zoomora 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zoomora.es.js","sources":["../src/zoomora.js"],"sourcesContent":["/*!\n * Zoomora Lightbox Plugin v1.0.0\n * A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features\n *\n * Copyright (c) 2025 Faruk Ahmed (FrontTheme)\n * Licensed under MIT License\n */\n\n// Import styles\nimport './styles/zoomora.scss';\n\n(function (global, factory) {\n 'use strict';\n\n if (typeof module === 'object' && typeof module.exports === 'object') {\n // CommonJS/Node.js\n module.exports = factory();\n } else if (typeof define === 'function' && define.amd) {\n // AMD\n define(factory);\n } else {\n // Browser globals\n global.Zoomora = factory();\n }\n}(typeof window !== 'undefined' ? window : this, function () {\n 'use strict';\n\n /**\n * Zoomora Lightbox Plugin\n * @class\n */\n class Zoomora {\n /**\n * Default configuration options\n * @type {Object}\n */\n static get defaults() {\n return {\n selector: '[data-zoomora]',\n showCounter: true,\n showThumbnails: true,\n showFullscreen: true,\n showZoom: true,\n transition: 'fade', // 'fade' or 'slide'\n useHref: false, // Use href instead of data-src\n maxZoomScale: 3, // Maximum zoom scale\n zoomStep: 0.1, // Zoom step for scroll wheel\n animationDuration: 300, // Animation duration in ms\n onOpen: null, // Callback when lightbox opens\n onClose: null, // Callback when lightbox closes\n onNext: null, // Callback when navigating to next item\n onPrev: null, // Callback when navigating to previous item\n\n // Auto-hide controls\n showAutoHideToggle: true, // Show auto-hide toggle button\n autoHideDelay: 3000, // Delay in ms before hiding controls\n autoHideEnabled: false, // Default state of auto-hide\n };\n }\n\n /**\n * Constructor\n * @param {Object} options - Configuration options\n */\n constructor(options = {}) {\n this.options = {...Zoomora.defaults, ...options};\n this.currentIndex = 0;\n this.items = [];\n this.isZoomed = false;\n this.isFullscreen = false;\n this.isDragging = false;\n this.thumbnailsVisible = true;\n this.startX = 0;\n this.startY = 0;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n this.isInitialized = false;\n this.eventListeners = new Map();\n\n // Auto-hide controls\n this.autoHideEnabled = false;\n this.autoHideTimeout = null;\n this.autoHideDelay = 3000;\n this.isControlsVisible = true;\n this.idleTimer = null;\n\n // Bound methods for event listeners\n this.boundMethods = {\n handleDocumentClick: this.handleDocumentClick.bind(this),\n handleKeydown: this.handleKeydown.bind(this),\n handleFullscreenChange: this.handleFullscreenChange.bind(this),\n handleZoomoraClick: this.handleZoomoraClick.bind(this),\n handleContentClick: this.handleContentClick.bind(this),\n handleMouseDown: this.handleMouseDown.bind(this),\n handleMouseMove: this.handleMouseMove.bind(this),\n handleMouseUp: this.handleMouseUp.bind(this),\n handleTouchStart: this.handleTouchStart.bind(this),\n handleTouchMove: this.handleTouchMove.bind(this),\n handleTouchEnd: this.handleTouchEnd.bind(this),\n };\n\n this.init();\n }\n\n /**\n * Initialize the plugin\n */\n init() {\n if (this.isInitialized) {\n console.warn('Zoomora: Plugin already initialized');\n return;\n }\n\n try {\n this.createLightbox();\n this.bindEvents();\n\n this.isInitialized = true;\n } catch (error) {\n console.error('Zoomora: Initialization failed', error);\n }\n }\n\n /**\n * Static method to bind to anchor tags with href\n * @param {string} selector - CSS selector\n * @param {Object} options - Configuration options\n * @returns {Zoomora} - New Zoomora instance\n */\n static bind(selector, options = {}) {\n const enhancedOptions = {\n ...options,\n selector: selector,\n useHref: true\n };\n return new Zoomora(enhancedOptions);\n }\n\n /**\n * Create lightbox HTML structure\n */\n createLightbox() {\n // Check if lightbox already exists\n if (document.getElementById('zoomoraLightbox')) {\n console.warn('Zoomora: Lightbox already exists in DOM');\n return;\n }\n\n const zoomoraHTML = `\n <div class=\"zoomora\" id=\"zoomoraLightbox\">\n <div class=\"zoomora-container\">\n <div class=\"zoomora-header\" id=\"zoomoraHeader\">\n <div class=\"zoomora-counter\" id=\"zoomoraCounter\">1 / 1</div>\n <div class=\"zoomora-controls\">\n <button class=\"zoomora-btn\" id=\"zoomoraThumbnailBtn\" title=\"Toggle Thumbnails\">\n <i class=\"zoomorai-thumbnails\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraAutoHideBtn\" title=\"Toggle Auto-Hide Controls\">\n <i class=\"zoomorai-controls-off\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraZoomBtn\" title=\"Zoom\">\n <i class=\"zoomorai-zoom\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraFullscreenBtn\" title=\"Fullscreen\">\n <i class=\"zoomorai-expand\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCollapseBtn\" title=\"Exit Fullscreen\" style=\"display: none;\">\n <i class=\"zoomorai-collapse\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCloseBtn\" title=\"Close\">\n <i class=\"zoomorai-close\"></i>\n </button>\n </div>\n </div>\n \n <div class=\"zoomora-content\" id=\"zoomoraContent\">\n <div class=\"zoomora-loading\" id=\"zoomoraLoading\"></div>\n <div class=\"zoomora-slides-container\" id=\"zoomoraSlidesContainer\"></div>\n </div>\n \n <button class=\"zoomora-nav prev\" id=\"zoomoraPrevBtn\">\n <i class=\"zoomorai-arrow-left\"></i>\n </button>\n <button class=\"zoomora-nav next\" id=\"zoomoraNextBtn\">\n <i class=\"zoomorai-arrow-right\"></i>\n </button>\n \n <div class=\"zoomora-caption\" id=\"zoomoraCaption\"></div>\n <div class=\"zoomora-thumbnails\" id=\"zoomoraThumbs\"></div>\n </div>\n </div>\n `;\n\n document.body.insertAdjacentHTML('beforeend', zoomoraHTML);\n\n // Cache DOM elements\n this.zoomora = document.getElementById('zoomoraLightbox');\n this.header = document.getElementById('zoomoraHeader');\n this.content = document.getElementById('zoomoraContent');\n this.slidesContainer = document.getElementById('zoomoraSlidesContainer');\n this.counter = document.getElementById('zoomoraCounter');\n this.thumbs = document.getElementById('zoomoraThumbs');\n this.loading = document.getElementById('zoomoraLoading');\n this.caption = document.getElementById('zoomoraCaption');\n this.prevBtn = document.getElementById('zoomoraPrevBtn');\n this.nextBtn = document.getElementById('zoomoraNextBtn');\n\n // Verify all elements were created\n if (!this.zoomora || !this.content || !this.counter || !this.thumbs || !this.loading || !this.caption) {\n throw new Error('Failed to create required DOM elements');\n }\n }\n\n /**\n * Bind event listeners\n */\n bindEvents() {\n // Document click handler for opening lightbox\n this.addEventListener(document, 'click', this.boundMethods.handleDocumentClick);\n\n // Control button handlers\n this.addEventListener(document.getElementById('zoomoraCloseBtn'), 'click', () => this.close());\n this.addEventListener(document.getElementById('zoomoraPrevBtn'), 'click', () => this.prev());\n this.addEventListener(document.getElementById('zoomoraNextBtn'), 'click', () => this.next());\n this.addEventListener(document.getElementById('zoomoraZoomBtn'), 'click', () => this.toggleZoom());\n this.addEventListener(document.getElementById('zoomoraFullscreenBtn'), 'click', () => this.toggleFullscreen());\n this.addEventListener(document.getElementById('zoomoraCollapseBtn'), 'click', () => this.exitFullscreen());\n this.addEventListener(document.getElementById('zoomoraThumbnailBtn'), 'click', () => this.toggleThumbnails());\n\n // Fullscreen change events\n this.addEventListener(document, 'fullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'webkitfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'mozfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'MSFullscreenChange', this.boundMethods.handleFullscreenChange);\n\n // Keyboard navigation\n this.addEventListener(document, 'keydown', this.boundMethods.handleKeydown);\n\n // Lightbox click to close\n this.addEventListener(this.zoomora, 'click', this.boundMethods.handleZoomoraClick);\n\n // Content click for zoom toggle\n this.addEventListener(this.content, 'click', this.boundMethods.handleContentClick);\n\n // Mouse drag events\n this.addEventListener(this.content, 'mousedown', this.boundMethods.handleMouseDown);\n this.addEventListener(this.content, 'mousemove', this.boundMethods.handleMouseMove);\n this.addEventListener(this.content, 'mouseup', this.boundMethods.handleMouseUp);\n this.addEventListener(this.content, 'mouseleave', this.boundMethods.handleMouseUp);\n\n // Touch events\n this.addEventListener(this.content, 'touchstart', this.boundMethods.handleTouchStart, {passive: false});\n this.addEventListener(this.content, 'touchmove', this.boundMethods.handleTouchMove, {passive: false});\n this.addEventListener(this.content, 'touchend', this.boundMethods.handleTouchEnd);\n\n // Add auto-hide toggle button handler\n this.addEventListener(document.getElementById('zoomoraAutoHideBtn'), 'click', () => this.toggleAutoHide());\n\n // Add mouse/touch activity listeners for auto-hide\n this.addEventListener(this.zoomora, 'mousemove', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'touchstart', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'keydown', () => this.handleUserActivity());\n }\n\n /**\n * Add event listener with cleanup tracking\n * @param {Element} element - DOM element\n * @param {string} event - Event type\n * @param {Function} handler - Event handler\n * @param {Object} options - Event options\n */\n addEventListener(element, event, handler, options = {}) {\n if (!element) return;\n\n element.addEventListener(event, handler, options);\n\n // Track for cleanup\n const key = `${element.constructor.name}_${event}`;\n if (!this.eventListeners.has(key)) {\n this.eventListeners.set(key, []);\n }\n this.eventListeners.get(key).push({element, event, handler, options});\n }\n\n /**\n * Handle document click events\n * @param {Event} e - Click event\n */\n handleDocumentClick(e) {\n const target = e.target.closest(this.options.selector);\n if (target) {\n e.preventDefault();\n this.open(target);\n }\n }\n\n /**\n * Handle keyboard events\n * @param {KeyboardEvent} e - Keyboard event\n */\n handleKeydown(e) {\n if (!this.zoomora.classList.contains('active')) return;\n\n switch (e.key) {\n case 'Escape':\n if (this.isFullscreen) {\n this.exitFullscreen();\n } else {\n this.close();\n }\n break;\n case 'ArrowLeft':\n this.prev();\n break;\n case 'ArrowRight':\n this.next();\n break;\n case 'z':\n case 'Z':\n this.toggleZoom();\n break;\n case 'f':\n case 'F':\n this.toggleFullscreen();\n break;\n case 't':\n case 'T':\n this.toggleThumbnails();\n break;\n }\n }\n\n /**\n * Handle fullscreen change events\n */\n handleFullscreenChange() {\n const isInFullscreen = document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement;\n\n if (!isInFullscreen && this.isFullscreen) {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n }\n\n /**\n * Handle zoomora container clicks\n * @param {Event} e - Click event\n */\n handleZoomoraClick(e) {\n if (e.target === this.zoomora) {\n this.close();\n }\n }\n\n /**\n * Handle content clicks\n * @param {Event} e - Click event\n */\n handleContentClick(e) {\n const media = e.target.closest('.zoomora-media');\n if (media && !media.classList.contains('no-zoom') && !this.isDragging) {\n this.toggleZoom();\n }\n }\n\n /**\n * Handle mouse down events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseDown(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle mouse move events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle mouse up events\n */\n handleMouseUp() {\n this.endDrag();\n }\n\n /**\n * Handle touch start events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchStart(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle touch move events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle touch end events\n */\n handleTouchEnd() {\n this.endDrag();\n }\n\n /**\n * Get image source from element\n * @param {Element} item - DOM element\n * @returns {string} - Image source URL\n */\n getImageSource(item) {\n const src = item.dataset.src || item.src || item.getAttribute('src');\n const type = item.dataset.type || 'image';\n\n // Handle YouTube URLs for video types\n if (type === 'video' && src) {\n return this.convertToEmbedUrl(src);\n }\n\n return src;\n }\n\n /**\n * Convert YouTube URLs to embed format\n * @param url\n * @returns {*|string}\n */\n convertToEmbedUrl(url) {\n // If already an embed URL, return as is\n if (url.includes('youtube.com/embed/')) {\n return url;\n }\n\n // Handle different YouTube URL formats\n let videoId = null;\n let startTime = null;\n\n // Extract video ID and start time from different YouTube URL formats\n if (url.includes('youtube.com/watch')) {\n const urlParams = new URLSearchParams(url.split('?')[1]);\n videoId = urlParams.get('v');\n const t = urlParams.get('t');\n if (t) {\n // Convert time format (e.g., \"111s\" to seconds)\n startTime = t.replace('s', '');\n }\n } else if (url.includes('youtu.be/')) {\n const parts = url.split('/');\n const videoAndParams = parts[parts.length - 1];\n if (videoAndParams.includes('?')) {\n videoId = videoAndParams.split('?')[0];\n const urlParams = new URLSearchParams(videoAndParams.split('?')[1]);\n const t = urlParams.get('t');\n if (t) startTime = t.replace('s', '');\n } else {\n videoId = videoAndParams;\n }\n }\n\n if (videoId) {\n let embedUrl = `https://www.youtube.com/embed/${videoId}`;\n const params = new URLSearchParams();\n\n if (startTime) {\n params.append('start', startTime);\n }\n\n // Add other useful parameters\n params.append('rel', '0'); // Don't show related videos\n params.append('modestbranding', '1'); // Modest branding\n\n // Option: Add autoplay for YouTube videos (uncomment if desired)\n // params.append('autoplay', '1');\n\n if (params.toString()) {\n embedUrl += '?' + params.toString();\n }\n\n return embedUrl;\n }\n\n // If not a YouTube URL or couldn't parse, return original\n return url;\n }\n\n /**\n * Get thumbnail source from element\n * @param {Element} item - DOM element\n * @returns {string} - Thumbnail source URL\n */\n getThumbnailSource(item) {\n const type = item.dataset.type || 'image';\n\n // For video items, always use the img.src as thumbnail (poster image)\n if (type === 'video') {\n return item.src || item.getAttribute('src');\n }\n\n // For regular images, use data-src or fallback to src\n return item.dataset.src || item.src || item.getAttribute('src');\n }\n\n /**\n * Get group identifier from element\n * @param {Element} element - DOM element\n * @returns {string} - Group identifier\n */\n getGroup(element) {\n if (this.options.useHref) {\n return element.dataset.lightbox || element.dataset.gallery || 'default';\n }\n return element.dataset.zoomora || 'default';\n }\n\n /**\n * Open lightbox with specified element\n * @param {Element} element - DOM element to open\n */\n open(element) {\n if (!element) return;\n\n const group = this.getGroup(element);\n let groupSelector;\n\n if (this.options.useHref) {\n if (element.dataset.lightbox) {\n groupSelector = `[data-lightbox=\"${group}\"]`;\n } else if (element.dataset.gallery) {\n groupSelector = `[data-gallery=\"${group}\"]`;\n } else {\n groupSelector = this.options.selector;\n }\n } else {\n groupSelector = `[data-zoomora=\"${group}\"]`;\n }\n\n this.items = Array.from(document.querySelectorAll(groupSelector));\n this.currentIndex = Math.max(0, this.items.indexOf(element));\n\n // Reset states\n this.isZoomed = false;\n this.isFullscreen = false;\n this.thumbnailsVisible = true;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n this.zoomora.classList.add('active');\n document.body.style.overflow = 'hidden';\n\n this.loadContent();\n this.updateThumbnails();\n this.updateCounter();\n this.updateNavigation();\n this.updateCaption();\n this.updateButtons();\n\n // Initialize auto-hide if enabled\n if (this.autoHideEnabled) {\n this.startAutoHideTimer();\n } else {\n this.showControls();\n }\n\n // Trigger callback\n if (typeof this.options.onOpen === 'function') {\n this.options.onOpen(element, this.currentIndex);\n }\n }\n\n /**\n * Close lightbox\n */\n close() {\n if (this.isFullscreen) {\n this.exitFullscreen();\n }\n\n this.zoomora.classList.remove('active');\n document.body.style.overflow = '';\n this.isZoomed = false;\n this.isFullscreen = false;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n const media = this.content.querySelector('.zoomora-media');\n if (media) {\n media.classList.remove('zoomed');\n media.style.transform = '';\n media.style.cursor = '';\n }\n\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n this.showControls();\n\n // Trigger callback\n if (typeof this.options.onClose === 'function') {\n this.options.onClose(this.currentIndex);\n }\n }\n\n /**\n * Navigate to previous item\n */\n prev() {\n if (this.currentIndex > 0) {\n this.currentIndex--;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onPrev === 'function') {\n this.options.onPrev(this.currentIndex);\n }\n }\n }\n\n /**\n * Navigate to next item\n */\n next() {\n if (this.currentIndex < this.items.length - 1) {\n this.currentIndex++;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onNext === 'function') {\n this.options.onNext(this.currentIndex);\n }\n }\n }\n\n /**\n * Load content for current item\n */\n loadContent() {\n if (!this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const src = this.getImageSource(item);\n const type = item.dataset.type || 'image';\n\n if (!src) {\n console.error('Zoomora: No source found for item');\n return;\n }\n\n // Show loading spinner\n this.loading.style.display = 'block';\n\n // Clear content but keep the loading reference intact\n // Don't replace innerHTML, just clear the slides\n if (this.slidesContainer) {\n this.slidesContainer.innerHTML = '';\n }\n\n // Add slight delay for smooth transition\n setTimeout(() => {\n this.renderContent(src, type, item);\n }, 100);\n }\n\n /**\n * Render content based on type\n * @param {string} src - Source URL\n * @param {string} type - Content type\n * @param {Element} item - Original item element\n */\n renderContent(src, type, item) {\n const slideContainer = document.createElement('div');\n slideContainer.className = 'zoomora-slide-container';\n\n // Create slide wrapper\n const slide = document.createElement('div');\n slide.className = `zoomora-slide ${this.options.transition === 'slide' ? 'slide-effect' : 'fade-effect'}`;\n slide.style.opacity = '0';\n slide.style.transform = this.options.transition === 'slide' ? 'translateX(100%)' : 'scale(0.8)';\n\n let mediaElement;\n\n try {\n switch (type) {\n case 'video':\n if (src.endsWith('.mp4') || src.endsWith('.webm') || src.endsWith('.ogg')) {\n const videoContainer = document.createElement('div');\n videoContainer.className = 'zoomora-video-container';\n\n mediaElement = document.createElement('video');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('preload', 'metadata');\n\n const posterSrc = item.src || item.getAttribute('src');\n if (posterSrc) {\n mediaElement.setAttribute('poster', posterSrc);\n }\n\n const playButton = document.createElement('div');\n playButton.className = 'zoomora-play-button';\n playButton.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>`;\n\n playButton.addEventListener('click', () => {\n mediaElement.play();\n playButton.style.display = 'none';\n mediaElement.setAttribute('controls', '');\n });\n\n mediaElement.addEventListener('ended', () => {\n playButton.style.display = 'flex';\n });\n\n videoContainer.appendChild(mediaElement);\n videoContainer.appendChild(playButton);\n slideContainer.appendChild(videoContainer);\n } else {\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('allowfullscreen', '');\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n }\n break;\n\n case 'iframe':\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-iframe';\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n break;\n\n default:\n mediaElement = document.createElement('img');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-media';\n mediaElement.alt = item.alt || item.title || '';\n\n mediaElement.onload = () => {\n this.loading.style.display = 'none';\n this.checkZoomability(mediaElement);\n this.animateSlideIn(slide);\n };\n\n mediaElement.onerror = () => {\n this.loading.style.display = 'none';\n console.error('Zoomora: Failed to load image:', src);\n this.animateSlideIn(slide);\n };\n\n slideContainer.appendChild(mediaElement);\n }\n\n slide.appendChild(slideContainer);\n\n // Clear existing slides and add new one\n this.slidesContainer.innerHTML = '';\n this.slidesContainer.appendChild(slide);\n\n if (type !== 'image') {\n this.loading.style.display = 'none';\n this.animateSlideIn(slide);\n }\n\n } catch (error) {\n console.error('Zoomora: Error rendering content:', error);\n this.loading.style.display = 'none';\n }\n }\n\n // Animation helper\n animateSlideIn(slide) {\n // Force reflow\n slide.offsetHeight;\n\n // Add active class and animate\n slide.classList.add('active');\n\n if (this.options.transition === 'slide') {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'translateX(0)';\n slide.style.opacity = '1';\n } else {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'scale(1)';\n slide.style.opacity = '1';\n }\n }\n\n // Toggle auto-hide controls\n toggleAutoHide() {\n this.autoHideEnabled = !this.autoHideEnabled;\n const autoHideBtn = document.getElementById('zoomoraAutoHideBtn');\n\n if (this.autoHideEnabled) {\n autoHideBtn.classList.add('active');\n autoHideBtn.title = 'Disable Auto-Hide Controls';\n this.startAutoHideTimer();\n } else {\n autoHideBtn.classList.remove('active');\n autoHideBtn.title = 'Enable Auto-Hide Controls';\n this.stopAutoHideTimer();\n this.showControls();\n }\n }\n\n // Handle user activity\n handleUserActivity() {\n if (!this.autoHideEnabled) return;\n\n this.showControls();\n this.startAutoHideTimer();\n }\n\n // Start auto-hide timer\n startAutoHideTimer() {\n this.stopAutoHideTimer();\n\n this.autoHideTimeout = setTimeout(() => {\n this.hideControls();\n }, this.options.autoHideDelay);\n }\n\n // Stop auto-hide timer\n stopAutoHideTimer() {\n if (this.autoHideTimeout) {\n clearTimeout(this.autoHideTimeout);\n this.autoHideTimeout = null;\n }\n }\n\n // Show controls\n showControls() {\n if (this.isControlsVisible) return;\n\n this.isControlsVisible = true;\n this.zoomora.classList.remove('controls-hidden');\n\n // Animate controls back in\n if (this.header) {\n this.header.style.transform = 'translateY(0)';\n this.header.style.opacity = '1';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(0)';\n this.thumbs.style.opacity = '1';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(0)';\n this.prevBtn.style.opacity = '1';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(0)';\n this.nextBtn.style.opacity = '1';\n }\n }\n\n // Hide controls\n hideControls() {\n if (!this.isControlsVisible) return;\n\n this.isControlsVisible = false;\n this.zoomora.classList.add('controls-hidden');\n\n // Animate controls out\n if (this.header) {\n this.header.style.transform = 'translateY(-100%)';\n this.header.style.opacity = '0';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(100%)';\n this.thumbs.style.opacity = '0';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(-100%)';\n this.prevBtn.style.opacity = '0';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(100%)';\n this.nextBtn.style.opacity = '0';\n }\n }\n\n /**\n * Check if image can be zoomed\n * @param {HTMLImageElement} img - Image element\n */\n checkZoomability(img) {\n if (!img || !img.naturalWidth || !img.naturalHeight) return;\n\n const imgRect = img.getBoundingClientRect();\n const renderedWidth = imgRect.width;\n const renderedHeight = imgRect.height;\n const naturalWidth = img.naturalWidth;\n const naturalHeight = img.naturalHeight;\n\n const isScaledDown = naturalWidth > renderedWidth || naturalHeight > renderedHeight;\n const zoomRatioX = naturalWidth / renderedWidth;\n const zoomRatioY = naturalHeight / renderedHeight;\n const maxZoomRatio = Math.max(zoomRatioX, zoomRatioY);\n\n // Store zoom info\n img.dataset.zoomRatio = maxZoomRatio;\n img.dataset.naturalWidth = naturalWidth;\n img.dataset.naturalHeight = naturalHeight;\n img.dataset.renderedWidth = renderedWidth;\n img.dataset.renderedHeight = renderedHeight;\n\n // Enable zoom if significantly scaled down\n if (isScaledDown && maxZoomRatio > 1.1) {\n img.classList.remove('no-zoom');\n } else {\n img.classList.add('no-zoom');\n }\n }\n\n /**\n * Update counter display\n */\n updateCounter() {\n if (this.options.showCounter && this.counter) {\n this.counter.textContent = `${this.currentIndex + 1} / ${this.items.length}`;\n }\n }\n\n /**\n * Update caption display\n */\n updateCaption() {\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption) {\n this.caption.textContent = caption;\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n this.caption.style.pointerEvents = 'auto';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n this.caption.style.pointerEvents = 'none';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n }\n }\n\n /**\n * Update thumbnails display\n */\n updateThumbnails() {\n if (!this.options.showThumbnails || !this.thumbs) return;\n\n if (this.items.length === 1) {\n this.caption.classList.add('single-item-thumbnail');\n this.thumbs.style.display = 'none';\n return;\n }\n\n this.caption.classList.remove('single-item-thumbnail');\n\n this.thumbs.style.display = 'flex';\n this.thumbs.innerHTML = '';\n\n this.items.forEach((item, index) => {\n const thumb = document.createElement('div');\n thumb.className = 'zoomora-thumb';\n if (index === this.currentIndex) thumb.classList.add('active');\n\n const img = document.createElement('img');\n const thumbSrc = this.getThumbnailSource(item);\n\n if (thumbSrc) {\n img.src = thumbSrc;\n img.alt = item.alt || item.title || '';\n img.onerror = () => {\n thumb.style.display = 'none';\n };\n }\n\n thumb.appendChild(img);\n\n thumb.addEventListener('click', () => {\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n });\n\n this.thumbs.appendChild(thumb);\n });\n }\n\n /**\n * Update navigation buttons\n */\n updateNavigation() {\n const prevBtn = document.getElementById('zoomoraPrevBtn');\n const nextBtn = document.getElementById('zoomoraNextBtn');\n\n if (prevBtn) {\n prevBtn.style.display = this.currentIndex > 0 ? 'flex' : 'none';\n }\n if (nextBtn) {\n nextBtn.style.display = this.currentIndex < this.items.length - 1 ? 'flex' : 'none';\n }\n }\n\n /**\n * Update control buttons\n */\n updateButtons() {\n const fullscreenBtn = document.getElementById('zoomoraFullscreenBtn');\n const collapseBtn = document.getElementById('zoomoraCollapseBtn');\n\n if (fullscreenBtn && collapseBtn) {\n if (this.isFullscreen) {\n fullscreenBtn.style.display = 'none';\n collapseBtn.style.display = 'flex';\n } else {\n fullscreenBtn.style.display = 'flex';\n collapseBtn.style.display = 'none';\n }\n }\n }\n\n /**\n * Toggle zoom state\n */\n toggleZoom() {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || media.tagName !== 'IMG' || media.classList.contains('no-zoom')) return;\n\n this.isZoomed = !this.isZoomed;\n media.classList.toggle('zoomed', this.isZoomed);\n\n if (this.isZoomed) {\n const zoomRatio = parseFloat(media.dataset.zoomRatio) || 2;\n let zoomScale = Math.min(zoomRatio, this.options.maxZoomScale);\n\n if (zoomRatio > 2.5) {\n zoomScale = Math.min(zoomRatio * 0.7, 2.5);\n }\n\n media.style.transform = `scale(${zoomScale})`;\n media.style.cursor = 'grab';\n media.dataset.currentZoomScale = zoomScale;\n this.currentScale = zoomScale;\n } else {\n media.style.transform = '';\n media.style.cursor = '';\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n }\n }\n\n /**\n * Toggle fullscreen mode\n */\n toggleFullscreen() {\n if (!this.isFullscreen) {\n this.enterFullscreen();\n } else {\n this.exitFullscreen();\n }\n }\n\n /**\n * Enter fullscreen mode\n */\n enterFullscreen() {\n const element = this.zoomora;\n const requestFullscreen = element.requestFullscreen ||\n element.webkitRequestFullscreen ||\n element.mozRequestFullScreen ||\n element.msRequestFullscreen;\n\n if (requestFullscreen) {\n requestFullscreen.call(element).then(() => {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }).catch(err => {\n console.warn('Zoomora: Could not enter fullscreen:', err);\n this.fallbackFullscreen();\n });\n } else {\n this.fallbackFullscreen();\n }\n }\n\n /**\n * Exit fullscreen mode\n */\n exitFullscreen() {\n const isInFullscreen = document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement;\n\n if (isInFullscreen) {\n const exitFullscreen = document.exitFullscreen ||\n document.webkitExitFullscreen ||\n document.mozCancelFullScreen ||\n document.msExitFullscreen;\n\n if (exitFullscreen) {\n exitFullscreen.call(document).then(() => {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }).catch(err => {\n console.warn('Zoomora: Could not exit fullscreen:', err);\n this.fallbackExitFullscreen();\n });\n } else {\n this.fallbackExitFullscreen();\n }\n } else {\n this.fallbackExitFullscreen();\n }\n }\n\n /**\n * Fallback fullscreen using CSS\n */\n fallbackFullscreen() {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Exit CSS fullscreen\n */\n fallbackExitFullscreen() {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Toggle thumbnails visibility\n */\n toggleThumbnails() {\n if (this.items.length === 1) return;\n\n this.thumbnailsVisible = !this.thumbnailsVisible;\n if (this.thumbs) {\n this.thumbs.classList.toggle('thumbs-hidden', !this.thumbnailsVisible);\n\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption && this.thumbs.classList.contains('thumbs-hidden')) {\n this.caption.style.bottom = '20px';\n this.caption.style.transition = 'bottom 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.bottom = '120px';\n }\n }\n }\n\n /**\n * Start drag operation\n * @param {Event} e - Mouse or touch event\n */\n startDrag(e) {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || !this.isZoomed) return;\n\n this.isDragging = true;\n media.style.cursor = 'grabbing';\n\n this.startX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n this.startY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n // Parse current transform\n const transform = media.style.transform;\n const scaleMatch = transform.match(/scale\\(([^)]+)\\)/);\n const translateMatch = transform.match(/translate\\(([^,]+),\\s*([^)]+)\\)/);\n\n this.currentScale = scaleMatch ? parseFloat(scaleMatch[1]) : 1;\n this.currentX = translateMatch ? parseFloat(translateMatch[1]) : 0;\n this.currentY = translateMatch ? parseFloat(translateMatch[2]) : 0;\n\n e.preventDefault();\n }\n\n /**\n * Handle drag movement\n * @param {Event} e - Mouse or touch event\n */\n drag(e) {\n if (!this.isDragging) return;\n\n e.preventDefault();\n const clientX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n const clientY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n const deltaX = clientX - this.startX;\n const deltaY = clientY - this.startY;\n\n const newX = this.currentX + deltaX;\n const newY = this.currentY + deltaY;\n\n const media = this.content.querySelector('.zoomora-media');\n if (!media) return;\n\n const mediaRect = media.getBoundingClientRect();\n const scale = this.currentScale;\n const maxX = (mediaRect.width * (scale - 1)) / 2;\n const maxY = (mediaRect.height * (scale - 1)) / 2;\n\n const constrainedX = Math.max(-maxX, Math.min(maxX, newX));\n const constrainedY = Math.max(-maxY, Math.min(maxY, newY));\n\n media.style.transform = `scale(${scale}) translate(${constrainedX}px, ${constrainedY}px)`;\n }\n\n /**\n * End drag operation\n */\n endDrag() {\n if (!this.isDragging) return;\n\n this.isDragging = false;\n const media = this.content.querySelector('.zoomora-media');\n if (media && this.isZoomed) {\n media.style.cursor = 'grab';\n }\n }\n\n /**\n * Go to specific item by index\n * @param {number} index - Item index\n */\n goTo(index) {\n if (index < 0 || index >= this.items.length) return;\n\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n }\n\n /**\n * Get current item index\n * @returns {number} - Current index\n */\n getCurrentIndex() {\n return this.currentIndex;\n }\n\n /**\n * Get total number of items\n * @returns {number} - Total items\n */\n getTotalItems() {\n return this.items.length;\n }\n\n /**\n * Check if lightbox is open\n * @returns {boolean} - True if open\n */\n isOpen() {\n return this.zoomora && this.zoomora.classList.contains('active');\n }\n\n /**\n * Update options\n * @param {Object} newOptions - New options to merge\n */\n updateOptions(newOptions) {\n this.options = {...this.options, ...newOptions};\n }\n\n /**\n * Refresh the lightbox (re-scan for items)\n */\n refresh() {\n if (this.isOpen()) {\n const currentItem = this.items[this.currentIndex];\n if (currentItem) {\n this.open(currentItem);\n }\n }\n }\n\n /**\n * Destroy the lightbox instance\n */\n destroy() {\n if (!this.isInitialized) return;\n\n // Close if open\n if (this.isOpen()) {\n this.close();\n }\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n\n // Remove all event listeners\n this.eventListeners.forEach((listeners, key) => {\n listeners.forEach(({element, event, handler, options}) => {\n if (element && element.removeEventListener) {\n element.removeEventListener(event, handler, options);\n }\n });\n });\n this.eventListeners.clear();\n\n // Remove DOM elements\n if (this.zoomora && this.zoomora.parentNode) {\n this.zoomora.parentNode.removeChild(this.zoomora);\n }\n\n // Reset properties\n this.isInitialized = false;\n this.items = [];\n this.currentIndex = 0;\n this.zoomora = null;\n this.content = null;\n this.counter = null;\n this.thumbs = null;\n this.loading = null;\n this.caption = null;\n }\n }\n\n // Export the class\n return Zoomora;\n}));"],"names":["this"],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ var t,e,s=Object.defineProperty,o=Object.defineProperties,i=Object.getOwnPropertyDescriptors,n=Object.getOwnPropertyNames,a=Object.getOwnPropertySymbols,r=Object.prototype.hasOwnProperty,l=Object.prototype.propertyIsEnumerable,h=(t,e,o)=>e in t?s(t,e,{enumerable:!0,configurable:!0,writable:!0,value:o}):t[e]=o,d=(t,e)=>{for(var s in e||(e={}))r.call(e,s)&&h(t,s,e[s]);if(a)for(var s of a(e))l.call(e,s)&&h(t,s,e[s]);return t},c=(t={"zoomora.es.min.js"(t,e){
2
+ /*!
3
+ * Zoomora Lightbox Plugin v1.0.0
4
+ * A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features
5
+ *
6
+ * Copyright (c) 2025 Faruk Ahmed (FrontTheme)
7
+ * Licensed under MIT License
8
+ */
9
+ var s,n;s="undefined"!=typeof window?window:void 0,n=function(){class t{static get defaults(){return{selector:"[data-zoomora]",showCounter:!0,showThumbnails:!0,showFullscreen:!0,showZoom:!0,transition:"fade",useHref:!1,maxZoomScale:3,zoomStep:.1,animationDuration:300,onOpen:null,onClose:null,onNext:null,onPrev:null,showAutoHideToggle:!0,autoHideDelay:3e3,autoHideEnabled:!1}}constructor(e={}){this.options=d(d({},t.defaults),e),this.currentIndex=0,this.items=[],this.isZoomed=!1,this.isFullscreen=!1,this.isDragging=!1,this.thumbnailsVisible=!0,this.startX=0,this.startY=0,this.currentX=0,this.currentY=0,this.currentScale=1,this.isInitialized=!1,this.eventListeners=new Map,this.autoHideEnabled=!1,this.autoHideTimeout=null,this.autoHideDelay=3e3,this.isControlsVisible=!0,this.idleTimer=null,this.boundMethods={handleDocumentClick:this.handleDocumentClick.bind(this),handleKeydown:this.handleKeydown.bind(this),handleFullscreenChange:this.handleFullscreenChange.bind(this),handleZoomoraClick:this.handleZoomoraClick.bind(this),handleContentClick:this.handleContentClick.bind(this),handleMouseDown:this.handleMouseDown.bind(this),handleMouseMove:this.handleMouseMove.bind(this),handleMouseUp:this.handleMouseUp.bind(this),handleTouchStart:this.handleTouchStart.bind(this),handleTouchMove:this.handleTouchMove.bind(this),handleTouchEnd:this.handleTouchEnd.bind(this)},this.init()}init(){if(this.isInitialized)console.warn("Zoomora: Plugin already initialized");else try{this.createLightbox(),this.bindEvents(),this.isInitialized=!0}catch(t){console.error("Zoomora: Initialization failed",t)}}static bind(e,s={}){const n=(a=d({},s),o(a,i({selector:e,useHref:!0})));var a;return new t(n)}createLightbox(){if(document.getElementById("zoomoraLightbox"))console.warn("Zoomora: Lightbox already exists in DOM");else if(document.body.insertAdjacentHTML("beforeend",'\n <div class="zoomora" id="zoomoraLightbox">\n <div class="zoomora-container">\n <div class="zoomora-header" id="zoomoraHeader">\n <div class="zoomora-counter" id="zoomoraCounter">1 / 1</div>\n <div class="zoomora-controls">\n <button class="zoomora-btn" id="zoomoraThumbnailBtn" title="Toggle Thumbnails">\n <i class="zoomorai-thumbnails"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraAutoHideBtn" title="Toggle Auto-Hide Controls">\n <i class="zoomorai-controls-off"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraZoomBtn" title="Zoom">\n <i class="zoomorai-zoom"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraFullscreenBtn" title="Fullscreen">\n <i class="zoomorai-expand"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraCollapseBtn" title="Exit Fullscreen" style="display: none;">\n <i class="zoomorai-collapse"></i>\n </button>\n <button class="zoomora-btn" id="zoomoraCloseBtn" title="Close">\n <i class="zoomorai-close"></i>\n </button>\n </div>\n </div>\n \n <div class="zoomora-content" id="zoomoraContent">\n <div class="zoomora-loading" id="zoomoraLoading"></div>\n <div class="zoomora-slides-container" id="zoomoraSlidesContainer"></div>\n </div>\n \n <button class="zoomora-nav prev" id="zoomoraPrevBtn">\n <i class="zoomorai-arrow-left"></i>\n </button>\n <button class="zoomora-nav next" id="zoomoraNextBtn">\n <i class="zoomorai-arrow-right"></i>\n </button>\n \n <div class="zoomora-caption" id="zoomoraCaption"></div>\n <div class="zoomora-thumbnails" id="zoomoraThumbs"></div>\n </div>\n </div>\n '),this.zoomora=document.getElementById("zoomoraLightbox"),this.header=document.getElementById("zoomoraHeader"),this.content=document.getElementById("zoomoraContent"),this.slidesContainer=document.getElementById("zoomoraSlidesContainer"),this.counter=document.getElementById("zoomoraCounter"),this.thumbs=document.getElementById("zoomoraThumbs"),this.loading=document.getElementById("zoomoraLoading"),this.caption=document.getElementById("zoomoraCaption"),this.prevBtn=document.getElementById("zoomoraPrevBtn"),this.nextBtn=document.getElementById("zoomoraNextBtn"),!(this.zoomora&&this.content&&this.counter&&this.thumbs&&this.loading&&this.caption))throw new Error("Failed to create required DOM elements")}bindEvents(){this.addEventListener(document,"click",this.boundMethods.handleDocumentClick),this.addEventListener(document.getElementById("zoomoraCloseBtn"),"click",()=>this.close()),this.addEventListener(document.getElementById("zoomoraPrevBtn"),"click",()=>this.prev()),this.addEventListener(document.getElementById("zoomoraNextBtn"),"click",()=>this.next()),this.addEventListener(document.getElementById("zoomoraZoomBtn"),"click",()=>this.toggleZoom()),this.addEventListener(document.getElementById("zoomoraFullscreenBtn"),"click",()=>this.toggleFullscreen()),this.addEventListener(document.getElementById("zoomoraCollapseBtn"),"click",()=>this.exitFullscreen()),this.addEventListener(document.getElementById("zoomoraThumbnailBtn"),"click",()=>this.toggleThumbnails()),this.addEventListener(document,"fullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"webkitfullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"mozfullscreenchange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"MSFullscreenChange",this.boundMethods.handleFullscreenChange),this.addEventListener(document,"keydown",this.boundMethods.handleKeydown),this.addEventListener(this.zoomora,"click",this.boundMethods.handleZoomoraClick),this.addEventListener(this.content,"click",this.boundMethods.handleContentClick),this.addEventListener(this.content,"mousedown",this.boundMethods.handleMouseDown),this.addEventListener(this.content,"mousemove",this.boundMethods.handleMouseMove),this.addEventListener(this.content,"mouseup",this.boundMethods.handleMouseUp),this.addEventListener(this.content,"mouseleave",this.boundMethods.handleMouseUp),this.addEventListener(this.content,"touchstart",this.boundMethods.handleTouchStart,{passive:!1}),this.addEventListener(this.content,"touchmove",this.boundMethods.handleTouchMove,{passive:!1}),this.addEventListener(this.content,"touchend",this.boundMethods.handleTouchEnd),this.addEventListener(document.getElementById("zoomoraAutoHideBtn"),"click",()=>this.toggleAutoHide()),this.addEventListener(this.zoomora,"mousemove",()=>this.handleUserActivity()),this.addEventListener(this.zoomora,"touchstart",()=>this.handleUserActivity()),this.addEventListener(this.zoomora,"keydown",()=>this.handleUserActivity())}addEventListener(t,e,s,o={}){if(!t)return;t.addEventListener(e,s,o);const i=`${t.constructor.name}_${e}`;this.eventListeners.has(i)||this.eventListeners.set(i,[]),this.eventListeners.get(i).push({element:t,event:e,handler:s,options:o})}handleDocumentClick(t){const e=t.target.closest(this.options.selector);e&&(t.preventDefault(),this.open(e))}handleKeydown(t){if(this.zoomora.classList.contains("active"))switch(t.key){case"Escape":this.isFullscreen?this.exitFullscreen():this.close();break;case"ArrowLeft":this.prev();break;case"ArrowRight":this.next();break;case"z":case"Z":this.toggleZoom();break;case"f":case"F":this.toggleFullscreen();break;case"t":case"T":this.toggleThumbnails()}}handleFullscreenChange(){!(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement)&&this.isFullscreen&&(this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons())}handleZoomoraClick(t){t.target===this.zoomora&&this.close()}handleContentClick(t){const e=t.target.closest(".zoomora-media");!e||e.classList.contains("no-zoom")||this.isDragging||this.toggleZoom()}handleMouseDown(t){this.startDrag(t)}handleMouseMove(t){this.drag(t)}handleMouseUp(){this.endDrag()}handleTouchStart(t){this.startDrag(t)}handleTouchMove(t){this.drag(t)}handleTouchEnd(){this.endDrag()}getImageSource(t){const e=t.dataset.src||t.src||t.getAttribute("src");return"video"===(t.dataset.type||"image")&&e?this.convertToEmbedUrl(e):e}convertToEmbedUrl(t){if(t.includes("youtube.com/embed/"))return t;let e=null,s=null;if(t.includes("youtube.com/watch")){const o=new URLSearchParams(t.split("?")[1]);e=o.get("v");const i=o.get("t");i&&(s=i.replace("s",""))}else if(t.includes("youtu.be/")){const o=t.split("/"),i=o[o.length-1];if(i.includes("?")){e=i.split("?")[0];const t=new URLSearchParams(i.split("?")[1]).get("t");t&&(s=t.replace("s",""))}else e=i}if(e){let t=`https://www.youtube.com/embed/${e}`;const o=new URLSearchParams;return s&&o.append("start",s),o.append("rel","0"),o.append("modestbranding","1"),o.toString()&&(t+="?"+o.toString()),t}return t}getThumbnailSource(t){return"video"===(t.dataset.type||"image")?t.src||t.getAttribute("src"):t.dataset.src||t.src||t.getAttribute("src")}getGroup(t){return this.options.useHref?t.dataset.lightbox||t.dataset.gallery||"default":t.dataset.zoomora||"default"}open(t){if(!t)return;const e=this.getGroup(t);let s;s=this.options.useHref?t.dataset.lightbox?`[data-lightbox="${e}"]`:t.dataset.gallery?`[data-gallery="${e}"]`:this.options.selector:`[data-zoomora="${e}"]`,this.items=Array.from(document.querySelectorAll(s)),this.currentIndex=Math.max(0,this.items.indexOf(t)),this.isZoomed=!1,this.isFullscreen=!1,this.thumbnailsVisible=!0,this.currentX=0,this.currentY=0,this.currentScale=1,this.zoomora.classList.add("active"),document.body.style.overflow="hidden",this.loadContent(),this.updateThumbnails(),this.updateCounter(),this.updateNavigation(),this.updateCaption(),this.updateButtons(),this.autoHideEnabled?this.startAutoHideTimer():this.showControls(),"function"==typeof this.options.onOpen&&this.options.onOpen(t,this.currentIndex)}close(){this.isFullscreen&&this.exitFullscreen(),this.zoomora.classList.remove("active"),document.body.style.overflow="",this.isZoomed=!1,this.isFullscreen=!1,this.currentX=0,this.currentY=0,this.currentScale=1;const t=this.content.querySelector(".zoomora-media");t&&(t.classList.remove("zoomed"),t.style.transform="",t.style.cursor=""),this.zoomora.classList.remove("fullscreen"),this.updateButtons(),this.stopAutoHideTimer(),this.showControls(),"function"==typeof this.options.onClose&&this.options.onClose(this.currentIndex)}prev(){this.currentIndex>0&&(this.currentIndex--,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption(),"function"==typeof this.options.onPrev&&this.options.onPrev(this.currentIndex))}next(){this.currentIndex<this.items.length-1&&(this.currentIndex++,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption(),"function"==typeof this.options.onNext&&this.options.onNext(this.currentIndex))}loadContent(){if(!this.items[this.currentIndex])return;const t=this.items[this.currentIndex],e=this.getImageSource(t),s=t.dataset.type||"image";e?(this.loading.style.display="block",this.slidesContainer&&(this.slidesContainer.innerHTML=""),setTimeout(()=>{this.renderContent(e,s,t)},100)):console.error("Zoomora: No source found for item")}renderContent(t,e,s){const o=document.createElement("div");o.className="zoomora-slide-container";const i=document.createElement("div");let n;i.className="zoomora-slide "+("slide"===this.options.transition?"slide-effect":"fade-effect"),i.style.opacity="0",i.style.transform="slide"===this.options.transition?"translateX(100%)":"scale(0.8)";try{switch(e){case"video":if(t.endsWith(".mp4")||t.endsWith(".webm")||t.endsWith(".ogg")){const e=document.createElement("div");e.className="zoomora-video-container",n=document.createElement("video"),n.src=t,n.className="zoomora-video",n.setAttribute("preload","metadata");const i=s.src||s.getAttribute("src");i&&n.setAttribute("poster",i);const a=document.createElement("div");a.className="zoomora-play-button",a.innerHTML='<svg viewBox="0 0 24 24" fill="currentColor"><path d="M8 5v14l11-7z"/></svg>',a.addEventListener("click",()=>{n.play(),a.style.display="none",n.setAttribute("controls","")}),n.addEventListener("ended",()=>{a.style.display="flex"}),e.appendChild(n),e.appendChild(a),o.appendChild(e)}else n=document.createElement("iframe"),n.src=t,n.className="zoomora-video",n.setAttribute("allowfullscreen",""),n.setAttribute("frameborder","0"),o.appendChild(n);break;case"iframe":n=document.createElement("iframe"),n.src=t,n.className="zoomora-iframe",n.setAttribute("frameborder","0"),o.appendChild(n);break;default:n=document.createElement("img"),n.src=t,n.className="zoomora-media",n.alt=s.alt||s.title||"",n.onload=()=>{this.loading.style.display="none",this.checkZoomability(n),this.animateSlideIn(i)},n.onerror=()=>{this.loading.style.display="none",console.error("Zoomora: Failed to load image:",t),this.animateSlideIn(i)},o.appendChild(n)}i.appendChild(o),this.slidesContainer.innerHTML="",this.slidesContainer.appendChild(i),"image"!==e&&(this.loading.style.display="none",this.animateSlideIn(i))}catch(t){console.error("Zoomora: Error rendering content:",t),this.loading.style.display="none"}}animateSlideIn(t){t.offsetHeight,t.classList.add("active"),"slide"===this.options.transition?(t.style.transition=`transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`,t.style.transform="translateX(0)",t.style.opacity="1"):(t.style.transition=`transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`,t.style.transform="scale(1)",t.style.opacity="1")}toggleAutoHide(){this.autoHideEnabled=!this.autoHideEnabled;const t=document.getElementById("zoomoraAutoHideBtn");this.autoHideEnabled?(t.classList.add("active"),t.title="Disable Auto-Hide Controls",this.startAutoHideTimer()):(t.classList.remove("active"),t.title="Enable Auto-Hide Controls",this.stopAutoHideTimer(),this.showControls())}handleUserActivity(){this.autoHideEnabled&&(this.showControls(),this.startAutoHideTimer())}startAutoHideTimer(){this.stopAutoHideTimer(),this.autoHideTimeout=setTimeout(()=>{this.hideControls()},this.options.autoHideDelay)}stopAutoHideTimer(){this.autoHideTimeout&&(clearTimeout(this.autoHideTimeout),this.autoHideTimeout=null)}showControls(){this.isControlsVisible||(this.isControlsVisible=!0,this.zoomora.classList.remove("controls-hidden"),this.header&&(this.header.style.transform="translateY(0)",this.header.style.opacity="1"),this.caption&&(this.caption.style.transform="translateX(-50%) translateY(0)",this.caption.style.opacity="1"),this.thumbs&&(this.thumbs.style.transform="translateX(-50%) translateY(0)",this.thumbs.style.opacity="1"),this.prevBtn&&(this.prevBtn.style.transform="translateX(0)",this.prevBtn.style.opacity="1"),this.nextBtn&&(this.nextBtn.style.transform="translateX(0)",this.nextBtn.style.opacity="1"))}hideControls(){this.isControlsVisible&&(this.isControlsVisible=!1,this.zoomora.classList.add("controls-hidden"),this.header&&(this.header.style.transform="translateY(-100%)",this.header.style.opacity="0"),this.caption&&(this.caption.style.transform="translateX(-50%) translateY(100%)",this.caption.style.opacity="0"),this.thumbs&&(this.thumbs.style.transform="translateX(-50%) translateY(100%)",this.thumbs.style.opacity="0"),this.prevBtn&&(this.prevBtn.style.transform="translateX(-100%)",this.prevBtn.style.opacity="0"),this.nextBtn&&(this.nextBtn.style.transform="translateX(100%)",this.nextBtn.style.opacity="0"))}checkZoomability(t){if(!t||!t.naturalWidth||!t.naturalHeight)return;const e=t.getBoundingClientRect(),s=e.width,o=e.height,i=t.naturalWidth,n=t.naturalHeight,a=i>s||n>o,r=i/s,l=n/o,h=Math.max(r,l);t.dataset.zoomRatio=h,t.dataset.naturalWidth=i,t.dataset.naturalHeight=n,t.dataset.renderedWidth=s,t.dataset.renderedHeight=o,a&&h>1.1?t.classList.remove("no-zoom"):t.classList.add("no-zoom")}updateCounter(){this.options.showCounter&&this.counter&&(this.counter.textContent=`${this.currentIndex+1} / ${this.items.length}`)}updateCaption(){if(!this.caption||!this.items[this.currentIndex])return;const t=this.items[this.currentIndex],e=t.dataset.caption||t.title||"";e?(this.caption.textContent=e,this.caption.style.transform="translateX(-50%) translateY(0)",this.caption.style.opacity="1",this.caption.style.pointerEvents="auto",this.caption.style.transition="opacity 0.3s ease, transform 0.3s ease"):(this.caption.style.transform="translateX(-50%) translateY(100%)",this.caption.style.opacity="0",this.caption.style.pointerEvents="none",this.caption.style.transition="opacity 0.3s ease, transform 0.3s ease")}updateThumbnails(){if(this.options.showThumbnails&&this.thumbs){if(1===this.items.length)return this.caption.classList.add("single-item-thumbnail"),void(this.thumbs.style.display="none");this.caption.classList.remove("single-item-thumbnail"),this.thumbs.style.display="flex",this.thumbs.innerHTML="",this.items.forEach((t,e)=>{const s=document.createElement("div");s.className="zoomora-thumb",e===this.currentIndex&&s.classList.add("active");const o=document.createElement("img"),i=this.getThumbnailSource(t);i&&(o.src=i,o.alt=t.alt||t.title||"",o.onerror=()=>{s.style.display="none"}),s.appendChild(o),s.addEventListener("click",()=>{this.currentIndex=e,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption()}),this.thumbs.appendChild(s)})}}updateNavigation(){const t=document.getElementById("zoomoraPrevBtn"),e=document.getElementById("zoomoraNextBtn");t&&(t.style.display=this.currentIndex>0?"flex":"none"),e&&(e.style.display=this.currentIndex<this.items.length-1?"flex":"none")}updateButtons(){const t=document.getElementById("zoomoraFullscreenBtn"),e=document.getElementById("zoomoraCollapseBtn");t&&e&&(this.isFullscreen?(t.style.display="none",e.style.display="flex"):(t.style.display="flex",e.style.display="none"))}toggleZoom(){const t=this.content.querySelector(".zoomora-media");if(t&&"IMG"===t.tagName&&!t.classList.contains("no-zoom"))if(this.isZoomed=!this.isZoomed,t.classList.toggle("zoomed",this.isZoomed),this.isZoomed){const e=parseFloat(t.dataset.zoomRatio)||2;let s=Math.min(e,this.options.maxZoomScale);e>2.5&&(s=Math.min(.7*e,2.5)),t.style.transform=`scale(${s})`,t.style.cursor="grab",t.dataset.currentZoomScale=s,this.currentScale=s}else t.style.transform="",t.style.cursor="",this.currentX=0,this.currentY=0,this.currentScale=1}toggleFullscreen(){this.isFullscreen?this.exitFullscreen():this.enterFullscreen()}enterFullscreen(){const t=this.zoomora,e=t.requestFullscreen||t.webkitRequestFullscreen||t.mozRequestFullScreen||t.msRequestFullscreen;e?e.call(t).then(()=>{this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()}).catch(t=>{console.warn("Zoomora: Could not enter fullscreen:",t),this.fallbackFullscreen()}):this.fallbackFullscreen()}exitFullscreen(){if(document.fullscreenElement||document.webkitFullscreenElement||document.mozFullScreenElement||document.msFullscreenElement){const t=document.exitFullscreen||document.webkitExitFullscreen||document.mozCancelFullScreen||document.msExitFullscreen;t?t.call(document).then(()=>{this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()}).catch(t=>{console.warn("Zoomora: Could not exit fullscreen:",t),this.fallbackExitFullscreen()}):this.fallbackExitFullscreen()}else this.fallbackExitFullscreen()}fallbackFullscreen(){this.isFullscreen=!0,this.zoomora.classList.add("fullscreen"),this.updateButtons()}fallbackExitFullscreen(){this.isFullscreen=!1,this.zoomora.classList.remove("fullscreen"),this.updateButtons()}toggleThumbnails(){if(1!==this.items.length&&(this.thumbnailsVisible=!this.thumbnailsVisible,this.thumbs)){if(this.thumbs.classList.toggle("thumbs-hidden",!this.thumbnailsVisible),!this.caption||!this.items[this.currentIndex])return;const t=this.items[this.currentIndex];(t.dataset.caption||t.title)&&this.thumbs.classList.contains("thumbs-hidden")?(this.caption.style.bottom="20px",this.caption.style.transition="bottom 0.3s ease, transform 0.3s ease"):this.caption.style.bottom="120px"}}startDrag(t){const e=this.content.querySelector(".zoomora-media");if(!e||!this.isZoomed)return;this.isDragging=!0,e.style.cursor="grabbing",this.startX=t.clientX||t.touches&&t.touches[0].clientX||0,this.startY=t.clientY||t.touches&&t.touches[0].clientY||0;const s=e.style.transform,o=s.match(/scale\(([^)]+)\)/),i=s.match(/translate\(([^,]+),\s*([^)]+)\)/);this.currentScale=o?parseFloat(o[1]):1,this.currentX=i?parseFloat(i[1]):0,this.currentY=i?parseFloat(i[2]):0,t.preventDefault()}drag(t){if(!this.isDragging)return;t.preventDefault();const e=t.clientX||t.touches&&t.touches[0].clientX||0,s=t.clientY||t.touches&&t.touches[0].clientY||0,o=e-this.startX,i=s-this.startY,n=this.currentX+o,a=this.currentY+i,r=this.content.querySelector(".zoomora-media");if(!r)return;const l=r.getBoundingClientRect(),h=this.currentScale,d=l.width*(h-1)/2,c=l.height*(h-1)/2,u=Math.max(-d,Math.min(d,n)),m=Math.max(-c,Math.min(c,a));r.style.transform=`scale(${h}) translate(${u}px, ${m}px)`}endDrag(){if(!this.isDragging)return;this.isDragging=!1;const t=this.content.querySelector(".zoomora-media");t&&this.isZoomed&&(t.style.cursor="grab")}goTo(t){t<0||t>=this.items.length||(this.currentIndex=t,this.loadContent(),this.updateCounter(),this.updateThumbnails(),this.updateNavigation(),this.updateCaption())}getCurrentIndex(){return this.currentIndex}getTotalItems(){return this.items.length}isOpen(){return this.zoomora&&this.zoomora.classList.contains("active")}updateOptions(t){this.options=d(d({},this.options),t)}refresh(){if(this.isOpen()){const t=this.items[this.currentIndex];t&&this.open(t)}}destroy(){this.isInitialized&&(this.isOpen()&&this.close(),this.stopAutoHideTimer(),this.eventListeners.forEach((t,e)=>{t.forEach(({element:t,event:e,handler:s,options:o})=>{t&&t.removeEventListener&&t.removeEventListener(e,s,o)})}),this.eventListeners.clear(),this.zoomora&&this.zoomora.parentNode&&this.zoomora.parentNode.removeChild(this.zoomora),this.isInitialized=!1,this.items=[],this.currentIndex=0,this.zoomora=null,this.content=null,this.counter=null,this.thumbs=null,this.loading=null,this.caption=null)}}return t},"object"==typeof e&&"object"==typeof e.exports?e.exports=n():"function"==typeof define&&define.amd?define(n):s.Zoomora=n()}},function(){return e||(0,t[n(t)[0]])((e={exports:{}}).exports,e),e.exports});export default c();
10
+ //# sourceMappingURL=zoomora.es.min.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"zoomora.es.min.js","sources":["../src/zoomora.js"],"sourcesContent":["/*!\n * Zoomora Lightbox Plugin v1.0.0\n * A modern, responsive lightbox plugin with zoom, fullscreen, and gallery features\n *\n * Copyright (c) 2025 Faruk Ahmed (FrontTheme)\n * Licensed under MIT License\n */\n\n// Import styles\nimport './styles/zoomora.scss';\n\n(function (global, factory) {\n 'use strict';\n\n if (typeof module === 'object' && typeof module.exports === 'object') {\n // CommonJS/Node.js\n module.exports = factory();\n } else if (typeof define === 'function' && define.amd) {\n // AMD\n define(factory);\n } else {\n // Browser globals\n global.Zoomora = factory();\n }\n}(typeof window !== 'undefined' ? window : this, function () {\n 'use strict';\n\n /**\n * Zoomora Lightbox Plugin\n * @class\n */\n class Zoomora {\n /**\n * Default configuration options\n * @type {Object}\n */\n static get defaults() {\n return {\n selector: '[data-zoomora]',\n showCounter: true,\n showThumbnails: true,\n showFullscreen: true,\n showZoom: true,\n transition: 'fade', // 'fade' or 'slide'\n useHref: false, // Use href instead of data-src\n maxZoomScale: 3, // Maximum zoom scale\n zoomStep: 0.1, // Zoom step for scroll wheel\n animationDuration: 300, // Animation duration in ms\n onOpen: null, // Callback when lightbox opens\n onClose: null, // Callback when lightbox closes\n onNext: null, // Callback when navigating to next item\n onPrev: null, // Callback when navigating to previous item\n\n // Auto-hide controls\n showAutoHideToggle: true, // Show auto-hide toggle button\n autoHideDelay: 3000, // Delay in ms before hiding controls\n autoHideEnabled: false, // Default state of auto-hide\n };\n }\n\n /**\n * Constructor\n * @param {Object} options - Configuration options\n */\n constructor(options = {}) {\n this.options = {...Zoomora.defaults, ...options};\n this.currentIndex = 0;\n this.items = [];\n this.isZoomed = false;\n this.isFullscreen = false;\n this.isDragging = false;\n this.thumbnailsVisible = true;\n this.startX = 0;\n this.startY = 0;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n this.isInitialized = false;\n this.eventListeners = new Map();\n\n // Auto-hide controls\n this.autoHideEnabled = false;\n this.autoHideTimeout = null;\n this.autoHideDelay = 3000;\n this.isControlsVisible = true;\n this.idleTimer = null;\n\n // Bound methods for event listeners\n this.boundMethods = {\n handleDocumentClick: this.handleDocumentClick.bind(this),\n handleKeydown: this.handleKeydown.bind(this),\n handleFullscreenChange: this.handleFullscreenChange.bind(this),\n handleZoomoraClick: this.handleZoomoraClick.bind(this),\n handleContentClick: this.handleContentClick.bind(this),\n handleMouseDown: this.handleMouseDown.bind(this),\n handleMouseMove: this.handleMouseMove.bind(this),\n handleMouseUp: this.handleMouseUp.bind(this),\n handleTouchStart: this.handleTouchStart.bind(this),\n handleTouchMove: this.handleTouchMove.bind(this),\n handleTouchEnd: this.handleTouchEnd.bind(this),\n };\n\n this.init();\n }\n\n /**\n * Initialize the plugin\n */\n init() {\n if (this.isInitialized) {\n console.warn('Zoomora: Plugin already initialized');\n return;\n }\n\n try {\n this.createLightbox();\n this.bindEvents();\n\n this.isInitialized = true;\n } catch (error) {\n console.error('Zoomora: Initialization failed', error);\n }\n }\n\n /**\n * Static method to bind to anchor tags with href\n * @param {string} selector - CSS selector\n * @param {Object} options - Configuration options\n * @returns {Zoomora} - New Zoomora instance\n */\n static bind(selector, options = {}) {\n const enhancedOptions = {\n ...options,\n selector: selector,\n useHref: true\n };\n return new Zoomora(enhancedOptions);\n }\n\n /**\n * Create lightbox HTML structure\n */\n createLightbox() {\n // Check if lightbox already exists\n if (document.getElementById('zoomoraLightbox')) {\n console.warn('Zoomora: Lightbox already exists in DOM');\n return;\n }\n\n const zoomoraHTML = `\n <div class=\"zoomora\" id=\"zoomoraLightbox\">\n <div class=\"zoomora-container\">\n <div class=\"zoomora-header\" id=\"zoomoraHeader\">\n <div class=\"zoomora-counter\" id=\"zoomoraCounter\">1 / 1</div>\n <div class=\"zoomora-controls\">\n <button class=\"zoomora-btn\" id=\"zoomoraThumbnailBtn\" title=\"Toggle Thumbnails\">\n <i class=\"zoomorai-thumbnails\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraAutoHideBtn\" title=\"Toggle Auto-Hide Controls\">\n <i class=\"zoomorai-controls-off\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraZoomBtn\" title=\"Zoom\">\n <i class=\"zoomorai-zoom\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraFullscreenBtn\" title=\"Fullscreen\">\n <i class=\"zoomorai-expand\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCollapseBtn\" title=\"Exit Fullscreen\" style=\"display: none;\">\n <i class=\"zoomorai-collapse\"></i>\n </button>\n <button class=\"zoomora-btn\" id=\"zoomoraCloseBtn\" title=\"Close\">\n <i class=\"zoomorai-close\"></i>\n </button>\n </div>\n </div>\n \n <div class=\"zoomora-content\" id=\"zoomoraContent\">\n <div class=\"zoomora-loading\" id=\"zoomoraLoading\"></div>\n <div class=\"zoomora-slides-container\" id=\"zoomoraSlidesContainer\"></div>\n </div>\n \n <button class=\"zoomora-nav prev\" id=\"zoomoraPrevBtn\">\n <i class=\"zoomorai-arrow-left\"></i>\n </button>\n <button class=\"zoomora-nav next\" id=\"zoomoraNextBtn\">\n <i class=\"zoomorai-arrow-right\"></i>\n </button>\n \n <div class=\"zoomora-caption\" id=\"zoomoraCaption\"></div>\n <div class=\"zoomora-thumbnails\" id=\"zoomoraThumbs\"></div>\n </div>\n </div>\n `;\n\n document.body.insertAdjacentHTML('beforeend', zoomoraHTML);\n\n // Cache DOM elements\n this.zoomora = document.getElementById('zoomoraLightbox');\n this.header = document.getElementById('zoomoraHeader');\n this.content = document.getElementById('zoomoraContent');\n this.slidesContainer = document.getElementById('zoomoraSlidesContainer');\n this.counter = document.getElementById('zoomoraCounter');\n this.thumbs = document.getElementById('zoomoraThumbs');\n this.loading = document.getElementById('zoomoraLoading');\n this.caption = document.getElementById('zoomoraCaption');\n this.prevBtn = document.getElementById('zoomoraPrevBtn');\n this.nextBtn = document.getElementById('zoomoraNextBtn');\n\n // Verify all elements were created\n if (!this.zoomora || !this.content || !this.counter || !this.thumbs || !this.loading || !this.caption) {\n throw new Error('Failed to create required DOM elements');\n }\n }\n\n /**\n * Bind event listeners\n */\n bindEvents() {\n // Document click handler for opening lightbox\n this.addEventListener(document, 'click', this.boundMethods.handleDocumentClick);\n\n // Control button handlers\n this.addEventListener(document.getElementById('zoomoraCloseBtn'), 'click', () => this.close());\n this.addEventListener(document.getElementById('zoomoraPrevBtn'), 'click', () => this.prev());\n this.addEventListener(document.getElementById('zoomoraNextBtn'), 'click', () => this.next());\n this.addEventListener(document.getElementById('zoomoraZoomBtn'), 'click', () => this.toggleZoom());\n this.addEventListener(document.getElementById('zoomoraFullscreenBtn'), 'click', () => this.toggleFullscreen());\n this.addEventListener(document.getElementById('zoomoraCollapseBtn'), 'click', () => this.exitFullscreen());\n this.addEventListener(document.getElementById('zoomoraThumbnailBtn'), 'click', () => this.toggleThumbnails());\n\n // Fullscreen change events\n this.addEventListener(document, 'fullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'webkitfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'mozfullscreenchange', this.boundMethods.handleFullscreenChange);\n this.addEventListener(document, 'MSFullscreenChange', this.boundMethods.handleFullscreenChange);\n\n // Keyboard navigation\n this.addEventListener(document, 'keydown', this.boundMethods.handleKeydown);\n\n // Lightbox click to close\n this.addEventListener(this.zoomora, 'click', this.boundMethods.handleZoomoraClick);\n\n // Content click for zoom toggle\n this.addEventListener(this.content, 'click', this.boundMethods.handleContentClick);\n\n // Mouse drag events\n this.addEventListener(this.content, 'mousedown', this.boundMethods.handleMouseDown);\n this.addEventListener(this.content, 'mousemove', this.boundMethods.handleMouseMove);\n this.addEventListener(this.content, 'mouseup', this.boundMethods.handleMouseUp);\n this.addEventListener(this.content, 'mouseleave', this.boundMethods.handleMouseUp);\n\n // Touch events\n this.addEventListener(this.content, 'touchstart', this.boundMethods.handleTouchStart, {passive: false});\n this.addEventListener(this.content, 'touchmove', this.boundMethods.handleTouchMove, {passive: false});\n this.addEventListener(this.content, 'touchend', this.boundMethods.handleTouchEnd);\n\n // Add auto-hide toggle button handler\n this.addEventListener(document.getElementById('zoomoraAutoHideBtn'), 'click', () => this.toggleAutoHide());\n\n // Add mouse/touch activity listeners for auto-hide\n this.addEventListener(this.zoomora, 'mousemove', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'touchstart', () => this.handleUserActivity());\n this.addEventListener(this.zoomora, 'keydown', () => this.handleUserActivity());\n }\n\n /**\n * Add event listener with cleanup tracking\n * @param {Element} element - DOM element\n * @param {string} event - Event type\n * @param {Function} handler - Event handler\n * @param {Object} options - Event options\n */\n addEventListener(element, event, handler, options = {}) {\n if (!element) return;\n\n element.addEventListener(event, handler, options);\n\n // Track for cleanup\n const key = `${element.constructor.name}_${event}`;\n if (!this.eventListeners.has(key)) {\n this.eventListeners.set(key, []);\n }\n this.eventListeners.get(key).push({element, event, handler, options});\n }\n\n /**\n * Handle document click events\n * @param {Event} e - Click event\n */\n handleDocumentClick(e) {\n const target = e.target.closest(this.options.selector);\n if (target) {\n e.preventDefault();\n this.open(target);\n }\n }\n\n /**\n * Handle keyboard events\n * @param {KeyboardEvent} e - Keyboard event\n */\n handleKeydown(e) {\n if (!this.zoomora.classList.contains('active')) return;\n\n switch (e.key) {\n case 'Escape':\n if (this.isFullscreen) {\n this.exitFullscreen();\n } else {\n this.close();\n }\n break;\n case 'ArrowLeft':\n this.prev();\n break;\n case 'ArrowRight':\n this.next();\n break;\n case 'z':\n case 'Z':\n this.toggleZoom();\n break;\n case 'f':\n case 'F':\n this.toggleFullscreen();\n break;\n case 't':\n case 'T':\n this.toggleThumbnails();\n break;\n }\n }\n\n /**\n * Handle fullscreen change events\n */\n handleFullscreenChange() {\n const isInFullscreen = document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement;\n\n if (!isInFullscreen && this.isFullscreen) {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n }\n\n /**\n * Handle zoomora container clicks\n * @param {Event} e - Click event\n */\n handleZoomoraClick(e) {\n if (e.target === this.zoomora) {\n this.close();\n }\n }\n\n /**\n * Handle content clicks\n * @param {Event} e - Click event\n */\n handleContentClick(e) {\n const media = e.target.closest('.zoomora-media');\n if (media && !media.classList.contains('no-zoom') && !this.isDragging) {\n this.toggleZoom();\n }\n }\n\n /**\n * Handle mouse down events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseDown(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle mouse move events\n * @param {MouseEvent} e - Mouse event\n */\n handleMouseMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle mouse up events\n */\n handleMouseUp() {\n this.endDrag();\n }\n\n /**\n * Handle touch start events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchStart(e) {\n this.startDrag(e);\n }\n\n /**\n * Handle touch move events\n * @param {TouchEvent} e - Touch event\n */\n handleTouchMove(e) {\n this.drag(e);\n }\n\n /**\n * Handle touch end events\n */\n handleTouchEnd() {\n this.endDrag();\n }\n\n /**\n * Get image source from element\n * @param {Element} item - DOM element\n * @returns {string} - Image source URL\n */\n getImageSource(item) {\n const src = item.dataset.src || item.src || item.getAttribute('src');\n const type = item.dataset.type || 'image';\n\n // Handle YouTube URLs for video types\n if (type === 'video' && src) {\n return this.convertToEmbedUrl(src);\n }\n\n return src;\n }\n\n /**\n * Convert YouTube URLs to embed format\n * @param url\n * @returns {*|string}\n */\n convertToEmbedUrl(url) {\n // If already an embed URL, return as is\n if (url.includes('youtube.com/embed/')) {\n return url;\n }\n\n // Handle different YouTube URL formats\n let videoId = null;\n let startTime = null;\n\n // Extract video ID and start time from different YouTube URL formats\n if (url.includes('youtube.com/watch')) {\n const urlParams = new URLSearchParams(url.split('?')[1]);\n videoId = urlParams.get('v');\n const t = urlParams.get('t');\n if (t) {\n // Convert time format (e.g., \"111s\" to seconds)\n startTime = t.replace('s', '');\n }\n } else if (url.includes('youtu.be/')) {\n const parts = url.split('/');\n const videoAndParams = parts[parts.length - 1];\n if (videoAndParams.includes('?')) {\n videoId = videoAndParams.split('?')[0];\n const urlParams = new URLSearchParams(videoAndParams.split('?')[1]);\n const t = urlParams.get('t');\n if (t) startTime = t.replace('s', '');\n } else {\n videoId = videoAndParams;\n }\n }\n\n if (videoId) {\n let embedUrl = `https://www.youtube.com/embed/${videoId}`;\n const params = new URLSearchParams();\n\n if (startTime) {\n params.append('start', startTime);\n }\n\n // Add other useful parameters\n params.append('rel', '0'); // Don't show related videos\n params.append('modestbranding', '1'); // Modest branding\n\n // Option: Add autoplay for YouTube videos (uncomment if desired)\n // params.append('autoplay', '1');\n\n if (params.toString()) {\n embedUrl += '?' + params.toString();\n }\n\n return embedUrl;\n }\n\n // If not a YouTube URL or couldn't parse, return original\n return url;\n }\n\n /**\n * Get thumbnail source from element\n * @param {Element} item - DOM element\n * @returns {string} - Thumbnail source URL\n */\n getThumbnailSource(item) {\n const type = item.dataset.type || 'image';\n\n // For video items, always use the img.src as thumbnail (poster image)\n if (type === 'video') {\n return item.src || item.getAttribute('src');\n }\n\n // For regular images, use data-src or fallback to src\n return item.dataset.src || item.src || item.getAttribute('src');\n }\n\n /**\n * Get group identifier from element\n * @param {Element} element - DOM element\n * @returns {string} - Group identifier\n */\n getGroup(element) {\n if (this.options.useHref) {\n return element.dataset.lightbox || element.dataset.gallery || 'default';\n }\n return element.dataset.zoomora || 'default';\n }\n\n /**\n * Open lightbox with specified element\n * @param {Element} element - DOM element to open\n */\n open(element) {\n if (!element) return;\n\n const group = this.getGroup(element);\n let groupSelector;\n\n if (this.options.useHref) {\n if (element.dataset.lightbox) {\n groupSelector = `[data-lightbox=\"${group}\"]`;\n } else if (element.dataset.gallery) {\n groupSelector = `[data-gallery=\"${group}\"]`;\n } else {\n groupSelector = this.options.selector;\n }\n } else {\n groupSelector = `[data-zoomora=\"${group}\"]`;\n }\n\n this.items = Array.from(document.querySelectorAll(groupSelector));\n this.currentIndex = Math.max(0, this.items.indexOf(element));\n\n // Reset states\n this.isZoomed = false;\n this.isFullscreen = false;\n this.thumbnailsVisible = true;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n this.zoomora.classList.add('active');\n document.body.style.overflow = 'hidden';\n\n this.loadContent();\n this.updateThumbnails();\n this.updateCounter();\n this.updateNavigation();\n this.updateCaption();\n this.updateButtons();\n\n // Initialize auto-hide if enabled\n if (this.autoHideEnabled) {\n this.startAutoHideTimer();\n } else {\n this.showControls();\n }\n\n // Trigger callback\n if (typeof this.options.onOpen === 'function') {\n this.options.onOpen(element, this.currentIndex);\n }\n }\n\n /**\n * Close lightbox\n */\n close() {\n if (this.isFullscreen) {\n this.exitFullscreen();\n }\n\n this.zoomora.classList.remove('active');\n document.body.style.overflow = '';\n this.isZoomed = false;\n this.isFullscreen = false;\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n\n const media = this.content.querySelector('.zoomora-media');\n if (media) {\n media.classList.remove('zoomed');\n media.style.transform = '';\n media.style.cursor = '';\n }\n\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n this.showControls();\n\n // Trigger callback\n if (typeof this.options.onClose === 'function') {\n this.options.onClose(this.currentIndex);\n }\n }\n\n /**\n * Navigate to previous item\n */\n prev() {\n if (this.currentIndex > 0) {\n this.currentIndex--;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onPrev === 'function') {\n this.options.onPrev(this.currentIndex);\n }\n }\n }\n\n /**\n * Navigate to next item\n */\n next() {\n if (this.currentIndex < this.items.length - 1) {\n this.currentIndex++;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n\n // Trigger callback\n if (typeof this.options.onNext === 'function') {\n this.options.onNext(this.currentIndex);\n }\n }\n }\n\n /**\n * Load content for current item\n */\n loadContent() {\n if (!this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const src = this.getImageSource(item);\n const type = item.dataset.type || 'image';\n\n if (!src) {\n console.error('Zoomora: No source found for item');\n return;\n }\n\n // Show loading spinner\n this.loading.style.display = 'block';\n\n // Clear content but keep the loading reference intact\n // Don't replace innerHTML, just clear the slides\n if (this.slidesContainer) {\n this.slidesContainer.innerHTML = '';\n }\n\n // Add slight delay for smooth transition\n setTimeout(() => {\n this.renderContent(src, type, item);\n }, 100);\n }\n\n /**\n * Render content based on type\n * @param {string} src - Source URL\n * @param {string} type - Content type\n * @param {Element} item - Original item element\n */\n renderContent(src, type, item) {\n const slideContainer = document.createElement('div');\n slideContainer.className = 'zoomora-slide-container';\n\n // Create slide wrapper\n const slide = document.createElement('div');\n slide.className = `zoomora-slide ${this.options.transition === 'slide' ? 'slide-effect' : 'fade-effect'}`;\n slide.style.opacity = '0';\n slide.style.transform = this.options.transition === 'slide' ? 'translateX(100%)' : 'scale(0.8)';\n\n let mediaElement;\n\n try {\n switch (type) {\n case 'video':\n if (src.endsWith('.mp4') || src.endsWith('.webm') || src.endsWith('.ogg')) {\n const videoContainer = document.createElement('div');\n videoContainer.className = 'zoomora-video-container';\n\n mediaElement = document.createElement('video');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('preload', 'metadata');\n\n const posterSrc = item.src || item.getAttribute('src');\n if (posterSrc) {\n mediaElement.setAttribute('poster', posterSrc);\n }\n\n const playButton = document.createElement('div');\n playButton.className = 'zoomora-play-button';\n playButton.innerHTML = `<svg viewBox=\"0 0 24 24\" fill=\"currentColor\"><path d=\"M8 5v14l11-7z\"/></svg>`;\n\n playButton.addEventListener('click', () => {\n mediaElement.play();\n playButton.style.display = 'none';\n mediaElement.setAttribute('controls', '');\n });\n\n mediaElement.addEventListener('ended', () => {\n playButton.style.display = 'flex';\n });\n\n videoContainer.appendChild(mediaElement);\n videoContainer.appendChild(playButton);\n slideContainer.appendChild(videoContainer);\n } else {\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-video';\n mediaElement.setAttribute('allowfullscreen', '');\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n }\n break;\n\n case 'iframe':\n mediaElement = document.createElement('iframe');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-iframe';\n mediaElement.setAttribute('frameborder', '0');\n slideContainer.appendChild(mediaElement);\n break;\n\n default:\n mediaElement = document.createElement('img');\n mediaElement.src = src;\n mediaElement.className = 'zoomora-media';\n mediaElement.alt = item.alt || item.title || '';\n\n mediaElement.onload = () => {\n this.loading.style.display = 'none';\n this.checkZoomability(mediaElement);\n this.animateSlideIn(slide);\n };\n\n mediaElement.onerror = () => {\n this.loading.style.display = 'none';\n console.error('Zoomora: Failed to load image:', src);\n this.animateSlideIn(slide);\n };\n\n slideContainer.appendChild(mediaElement);\n }\n\n slide.appendChild(slideContainer);\n\n // Clear existing slides and add new one\n this.slidesContainer.innerHTML = '';\n this.slidesContainer.appendChild(slide);\n\n if (type !== 'image') {\n this.loading.style.display = 'none';\n this.animateSlideIn(slide);\n }\n\n } catch (error) {\n console.error('Zoomora: Error rendering content:', error);\n this.loading.style.display = 'none';\n }\n }\n\n // Animation helper\n animateSlideIn(slide) {\n // Force reflow\n slide.offsetHeight;\n\n // Add active class and animate\n slide.classList.add('active');\n\n if (this.options.transition === 'slide') {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'translateX(0)';\n slide.style.opacity = '1';\n } else {\n slide.style.transition = `transform ${this.options.animationDuration}ms ease, opacity ${this.options.animationDuration}ms ease`;\n slide.style.transform = 'scale(1)';\n slide.style.opacity = '1';\n }\n }\n\n // Toggle auto-hide controls\n toggleAutoHide() {\n this.autoHideEnabled = !this.autoHideEnabled;\n const autoHideBtn = document.getElementById('zoomoraAutoHideBtn');\n\n if (this.autoHideEnabled) {\n autoHideBtn.classList.add('active');\n autoHideBtn.title = 'Disable Auto-Hide Controls';\n this.startAutoHideTimer();\n } else {\n autoHideBtn.classList.remove('active');\n autoHideBtn.title = 'Enable Auto-Hide Controls';\n this.stopAutoHideTimer();\n this.showControls();\n }\n }\n\n // Handle user activity\n handleUserActivity() {\n if (!this.autoHideEnabled) return;\n\n this.showControls();\n this.startAutoHideTimer();\n }\n\n // Start auto-hide timer\n startAutoHideTimer() {\n this.stopAutoHideTimer();\n\n this.autoHideTimeout = setTimeout(() => {\n this.hideControls();\n }, this.options.autoHideDelay);\n }\n\n // Stop auto-hide timer\n stopAutoHideTimer() {\n if (this.autoHideTimeout) {\n clearTimeout(this.autoHideTimeout);\n this.autoHideTimeout = null;\n }\n }\n\n // Show controls\n showControls() {\n if (this.isControlsVisible) return;\n\n this.isControlsVisible = true;\n this.zoomora.classList.remove('controls-hidden');\n\n // Animate controls back in\n if (this.header) {\n this.header.style.transform = 'translateY(0)';\n this.header.style.opacity = '1';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(0)';\n this.thumbs.style.opacity = '1';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(0)';\n this.prevBtn.style.opacity = '1';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(0)';\n this.nextBtn.style.opacity = '1';\n }\n }\n\n // Hide controls\n hideControls() {\n if (!this.isControlsVisible) return;\n\n this.isControlsVisible = false;\n this.zoomora.classList.add('controls-hidden');\n\n // Animate controls out\n if (this.header) {\n this.header.style.transform = 'translateY(-100%)';\n this.header.style.opacity = '0';\n }\n\n if (this.caption) {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n }\n\n if (this.thumbs) {\n this.thumbs.style.transform = 'translateX(-50%) translateY(100%)';\n this.thumbs.style.opacity = '0';\n }\n\n if (this.prevBtn) {\n this.prevBtn.style.transform = 'translateX(-100%)';\n this.prevBtn.style.opacity = '0';\n }\n\n if (this.nextBtn) {\n this.nextBtn.style.transform = 'translateX(100%)';\n this.nextBtn.style.opacity = '0';\n }\n }\n\n /**\n * Check if image can be zoomed\n * @param {HTMLImageElement} img - Image element\n */\n checkZoomability(img) {\n if (!img || !img.naturalWidth || !img.naturalHeight) return;\n\n const imgRect = img.getBoundingClientRect();\n const renderedWidth = imgRect.width;\n const renderedHeight = imgRect.height;\n const naturalWidth = img.naturalWidth;\n const naturalHeight = img.naturalHeight;\n\n const isScaledDown = naturalWidth > renderedWidth || naturalHeight > renderedHeight;\n const zoomRatioX = naturalWidth / renderedWidth;\n const zoomRatioY = naturalHeight / renderedHeight;\n const maxZoomRatio = Math.max(zoomRatioX, zoomRatioY);\n\n // Store zoom info\n img.dataset.zoomRatio = maxZoomRatio;\n img.dataset.naturalWidth = naturalWidth;\n img.dataset.naturalHeight = naturalHeight;\n img.dataset.renderedWidth = renderedWidth;\n img.dataset.renderedHeight = renderedHeight;\n\n // Enable zoom if significantly scaled down\n if (isScaledDown && maxZoomRatio > 1.1) {\n img.classList.remove('no-zoom');\n } else {\n img.classList.add('no-zoom');\n }\n }\n\n /**\n * Update counter display\n */\n updateCounter() {\n if (this.options.showCounter && this.counter) {\n this.counter.textContent = `${this.currentIndex + 1} / ${this.items.length}`;\n }\n }\n\n /**\n * Update caption display\n */\n updateCaption() {\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption) {\n this.caption.textContent = caption;\n this.caption.style.transform = 'translateX(-50%) translateY(0)';\n this.caption.style.opacity = '1';\n this.caption.style.pointerEvents = 'auto';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.transform = 'translateX(-50%) translateY(100%)';\n this.caption.style.opacity = '0';\n this.caption.style.pointerEvents = 'none';\n this.caption.style.transition = 'opacity 0.3s ease, transform 0.3s ease';\n }\n }\n\n /**\n * Update thumbnails display\n */\n updateThumbnails() {\n if (!this.options.showThumbnails || !this.thumbs) return;\n\n if (this.items.length === 1) {\n this.caption.classList.add('single-item-thumbnail');\n this.thumbs.style.display = 'none';\n return;\n }\n\n this.caption.classList.remove('single-item-thumbnail');\n\n this.thumbs.style.display = 'flex';\n this.thumbs.innerHTML = '';\n\n this.items.forEach((item, index) => {\n const thumb = document.createElement('div');\n thumb.className = 'zoomora-thumb';\n if (index === this.currentIndex) thumb.classList.add('active');\n\n const img = document.createElement('img');\n const thumbSrc = this.getThumbnailSource(item);\n\n if (thumbSrc) {\n img.src = thumbSrc;\n img.alt = item.alt || item.title || '';\n img.onerror = () => {\n thumb.style.display = 'none';\n };\n }\n\n thumb.appendChild(img);\n\n thumb.addEventListener('click', () => {\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n });\n\n this.thumbs.appendChild(thumb);\n });\n }\n\n /**\n * Update navigation buttons\n */\n updateNavigation() {\n const prevBtn = document.getElementById('zoomoraPrevBtn');\n const nextBtn = document.getElementById('zoomoraNextBtn');\n\n if (prevBtn) {\n prevBtn.style.display = this.currentIndex > 0 ? 'flex' : 'none';\n }\n if (nextBtn) {\n nextBtn.style.display = this.currentIndex < this.items.length - 1 ? 'flex' : 'none';\n }\n }\n\n /**\n * Update control buttons\n */\n updateButtons() {\n const fullscreenBtn = document.getElementById('zoomoraFullscreenBtn');\n const collapseBtn = document.getElementById('zoomoraCollapseBtn');\n\n if (fullscreenBtn && collapseBtn) {\n if (this.isFullscreen) {\n fullscreenBtn.style.display = 'none';\n collapseBtn.style.display = 'flex';\n } else {\n fullscreenBtn.style.display = 'flex';\n collapseBtn.style.display = 'none';\n }\n }\n }\n\n /**\n * Toggle zoom state\n */\n toggleZoom() {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || media.tagName !== 'IMG' || media.classList.contains('no-zoom')) return;\n\n this.isZoomed = !this.isZoomed;\n media.classList.toggle('zoomed', this.isZoomed);\n\n if (this.isZoomed) {\n const zoomRatio = parseFloat(media.dataset.zoomRatio) || 2;\n let zoomScale = Math.min(zoomRatio, this.options.maxZoomScale);\n\n if (zoomRatio > 2.5) {\n zoomScale = Math.min(zoomRatio * 0.7, 2.5);\n }\n\n media.style.transform = `scale(${zoomScale})`;\n media.style.cursor = 'grab';\n media.dataset.currentZoomScale = zoomScale;\n this.currentScale = zoomScale;\n } else {\n media.style.transform = '';\n media.style.cursor = '';\n this.currentX = 0;\n this.currentY = 0;\n this.currentScale = 1;\n }\n }\n\n /**\n * Toggle fullscreen mode\n */\n toggleFullscreen() {\n if (!this.isFullscreen) {\n this.enterFullscreen();\n } else {\n this.exitFullscreen();\n }\n }\n\n /**\n * Enter fullscreen mode\n */\n enterFullscreen() {\n const element = this.zoomora;\n const requestFullscreen = element.requestFullscreen ||\n element.webkitRequestFullscreen ||\n element.mozRequestFullScreen ||\n element.msRequestFullscreen;\n\n if (requestFullscreen) {\n requestFullscreen.call(element).then(() => {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }).catch(err => {\n console.warn('Zoomora: Could not enter fullscreen:', err);\n this.fallbackFullscreen();\n });\n } else {\n this.fallbackFullscreen();\n }\n }\n\n /**\n * Exit fullscreen mode\n */\n exitFullscreen() {\n const isInFullscreen = document.fullscreenElement ||\n document.webkitFullscreenElement ||\n document.mozFullScreenElement ||\n document.msFullscreenElement;\n\n if (isInFullscreen) {\n const exitFullscreen = document.exitFullscreen ||\n document.webkitExitFullscreen ||\n document.mozCancelFullScreen ||\n document.msExitFullscreen;\n\n if (exitFullscreen) {\n exitFullscreen.call(document).then(() => {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }).catch(err => {\n console.warn('Zoomora: Could not exit fullscreen:', err);\n this.fallbackExitFullscreen();\n });\n } else {\n this.fallbackExitFullscreen();\n }\n } else {\n this.fallbackExitFullscreen();\n }\n }\n\n /**\n * Fallback fullscreen using CSS\n */\n fallbackFullscreen() {\n this.isFullscreen = true;\n this.zoomora.classList.add('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Exit CSS fullscreen\n */\n fallbackExitFullscreen() {\n this.isFullscreen = false;\n this.zoomora.classList.remove('fullscreen');\n this.updateButtons();\n }\n\n /**\n * Toggle thumbnails visibility\n */\n toggleThumbnails() {\n if (this.items.length === 1) return;\n\n this.thumbnailsVisible = !this.thumbnailsVisible;\n if (this.thumbs) {\n this.thumbs.classList.toggle('thumbs-hidden', !this.thumbnailsVisible);\n\n if (!this.caption || !this.items[this.currentIndex]) return;\n\n const item = this.items[this.currentIndex];\n const caption = item.dataset.caption || item.title || '';\n\n if (caption && this.thumbs.classList.contains('thumbs-hidden')) {\n this.caption.style.bottom = '20px';\n this.caption.style.transition = 'bottom 0.3s ease, transform 0.3s ease';\n } else {\n this.caption.style.bottom = '120px';\n }\n }\n }\n\n /**\n * Start drag operation\n * @param {Event} e - Mouse or touch event\n */\n startDrag(e) {\n const media = this.content.querySelector('.zoomora-media');\n if (!media || !this.isZoomed) return;\n\n this.isDragging = true;\n media.style.cursor = 'grabbing';\n\n this.startX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n this.startY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n // Parse current transform\n const transform = media.style.transform;\n const scaleMatch = transform.match(/scale\\(([^)]+)\\)/);\n const translateMatch = transform.match(/translate\\(([^,]+),\\s*([^)]+)\\)/);\n\n this.currentScale = scaleMatch ? parseFloat(scaleMatch[1]) : 1;\n this.currentX = translateMatch ? parseFloat(translateMatch[1]) : 0;\n this.currentY = translateMatch ? parseFloat(translateMatch[2]) : 0;\n\n e.preventDefault();\n }\n\n /**\n * Handle drag movement\n * @param {Event} e - Mouse or touch event\n */\n drag(e) {\n if (!this.isDragging) return;\n\n e.preventDefault();\n const clientX = e.clientX || (e.touches && e.touches[0].clientX) || 0;\n const clientY = e.clientY || (e.touches && e.touches[0].clientY) || 0;\n\n const deltaX = clientX - this.startX;\n const deltaY = clientY - this.startY;\n\n const newX = this.currentX + deltaX;\n const newY = this.currentY + deltaY;\n\n const media = this.content.querySelector('.zoomora-media');\n if (!media) return;\n\n const mediaRect = media.getBoundingClientRect();\n const scale = this.currentScale;\n const maxX = (mediaRect.width * (scale - 1)) / 2;\n const maxY = (mediaRect.height * (scale - 1)) / 2;\n\n const constrainedX = Math.max(-maxX, Math.min(maxX, newX));\n const constrainedY = Math.max(-maxY, Math.min(maxY, newY));\n\n media.style.transform = `scale(${scale}) translate(${constrainedX}px, ${constrainedY}px)`;\n }\n\n /**\n * End drag operation\n */\n endDrag() {\n if (!this.isDragging) return;\n\n this.isDragging = false;\n const media = this.content.querySelector('.zoomora-media');\n if (media && this.isZoomed) {\n media.style.cursor = 'grab';\n }\n }\n\n /**\n * Go to specific item by index\n * @param {number} index - Item index\n */\n goTo(index) {\n if (index < 0 || index >= this.items.length) return;\n\n this.currentIndex = index;\n this.loadContent();\n this.updateCounter();\n this.updateThumbnails();\n this.updateNavigation();\n this.updateCaption();\n }\n\n /**\n * Get current item index\n * @returns {number} - Current index\n */\n getCurrentIndex() {\n return this.currentIndex;\n }\n\n /**\n * Get total number of items\n * @returns {number} - Total items\n */\n getTotalItems() {\n return this.items.length;\n }\n\n /**\n * Check if lightbox is open\n * @returns {boolean} - True if open\n */\n isOpen() {\n return this.zoomora && this.zoomora.classList.contains('active');\n }\n\n /**\n * Update options\n * @param {Object} newOptions - New options to merge\n */\n updateOptions(newOptions) {\n this.options = {...this.options, ...newOptions};\n }\n\n /**\n * Refresh the lightbox (re-scan for items)\n */\n refresh() {\n if (this.isOpen()) {\n const currentItem = this.items[this.currentIndex];\n if (currentItem) {\n this.open(currentItem);\n }\n }\n }\n\n /**\n * Destroy the lightbox instance\n */\n destroy() {\n if (!this.isInitialized) return;\n\n // Close if open\n if (this.isOpen()) {\n this.close();\n }\n\n // Clean up auto-hide\n this.stopAutoHideTimer();\n\n // Remove all event listeners\n this.eventListeners.forEach((listeners, key) => {\n listeners.forEach(({element, event, handler, options}) => {\n if (element && element.removeEventListener) {\n element.removeEventListener(event, handler, options);\n }\n });\n });\n this.eventListeners.clear();\n\n // Remove DOM elements\n if (this.zoomora && this.zoomora.parentNode) {\n this.zoomora.parentNode.removeChild(this.zoomora);\n }\n\n // Reset properties\n this.isInitialized = false;\n this.items = [];\n this.currentIndex = 0;\n this.zoomora = null;\n this.content = null;\n this.counter = null;\n this.thumbs = null;\n this.loading = null;\n this.caption = null;\n }\n }\n\n // Export the class\n return Zoomora;\n}));"],"names":["require_zoomora_es_min","exports","module","global","factory","window","this","Zoomora","defaults","selector","showCounter","showThumbnails","showFullscreen","showZoom","transition","useHref","maxZoomScale","zoomStep","animationDuration","onOpen","onClose","onNext","onPrev","showAutoHideToggle","autoHideDelay","autoHideEnabled","constructor","options","__spreadValues","currentIndex","items","isZoomed","isFullscreen","isDragging","thumbnailsVisible","startX","startY","currentX","currentY","currentScale","isInitialized","eventListeners","Map","autoHideTimeout","isControlsVisible","idleTimer","boundMethods","handleDocumentClick","bind","handleKeydown","handleFullscreenChange","handleZoomoraClick","handleContentClick","handleMouseDown","handleMouseMove","handleMouseUp","handleTouchStart","handleTouchMove","handleTouchEnd","init","console","warn","createLightbox","bindEvents","error","enhancedOptions","document","getElementById","body","insertAdjacentHTML","zoomora","header","content","slidesContainer","counter","thumbs","loading","caption","prevBtn","nextBtn","Error","addEventListener","close","prev","next","toggleZoom","toggleFullscreen","exitFullscreen","toggleThumbnails","passive","toggleAutoHide","handleUserActivity","element","event","handler","key","name","has","set","get","push","e","target","closest","preventDefault","open","classList","contains","fullscreenElement","webkitFullscreenElement","mozFullScreenElement","msFullscreenElement","remove","updateButtons","media","startDrag","drag","endDrag","getImageSource","item","src","dataset","getAttribute","type","convertToEmbedUrl","url","includes","videoId","startTime","urlParams","URLSearchParams","split","t","replace","parts","videoAndParams","length","embedUrl","params","append","toString","getThumbnailSource","getGroup","lightbox","gallery","group","groupSelector","Array","from","querySelectorAll","Math","max","indexOf","add","style","overflow","loadContent","updateThumbnails","updateCounter","updateNavigation","updateCaption","startAutoHideTimer","showControls","querySelector","transform","cursor","stopAutoHideTimer","display","innerHTML","setTimeout","renderContent","slideContainer","createElement","className","slide","mediaElement","opacity","endsWith","videoContainer","setAttribute","posterSrc","playButton","play","appendChild","alt","title","onload","checkZoomability","animateSlideIn","onerror","offsetHeight","autoHideBtn","hideControls","clearTimeout","img","naturalWidth","naturalHeight","imgRect","getBoundingClientRect","renderedWidth","width","renderedHeight","height","isScaledDown","zoomRatioX","zoomRatioY","maxZoomRatio","zoomRatio","textContent","pointerEvents","forEach","index","thumb","thumbSrc","fullscreenBtn","collapseBtn","tagName","toggle","parseFloat","zoomScale","min","currentZoomScale","enterFullscreen","requestFullscreen","webkitRequestFullscreen","mozRequestFullScreen","msRequestFullscreen","call","then","catch","err","fallbackFullscreen","webkitExitFullscreen","mozCancelFullScreen","msExitFullscreen","fallbackExitFullscreen","bottom","clientX","touches","clientY","scaleMatch","match","translateMatch","deltaX","deltaY","newX","newY","mediaRect","scale","maxX","maxY","constrainedX","constrainedY","goTo","getCurrentIndex","getTotalItems","isOpen","updateOptions","newOptions","refresh","currentItem","destroy","listeners","removeEventListener","clear","parentNode","removeChild","define","amd"],"mappings":"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"}