{"version":3,"sources":["../../src/ts/Draggable.ts","../../src/ts/Screensaver.ts","../../src/ts/Keyboard.ts","../../src/ts/Gesture.ts","../../src/ts/VideoOverlay.ts","../../src/ts/LoaderManager.ts","../../src/ts/index.ts"],"sourcesContent":["// ============================================================================\n// move.gl | Draggable\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * Options for the Draggable class\n */\nexport interface DraggableOptions {\n    /** Whether to constrain dragging to parent bounds */\n    constrainToParent?: boolean;\n    /** CSS cursor style during drag */\n    dragCursor?: string;\n    /** Callback when drag starts */\n    onDragStart?: (x: number, y: number) => void;\n    /** Callback during drag */\n    onDrag?: (x: number, y: number) => void;\n    /** Callback when drag ends */\n    onDragEnd?: (x: number, y: number) => void;\n}\n\n/**\n * Draggable Element Handler\n *\n * Provides functionality to make an element draggable within the confines\n * of its parent container. Supports both mouse and touch interactions,\n * ensuring usability across different devices.\n *\n * @example\n * ```typescript\n * const draggable = new Draggable('myElement');\n * // Element with id=\"myElement\" is now draggable\n * ```\n */\nexport class Draggable {\n    private element: HTMLElement;\n    private isDragging: boolean = false;\n    private startX: number = 0;\n    private startY: number = 0;\n    private boundRect: DOMRect;\n\n    /**\n     * Creates a new Draggable instance.\n     * @param elementId - The ID of the HTML element to make draggable.\n     * @throws Error if element or parent element is not found.\n     */\n    constructor(elementId: string) {\n        const element = document.getElementById(elementId);\n        if (!element) {\n            throw new Error(`Element with id \"${elementId}\" not found`);\n        }\n        this.element = element;\n\n        const parent = this.element.parentElement;\n        if (!parent) {\n            throw new Error('Draggable element must have a parent element');\n        }\n        this.boundRect = parent.getBoundingClientRect();\n        this.attachEventListeners();\n    }\n\n    /**\n     * Attaches all necessary event listeners for drag functionality.\n     */\n    private attachEventListeners(): void {\n        this.element.addEventListener('mousedown', this.startDrag);\n        this.element.addEventListener('touchstart', this.startDrag, { passive: false });\n\n        document.addEventListener('mouseup', this.stopDrag);\n        document.addEventListener('touchend', this.stopDrag);\n\n        document.addEventListener('mousemove', this.drag);\n        document.addEventListener('touchmove', this.drag, { passive: false });\n    }\n\n    /**\n     * Gets the client coordinates from a mouse or touch event.\n     */\n    private getClientCoordinates(event: MouseEvent | TouchEvent): { clientX: number; clientY: number } {\n        if ('touches' in event && event.touches.length > 0) {\n            return {\n                clientX: event.touches[0].clientX,\n                clientY: event.touches[0].clientY\n            };\n        }\n        return {\n            clientX: (event as MouseEvent).clientX,\n            clientY: (event as MouseEvent).clientY\n        };\n    }\n\n    /**\n     * Initiates the drag operation.\n     */\n    private startDrag = (event: MouseEvent | TouchEvent): void => {\n        const coords = this.getClientCoordinates(event);\n        this.isDragging = true;\n        this.startX = coords.clientX - this.element.offsetLeft;\n        this.startY = coords.clientY - this.element.offsetTop;\n        event.preventDefault();\n    };\n\n    /**\n     * Handles the drag movement.\n     */\n    private drag = (event: MouseEvent | TouchEvent): void => {\n        if (!this.isDragging) return;\n\n        const coords = this.getClientCoordinates(event);\n        let x = coords.clientX - this.startX;\n        let y = coords.clientY - this.startY;\n\n        // Constrain the movement within the bounds of the element's parent\n        x = Math.max(this.boundRect.left, Math.min(x, this.boundRect.right - this.element.offsetWidth));\n        y = Math.max(this.boundRect.top, Math.min(y, this.boundRect.bottom - this.element.offsetHeight));\n\n        this.element.style.left = `${x}px`;\n        this.element.style.top = `${y}px`;\n    };\n\n    /**\n     * Stops the drag operation.\n     */\n    private stopDrag = (): void => {\n        this.isDragging = false;\n    };\n\n    /**\n     * Removes all event listeners and cleans up.\n     */\n    public destroy(): void {\n        this.element.removeEventListener('mousedown', this.startDrag);\n        this.element.removeEventListener('touchstart', this.startDrag);\n        document.removeEventListener('mouseup', this.stopDrag);\n        document.removeEventListener('touchend', this.stopDrag);\n        document.removeEventListener('mousemove', this.drag);\n        document.removeEventListener('touchmove', this.drag);\n    }\n}\n\nexport default Draggable;\n","// ============================================================================\n// move.gl | Screensaver\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * Screensaver Configuration Options\n */\nexport interface ScreensaverOptions {\n    /** Inactivity timeout in milliseconds */\n    timeout: number;\n    /** URL for the video to play */\n    videoUrl?: string;\n    /** URL for the audio to play */\n    audioUrl?: string;\n    /** ID of the screensaver container element */\n    containerId?: string;\n    /** ID of the video element */\n    videoId?: string;\n    /** ID of the audio element */\n    audioId?: string;\n}\n\n/**\n * Screensaver Class\n *\n * Handles the activation and deactivation of a screensaver based on\n * user inactivity. Provides methods to start and stop the screensaver,\n * manage media sources, and handle user interactions.\n *\n * @example\n * ```typescript\n * const screensaver = new Screensaver({\n *     timeout: 300000, // 5 minutes\n *     videoUrl: 'path/to/video.mp4',\n *     audioUrl: 'path/to/audio.mp3'\n * });\n * screensaver.setVolume(0.5);\n * ```\n */\nexport class Screensaver {\n    private timeoutId: number | undefined;\n    private readonly timeout: number;\n    private screensaverElement: HTMLElement | null = null;\n    private videoElement: HTMLVideoElement | null = null;\n    private audioElement: HTMLAudioElement | null = null;\n    private isActive: boolean = false;\n    private readonly options: ScreensaverOptions;\n\n    /**\n     * Creates a new Screensaver instance.\n     * @param options - Configuration options for the screensaver.\n     */\n    constructor(options: ScreensaverOptions) {\n        this.options = {\n            containerId: 'screensaver',\n            videoId: 'screensaverVideo',\n            audioId: 'screensaverAudio',\n            ...options\n        };\n        this.timeout = options.timeout;\n        this.initializeElements();\n        if (options.videoUrl && options.audioUrl) {\n            this.loadMedia(options.videoUrl, options.audioUrl);\n        }\n        this.setupEventListeners();\n        this.startScreensaverTimeout();\n    }\n\n    /**\n     * Initializes HTML elements from the DOM.\n     */\n    private initializeElements(): void {\n        this.screensaverElement = document.getElementById(this.options.containerId!);\n        this.videoElement = document.getElementById(this.options.videoId!) as HTMLVideoElement | null;\n        this.audioElement = document.getElementById(this.options.audioId!) as HTMLAudioElement | null;\n    }\n\n    /**\n     * Loads media sources into the video and audio elements.\n     * @param videoUrl - The source URL of the video.\n     * @param audioUrl - The source URL of the audio.\n     */\n    private loadMedia(videoUrl: string, audioUrl: string): void {\n        if (this.videoElement) {\n            this.videoElement.src = videoUrl;\n        }\n        if (this.audioElement) {\n            this.audioElement.src = audioUrl;\n        }\n    }\n\n    /**\n     * @notice Sets up event listeners for user interaction to prevent\n     * screensaver activation.\n     * @dev Listens for 'mousemove', 'keydown', and 'touchstart' events\n     * to reset the screensaver timer.\n     */\n    private setupEventListeners() {\n        ['mousemove', 'keydown', 'touchstart'].forEach(event => {\n            document.addEventListener(event, this.resetScreensaver);\n        });\n    }\n\n    /**\n     * @notice Starts or restarts the screensaver timeout.\n     * @dev Resets any existing timeout and sets a new timeout to activate\n     * the screensaver.\n     */\n    private startScreensaverTimeout() {\n        this.stopScreensaver(); // Stop existing screensaver if active\n        this.timeoutId = window.setTimeout(\n            () => this.activateScreensaver(), this.timeout\n        );\n    }\n\n    /**\n     * @notice Resets the screensaver timer and stops the screensaver if\n     * active.\n     * @dev Called upon user interactions detected by event listeners.\n     */\n    private resetScreensaver = () => {\n        if (this.isActive) {\n            this.stopScreensaver();\n        }\n        this.startScreensaverTimeout();\n    };\n\n    /**\n     * Activates the screensaver, displaying elements and playing media.\n     */\n    private activateScreensaver = (): void => {\n        if (this.screensaverElement) {\n            this.screensaverElement.style.display = 'block';\n        }\n        this.videoElement?.play();\n        this.audioElement?.play();\n        this.isActive = true;\n    };\n\n    /**\n     * Stops the screensaver and hides its elements.\n     */\n    public stopScreensaver(): void {\n        if (this.screensaverElement) {\n            this.screensaverElement.style.display = 'none';\n        }\n        this.videoElement?.pause();\n        this.audioElement?.pause();\n        this.isActive = false;\n\n        if (this.timeoutId !== undefined) {\n            clearTimeout(this.timeoutId);\n            this.timeoutId = undefined;\n        }\n    }\n\n    /**\n     * Sets the volume for both video and audio elements.\n     * @param volume - A number between 0.0 and 1.0 indicating the volume level.\n     */\n    public setVolume(volume: number): void {\n        const clampedVolume = Math.max(0, Math.min(1, volume));\n        if (this.videoElement) {\n            this.videoElement.volume = clampedVolume;\n        }\n        if (this.audioElement) {\n            this.audioElement.volume = clampedVolume;\n        }\n    }\n\n    /**\n     * Returns whether the screensaver is currently active.\n     */\n    public getIsActive(): boolean {\n        return this.isActive;\n    }\n\n    /**\n     * Cleans up event listeners and stops the screensaver.\n     */\n    public destroy(): void {\n        this.stopScreensaver();\n        ['mousemove', 'keydown', 'touchstart'].forEach(event => {\n            document.removeEventListener(event, this.resetScreensaver);\n        });\n    }\n}\n\nexport default Screensaver;\n","// ============================================================================\n// move.gl | Virtual Keyboard\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * Keyboard layout configuration\n */\nexport interface KeyboardLayout {\n    [mode: string]: string[][];\n}\n\n/**\n * Virtual Keyboard Configuration Options\n */\nexport interface VirtualKeyboardOptions {\n    /** Custom keyboard layout */\n    layout?: KeyboardLayout;\n    /** Callback when a key is pressed */\n    onKeyPress?: (key: string) => void;\n}\n\n/**\n * Virtual Keyboard\n *\n * Manages the rendering and interaction of a virtual keyboard on the web.\n * Supports multiple layouts (default, shift, special) and handles both\n * mouse and keyboard inputs, including touch support.\n *\n * @example\n * ```typescript\n * const keyboard = new VirtualKeyboard('textInput', 'keyboard');\n * keyboard.switchMode('special');\n * ```\n */\nexport class VirtualKeyboard {\n\n    private keys: { [mode: string]: string[][] } = {\n        \"default\": [\n            [\"1\", \"2\", \"3\", \"4\", \"5\", \"6\", \"7\", \"8\", \"9\", \"0\"],\n            [\"q\", \"w\", \"e\", \"r\", \"t\", \"y\", \"u\", \"i\", \"o\", \"p\"],\n            [\"a\", \"s\", \"d\", \"f\", \"g\", \"h\", \"j\", \"k\", \"l\"],\n            [\"z\", \"x\", \"c\", \"v\", \"b\", \"n\", \"m\", \"Backspace\"]\n        ],\n        \"shift\": [\n            [\"!\", \"@\", \"#\", \"$\", \"%\", \"^\", \"&\", \"*\", \"(\", \")\"],\n            [\"Q\", \"W\", \"E\", \"R\", \"T\", \"Y\", \"U\", \"I\", \"O\", \"P\"],\n            [\"A\", \"S\", \"D\", \"F\", \"G\", \"H\", \"J\", \"K\", \"L\"],\n            [\"Z\", \"X\", \"C\", \"V\", \"B\", \"N\", \"M\", \"Backspace\"]\n        ],\n        \"special\": [\n            [\"[\", \"]\", \"{\", \"}\", \"#\", \"%\", \"^\", \"*\", \"+\", \"=\"],\n            [\"_\", \"\\\\\", \"|\", \"~\", \"<\", \">\", \"€\", \"£\", \"¥\"],\n            [\".\", \",\", \"?\", \"!\", \"'\", '\"', \":\", \";\", \"Backspace\"]\n        ]\n    };\n    private currentMode = \"default\";\n    private inputElement: HTMLInputElement;\n    private keyboardElement: HTMLElement;\n\n    /**\n     * @notice Initializes the virtual keyboard with specific input and\n     * keyboard element IDs.\n     * @param inputId The ID of the HTML input element to which the keyboard\n     * will be linked.\n     * @param keyboardId The ID of the container element where the keyboard\n     * will be rendered.\n     */\n    constructor(inputId: string, keyboardId: string) {\n        this.inputElement = document.getElementById(\n            inputId\n        ) as HTMLInputElement;\n        this.keyboardElement = document.getElementById(\n            keyboardId\n        ) as HTMLElement;\n        this.renderKeyboard();\n        this.attachEventListeners();\n    }\n\n    /**\n     * @notice Renders the keyboard based on the current mode (default, shift,\n     * or special).\n     * @dev Dynamically creates HTML for keyboard keys and appends them to the\n     * keyboardElement.\n     */\n    private renderKeyboard() {\n        // Clear existing keys\n        this.keyboardElement.innerHTML = \"\";\n        this.keys[this.currentMode].forEach(row => {\n            const rowElement = document.createElement(\"div\");\n            rowElement.className = \"keyboard__row\";\n            row.forEach(key => {\n                const keyElement = document.createElement(\"div\");\n                keyElement.textContent = key;\n                // Assign a class for easier CSS styling\n                keyElement.className = \"key\";\n                keyElement.addEventListener(\n                    \"click\", () => this.handleKeyPress(key)\n                );\n                rowElement.appendChild(keyElement);\n            });\n            this.keyboardElement.appendChild(rowElement);\n        });\n    }\n\n    /**\n     * @notice Handles key presses on the virtual keyboard.\n     * @param key The key character or function (like \"Backspace\") that was\n     * pressed.\n     */\n    private handleKeyPress(key: string) {\n        if (key === \"Backspace\") {\n            this.inputElement.value = this.inputElement.value.slice(0, -1);\n        } else if (key === \"Shift\" || key === \"CapsLock\") {\n            this.toggleShift();\n        } else {\n            this.inputElement.value += key;\n        }\n    }\n\n    /**\n     * @notice Toggles the keyboard between \"default\" and \"shift\" modes.\n     * @dev This method is called when the \"Shift\" or \"CapsLock\" key is pressed.\n     */\n    private toggleShift() {\n        this.currentMode = this.currentMode === \"default\" ? \"shift\" : \"default\";\n        this.renderKeyboard();\n    }\n\n    /**\n     * @notice Attaches necessary event listeners to handle both physical\n     * keyboard and touch inputs.\n     */\n    private attachEventListeners() {\n        document.addEventListener(\"keydown\", this.handlePhysicalKeyPress);\n        this.keyboardElement.addEventListener(\n            \"touchstart\", this.handleTouchStart, false\n        );\n    }\n\n    /**\n     * @notice Handles physical keyboard events and maps them to virtual key\n     * presses.\n     * @param event The keyboard event captured from the user\"s physical\n     * keyboard.\n     */\n    private handlePhysicalKeyPress = (event: KeyboardEvent) => {\n        const key = event.key;\n        if (key === \"Shift\" || key === \"CapsLock\") {\n            this.toggleShift();\n            event.preventDefault();\n        } else if (key === \"Enter\" || key === \"Tab\") {\n            // Optional: Implement behavior for Enter and Tab if needed\n        } else {\n            this.handleKeyPress(key);\n        }\n    };\n\n    /**\n     * @notice Handles touch events on the keyboard element.\n     * @param event The touch event on the virtual keyboard.\n     */\n    private handleTouchStart = (event: TouchEvent) => {\n        event.preventDefault(); // Prevents emulating mouse events\n        const keyElement = event.target as HTMLElement;\n        if (keyElement.classList.contains(\"key\")) {\n            this.handleKeyPress(keyElement.textContent || \"\");\n        }\n    };\n\n    /**\n     * @notice Switches the keyboard layout to a specified mode.\n     * @param mode The mode to which the keyboard layout should switch\n     * (\"default\", \"shift\", or \"special\").\n     */\n    public switchMode(mode: string) {\n        if (this.keys[mode]) {\n            this.currentMode = mode;\n            this.renderKeyboard();\n        }\n    }\n\n    /**\n     * Removes all event listeners and cleans up.\n     */\n    public destroy(): void {\n        document.removeEventListener('keydown', this.handlePhysicalKeyPress);\n        this.keyboardElement.removeEventListener('touchstart', this.handleTouchStart);\n        this.keyboardElement.innerHTML = '';\n    }\n}\n\nexport default VirtualKeyboard;\n","// ============================================================================\n// move.gl | Gesture Handlers\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * Swipe direction type\n */\nexport type SwipeDirection = 'left' | 'right' | 'up' | 'down';\n\n/**\n * Gesture event callbacks\n */\nexport interface GestureCallbacks {\n    onTap?: () => void;\n    onSwipe?: (direction: SwipeDirection, deltaX: number, deltaY: number) => void;\n    onPinch?: (scale: number) => void;\n    onRotate?: (angle: number) => void;\n}\n\n/**\n * Touch Gesture Handler Class\n *\n * Manages touch interactions on a specified element, interpreting various\n * gestures like taps, swipes, and pinches.\n *\n * @example\n * ```typescript\n * const gesture = new TouchGestureHandler('myElement', {\n *     onSwipe: (dir, dx, dy) => console.log(`Swiped ${dir}`),\n *     onPinch: (scale) => console.log(`Pinch scale: ${scale}`)\n * });\n * ```\n */\nexport class TouchGestureHandler {\n    private element: HTMLElement;\n    private startTouches: Touch[] | null = null;\n    private lastTouches: Touch[] | null = null;\n    private isSwiping = false;\n    private isPinching = false;\n    private callbacks: GestureCallbacks;\n\n    /**\n     * Creates a new TouchGestureHandler instance.\n     * @param elementId - The ID of the element to attach gesture handling to.\n     * @param callbacks - Optional callback functions for gesture events.\n     */\n    constructor(elementId: string, callbacks: GestureCallbacks = {}) {\n        const element = document.getElementById(elementId);\n        if (!element) {\n            throw new Error(`Element with id \"${elementId}\" not found`);\n        }\n        this.element = element;\n        this.callbacks = callbacks;\n        this.addTouchListeners();\n    }\n\n    private addTouchListeners(): void {\n        this.element.addEventListener('touchstart', this.handleTouchStart, false);\n        this.element.addEventListener('touchmove', this.handleTouchMove, false);\n        this.element.addEventListener('touchend', this.handleTouchEnd, false);\n    }\n\n    private handleTouchStart = (event: TouchEvent): void => {\n        if (event.touches.length === 1) {\n            this.startTouches = Array.from(event.touches);\n        } else if (event.touches.length > 1) {\n            this.startTouches = Array.from(event.touches);\n            this.isPinching = true;\n        }\n    };\n\n    private handleTouchMove = (event: TouchEvent): void => {\n        if (!this.startTouches) return;\n\n        this.lastTouches = Array.from(event.touches);\n\n        if (event.touches.length === 1 && !this.isPinching) {\n            const dx = event.touches[0].clientX - this.startTouches[0].clientX;\n            const dy = event.touches[0].clientY - this.startTouches[0].clientY;\n            if (Math.abs(dx) > 10 || Math.abs(dy) > 10) {\n                this.isSwiping = true;\n            }\n        } else if (event.touches.length > 1 && this.isPinching && this.startTouches.length > 1) {\n            const startDistance = this.getDistance(this.startTouches[0], this.startTouches[1]);\n            const currentDistance = this.getDistance(event.touches[0], event.touches[1]);\n            const scale = currentDistance / startDistance;\n            this.callbacks.onPinch?.(scale);\n        }\n    };\n\n    private handleTouchEnd = (): void => {\n        if (this.isSwiping && this.startTouches && this.lastTouches) {\n            const dx = this.lastTouches[0].clientX - this.startTouches[0].clientX;\n            const dy = this.lastTouches[0].clientY - this.startTouches[0].clientY;\n            const direction = this.getSwipeDirection(dx, dy);\n            this.callbacks.onSwipe?.(direction, dx, dy);\n            this.isSwiping = false;\n        } else if (this.isPinching) {\n            this.isPinching = false;\n        } else {\n            this.callbacks.onTap?.();\n        }\n        this.startTouches = null;\n        this.lastTouches = null;\n    };\n\n    /**\n     * Determines swipe direction based on deltas.\n     */\n    private getSwipeDirection(dx: number, dy: number): SwipeDirection {\n        if (Math.abs(dx) > Math.abs(dy)) {\n            return dx > 0 ? 'right' : 'left';\n        }\n        return dy > 0 ? 'down' : 'up';\n    }\n\n    /**\n     * Calculates the distance between two touch points.\n     */\n    private getDistance(touch1: Touch, touch2: Touch): number {\n        const dx = touch2.clientX - touch1.clientX;\n        const dy = touch2.clientY - touch1.clientY;\n        return Math.sqrt(dx * dx + dy * dy);\n    }\n\n    /**\n     * Removes all event listeners and cleans up.\n     */\n    public destroy(): void {\n        this.element.removeEventListener('touchstart', this.handleTouchStart);\n        this.element.removeEventListener('touchmove', this.handleTouchMove);\n        this.element.removeEventListener('touchend', this.handleTouchEnd);\n    }\n}\n\n\n/**\n * Pointer event callbacks\n */\nexport interface PointerGestureCallbacks {\n    onGestureStart?: (event: PointerEvent) => void;\n    onGestureMove?: (deltaX: number, deltaY: number, event: PointerEvent) => void;\n    onGestureEnd?: (event: PointerEvent) => void;\n}\n\n/**\n * Advanced Gesture Recognition Handler\n *\n * Handles complex gestures for interactive applications using pointer events.\n * Works with mouse, touch, and pen input.\n *\n * @example\n * ```typescript\n * const gesture = new AdvancedGestureRecognition('myElement', {\n *     onGestureMove: (dx, dy) => console.log(`Moved ${dx}px, ${dy}px`)\n * });\n * ```\n */\nexport class AdvancedGestureRecognition {\n    private element: HTMLElement;\n    private ongoingTouches: Map<number, PointerEvent> = new Map();\n    private callbacks: PointerGestureCallbacks;\n\n    /**\n     * Creates a new AdvancedGestureRecognition instance.\n     * @param elementId - The ID of the element to attach gesture handling to.\n     * @param callbacks - Optional callback functions for gesture events.\n     */\n    constructor(elementId: string, callbacks: PointerGestureCallbacks = {}) {\n        const element = document.getElementById(elementId);\n        if (!element) {\n            throw new Error(`Element with id \"${elementId}\" not found`);\n        }\n        this.element = element;\n        this.callbacks = callbacks;\n        this.attachEventListeners();\n    }\n\n    private attachEventListeners(): void {\n        this.element.addEventListener('pointerdown', this.handleGestureStart, { passive: false });\n        this.element.addEventListener('pointermove', this.handleGestureMove, { passive: false });\n        this.element.addEventListener('pointerup', this.handleGestureEnd, { passive: false });\n        this.element.addEventListener('pointercancel', this.handleGestureEnd, { passive: false });\n    }\n\n    private handleGestureStart = (event: PointerEvent): void => {\n        this.ongoingTouches.set(event.pointerId, event);\n        this.callbacks.onGestureStart?.(event);\n    };\n\n    private handleGestureMove = (event: PointerEvent): void => {\n        if (this.ongoingTouches.has(event.pointerId)) {\n            const startEvent = this.ongoingTouches.get(event.pointerId)!;\n            const dx = event.clientX - startEvent.clientX;\n            const dy = event.clientY - startEvent.clientY;\n            this.callbacks.onGestureMove?.(dx, dy, event);\n        }\n    };\n\n    private handleGestureEnd = (event: PointerEvent): void => {\n        this.ongoingTouches.delete(event.pointerId);\n        this.callbacks.onGestureEnd?.(event);\n    };\n\n    /**\n     * Removes all event listeners and cleans up.\n     */\n    public destroy(): void {\n        this.element.removeEventListener('pointerdown', this.handleGestureStart);\n        this.element.removeEventListener('pointermove', this.handleGestureMove);\n        this.element.removeEventListener('pointerup', this.handleGestureEnd);\n        this.element.removeEventListener('pointercancel', this.handleGestureEnd);\n    }\n}\n\nexport default {\n    TouchGestureHandler,\n    AdvancedGestureRecognition\n};\n\n\n\n\n","// ============================================================================\n// move.gl | Video Overlay\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * Video overlay options\n */\nexport interface VideoOverlayOptions {\n    /** Fade transition duration in milliseconds */\n    fadeTransitionDuration?: number;\n    /** Whether to loop the video */\n    loop?: boolean;\n    /** Initial video source URL */\n    initialSource?: string;\n}\n\n/**\n * Transparent Video Overlay Handler\n *\n * Manages a transparent video overlay, controlling its visibility,\n * playback, and effects.\n *\n * @example\n * ```typescript\n * const overlay = new TransparentVideoOverlay('myVideo', {\n *     fadeTransitionDuration: 500,\n *     loop: true\n * });\n * overlay.showOverlay();\n * ```\n */\nexport class TransparentVideoOverlay {\n    private videoElement: HTMLVideoElement | null = null;\n    private isVisible: boolean = false;\n    private fadeTransitionDuration: number;\n    private loop: boolean;\n\n    /**\n     * Creates a new TransparentVideoOverlay instance.\n     * @param videoElementId - The ID of the video element to manage.\n     * @param options - Optional configuration options.\n     */\n    constructor(videoElementId: string, options: VideoOverlayOptions = {}) {\n        const element = document.getElementById(videoElementId);\n        if (element instanceof HTMLVideoElement) {\n            this.videoElement = element;\n        } else {\n            console.warn(`Element with id \"${videoElementId}\" is not a video element`);\n        }\n\n        this.fadeTransitionDuration = options.fadeTransitionDuration ?? 500;\n        this.loop = options.loop ?? true;\n\n        if (this.videoElement) {\n            this.setupVideo();\n            if (options.initialSource) {\n                this.changeVideoSource(options.initialSource, false);\n            }\n        }\n    }\n\n    /**\n     * Initializes video settings and event listeners.\n     */\n    private setupVideo(): void {\n        if (!this.videoElement) return;\n\n        if (this.loop) {\n            this.videoElement.addEventListener('ended', () => {\n                this.videoElement?.play();\n            });\n        }\n\n        this.videoElement.addEventListener('loadeddata', () => {\n            console.log('Video loaded successfully.');\n        });\n\n        this.videoElement.addEventListener('error', (e) => {\n            console.error('Error loading video:', e);\n        });\n\n        // Set initial style for smooth transitions\n        this.videoElement.style.transition = `opacity ${this.fadeTransitionDuration}ms ease`;\n    }\n\n    /**\n     * Shows the video overlay with a fade-in effect.\n     */\n    public showOverlay(): void {\n        if (!this.videoElement) return;\n\n        this.videoElement.style.display = 'block';\n        this.videoElement.style.opacity = '0';\n\n        // Use requestAnimationFrame for smoother transition\n        requestAnimationFrame(() => {\n            if (this.videoElement) {\n                this.videoElement.style.opacity = '1';\n                this.videoElement.play().catch(err => {\n                    console.warn('Auto-play prevented:', err);\n                });\n            }\n        });\n\n        this.isVisible = true;\n    }\n\n    /**\n     * Hides the video overlay with a fade-out effect.\n     */\n    public hideOverlay(): void {\n        if (!this.videoElement) return;\n\n        this.videoElement.style.opacity = '0';\n\n        setTimeout(() => {\n            if (this.videoElement) {\n                this.videoElement.style.display = 'none';\n                this.videoElement.pause();\n            }\n        }, this.fadeTransitionDuration);\n\n        this.isVisible = false;\n    }\n\n    /**\n     * Toggles the visibility of the video overlay.\n     */\n    public toggleOverlay(): void {\n        if (this.isVisible) {\n            this.hideOverlay();\n        } else {\n            this.showOverlay();\n        }\n    }\n\n    /**\n     * Changes the video source and optionally plays it immediately.\n     * @param videoUrl - The URL of the new video source.\n     * @param autoPlay - Whether the video should play immediately after loading.\n     */\n    public changeVideoSource(videoUrl: string, autoPlay: boolean = true): void {\n        if (!this.videoElement) return;\n\n        this.videoElement.src = videoUrl;\n        this.videoElement.load();\n\n        if (autoPlay) {\n            this.showOverlay();\n        }\n    }\n\n    /**\n     * Gets the visibility state of the overlay.\n     */\n    public getIsVisible(): boolean {\n        return this.isVisible;\n    }\n\n    /**\n     * Cleans up the video overlay instance.\n     */\n    public destroy(): void {\n        if (this.videoElement) {\n            this.videoElement.pause();\n            this.videoElement.src = '';\n            this.videoElement = null;\n        }\n    }\n}\n\n/**\n * Checks if the browser supports HEVC alpha channel videos.\n * This is primarily supported in Safari.\n * @returns Whether HEVC alpha is supported.\n */\nexport function supportsHEVCAlpha(): boolean {\n    const navigator = window.navigator;\n    const ua = navigator.userAgent.toLowerCase();\n    const hasMediaCapabilities = !!(\n        navigator.mediaCapabilities &&\n        navigator.mediaCapabilities.decodingInfo\n    );\n    const isSafari = (\n        ua.indexOf('safari') !== -1 &&\n        ua.indexOf('chrome') === -1 &&\n        ua.indexOf('version/') !== -1\n    );\n    return isSafari && hasMediaCapabilities;\n}\n\n/**\n * Gets the appropriate video source based on browser support.\n * @param hevcSource - The HEVC/MOV source for Safari.\n * @param webmSource - The WebM source for other browsers.\n * @returns The appropriate video source URL.\n */\nexport function getOptimalVideoSource(hevcSource: string, webmSource: string): string {\n    return supportsHEVCAlpha() ? hevcSource : webmSource;\n}\n\nexport default TransparentVideoOverlay;\n","// ============================================================================\n// move.gl | Loader Manager\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * Loader Manager\n * ===========================================================================\n *\n * A TypeScript class for dynamically creating and managing CSS-based loader\n * animations with Shadow DOM encapsulation.\n *\n * @module LoaderManager\n * @author Scape Agency\n * @link https://move.gl\n * @since 0.1.0\n */\n\n\n// ============================================================================\n// Interfaces\n// ============================================================================\n\n/**\n * Configuration for a loader instance.\n */\nexport interface LoaderConfig {\n    /** Unique identifier for the loader */\n    id: string;\n    /** HTML content for the loader (default: empty span) */\n    content?: string;\n    /** CSS styles for the loader */\n    css: string;\n    /** Optional HTML markup override */\n    html?: string;\n}\n\n/**\n * Options for creating a loader element.\n */\nexport interface LoaderOptions {\n    /** Container element or selector */\n    container?: HTMLElement | string;\n    /** Whether to use Shadow DOM (default: true) */\n    useShadowDOM?: boolean;\n    /** Additional CSS classes to add */\n    className?: string;\n    /** Custom size override */\n    size?: number | string;\n    /** Primary color override */\n    color?: string;\n    /** Secondary/accent color override */\n    accentColor?: string;\n}\n\n/**\n * Loader preset categories.\n */\nexport type LoaderCategory =\n    | 'spinner'\n    | 'dots'\n    | 'bars'\n    | 'progress'\n    | 'pulse'\n    | 'bounce'\n    | 'text'\n    | 'skeleton'\n    | 'custom';\n\n\n// ============================================================================\n// Loader Manager Class\n// ============================================================================\n\n/**\n * LoaderManager provides methods for creating, managing, and rendering\n * CSS-based loading animations with Shadow DOM encapsulation.\n *\n * @example\n * ```typescript\n * const manager = new LoaderManager();\n *\n * // Register a custom loader\n * manager.register({\n *     id: 'my-spinner',\n *     css: `.loader { width: 48px; height: 48px; ... }`\n * });\n *\n * // Create and show loader\n * const loader = manager.create('my-spinner', {\n *     container: '#app',\n *     color: '#FF3D00'\n * });\n *\n * // Later, remove it\n * manager.destroy(loader);\n * ```\n */\nexport class LoaderManager {\n\n    // ========================================================================\n    // Properties\n    // ========================================================================\n\n    /** Registry of loader configurations */\n    private loaders: Map<string, LoaderConfig> = new Map();\n\n    /** Active loader instances */\n    private activeLoaders: Map<HTMLElement, { id: string; shadowRoot?: ShadowRoot }> = new Map();\n\n    /** Default CSS variables for customization */\n    private defaultVars = {\n        '--loader-size': '48px',\n        '--loader-color': '#FFF',\n        '--loader-accent': '#FF3D00',\n        '--loader-speed': '1s',\n    };\n\n\n    // ========================================================================\n    // Constructor\n    // ========================================================================\n\n    /**\n     * Creates a new LoaderManager instance.\n     * @param preloadBuiltins - Whether to preload built-in loaders (default: true)\n     */\n    constructor(preloadBuiltins: boolean = true) {\n        if (preloadBuiltins) {\n            this.registerBuiltinLoaders();\n        }\n    }\n\n\n    // ========================================================================\n    // Public Methods\n    // ========================================================================\n\n    /**\n     * Registers a loader configuration.\n     * @param config - The loader configuration to register\n     * @returns The LoaderManager instance for chaining\n     */\n    public register(config: LoaderConfig): this {\n        this.loaders.set(config.id, config);\n        return this;\n    }\n\n    /**\n     * Registers multiple loader configurations.\n     * @param configs - Array of loader configurations\n     * @returns The LoaderManager instance for chaining\n     */\n    public registerAll(configs: LoaderConfig[]): this {\n        configs.forEach(config => this.register(config));\n        return this;\n    }\n\n    /**\n     * Creates and mounts a loader element.\n     * @param loaderId - ID of the registered loader to create\n     * @param options - Creation options\n     * @returns The created loader element\n     */\n    public create(loaderId: string, options: LoaderOptions = {}): HTMLElement {\n        const config = this.loaders.get(loaderId);\n        if (!config) {\n            throw new Error(`Loader \"${loaderId}\" not found. Register it first.`);\n        }\n\n        const {\n            container,\n            useShadowDOM = true,\n            className = '',\n            size,\n            color,\n            accentColor,\n        } = options;\n\n        // Create wrapper element\n        const wrapper = document.createElement('div');\n        wrapper.className = `loader-wrapper ${className}`.trim();\n        wrapper.setAttribute('data-loader-id', loaderId);\n\n        // Apply CSS custom properties\n        if (size) {\n            wrapper.style.setProperty('--loader-size', typeof size === 'number' ? `${size}px` : size);\n        }\n        if (color) {\n            wrapper.style.setProperty('--loader-color', color);\n        }\n        if (accentColor) {\n            wrapper.style.setProperty('--loader-accent', accentColor);\n        }\n\n        // Create loader content\n        if (useShadowDOM) {\n            const shadowRoot = wrapper.attachShadow({ mode: 'open' });\n\n            // Add styles\n            const styleEl = document.createElement('style');\n            styleEl.textContent = this.processCSS(config.css, options);\n            shadowRoot.appendChild(styleEl);\n\n            // Add loader element\n            const loaderEl = document.createElement('span');\n            loaderEl.className = 'loader';\n            if (config.content) {\n                loaderEl.innerHTML = config.content;\n            }\n            shadowRoot.appendChild(loaderEl);\n\n            this.activeLoaders.set(wrapper, { id: loaderId, shadowRoot });\n        } else {\n            // Without Shadow DOM\n            const styleEl = document.createElement('style');\n            styleEl.textContent = this.scopeCSS(config.css, wrapper, loaderId);\n            wrapper.appendChild(styleEl);\n\n            const loaderEl = document.createElement('span');\n            loaderEl.className = `loader loader-${loaderId}`;\n            if (config.content) {\n                loaderEl.innerHTML = config.content;\n            }\n            wrapper.appendChild(loaderEl);\n\n            this.activeLoaders.set(wrapper, { id: loaderId });\n        }\n\n        // Mount to container if provided\n        if (container) {\n            const containerEl = typeof container === 'string'\n                ? document.querySelector(container)\n                : container;\n            containerEl?.appendChild(wrapper);\n        }\n\n        return wrapper;\n    }\n\n    /**\n     * Creates a full-screen overlay loader.\n     * @param loaderId - ID of the registered loader\n     * @param options - Creation options\n     * @returns The created overlay element\n     */\n    public createOverlay(loaderId: string, options: Omit<LoaderOptions, 'container'> = {}): HTMLElement {\n        const overlay = document.createElement('div');\n        overlay.className = 'loader-overlay';\n        overlay.style.cssText = `\n            position: fixed;\n            inset: 0;\n            display: flex;\n            align-items: center;\n            justify-content: center;\n            background: rgba(0, 0, 0, 0.7);\n            z-index: 9999;\n        `;\n\n        const loader = this.create(loaderId, { ...options, container: overlay });\n        document.body.appendChild(overlay);\n\n        // Store reference for cleanup\n        this.activeLoaders.set(overlay, { id: `overlay-${loaderId}` });\n\n        return overlay;\n    }\n\n    /**\n     * Shows a loader in an existing element, replacing its content.\n     * @param loaderId - ID of the registered loader\n     * @param target - Target element or selector\n     * @param options - Creation options\n     * @returns The created loader element\n     */\n    public showIn(loaderId: string, target: HTMLElement | string, options: LoaderOptions = {}): HTMLElement {\n        const targetEl = typeof target === 'string'\n            ? document.querySelector<HTMLElement>(target)\n            : target;\n\n        if (!targetEl) {\n            throw new Error(`Target element not found: ${target}`);\n        }\n\n        // Store original content\n        const originalContent = targetEl.innerHTML;\n        targetEl.setAttribute('data-original-content', originalContent);\n        targetEl.innerHTML = '';\n\n        // Create loader\n        const loader = this.create(loaderId, { ...options, container: targetEl });\n\n        return loader;\n    }\n\n    /**\n     * Hides a loader and restores original content.\n     * @param target - Target element or selector\n     */\n    public hideIn(target: HTMLElement | string): void {\n        const targetEl = typeof target === 'string'\n            ? document.querySelector<HTMLElement>(target)\n            : target;\n\n        if (!targetEl) return;\n\n        const originalContent = targetEl.getAttribute('data-original-content');\n        if (originalContent !== null) {\n            targetEl.innerHTML = originalContent;\n            targetEl.removeAttribute('data-original-content');\n        }\n    }\n\n    /**\n     * Destroys a loader element.\n     * @param loader - The loader element to destroy\n     */\n    public destroy(loader: HTMLElement): void {\n        this.activeLoaders.delete(loader);\n        loader.remove();\n    }\n\n    /**\n     * Destroys all active loaders.\n     */\n    public destroyAll(): void {\n        this.activeLoaders.forEach((_, loader) => this.destroy(loader));\n    }\n\n    /**\n     * Gets a list of all registered loader IDs.\n     * @returns Array of loader IDs\n     */\n    public getRegisteredLoaders(): string[] {\n        return Array.from(this.loaders.keys());\n    }\n\n    /**\n     * Checks if a loader is registered.\n     * @param loaderId - Loader ID to check\n     * @returns True if registered\n     */\n    public has(loaderId: string): boolean {\n        return this.loaders.has(loaderId);\n    }\n\n    /**\n     * Gets the configuration for a registered loader.\n     * @param loaderId - Loader ID\n     * @returns The loader configuration or undefined\n     */\n    public getConfig(loaderId: string): LoaderConfig | undefined {\n        return this.loaders.get(loaderId);\n    }\n\n\n    // ========================================================================\n    // Private Methods\n    // ========================================================================\n\n    /**\n     * Processes CSS with variable replacements.\n     */\n    private processCSS(css: string, options: LoaderOptions): string {\n        let processed = css;\n\n        // Replace hardcoded colors with CSS variables\n        processed = processed.replace(/#FFF\\b/gi, 'var(--loader-color, #FFF)');\n        processed = processed.replace(/#FF3D00\\b/gi, 'var(--loader-accent, #FF3D00)');\n        processed = processed.replace(/48px/g, 'var(--loader-size, 48px)');\n\n        return processed;\n    }\n\n    /**\n     * Scopes CSS to a specific element (for non-Shadow DOM usage).\n     */\n    private scopeCSS(css: string, wrapper: HTMLElement, loaderId: string): string {\n        // Replace .loader with scoped selector\n        return css.replace(/\\.loader/g, `.loader-${loaderId}`);\n    }\n\n    /**\n     * Registers built-in loader presets.\n     */\n    private registerBuiltinLoaders(): void {\n        // Spinner loaders\n        this.register({\n            id: 'spinner',\n            css: `.loader {\n                width: 48px;\n                height: 48px;\n                border: 5px solid #FFF;\n                border-bottom-color: #FF3D00;\n                border-radius: 50%;\n                display: inline-block;\n                box-sizing: border-box;\n                animation: rotation 1s linear infinite;\n            }\n            @keyframes rotation {\n                0% { transform: rotate(0deg); }\n                100% { transform: rotate(360deg); }\n            }`\n        });\n\n        this.register({\n            id: 'spinner-dual',\n            css: `.loader {\n                width: 48px;\n                height: 48px;\n                border: 5px solid #FFF;\n                border-bottom-color: transparent;\n                border-radius: 50%;\n                display: inline-block;\n                box-sizing: border-box;\n                animation: rotation 1s linear infinite;\n            }\n            @keyframes rotation {\n                0% { transform: rotate(0deg); }\n                100% { transform: rotate(360deg); }\n            }`\n        });\n\n        // Dots loaders\n        this.register({\n            id: 'dots-bounce',\n            css: `.loader, .loader:before, .loader:after {\n                border-radius: 50%;\n                width: 2.5em;\n                height: 2.5em;\n                animation-fill-mode: both;\n                animation: bblFadInOut 1.8s infinite ease-in-out;\n            }\n            .loader {\n                color: #FFF;\n                font-size: 7px;\n                position: relative;\n                text-indent: -9999em;\n                transform: translateZ(0);\n                animation-delay: -0.16s;\n            }\n            .loader:before, .loader:after {\n                content: '';\n                position: absolute;\n                top: 0;\n            }\n            .loader:before {\n                left: -3.5em;\n                animation-delay: -0.32s;\n            }\n            .loader:after {\n                left: 3.5em;\n            }\n            @keyframes bblFadInOut {\n                0%, 80%, 100% { box-shadow: 0 2.5em 0 -1.3em }\n                40% { box-shadow: 0 2.5em 0 0 }\n            }`\n        });\n\n        this.register({\n            id: 'dots-flash',\n            css: `.loader {\n                width: 16px;\n                height: 16px;\n                border-radius: 50%;\n                background-color: #fff;\n                box-shadow: 32px 0 #fff, -32px 0 #fff;\n                position: relative;\n                animation: flash 0.5s ease-out infinite alternate;\n            }\n            @keyframes flash {\n                0% {\n                    background-color: #FFF2;\n                    box-shadow: 32px 0 #FFF2, -32px 0 #FFF;\n                }\n                50% {\n                    background-color: #FFF;\n                    box-shadow: 32px 0 #FFF2, -32px 0 #FFF2;\n                }\n                100% {\n                    background-color: #FFF2;\n                    box-shadow: 32px 0 #FFF, -32px 0 #FFF2;\n                }\n            }`\n        });\n\n        // Progress bar loaders\n        this.register({\n            id: 'progress-bar',\n            css: `.loader {\n                width: 100%;\n                height: 4.8px;\n                display: inline-block;\n                position: relative;\n                background: rgba(255, 255, 255, 0.15);\n                overflow: hidden;\n            }\n            .loader::after {\n                content: '';\n                width: 96px;\n                height: 4.8px;\n                background: #FFF;\n                position: absolute;\n                top: 0;\n                left: 0;\n                box-sizing: border-box;\n                animation: hitZak 1s linear infinite alternate;\n            }\n            @keyframes hitZak {\n                0% { left: 0; transform: translateX(-1%); }\n                100% { left: 100%; transform: translateX(-99%); }\n            }`\n        });\n\n        this.register({\n            id: 'progress-fill',\n            css: `.loader {\n                width: 100%;\n                height: 4.8px;\n                display: inline-block;\n                position: relative;\n                background: rgba(255, 255, 255, 0.15);\n                overflow: hidden;\n            }\n            .loader::after {\n                content: '';\n                box-sizing: border-box;\n                width: 0;\n                height: 4.8px;\n                background: #FFF;\n                position: absolute;\n                top: 0;\n                left: 0;\n                animation: animFw 10s linear infinite;\n            }\n            @keyframes animFw {\n                0% { width: 0; }\n                100% { width: 100%; }\n            }`\n        });\n\n        // Pulse loaders\n        this.register({\n            id: 'pulse',\n            css: `.loader {\n                width: 48px;\n                height: 48px;\n                border-radius: 50%;\n                display: inline-block;\n                position: relative;\n                background: #FFF;\n                box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5);\n                animation: pulse 1.5s ease-out infinite;\n            }\n            @keyframes pulse {\n                0% { box-shadow: 0 0 0 0 rgba(255, 255, 255, 0.5); }\n                100% { box-shadow: 0 0 0 30px rgba(255, 255, 255, 0); }\n            }`\n        });\n\n        // Square loaders\n        this.register({\n            id: 'square-flip',\n            css: `.loader {\n                width: 48px;\n                height: 48px;\n                display: inline-block;\n                position: relative;\n                background: #FFF;\n                box-sizing: border-box;\n                animation: flipX 1s linear infinite;\n            }\n            @keyframes flipX {\n                0% { transform: perspective(200px) rotateX(0deg) rotateY(0deg); }\n                50% { transform: perspective(200px) rotateX(-180deg) rotateY(0deg); }\n                100% { transform: perspective(200px) rotateX(-180deg) rotateY(-180deg); }\n            }`\n        });\n\n        // Skeleton loaders\n        this.register({\n            id: 'skeleton-card',\n            css: `.loader {\n                width: 320px;\n                height: 150px;\n                display: block;\n                margin: auto;\n                position: relative;\n                background: #FFF;\n                box-sizing: border-box;\n            }\n            .loader::after {\n                content: '';\n                width: calc(100% - 30px);\n                height: calc(100% - 30px);\n                top: 15px;\n                left: 15px;\n                position: absolute;\n                background-image:\n                    linear-gradient(100deg, transparent, rgba(255, 255, 255, 0.5) 50%, transparent 80%),\n                    linear-gradient(#DDD 56px, transparent 0),\n                    linear-gradient(#DDD 24px, transparent 0),\n                    linear-gradient(#DDD 18px, transparent 0),\n                    linear-gradient(#DDD 66px, transparent 0);\n                background-repeat: no-repeat;\n                background-size: 75px 130px, 55px 56px, 160px 30px, 260px 20px, 290px 56px;\n                background-position: 0% 0, 0 0, 70px 5px, 70px 38px, 0px 66px;\n                box-sizing: border-box;\n                animation: animloader 1s linear infinite;\n            }\n            @keyframes animloader {\n                0% { background-position: 0% 0, 0 0, 70px 5px, 70px 38px, 0px 66px; }\n                100% { background-position: 150% 0, 0 0, 70px 5px, 70px 38px, 0px 66px; }\n            }`\n        });\n\n        // Bars loaders\n        this.register({\n            id: 'bars-wave',\n            css: `.loader {\n                color: #FFF;\n                position: relative;\n                font-size: 11px;\n                background: #FFF;\n                animation: escaleY 1s infinite ease-in-out;\n                width: 1em;\n                height: 4em;\n                animation-delay: -0.16s;\n            }\n            .loader:before, .loader:after {\n                content: '';\n                position: absolute;\n                top: 0;\n                left: 2em;\n                background: #FFF;\n                width: 1em;\n                height: 4em;\n                animation: escaleY 1s infinite ease-in-out;\n            }\n            .loader:before {\n                left: -2em;\n                animation-delay: -0.32s;\n            }\n            @keyframes escaleY {\n                0%, 80%, 100% { box-shadow: 0 0; height: 4em; }\n                40% { box-shadow: 0 -2em; height: 5em; }\n            }`\n        });\n    }\n}\n\n\n// ============================================================================\n// Singleton Export\n// ============================================================================\n\n/** Default LoaderManager instance */\nexport const loaderManager = new LoaderManager();\n\nexport default LoaderManager;\n","// ============================================================================\n// move.gl | Main Entry Point\n// ============================================================================\n// Copyright 2025 Scape Agency BV\n// Licensed under MIT License\n// ============================================================================\n\n/**\n * move.gl - Motion & Animation Library\n *\n * A comprehensive TypeScript/SCSS library for creating interactive\n * motion effects, gestures, and animations for web applications.\n */\n\n// Core Components\nexport { Draggable } from './Draggable.js';\nexport type { DraggableOptions } from './Draggable.js';\n\nexport { Screensaver } from './Screensaver.js';\nexport type { ScreensaverOptions } from './Screensaver.js';\n\nexport { VirtualKeyboard } from './Keyboard.js';\nexport type { KeyboardLayout, VirtualKeyboardOptions } from './Keyboard.js';\n\nexport {\n    AdvancedGestureRecognition, TouchGestureHandler\n} from './Gesture.js';\nexport type {\n    GestureCallbacks,\n    PointerGestureCallbacks, SwipeDirection\n} from './Gesture.js';\n\nexport {\n    getOptimalVideoSource, supportsHEVCAlpha, TransparentVideoOverlay\n} from './VideoOverlay.js';\nexport type { VideoOverlayOptions } from './VideoOverlay.js';\n\n// Loader Management\nexport { LoaderManager, loaderManager } from './LoaderManager.js';\nexport type { LoaderCategory, LoaderConfig, LoaderOptions } from './LoaderManager.js';\n\n// Re-export default classes\nimport { Draggable } from './Draggable.js';\nimport { AdvancedGestureRecognition, TouchGestureHandler } from './Gesture.js';\nimport { VirtualKeyboard } from './Keyboard.js';\nimport { LoaderManager } from './LoaderManager.js';\nimport { Screensaver } from './Screensaver.js';\nimport { TransparentVideoOverlay } from './VideoOverlay.js';\n\nexport default {\n    Draggable,\n    LoaderManager,\n    Screensaver,\n    VirtualKeyboard,\n    TouchGestureHandler,\n    AdvancedGestureRecognition,\n    TransparentVideoOverlay,\n};\n"],"mappings":"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","names":[]}