@redot-src/glare 1.4.0 → 1.4.1
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/glare.css +1 -1
- package/dist/glare.esm.js +122 -122
- package/dist/glare.esm.js.map +1 -1
- package/dist/glare.js +2 -2
- package/dist/glare.js.map +1 -1
- package/package.json +1 -1
package/dist/glare.esm.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"glare.esm.js","sources":["../src/i18n.ts","../src/utils/template.ts","../src/media/providers.ts","../src/icons.ts","../src/templates.ts","../src/defaults.ts","../src/media/detect.ts","../src/media/items.ts","../src/utils/dom.ts","../src/utils/env.ts","../src/core/dom.ts","../src/modules/fullscreen.ts","../src/utils/object.ts","../src/core/zoom.ts","../src/modules/gestures.ts","../src/modules/hash.ts","../src/modules/slideshow.ts","../src/modules/thumbs.ts","../src/modules/wheel.ts","../src/core/animation.ts","../src/core/options.ts","../src/core/bind.ts","../src/core/idle.ts","../src/core/registry.ts","../src/core/interactions.ts","../src/core/loaders.ts","../src/core/glare.ts","../src/index.ts"],"sourcesContent":["import type { GlareOptions, I18nDict } from './types'\n\nexport const i18nEn: I18nDict = {\n CLOSE: 'Close',\n NEXT: 'Next',\n PREV: 'Previous',\n ERROR: 'The requested content cannot be loaded.<br/>Please try again later.',\n LOADING: 'Loading',\n LIGHTBOX: 'Media lightbox',\n GO_TO_SLIDE: 'Go to slide {{index}}',\n VIDEO_UNSUPPORTED: 'Your browser does not support HTML5 video.',\n PLAY_START: 'Start slideshow',\n PLAY_STOP: 'Pause slideshow',\n FULL_SCREEN: 'Full screen',\n FULL_SCREEN_EXIT: 'Exit full screen',\n THUMBS: 'Thumbnails',\n DOWNLOAD: 'Download',\n MORE: 'More options',\n ZOOM: 'Zoom',\n ZOOM_OUT: 'Zoom out',\n}\n\n/** Resolves the active dictionary: built-in English, then `i18n.en`, then `i18n[lang]`. */\nexport function getDict(opts: GlareOptions): I18nDict {\n const lang = opts.lang ?? 'en'\n return { ...i18nEn, ...opts.i18n?.en, ...opts.i18n?.[lang] }\n}\n","/** Replaces `{{key}}` placeholders with values from `dict`. */\nexport function translate(template: string, dict: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => dict[key] ?? '')\n}\n\nexport function buildQuery(params: Record<string, string | number | boolean>): string {\n return Object.entries(params)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\n .join('&')\n}\n\n/** Expands `$1`-style capture references from a RegExp match. */\nexport function expandMatch(template: string, match: RegExpMatchArray): string {\n return template.replace(/\\$(\\d+)/g, (_, n: string) => match[Number(n)] ?? '')\n}\n","import type { ContentType, MediaProvider, SlideSource } from '../types'\nimport { buildQuery, expandMatch } from '../utils/template'\n\nexport const providers: Record<string, MediaProvider> = {\n youtube: {\n matcher:\n /(?:youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/(?:watch\\?(?:.*&)?v=|v\\/|u\\/\\w\\/|embed\\/|shorts\\/)?([\\w-]{11})/i,\n type: 'embed',\n url: 'https://www.youtube-nocookie.com/embed/$1',\n thumb: 'https://img.youtube.com/vi/$1/hqdefault.jpg',\n params: { autoplay: 1, rel: 0, modestbranding: 1, playsinline: 1 },\n },\n vimeo: {\n matcher: /vimeo\\.com\\/(?:video\\/)?(\\d+)/i,\n type: 'embed',\n url: 'https://player.vimeo.com/video/$1',\n params: { autoplay: 1, title: 0, byline: 0, portrait: 0 },\n },\n gmap: {\n matcher:\n /(?:maps\\.)?google\\.([a-z]{2,3}(?:\\.[a-z]{2})?)\\/(?:maps\\/(?:place\\/[^/]+\\/)?@([^/]+)|maps\\?q=([^&]+)|maps\\/search\\/([^/?]+))/i,\n type: 'iframe',\n url: (match) => {\n const [, tld, coords, query, search] = match\n if (coords) {\n const [lat, lng, zoom] = coords.split(',')\n const z = zoom ? Math.floor(parseFloat(zoom)) : 14\n return `https://maps.google.${tld}/maps?ll=${lat},${lng}&z=${z}&output=embed`\n }\n const q = encodeURIComponent(decodeURIComponent(query || search || ''))\n return `https://maps.google.${tld}/maps?q=${q}&output=embed`\n },\n },\n}\n\nfunction resolve(\n value: MediaProvider['url'],\n match: RegExpMatchArray,\n src: string,\n): string | undefined {\n if (typeof value === 'function') return value(match, src)\n if (typeof value === 'string') return expandMatch(value, match)\n return undefined\n}\n\n/** Rewrites `src` through the first matching provider, or returns null. */\nexport function applyProvider(\n src: string,\n media: Record<string, MediaProvider> | undefined,\n): Pick<SlideSource, 'src' | 'thumb'> & { type: ContentType } | null {\n for (const provider of Object.values(media ?? {})) {\n const match = src.match(provider.matcher)\n if (!match) continue\n\n let url = resolve(provider.url, match, src) ?? src\n if (provider.params) {\n url += (url.includes('?') ? '&' : '?') + buildQuery(provider.params)\n }\n\n return {\n src: url,\n type: provider.type ?? 'iframe',\n thumb: resolve(provider.thumb, match, src),\n }\n }\n return null\n}\n","const svg = (paths: string): string =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths}</svg>`\n\nexport const icons = {\n close: svg('<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>'),\n next: svg('<path d=\"m9 18 6-6-6-6\"/>'),\n prev: svg('<path d=\"m15 18-6-6 6-6\"/>'),\n zoomIn: svg('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M11 8v6\"/><path d=\"M8 11h6\"/>'),\n zoomOut: svg('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M8 11h6\"/>'),\n download: svg('<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\"/>'),\n thumbs: svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M9 21V9\"/>'),\n play: svg('<polygon points=\"6 3 20 12 6 21 6 3\"/>'),\n pause: svg('<rect width=\"4\" height=\"16\" x=\"6\" y=\"4\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"4\"/>'),\n fullscreen: svg('<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"/><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"/><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"/><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"/>'),\n fullscreenExit: svg('<path d=\"M8 3v3a2 2 0 0 1-2 2H3\"/><path d=\"M21 8h-3a2 2 0 0 1-2-2V3\"/><path d=\"M3 16h3a2 2 0 0 1 2 2v3\"/><path d=\"M16 21v-3a2 2 0 0 1 2-2h3\"/>'),\n more: svg('<circle cx=\"5\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>'),\n thumbImage: svg('<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"/><circle cx=\"8.5\" cy=\"9\" r=\"1.5\"/><path d=\"m4 17 5-5 4 4 2-2 5 5\"/>'),\n thumbVideo: svg('<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><path d=\"m10 9 5 3-5 3Z\"/>'),\n thumbEmbed: svg('<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"m10 8 6 4-6 4Z\"/>'),\n thumbIframe: svg('<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"/><path d=\"M3 8h18\"/><circle cx=\"6\" cy=\"6\" r=\".5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"9\" cy=\"6\" r=\".5\" fill=\"currentColor\" stroke=\"none\"/>'),\n thumbInline: svg('<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"/><path d=\"M8 8h8M8 12h8M8 16h5\"/>'),\n thumbAjax: svg('<path d=\"M20 15a4 4 0 0 0-3-3.87A6 6 0 1 0 6 14\"/><path d=\"m9 16 3 3 3-3M12 12v7\"/>'),\n thumbHtml: svg('<path d=\"m8 9-3 3 3 3M16 9l3 3-3 3M14 5l-4 14\"/>'),\n thumbSlide: svg('<path d=\"M6 3h9l4 4v14H6Z\"/><path d=\"M14 3v5h5M9 13h7M9 17h5\"/>'),\n} as const\n","import { icons } from './icons'\n\nconst button = (name: string, label: string, icon: string, attrs = ''): string =>\n `<button type=\"button\" class=\"glare-button glare-button--${name}\" data-glare-${name} title=\"{{${label}}}\" aria-label=\"{{${label}}}\"${attrs}>${icon}</button>`\n\nexport const baseTemplate = `\n<div class=\"glare-container\" role=\"dialog\" aria-modal=\"true\" tabindex=\"-1\">\n <div class=\"glare-bg\"></div>\n <div class=\"glare-progress\" hidden></div>\n <div class=\"glare-inner\">\n <div class=\"glare-live glare-sr-only\" aria-live=\"polite\" aria-atomic=\"true\"></div>\n <div class=\"glare-infobar\"><span class=\"glare-infobar-index\"></span></div>\n <div class=\"glare-toolbar\"></div>\n <div class=\"glare-navigation\">\n ${button('prev', 'PREV', icons.prev)}\n ${button('next', 'NEXT', icons.next)}\n </div>\n <div class=\"glare-stage\"></div>\n <div class=\"glare-caption\"></div>\n </div>\n</div>`\n\nexport const buttonTemplates: Record<string, string> = {\n zoom: button('zoom', 'ZOOM', icons.zoomIn),\n slideshow: button('slideshow', 'PLAY_START', icons.play),\n thumbs: button('thumbs', 'THUMBS', icons.thumbs, ' aria-expanded=\"false\"'),\n fullscreen: button('fullscreen', 'FULL_SCREEN', icons.fullscreen),\n more: button('more', 'MORE', icons.more, ' aria-expanded=\"false\" aria-haspopup=\"true\"'),\n close: button('close', 'CLOSE', icons.close),\n download: `<a class=\"glare-button glare-button--download\" data-glare-download download target=\"_blank\" rel=\"noopener\" title=\"{{DOWNLOAD}}\" aria-label=\"{{DOWNLOAD}}\">${icons.download}</a>`,\n smallBtn: `<button type=\"button\" class=\"glare-button glare-close-small\" data-glare-close title=\"{{CLOSE}}\" aria-label=\"{{CLOSE}}\">${icons.close}</button>`,\n}\n\nexport const spinnerTemplate = '<div class=\"glare-spinner\" role=\"status\" aria-label=\"{{LOADING}}\"></div>'\n\nexport const errorTemplate = '<div class=\"glare-error\"><p>{{ERROR}}</p></div>'\n\nexport const videoTemplate =\n '<video class=\"glare-video\" controls playsinline controlsList=\"nodownload\" poster=\"{{poster}}\">' +\n '<source src=\"{{src}}\" type=\"{{format}}\"/>' +\n '{{VIDEO_UNSUPPORTED}}' +\n '</video>'\n\nexport const iframeTemplate = '<iframe class=\"glare-iframe\"></iframe>'\n","import type {\n FullscreenOptions,\n ResolvedOptions,\n SlideshowOptions,\n ThumbsOptions,\n} from './types'\nimport { i18nEn } from './i18n'\nimport { providers } from './media/providers'\nimport {\n baseTemplate,\n buttonTemplates,\n errorTemplate,\n iframeTemplate,\n spinnerTemplate,\n videoTemplate,\n} from './templates'\n\nexport const thumbsDefaults: Required<Omit<ThumbsOptions, 'parentEl'>> & ThumbsOptions = {\n autoStart: false,\n axis: 'x',\n fit: 'cover',\n}\n\nexport const slideshowDefaults: Required<SlideshowOptions> = {\n autoStart: false,\n speed: 3000,\n}\n\nexport const fullscreenDefaults: Required<FullscreenOptions> = {\n autoStart: false,\n}\n\nexport const defaults: ResolvedOptions = {\n closeExisting: false,\n loop: false,\n keyboard: true,\n protect: false,\n modal: false,\n idleTime: 3,\n hideScrollbar: true,\n autoFocus: true,\n backFocus: true,\n trapFocus: true,\n defaultType: 'image',\n parentEl: 'body',\n baseClass: '',\n slideClass: '',\n\n arrows: true,\n infobar: true,\n toolbar: 'auto',\n smallBtn: 'auto',\n buttons: ['zoom', 'slideshow', 'thumbs', 'download', 'fullscreen', 'close'],\n\n animationEffect: 'zoom',\n animationDuration: 366,\n anchor: 'trigger',\n zoomOpacity: true,\n transitionEffect: 'fade',\n transitionDuration: 366,\n\n clickContent: (current) => (current.type === 'image' ? 'zoom' : false),\n clickSlide: 'close',\n dblclickContent: false,\n dblclickSlide: false,\n wheel: 'auto',\n touch: { vertical: true, momentum: true },\n mobile: {\n idleTime: false,\n clickContent: (current) => (current.type === 'image' ? 'toggleControls' : false),\n clickSlide: (current) => (current.type === 'image' ? 'toggleControls' : 'close'),\n dblclickContent: (current) => (current.type === 'image' ? 'zoom' : false),\n dblclickSlide: (current) => (current.type === 'image' ? 'zoom' : false),\n },\n\n image: { preload: false },\n video: { tpl: videoTemplate, format: '', autoStart: true },\n iframe: {\n preload: true,\n css: {},\n attr: { allowfullscreen: 'true', allow: 'autoplay; fullscreen; picture-in-picture' },\n tpl: iframeTemplate,\n },\n ajax: { settings: { headers: { 'X-Requested-With': 'XMLHttpRequest' } } },\n media: providers,\n\n hash: true,\n slideshow: slideshowDefaults,\n thumbs: thumbsDefaults,\n fullscreen: fullscreenDefaults,\n\n lang: 'en',\n i18n: { en: i18nEn },\n baseTpl: baseTemplate,\n btnTpl: buttonTemplates,\n spinnerTpl: spinnerTemplate,\n errorTpl: errorTemplate,\n}\n","import type { ContentType } from '../types'\n\nconst IMAGE_EXT = /\\.(avif|bmp|gif|jpe?g|png|svg|webp|ico)(\\?.*)?$/i\nconst VIDEO_EXT = /\\.(mp4|webm|ogg|ogv|mov|m4v)(\\?.*)?$/i\nconst PDF_EXT = /\\.pdf(\\?.*)?$/i\nconst SELECTOR = /^(#[\\w-]+|\\.[\\w-]+)$/\n\n/** Guesses the content type from a URL; falls back to `fallback` for unknown URLs. */\nexport function detectType(src: string, fallback: ContentType = 'image'): ContentType {\n if (!src) return 'html'\n if (SELECTOR.test(src)) return 'inline'\n if (IMAGE_EXT.test(src)) return 'image'\n if (VIDEO_EXT.test(src)) return 'video'\n if (PDF_EXT.test(src)) return 'iframe'\n return fallback\n}\n\nexport function videoMime(src: string): string {\n const ext = src.match(/\\.(\\w+)(?:\\?|$)/)?.[1]?.toLowerCase()\n if (!ext) return 'video/mp4'\n return `video/${ext === 'ogv' ? 'ogg' : ext}`\n}\n","import type { ContentType, GlareOptions, SlideItem, SlideSource } from '../types'\nimport { detectType } from './detect'\nimport { applyProvider } from './providers'\n\n/** Turns a user-provided slide into a normalized `SlideItem`. */\nexport function normalizeItem(source: SlideSource | string, index: number, opts: GlareOptions): SlideItem {\n const raw: SlideSource = typeof source === 'string' ? { src: source } : { ...source }\n let src = raw.src ?? ''\n let type = raw.type\n let thumb = raw.thumb\n\n const provided = src ? applyProvider(src, opts.media) : null\n if (provided) {\n src = provided.src ?? src\n type ??= provided.type\n thumb ??= provided.thumb\n }\n\n if (!type) {\n type = raw.html || raw.content ? 'html' : detectType(src, opts.defaultType)\n }\n\n return {\n ...raw,\n index,\n src,\n type,\n thumb,\n caption: raw.caption ?? raw.title ?? '',\n isLoaded: false,\n hasError: false,\n }\n}\n\nconst attr = (el: HTMLElement, name: string): string | undefined => el.getAttribute(name) || undefined\n\n/** Reads slide data from trigger elements (`href`, `data-*` attributes, nested `<img>`). */\nexport function itemsFromElements(elements: HTMLElement[], opts: GlareOptions): SlideItem[] {\n return elements.map((el, index) => {\n const img = el.querySelector('img')\n const caption = attr(el, 'data-caption') ?? attr(el, 'title') ?? ''\n\n return normalizeItem(\n {\n src: attr(el, 'data-src') ?? attr(el, 'href') ?? '',\n type: attr(el, 'data-type') as ContentType | undefined,\n caption,\n alt: img?.getAttribute('alt') || caption,\n thumb: attr(el, 'data-thumb') ?? img?.getAttribute('src') ?? undefined,\n width: attr(el, 'data-width'),\n height: attr(el, 'data-height'),\n ratio: attr(el, 'data-ratio'),\n poster: attr(el, 'data-poster'),\n downloadSrc: attr(el, 'data-download-src'),\n html: attr(el, 'data-html'),\n $trigger: el,\n },\n index,\n opts,\n )\n })\n}\n\nexport function createItems(\n items: Array<SlideSource | string> | HTMLElement[],\n opts: GlareOptions,\n): SlideItem[] {\n // `nodeType` rather than `instanceof`, so elements from another window (see `delegate`) still count.\n if (items.length && (items[0] as Node).nodeType === 1) {\n return itemsFromElements(items as HTMLElement[], opts)\n }\n return (items as Array<SlideSource | string>).map((item, i) => normalizeItem(item, i, opts))\n}\n","export function $(selector: string, root: ParentNode = document): HTMLElement | null {\n return root.querySelector<HTMLElement>(selector)\n}\n\nexport function $$(selector: string, root: ParentNode = document): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(selector))\n}\n\nexport function createEl<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className = '',\n html = '',\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag)\n if (className) el.className = className\n if (html) el.innerHTML = html\n return el\n}\n\n/** Parses an HTML string and returns its first element. */\nexport function fromHtml(html: string): HTMLElement {\n const wrapper = createEl('div', '', html.trim())\n return wrapper.firstElementChild as HTMLElement\n}\n\n/** Strips markup from an HTML string, for labels that must be plain text. */\nexport function toText(html: string): string {\n if (!/[<&]/.test(html)) return html.trim()\n return new DOMParser().parseFromString(html, 'text/html').body.textContent?.trim() ?? ''\n}\n\n/** Resolves a selector or element, searching `root` first and then the document. */\nexport function resolveElement(\n target: string | HTMLElement | null | undefined,\n root: ParentNode = document,\n): HTMLElement | null {\n if (!target) return null\n if (typeof target !== 'string') return target\n return $(target, root) ?? $(target)\n}\n\nexport function toCssSize(value: number | string): string {\n return typeof value === 'number' ? `${value}px` : value\n}\n\n/** Adds an event listener and returns a function that removes it. */\nexport function on<K extends keyof GlobalEventHandlersEventMap>(\n target: EventTarget,\n type: K,\n handler: (event: GlobalEventHandlersEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void {\n target.addEventListener(type, handler, options)\n return () => target.removeEventListener(type, handler, options)\n}\n\n/** Runs `callback` after the browser has painted the current frame. */\nexport function nextFrame(callback: () => void): void {\n requestAnimationFrame(() => requestAnimationFrame(callback))\n}\n\n/**\n * Runs `done` exactly once when a transition on `el` ends,\n * or after `duration` as a fallback for transitions that never fire.\n */\nexport function afterTransition(el: HTMLElement, duration: number, done: () => void): void {\n let finished = false\n const finish = () => {\n if (finished) return\n finished = true\n clearTimeout(timer)\n el.removeEventListener('transitionend', onEnd)\n done()\n }\n const onEnd = (event: Event) => {\n if (event.target === el) finish()\n }\n el.addEventListener('transitionend', onEnd)\n const timer = setTimeout(finish, duration + 50)\n}\n","export function isMobile(): boolean {\n return navigator.maxTouchPoints > 0 && window.matchMedia('(pointer: coarse)').matches\n}\n\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches\n}\n\nexport function supportsFullscreen(): boolean {\n const doc = document as Document & { webkitFullscreenEnabled?: boolean }\n return Boolean(doc.fullscreenEnabled ?? doc.webkitFullscreenEnabled)\n}\n\nconst LOCK_CLASS = 'glare-lock'\n\n/** Locks page scrolling while compensating for the scrollbar width. */\nexport function lockScroll(lock: boolean): void {\n const html = document.documentElement\n if (lock) {\n const scrollbar = window.innerWidth - html.clientWidth\n html.classList.add(LOCK_CLASS)\n if (scrollbar > 0) html.style.marginRight = `${scrollbar}px`\n } else {\n html.classList.remove(LOCK_CLASS)\n html.style.marginRight = ''\n }\n}\n","import type { CustomButton, GlareRefs, I18nDict, ResolvedOptions, SlideItem } from '../types'\nimport { icons } from '../icons'\nimport { $, $$, createEl, fromHtml, toText } from '../utils/dom'\nimport { supportsFullscreen } from '../utils/env'\nimport { translate } from '../utils/template'\n\nconst HIDDEN = 'glare-hidden'\n\nexport function buildContainer(opts: ResolvedOptions, dict: I18nDict, id: number, count: number): GlareRefs {\n const container = fromHtml(translate(opts.baseTpl, dict))\n container.dataset.glareId = String(id)\n if (opts.baseClass) container.classList.add(opts.baseClass)\n if (opts.modal) container.classList.add('glare-is-modal')\n\n const stage = $('.glare-stage', container)\n if (!stage) throw new Error('baseTpl must contain a .glare-stage element')\n\n const refs: GlareRefs = {\n container,\n bg: $('.glare-bg', container),\n inner: $('.glare-inner', container),\n stage,\n caption: $('.glare-caption', container),\n toolbar: $('.glare-toolbar', container),\n infobar: $('.glare-infobar', container),\n navigation: $('.glare-navigation', container),\n }\n\n const single = count < 2\n refs.navigation?.classList.toggle(HIDDEN, !opts.arrows || single)\n refs.infobar?.classList.toggle(HIDDEN, !opts.infobar || single)\n if (refs.toolbar) buildToolbar(refs.toolbar, opts, dict, single)\n\n return refs\n}\n\nfunction buildToolbar(toolbar: HTMLElement, opts: ResolvedOptions, dict: I18nDict, single: boolean): void {\n if (opts.toolbar === false) {\n toolbar.classList.add(HIDDEN)\n return\n }\n\n const menu = createEl('div', 'glare-toolbar-menu')\n menu.id = `glare-toolbar-menu-${toolbar.closest<HTMLElement>('.glare-container')?.dataset.glareId ?? ''}`\n\n for (const name of opts.buttons) {\n if (typeof name !== 'string') {\n menu.appendChild(createCustomButton(name))\n continue\n }\n\n if (single && (name === 'thumbs' || name === 'slideshow')) continue\n if (name === 'fullscreen' && !supportsFullscreen()) continue\n if (name === 'more' || name === 'close') continue\n\n const tpl = opts.btnTpl[name]\n if (tpl) menu.insertAdjacentHTML('beforeend', translate(tpl, dict))\n }\n\n if (menu.childElementCount) {\n toolbar.appendChild(menu)\n const moreTpl = opts.btnTpl.more\n if (moreTpl) {\n toolbar.insertAdjacentHTML('beforeend', translate(moreTpl, dict))\n toolbar.querySelector('[data-glare-more]')?.setAttribute('aria-controls', menu.id)\n }\n }\n\n if (opts.buttons.includes('close')) {\n const closeTpl = opts.btnTpl.close\n if (closeTpl) toolbar.insertAdjacentHTML('beforeend', translate(closeTpl, dict))\n }\n}\n\n/** A button defined inline in `buttons`: the built-in markup, matched back to its `click` by name. */\nfunction createCustomButton({ name, label, icon }: CustomButton): HTMLElement {\n const button = createEl('button', `glare-button glare-button--${name}`, icon)\n\n button.type = 'button'\n button.title = label\n button.dataset.glareCustom = name\n button.setAttribute('aria-label', label)\n\n return button\n}\n\n/**\n * Distance from `el`'s top edge to `ancestor`'s, from layout alone. Unlike a bounding rect it\n * ignores transforms, so an effect, swipe or zoom that is moving `el` does not skew it.\n */\nfunction layoutTop(el: HTMLElement, ancestor: Element | null): number {\n let top = 0\n for (let node: Element | null = el; node instanceof HTMLElement && node !== ancestor; node = node.offsetParent) {\n top += node.offsetTop\n }\n\n return top\n}\n\n/**\n * Lays out the caption: slides reserve its height through `--glare-caption-inset`, and it sits\n * right under the media of the slide passed to `follow`. Until then it rests at the bottom.\n */\nexport function trackCaption({ container, caption }: GlareRefs): { follow(slide: HTMLElement): void; destroy(): void } {\n let slide: HTMLElement | null = null\n\n const sync = () => {\n if (!caption) return\n container.style.setProperty('--glare-caption-inset', `${caption.offsetHeight}px`)\n\n const content = slide && $('.glare-content', slide)\n if (!content) return\n Object.assign(caption.style, { top: `${layoutTop(content, caption.offsetParent) + content.offsetHeight}px`, bottom: 'auto' })\n }\n\n // The slide's content box changes with the insets, and the content's with the media.\n const observer = new ResizeObserver(sync)\n if (caption) observer.observe(caption)\n sync()\n\n return {\n follow(next) {\n if (slide) for (const el of [slide, $('.glare-content', slide)]) if (el) observer.unobserve(el)\n slide = next\n for (const el of [next, $('.glare-content', next)]) if (el) observer.observe(el)\n sync()\n },\n destroy: () => observer.disconnect(),\n }\n}\n\n/** Creates a hidden slide with an empty content box and appends it to the stage. */\nexport function mountSlide(stage: HTMLElement, item: SlideItem, opts: ResolvedOptions): HTMLElement {\n const slide = createEl('div', `glare-slide glare-slide--${item.type}`)\n if (opts.slideClass) slide.classList.add(opts.slideClass)\n\n const content = createEl('div', 'glare-content')\n slide.appendChild(content)\n stage.appendChild(slide)\n\n item.$slide = slide\n item.$content = content\n return slide\n}\n\n/** Which way a slide change goes: 1 towards later slides, -1 towards earlier ones. */\nexport type Direction = 1 | -1\n\n/**\n * Makes a mounted slide the current one, fading it in unless `opening`. The first slide is\n * marked `--opening` and later ones `--in`, so open animations and slide-change effects each\n * have their own target. Every slide carries the direction it arrived from, for effects to mirror.\n */\nexport function revealSlide(slide: HTMLElement, opening: boolean, direction: Direction): void {\n slide.style.setProperty('--glare-direction', String(direction))\n slide.classList.add(opening ? 'glare-slide--opening' : 'glare-slide--in')\n if (opening) slide.style.transition = 'none'\n\n // Force a style flush so the opacity change below is transitioned (or not) as intended.\n void slide.offsetWidth\n slide.classList.add('glare-slide--current')\n\n if (opening) {\n void slide.offsetWidth\n slide.style.transition = ''\n }\n}\n\n/** Fades out every slide except `keep` and removes it after `delay`. */\nexport function retireSlides(stage: HTMLElement, keep: HTMLElement, delay: number, direction: Direction): void {\n for (const slide of $$('.glare-slide', stage)) {\n if (slide === keep) continue\n // A slide that is already leaving keeps the direction it left in.\n if (!slide.classList.contains('glare-slide--out')) slide.style.setProperty('--glare-direction', String(direction))\n slide.classList.remove('glare-slide--current', 'glare-slide--in', 'glare-slide--opening')\n slide.classList.add('glare-slide--out')\n setTimeout(() => slide.remove(), delay)\n }\n}\n\nexport function addSmallButton(slide: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void {\n slide.insertAdjacentHTML('beforeend', translate(opts.btnTpl.smallBtn ?? '', dict))\n}\n\nexport function showSpinner(stage: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void {\n if (!stage.querySelector(':scope > .glare-spinner')) {\n stage.insertAdjacentHTML('beforeend', translate(opts.spinnerTpl, dict))\n }\n}\n\nexport function hideSpinner(stage: HTMLElement): void {\n stage.querySelector(':scope > .glare-spinner')?.remove()\n}\n\nexport function showError(item: SlideItem, error: unknown, opts: ResolvedOptions, dict: I18nDict): void {\n item.hasError = true\n item.error = error\n if (!item.$content) return\n\n item.$content.className = 'glare-content glare-content--error'\n item.$content.innerHTML = translate(opts.errorTpl, dict)\n}\n\nfunction isToolbarVisible(opts: ResolvedOptions, item: SlideItem): boolean {\n if (typeof opts.toolbar === 'boolean') return opts.toolbar\n return item.type === 'image'\n}\n\nexport function usesSmallButton(opts: ResolvedOptions, item: SlideItem): boolean {\n if (typeof opts.smallBtn === 'boolean') return opts.smallBtn\n return !isToolbarVisible(opts, item)\n}\n\n/** Updates every piece of chrome that depends on the current slide. */\nexport function syncChrome(refs: GlareRefs, opts: ResolvedOptions, dict: I18nDict, item: SlideItem, total: number, caption: string): void {\n const { container, toolbar, infobar } = refs\n\n setTypeClass(container, item.type)\n if (toolbar) syncToolbar(toolbar, opts, item)\n syncDownloadLink(container, item)\n if (infobar) syncInfobar(infobar, item.index, total)\n if (refs.caption) syncCaption(refs.caption, caption)\n syncArrows(container, opts, item.index, total)\n syncDialogLabel(container, dict, item, total)\n}\n\n/** Shows the toolbar for images; with `toolbar: true` other types keep everything except zoom. */\nfunction syncToolbar(toolbar: HTMLElement, opts: ResolvedOptions, item: SlideItem): void {\n if (opts.toolbar === false) return\n\n toolbar.classList.remove('glare-toolbar--expanded')\n toolbar.querySelector('[data-glare-more]')?.setAttribute('aria-expanded', 'false')\n\n const visible = isToolbarVisible(opts, item)\n toolbar.classList.toggle(HIDDEN, !visible)\n if (!visible) return\n\n const zoomable = item.type === 'image'\n $('[data-glare-zoom]', toolbar)?.classList.toggle(HIDDEN, !zoomable)\n}\n\nfunction syncDownloadLink(container: HTMLElement, item: SlideItem): void {\n const link = container.querySelector<HTMLAnchorElement>('[data-glare-download]')\n if (!link) return\n\n const href = item.downloadSrc || (item.type === 'image' ? item.src : '')\n link.classList.toggle(HIDDEN, !href)\n if (href) link.href = href\n}\n\nfunction syncInfobar(infobar: HTMLElement, index: number, total: number): void {\n const indexEl = $('.glare-infobar-index', infobar)\n if (indexEl) indexEl.textContent = `${index + 1} / ${total}`\n}\n\nfunction syncCaption(caption: HTMLElement, html: string): void {\n caption.innerHTML = html\n caption.classList.toggle(HIDDEN, !html)\n}\n\nfunction syncArrows(container: HTMLElement, opts: ResolvedOptions, index: number, total: number): void {\n const atStart = !opts.loop && index === 0\n const atEnd = !opts.loop && index === total - 1\n setDisabled($('[data-glare-prev]', container), atStart)\n setDisabled($('[data-glare-next]', container), atEnd)\n}\n\nfunction setDisabled(button: HTMLElement | null, disabled: boolean): void {\n if (!button) return\n button.classList.toggle('glare-is-disabled', disabled)\n button.setAttribute('aria-disabled', String(disabled))\n}\n\n/** Labels the dialog and announces the slide change through the live region. */\nfunction syncDialogLabel(container: HTMLElement, dict: I18nDict, item: SlideItem, total: number): void {\n const base = toText(item.caption) || item.alt || dict.LIGHTBOX\n const label = total > 1 ? `${base} (${item.index + 1} of ${total})` : base\n\n container.setAttribute('aria-label', label)\n const live = $('.glare-live', container)\n if (live) live.textContent = label\n}\n\nfunction setTypeClass(el: HTMLElement, type: string): void {\n const previous = el.dataset.type\n if (previous) el.classList.remove(`glare-type-${previous}`)\n el.dataset.type = type\n el.classList.add(`glare-type-${type}`)\n}\n\nexport function syncZoomButton(container: HTMLElement, dict: I18nDict, zoomed: boolean, hasImage: boolean): void {\n container.classList.toggle('glare-can-zoom-out', zoomed)\n container.classList.toggle('glare-can-zoom-in', !zoomed && hasImage)\n\n const button = $('[data-glare-zoom]', container)\n const state = zoomed ? 'out' : 'in'\n if (!button || button.dataset.state === state) return\n\n button.dataset.state = state\n setToggleState(button, zoomed, zoomed ? dict.ZOOM_OUT : dict.ZOOM, zoomed ? icons.zoomOut : icons.zoomIn)\n}\n\n/** Swaps a toolbar toggle's label and icon and marks it active. */\nexport function setToggleState(button: HTMLElement, active: boolean, label: string, icon: string): void {\n button.setAttribute('title', label)\n button.setAttribute('aria-label', label)\n button.innerHTML = icon\n button.classList.toggle('glare-is-active', active)\n}\n","import type { FullscreenOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { setToggleState } from '../core/dom'\nimport { icons } from '../icons'\nimport { $, on } from '../utils/dom'\n\ntype FullscreenDocument = Document & {\n webkitFullscreenElement?: Element | null\n webkitExitFullscreen?: () => Promise<void> | void\n}\n\ntype FullscreenElement = HTMLElement & {\n webkitRequestFullscreen?: () => Promise<void> | void\n}\n\n/** Fullscreen API wrapper with the WebKit fallback still needed by Safari. */\nexport class Fullscreen {\n private readonly offs: Array<() => void>\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n opts: FullscreenOptions,\n ) {\n this.offs = [\n on(document, 'fullscreenchange', () => this.sync()),\n on(document, 'webkitfullscreenchange', () => this.sync()),\n ]\n if (opts.autoStart) this.request()\n }\n\n isFullscreen(): boolean {\n const doc = document as FullscreenDocument\n return Boolean(doc.fullscreenElement ?? doc.webkitFullscreenElement)\n }\n\n request(): void {\n const el = this.container as FullscreenElement\n const request = el.requestFullscreen ?? el.webkitRequestFullscreen\n void request?.call(el)\n }\n\n exit(): void {\n if (!this.isFullscreen()) return\n const doc = document as FullscreenDocument\n const exit = doc.exitFullscreen ?? doc.webkitExitFullscreen\n void exit?.call(document)\n }\n\n toggle(): void {\n if (this.isFullscreen()) this.exit()\n else this.request()\n }\n\n destroy(): void {\n this.exit()\n this.offs.forEach((off) => off())\n }\n\n private sync(): void {\n const active = this.isFullscreen()\n this.container.classList.toggle('glare-is-fullscreen', active)\n\n const button = $('[data-glare-fullscreen]', this.container)\n if (!button) return\n\n const { dict } = this.glare\n setToggleState(\n button,\n active,\n active ? dict.FULL_SCREEN_EXIT : dict.FULL_SCREEN,\n active ? icons.fullscreenExit : icons.fullscreen,\n )\n }\n}\n","function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const proto = Object.getPrototypeOf(value)\n // An `Object.prototype` from any window, so options passed across frames still merge.\n return proto === null || Object.getPrototypeOf(proto) === null\n}\n\n/** Recursively merges plain objects; other values (arrays, elements, RegExps) are replaced. */\nexport function deepMerge<T extends object>(...sources: Array<object | null | undefined | false>): T {\n const result: Record<string, unknown> = {}\n\n for (const source of sources) {\n if (!source) continue\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue\n const existing = result[key]\n result[key] = isPlainObject(value)\n ? deepMerge(isPlainObject(existing) ? existing : {}, value)\n : value\n }\n }\n\n return result as T\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n","import { clamp } from '../utils/object'\n\nexport interface Point {\n x: number\n y: number\n}\n\nexport interface ZoomState extends Point {\n scale: number\n}\n\nexport interface ZoomTarget {\n image(): HTMLImageElement | null\n stage(): HTMLElement | null\n onChange(zoomed: boolean): void\n}\n\nexport const ZOOM_MIN = 1\nexport const ZOOM_MAX = 5\nconst ZOOMED_THRESHOLD = 1.01\n\n/**\n * Controls the transform of the current image.\n * The image is scaled around its centre and then translated by (x, y).\n */\nexport class Zoom {\n scale = ZOOM_MIN\n x = 0\n y = 0\n\n constructor(private readonly target: ZoomTarget) {}\n\n get isZoomed(): boolean {\n return this.scale > ZOOMED_THRESHOLD\n }\n\n get state(): ZoomState {\n return { scale: this.scale, x: this.x, y: this.y }\n }\n\n /** Centre of the image in viewport coordinates, ignoring the current translation. */\n center(): Point | null {\n const image = this.target.image()\n if (!image) return null\n const rect = image.getBoundingClientRect()\n return { x: rect.left + rect.width / 2 - this.x, y: rect.top + rect.height / 2 - this.y }\n }\n\n apply(scale: number, x: number, y: number, duration = 0): void {\n const image = this.target.image()\n if (!image) return\n\n this.scale = clamp(scale, ZOOM_MIN, ZOOM_MAX)\n const translate = this.isZoomed ? this.bounded(x, y) : { x: 0, y: 0 }\n this.x = translate.x\n this.y = translate.y\n\n image.style.transitionDuration = `${duration}ms`\n image.style.transform = `translate3d(${this.x}px, ${this.y}px, 0) scale(${this.scale})`\n this.target.onChange(this.isZoomed)\n }\n\n toFit(duration = 300): void {\n this.apply(ZOOM_MIN, 0, 0, duration)\n }\n\n /** Zooms to the image's natural size (at least 1.5x), keeping `focus` under the pointer. */\n toActual(focus?: Partial<Point>, duration = 300): void {\n const image = this.target.image()\n const center = this.center()\n if (!image || !center) return\n\n const natural = image.naturalWidth / Math.max(image.offsetWidth, 1)\n const scale = clamp(Math.max(natural, 1.5), ZOOM_MIN, ZOOM_MAX)\n const fx = focus?.x ?? center.x\n const fy = focus?.y ?? center.y\n this.apply(scale, (center.x - fx) * (scale - 1), (center.y - fy) * (scale - 1), duration)\n }\n\n reset(): void {\n const image = this.target.image()\n if (image) {\n image.style.transform = ''\n image.style.transitionDuration = ''\n }\n this.scale = ZOOM_MIN\n this.x = 0\n this.y = 0\n this.target.onChange(false)\n }\n\n /** Keeps the scaled image from being dragged fully out of the stage. */\n private bounded(x: number, y: number): Point {\n const image = this.target.image()\n const stage = this.target.stage()\n if (!image || !stage) return { x, y }\n const maxX = Math.max(0, (image.offsetWidth * this.scale - stage.clientWidth) / 2)\n const maxY = Math.max(0, (image.offsetHeight * this.scale - stage.clientHeight) / 2)\n return { x: clamp(x, -maxX, maxX), y: clamp(y, -maxY, maxY) }\n }\n}\n","import type { TouchOptions } from '../types'\nimport type { Point, Zoom, ZoomState } from '../core/zoom'\nimport { on } from '../utils/dom'\nimport { clamp } from '../utils/object'\nimport { ZOOM_MAX, ZOOM_MIN } from '../core/zoom'\n\nexport interface GestureHost {\n zoom: Zoom\n touch: TouchOptions\n /** The backdrop, dimmed while the stage is dragged vertically. */\n bg: HTMLElement | null\n /** Whether the current slide can be panned when zoomed. */\n canPan(): boolean\n close(): void\n next(): void\n prev(): void\n}\n\ntype Mode = 'idle' | 'swipe' | 'pan' | 'pinch'\n\nconst MOVE_THRESHOLD = 6\nconst MOMENTUM = 120\nconst SWIPE_CLOSE_DISTANCE = 100\nconst SWIPE_CLOSE_VELOCITY = 0.5\nconst SWIPE_NAV_DISTANCE = 80\nconst SWIPE_NAV_VELOCITY = 0.4\nconst IGNORED_TARGETS = 'a, button, input, textarea, select, video, .glare-thumbs'\n\nconst distance = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y)\nconst midpoint = (a: Point, b: Point): Point => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 })\nconst pointOf = (event: PointerEvent): Point => ({ x: event.clientX, y: event.clientY })\n\n/** Swipe, pan and pinch handling on top of Pointer Events. */\nexport class Gestures {\n private readonly pointers = new Map<number, Point>()\n private readonly offs: Array<() => void>\n private mode: Mode = 'idle'\n private moved = false\n private start: Point[] = []\n private startTime = 0\n private startZoom: ZoomState = { scale: 1, x: 0, y: 0 }\n private startMid: Point = { x: 0, y: 0 }\n private startDistance = 0\n\n constructor(\n private readonly stage: HTMLElement,\n private readonly host: GestureHost,\n ) {\n this.offs = [\n on(stage, 'pointerdown', (event) => this.onDown(event)),\n on(window, 'pointermove', (event) => this.onMove(event), { passive: false }),\n on(window, 'pointerup', (event) => this.onUp(event)),\n on(window, 'pointercancel', (event) => this.onUp(event)),\n ]\n }\n\n destroy(): void {\n this.offs.forEach((off) => off())\n this.pointers.clear()\n }\n\n /** Returns whether the last gesture moved, then clears the flag. */\n consumeMoved(): boolean {\n const moved = this.moved\n this.moved = false\n return moved\n }\n\n private onDown(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return\n if ((event.target as Element).closest(IGNORED_TARGETS)) return\n\n this.pointers.set(event.pointerId, pointOf(event))\n if (this.pointers.size <= 2) this.begin()\n }\n\n private onMove(event: PointerEvent): void {\n if (!this.pointers.has(event.pointerId)) return\n this.pointers.set(event.pointerId, pointOf(event))\n this.move(event)\n }\n\n private onUp(event: PointerEvent): void {\n if (!this.pointers.has(event.pointerId)) return\n this.pointers.delete(event.pointerId)\n\n if (this.pointers.size === 0) this.end(pointOf(event))\n else this.begin()\n }\n\n /** Anchors a new gesture on the currently pressed pointers. */\n private begin(): void {\n if (this.mode === 'swipe') this.releaseStage()\n\n const points = [...this.pointers.values()]\n this.start = points\n this.startTime = performance.now()\n this.startZoom = this.host.zoom.state\n this.mode = points.length >= 2 ? 'pinch' : 'idle'\n\n if (points.length >= 2) {\n this.startDistance = distance(points[0], points[1])\n this.startMid = midpoint(points[0], points[1])\n }\n }\n\n private move(event: PointerEvent): void {\n const points = [...this.pointers.values()]\n if (!this.start.length || !points.length) return\n\n if (this.mode === 'pinch' && points.length >= 2) {\n event.preventDefault()\n this.moved = true\n this.pinch(points[0], points[1])\n return\n }\n\n const dx = points[0].x - this.start[0].x\n const dy = points[0].y - this.start[0].y\n if (!this.moved && Math.hypot(dx, dy) < MOVE_THRESHOLD) return\n this.moved = true\n\n if (this.mode === 'idle') {\n this.mode = this.host.zoom.isZoomed && this.host.canPan() ? 'pan' : 'swipe'\n }\n\n if (this.mode === 'pan') {\n event.preventDefault()\n this.host.zoom.apply(this.startZoom.scale, this.startZoom.x + dx, this.startZoom.y + dy)\n } else if (this.mode === 'swipe') {\n const vertical = this.host.touch.vertical !== false\n if (!vertical && Math.abs(dy) > Math.abs(dx)) return\n event.preventDefault()\n this.dragStage(dx, vertical ? dy : 0)\n }\n }\n\n /** Scales around the pinch midpoint so the content under the fingers stays put. */\n private pinch(a: Point, b: Point): void {\n const { zoom } = this.host\n const mid = midpoint(a, b)\n const center = zoom.center() ?? mid\n const scale = clamp(\n (this.startZoom.scale * distance(a, b)) / (this.startDistance || 1),\n ZOOM_MIN,\n ZOOM_MAX,\n )\n\n // Image-space offset of the point that was under the starting midpoint.\n const ox = (this.startMid.x - center.x - this.startZoom.x) / this.startZoom.scale\n const oy = (this.startMid.y - center.y - this.startZoom.y) / this.startZoom.scale\n zoom.apply(scale, mid.x - center.x - scale * ox, mid.y - center.y - scale * oy)\n }\n\n private end(last: Point): void {\n if (!this.start.length) return\n\n const elapsed = Math.max(performance.now() - this.startTime, 1)\n const dx = last.x - this.start[0].x\n const dy = last.y - this.start[0].y\n const velocity = { x: dx / elapsed, y: dy / elapsed }\n\n if (this.mode === 'swipe') {\n this.releaseStage()\n this.finishSwipe(dx, dy, velocity)\n } else if (this.mode === 'pan' && this.host.touch.momentum !== false) {\n const { zoom } = this.host\n zoom.apply(zoom.scale, zoom.x + velocity.x * MOMENTUM, zoom.y + velocity.y * MOMENTUM, 250)\n }\n\n this.mode = 'idle'\n this.start = []\n // Let the click that follows this gesture see `moved`, then forget it.\n if (this.moved) setTimeout(() => (this.moved = false), 0)\n }\n\n /** Moves the whole stage with the finger and dims the backdrop on vertical drags. */\n private dragStage(dx: number, dy: number): void {\n this.stage.style.transitionDuration = '0ms'\n this.stage.style.transform = `translate3d(${dx}px, ${dy}px, 0)`\n\n const { bg } = this.host\n if (bg) {\n bg.style.transitionDuration = '0ms'\n bg.style.opacity = String(clamp(1 - Math.abs(dy) / 400, 0.35, 1))\n }\n }\n\n private releaseStage(): void {\n this.stage.style.transitionDuration = ''\n this.stage.style.transform = ''\n\n const { bg } = this.host\n if (bg) {\n bg.style.transitionDuration = ''\n bg.style.opacity = ''\n }\n }\n\n /** A long or fast vertical swipe closes; a horizontal one navigates. */\n private finishSwipe(dx: number, dy: number, velocity: Point): void {\n const vertical = Math.abs(dy) > Math.abs(dx)\n\n if (vertical) {\n if (Math.abs(dy) > SWIPE_CLOSE_DISTANCE || Math.abs(velocity.y) > SWIPE_CLOSE_VELOCITY) this.host.close()\n return\n }\n\n if (Math.abs(dx) > SWIPE_NAV_DISTANCE || Math.abs(velocity.x) > SWIPE_NAV_VELOCITY) {\n if (dx < 0) this.host.next()\n else this.host.prev()\n }\n }\n}\n","import type { Glare } from '../core/glare'\nimport { on } from '../utils/dom'\n\nconst HASH_PATTERN = /^(.+)-(\\d+)$/\n\n/** Parses `#gallery-3` into `{ gallery: 'gallery', index: 2 }`. */\nexport function parseHash(hash = window.location.hash): { gallery: string; index: number } | null {\n const match = hash.replace(/^#/, '').match(HASH_PATTERN)\n if (!match) return null\n return { gallery: match[1], index: Math.max(0, parseInt(match[2], 10) - 1) }\n}\n\nfunction formatHash(gallery: string, index: number): string {\n return `${gallery}-${index + 1}`\n}\n\n/**\n * Keeps the URL hash in sync with the current slide of a named gallery.\n * Opening pushes one history entry so the browser's Back button closes the lightbox;\n * slide changes replace it so Back never walks through every slide.\n */\nexport class Hash {\n private readonly off: () => void\n private pushed = false\n\n constructor(\n private readonly glare: Glare,\n private readonly gallery: string,\n ) {\n this.off = on(window, 'hashchange', () => this.onHashChange())\n\n const next = formatHash(gallery, glare.currIndex)\n if (currentHash() !== next) {\n window.history.pushState(null, '', `#${next}`)\n this.pushed = true\n }\n }\n\n update(index = this.glare.currIndex): void {\n const next = formatHash(this.gallery, index)\n if (currentHash() !== next) this.replace(`#${next}`)\n }\n\n destroy(): void {\n this.off()\n if (parseHash()?.gallery !== this.gallery) return\n\n if (this.pushed) window.history.back()\n else this.replace('')\n }\n\n private onHashChange(): void {\n const parsed = parseHash()\n if (!parsed || parsed.gallery !== this.gallery) {\n this.pushed = false\n this.glare.close()\n } else if (parsed.index !== this.glare.currIndex) {\n this.glare.jumpTo(parsed.index)\n }\n }\n\n private replace(hash: string): void {\n const { pathname, search } = window.location\n window.history.replaceState(null, '', `${pathname}${search}${hash}`)\n }\n}\n\nconst currentHash = (): string => window.location.hash.replace(/^#/, '')\n","import type { SlideshowOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { setToggleState } from '../core/dom'\nimport { slideshowDefaults } from '../defaults'\nimport { icons } from '../icons'\nimport { $ } from '../utils/dom'\nimport { prefersReducedMotion } from '../utils/env'\n\n/** Advances slides on a timer and animates the top progress bar. */\nexport class Slideshow {\n private readonly bar: HTMLElement | null\n private readonly button: HTMLElement | null\n private timer: ReturnType<typeof setTimeout> | null = null\n private active = false\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: SlideshowOptions,\n ) {\n this.bar = $('.glare-progress', container)\n this.button = $('[data-glare-slideshow]', container)\n if (opts.autoStart) this.start()\n }\n\n isActive(): boolean {\n return this.active\n }\n\n start(): void {\n if (this.glare.group.length < 2) return\n\n this.active = true\n this.container.classList.add('glare-is-slideshow')\n this.syncButton()\n this.schedule()\n }\n\n stop(): void {\n this.active = false\n this.clearTimer()\n this.setProgress(0, true)\n this.container.classList.remove('glare-is-slideshow')\n this.syncButton()\n }\n\n toggle(): void {\n if (this.active) this.stop()\n else this.start()\n }\n\n onIndexChange(): void {\n if (this.active) this.schedule()\n }\n\n destroy(): void {\n this.stop()\n }\n\n private get speed(): number {\n return this.opts.speed ?? slideshowDefaults.speed\n }\n\n private get atEnd(): boolean {\n return !this.glare.opts.loop && this.glare.currIndex === this.glare.group.length - 1\n }\n\n private schedule(): void {\n this.clearTimer()\n this.setProgress(0)\n\n if (!prefersReducedMotion()) {\n // Force a reflow so the bar restarts from zero before animating.\n void this.bar?.offsetWidth\n this.setProgress(1)\n }\n\n this.timer = setTimeout(() => (this.atEnd ? this.stop() : this.glare.next()), this.speed)\n }\n\n private clearTimer(): void {\n if (this.timer) clearTimeout(this.timer)\n this.timer = null\n }\n\n private setProgress(value: 0 | 1, hide = false): void {\n if (!this.bar) return\n\n this.bar.hidden = hide\n this.bar.style.transitionDuration = value ? `${this.speed}ms` : '0ms'\n this.bar.style.transform = `scaleX(${value})`\n }\n\n private syncButton(): void {\n if (!this.button) return\n\n const { dict } = this.glare\n setToggleState(\n this.button,\n this.active,\n this.active ? dict.PLAY_STOP : dict.PLAY_START,\n this.active ? icons.pause : icons.play,\n )\n }\n}\n","import type { ContentType, SlideItem, ThumbsOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { icons } from '../icons'\nimport { $, $$, createEl, on, resolveElement, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\nconst placeholderIcons: Record<ContentType, string> = {\n image: icons.thumbImage,\n video: icons.thumbVideo,\n embed: icons.thumbEmbed,\n iframe: icons.thumbIframe,\n inline: icons.thumbInline,\n ajax: icons.thumbAjax,\n html: icons.thumbHtml,\n}\n\nfunction thumbnailSource(item: SlideItem): string {\n return item.thumb || (item.type === 'video' ? item.poster : '') || (item.type === 'image' ? item.src : '')\n}\n\nfunction showPlaceholder(button: HTMLButtonElement, type: ContentType): void {\n button.classList.add('glare-thumbs-item--placeholder')\n button.innerHTML = placeholderIcons[type] ?? icons.thumbSlide\n}\n\n/** Clickable thumbnail strip, horizontal (`x`) or vertical (`y`). */\nexport class Thumbs {\n isActive = false\n private readonly axis: 'x' | 'y'\n private readonly strip: HTMLElement\n private readonly list: HTMLElement\n private offs: Array<() => void> = []\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: ThumbsOptions,\n ) {\n this.axis = opts.axis === 'y' ? 'y' : 'x'\n this.list = createEl('div', 'glare-thumbs-list')\n this.strip = createEl('div', `glare-thumbs glare-thumbs--${this.axis}`)\n this.strip.style.setProperty('--glare-thumbs-fit', opts.fit ?? 'cover')\n this.strip.appendChild(this.list)\n this.build()\n }\n\n show(): void {\n this.setActive(true)\n }\n\n hide(): void {\n this.setActive(false)\n }\n\n toggle(): void {\n this.setActive(!this.isActive)\n }\n\n /** Highlights the thumbnail for `index` and scrolls it into view. */\n focus(index = this.glare.currIndex): void {\n for (const el of $$('.glare-thumbs-item', this.list)) {\n el.classList.toggle('glare-is-active', Number(el.dataset.index) === index)\n }\n this.list\n .querySelector('.glare-is-active')\n ?.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' })\n }\n\n destroy(): void {\n this.offs.forEach((off) => off())\n this.offs = []\n this.container.classList.remove(`glare-thumbs-axis-${this.axis}`)\n this.strip.remove()\n }\n\n private setActive(active: boolean): void {\n this.isActive = active\n this.strip.classList.toggle('glare-thumbs--active', active)\n this.container.classList.toggle('glare-show-thumbs', active)\n\n const button = $('[data-glare-thumbs]', this.container)\n button?.classList.toggle('glare-is-active', active)\n button?.setAttribute('aria-expanded', String(active))\n }\n\n private build(): void {\n const { group, dict } = this.glare\n if (group.length < 2) return\n\n this.container.classList.add(`glare-thumbs-axis-${this.axis}`)\n\n for (const item of group) {\n const button = createEl('button', 'glare-thumbs-item')\n button.type = 'button'\n button.dataset.index = String(item.index)\n button.setAttribute('aria-label', translate(dict.GO_TO_SLIDE, { index: String(item.index + 1) }))\n\n const src = thumbnailSource(item)\n if (src) {\n const img = createEl('img')\n img.src = src\n img.alt = item.alt || toText(item.caption)\n img.loading = 'lazy'\n img.onerror = () => showPlaceholder(button, item.type)\n button.appendChild(img)\n } else {\n showPlaceholder(button, item.type)\n }\n\n this.list.appendChild(button)\n this.offs.push(on(button, 'click', () => this.glare.jumpTo(item.index)))\n }\n\n const parent = resolveElement(this.opts.parentEl, this.container) ?? this.container\n parent.appendChild(this.strip)\n if (this.opts.autoStart) this.show()\n this.focus()\n }\n}\n","import type { SlideItem } from '../types'\nimport { on } from '../utils/dom'\n\nexport interface WheelHost {\n /** `'auto'` only navigates on image slides; `true` on every slide. */\n mode: boolean | 'auto'\n current(): SlideItem | null\n isZoomed(): boolean\n next(): void\n prev(): void\n}\n\n/** Accumulated distance that counts as one deliberate scroll. */\nconst STEP = 40\n/** Gap between events that marks the end of a gesture, including trackpad inertia. */\nconst SETTLE = 150\nconst LINE_HEIGHT = 16\n\n/** Mouse-wheel navigation between slides: one gesture moves one slide. */\nexport class WheelNav {\n private readonly off: () => void\n private distance = 0\n private fired = false\n private settle: ReturnType<typeof setTimeout> | null = null\n\n constructor(stage: HTMLElement, host: WheelHost) {\n this.off = on(\n stage,\n 'wheel',\n (event) => {\n const current = host.current()\n if (!current || event.deltaY === 0) return\n if (host.mode === 'auto' && current.type !== 'image') return\n if (current.type === 'image' && host.isZoomed()) return\n\n event.preventDefault()\n this.restartSettle()\n if (this.fired) return\n\n this.distance += normalize(event, stage)\n if (Math.abs(this.distance) < STEP) return\n\n this.fired = true\n if (this.distance > 0) host.next()\n else host.prev()\n },\n { passive: false },\n )\n }\n\n destroy(): void {\n if (this.settle) clearTimeout(this.settle)\n this.off()\n }\n\n private restartSettle(): void {\n if (this.settle) clearTimeout(this.settle)\n this.settle = setTimeout(() => {\n this.distance = 0\n this.fired = false\n }, SETTLE)\n }\n}\n\n/** Converts line- and page-based deltas to pixels so every input reaches `STEP`. */\nfunction normalize(event: WheelEvent, stage: HTMLElement): number {\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) return event.deltaY * LINE_HEIGHT\n if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) return event.deltaY * stage.clientHeight\n return event.deltaY\n}\n","import type { Anchor, ResolvedOptions, SlideItem } from '../types'\nimport { nextFrame, resolveElement } from '../utils/dom'\nimport { prefersReducedMotion } from '../utils/env'\n\n/**\n * The motion actually in effect. An effect is off when it is disabled, its duration is zero,\n * or the user prefers reduced motion; its duration is then zero too. Timers must wait on these\n * values rather than the raw options, since a 0ms transition never fires `transitionend`.\n */\nexport function resolveMotion(opts: ResolvedOptions) {\n const reduced = prefersReducedMotion()\n const animationDuration = reduced || !opts.animationEffect ? 0 : Math.max(0, opts.animationDuration)\n const transitionDuration = reduced || !opts.transitionEffect ? 0 : Math.max(0, opts.transitionDuration)\n\n return {\n animationEffect: animationDuration ? opts.animationEffect : false,\n animationDuration,\n transitionEffect: transitionDuration ? opts.transitionEffect : false,\n transitionDuration,\n }\n}\n\n/** Writes the effect and duration settings onto the container for the stylesheet to use. */\nexport function applyMotionSettings(container: HTMLElement, opts: ResolvedOptions): void {\n const motion = resolveMotion(opts)\n\n container.dataset.animation = motion.animationEffect || 'none'\n container.style.setProperty('--glare-duration', `${motion.animationDuration}ms`)\n container.style.setProperty('--glare-transition-duration', `${motion.transitionDuration}ms`)\n}\n\n/** Marks the container so slide-change keyframes apply from now on. */\nexport function enableTransitions(container: HTMLElement, opts: ResolvedOptions): void {\n container.dataset.transition = resolveMotion(opts).transitionEffect || 'none'\n}\n\nconst POSITION = /^(top|center|bottom)-(left|center|right)$/\nconst FRACTION: Record<string, number> = { top: 0, left: 0, center: 0.5, bottom: 1, right: 1 }\n\n/** Resolves an anchor to the rectangle the image starts from; a position yields a zero-size one. */\nfunction anchorRect(container: HTMLElement, item: SlideItem, anchor: Anchor): DOMRect | null {\n const position = typeof anchor === 'string' ? POSITION.exec(anchor) : null\n if (position) {\n const box = container.getBoundingClientRect()\n const x = box.left + box.width * FRACTION[position[2]]\n const y = box.top + box.height * FRACTION[position[1]]\n return new DOMRect(x, y, 0, 0)\n }\n\n // An element that is not rendered has no box to fly from.\n const rendered = (el?: HTMLElement | null) => (el?.getClientRects().length ? el : null)\n const el = (anchor !== 'trigger' && rendered(resolveElement(anchor))) || rendered(item.$trigger)\n\n if (!el) return null\n\n // A trigger inside an iframe (see `delegate`) reports its box relative to that frame.\n const rect = el.getBoundingClientRect()\n const frame = el.ownerDocument === container.ownerDocument ? null : el.ownerDocument.defaultView?.frameElement\n const offset = frame?.getBoundingClientRect()\n return offset ? new DOMRect(rect.x + offset.x, rect.y + offset.y, rect.width, rect.height) : rect\n}\n\n/** Flies the opened image in from its anchor. */\nexport function animateOpen(container: HTMLElement, item: SlideItem, opts: ResolvedOptions): void {\n const image = item.$image\n if (container.dataset.animation !== 'zoom' || !image) return\n\n const from = anchorRect(container, item, opts.anchor)\n if (!from) return\n\n const to = image.getBoundingClientRect()\n const scale = Math.max(from.width / Math.max(to.width, 1), from.height / Math.max(to.height, 1))\n const dx = from.left + from.width / 2 - (to.left + to.width / 2)\n const dy = from.top + from.height / 2 - (to.top + to.height / 2)\n\n Object.assign(image.style, {\n transform: `translate3d(${dx}px, ${dy}px, 0) scale(${scale})`,\n opacity: opts.zoomOpacity ? '0.2' : '1',\n transitionDuration: '0ms',\n })\n nextFrame(() => {\n Object.assign(image.style, { transform: '', opacity: '', transitionDuration: '' })\n })\n}\n","import type { GlareOptions, ResolvedOptions } from '../types'\nimport { defaults } from '../defaults'\nimport { isMobile } from '../utils/env'\nimport { deepMerge } from '../utils/object'\n\n/** Merges user options over the defaults, then applies `mobile` overrides on touch devices. */\nexport function resolveOptions(options: GlareOptions): ResolvedOptions {\n const merged = deepMerge<ResolvedOptions>(defaults, options)\n return isMobile() && merged.mobile ? deepMerge<ResolvedOptions>(merged, merged.mobile) : merged\n}\n\n/** Normalizes a `T | boolean` module option: `true` yields the defaults, falsy disables it. */\nexport function moduleOptions<T extends object>(value: Partial<T> | boolean | undefined, fallback: T): T | null {\n if (!value) return null\n return value === true ? { ...fallback } : { ...fallback, ...value }\n}\n","import type { BoundGroup, GlareOptions } from '../types'\nimport { parseHash } from '../modules/hash'\nimport { $$, on } from '../utils/dom'\nimport { resolveOptions } from './options'\n\nexport type BindTarget = string | HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>\n\n/** Opens `elements` as a gallery named `gallery`, starting at `index`. */\ntype Opener = (elements: HTMLElement[], index: number, gallery: string) => void\n\nconst groups: BoundGroup[] = []\n\nconst galleryOf = (el: HTMLElement): string => el.getAttribute('data-glare') ?? ''\n\nfunction toElements(target: BindTarget): HTMLElement[] {\n if (typeof target === 'string') return $$(target)\n if (target instanceof HTMLElement) return [target]\n return Array.from(target)\n}\n\n/** Attaches click handlers that open a lightbox for the clicked element's gallery. */\nexport function bind(target: BindTarget, options: GlareOptions, open: Opener): BoundGroup {\n const elements = toElements(target)\n\n const openFrom = (el: HTMLElement) => {\n const gallery = galleryOf(el)\n const members = gallery ? elements.filter((item) => galleryOf(item) === gallery) : [el]\n open(members, members.indexOf(el), gallery)\n }\n\n const offs = elements.map((el) =>\n on(el, 'click', (event) => {\n event.preventDefault()\n openFrom(el)\n }),\n )\n\n const group: BoundGroup = {\n elements,\n destroy() {\n offs.forEach((off) => off())\n const index = groups.indexOf(group)\n if (index >= 0) groups.splice(index, 1)\n },\n }\n groups.push(group)\n\n if (resolveOptions(options).hash) restoreFromHash(elements, openFrom)\n return group\n}\n\nexport function unbindAll(): void {\n for (const group of [...groups]) group.destroy()\n}\n\n/** Opens the slide referenced by the current URL hash, if it belongs to a bound gallery. */\nfunction restoreFromHash(elements: HTMLElement[], openFrom: (el: HTMLElement) => void): void {\n const parsed = parseHash()\n if (!parsed) return\n\n const members = elements.filter((el) => galleryOf(el) === parsed.gallery)\n const el = members[parsed.index]\n if (el) openFrom(el)\n}\n","/** Calls `onIdle` after `seconds` of no activity; `false` disables it. */\nexport class IdleTimer {\n private timer: ReturnType<typeof setTimeout> | null = null\n\n constructor(\n private readonly seconds: number | false,\n private readonly onIdle: () => void,\n ) {}\n\n reset(): void {\n this.stop()\n if (this.seconds) this.timer = setTimeout(this.onIdle, this.seconds * 1000)\n }\n\n stop(): void {\n if (this.timer) clearTimeout(this.timer)\n this.timer = null\n }\n}\n","import type { Glare } from './glare'\n\n/** Stack of open instances, topmost last. */\nconst stack: Glare[] = []\n\nexport const registry = {\n add(instance: Glare): void {\n stack.push(instance)\n },\n remove(instance: Glare): void {\n const index = stack.indexOf(instance)\n if (index >= 0) stack.splice(index, 1)\n },\n top(): Glare | null {\n return stack[stack.length - 1] ?? null\n },\n get(id: number): Glare | null {\n return stack.find((instance) => instance.id === id) ?? null\n },\n all(): Glare[] {\n return [...stack]\n },\n get size(): number {\n return stack.length\n },\n}\n","import type { ClickAction, ClickActionName, CustomButton } from '../types'\nimport type { Glare } from './glare'\nimport { $$, on } from '../utils/dom'\nimport { registry } from './registry'\n\ntype ButtonHandler = (glare: Glare) => void\n\n/** Toolbar / navigation buttons, matched against `event.target` in order. */\nconst BUTTONS: Array<[selector: string, handler: ButtonHandler]> = [\n ['[data-glare-close]', (g) => g.close()],\n ['[data-glare-next]', (g) => g.next()],\n ['[data-glare-prev]', (g) => g.prev()],\n ['[data-glare-zoom]', (g) => g.toggleZoom()],\n ['[data-glare-slideshow]', (g) => g.slideshow?.toggle()],\n ['[data-glare-thumbs]', (g) => g.thumbs?.toggle()],\n ['[data-glare-fullscreen]', (g) => g.fullscreen?.toggle()],\n]\n\nconst CONTENT = '.glare-content'\nconst SLIDE_AREA = '.glare-slide, .glare-stage'\nconst FOCUSABLE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\nconst FORM_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\n/** How long a single click waits for a possible second click when a double-click action exists. */\nconst DBLCLICK_WINDOW = 300\n\n/** Wires clicks, keyboard, focus trapping and idle tracking. Returns a cleanup function. */\nexport function bindInteractions(glare: Glare, container: HTMLElement, onActivity: () => void): () => void {\n let pendingClick: ReturnType<typeof setTimeout> | null = null\n const cancelPending = () => {\n if (pendingClick) clearTimeout(pendingClick)\n pendingClick = null\n }\n\n const offs = [\n on(container, 'click', (event) => {\n if (glare.consumeGesture()) return\n\n const target = event.target as HTMLElement\n const more = target.closest<HTMLElement>('[data-glare-more]')\n\n if (more) {\n const toolbar = more.closest('.glare-toolbar')\n const expanded = !toolbar?.classList.contains('glare-toolbar--expanded')\n toolbar?.classList.toggle('glare-toolbar--expanded', expanded)\n more.setAttribute('aria-expanded', String(expanded))\n return\n }\n\n closeToolbarMenu(container)\n const custom = target.closest<HTMLElement>('[data-glare-custom]')\n if (custom) return runCustomButton(glare, custom.dataset.glareCustom, event)\n\n const button = BUTTONS.find(([selector]) => target.closest(selector))\n if (button) return button[1](glare)\n if (target.closest('.glare-button')) return\n\n const single = slideAction(glare, target, 'click')\n if (!single) return\n\n // When a double-click action exists, hold the single click so a double-tap does not fire both.\n if (!resolveAction(glare, slideAction(glare, target, 'dblclick'), event)) {\n return runAction(glare, single, event)\n }\n cancelPending()\n pendingClick = setTimeout(() => runAction(glare, single, event), DBLCLICK_WINDOW)\n }),\n on(container, 'dblclick', (event) => {\n cancelPending()\n const target = event.target as HTMLElement\n if (target.closest('.glare-button')) return\n runAction(glare, slideAction(glare, target, 'dblclick'), event)\n }),\n on(document, 'keydown', (event) => onKeydown(glare, event)),\n on(document, 'keydown', onActivity),\n on(document, 'click', onActivity, { capture: true }),\n on(document, 'mousemove', onActivity),\n on(document, 'touchstart', onActivity, { passive: true }),\n ]\n\n if (glare.opts.trapFocus) {\n offs.push(on(container, 'keydown', (event) => trapFocus(container, event)))\n }\n\n if (glare.opts.protect) {\n offs.push(\n on(container, 'contextmenu', (event) => event.preventDefault()),\n on(container, 'dragstart', (event) => {\n if ((event.target as HTMLElement).tagName === 'IMG') event.preventDefault()\n }),\n )\n }\n\n return () => {\n cancelPending()\n offs.forEach((off) => off())\n }\n}\n\n/** Runs the `click` of the inline button called `name`. */\nfunction runCustomButton(glare: Glare, name: string | undefined, event: MouseEvent): void {\n const button = glare.opts.buttons.find((b): b is CustomButton => typeof b !== 'string' && b.name === name)\n if (button && glare.current) button.click(glare, glare.current, event)\n}\n\n/** Picks the content action or the slide action for `target`; modal mode ignores the slide area. */\nfunction slideAction(glare: Glare, target: HTMLElement, kind: 'click' | 'dblclick'): ClickAction | undefined {\n const { opts } = glare\n if (target.closest(CONTENT)) return kind === 'click' ? opts.clickContent : opts.dblclickContent\n if (opts.modal || !target.closest(SLIDE_AREA)) return undefined\n return kind === 'click' ? opts.clickSlide : opts.dblclickSlide\n}\n\nfunction resolveAction(glare: Glare, action: ClickAction | undefined, event: Event): ClickActionName | false | void {\n if (!action || !glare.current) return false\n return typeof action === 'function' ? action(glare.current, event) : action\n}\n\nfunction runAction(glare: Glare, action: ClickAction | undefined, event: Event): void {\n switch (resolveAction(glare, action, event)) {\n case 'close':\n return glare.close()\n case 'next':\n return glare.next()\n case 'nextOrClose':\n return glare.currIndex === glare.group.length - 1 && !glare.opts.loop ? glare.close() : glare.next()\n case 'toggleControls':\n return glare.toggleControls()\n case 'zoom': {\n const point = event instanceof MouseEvent ? { x: event.clientX, y: event.clientY } : undefined\n return glare.toggleZoom(point)\n }\n }\n}\n\nfunction onKeydown(glare: Glare, event: KeyboardEvent): void {\n if (registry.top() !== glare) return\n\n if (event.key === 'Escape' && closeToolbarMenu(glare.$refs?.container ?? null)) {\n event.preventDefault()\n return\n }\n\n if (!glare.opts.keyboard || glare.opts.modal) return\n\n const target = event.target as HTMLElement\n if (FORM_TAGS.has(target.tagName)) return\n // A focused button already activates on Space; don't toggle the slideshow as well.\n if (event.key === ' ' && target.closest('button')) return\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n return glare.close()\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n return glare.next()\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n return glare.prev()\n case ' ':\n event.preventDefault()\n return glare.slideshow?.toggle()\n case 'f':\n case 'F':\n return glare.fullscreen?.toggle()\n }\n}\n\nfunction closeToolbarMenu(container: HTMLElement | null): boolean {\n const toolbar = container?.querySelector('.glare-toolbar--expanded')\n if (!toolbar) return false\n\n toolbar.classList.remove('glare-toolbar--expanded')\n toolbar.querySelector('[data-glare-more]')?.setAttribute('aria-expanded', 'false')\n return true\n}\n\nfunction trapFocus(container: HTMLElement, event: KeyboardEvent): void {\n if (event.key !== 'Tab') return\n\n const focusable = $$(FOCUSABLE, container).filter(\n (el) => !el.hasAttribute('disabled') && el.offsetParent !== null && getComputedStyle(el).visibility !== 'hidden',\n )\n if (!focusable.length) return\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n","import type { ContentType, I18nDict, ResolvedOptions, SlideItem } from '../types'\nimport { videoMime } from '../media/detect'\nimport { $, createEl, toCssSize, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\ntype Loader = (item: SlideItem, content: HTMLElement, opts: ResolvedOptions, dict: I18nDict) => Promise<void> | void\n\nconst IFRAME_LOAD_FALLBACK = 1200\nconst DEFAULT_EMBED_RATIO = 16 / 9\n\nfunction embedRatio(item: SlideItem, width?: number, height?: number): number {\n if (width && height) return width / height\n\n const value = String(item.ratio || DEFAULT_EMBED_RATIO).replace(':', '/')\n const [x, y = '1'] = value.split('/').map((part) => part.trim())\n const numerator = parseFloat(x)\n const denominator = parseFloat(y)\n return numerator > 0 && denominator > 0 ? numerator / denominator : DEFAULT_EMBED_RATIO\n}\n\nfunction toPixels(value: number | string | undefined, available: number, viewport: number): number {\n if (!value) return 0\n if (typeof value === 'number') return value\n\n const input = value.trim()\n const amount = parseFloat(input)\n\n if (!(amount > 0)) return 0\n if (input.endsWith('%')) return available * amount / 100\n if (input.endsWith('vw') || input.endsWith('vh')) return viewport * amount / 100\n\n return amount\n}\n\n/** Fits video dimensions inside the slide using the same ratio-first model as Fancybox v3. */\nfunction fitEmbed(item: SlideItem, content: HTMLElement): void {\n const slide = content.parentElement\n if (!slide) return\n\n const style = getComputedStyle(slide)\n const availableWidth = slide.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight)\n const availableHeight = slide.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom)\n if (!(availableWidth > 0 && availableHeight > 0)) return\n\n const hasDimensions = item.width !== undefined && item.height !== undefined\n let width = hasDimensions ? toPixels(item.width, availableWidth, innerWidth) : availableWidth\n let height = hasDimensions ? toPixels(item.height, availableHeight, innerHeight) : availableHeight\n const ratio = embedRatio(item, hasDimensions ? width : undefined, hasDimensions ? height : undefined)\n\n const scale = Math.min(1, availableWidth / width, availableHeight / height)\n width *= scale\n height *= scale\n\n if (height > width / ratio) height = width / ratio\n else if (width > height * ratio) width = height * ratio\n\n content.style.width = `${width}px`\n content.style.height = `${height}px`\n content.style.aspectRatio = String(ratio)\n}\n\nfunction observeEmbed(item: SlideItem, content: HTMLElement): void {\n fitEmbed(item, content)\n if (typeof ResizeObserver === 'undefined' || !content.parentElement) return\n\n const observer = new ResizeObserver(() => {\n if (!content.isConnected) return observer.disconnect()\n fitEmbed(item, content)\n })\n\n observer.observe(content.parentElement)\n}\n\nconst image: Loader = (item, content, opts) =>\n new Promise((resolve, reject) => {\n const img = createEl('img', 'glare-image')\n img.alt = item.alt || toText(item.caption)\n img.decoding = 'async'\n img.draggable = false\n if (opts.protect) img.style.pointerEvents = 'none'\n\n img.onload = () => {\n item.$image = img\n item.contentWidth = img.naturalWidth\n item.contentHeight = img.naturalHeight\n content.appendChild(img)\n resolve()\n }\n img.onerror = () => reject(new Error(`Failed to load image: ${item.src}`))\n img.src = item.src\n })\n\nconst video: Loader = (item, content, opts, dict) => {\n const format = item.format || opts.video.format || videoMime(item.src)\n content.innerHTML = translate(opts.video.tpl, {\n ...dict,\n src: item.src,\n format,\n poster: item.poster ?? '',\n })\n\n const el = content.querySelector('video')\n if (el && (item.autoStart ?? opts.video.autoStart)) {\n void el.play().catch(() => undefined)\n }\n}\n\nconst iframe: Loader = (item, content, opts) =>\n new Promise((resolve) => {\n const settings = opts.iframe\n const wrap = createEl('div', 'glare-iframe-wrap', settings.tpl)\n const frame = wrap.querySelector('iframe')\n if (!frame) throw new Error('Iframe template must contain an <iframe>')\n\n for (const [name, value] of Object.entries(settings.attr)) frame.setAttribute(name, value)\n Object.assign(frame.style, settings.css)\n content.appendChild(wrap)\n\n if (item.type === 'embed') {\n observeEmbed(item, content)\n } else {\n if (item.width) wrap.style.width = toCssSize(item.width)\n if (item.height) wrap.style.height = toCssSize(item.height)\n }\n\n if (!settings.preload) {\n frame.src = item.src\n resolve()\n return\n }\n\n frame.onload = () => resolve()\n frame.src = item.src\n // Cross-origin frames may never fire `load`; reveal the slide anyway.\n setTimeout(resolve, IFRAME_LOAD_FALLBACK)\n })\n\nconst inline: Loader = (item, content) => {\n const source = item.src ? $(item.src) : null\n if (!source) throw new Error(`Inline target not found: ${item.src}`)\n\n const clone = source.cloneNode(true) as HTMLElement\n clone.removeAttribute('id')\n clone.hidden = false\n clone.style.display = ''\n content.appendChild(clone)\n}\n\nconst ajax: Loader = async (item, content, opts) => {\n const response = await fetch(item.src, opts.ajax.settings)\n if (!response.ok) throw new Error(`Request failed: ${response.status} ${item.src}`)\n content.innerHTML = await response.text()\n}\n\nconst html: Loader = (item, content) => {\n if (item.content && typeof item.content === 'object') {\n content.appendChild(item.content)\n } else {\n content.innerHTML = item.html ?? item.content ?? item.src\n }\n}\n\nconst loaders: Record<ContentType, Loader> = { image, video, embed: iframe, iframe, inline, ajax, html }\n\n/** Renders the slide's content into `content` and resolves once it can be shown. */\nexport async function loadContent(item: SlideItem, content: HTMLElement, opts: ResolvedOptions, dict: I18nDict): Promise<void> {\n content.innerHTML = ''\n content.className = `glare-content glare-content--${item.type}`\n await loaders[item.type](item, content, opts, dict)\n item.isLoaded = true\n}\n\n/** Warms the browser cache for neighbouring images. */\nexport function preloadNeighbours(group: SlideItem[], index: number): void {\n for (const neighbour of [group[index - 1], group[index + 1]]) {\n if (neighbour?.type === 'image' && neighbour.src) new Image().src = neighbour.src\n }\n}\n","import type {\n BoundGroup,\n GlareInstance,\n GlareOptions,\n GlareRefs,\n I18nDict,\n LifecycleEvent,\n ResolvedOptions,\n SlideEvent,\n SlideItem,\n SlideSource,\n} from '../types'\nimport { defaults, fullscreenDefaults, slideshowDefaults, thumbsDefaults } from '../defaults'\nimport { getDict } from '../i18n'\nimport { createItems } from '../media/items'\nimport { Fullscreen } from '../modules/fullscreen'\nimport { Gestures } from '../modules/gestures'\nimport { Hash } from '../modules/hash'\nimport { Slideshow } from '../modules/slideshow'\nimport { Thumbs } from '../modules/thumbs'\nimport { WheelNav } from '../modules/wheel'\nimport { afterTransition, nextFrame } from '../utils/dom'\nimport { lockScroll, supportsFullscreen } from '../utils/env'\nimport { clamp } from '../utils/object'\nimport { animateOpen, applyMotionSettings, enableTransitions, resolveMotion } from './animation'\nimport { bind, unbindAll, type BindTarget } from './bind'\nimport * as dom from './dom'\nimport { IdleTimer } from './idle'\nimport { bindInteractions } from './interactions'\nimport { loadContent, preloadNeighbours } from './loaders'\nimport { moduleOptions, resolveOptions } from './options'\nimport { registry } from './registry'\nimport { Zoom, type Point } from './zoom'\n\nlet nextId = 0\n\n/** The `Glare` class loaded in another window. A cross-origin window throws on access and counts as having none. */\nfunction glareOf(target?: Window): typeof Glare | undefined {\n try {\n return (target as (Window & { Glare?: typeof Glare }) | undefined)?.Glare\n } catch {\n return undefined\n }\n}\n\nexport class Glare implements GlareInstance {\n readonly id = ++nextId\n readonly opts: ResolvedOptions\n readonly group: SlideItem[]\n readonly dict: I18nDict\n readonly zoom: Zoom\n current: SlideItem | null = null\n currIndex = 0\n prevIndex = 0\n isActive = false\n isClosing = false\n isIdle = false\n $refs: GlareRefs | null = null\n\n slideshow?: Slideshow\n thumbs?: Thumbs\n fullscreen?: Fullscreen\n\n private readonly galleryName: string\n private readonly idle: IdleTimer\n private hash: Hash | null = null\n private gestures: Gestures | null = null\n private wheel: WheelNav | null = null\n private cleanups: Array<() => void> = []\n private captionTracker: ReturnType<typeof dom.trackCaption> | null = null\n private previouslyFocused: HTMLElement | null = null\n private direction: dom.Direction = 1\n\n constructor(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n galleryName = '',\n ) {\n this.opts = resolveOptions(options)\n this.dict = getDict(this.opts)\n this.group = createItems(items, this.opts)\n this.galleryName = galleryName\n this.currIndex = this.clampIndex(index)\n\n this.zoom = new Zoom({\n image: () => this.current?.$image ?? null,\n stage: () => this.$refs?.stage ?? null,\n onChange: (zoomed) => this.syncZoomState(zoomed),\n })\n this.idle = new IdleTimer(this.opts.modal ? false : this.opts.idleTime, () => this.toggleControls(true))\n }\n\n open(index = this.currIndex): void {\n if (this.isActive) return this.jumpTo(index)\n if (!this.group.length) return\n if (this.opts.closeExisting) Glare.close(true)\n\n this.currIndex = this.clampIndex(index)\n this.current = this.group[this.currIndex]\n this.previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null\n this.emit('onInit')\n\n const refs = dom.buildContainer(this.opts, this.dict, this.id, this.group.length)\n const { container } = refs\n this.$refs = refs\n\n applyMotionSettings(container, this.opts)\n\n this.syncChrome()\n this.resolveParent().appendChild(container)\n this.captionTracker = dom.trackCaption(refs)\n this.cleanups.push(() => this.captionTracker?.destroy())\n\n this.isActive = true\n registry.add(this)\n if (this.opts.hideScrollbar) lockScroll(true)\n this.emit('onActivate')\n this.emitSlide('beforeShow', this.current)\n\n nextFrame(() => {\n if (!this.isActive) return\n\n container.classList.add('glare-is-open')\n this.showSlide(this.currIndex, true)\n this.cleanups.push(bindInteractions(this, container, () => this.onActivity()))\n this.startModules(refs)\n if (this.opts.autoFocus) this.focus()\n this.idle.reset()\n })\n }\n\n close(): void {\n if (!this.isActive || this.isClosing || !this.current || !this.$refs) return\n if (this.emitSlide('beforeClose', this.current) === false) return\n\n this.isClosing = true\n this.slideshow?.stop()\n this.idle.stop()\n\n const { container, bg } = this.$refs\n const duration = resolveMotion(this.opts).animationDuration\n if (duration === 0) return this.teardown()\n\n container.classList.remove('glare-is-open')\n container.classList.add('glare-is-closing')\n afterTransition(bg ?? container, duration, () => this.teardown())\n }\n\n next(): void {\n this.jumpTo(this.currIndex + 1)\n }\n\n prev(): void {\n this.jumpTo(this.currIndex - 1)\n }\n\n jumpTo(index: number): void {\n if (!this.isActive || this.isClosing) return\n\n const total = this.group.length\n const target = this.opts.loop ? ((index % total) + total) % total : clamp(index, 0, total - 1)\n if (target === this.currIndex) return\n\n // Compared before wrapping, so next() off the last slide still counts as forward.\n this.direction = index > this.currIndex ? 1 : -1\n this.prevIndex = this.currIndex\n this.currIndex = target\n this.zoom.reset()\n this.current = this.group[target]\n this.syncChrome()\n this.showSlide(target, false)\n\n this.thumbs?.focus(target)\n this.hash?.update(target)\n this.slideshow?.onIndexChange()\n this.emitSlide('onUpdate', this.current)\n }\n\n toggleZoom(focus?: Point): void {\n if (this.current?.type !== 'image') return\n if (this.zoom.isZoomed) this.zoom.toFit()\n else this.zoom.toActual(focus)\n }\n\n update(): void {\n this.syncChrome()\n }\n\n focus(): void {\n this.$refs?.container.focus({ preventScroll: true })\n }\n\n toggleControls(force?: boolean): void {\n if (!this.$refs) return\n this.isIdle = force ?? !this.isIdle\n this.$refs.container.classList.toggle('glare-is-idle', this.isIdle)\n }\n\n /** True once per drag gesture, so the click that follows it can be ignored. */\n consumeGesture(): boolean {\n return this.gestures?.consumeMoved() ?? false\n }\n\n private async showSlide(index: number, opening: boolean): Promise<void> {\n const item = this.group[index]\n if (!this.$refs || !item) return\n\n const { container, stage } = this.$refs\n const slide = dom.mountSlide(stage, item, this.opts)\n if (dom.usesSmallButton(this.opts, item)) dom.addSmallButton(slide, this.opts, this.dict)\n dom.showSpinner(stage, this.opts, this.dict)\n this.emitSlide('beforeLoad', item)\n if (this.opts.image.preload) preloadNeighbours(this.group, index)\n\n let failed = false\n try {\n await loadContent(item, item.$content as HTMLElement, this.opts, this.dict)\n } catch (error) {\n failed = true\n dom.showError(item, error, this.opts, this.dict)\n this.emitSlide('onError', item)\n if (!this.opts.onError) console.warn('[glare]', error)\n }\n\n if (!this.isActive || this.currIndex !== index) return slide.remove()\n if (!failed) this.emitSlide('afterLoad', item)\n\n // The previous slide stays visible until the new content is ready, then they cross-fade.\n dom.hideSpinner(stage)\n if (!opening) enableTransitions(container, this.opts)\n dom.revealSlide(slide, opening, this.direction)\n this.captionTracker?.follow(slide)\n dom.retireSlides(stage, slide, resolveMotion(this.opts).transitionDuration, this.direction)\n this.syncZoomState(this.zoom.isZoomed)\n\n if (failed) return\n if (opening) animateOpen(container, item, this.opts)\n this.emitSlide('afterShow', item)\n }\n\n private syncChrome(): void {\n if (!this.$refs || !this.current) return\n dom.syncChrome(this.$refs, this.opts, this.dict, this.current, this.group.length, this.captionFor(this.current))\n this.syncZoomState(this.zoom.isZoomed)\n }\n\n private captionFor(item: SlideItem): string {\n const { caption } = this.opts\n if (typeof caption === 'function') return caption(this, item)\n return caption ?? item.caption\n }\n\n private syncZoomState(zoomed: boolean): void {\n if (this.$refs) dom.syncZoomButton(this.$refs.container, this.dict, zoomed, !!this.current?.$image)\n }\n\n private resolveParent(): HTMLElement {\n const { parentEl } = this.opts\n const el = typeof parentEl === 'string' ? document.querySelector<HTMLElement>(parentEl) : parentEl\n return el ?? document.body\n }\n\n private startModules({ container, stage, bg }: GlareRefs): void {\n const opts = this.opts\n\n const thumbs = moduleOptions(opts.thumbs, thumbsDefaults)\n if (thumbs) this.thumbs = new Thumbs(this, container, thumbs)\n\n const slideshow = moduleOptions(opts.slideshow, slideshowDefaults)\n if (slideshow) this.slideshow = new Slideshow(this, container, slideshow)\n\n const fullscreen = moduleOptions(opts.fullscreen, fullscreenDefaults)\n if (fullscreen && supportsFullscreen()) this.fullscreen = new Fullscreen(this, container, fullscreen)\n\n if (opts.hash && this.galleryName) this.hash = new Hash(this, this.galleryName)\n\n if (opts.wheel) {\n this.wheel = new WheelNav(stage, {\n mode: opts.wheel,\n current: () => this.current,\n isZoomed: () => this.zoom.isZoomed,\n next: () => this.next(),\n prev: () => this.prev(),\n })\n }\n\n if (opts.touch) {\n this.gestures = new Gestures(stage, {\n zoom: this.zoom,\n touch: opts.touch,\n bg,\n canPan: () => this.current?.type === 'image',\n close: () => this.close(),\n next: () => this.next(),\n prev: () => this.prev(),\n })\n }\n }\n\n private onActivity(): void {\n if (this.isIdle) this.toggleControls(false)\n this.idle.reset()\n }\n\n private teardown(): void {\n for (const module of [\n this.gestures,\n this.wheel,\n this.hash,\n this.thumbs,\n this.slideshow,\n this.fullscreen,\n ]) {\n module?.destroy()\n }\n this.gestures = this.wheel = this.hash = null\n this.thumbs = this.slideshow = this.fullscreen = undefined\n\n this.cleanups.forEach((off) => off())\n this.cleanups = []\n this.$refs?.container.remove()\n this.$refs = null\n\n registry.remove(this)\n if (this.opts.hideScrollbar && registry.size === 0) lockScroll(false)\n if (this.opts.backFocus) {\n const target = this.current?.$trigger ?? this.previouslyFocused\n target?.focus({ preventScroll: true })\n }\n\n this.isActive = false\n this.isClosing = false\n if (this.current) this.emitSlide('afterClose', this.current)\n }\n\n private emit(name: LifecycleEvent): unknown {\n return this.opts[name]?.(this)\n }\n\n private emitSlide(name: SlideEvent, item: SlideItem): unknown {\n return this.opts[name]?.(this, item)\n }\n\n private clampIndex(index: number): number {\n return clamp(index, 0, Math.max(0, this.group.length - 1))\n }\n\n static defaults = defaults\n\n static open(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n ): Glare {\n const instance = Glare.create(items, options, index)\n instance.open()\n return instance\n }\n\n static bind(target: BindTarget, options: GlareOptions = {}): BoundGroup {\n return bind(target, options, (elements, index, gallery) => {\n Glare.create(elements, options, index, gallery).open()\n })\n }\n\n /** Builds the instance here, or in the `delegate` window when that window has Glare loaded. */\n private static create(\n items: Array<SlideSource | string> | HTMLElement[],\n { delegate = defaults.delegate, ...options }: GlareOptions,\n index: number,\n gallery = '',\n ): Glare {\n return new (glareOf(delegate) ?? Glare)(items, options, index, gallery)\n }\n\n static close(all = false): void {\n if (all) registry.all().reverse().forEach((instance) => instance.close())\n else registry.top()?.close()\n }\n\n static getInstance(id?: number): Glare | null {\n return id == null ? registry.top() : registry.get(id)\n }\n\n static getInstances(): Glare[] {\n return registry.all()\n }\n\n /** Closes every instance and removes all `bind()` handlers. */\n static destroy(): void {\n Glare.close(true)\n unbindAll()\n }\n\n /** Binds every `[data-glare]` element once the DOM is ready. */\n static autoBind(options: GlareOptions = {}): void {\n const run = () => Glare.bind('[data-glare]', options)\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', run, { once: true })\n } else {\n run()\n }\n }\n}\n","import { Glare } from './core/glare'\n\nexport type {\n AjaxOptions,\n Anchor,\n AnchorPosition,\n AnimationEffect,\n BoundGroup,\n ClickAction,\n ClickActionName,\n ContentType,\n CustomButton,\n EventHandler,\n EventName,\n FullscreenOptions,\n GlareInstance,\n GlareOptions,\n GlareRefs,\n I18nDict,\n IframeOptions,\n ImageOptions,\n LifecycleEvent,\n LifecycleHandler,\n MediaProvider,\n ResolvedOptions,\n SlideEvent,\n SlideItem,\n SlideSource,\n SlideshowOptions,\n ThumbsFit,\n ThumbsOptions,\n ToolbarButton,\n TouchOptions,\n TransitionEffect,\n VideoOptions,\n} from './types'\nexport type { Point, Zoom, ZoomState } from './core/zoom'\n\nexport { Glare }\n\nexport const autoBind = Glare.autoBind\n\nexport default Glare\n"],"names":["i18nEn","getDict","opts","lang","translate","template","dict","_","key","buildQuery","params","value","expandMatch","match","n","providers","tld","coords","query","search","lat","lng","zoom","z","q","resolve","src","applyProvider","media","provider","url","svg","paths","icons","button","name","label","icon","attrs","baseTemplate","buttonTemplates","spinnerTemplate","errorTemplate","videoTemplate","iframeTemplate","thumbsDefaults","slideshowDefaults","fullscreenDefaults","defaults","current","IMAGE_EXT","VIDEO_EXT","PDF_EXT","SELECTOR","detectType","fallback","videoMime","ext","normalizeItem","source","index","raw","type","thumb","provided","attr","el","itemsFromElements","elements","img","caption","createItems","items","item","$","selector","root","$$","createEl","tag","className","html","fromHtml","toText","resolveElement","target","toCssSize","on","handler","options","nextFrame","callback","afterTransition","duration","done","finished","finish","timer","onEnd","event","isMobile","prefersReducedMotion","supportsFullscreen","doc","LOCK_CLASS","lockScroll","lock","scrollbar","HIDDEN","buildContainer","id","count","container","stage","refs","single","buildToolbar","toolbar","menu","createCustomButton","tpl","moreTpl","closeTpl","layoutTop","ancestor","top","node","trackCaption","slide","sync","content","observer","next","mountSlide","revealSlide","opening","direction","retireSlides","keep","delay","addSmallButton","showSpinner","hideSpinner","showError","error","isToolbarVisible","usesSmallButton","syncChrome","total","infobar","setTypeClass","syncToolbar","syncDownloadLink","syncInfobar","syncCaption","syncArrows","syncDialogLabel","visible","zoomable","link","href","indexEl","atStart","atEnd","setDisabled","disabled","base","live","previous","syncZoomButton","zoomed","hasImage","state","setToggleState","active","Fullscreen","glare","off","isPlainObject","proto","deepMerge","sources","result","existing","clamp","min","max","ZOOM_MIN","ZOOM_MAX","ZOOMED_THRESHOLD","Zoom","image","rect","scale","x","y","focus","center","natural","fx","fy","maxX","maxY","MOVE_THRESHOLD","MOMENTUM","SWIPE_CLOSE_DISTANCE","SWIPE_CLOSE_VELOCITY","SWIPE_NAV_DISTANCE","SWIPE_NAV_VELOCITY","IGNORED_TARGETS","distance","a","b","midpoint","pointOf","Gestures","host","moved","points","dx","dy","vertical","mid","ox","oy","last","elapsed","velocity","bg","HASH_PATTERN","parseHash","hash","formatHash","gallery","Hash","currentHash","parsed","pathname","Slideshow","hide","placeholderIcons","thumbnailSource","showPlaceholder","Thumbs","group","STEP","SETTLE","LINE_HEIGHT","WheelNav","normalize","resolveMotion","reduced","animationDuration","transitionDuration","applyMotionSettings","motion","enableTransitions","POSITION","FRACTION","anchorRect","anchor","position","box","rendered","offset","animateOpen","from","to","resolveOptions","merged","moduleOptions","groups","galleryOf","toElements","bind","open","openFrom","members","offs","restoreFromHash","unbindAll","IdleTimer","seconds","onIdle","stack","registry","instance","BUTTONS","g","CONTENT","SLIDE_AREA","FOCUSABLE","FORM_TAGS","DBLCLICK_WINDOW","bindInteractions","onActivity","pendingClick","cancelPending","more","expanded","closeToolbarMenu","custom","runCustomButton","slideAction","resolveAction","runAction","onKeydown","trapFocus","kind","action","point","focusable","first","IFRAME_LOAD_FALLBACK","DEFAULT_EMBED_RATIO","embedRatio","width","height","part","numerator","denominator","toPixels","available","viewport","input","amount","fitEmbed","style","availableWidth","availableHeight","hasDimensions","ratio","observeEmbed","reject","video","format","iframe","settings","wrap","frame","inline","clone","ajax","response","loaders","loadContent","preloadNeighbours","neighbour","nextId","glareOf","_Glare","galleryName","dom.buildContainer","dom.trackCaption","force","dom.mountSlide","dom.usesSmallButton","dom.addSmallButton","dom.showSpinner","failed","dom.showError","dom.hideSpinner","dom.revealSlide","dom.retireSlides","dom.syncChrome","dom.syncZoomButton","parentEl","thumbs","slideshow","fullscreen","module","delegate","all","run","Glare","autoBind"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"glare.esm.js","sources":["../src/i18n.ts","../src/utils/template.ts","../src/media/providers.ts","../src/icons.ts","../src/templates.ts","../src/defaults.ts","../src/media/detect.ts","../src/media/items.ts","../src/utils/dom.ts","../src/utils/env.ts","../src/core/dom.ts","../src/modules/fullscreen.ts","../src/utils/object.ts","../src/core/zoom.ts","../src/modules/gestures.ts","../src/modules/hash.ts","../src/modules/slideshow.ts","../src/modules/thumbs.ts","../src/modules/wheel.ts","../src/core/animation.ts","../src/core/options.ts","../src/core/bind.ts","../src/core/idle.ts","../src/core/registry.ts","../src/core/interactions.ts","../src/core/loaders.ts","../src/core/glare.ts","../src/index.ts"],"sourcesContent":["import type { GlareOptions, I18nDict } from './types'\n\nexport const i18nEn: I18nDict = {\n CLOSE: 'Close',\n NEXT: 'Next',\n PREV: 'Previous',\n ERROR: 'The requested content cannot be loaded.<br/>Please try again later.',\n LOADING: 'Loading',\n LIGHTBOX: 'Media lightbox',\n GO_TO_SLIDE: 'Go to slide {{index}}',\n VIDEO_UNSUPPORTED: 'Your browser does not support HTML5 video.',\n PLAY_START: 'Start slideshow',\n PLAY_STOP: 'Pause slideshow',\n FULL_SCREEN: 'Full screen',\n FULL_SCREEN_EXIT: 'Exit full screen',\n THUMBS: 'Thumbnails',\n DOWNLOAD: 'Download',\n MORE: 'More options',\n ZOOM: 'Zoom',\n ZOOM_OUT: 'Zoom out',\n}\n\n/** Resolves the active dictionary: built-in English, then `i18n.en`, then `i18n[lang]`. */\nexport function getDict(opts: GlareOptions): I18nDict {\n const lang = opts.lang ?? 'en'\n return { ...i18nEn, ...opts.i18n?.en, ...opts.i18n?.[lang] }\n}\n","/** Replaces `{{key}}` placeholders with values from `dict`. */\nexport function translate(template: string, dict: Record<string, string>): string {\n return template.replace(/\\{\\{(\\w+)\\}\\}/g, (_, key: string) => dict[key] ?? '')\n}\n\nexport function buildQuery(params: Record<string, string | number | boolean>): string {\n return Object.entries(params)\n .map(([key, value]) => `${encodeURIComponent(key)}=${encodeURIComponent(String(value))}`)\n .join('&')\n}\n\n/** Expands `$1`-style capture references from a RegExp match. */\nexport function expandMatch(template: string, match: RegExpMatchArray): string {\n return template.replace(/\\$(\\d+)/g, (_, n: string) => match[Number(n)] ?? '')\n}\n","import type { ContentType, MediaProvider, SlideSource } from '../types'\nimport { buildQuery, expandMatch } from '../utils/template'\n\nexport const providers: Record<string, MediaProvider> = {\n youtube: {\n matcher:\n /(?:youtube\\.com|youtu\\.be|youtube-nocookie\\.com)\\/(?:watch\\?(?:.*&)?v=|v\\/|u\\/\\w\\/|embed\\/|shorts\\/)?([\\w-]{11})/i,\n type: 'embed',\n url: 'https://www.youtube-nocookie.com/embed/$1',\n thumb: 'https://img.youtube.com/vi/$1/hqdefault.jpg',\n params: { autoplay: 1, rel: 0, modestbranding: 1, playsinline: 1 },\n },\n vimeo: {\n matcher: /vimeo\\.com\\/(?:video\\/)?(\\d+)/i,\n type: 'embed',\n url: 'https://player.vimeo.com/video/$1',\n params: { autoplay: 1, title: 0, byline: 0, portrait: 0 },\n },\n gmap: {\n matcher:\n /(?:maps\\.)?google\\.([a-z]{2,3}(?:\\.[a-z]{2})?)\\/(?:maps\\/(?:place\\/[^/]+\\/)?@([^/]+)|maps\\?q=([^&]+)|maps\\/search\\/([^/?]+))/i,\n type: 'iframe',\n url: (match) => {\n const [, tld, coords, query, search] = match\n if (coords) {\n const [lat, lng, zoom] = coords.split(',')\n const z = zoom ? Math.floor(parseFloat(zoom)) : 14\n return `https://maps.google.${tld}/maps?ll=${lat},${lng}&z=${z}&output=embed`\n }\n const q = encodeURIComponent(decodeURIComponent(query || search || ''))\n return `https://maps.google.${tld}/maps?q=${q}&output=embed`\n },\n },\n}\n\nfunction resolve(\n value: MediaProvider['url'],\n match: RegExpMatchArray,\n src: string,\n): string | undefined {\n if (typeof value === 'function') return value(match, src)\n if (typeof value === 'string') return expandMatch(value, match)\n return undefined\n}\n\n/** Rewrites `src` through the first matching provider, or returns null. */\nexport function applyProvider(\n src: string,\n media: Record<string, MediaProvider> | undefined,\n): Pick<SlideSource, 'src' | 'thumb'> & { type: ContentType } | null {\n for (const provider of Object.values(media ?? {})) {\n const match = src.match(provider.matcher)\n if (!match) continue\n\n let url = resolve(provider.url, match, src) ?? src\n if (provider.params) {\n url += (url.includes('?') ? '&' : '?') + buildQuery(provider.params)\n }\n\n return {\n src: url,\n type: provider.type ?? 'iframe',\n thumb: resolve(provider.thumb, match, src),\n }\n }\n return null\n}\n","const svg = (paths: string): string =>\n `<svg xmlns=\"http://www.w3.org/2000/svg\" viewBox=\"0 0 24 24\" fill=\"none\" stroke=\"currentColor\" stroke-width=\"2\" stroke-linecap=\"round\" stroke-linejoin=\"round\" aria-hidden=\"true\">${paths}</svg>`\n\nexport const icons = {\n close: svg('<path d=\"M18 6 6 18\"/><path d=\"m6 6 12 12\"/>'),\n next: svg('<path d=\"m9 18 6-6-6-6\"/>'),\n prev: svg('<path d=\"m15 18-6-6 6-6\"/>'),\n zoomIn: svg('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M11 8v6\"/><path d=\"M8 11h6\"/>'),\n zoomOut: svg('<circle cx=\"11\" cy=\"11\" r=\"8\"/><path d=\"m21 21-4.3-4.3\"/><path d=\"M8 11h6\"/>'),\n download: svg('<path d=\"M21 15v4a2 2 0 0 1-2 2H5a2 2 0 0 1-2-2v-4\"/><polyline points=\"7 10 12 15 17 10\"/><line x1=\"12\" x2=\"12\" y1=\"15\" y2=\"3\"/>'),\n thumbs: svg('<rect width=\"18\" height=\"18\" x=\"3\" y=\"3\" rx=\"2\"/><path d=\"M3 9h18\"/><path d=\"M9 21V9\"/>'),\n play: svg('<polygon points=\"6 3 20 12 6 21 6 3\"/>'),\n pause: svg('<rect width=\"4\" height=\"16\" x=\"6\" y=\"4\"/><rect width=\"4\" height=\"16\" x=\"14\" y=\"4\"/>'),\n fullscreen: svg('<path d=\"M8 3H5a2 2 0 0 0-2 2v3\"/><path d=\"M21 8V5a2 2 0 0 0-2-2h-3\"/><path d=\"M3 16v3a2 2 0 0 0 2 2h3\"/><path d=\"M16 21h3a2 2 0 0 0 2-2v-3\"/>'),\n fullscreenExit: svg('<path d=\"M8 3v3a2 2 0 0 1-2 2H3\"/><path d=\"M21 8h-3a2 2 0 0 1-2-2V3\"/><path d=\"M3 16h3a2 2 0 0 1 2 2v3\"/><path d=\"M16 21v-3a2 2 0 0 1 2-2h3\"/>'),\n more: svg('<circle cx=\"5\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"12\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"19\" cy=\"12\" r=\"1\" fill=\"currentColor\" stroke=\"none\"/>'),\n thumbImage: svg('<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"/><circle cx=\"8.5\" cy=\"9\" r=\"1.5\"/><path d=\"m4 17 5-5 4 4 2-2 5 5\"/>'),\n thumbVideo: svg('<rect x=\"3\" y=\"5\" width=\"18\" height=\"14\" rx=\"2\"/><path d=\"m10 9 5 3-5 3Z\"/>'),\n thumbEmbed: svg('<circle cx=\"12\" cy=\"12\" r=\"9\"/><path d=\"m10 8 6 4-6 4Z\"/>'),\n thumbIframe: svg('<rect x=\"3\" y=\"4\" width=\"18\" height=\"16\" rx=\"2\"/><path d=\"M3 8h18\"/><circle cx=\"6\" cy=\"6\" r=\".5\" fill=\"currentColor\" stroke=\"none\"/><circle cx=\"9\" cy=\"6\" r=\".5\" fill=\"currentColor\" stroke=\"none\"/>'),\n thumbInline: svg('<rect x=\"4\" y=\"4\" width=\"16\" height=\"16\" rx=\"2\"/><path d=\"M8 8h8M8 12h8M8 16h5\"/>'),\n thumbAjax: svg('<path d=\"M20 15a4 4 0 0 0-3-3.87A6 6 0 1 0 6 14\"/><path d=\"m9 16 3 3 3-3M12 12v7\"/>'),\n thumbHtml: svg('<path d=\"m8 9-3 3 3 3M16 9l3 3-3 3M14 5l-4 14\"/>'),\n thumbSlide: svg('<path d=\"M6 3h9l4 4v14H6Z\"/><path d=\"M14 3v5h5M9 13h7M9 17h5\"/>'),\n} as const\n","import { icons } from './icons'\n\nconst button = (name: string, label: string, icon: string, attrs = ''): string =>\n `<button type=\"button\" class=\"glare-button glare-button--${name}\" data-glare-${name} title=\"{{${label}}}\" aria-label=\"{{${label}}}\"${attrs}>${icon}</button>`\n\nexport const baseTemplate = `\n<div class=\"glare-container\" role=\"dialog\" aria-modal=\"true\" tabindex=\"-1\">\n <div class=\"glare-bg\"></div>\n <div class=\"glare-progress\" hidden></div>\n <div class=\"glare-inner\">\n <div class=\"glare-live glare-sr-only\" aria-live=\"polite\" aria-atomic=\"true\"></div>\n <div class=\"glare-infobar\"><span class=\"glare-infobar-index\"></span></div>\n <div class=\"glare-toolbar\"></div>\n <div class=\"glare-navigation\">\n ${button('prev', 'PREV', icons.prev)}\n ${button('next', 'NEXT', icons.next)}\n </div>\n <div class=\"glare-stage\"></div>\n <div class=\"glare-caption\"></div>\n </div>\n</div>`\n\nexport const buttonTemplates: Record<string, string> = {\n zoom: button('zoom', 'ZOOM', icons.zoomIn),\n slideshow: button('slideshow', 'PLAY_START', icons.play),\n thumbs: button('thumbs', 'THUMBS', icons.thumbs, ' aria-expanded=\"false\"'),\n fullscreen: button('fullscreen', 'FULL_SCREEN', icons.fullscreen),\n more: button('more', 'MORE', icons.more, ' aria-expanded=\"false\" aria-haspopup=\"true\"'),\n close: button('close', 'CLOSE', icons.close),\n download: `<a class=\"glare-button glare-button--download\" data-glare-download download target=\"_blank\" rel=\"noopener\" title=\"{{DOWNLOAD}}\" aria-label=\"{{DOWNLOAD}}\">${icons.download}</a>`,\n smallBtn: `<button type=\"button\" class=\"glare-button glare-close-small\" data-glare-close title=\"{{CLOSE}}\" aria-label=\"{{CLOSE}}\">${icons.close}</button>`,\n}\n\nexport const spinnerTemplate = '<div class=\"glare-spinner\" role=\"status\" aria-label=\"{{LOADING}}\"></div>'\n\nexport const errorTemplate = '<div class=\"glare-error\"><p>{{ERROR}}</p></div>'\n\nexport const videoTemplate =\n '<video class=\"glare-video\" controls playsinline controlsList=\"nodownload\" poster=\"{{poster}}\">' +\n '<source src=\"{{src}}\" type=\"{{format}}\"/>' +\n '{{VIDEO_UNSUPPORTED}}' +\n '</video>'\n\nexport const iframeTemplate = '<iframe class=\"glare-iframe\"></iframe>'\n","import type {\n FullscreenOptions,\n ResolvedOptions,\n SlideshowOptions,\n ThumbsOptions,\n} from './types'\nimport { i18nEn } from './i18n'\nimport { providers } from './media/providers'\nimport {\n baseTemplate,\n buttonTemplates,\n errorTemplate,\n iframeTemplate,\n spinnerTemplate,\n videoTemplate,\n} from './templates'\n\nexport const thumbsDefaults: Required<Omit<ThumbsOptions, 'parentEl'>> & ThumbsOptions = {\n autoStart: false,\n axis: 'x',\n fit: 'cover',\n}\n\nexport const slideshowDefaults: Required<SlideshowOptions> = {\n autoStart: false,\n speed: 3000,\n}\n\nexport const fullscreenDefaults: Required<FullscreenOptions> = {\n autoStart: false,\n}\n\nexport const defaults: ResolvedOptions = {\n closeExisting: false,\n loop: false,\n keyboard: true,\n protect: false,\n modal: false,\n idleTime: 3,\n hideScrollbar: true,\n autoFocus: true,\n backFocus: true,\n trapFocus: true,\n defaultType: 'image',\n parentEl: 'body',\n baseClass: '',\n slideClass: '',\n\n arrows: true,\n infobar: true,\n toolbar: 'auto',\n smallBtn: 'auto',\n buttons: ['zoom', 'slideshow', 'thumbs', 'download', 'fullscreen', 'close'],\n\n animationEffect: 'zoom',\n animationDuration: 366,\n anchor: 'trigger',\n zoomOpacity: true,\n transitionEffect: 'fade',\n transitionDuration: 366,\n\n clickContent: (current) => (current.type === 'image' ? 'zoom' : false),\n clickSlide: 'close',\n dblclickContent: false,\n dblclickSlide: false,\n wheel: 'auto',\n touch: { vertical: true, momentum: true },\n mobile: {\n idleTime: false,\n clickContent: (current) => (current.type === 'image' ? 'toggleControls' : false),\n clickSlide: (current) => (current.type === 'image' ? 'toggleControls' : 'close'),\n dblclickContent: (current) => (current.type === 'image' ? 'zoom' : false),\n dblclickSlide: (current) => (current.type === 'image' ? 'zoom' : false),\n },\n\n image: { preload: false },\n video: { tpl: videoTemplate, format: '', autoStart: true },\n iframe: {\n preload: true,\n css: {},\n attr: { allowfullscreen: 'true', allow: 'autoplay; fullscreen; picture-in-picture' },\n tpl: iframeTemplate,\n },\n ajax: { settings: { headers: { 'X-Requested-With': 'XMLHttpRequest' } } },\n media: providers,\n\n hash: true,\n slideshow: slideshowDefaults,\n thumbs: thumbsDefaults,\n fullscreen: fullscreenDefaults,\n\n lang: 'en',\n i18n: { en: i18nEn },\n baseTpl: baseTemplate,\n btnTpl: buttonTemplates,\n spinnerTpl: spinnerTemplate,\n errorTpl: errorTemplate,\n}\n","import type { ContentType } from '../types'\n\nconst IMAGE_EXT = /\\.(avif|bmp|gif|jpe?g|png|svg|webp|ico)(\\?.*)?$/i\nconst VIDEO_EXT = /\\.(mp4|webm|ogg|ogv|mov|m4v)(\\?.*)?$/i\nconst PDF_EXT = /\\.pdf(\\?.*)?$/i\nconst SELECTOR = /^(#[\\w-]+|\\.[\\w-]+)$/\n\n/** Guesses the content type from a URL; falls back to `fallback` for unknown URLs. */\nexport function detectType(src: string, fallback: ContentType = 'image'): ContentType {\n if (!src) return 'html'\n if (SELECTOR.test(src)) return 'inline'\n if (IMAGE_EXT.test(src)) return 'image'\n if (VIDEO_EXT.test(src)) return 'video'\n if (PDF_EXT.test(src)) return 'iframe'\n return fallback\n}\n\nexport function videoMime(src: string): string {\n const ext = src.match(/\\.(\\w+)(?:\\?|$)/)?.[1]?.toLowerCase()\n if (!ext) return 'video/mp4'\n return `video/${ext === 'ogv' ? 'ogg' : ext}`\n}\n","import type { ContentType, GlareOptions, SlideItem, SlideSource } from '../types'\nimport { detectType } from './detect'\nimport { applyProvider } from './providers'\n\n/** Turns a user-provided slide into a normalized `SlideItem`. */\nexport function normalizeItem(source: SlideSource | string, index: number, opts: GlareOptions): SlideItem {\n const raw: SlideSource = typeof source === 'string' ? { src: source } : { ...source }\n let src = raw.src ?? ''\n let type = raw.type\n let thumb = raw.thumb\n\n const provided = src ? applyProvider(src, opts.media) : null\n if (provided) {\n src = provided.src ?? src\n type ??= provided.type\n thumb ??= provided.thumb\n }\n\n if (!type) {\n type = raw.html || raw.content ? 'html' : detectType(src, opts.defaultType)\n }\n\n return {\n ...raw,\n index,\n src,\n type,\n thumb,\n caption: raw.caption ?? raw.title ?? '',\n isLoaded: false,\n hasError: false,\n }\n}\n\nconst attr = (el: HTMLElement, name: string): string | undefined => el.getAttribute(name) || undefined\n\n/** Reads slide data from trigger elements (`href`, `data-*` attributes, nested `<img>`). */\nexport function itemsFromElements(elements: HTMLElement[], opts: GlareOptions): SlideItem[] {\n return elements.map((el, index) => {\n const img = el.querySelector('img')\n const caption = attr(el, 'data-caption') ?? attr(el, 'title') ?? ''\n\n return normalizeItem(\n {\n src: attr(el, 'data-src') ?? attr(el, 'href') ?? '',\n type: attr(el, 'data-type') as ContentType | undefined,\n caption,\n alt: img?.getAttribute('alt') || caption,\n thumb: attr(el, 'data-thumb') ?? img?.getAttribute('src') ?? undefined,\n width: attr(el, 'data-width'),\n height: attr(el, 'data-height'),\n ratio: attr(el, 'data-ratio'),\n poster: attr(el, 'data-poster'),\n downloadSrc: attr(el, 'data-download-src'),\n html: attr(el, 'data-html'),\n $trigger: el,\n },\n index,\n opts,\n )\n })\n}\n\nexport function createItems(\n items: Array<SlideSource | string> | HTMLElement[],\n opts: GlareOptions,\n): SlideItem[] {\n // `nodeType` rather than `instanceof`, so elements from another window (see `delegate`) still count.\n if (items.length && (items[0] as Node).nodeType === 1) {\n return itemsFromElements(items as HTMLElement[], opts)\n }\n return (items as Array<SlideSource | string>).map((item, i) => normalizeItem(item, i, opts))\n}\n","export function $(selector: string, root: ParentNode = document): HTMLElement | null {\n return root.querySelector<HTMLElement>(selector)\n}\n\nexport function $$(selector: string, root: ParentNode = document): HTMLElement[] {\n return Array.from(root.querySelectorAll<HTMLElement>(selector))\n}\n\nexport function createEl<K extends keyof HTMLElementTagNameMap>(\n tag: K,\n className = '',\n html = '',\n): HTMLElementTagNameMap[K] {\n const el = document.createElement(tag)\n if (className) el.className = className\n if (html) el.innerHTML = html\n return el\n}\n\n/** Parses an HTML string and returns its first element. */\nexport function fromHtml(html: string): HTMLElement {\n const wrapper = createEl('div', '', html.trim())\n return wrapper.firstElementChild as HTMLElement\n}\n\n/** Strips markup from an HTML string, for labels that must be plain text. */\nexport function toText(html: string): string {\n if (!/[<&]/.test(html)) return html.trim()\n return new DOMParser().parseFromString(html, 'text/html').body.textContent?.trim() ?? ''\n}\n\n/** Resolves a selector or element, searching `root` first and then the document. */\nexport function resolveElement(\n target: string | HTMLElement | null | undefined,\n root: ParentNode = document,\n): HTMLElement | null {\n if (!target) return null\n if (typeof target !== 'string') return target\n return $(target, root) ?? $(target)\n}\n\nexport function toCssSize(value: number | string): string {\n return typeof value === 'number' ? `${value}px` : value\n}\n\n/** Adds an event listener and returns a function that removes it. */\nexport function on<K extends keyof GlobalEventHandlersEventMap>(\n target: EventTarget,\n type: K,\n handler: (event: GlobalEventHandlersEventMap[K]) => void,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void\nexport function on(\n target: EventTarget,\n type: string,\n handler: EventListener,\n options?: boolean | AddEventListenerOptions,\n): () => void {\n target.addEventListener(type, handler, options)\n return () => target.removeEventListener(type, handler, options)\n}\n\n/** Runs `callback` after the browser has painted the current frame. */\nexport function nextFrame(callback: () => void): void {\n requestAnimationFrame(() => requestAnimationFrame(callback))\n}\n\n/**\n * Runs `done` exactly once when a transition on `el` ends,\n * or after `duration` as a fallback for transitions that never fire.\n */\nexport function afterTransition(el: HTMLElement, duration: number, done: () => void): void {\n let finished = false\n const finish = () => {\n if (finished) return\n finished = true\n clearTimeout(timer)\n el.removeEventListener('transitionend', onEnd)\n done()\n }\n const onEnd = (event: Event) => {\n if (event.target === el) finish()\n }\n el.addEventListener('transitionend', onEnd)\n const timer = setTimeout(finish, duration + 50)\n}\n","export function isMobile(): boolean {\n return navigator.maxTouchPoints > 0 && window.matchMedia('(pointer: coarse)').matches\n}\n\nexport function prefersReducedMotion(): boolean {\n return window.matchMedia('(prefers-reduced-motion: reduce)').matches\n}\n\nexport function supportsFullscreen(): boolean {\n const doc = document as Document & { webkitFullscreenEnabled?: boolean }\n return Boolean(doc.fullscreenEnabled ?? doc.webkitFullscreenEnabled)\n}\n\nconst LOCK_CLASS = 'glare-lock'\n\n/** Locks page scrolling while compensating for the scrollbar width. */\nexport function lockScroll(lock: boolean): void {\n const html = document.documentElement\n if (lock) {\n const scrollbar = window.innerWidth - html.clientWidth\n html.classList.add(LOCK_CLASS)\n if (scrollbar > 0) html.style.marginRight = `${scrollbar}px`\n } else {\n html.classList.remove(LOCK_CLASS)\n html.style.marginRight = ''\n }\n}\n","import type { CustomButton, GlareRefs, I18nDict, ResolvedOptions, SlideItem } from '../types'\nimport { icons } from '../icons'\nimport { $, $$, createEl, fromHtml, toText } from '../utils/dom'\nimport { supportsFullscreen } from '../utils/env'\nimport { translate } from '../utils/template'\n\nconst HIDDEN = 'glare-hidden'\n\nexport function buildContainer(opts: ResolvedOptions, dict: I18nDict, id: number, count: number): GlareRefs {\n const container = fromHtml(translate(opts.baseTpl, dict))\n container.dataset.glareId = String(id)\n if (opts.baseClass) container.classList.add(opts.baseClass)\n if (opts.modal) container.classList.add('glare-is-modal')\n\n const stage = $('.glare-stage', container)\n if (!stage) throw new Error('baseTpl must contain a .glare-stage element')\n\n const refs: GlareRefs = {\n container,\n bg: $('.glare-bg', container),\n inner: $('.glare-inner', container),\n stage,\n caption: $('.glare-caption', container),\n toolbar: $('.glare-toolbar', container),\n infobar: $('.glare-infobar', container),\n navigation: $('.glare-navigation', container),\n }\n\n const single = count < 2\n refs.navigation?.classList.toggle(HIDDEN, !opts.arrows || single)\n refs.infobar?.classList.toggle(HIDDEN, !opts.infobar || single)\n if (refs.toolbar) buildToolbar(refs.toolbar, opts, dict, single)\n\n return refs\n}\n\nfunction buildToolbar(toolbar: HTMLElement, opts: ResolvedOptions, dict: I18nDict, single: boolean): void {\n if (opts.toolbar === false) {\n toolbar.classList.add(HIDDEN)\n return\n }\n\n const menu = createEl('div', 'glare-toolbar-menu')\n menu.id = `glare-toolbar-menu-${toolbar.closest<HTMLElement>('.glare-container')?.dataset.glareId ?? ''}`\n\n for (const name of opts.buttons) {\n if (typeof name !== 'string') {\n menu.appendChild(createCustomButton(name))\n continue\n }\n\n if (single && (name === 'thumbs' || name === 'slideshow')) continue\n if (name === 'fullscreen' && !supportsFullscreen()) continue\n if (name === 'more' || name === 'close') continue\n\n const tpl = opts.btnTpl[name]\n if (tpl) menu.insertAdjacentHTML('beforeend', translate(tpl, dict))\n }\n\n if (menu.childElementCount) {\n toolbar.appendChild(menu)\n const moreTpl = opts.btnTpl.more\n if (moreTpl) {\n toolbar.insertAdjacentHTML('beforeend', translate(moreTpl, dict))\n toolbar.querySelector('[data-glare-more]')?.setAttribute('aria-controls', menu.id)\n }\n }\n\n if (opts.buttons.includes('close')) {\n const closeTpl = opts.btnTpl.close\n if (closeTpl) toolbar.insertAdjacentHTML('beforeend', translate(closeTpl, dict))\n }\n}\n\n/** A button defined inline in `buttons`: the built-in markup, matched back to its `click` by name. */\nfunction createCustomButton({ name, label, icon }: CustomButton): HTMLElement {\n const button = createEl('button', `glare-button glare-button--${name}`, icon)\n\n button.type = 'button'\n button.title = label\n button.dataset.glareCustom = name\n button.setAttribute('aria-label', label)\n\n return button\n}\n\n/**\n * Distance from `el`'s top edge to `ancestor`'s, from layout alone. Unlike a bounding rect it\n * ignores transforms, so an effect, swipe or zoom that is moving `el` does not skew it.\n */\nfunction layoutTop(el: HTMLElement, ancestor: Element | null): number {\n let top = 0\n for (let node: Element | null = el; node instanceof HTMLElement && node !== ancestor; node = node.offsetParent) {\n top += node.offsetTop\n }\n\n return top\n}\n\n/**\n * Lays out the caption: slides reserve its height through `--glare-caption-inset`, and it sits\n * right under the media of the slide passed to `follow`. Until then it rests at the bottom.\n */\nexport function trackCaption({ container, caption }: GlareRefs): { follow(slide: HTMLElement): void; destroy(): void } {\n let slide: HTMLElement | null = null\n\n const sync = () => {\n if (!caption) return\n container.style.setProperty('--glare-caption-inset', `${caption.offsetHeight}px`)\n\n const content = slide && $('.glare-content', slide)\n if (!content) return\n Object.assign(caption.style, { top: `${layoutTop(content, caption.offsetParent) + content.offsetHeight}px`, bottom: 'auto' })\n }\n\n // The slide's content box changes with the insets, and the content's with the media.\n const observer = new ResizeObserver(sync)\n if (caption) observer.observe(caption)\n sync()\n\n return {\n follow(next) {\n if (slide) for (const el of [slide, $('.glare-content', slide)]) if (el) observer.unobserve(el)\n slide = next\n for (const el of [next, $('.glare-content', next)]) if (el) observer.observe(el)\n sync()\n },\n destroy: () => observer.disconnect(),\n }\n}\n\n/** Creates a hidden slide with an empty content box and appends it to the stage. */\nexport function mountSlide(stage: HTMLElement, item: SlideItem, opts: ResolvedOptions): HTMLElement {\n const slide = createEl('div', `glare-slide glare-slide--${item.type}`)\n if (opts.slideClass) slide.classList.add(opts.slideClass)\n\n const content = createEl('div', 'glare-content')\n slide.appendChild(content)\n stage.appendChild(slide)\n\n item.$slide = slide\n item.$content = content\n return slide\n}\n\n/** Which way a slide change goes: 1 towards later slides, -1 towards earlier ones. */\nexport type Direction = 1 | -1\n\n/**\n * Makes a mounted slide the current one, fading it in unless `opening`. The first slide is\n * marked `--opening` and later ones `--in`, so open animations and slide-change effects each\n * have their own target. Every slide carries the direction it arrived from, for effects to mirror.\n */\nexport function revealSlide(slide: HTMLElement, opening: boolean, direction: Direction): void {\n slide.style.setProperty('--glare-direction', String(direction))\n slide.classList.add(opening ? 'glare-slide--opening' : 'glare-slide--in')\n if (opening) slide.style.transition = 'none'\n\n // Force a style flush so the opacity change below is transitioned (or not) as intended.\n void slide.offsetWidth\n slide.classList.add('glare-slide--current')\n\n if (opening) {\n void slide.offsetWidth\n slide.style.transition = ''\n }\n}\n\n/** Fades out every slide except `keep` and removes it after `delay`. */\nexport function retireSlides(stage: HTMLElement, keep: HTMLElement, delay: number, direction: Direction): void {\n for (const slide of $$('.glare-slide', stage)) {\n if (slide === keep) continue\n // A slide that is already leaving keeps the direction it left in.\n if (!slide.classList.contains('glare-slide--out')) slide.style.setProperty('--glare-direction', String(direction))\n slide.classList.remove('glare-slide--current', 'glare-slide--in', 'glare-slide--opening')\n slide.classList.add('glare-slide--out')\n setTimeout(() => slide.remove(), delay)\n }\n}\n\nexport function addSmallButton(slide: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void {\n slide.insertAdjacentHTML('beforeend', translate(opts.btnTpl.smallBtn ?? '', dict))\n}\n\nexport function showSpinner(stage: HTMLElement, opts: ResolvedOptions, dict: I18nDict): void {\n if (!stage.querySelector(':scope > .glare-spinner')) {\n stage.insertAdjacentHTML('beforeend', translate(opts.spinnerTpl, dict))\n }\n}\n\nexport function hideSpinner(stage: HTMLElement): void {\n stage.querySelector(':scope > .glare-spinner')?.remove()\n}\n\nexport function showError(item: SlideItem, error: unknown, opts: ResolvedOptions, dict: I18nDict): void {\n item.hasError = true\n item.error = error\n if (!item.$content) return\n\n item.$content.className = 'glare-content glare-content--error'\n item.$content.innerHTML = translate(opts.errorTpl, dict)\n}\n\nfunction isToolbarVisible(opts: ResolvedOptions, item: SlideItem): boolean {\n if (typeof opts.toolbar === 'boolean') return opts.toolbar\n return item.type === 'image'\n}\n\nexport function usesSmallButton(opts: ResolvedOptions, item: SlideItem): boolean {\n if (typeof opts.smallBtn === 'boolean') return opts.smallBtn\n return !isToolbarVisible(opts, item)\n}\n\n/** Updates every piece of chrome that depends on the current slide. */\nexport function syncChrome(refs: GlareRefs, opts: ResolvedOptions, dict: I18nDict, item: SlideItem, total: number, caption: string): void {\n const { container, toolbar, infobar } = refs\n\n setTypeClass(container, item.type)\n if (toolbar) syncToolbar(toolbar, opts, item)\n syncDownloadLink(container, item)\n if (infobar) syncInfobar(infobar, item.index, total)\n if (refs.caption) syncCaption(refs.caption, caption)\n syncArrows(container, opts, item.index, total)\n syncDialogLabel(container, dict, item, total)\n}\n\n/** Shows the toolbar for images; with `toolbar: true` other types keep everything except zoom. */\nfunction syncToolbar(toolbar: HTMLElement, opts: ResolvedOptions, item: SlideItem): void {\n if (opts.toolbar === false) return\n\n toolbar.classList.remove('glare-toolbar--expanded')\n toolbar.querySelector('[data-glare-more]')?.setAttribute('aria-expanded', 'false')\n\n const visible = isToolbarVisible(opts, item)\n toolbar.classList.toggle(HIDDEN, !visible)\n if (!visible) return\n\n const zoomable = item.type === 'image'\n $('[data-glare-zoom]', toolbar)?.classList.toggle(HIDDEN, !zoomable)\n}\n\nfunction syncDownloadLink(container: HTMLElement, item: SlideItem): void {\n const link = container.querySelector<HTMLAnchorElement>('[data-glare-download]')\n if (!link) return\n\n const href = item.downloadSrc || (item.type === 'image' ? item.src : '')\n link.classList.toggle(HIDDEN, !href)\n if (href) link.href = href\n}\n\nfunction syncInfobar(infobar: HTMLElement, index: number, total: number): void {\n const indexEl = $('.glare-infobar-index', infobar)\n if (indexEl) indexEl.textContent = `${index + 1} / ${total}`\n}\n\nfunction syncCaption(caption: HTMLElement, html: string): void {\n caption.innerHTML = html\n caption.classList.toggle(HIDDEN, !html)\n}\n\nfunction syncArrows(container: HTMLElement, opts: ResolvedOptions, index: number, total: number): void {\n const atStart = !opts.loop && index === 0\n const atEnd = !opts.loop && index === total - 1\n setDisabled($('[data-glare-prev]', container), atStart)\n setDisabled($('[data-glare-next]', container), atEnd)\n}\n\nfunction setDisabled(button: HTMLElement | null, disabled: boolean): void {\n if (!button) return\n button.classList.toggle('glare-is-disabled', disabled)\n button.setAttribute('aria-disabled', String(disabled))\n}\n\n/** Labels the dialog and announces the slide change through the live region. */\nfunction syncDialogLabel(container: HTMLElement, dict: I18nDict, item: SlideItem, total: number): void {\n const base = toText(item.caption) || item.alt || dict.LIGHTBOX\n const label = total > 1 ? `${base} (${item.index + 1} of ${total})` : base\n\n container.setAttribute('aria-label', label)\n const live = $('.glare-live', container)\n if (live) live.textContent = label\n}\n\nfunction setTypeClass(el: HTMLElement, type: string): void {\n const previous = el.dataset.type\n if (previous) el.classList.remove(`glare-type-${previous}`)\n el.dataset.type = type\n el.classList.add(`glare-type-${type}`)\n}\n\nexport function syncZoomButton(container: HTMLElement, dict: I18nDict, zoomed: boolean, hasImage: boolean): void {\n container.classList.toggle('glare-can-zoom-out', zoomed)\n container.classList.toggle('glare-can-zoom-in', !zoomed && hasImage)\n\n const button = $('[data-glare-zoom]', container)\n const state = zoomed ? 'out' : 'in'\n if (!button || button.dataset.state === state) return\n\n button.dataset.state = state\n setToggleState(button, zoomed, zoomed ? dict.ZOOM_OUT : dict.ZOOM, zoomed ? icons.zoomOut : icons.zoomIn)\n}\n\n/** Swaps a toolbar toggle's label and icon and marks it active. */\nexport function setToggleState(button: HTMLElement, active: boolean, label: string, icon: string): void {\n button.setAttribute('title', label)\n button.setAttribute('aria-label', label)\n button.innerHTML = icon\n button.classList.toggle('glare-is-active', active)\n}\n","import type { FullscreenOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { setToggleState } from '../core/dom'\nimport { icons } from '../icons'\nimport { $, on } from '../utils/dom'\n\ntype FullscreenDocument = Document & {\n webkitFullscreenElement?: Element | null\n webkitExitFullscreen?: () => Promise<void> | void\n}\n\ntype FullscreenElement = HTMLElement & {\n webkitRequestFullscreen?: () => Promise<void> | void\n}\n\n/** Fullscreen API wrapper with the WebKit fallback still needed by Safari. */\nexport class Fullscreen {\n private readonly offs: Array<() => void>\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n opts: FullscreenOptions,\n ) {\n this.offs = [\n on(document, 'fullscreenchange', () => this.sync()),\n on(document, 'webkitfullscreenchange', () => this.sync()),\n ]\n if (opts.autoStart) this.request()\n }\n\n isFullscreen(): boolean {\n const doc = document as FullscreenDocument\n return Boolean(doc.fullscreenElement ?? doc.webkitFullscreenElement)\n }\n\n request(): void {\n const el = this.container as FullscreenElement\n const request = el.requestFullscreen ?? el.webkitRequestFullscreen\n void request?.call(el)\n }\n\n exit(): void {\n if (!this.isFullscreen()) return\n const doc = document as FullscreenDocument\n const exit = doc.exitFullscreen ?? doc.webkitExitFullscreen\n void exit?.call(document)\n }\n\n toggle(): void {\n if (this.isFullscreen()) this.exit()\n else this.request()\n }\n\n destroy(): void {\n this.exit()\n this.offs.forEach((off) => off())\n }\n\n private sync(): void {\n const active = this.isFullscreen()\n this.container.classList.toggle('glare-is-fullscreen', active)\n\n const button = $('[data-glare-fullscreen]', this.container)\n if (!button) return\n\n const { dict } = this.glare\n setToggleState(\n button,\n active,\n active ? dict.FULL_SCREEN_EXIT : dict.FULL_SCREEN,\n active ? icons.fullscreenExit : icons.fullscreen,\n )\n }\n}\n","function isPlainObject(value: unknown): value is Record<string, unknown> {\n if (typeof value !== 'object' || value === null) return false\n const proto = Object.getPrototypeOf(value)\n // An `Object.prototype` from any window, so options passed across frames still merge.\n return proto === null || Object.getPrototypeOf(proto) === null\n}\n\n/** Recursively merges plain objects; other values (arrays, elements, RegExps) are replaced. */\nexport function deepMerge<T extends object>(...sources: Array<object | null | undefined | false>): T {\n const result: Record<string, unknown> = {}\n\n for (const source of sources) {\n if (!source) continue\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined) continue\n const existing = result[key]\n result[key] = isPlainObject(value)\n ? deepMerge(isPlainObject(existing) ? existing : {}, value)\n : value\n }\n }\n\n return result as T\n}\n\nexport function clamp(value: number, min: number, max: number): number {\n return Math.min(max, Math.max(min, value))\n}\n","import { clamp } from '../utils/object'\n\nexport interface Point {\n x: number\n y: number\n}\n\nexport interface ZoomState extends Point {\n scale: number\n}\n\nexport interface ZoomTarget {\n image(): HTMLImageElement | null\n stage(): HTMLElement | null\n onChange(zoomed: boolean): void\n}\n\nexport const ZOOM_MIN = 1\nexport const ZOOM_MAX = 5\nconst ZOOMED_THRESHOLD = 1.01\n\n/**\n * Controls the transform of the current image.\n * The image is scaled around its centre and then translated by (x, y).\n */\nexport class Zoom {\n scale = ZOOM_MIN\n x = 0\n y = 0\n\n constructor(private readonly target: ZoomTarget) {}\n\n get isZoomed(): boolean {\n return this.scale > ZOOMED_THRESHOLD\n }\n\n get state(): ZoomState {\n return { scale: this.scale, x: this.x, y: this.y }\n }\n\n /** Centre of the image in viewport coordinates, ignoring the current translation. */\n center(): Point | null {\n const image = this.target.image()\n if (!image) return null\n const rect = image.getBoundingClientRect()\n return { x: rect.left + rect.width / 2 - this.x, y: rect.top + rect.height / 2 - this.y }\n }\n\n apply(scale: number, x: number, y: number, duration = 0): void {\n const image = this.target.image()\n if (!image) return\n\n this.scale = clamp(scale, ZOOM_MIN, ZOOM_MAX)\n const translate = this.isZoomed ? this.bounded(x, y) : { x: 0, y: 0 }\n this.x = translate.x\n this.y = translate.y\n\n image.style.transitionDuration = `${duration}ms`\n image.style.transform = `translate3d(${this.x}px, ${this.y}px, 0) scale(${this.scale})`\n this.target.onChange(this.isZoomed)\n }\n\n toFit(duration = 300): void {\n this.apply(ZOOM_MIN, 0, 0, duration)\n }\n\n /** Zooms to the image's natural size (at least 1.5x), keeping `focus` under the pointer. */\n toActual(focus?: Partial<Point>, duration = 300): void {\n const image = this.target.image()\n const center = this.center()\n if (!image || !center) return\n\n const natural = image.naturalWidth / Math.max(image.offsetWidth, 1)\n const scale = clamp(Math.max(natural, 1.5), ZOOM_MIN, ZOOM_MAX)\n const fx = focus?.x ?? center.x\n const fy = focus?.y ?? center.y\n this.apply(scale, (center.x - fx) * (scale - 1), (center.y - fy) * (scale - 1), duration)\n }\n\n reset(): void {\n const image = this.target.image()\n if (image) {\n image.style.transform = ''\n image.style.transitionDuration = ''\n }\n this.scale = ZOOM_MIN\n this.x = 0\n this.y = 0\n this.target.onChange(false)\n }\n\n /** Keeps the scaled image from being dragged fully out of the stage. */\n private bounded(x: number, y: number): Point {\n const image = this.target.image()\n const stage = this.target.stage()\n if (!image || !stage) return { x, y }\n const maxX = Math.max(0, (image.offsetWidth * this.scale - stage.clientWidth) / 2)\n const maxY = Math.max(0, (image.offsetHeight * this.scale - stage.clientHeight) / 2)\n return { x: clamp(x, -maxX, maxX), y: clamp(y, -maxY, maxY) }\n }\n}\n","import type { TouchOptions } from '../types'\nimport type { Point, Zoom, ZoomState } from '../core/zoom'\nimport { on } from '../utils/dom'\nimport { clamp } from '../utils/object'\nimport { ZOOM_MAX, ZOOM_MIN } from '../core/zoom'\n\nexport interface GestureHost {\n zoom: Zoom\n touch: TouchOptions\n /** The backdrop, dimmed while the stage is dragged vertically. */\n bg: HTMLElement | null\n /** Whether the current slide can be panned when zoomed. */\n canPan(): boolean\n close(): void\n next(): void\n prev(): void\n}\n\ntype Mode = 'idle' | 'swipe' | 'pan' | 'pinch'\n\nconst MOVE_THRESHOLD = 6\nconst MOMENTUM = 120\nconst SWIPE_CLOSE_DISTANCE = 100\nconst SWIPE_CLOSE_VELOCITY = 0.5\nconst SWIPE_NAV_DISTANCE = 80\nconst SWIPE_NAV_VELOCITY = 0.4\nconst IGNORED_TARGETS = 'a, button, input, textarea, select, video, .glare-thumbs'\n\nconst distance = (a: Point, b: Point): number => Math.hypot(a.x - b.x, a.y - b.y)\nconst midpoint = (a: Point, b: Point): Point => ({ x: (a.x + b.x) / 2, y: (a.y + b.y) / 2 })\nconst pointOf = (event: PointerEvent): Point => ({ x: event.clientX, y: event.clientY })\n\n/** Swipe, pan and pinch handling on top of Pointer Events. */\nexport class Gestures {\n private readonly pointers = new Map<number, Point>()\n private readonly offs: Array<() => void>\n private mode: Mode = 'idle'\n private moved = false\n private start: Point[] = []\n private startTime = 0\n private startZoom: ZoomState = { scale: 1, x: 0, y: 0 }\n private startMid: Point = { x: 0, y: 0 }\n private startDistance = 0\n\n constructor(\n private readonly stage: HTMLElement,\n private readonly host: GestureHost,\n ) {\n this.offs = [\n on(stage, 'pointerdown', (event) => this.onDown(event)),\n on(window, 'pointermove', (event) => this.onMove(event), { passive: false }),\n on(window, 'pointerup', (event) => this.onUp(event)),\n on(window, 'pointercancel', (event) => this.onUp(event)),\n ]\n }\n\n destroy(): void {\n this.offs.forEach((off) => off())\n this.pointers.clear()\n }\n\n /** Returns whether the last gesture moved, then clears the flag. */\n consumeMoved(): boolean {\n const moved = this.moved\n this.moved = false\n return moved\n }\n\n private onDown(event: PointerEvent): void {\n if (event.pointerType === 'mouse' && event.button !== 0) return\n if ((event.target as Element).closest(IGNORED_TARGETS)) return\n\n this.pointers.set(event.pointerId, pointOf(event))\n if (this.pointers.size <= 2) this.begin()\n }\n\n private onMove(event: PointerEvent): void {\n if (!this.pointers.has(event.pointerId)) return\n this.pointers.set(event.pointerId, pointOf(event))\n this.move(event)\n }\n\n private onUp(event: PointerEvent): void {\n if (!this.pointers.has(event.pointerId)) return\n this.pointers.delete(event.pointerId)\n\n if (this.pointers.size === 0) this.end(pointOf(event))\n else this.begin()\n }\n\n /** Anchors a new gesture on the currently pressed pointers. */\n private begin(): void {\n if (this.mode === 'swipe') this.releaseStage()\n\n const points = [...this.pointers.values()]\n this.start = points\n this.startTime = performance.now()\n this.startZoom = this.host.zoom.state\n this.mode = points.length >= 2 ? 'pinch' : 'idle'\n\n if (points.length >= 2) {\n this.startDistance = distance(points[0], points[1])\n this.startMid = midpoint(points[0], points[1])\n }\n }\n\n private move(event: PointerEvent): void {\n const points = [...this.pointers.values()]\n if (!this.start.length || !points.length) return\n\n if (this.mode === 'pinch' && points.length >= 2) {\n event.preventDefault()\n this.moved = true\n this.pinch(points[0], points[1])\n return\n }\n\n const dx = points[0].x - this.start[0].x\n const dy = points[0].y - this.start[0].y\n if (!this.moved && Math.hypot(dx, dy) < MOVE_THRESHOLD) return\n this.moved = true\n\n if (this.mode === 'idle') {\n this.mode = this.host.zoom.isZoomed && this.host.canPan() ? 'pan' : 'swipe'\n }\n\n if (this.mode === 'pan') {\n event.preventDefault()\n this.host.zoom.apply(this.startZoom.scale, this.startZoom.x + dx, this.startZoom.y + dy)\n } else if (this.mode === 'swipe') {\n const vertical = this.host.touch.vertical !== false\n if (!vertical && Math.abs(dy) > Math.abs(dx)) return\n event.preventDefault()\n this.dragStage(dx, vertical ? dy : 0)\n }\n }\n\n /** Scales around the pinch midpoint so the content under the fingers stays put. */\n private pinch(a: Point, b: Point): void {\n const { zoom } = this.host\n const mid = midpoint(a, b)\n const center = zoom.center() ?? mid\n const scale = clamp(\n (this.startZoom.scale * distance(a, b)) / (this.startDistance || 1),\n ZOOM_MIN,\n ZOOM_MAX,\n )\n\n // Image-space offset of the point that was under the starting midpoint.\n const ox = (this.startMid.x - center.x - this.startZoom.x) / this.startZoom.scale\n const oy = (this.startMid.y - center.y - this.startZoom.y) / this.startZoom.scale\n zoom.apply(scale, mid.x - center.x - scale * ox, mid.y - center.y - scale * oy)\n }\n\n private end(last: Point): void {\n if (!this.start.length) return\n\n const elapsed = Math.max(performance.now() - this.startTime, 1)\n const dx = last.x - this.start[0].x\n const dy = last.y - this.start[0].y\n const velocity = { x: dx / elapsed, y: dy / elapsed }\n\n if (this.mode === 'swipe') {\n this.releaseStage()\n this.finishSwipe(dx, dy, velocity)\n } else if (this.mode === 'pan' && this.host.touch.momentum !== false) {\n const { zoom } = this.host\n zoom.apply(zoom.scale, zoom.x + velocity.x * MOMENTUM, zoom.y + velocity.y * MOMENTUM, 250)\n }\n\n this.mode = 'idle'\n this.start = []\n // Let the click that follows this gesture see `moved`, then forget it.\n if (this.moved) setTimeout(() => (this.moved = false), 0)\n }\n\n /** Moves the whole stage with the finger and dims the backdrop on vertical drags. */\n private dragStage(dx: number, dy: number): void {\n this.stage.style.transitionDuration = '0ms'\n this.stage.style.transform = `translate3d(${dx}px, ${dy}px, 0)`\n\n const { bg } = this.host\n if (bg) {\n bg.style.transitionDuration = '0ms'\n bg.style.opacity = String(clamp(1 - Math.abs(dy) / 400, 0.35, 1))\n }\n }\n\n private releaseStage(): void {\n this.stage.style.transitionDuration = ''\n this.stage.style.transform = ''\n\n const { bg } = this.host\n if (bg) {\n bg.style.transitionDuration = ''\n bg.style.opacity = ''\n }\n }\n\n /** A long or fast vertical swipe closes; a horizontal one navigates. */\n private finishSwipe(dx: number, dy: number, velocity: Point): void {\n const vertical = Math.abs(dy) > Math.abs(dx)\n\n if (vertical) {\n if (Math.abs(dy) > SWIPE_CLOSE_DISTANCE || Math.abs(velocity.y) > SWIPE_CLOSE_VELOCITY) this.host.close()\n return\n }\n\n if (Math.abs(dx) > SWIPE_NAV_DISTANCE || Math.abs(velocity.x) > SWIPE_NAV_VELOCITY) {\n if (dx < 0) this.host.next()\n else this.host.prev()\n }\n }\n}\n","import type { Glare } from '../core/glare'\nimport { on } from '../utils/dom'\n\nconst HASH_PATTERN = /^(.+)-(\\d+)$/\n\n/** Parses `#gallery-3` into `{ gallery: 'gallery', index: 2 }`. */\nexport function parseHash(hash = window.location.hash): { gallery: string; index: number } | null {\n const match = hash.replace(/^#/, '').match(HASH_PATTERN)\n if (!match) return null\n return { gallery: match[1], index: Math.max(0, parseInt(match[2], 10) - 1) }\n}\n\nfunction formatHash(gallery: string, index: number): string {\n return `${gallery}-${index + 1}`\n}\n\n/**\n * Keeps the URL hash in sync with the current slide of a named gallery.\n * Opening pushes one history entry so the browser's Back button closes the lightbox;\n * slide changes replace it so Back never walks through every slide.\n */\nexport class Hash {\n private readonly off: () => void\n private pushed = false\n\n constructor(\n private readonly glare: Glare,\n private readonly gallery: string,\n ) {\n this.off = on(window, 'hashchange', () => this.onHashChange())\n\n const next = formatHash(gallery, glare.currIndex)\n if (currentHash() !== next) {\n window.history.pushState(null, '', `#${next}`)\n this.pushed = true\n }\n }\n\n update(index = this.glare.currIndex): void {\n const next = formatHash(this.gallery, index)\n if (currentHash() !== next) this.replace(`#${next}`)\n }\n\n destroy(): void {\n this.off()\n if (parseHash()?.gallery !== this.gallery) return\n\n if (this.pushed) window.history.back()\n else this.replace('')\n }\n\n private onHashChange(): void {\n const parsed = parseHash()\n if (!parsed || parsed.gallery !== this.gallery) {\n this.pushed = false\n this.glare.close()\n } else if (parsed.index !== this.glare.currIndex) {\n this.glare.jumpTo(parsed.index)\n }\n }\n\n private replace(hash: string): void {\n const { pathname, search } = window.location\n window.history.replaceState(null, '', `${pathname}${search}${hash}`)\n }\n}\n\nconst currentHash = (): string => window.location.hash.replace(/^#/, '')\n","import type { SlideshowOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { setToggleState } from '../core/dom'\nimport { slideshowDefaults } from '../defaults'\nimport { icons } from '../icons'\nimport { $ } from '../utils/dom'\nimport { prefersReducedMotion } from '../utils/env'\n\n/** Advances slides on a timer and animates the top progress bar. */\nexport class Slideshow {\n private readonly bar: HTMLElement | null\n private readonly button: HTMLElement | null\n private timer: ReturnType<typeof setTimeout> | null = null\n private active = false\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: SlideshowOptions,\n ) {\n this.bar = $('.glare-progress', container)\n this.button = $('[data-glare-slideshow]', container)\n if (opts.autoStart) this.start()\n }\n\n isActive(): boolean {\n return this.active\n }\n\n start(): void {\n if (this.glare.group.length < 2) return\n\n this.active = true\n this.container.classList.add('glare-is-slideshow')\n this.syncButton()\n this.schedule()\n }\n\n stop(): void {\n this.active = false\n this.clearTimer()\n this.setProgress(0, true)\n this.container.classList.remove('glare-is-slideshow')\n this.syncButton()\n }\n\n toggle(): void {\n if (this.active) this.stop()\n else this.start()\n }\n\n onIndexChange(): void {\n if (this.active) this.schedule()\n }\n\n destroy(): void {\n this.stop()\n }\n\n private get speed(): number {\n return this.opts.speed ?? slideshowDefaults.speed\n }\n\n private get atEnd(): boolean {\n return !this.glare.opts.loop && this.glare.currIndex === this.glare.group.length - 1\n }\n\n private schedule(): void {\n this.clearTimer()\n this.setProgress(0)\n\n if (!prefersReducedMotion()) {\n // Force a reflow so the bar restarts from zero before animating.\n void this.bar?.offsetWidth\n this.setProgress(1)\n }\n\n this.timer = setTimeout(() => (this.atEnd ? this.stop() : this.glare.next()), this.speed)\n }\n\n private clearTimer(): void {\n if (this.timer) clearTimeout(this.timer)\n this.timer = null\n }\n\n private setProgress(value: 0 | 1, hide = false): void {\n if (!this.bar) return\n\n this.bar.hidden = hide\n this.bar.style.transitionDuration = value ? `${this.speed}ms` : '0ms'\n this.bar.style.transform = `scaleX(${value})`\n }\n\n private syncButton(): void {\n if (!this.button) return\n\n const { dict } = this.glare\n setToggleState(\n this.button,\n this.active,\n this.active ? dict.PLAY_STOP : dict.PLAY_START,\n this.active ? icons.pause : icons.play,\n )\n }\n}\n","import type { ContentType, SlideItem, ThumbsOptions } from '../types'\nimport type { Glare } from '../core/glare'\nimport { icons } from '../icons'\nimport { $, $$, createEl, on, resolveElement, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\nconst placeholderIcons: Record<ContentType, string> = {\n image: icons.thumbImage,\n video: icons.thumbVideo,\n embed: icons.thumbEmbed,\n iframe: icons.thumbIframe,\n inline: icons.thumbInline,\n ajax: icons.thumbAjax,\n html: icons.thumbHtml,\n}\n\nfunction thumbnailSource(item: SlideItem): string {\n return item.thumb || (item.type === 'video' ? item.poster : '') || (item.type === 'image' ? item.src : '')\n}\n\nfunction showPlaceholder(button: HTMLButtonElement, type: ContentType): void {\n button.classList.add('glare-thumbs-item--placeholder')\n button.innerHTML = placeholderIcons[type] ?? icons.thumbSlide\n}\n\n/** Clickable thumbnail strip, horizontal (`x`) or vertical (`y`). */\nexport class Thumbs {\n isActive = false\n private readonly axis: 'x' | 'y'\n private readonly strip: HTMLElement\n private readonly list: HTMLElement\n private offs: Array<() => void> = []\n\n constructor(\n private readonly glare: Glare,\n private readonly container: HTMLElement,\n private readonly opts: ThumbsOptions,\n ) {\n this.axis = opts.axis === 'y' ? 'y' : 'x'\n this.list = createEl('div', 'glare-thumbs-list')\n this.strip = createEl('div', `glare-thumbs glare-thumbs--${this.axis}`)\n this.strip.style.setProperty('--glare-thumbs-fit', opts.fit ?? 'cover')\n this.strip.appendChild(this.list)\n this.build()\n }\n\n show(): void {\n this.setActive(true)\n }\n\n hide(): void {\n this.setActive(false)\n }\n\n toggle(): void {\n this.setActive(!this.isActive)\n }\n\n /** Highlights the thumbnail for `index` and scrolls it into view. */\n focus(index = this.glare.currIndex): void {\n for (const el of $$('.glare-thumbs-item', this.list)) {\n el.classList.toggle('glare-is-active', Number(el.dataset.index) === index)\n }\n this.list\n .querySelector('.glare-is-active')\n ?.scrollIntoView({ block: 'nearest', inline: 'nearest', behavior: 'smooth' })\n }\n\n destroy(): void {\n this.offs.forEach((off) => off())\n this.offs = []\n this.container.classList.remove(`glare-thumbs-axis-${this.axis}`)\n this.strip.remove()\n }\n\n private setActive(active: boolean): void {\n this.isActive = active\n this.strip.classList.toggle('glare-thumbs--active', active)\n this.container.classList.toggle('glare-show-thumbs', active)\n\n const button = $('[data-glare-thumbs]', this.container)\n button?.classList.toggle('glare-is-active', active)\n button?.setAttribute('aria-expanded', String(active))\n }\n\n private build(): void {\n const { group, dict } = this.glare\n if (group.length < 2) return\n\n this.container.classList.add(`glare-thumbs-axis-${this.axis}`)\n\n for (const item of group) {\n const button = createEl('button', 'glare-thumbs-item')\n button.type = 'button'\n button.dataset.index = String(item.index)\n button.setAttribute('aria-label', translate(dict.GO_TO_SLIDE, { index: String(item.index + 1) }))\n\n const src = thumbnailSource(item)\n if (src) {\n const img = createEl('img')\n img.src = src\n img.alt = item.alt || toText(item.caption)\n img.loading = 'lazy'\n img.onerror = () => showPlaceholder(button, item.type)\n button.appendChild(img)\n } else {\n showPlaceholder(button, item.type)\n }\n\n this.list.appendChild(button)\n this.offs.push(on(button, 'click', () => this.glare.jumpTo(item.index)))\n }\n\n const parent = resolveElement(this.opts.parentEl, this.container) ?? this.container\n parent.appendChild(this.strip)\n if (this.opts.autoStart) this.show()\n this.focus()\n }\n}\n","import type { SlideItem } from '../types'\nimport { on } from '../utils/dom'\n\nexport interface WheelHost {\n /** `'auto'` only navigates on image slides; `true` on every slide. */\n mode: boolean | 'auto'\n current(): SlideItem | null\n isZoomed(): boolean\n next(): void\n prev(): void\n}\n\n/** Accumulated distance that counts as one deliberate scroll. */\nconst STEP = 40\n/** Gap between events that marks the end of a gesture, including trackpad inertia. */\nconst SETTLE = 150\nconst LINE_HEIGHT = 16\n\n/** Mouse-wheel navigation between slides: one gesture moves one slide. */\nexport class WheelNav {\n private readonly off: () => void\n private distance = 0\n private fired = false\n private settle: ReturnType<typeof setTimeout> | null = null\n\n constructor(stage: HTMLElement, host: WheelHost) {\n this.off = on(\n stage,\n 'wheel',\n (event) => {\n const current = host.current()\n if (!current || event.deltaY === 0) return\n if (host.mode === 'auto' && current.type !== 'image') return\n if (current.type === 'image' && host.isZoomed()) return\n\n event.preventDefault()\n this.restartSettle()\n if (this.fired) return\n\n this.distance += normalize(event, stage)\n if (Math.abs(this.distance) < STEP) return\n\n this.fired = true\n if (this.distance > 0) host.next()\n else host.prev()\n },\n { passive: false },\n )\n }\n\n destroy(): void {\n if (this.settle) clearTimeout(this.settle)\n this.off()\n }\n\n private restartSettle(): void {\n if (this.settle) clearTimeout(this.settle)\n this.settle = setTimeout(() => {\n this.distance = 0\n this.fired = false\n }, SETTLE)\n }\n}\n\n/** Converts line- and page-based deltas to pixels so every input reaches `STEP`. */\nfunction normalize(event: WheelEvent, stage: HTMLElement): number {\n if (event.deltaMode === WheelEvent.DOM_DELTA_LINE) return event.deltaY * LINE_HEIGHT\n if (event.deltaMode === WheelEvent.DOM_DELTA_PAGE) return event.deltaY * stage.clientHeight\n return event.deltaY\n}\n","import type { Anchor, ResolvedOptions, SlideItem } from '../types'\nimport { nextFrame, resolveElement } from '../utils/dom'\nimport { prefersReducedMotion } from '../utils/env'\n\n/**\n * The motion actually in effect. An effect is off when it is disabled, its duration is zero,\n * or the user prefers reduced motion; its duration is then zero too. Timers must wait on these\n * values rather than the raw options, since a 0ms transition never fires `transitionend`.\n */\nexport function resolveMotion(opts: ResolvedOptions) {\n const reduced = prefersReducedMotion()\n const animationDuration = reduced || !opts.animationEffect ? 0 : Math.max(0, opts.animationDuration)\n const transitionDuration = reduced || !opts.transitionEffect ? 0 : Math.max(0, opts.transitionDuration)\n\n return {\n animationEffect: animationDuration ? opts.animationEffect : false,\n animationDuration,\n transitionEffect: transitionDuration ? opts.transitionEffect : false,\n transitionDuration,\n }\n}\n\n/** Writes the effect and duration settings onto the container for the stylesheet to use. */\nexport function applyMotionSettings(container: HTMLElement, opts: ResolvedOptions): void {\n const motion = resolveMotion(opts)\n\n container.dataset.animation = motion.animationEffect || 'none'\n container.style.setProperty('--glare-duration', `${motion.animationDuration}ms`)\n container.style.setProperty('--glare-transition-duration', `${motion.transitionDuration}ms`)\n}\n\n/** Marks the container so slide-change keyframes apply from now on. */\nexport function enableTransitions(container: HTMLElement, opts: ResolvedOptions): void {\n container.dataset.transition = resolveMotion(opts).transitionEffect || 'none'\n}\n\nconst POSITION = /^(top|center|bottom)-(left|center|right)$/\nconst FRACTION: Record<string, number> = { top: 0, left: 0, center: 0.5, bottom: 1, right: 1 }\n\n/** Resolves an anchor to the rectangle the image starts from; a position yields a zero-size one. */\nfunction anchorRect(container: HTMLElement, item: SlideItem, anchor: Anchor): DOMRect | null {\n const position = typeof anchor === 'string' ? POSITION.exec(anchor) : null\n if (position) {\n const box = container.getBoundingClientRect()\n const x = box.left + box.width * FRACTION[position[2]]\n const y = box.top + box.height * FRACTION[position[1]]\n return new DOMRect(x, y, 0, 0)\n }\n\n // An element that is not rendered has no box to fly from.\n const rendered = (el?: HTMLElement | null) => (el?.getClientRects().length ? el : null)\n const el = (anchor !== 'trigger' && rendered(resolveElement(anchor))) || rendered(item.$trigger)\n\n if (!el) return null\n\n // A trigger inside an iframe (see `delegate`) reports its box relative to that frame.\n const rect = el.getBoundingClientRect()\n const frame = el.ownerDocument === container.ownerDocument ? null : el.ownerDocument.defaultView?.frameElement\n const offset = frame?.getBoundingClientRect()\n return offset ? new DOMRect(rect.x + offset.x, rect.y + offset.y, rect.width, rect.height) : rect\n}\n\n/** Flies the opened image in from its anchor. */\nexport function animateOpen(container: HTMLElement, item: SlideItem, opts: ResolvedOptions): void {\n const image = item.$image\n if (container.dataset.animation !== 'zoom' || !image) return\n\n const from = anchorRect(container, item, opts.anchor)\n if (!from) return\n\n const to = image.getBoundingClientRect()\n const scale = Math.max(from.width / Math.max(to.width, 1), from.height / Math.max(to.height, 1))\n const dx = from.left + from.width / 2 - (to.left + to.width / 2)\n const dy = from.top + from.height / 2 - (to.top + to.height / 2)\n\n Object.assign(image.style, {\n transform: `translate3d(${dx}px, ${dy}px, 0) scale(${scale})`,\n opacity: opts.zoomOpacity ? '0.2' : '1',\n transitionDuration: '0ms',\n })\n nextFrame(() => {\n Object.assign(image.style, { transform: '', opacity: '', transitionDuration: '' })\n })\n}\n","import type { GlareOptions, ResolvedOptions } from '../types'\nimport { defaults } from '../defaults'\nimport { isMobile } from '../utils/env'\nimport { deepMerge } from '../utils/object'\n\n/** Merges user options over the defaults, then applies `mobile` overrides on touch devices. */\nexport function resolveOptions(options: GlareOptions): ResolvedOptions {\n const merged = deepMerge<ResolvedOptions>(defaults, options)\n return isMobile() && merged.mobile ? deepMerge<ResolvedOptions>(merged, merged.mobile) : merged\n}\n\n/** Normalizes a `T | boolean` module option: `true` yields the defaults, falsy disables it. */\nexport function moduleOptions<T extends object>(value: Partial<T> | boolean | undefined, fallback: T): T | null {\n if (!value) return null\n return value === true ? { ...fallback } : { ...fallback, ...value }\n}\n","import type { BoundGroup, GlareOptions } from '../types'\nimport { parseHash } from '../modules/hash'\nimport { $$, on } from '../utils/dom'\nimport { resolveOptions } from './options'\n\nexport type BindTarget = string | HTMLElement | HTMLElement[] | NodeListOf<HTMLElement>\n\n/** Opens `elements` as a gallery named `gallery`, starting at `index`. */\ntype Opener = (elements: HTMLElement[], index: number, gallery: string) => void\n\nconst groups: BoundGroup[] = []\n\nconst galleryOf = (el: HTMLElement): string => el.getAttribute('data-glare') ?? ''\n\nfunction toElements(target: BindTarget): HTMLElement[] {\n if (typeof target === 'string') return $$(target)\n if (target instanceof HTMLElement) return [target]\n return Array.from(target)\n}\n\n/** Attaches click handlers that open a lightbox for the clicked element's gallery. */\nexport function bind(target: BindTarget, options: GlareOptions, open: Opener): BoundGroup {\n const elements = toElements(target)\n\n const openFrom = (el: HTMLElement) => {\n const gallery = galleryOf(el)\n const members = gallery ? elements.filter((item) => galleryOf(item) === gallery) : [el]\n open(members, members.indexOf(el), gallery)\n }\n\n const offs = elements.map((el) =>\n on(el, 'click', (event) => {\n event.preventDefault()\n openFrom(el)\n }),\n )\n\n const group: BoundGroup = {\n elements,\n destroy() {\n offs.forEach((off) => off())\n const index = groups.indexOf(group)\n if (index >= 0) groups.splice(index, 1)\n },\n }\n groups.push(group)\n\n if (resolveOptions(options).hash) restoreFromHash(elements, openFrom)\n return group\n}\n\nexport function unbindAll(): void {\n for (const group of [...groups]) group.destroy()\n}\n\n/** Opens the slide referenced by the current URL hash, if it belongs to a bound gallery. */\nfunction restoreFromHash(elements: HTMLElement[], openFrom: (el: HTMLElement) => void): void {\n const parsed = parseHash()\n if (!parsed) return\n\n const members = elements.filter((el) => galleryOf(el) === parsed.gallery)\n const el = members[parsed.index]\n if (el) openFrom(el)\n}\n","/** Calls `onIdle` after `seconds` of no activity; `false` disables it. */\nexport class IdleTimer {\n private timer: ReturnType<typeof setTimeout> | null = null\n\n constructor(\n private readonly seconds: number | false,\n private readonly onIdle: () => void,\n ) {}\n\n reset(): void {\n this.stop()\n if (this.seconds) this.timer = setTimeout(this.onIdle, this.seconds * 1000)\n }\n\n stop(): void {\n if (this.timer) clearTimeout(this.timer)\n this.timer = null\n }\n}\n","import type { Glare } from './glare'\n\n/** Stack of open instances, topmost last. */\nconst stack: Glare[] = []\n\nexport const registry = {\n add(instance: Glare): void {\n stack.push(instance)\n },\n remove(instance: Glare): void {\n const index = stack.indexOf(instance)\n if (index >= 0) stack.splice(index, 1)\n },\n top(): Glare | null {\n return stack[stack.length - 1] ?? null\n },\n get(id: number): Glare | null {\n return stack.find((instance) => instance.id === id) ?? null\n },\n all(): Glare[] {\n return [...stack]\n },\n get size(): number {\n return stack.length\n },\n}\n","import type { ClickAction, ClickActionName, CustomButton } from '../types'\nimport type { Glare } from './glare'\nimport { $$, on } from '../utils/dom'\nimport { registry } from './registry'\n\ntype ButtonHandler = (glare: Glare) => void\n\n/** Toolbar / navigation buttons, matched against `event.target` in order. */\nconst BUTTONS: Array<[selector: string, handler: ButtonHandler]> = [\n ['[data-glare-close]', (g) => g.close()],\n ['[data-glare-next]', (g) => g.next()],\n ['[data-glare-prev]', (g) => g.prev()],\n ['[data-glare-zoom]', (g) => g.toggleZoom()],\n ['[data-glare-slideshow]', (g) => g.slideshow?.toggle()],\n ['[data-glare-thumbs]', (g) => g.thumbs?.toggle()],\n ['[data-glare-fullscreen]', (g) => g.fullscreen?.toggle()],\n]\n\nconst CONTENT = '.glare-content'\nconst SLIDE_AREA = '.glare-slide, .glare-stage'\nconst FOCUSABLE = 'button, [href], input, select, textarea, [tabindex]:not([tabindex=\"-1\"])'\nconst FORM_TAGS = new Set(['INPUT', 'TEXTAREA', 'SELECT'])\n\n/** How long a single click waits for a possible second click when a double-click action exists. */\nconst DBLCLICK_WINDOW = 300\n\n/** Wires clicks, keyboard, focus trapping and idle tracking. Returns a cleanup function. */\nexport function bindInteractions(glare: Glare, container: HTMLElement, onActivity: () => void): () => void {\n let pendingClick: ReturnType<typeof setTimeout> | null = null\n const cancelPending = () => {\n if (pendingClick) clearTimeout(pendingClick)\n pendingClick = null\n }\n\n const offs = [\n on(container, 'click', (event) => {\n if (glare.consumeGesture()) return\n\n const target = event.target as HTMLElement\n const more = target.closest<HTMLElement>('[data-glare-more]')\n\n if (more) {\n const toolbar = more.closest('.glare-toolbar')\n const expanded = !toolbar?.classList.contains('glare-toolbar--expanded')\n toolbar?.classList.toggle('glare-toolbar--expanded', expanded)\n more.setAttribute('aria-expanded', String(expanded))\n return\n }\n\n closeToolbarMenu(container)\n const custom = target.closest<HTMLElement>('[data-glare-custom]')\n if (custom) return runCustomButton(glare, custom.dataset.glareCustom, event)\n\n const button = BUTTONS.find(([selector]) => target.closest(selector))\n if (button) return button[1](glare)\n if (target.closest('.glare-button')) return\n\n const single = slideAction(glare, target, 'click')\n if (!single) return\n\n // When a double-click action exists, hold the single click so a double-tap does not fire both.\n if (!resolveAction(glare, slideAction(glare, target, 'dblclick'), event)) {\n return runAction(glare, single, event)\n }\n cancelPending()\n pendingClick = setTimeout(() => runAction(glare, single, event), DBLCLICK_WINDOW)\n }),\n on(container, 'dblclick', (event) => {\n cancelPending()\n const target = event.target as HTMLElement\n if (target.closest('.glare-button')) return\n runAction(glare, slideAction(glare, target, 'dblclick'), event)\n }),\n on(document, 'keydown', (event) => onKeydown(glare, event)),\n on(document, 'keydown', onActivity),\n on(document, 'click', onActivity, { capture: true }),\n on(document, 'mousemove', onActivity),\n on(document, 'touchstart', onActivity, { passive: true }),\n ]\n\n if (glare.opts.trapFocus) {\n offs.push(on(container, 'keydown', (event) => trapFocus(container, event)))\n }\n\n if (glare.opts.protect) {\n offs.push(\n on(container, 'contextmenu', (event) => event.preventDefault()),\n on(container, 'dragstart', (event) => {\n if ((event.target as HTMLElement).tagName === 'IMG') event.preventDefault()\n }),\n )\n }\n\n return () => {\n cancelPending()\n offs.forEach((off) => off())\n }\n}\n\n/** Runs the `click` of the inline button called `name`. */\nfunction runCustomButton(glare: Glare, name: string | undefined, event: MouseEvent): void {\n const button = glare.opts.buttons.find((b): b is CustomButton => typeof b !== 'string' && b.name === name)\n if (button && glare.current) button.click(glare, glare.current, event)\n}\n\n/** Picks the content action or the slide action for `target`; modal mode ignores the slide area. */\nfunction slideAction(glare: Glare, target: HTMLElement, kind: 'click' | 'dblclick'): ClickAction | undefined {\n const { opts } = glare\n if (target.closest(CONTENT)) return kind === 'click' ? opts.clickContent : opts.dblclickContent\n if (opts.modal || !target.closest(SLIDE_AREA)) return undefined\n return kind === 'click' ? opts.clickSlide : opts.dblclickSlide\n}\n\nfunction resolveAction(glare: Glare, action: ClickAction | undefined, event: Event): ClickActionName | false | void {\n if (!action || !glare.current) return false\n return typeof action === 'function' ? action(glare.current, event) : action\n}\n\nfunction runAction(glare: Glare, action: ClickAction | undefined, event: Event): void {\n switch (resolveAction(glare, action, event)) {\n case 'close':\n return glare.close()\n case 'next':\n return glare.next()\n case 'nextOrClose':\n return glare.currIndex === glare.group.length - 1 && !glare.opts.loop ? glare.close() : glare.next()\n case 'toggleControls':\n return glare.toggleControls()\n case 'zoom': {\n const point = event instanceof MouseEvent ? { x: event.clientX, y: event.clientY } : undefined\n return glare.toggleZoom(point)\n }\n }\n}\n\nfunction onKeydown(glare: Glare, event: KeyboardEvent): void {\n if (registry.top() !== glare) return\n\n if (event.key === 'Escape' && closeToolbarMenu(glare.$refs?.container ?? null)) {\n event.preventDefault()\n return\n }\n\n if (!glare.opts.keyboard || glare.opts.modal) return\n\n const target = event.target as HTMLElement\n if (FORM_TAGS.has(target.tagName)) return\n // A focused button already activates on Space; don't toggle the slideshow as well.\n if (event.key === ' ' && target.closest('button')) return\n\n switch (event.key) {\n case 'Escape':\n event.preventDefault()\n return glare.close()\n case 'ArrowRight':\n case 'ArrowDown':\n event.preventDefault()\n return glare.next()\n case 'ArrowLeft':\n case 'ArrowUp':\n event.preventDefault()\n return glare.prev()\n case ' ':\n event.preventDefault()\n return glare.slideshow?.toggle()\n case 'f':\n case 'F':\n return glare.fullscreen?.toggle()\n }\n}\n\nfunction closeToolbarMenu(container: HTMLElement | null): boolean {\n const toolbar = container?.querySelector('.glare-toolbar--expanded')\n if (!toolbar) return false\n\n toolbar.classList.remove('glare-toolbar--expanded')\n toolbar.querySelector('[data-glare-more]')?.setAttribute('aria-expanded', 'false')\n return true\n}\n\nfunction trapFocus(container: HTMLElement, event: KeyboardEvent): void {\n if (event.key !== 'Tab') return\n\n const focusable = $$(FOCUSABLE, container).filter(\n (el) => !el.hasAttribute('disabled') && el.offsetParent !== null && getComputedStyle(el).visibility !== 'hidden',\n )\n if (!focusable.length) return\n\n const first = focusable[0]\n const last = focusable[focusable.length - 1]\n if (event.shiftKey && document.activeElement === first) {\n event.preventDefault()\n last.focus()\n } else if (!event.shiftKey && document.activeElement === last) {\n event.preventDefault()\n first.focus()\n }\n}\n","import type { ContentType, I18nDict, ResolvedOptions, SlideItem } from '../types'\nimport { videoMime } from '../media/detect'\nimport { $, createEl, toCssSize, toText } from '../utils/dom'\nimport { translate } from '../utils/template'\n\ntype Loader = (item: SlideItem, content: HTMLElement, opts: ResolvedOptions, dict: I18nDict) => Promise<void> | void\n\nconst IFRAME_LOAD_FALLBACK = 1200\nconst DEFAULT_EMBED_RATIO = 16 / 9\n\nfunction embedRatio(item: SlideItem, width?: number, height?: number): number {\n if (width && height) return width / height\n\n const value = String(item.ratio || DEFAULT_EMBED_RATIO).replace(':', '/')\n const [x, y = '1'] = value.split('/').map((part) => part.trim())\n const numerator = parseFloat(x)\n const denominator = parseFloat(y)\n return numerator > 0 && denominator > 0 ? numerator / denominator : DEFAULT_EMBED_RATIO\n}\n\nfunction toPixels(value: number | string | undefined, available: number, viewport: number): number {\n if (!value) return 0\n if (typeof value === 'number') return value\n\n const input = value.trim()\n const amount = parseFloat(input)\n\n if (!(amount > 0)) return 0\n if (input.endsWith('%')) return available * amount / 100\n if (input.endsWith('vw') || input.endsWith('vh')) return viewport * amount / 100\n\n return amount\n}\n\n/** Fits video dimensions inside the slide using the same ratio-first model as Fancybox v3. */\nfunction fitEmbed(item: SlideItem, content: HTMLElement): void {\n const slide = content.parentElement\n if (!slide) return\n\n const style = getComputedStyle(slide)\n const availableWidth = slide.clientWidth - parseFloat(style.paddingLeft) - parseFloat(style.paddingRight)\n const availableHeight = slide.clientHeight - parseFloat(style.paddingTop) - parseFloat(style.paddingBottom)\n if (!(availableWidth > 0 && availableHeight > 0)) return\n\n const hasDimensions = item.width !== undefined && item.height !== undefined\n let width = hasDimensions ? toPixels(item.width, availableWidth, innerWidth) : availableWidth\n let height = hasDimensions ? toPixels(item.height, availableHeight, innerHeight) : availableHeight\n const ratio = embedRatio(item, hasDimensions ? width : undefined, hasDimensions ? height : undefined)\n\n const scale = Math.min(1, availableWidth / width, availableHeight / height)\n width *= scale\n height *= scale\n\n if (height > width / ratio) height = width / ratio\n else if (width > height * ratio) width = height * ratio\n\n content.style.width = `${width}px`\n content.style.height = `${height}px`\n content.style.aspectRatio = String(ratio)\n}\n\nfunction observeEmbed(item: SlideItem, content: HTMLElement): void {\n fitEmbed(item, content)\n if (typeof ResizeObserver === 'undefined' || !content.parentElement) return\n\n const observer = new ResizeObserver(() => {\n if (!content.isConnected) return observer.disconnect()\n fitEmbed(item, content)\n })\n\n observer.observe(content.parentElement)\n}\n\nconst image: Loader = (item, content, opts) =>\n new Promise((resolve, reject) => {\n const img = createEl('img', 'glare-image')\n img.alt = item.alt || toText(item.caption)\n img.decoding = 'async'\n img.draggable = false\n if (opts.protect) img.style.pointerEvents = 'none'\n\n img.onload = () => {\n item.$image = img\n item.contentWidth = img.naturalWidth\n item.contentHeight = img.naturalHeight\n content.appendChild(img)\n resolve()\n }\n img.onerror = () => reject(new Error(`Failed to load image: ${item.src}`))\n img.src = item.src\n })\n\nconst video: Loader = (item, content, opts, dict) => {\n const format = item.format || opts.video.format || videoMime(item.src)\n content.innerHTML = translate(opts.video.tpl, {\n ...dict,\n src: item.src,\n format,\n poster: item.poster ?? '',\n })\n\n const el = content.querySelector('video')\n if (el && (item.autoStart ?? opts.video.autoStart)) {\n void el.play().catch(() => undefined)\n }\n}\n\nconst iframe: Loader = (item, content, opts) =>\n new Promise((resolve) => {\n const settings = opts.iframe\n const wrap = createEl('div', 'glare-iframe-wrap', settings.tpl)\n const frame = wrap.querySelector('iframe')\n if (!frame) throw new Error('Iframe template must contain an <iframe>')\n\n for (const [name, value] of Object.entries(settings.attr)) frame.setAttribute(name, value)\n Object.assign(frame.style, settings.css)\n content.appendChild(wrap)\n\n if (item.type === 'embed') {\n observeEmbed(item, content)\n } else {\n if (item.width) wrap.style.width = toCssSize(item.width)\n if (item.height) wrap.style.height = toCssSize(item.height)\n }\n\n if (!settings.preload) {\n frame.src = item.src\n resolve()\n return\n }\n\n frame.onload = () => resolve()\n frame.src = item.src\n // Cross-origin frames may never fire `load`; reveal the slide anyway.\n setTimeout(resolve, IFRAME_LOAD_FALLBACK)\n })\n\nconst inline: Loader = (item, content) => {\n const source = item.src ? $(item.src) : null\n if (!source) throw new Error(`Inline target not found: ${item.src}`)\n\n const clone = source.cloneNode(true) as HTMLElement\n clone.removeAttribute('id')\n clone.hidden = false\n clone.style.display = ''\n content.appendChild(clone)\n}\n\nconst ajax: Loader = async (item, content, opts) => {\n const response = await fetch(item.src, opts.ajax.settings)\n if (!response.ok) throw new Error(`Request failed: ${response.status} ${item.src}`)\n content.innerHTML = await response.text()\n}\n\nconst html: Loader = (item, content) => {\n if (item.content && typeof item.content === 'object') {\n content.appendChild(item.content)\n } else {\n content.innerHTML = item.html ?? item.content ?? item.src\n }\n}\n\nconst loaders: Record<ContentType, Loader> = { image, video, embed: iframe, iframe, inline, ajax, html }\n\n/** Renders the slide's content into `content` and resolves once it can be shown. */\nexport async function loadContent(item: SlideItem, content: HTMLElement, opts: ResolvedOptions, dict: I18nDict): Promise<void> {\n content.innerHTML = ''\n content.className = `glare-content glare-content--${item.type}`\n await loaders[item.type](item, content, opts, dict)\n item.isLoaded = true\n}\n\n/** Warms the browser cache for neighbouring images. */\nexport function preloadNeighbours(group: SlideItem[], index: number): void {\n for (const neighbour of [group[index - 1], group[index + 1]]) {\n if (neighbour?.type === 'image' && neighbour.src) new Image().src = neighbour.src\n }\n}\n","import type {\n BoundGroup,\n GlareInstance,\n GlareOptions,\n GlareRefs,\n I18nDict,\n LifecycleEvent,\n ResolvedOptions,\n SlideEvent,\n SlideItem,\n SlideSource,\n} from '../types'\nimport { defaults, fullscreenDefaults, slideshowDefaults, thumbsDefaults } from '../defaults'\nimport { getDict } from '../i18n'\nimport { createItems } from '../media/items'\nimport { Fullscreen } from '../modules/fullscreen'\nimport { Gestures } from '../modules/gestures'\nimport { Hash } from '../modules/hash'\nimport { Slideshow } from '../modules/slideshow'\nimport { Thumbs } from '../modules/thumbs'\nimport { WheelNav } from '../modules/wheel'\nimport { afterTransition, nextFrame } from '../utils/dom'\nimport { lockScroll, supportsFullscreen } from '../utils/env'\nimport { clamp } from '../utils/object'\nimport { animateOpen, applyMotionSettings, enableTransitions, resolveMotion } from './animation'\nimport { bind, unbindAll, type BindTarget } from './bind'\nimport * as dom from './dom'\nimport { IdleTimer } from './idle'\nimport { bindInteractions } from './interactions'\nimport { loadContent, preloadNeighbours } from './loaders'\nimport { moduleOptions, resolveOptions } from './options'\nimport { registry } from './registry'\nimport { Zoom, type Point } from './zoom'\n\nlet nextId = 0\n\n/** The `Glare` class loaded in another window. A cross-origin window throws on access and counts as having none. */\nfunction glareOf(target?: Window): typeof Glare | undefined {\n try {\n return (target as (Window & { Glare?: typeof Glare }) | undefined)?.Glare\n } catch {\n return undefined\n }\n}\n\nexport class Glare implements GlareInstance {\n readonly id = ++nextId\n readonly opts: ResolvedOptions\n readonly group: SlideItem[]\n readonly dict: I18nDict\n readonly zoom: Zoom\n current: SlideItem | null = null\n currIndex = 0\n prevIndex = 0\n isActive = false\n isClosing = false\n isIdle = false\n $refs: GlareRefs | null = null\n\n slideshow?: Slideshow\n thumbs?: Thumbs\n fullscreen?: Fullscreen\n\n private readonly galleryName: string\n private readonly idle: IdleTimer\n private hash: Hash | null = null\n private gestures: Gestures | null = null\n private wheel: WheelNav | null = null\n private cleanups: Array<() => void> = []\n private captionTracker: ReturnType<typeof dom.trackCaption> | null = null\n private previouslyFocused: HTMLElement | null = null\n private direction: dom.Direction = 1\n\n constructor(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n galleryName = '',\n ) {\n this.opts = resolveOptions(options)\n this.dict = getDict(this.opts)\n this.group = createItems(items, this.opts)\n this.galleryName = galleryName\n this.currIndex = this.clampIndex(index)\n\n this.zoom = new Zoom({\n image: () => this.current?.$image ?? null,\n stage: () => this.$refs?.stage ?? null,\n onChange: (zoomed) => this.syncZoomState(zoomed),\n })\n this.idle = new IdleTimer(this.opts.modal ? false : this.opts.idleTime, () => this.toggleControls(true))\n }\n\n open(index = this.currIndex): void {\n if (this.isActive) return this.jumpTo(index)\n if (!this.group.length) return\n if (this.opts.closeExisting) Glare.close(true)\n\n this.currIndex = this.clampIndex(index)\n this.current = this.group[this.currIndex]\n this.previouslyFocused = document.activeElement instanceof HTMLElement ? document.activeElement : null\n this.emit('onInit')\n\n const refs = dom.buildContainer(this.opts, this.dict, this.id, this.group.length)\n const { container } = refs\n container.classList.add('glare-is-loading')\n this.$refs = refs\n\n applyMotionSettings(container, this.opts)\n\n this.syncChrome()\n this.resolveParent().appendChild(container)\n this.captionTracker = dom.trackCaption(refs)\n this.cleanups.push(() => this.captionTracker?.destroy())\n\n this.isActive = true\n registry.add(this)\n if (this.opts.hideScrollbar) lockScroll(true)\n this.emit('onActivate')\n this.emitSlide('beforeShow', this.current)\n\n nextFrame(() => {\n if (!this.isActive) return\n\n container.classList.add('glare-is-open')\n this.showSlide(this.currIndex, true)\n this.cleanups.push(bindInteractions(this, container, () => this.onActivity()))\n this.startModules(refs)\n if (this.opts.autoFocus) this.focus()\n this.idle.reset()\n })\n }\n\n close(): void {\n if (!this.isActive || this.isClosing || !this.current || !this.$refs) return\n if (this.emitSlide('beforeClose', this.current) === false) return\n\n this.isClosing = true\n this.slideshow?.stop()\n this.idle.stop()\n\n const { container, bg } = this.$refs\n const duration = resolveMotion(this.opts).animationDuration\n if (duration === 0) return this.teardown()\n\n container.classList.remove('glare-is-open')\n container.classList.add('glare-is-closing')\n afterTransition(bg ?? container, duration, () => this.teardown())\n }\n\n next(): void {\n this.jumpTo(this.currIndex + 1)\n }\n\n prev(): void {\n this.jumpTo(this.currIndex - 1)\n }\n\n jumpTo(index: number): void {\n if (!this.isActive || this.isClosing) return\n\n const total = this.group.length\n const target = this.opts.loop ? ((index % total) + total) % total : clamp(index, 0, total - 1)\n if (target === this.currIndex) return\n\n // Compared before wrapping, so next() off the last slide still counts as forward.\n this.direction = index > this.currIndex ? 1 : -1\n this.prevIndex = this.currIndex\n this.currIndex = target\n this.zoom.reset()\n this.current = this.group[target]\n this.$refs?.container.classList.add('glare-is-loading')\n this.syncChrome()\n this.showSlide(target, false)\n\n this.thumbs?.focus(target)\n this.hash?.update(target)\n this.slideshow?.onIndexChange()\n this.emitSlide('onUpdate', this.current)\n }\n\n toggleZoom(focus?: Point): void {\n if (this.current?.type !== 'image') return\n if (this.zoom.isZoomed) this.zoom.toFit()\n else this.zoom.toActual(focus)\n }\n\n update(): void {\n this.syncChrome()\n }\n\n focus(): void {\n this.$refs?.container.focus({ preventScroll: true })\n }\n\n toggleControls(force?: boolean): void {\n if (!this.$refs) return\n this.isIdle = force ?? !this.isIdle\n this.$refs.container.classList.toggle('glare-is-idle', this.isIdle)\n }\n\n /** True once per drag gesture, so the click that follows it can be ignored. */\n consumeGesture(): boolean {\n return this.gestures?.consumeMoved() ?? false\n }\n\n private async showSlide(index: number, opening: boolean): Promise<void> {\n const item = this.group[index]\n if (!this.$refs || !item) return\n\n const { container, stage } = this.$refs\n const slide = dom.mountSlide(stage, item, this.opts)\n if (dom.usesSmallButton(this.opts, item)) dom.addSmallButton(slide, this.opts, this.dict)\n if (!opening) dom.retireSlides(stage, slide, 0, this.direction)\n dom.showSpinner(stage, this.opts, this.dict)\n this.emitSlide('beforeLoad', item)\n if (this.opts.image.preload) preloadNeighbours(this.group, index)\n\n let failed = false\n try {\n await loadContent(item, item.$content as HTMLElement, this.opts, this.dict)\n } catch (error) {\n failed = true\n dom.showError(item, error, this.opts, this.dict)\n this.emitSlide('onError', item)\n if (!this.opts.onError) console.warn('[glare]', error)\n }\n\n if (!this.isActive || this.currIndex !== index) return slide.remove()\n if (!failed) this.emitSlide('afterLoad', item)\n\n dom.hideSpinner(stage)\n if (!opening) enableTransitions(container, this.opts)\n dom.revealSlide(slide, opening, this.direction)\n this.captionTracker?.follow(slide)\n container.classList.remove('glare-is-loading')\n dom.retireSlides(stage, slide, resolveMotion(this.opts).transitionDuration, this.direction)\n this.syncZoomState(this.zoom.isZoomed)\n\n if (failed) return\n if (opening) animateOpen(container, item, this.opts)\n this.emitSlide('afterShow', item)\n }\n\n private syncChrome(): void {\n if (!this.$refs || !this.current) return\n dom.syncChrome(this.$refs, this.opts, this.dict, this.current, this.group.length, this.captionFor(this.current))\n this.syncZoomState(this.zoom.isZoomed)\n }\n\n private captionFor(item: SlideItem): string {\n const { caption } = this.opts\n if (typeof caption === 'function') return caption(this, item)\n return caption ?? item.caption\n }\n\n private syncZoomState(zoomed: boolean): void {\n if (this.$refs) dom.syncZoomButton(this.$refs.container, this.dict, zoomed, !!this.current?.$image)\n }\n\n private resolveParent(): HTMLElement {\n const { parentEl } = this.opts\n const el = typeof parentEl === 'string' ? document.querySelector<HTMLElement>(parentEl) : parentEl\n return el ?? document.body\n }\n\n private startModules({ container, stage, bg }: GlareRefs): void {\n const opts = this.opts\n\n const thumbs = moduleOptions(opts.thumbs, thumbsDefaults)\n if (thumbs) this.thumbs = new Thumbs(this, container, thumbs)\n\n const slideshow = moduleOptions(opts.slideshow, slideshowDefaults)\n if (slideshow) this.slideshow = new Slideshow(this, container, slideshow)\n\n const fullscreen = moduleOptions(opts.fullscreen, fullscreenDefaults)\n if (fullscreen && supportsFullscreen()) this.fullscreen = new Fullscreen(this, container, fullscreen)\n\n if (opts.hash && this.galleryName) this.hash = new Hash(this, this.galleryName)\n\n if (opts.wheel) {\n this.wheel = new WheelNav(stage, {\n mode: opts.wheel,\n current: () => this.current,\n isZoomed: () => this.zoom.isZoomed,\n next: () => this.next(),\n prev: () => this.prev(),\n })\n }\n\n if (opts.touch) {\n this.gestures = new Gestures(stage, {\n zoom: this.zoom,\n touch: opts.touch,\n bg,\n canPan: () => this.current?.type === 'image',\n close: () => this.close(),\n next: () => this.next(),\n prev: () => this.prev(),\n })\n }\n }\n\n private onActivity(): void {\n if (this.isIdle) this.toggleControls(false)\n this.idle.reset()\n }\n\n private teardown(): void {\n for (const module of [\n this.gestures,\n this.wheel,\n this.hash,\n this.thumbs,\n this.slideshow,\n this.fullscreen,\n ]) {\n module?.destroy()\n }\n this.gestures = this.wheel = this.hash = null\n this.thumbs = this.slideshow = this.fullscreen = undefined\n\n this.cleanups.forEach((off) => off())\n this.cleanups = []\n this.$refs?.container.remove()\n this.$refs = null\n\n registry.remove(this)\n if (this.opts.hideScrollbar && registry.size === 0) lockScroll(false)\n if (this.opts.backFocus) {\n const target = this.current?.$trigger ?? this.previouslyFocused\n target?.focus({ preventScroll: true })\n }\n\n this.isActive = false\n this.isClosing = false\n if (this.current) this.emitSlide('afterClose', this.current)\n }\n\n private emit(name: LifecycleEvent): unknown {\n return this.opts[name]?.(this)\n }\n\n private emitSlide(name: SlideEvent, item: SlideItem): unknown {\n return this.opts[name]?.(this, item)\n }\n\n private clampIndex(index: number): number {\n return clamp(index, 0, Math.max(0, this.group.length - 1))\n }\n\n static defaults = defaults\n\n static open(\n items: Array<SlideSource | string> | HTMLElement[],\n options: GlareOptions = {},\n index = 0,\n ): Glare {\n const instance = Glare.create(items, options, index)\n instance.open()\n return instance\n }\n\n static bind(target: BindTarget, options: GlareOptions = {}): BoundGroup {\n return bind(target, options, (elements, index, gallery) => {\n Glare.create(elements, options, index, gallery).open()\n })\n }\n\n /** Builds the instance here, or in the `delegate` window when that window has Glare loaded. */\n private static create(\n items: Array<SlideSource | string> | HTMLElement[],\n { delegate = defaults.delegate, ...options }: GlareOptions,\n index: number,\n gallery = '',\n ): Glare {\n return new (glareOf(delegate) ?? Glare)(items, options, index, gallery)\n }\n\n static close(all = false): void {\n if (all) registry.all().reverse().forEach((instance) => instance.close())\n else registry.top()?.close()\n }\n\n static getInstance(id?: number): Glare | null {\n return id == null ? registry.top() : registry.get(id)\n }\n\n static getInstances(): Glare[] {\n return registry.all()\n }\n\n /** Closes every instance and removes all `bind()` handlers. */\n static destroy(): void {\n Glare.close(true)\n unbindAll()\n }\n\n /** Binds every `[data-glare]` element once the DOM is ready. */\n static autoBind(options: GlareOptions = {}): void {\n const run = () => Glare.bind('[data-glare]', options)\n if (document.readyState === 'loading') {\n document.addEventListener('DOMContentLoaded', run, { once: true })\n } else {\n run()\n }\n }\n}\n","import { Glare } from './core/glare'\n\nexport type {\n AjaxOptions,\n Anchor,\n AnchorPosition,\n AnimationEffect,\n BoundGroup,\n ClickAction,\n ClickActionName,\n ContentType,\n CustomButton,\n EventHandler,\n EventName,\n FullscreenOptions,\n GlareInstance,\n GlareOptions,\n GlareRefs,\n I18nDict,\n IframeOptions,\n ImageOptions,\n LifecycleEvent,\n LifecycleHandler,\n MediaProvider,\n ResolvedOptions,\n SlideEvent,\n SlideItem,\n SlideSource,\n SlideshowOptions,\n ThumbsFit,\n ThumbsOptions,\n ToolbarButton,\n TouchOptions,\n TransitionEffect,\n VideoOptions,\n} from './types'\nexport type { Point, Zoom, ZoomState } from './core/zoom'\n\nexport { Glare }\n\nexport const autoBind = Glare.autoBind\n\nexport default Glare\n"],"names":["i18nEn","getDict","opts","lang","translate","template","dict","_","key","buildQuery","params","value","expandMatch","match","n","providers","tld","coords","query","search","lat","lng","zoom","z","q","resolve","src","applyProvider","media","provider","url","svg","paths","icons","button","name","label","icon","attrs","baseTemplate","buttonTemplates","spinnerTemplate","errorTemplate","videoTemplate","iframeTemplate","thumbsDefaults","slideshowDefaults","fullscreenDefaults","defaults","current","IMAGE_EXT","VIDEO_EXT","PDF_EXT","SELECTOR","detectType","fallback","videoMime","ext","normalizeItem","source","index","raw","type","thumb","provided","attr","el","itemsFromElements","elements","img","caption","createItems","items","item","$","selector","root","$$","createEl","tag","className","html","fromHtml","toText","resolveElement","target","toCssSize","on","handler","options","nextFrame","callback","afterTransition","duration","done","finished","finish","timer","onEnd","event","isMobile","prefersReducedMotion","supportsFullscreen","doc","LOCK_CLASS","lockScroll","lock","scrollbar","HIDDEN","buildContainer","id","count","container","stage","refs","single","buildToolbar","toolbar","menu","createCustomButton","tpl","moreTpl","closeTpl","layoutTop","ancestor","top","node","trackCaption","slide","sync","content","observer","next","mountSlide","revealSlide","opening","direction","retireSlides","keep","delay","addSmallButton","showSpinner","hideSpinner","showError","error","isToolbarVisible","usesSmallButton","syncChrome","total","infobar","setTypeClass","syncToolbar","syncDownloadLink","syncInfobar","syncCaption","syncArrows","syncDialogLabel","visible","zoomable","link","href","indexEl","atStart","atEnd","setDisabled","disabled","base","live","previous","syncZoomButton","zoomed","hasImage","state","setToggleState","active","Fullscreen","glare","off","isPlainObject","proto","deepMerge","sources","result","existing","clamp","min","max","ZOOM_MIN","ZOOM_MAX","ZOOMED_THRESHOLD","Zoom","image","rect","scale","x","y","focus","center","natural","fx","fy","maxX","maxY","MOVE_THRESHOLD","MOMENTUM","SWIPE_CLOSE_DISTANCE","SWIPE_CLOSE_VELOCITY","SWIPE_NAV_DISTANCE","SWIPE_NAV_VELOCITY","IGNORED_TARGETS","distance","a","b","midpoint","pointOf","Gestures","host","moved","points","dx","dy","vertical","mid","ox","oy","last","elapsed","velocity","bg","HASH_PATTERN","parseHash","hash","formatHash","gallery","Hash","currentHash","parsed","pathname","Slideshow","hide","placeholderIcons","thumbnailSource","showPlaceholder","Thumbs","group","STEP","SETTLE","LINE_HEIGHT","WheelNav","normalize","resolveMotion","reduced","animationDuration","transitionDuration","applyMotionSettings","motion","enableTransitions","POSITION","FRACTION","anchorRect","anchor","position","box","rendered","offset","animateOpen","from","to","resolveOptions","merged","moduleOptions","groups","galleryOf","toElements","bind","open","openFrom","members","offs","restoreFromHash","unbindAll","IdleTimer","seconds","onIdle","stack","registry","instance","BUTTONS","g","CONTENT","SLIDE_AREA","FOCUSABLE","FORM_TAGS","DBLCLICK_WINDOW","bindInteractions","onActivity","pendingClick","cancelPending","more","expanded","closeToolbarMenu","custom","runCustomButton","slideAction","resolveAction","runAction","onKeydown","trapFocus","kind","action","point","focusable","first","IFRAME_LOAD_FALLBACK","DEFAULT_EMBED_RATIO","embedRatio","width","height","part","numerator","denominator","toPixels","available","viewport","input","amount","fitEmbed","style","availableWidth","availableHeight","hasDimensions","ratio","observeEmbed","reject","video","format","iframe","settings","wrap","frame","inline","clone","ajax","response","loaders","loadContent","preloadNeighbours","neighbour","nextId","glareOf","_Glare","galleryName","dom.buildContainer","dom.trackCaption","force","dom.mountSlide","dom.usesSmallButton","dom.addSmallButton","dom.retireSlides","dom.showSpinner","failed","dom.showError","dom.hideSpinner","dom.revealSlide","dom.syncChrome","dom.syncZoomButton","parentEl","thumbs","slideshow","fullscreen","module","delegate","all","run","Glare","autoBind"],"mappings":"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"}
|