{"mappings":"A,S,E,C,C,C,C,C,C,C,E,O,c,C,E,E,C,I,E,I,E,W,C,E,a,C,C,E,C,I,E,W,E,C,E,E,C,E,E,E,iB,A,O,I,A,C,E,S,C,E,G,K,E,O,C,C,E,C,O,C,G,K,E,C,I,E,C,C,E,A,Q,C,C,E,C,I,E,C,G,E,Q,C,C,E,O,C,C,E,C,E,E,I,C,E,O,C,E,E,O,E,E,O,A,C,I,E,A,M,uB,E,I,O,E,I,C,mB,C,C,E,Q,C,S,C,C,C,E,C,C,E,C,C,E,E,iB,C,G,I,E,E,Q,C,E,Q,S,C,C,C,E,E,S,I,E,E,S,E,SC0CiC,EAAA,OAAa,A,G,E,Q,S,C,C,C,ECjCvC,SAAS,EAAc,CAAS,CAAE,CAAO,CAAE,CAAU,EAC1D,IAAM,EAAK,SAAS,aAAa,CAAC,GAOlC,OANI,GACF,CAAA,EAAG,SAAS,CAAG,CADjB,EAGI,GACF,EAAW,WAAW,CAAC,GAElB,CACT,CAoEO,SAAS,EAAkB,CAAC,CAAE,CAAC,CAAE,CAAK,EAC3C,IAAI,EAAY,CAAC,YAAY,EAAE,EAAE,GAAG,EAAE,GAAK,EAAE,KAAK,CAAC,CAMnD,OAJc,KAAA,IAAV,GACF,CAAA,GAAa,CAAC,SAAS,EAAE,EAAM,CAAC,EAAE,EAAM,GAAG,CAAC,AAAD,EAGtC,CACT,CAwCO,SAAS,EAAe,CAAE,CAAE,CAAC,CAAE,CAAC,EACrC,EAAG,KAAK,CAAC,KAAK,CAAG,AAAc,UAAd,OAAQ,EAAkB,CAAA,EAAG,EAAE,EAAE,CAAC,CAAG,EACtD,EAAG,KAAK,CAAC,MAAM,CAAG,AAAc,UAAd,OAAQ,EAAkB,CAAA,EAAG,EAAE,EAAE,CAAC,CAAG,CACzD,C,E,E,O,C,gB,I,G,E,E,O,C,oB,I,G,E,E,O,C,iB,I,G,E,E,O,C,a,I,G,E,E,O,C,iB,I,G,E,E,O,C,wB,I,G,E,E,O,C,c,I,G,E,E,O,C,W,I,GA8BO,IAAM,EAAa,CACxB,KAAM,OACN,QAAS,UACT,OAAQ,SACR,MAAO,OACT,EAUO,SAAS,EAAe,CAAC,EAC9B,MAAQ,WAAY,GAAK,AAAa,IAAb,EAAE,MAAM,EAAW,EAAE,OAAO,EAAI,EAAE,OAAO,EAAI,EAAE,MAAM,E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","sources":["","node_modules/photoswipe/src/js/lightbox/lightbox.js","node_modules/photoswipe/src/js/util/util.js","node_modules/photoswipe/src/js/core/base.js","node_modules/photoswipe/src/js/core/eventable.js","node_modules/photoswipe/src/js/slide/content.js","node_modules/photoswipe/src/js/slide/placeholder.js","node_modules/photoswipe/src/js/slide/loader.js","node_modules/photoswipe/src/js/util/viewport-size.js","node_modules/photoswipe/src/js/slide/zoom-level.js"],"sourcesContent":["\nfunction $parcel$export(e, n, v, s) {\n Object.defineProperty(e, n, {get: v, set: s, enumerable: true, configurable: true});\n}\n\n var $parcel$global = globalThis;\n \nvar $parcel$modules = {};\nvar $parcel$inits = {};\n\nvar parcelRequire = $parcel$global[\"parcelRequire94c2\"];\n\nif (parcelRequire == null) {\n parcelRequire = function(id) {\n if (id in $parcel$modules) {\n return $parcel$modules[id].exports;\n }\n if (id in $parcel$inits) {\n var init = $parcel$inits[id];\n delete $parcel$inits[id];\n var module = {id: id, exports: {}};\n $parcel$modules[id] = module;\n init.call(module.exports, module, module.exports);\n return module.exports;\n }\n var err = new Error(\"Cannot find module '\" + id + \"'\");\n err.code = 'MODULE_NOT_FOUND';\n throw err;\n };\n\n parcelRequire.register = function register(id, init) {\n $parcel$inits[id] = init;\n };\n\n $parcel$global[\"parcelRequire94c2\"] = parcelRequire;\n}\n\nvar parcelRegister = parcelRequire.register;\nparcelRegister(\"4ex3T\", function(module, exports) {\n\nvar $lQUwv = parcelRequire(\"lQUwv\");\n\nvar $9pQ3o = parcelRequire(\"9pQ3o\");\n\nvar $ho1E2 = parcelRequire(\"ho1E2\");\n/**\r\n * @template T\r\n * @typedef {import('../types.js').Type} Type\r\n */ /** @typedef {import('../photoswipe.js').default} PhotoSwipe */ /** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */ /** @typedef {import('../photoswipe.js').DataSource} DataSource */ /** @typedef {import('../photoswipe.js').Point} Point */ /** @typedef {import('../slide/content.js').default} Content */ /** @typedef {import('../core/eventable.js').PhotoSwipeEventsMap} PhotoSwipeEventsMap */ /** @typedef {import('../core/eventable.js').PhotoSwipeFiltersMap} PhotoSwipeFiltersMap */ /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('../core/eventable.js').EventCallback} EventCallback\r\n */ /**\r\n * PhotoSwipe Lightbox\r\n *\r\n * - If user has unsupported browser it falls back to default browser action (just opens URL)\r\n * - Binds click event to links that should open PhotoSwipe\r\n * - parses DOM strcture for PhotoSwipe (retrieves large image URLs and sizes)\r\n * - Initializes PhotoSwipe\r\n *\r\n *\r\n * Loader options use the same object as PhotoSwipe, and supports such options:\r\n *\r\n * gallery - Element | Element[] | NodeList | string selector for the gallery element\r\n * children - Element | Element[] | NodeList | string selector for the gallery children\r\n *\r\n */ class $31521d9cfdbe0299$var$PhotoSwipeLightbox extends (0, $9pQ3o.default) {\n /**\r\n * @param {PhotoSwipeOptions} [options]\r\n */ constructor(options){\n super();\n /** @type {PhotoSwipeOptions} */ this.options = options || {};\n this._uid = 0;\n this.shouldOpen = false;\n /**\r\n * @private\r\n * @type {Content | undefined}\r\n */ this._preloadedContent = undefined;\n this.onThumbnailsClick = this.onThumbnailsClick.bind(this);\n }\n /**\r\n * Initialize lightbox, should be called only once.\r\n * It's not included in the main constructor, so you may bind events before it.\r\n */ init() {\n // Bind click events to each gallery\n (0, $lQUwv.getElementsFromOption)(this.options.gallery, this.options.gallerySelector).forEach((galleryElement)=>{\n galleryElement.addEventListener('click', this.onThumbnailsClick, false);\n });\n }\n /**\r\n * @param {MouseEvent} e\r\n */ onThumbnailsClick(e) {\n // Exit and allow default browser action if:\n if ((0, $lQUwv.specialKeyUsed)(e) // ... if clicked with a special key (ctrl/cmd...)\n || window.pswp) return;\n // If both clientX and clientY are 0 or not defined,\n // the event is likely triggered by keyboard,\n // so we do not pass the initialPoint\n //\n // Note that some screen readers emulate the mouse position,\n // so it's not the ideal way to detect them.\n //\n /** @type {Point | null} */ let initialPoint = {\n x: e.clientX,\n y: e.clientY\n };\n if (!initialPoint.x && !initialPoint.y) initialPoint = null;\n let clickedIndex = this.getClickedIndex(e);\n clickedIndex = this.applyFilters('clickedIndex', clickedIndex, e, this);\n /** @type {DataSource} */ const dataSource = {\n gallery: /** @type {HTMLElement} */ e.currentTarget\n };\n if (clickedIndex >= 0) {\n e.preventDefault();\n this.loadAndOpen(clickedIndex, dataSource, initialPoint);\n }\n }\n /**\r\n * Get index of gallery item that was clicked.\r\n *\r\n * @param {MouseEvent} e click event\r\n * @returns {number}\r\n */ getClickedIndex(e) {\n // legacy option\n if (this.options.getClickedIndexFn) return this.options.getClickedIndexFn.call(this, e);\n const clickedTarget = /** @type {HTMLElement} */ e.target;\n const childElements = (0, $lQUwv.getElementsFromOption)(this.options.children, this.options.childSelector, /** @type {HTMLElement} */ e.currentTarget);\n const clickedChildIndex = childElements.findIndex((child)=>child === clickedTarget || child.contains(clickedTarget));\n if (clickedChildIndex !== -1) return clickedChildIndex;\n else if (this.options.children || this.options.childSelector) // click wasn't on a child element\n return -1;\n // There is only one item (which is the gallery)\n return 0;\n }\n /**\r\n * Load and open PhotoSwipe\r\n *\r\n * @param {number} index\r\n * @param {DataSource} [dataSource]\r\n * @param {Point | null} [initialPoint]\r\n * @returns {boolean}\r\n */ loadAndOpen(index, dataSource, initialPoint) {\n // Check if the gallery is already open\n if (window.pswp || !this.options) return false;\n // Use the first gallery element if dataSource is not provided\n if (!dataSource && this.options.gallery && this.options.children) {\n const galleryElements = (0, $lQUwv.getElementsFromOption)(this.options.gallery);\n if (galleryElements[0]) dataSource = {\n gallery: galleryElements[0]\n };\n }\n // set initial index\n this.options.index = index;\n // define options for PhotoSwipe constructor\n this.options.initialPointerPos = initialPoint;\n this.shouldOpen = true;\n this.preload(index, dataSource);\n return true;\n }\n /**\r\n * Load the main module and the slide content by index\r\n *\r\n * @param {number} index\r\n * @param {DataSource} [dataSource]\r\n */ preload(index, dataSource) {\n const { options: options } = this;\n if (dataSource) options.dataSource = dataSource;\n // Add the main module\n /** @type {Promise>[]} */ const promiseArray = [];\n const pswpModuleType = typeof options.pswpModule;\n if ((0, $lQUwv.isPswpClass)(options.pswpModule)) promiseArray.push(Promise.resolve(/** @type {Type} */ options.pswpModule));\n else if (pswpModuleType === 'string') throw new Error('pswpModule as string is no longer supported');\n else if (pswpModuleType === 'function') promiseArray.push(/** @type {() => Promise>} */ options.pswpModule());\n else throw new Error('pswpModule is not valid');\n // Add custom-defined promise, if any\n if (typeof options.openPromise === 'function') // allow developers to perform some task before opening\n promiseArray.push(options.openPromise());\n if (options.preloadFirstSlide !== false && index >= 0) this._preloadedContent = (0, $ho1E2.lazyLoadSlide)(index, this);\n // Wait till all promises resolve and open PhotoSwipe\n const uid = ++this._uid;\n Promise.all(promiseArray).then((iterableModules)=>{\n if (this.shouldOpen) {\n const mainModule = iterableModules[0];\n this._openPhotoswipe(mainModule, uid);\n }\n });\n }\n /**\r\n * @private\r\n * @param {Type | { default: Type }} module\r\n * @param {number} uid\r\n */ _openPhotoswipe(module, uid) {\n // Cancel opening if UID doesn't match the current one\n // (if user clicked on another gallery item before current was loaded).\n //\n // Or if shouldOpen flag is set to false\n // (developer may modify it via public API)\n if (uid !== this._uid && this.shouldOpen) return;\n this.shouldOpen = false;\n // PhotoSwipe is already open\n if (window.pswp) return;\n /**\r\n * Pass data to PhotoSwipe and open init\r\n *\r\n * @type {PhotoSwipe}\r\n */ const pswp = typeof module === 'object' ? new module.default(this.options) // eslint-disable-line\n : new module(this.options); // eslint-disable-line\n this.pswp = pswp;\n window.pswp = pswp;\n // map listeners from Lightbox to PhotoSwipe Core\n /** @type {(keyof PhotoSwipeEventsMap)[]} */ Object.keys(this._listeners).forEach((name)=>{\n this._listeners[name]?.forEach((fn)=>{\n pswp.on(name, /** @type {EventCallback} */ fn);\n });\n });\n // same with filters\n /** @type {(keyof PhotoSwipeFiltersMap)[]} */ Object.keys(this._filters).forEach((name)=>{\n this._filters[name]?.forEach((filter)=>{\n pswp.addFilter(name, filter.fn, filter.priority);\n });\n });\n if (this._preloadedContent) {\n pswp.contentLoader.addToCache(this._preloadedContent);\n this._preloadedContent = undefined;\n }\n pswp.on('destroy', ()=>{\n // clean up public variables\n this.pswp = undefined;\n delete window.pswp;\n });\n pswp.init();\n }\n /**\r\n * Unbinds all events, closes PhotoSwipe if it's open.\r\n */ destroy() {\n this.pswp?.destroy();\n this.shouldOpen = false;\n this._listeners = {};\n (0, $lQUwv.getElementsFromOption)(this.options.gallery, this.options.gallerySelector).forEach((galleryElement)=>{\n galleryElement.removeEventListener('click', this.onThumbnailsClick, false);\n });\n }\n}\nvar $31521d9cfdbe0299$export$2e2bcd8739ae039 = $31521d9cfdbe0299$var$PhotoSwipeLightbox;\n\n});\nparcelRegister(\"lQUwv\", function(module, exports) {\n\n$parcel$export(module.exports, \"createElement\", () => $fe8a4ca7935abc37$export$c8a8987d4410bf2d);\n$parcel$export(module.exports, \"toTransformString\", () => $fe8a4ca7935abc37$export$9ebaeae2c52fdc4c);\n$parcel$export(module.exports, \"setWidthHeight\", () => $fe8a4ca7935abc37$export$9fc2289bf66bbc6a);\n$parcel$export(module.exports, \"LOAD_STATE\", () => $fe8a4ca7935abc37$export$c303146534fe0490);\n$parcel$export(module.exports, \"specialKeyUsed\", () => $fe8a4ca7935abc37$export$44619521c4b78f15);\n$parcel$export(module.exports, \"getElementsFromOption\", () => $fe8a4ca7935abc37$export$f900bd3a95fb7e3c);\n$parcel$export(module.exports, \"isPswpClass\", () => $fe8a4ca7935abc37$export$c923a85b9c2e680f);\n$parcel$export(module.exports, \"isSafari\", () => $fe8a4ca7935abc37$export$95df08bae54cb4df);\n/** @typedef {import('../photoswipe.js').Point} Point */ /**\r\n * @template {keyof HTMLElementTagNameMap} T\r\n * @param {string} className\r\n * @param {T} tagName\r\n * @param {Node} [appendToEl]\r\n * @returns {HTMLElementTagNameMap[T]}\r\n */ function $fe8a4ca7935abc37$export$c8a8987d4410bf2d(className, tagName, appendToEl) {\n const el = document.createElement(tagName);\n if (className) el.className = className;\n if (appendToEl) appendToEl.appendChild(el);\n return el;\n}\nfunction $fe8a4ca7935abc37$export$ec1930202b830a12(p1, p2) {\n p1.x = p2.x;\n p1.y = p2.y;\n if (p2.id !== undefined) p1.id = p2.id;\n return p1;\n}\nfunction $fe8a4ca7935abc37$export$36ff03cec7ce5ec3(p) {\n p.x = Math.round(p.x);\n p.y = Math.round(p.y);\n}\nfunction $fe8a4ca7935abc37$export$2ca3ac4428d5aa9c(p1, p2) {\n const x = Math.abs(p1.x - p2.x);\n const y = Math.abs(p1.y - p2.y);\n return Math.sqrt(x * x + y * y);\n}\nfunction $fe8a4ca7935abc37$export$6004e301464e23f7(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\nfunction $fe8a4ca7935abc37$export$7d15b64cf5a3a4c4(val, min, max) {\n return Math.min(Math.max(val, min), max);\n}\nfunction $fe8a4ca7935abc37$export$9ebaeae2c52fdc4c(x, y, scale) {\n let propValue = `translate3d(${x}px,${y || 0}px,0)`;\n if (scale !== undefined) propValue += ` scale3d(${scale},${scale},1)`;\n return propValue;\n}\nfunction $fe8a4ca7935abc37$export$ff09356c35bee89b(el, x, y, scale) {\n el.style.transform = $fe8a4ca7935abc37$export$9ebaeae2c52fdc4c(x, y, scale);\n}\nconst $fe8a4ca7935abc37$var$defaultCSSEasing = 'cubic-bezier(.4,0,.22,1)';\nfunction $fe8a4ca7935abc37$export$d8f62f1ab6a7a545(el, prop, duration, ease) {\n // inOut: 'cubic-bezier(.4, 0, .22, 1)', // for \"toggle state\" transitions\n // out: 'cubic-bezier(0, 0, .22, 1)', // for \"show\" transitions\n // in: 'cubic-bezier(.4, 0, 1, 1)'// for \"hide\" transitions\n el.style.transition = prop ? `${prop} ${duration}ms ${ease || $fe8a4ca7935abc37$var$defaultCSSEasing}` : 'none';\n}\nfunction $fe8a4ca7935abc37$export$9fc2289bf66bbc6a(el, w, h) {\n el.style.width = typeof w === 'number' ? `${w}px` : w;\n el.style.height = typeof h === 'number' ? `${h}px` : h;\n}\nfunction $fe8a4ca7935abc37$export$478ace17dcc2023c(el) {\n $fe8a4ca7935abc37$export$d8f62f1ab6a7a545(el);\n}\nfunction $fe8a4ca7935abc37$export$442483c9a651cd8d(img) {\n if ('decode' in img) return img.decode().catch(()=>{});\n if (img.complete) return Promise.resolve(img);\n return new Promise((resolve, reject)=>{\n img.onload = ()=>resolve(img);\n img.onerror = reject;\n });\n}\nconst $fe8a4ca7935abc37$export$c303146534fe0490 = {\n IDLE: 'idle',\n LOADING: 'loading',\n LOADED: 'loaded',\n ERROR: 'error'\n};\nfunction $fe8a4ca7935abc37$export$44619521c4b78f15(e) {\n return 'button' in e && e.button === 1 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey;\n}\nfunction $fe8a4ca7935abc37$export$f900bd3a95fb7e3c(option, legacySelector, parent = document) {\n /** @type {HTMLElement[]} */ let elements = [];\n if (option instanceof Element) elements = [\n option\n ];\n else if (option instanceof NodeList || Array.isArray(option)) elements = Array.from(option);\n else {\n const selector = typeof option === 'string' ? option : legacySelector;\n if (selector) elements = Array.from(parent.querySelectorAll(selector));\n }\n return elements;\n}\nfunction $fe8a4ca7935abc37$export$c923a85b9c2e680f(fn) {\n return typeof fn === 'function' && fn.prototype && fn.prototype.goTo;\n}\nfunction $fe8a4ca7935abc37$export$95df08bae54cb4df() {\n return !!(navigator.vendor && navigator.vendor.match(/apple/i));\n}\n\n});\n\nparcelRegister(\"9pQ3o\", function(module, exports) {\n\n$parcel$export(module.exports, \"default\", () => $6daed3a2f8f8bac9$export$2e2bcd8739ae039);\n\nvar $k2V0X = parcelRequire(\"k2V0X\");\n\nvar $lQUwv = parcelRequire(\"lQUwv\");\n\nvar $gGYae = parcelRequire(\"gGYae\");\n\nvar $ho1E2 = parcelRequire(\"ho1E2\");\n/** @typedef {import(\"../photoswipe.js\").default} PhotoSwipe */ /** @typedef {import(\"../slide/slide.js\").SlideData} SlideData */ /**\r\n * PhotoSwipe base class that can retrieve data about every slide.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox\r\n */ class $6daed3a2f8f8bac9$var$PhotoSwipeBase extends (0, $k2V0X.default) {\n /**\r\n * Get total number of slides\r\n *\r\n * @returns {number}\r\n */ getNumItems() {\n let numItems = 0;\n const dataSource = this.options?.dataSource;\n if (dataSource && 'length' in dataSource) // may be an array or just object with length property\n numItems = dataSource.length;\n else if (dataSource && 'gallery' in dataSource) {\n // query DOM elements\n if (!dataSource.items) dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\n if (dataSource.items) numItems = dataSource.items.length;\n }\n // legacy event, before filters were introduced\n const event = this.dispatch('numItems', {\n dataSource: dataSource,\n numItems: numItems\n });\n return this.applyFilters('numItems', event.numItems, dataSource);\n }\n /**\r\n * @param {SlideData} slideData\r\n * @param {number} index\r\n * @returns {Content}\r\n */ createContentFromData(slideData, index) {\n return new (0, $gGYae.default)(slideData, this, index);\n }\n /**\r\n * Get item data by index.\r\n *\r\n * \"item data\" should contain normalized information that PhotoSwipe needs to generate a slide.\r\n * For example, it may contain properties like\r\n * `src`, `srcset`, `w`, `h`, which will be used to generate a slide with image.\r\n *\r\n * @param {number} index\r\n * @returns {SlideData}\r\n */ getItemData(index) {\n const dataSource = this.options?.dataSource;\n /** @type {SlideData | HTMLElement} */ let dataSourceItem = {};\n if (Array.isArray(dataSource)) // Datasource is an array of elements\n dataSourceItem = dataSource[index];\n else if (dataSource && 'gallery' in dataSource) {\n // dataSource has gallery property,\n // thus it was created by Lightbox, based on\n // gallery and children options\n // query DOM elements\n if (!dataSource.items) dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\n dataSourceItem = dataSource.items[index];\n }\n let itemData = dataSourceItem;\n if (itemData instanceof Element) itemData = this._domElementToItemData(itemData);\n // Dispatching the itemData event,\n // it's a legacy verion before filters were introduced\n const event = this.dispatch('itemData', {\n itemData: itemData || {},\n index: index\n });\n return this.applyFilters('itemData', event.itemData, index);\n }\n /**\r\n * Get array of gallery DOM elements,\r\n * based on childSelector and gallery element.\r\n *\r\n * @param {HTMLElement} galleryElement\r\n * @returns {HTMLElement[]}\r\n */ _getGalleryDOMElements(galleryElement) {\n if (this.options?.children || this.options?.childSelector) return (0, $lQUwv.getElementsFromOption)(this.options.children, this.options.childSelector, galleryElement) || [];\n return [\n galleryElement\n ];\n }\n /**\r\n * Converts DOM element to item data object.\r\n *\r\n * @param {HTMLElement} element DOM element\r\n * @returns {SlideData}\r\n */ _domElementToItemData(element) {\n /** @type {SlideData} */ const itemData = {\n element: element\n };\n const linkEl = /** @type {HTMLAnchorElement} */ element.tagName === 'A' ? element : element.querySelector('a');\n if (linkEl) {\n // src comes from data-pswp-src attribute,\n // if it's empty link href is used\n itemData.src = linkEl.dataset.pswpSrc || linkEl.href;\n if (linkEl.dataset.pswpSrcset) itemData.srcset = linkEl.dataset.pswpSrcset;\n itemData.width = linkEl.dataset.pswpWidth ? parseInt(linkEl.dataset.pswpWidth, 10) : 0;\n itemData.height = linkEl.dataset.pswpHeight ? parseInt(linkEl.dataset.pswpHeight, 10) : 0;\n // support legacy w & h properties\n itemData.w = itemData.width;\n itemData.h = itemData.height;\n if (linkEl.dataset.pswpType) itemData.type = linkEl.dataset.pswpType;\n const thumbnailEl = element.querySelector('img');\n if (thumbnailEl) {\n // msrc is URL to placeholder image that's displayed before large image is loaded\n // by default it's displayed only for the first slide\n itemData.msrc = thumbnailEl.currentSrc || thumbnailEl.src;\n itemData.alt = thumbnailEl.getAttribute('alt') ?? '';\n }\n if (linkEl.dataset.pswpCropped || linkEl.dataset.cropped) itemData.thumbCropped = true;\n }\n return this.applyFilters('domItemData', itemData, element, linkEl);\n }\n /**\r\n * Lazy-load by slide data\r\n *\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {number} index\r\n * @returns {Content} Image that is being decoded or false.\r\n */ lazyLoadData(itemData, index) {\n return (0, $ho1E2.lazyLoadData)(itemData, this, index);\n }\n}\nvar $6daed3a2f8f8bac9$export$2e2bcd8739ae039 = $6daed3a2f8f8bac9$var$PhotoSwipeBase;\n\n});\nparcelRegister(\"k2V0X\", function(module, exports) {\n\n$parcel$export(module.exports, \"default\", () => $e980386d0a2b9ae1$export$2e2bcd8739ae039);\n/** @typedef {import('../lightbox/lightbox.js').default} PhotoSwipeLightbox */ /** @typedef {import('../photoswipe.js').default} PhotoSwipe */ /** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */ /** @typedef {import('../photoswipe.js').DataSource} DataSource */ /** @typedef {import('../ui/ui-element.js').UIElementData} UIElementData */ /** @typedef {import('../slide/content.js').default} ContentDefault */ /** @typedef {import('../slide/slide.js').default} Slide */ /** @typedef {import('../slide/slide.js').SlideData} SlideData */ /** @typedef {import('../slide/zoom-level.js').default} ZoomLevel */ /** @typedef {import('../slide/get-thumb-bounds.js').Bounds} Bounds */ /**\r\n * Allow adding an arbitrary props to the Content\r\n * https://photoswipe.com/custom-content/#using-webp-image-format\r\n * @typedef {ContentDefault & Record} Content\r\n */ /** @typedef {{ x?: number; y?: number }} Point */ /**\r\n * @typedef {Object} PhotoSwipeEventsMap https://photoswipe.com/events/\r\n *\r\n *\r\n * https://photoswipe.com/adding-ui-elements/\r\n *\r\n * @prop {undefined} uiRegister\r\n * @prop {{ data: UIElementData }} uiElementCreate\r\n *\r\n *\r\n * https://photoswipe.com/events/#initialization-events\r\n *\r\n * @prop {undefined} beforeOpen\r\n * @prop {undefined} firstUpdate\r\n * @prop {undefined} initialLayout\r\n * @prop {undefined} change\r\n * @prop {undefined} afterInit\r\n * @prop {undefined} bindEvents\r\n *\r\n *\r\n * https://photoswipe.com/events/#opening-or-closing-transition-events\r\n *\r\n * @prop {undefined} openingAnimationStart\r\n * @prop {undefined} openingAnimationEnd\r\n * @prop {undefined} closingAnimationStart\r\n * @prop {undefined} closingAnimationEnd\r\n *\r\n *\r\n * https://photoswipe.com/events/#closing-events\r\n *\r\n * @prop {undefined} close\r\n * @prop {undefined} destroy\r\n *\r\n *\r\n * https://photoswipe.com/events/#pointer-and-gesture-events\r\n *\r\n * @prop {{ originalEvent: PointerEvent }} pointerDown\r\n * @prop {{ originalEvent: PointerEvent }} pointerMove\r\n * @prop {{ originalEvent: PointerEvent }} pointerUp\r\n * @prop {{ bgOpacity: number }} pinchClose can be default prevented\r\n * @prop {{ panY: number }} verticalDrag can be default prevented\r\n *\r\n *\r\n * https://photoswipe.com/events/#slide-content-events\r\n *\r\n * @prop {{ content: Content }} contentInit\r\n * @prop {{ content: Content; isLazy: boolean }} contentLoad can be default prevented\r\n * @prop {{ content: Content; isLazy: boolean }} contentLoadImage can be default prevented\r\n * @prop {{ content: Content; slide: Slide; isError?: boolean }} loadComplete\r\n * @prop {{ content: Content; slide: Slide }} loadError\r\n * @prop {{ content: Content; width: number; height: number }} contentResize can be default prevented\r\n * @prop {{ content: Content; width: number; height: number; slide: Slide }} imageSizeChange\r\n * @prop {{ content: Content }} contentLazyLoad can be default prevented\r\n * @prop {{ content: Content }} contentAppend can be default prevented\r\n * @prop {{ content: Content }} contentActivate can be default prevented\r\n * @prop {{ content: Content }} contentDeactivate can be default prevented\r\n * @prop {{ content: Content }} contentRemove can be default prevented\r\n * @prop {{ content: Content }} contentDestroy can be default prevented\r\n *\r\n *\r\n * undocumented\r\n *\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} imageClickAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} bgClickAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} tapAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} doubleTapAction can be default prevented\r\n *\r\n * @prop {{ originalEvent: KeyboardEvent }} keydown can be default prevented\r\n * @prop {{ x: number; dragging: boolean }} moveMainScroll\r\n * @prop {{ slide: Slide }} firstZoomPan\r\n * @prop {{ slide: Slide | undefined, data: SlideData, index: number }} gettingData\r\n * @prop {undefined} beforeResize\r\n * @prop {undefined} resize\r\n * @prop {undefined} viewportSize\r\n * @prop {undefined} updateScrollOffset\r\n * @prop {{ slide: Slide }} slideInit\r\n * @prop {{ slide: Slide }} afterSetContent\r\n * @prop {{ slide: Slide }} slideLoad\r\n * @prop {{ slide: Slide }} appendHeavy can be default prevented\r\n * @prop {{ slide: Slide }} appendHeavyContent\r\n * @prop {{ slide: Slide }} slideActivate\r\n * @prop {{ slide: Slide }} slideDeactivate\r\n * @prop {{ slide: Slide }} slideDestroy\r\n * @prop {{ destZoomLevel: number, centerPoint: Point | undefined, transitionDuration: number | false | undefined }} beforeZoomTo\r\n * @prop {{ slide: Slide }} zoomPanUpdate\r\n * @prop {{ slide: Slide }} initialZoomPan\r\n * @prop {{ slide: Slide }} calcSlideSize\r\n * @prop {undefined} resolutionChanged\r\n * @prop {{ originalEvent: WheelEvent }} wheel can be default prevented\r\n * @prop {{ content: Content }} contentAppendImage can be default prevented\r\n * @prop {{ index: number; itemData: SlideData }} lazyLoadSlide can be default prevented\r\n * @prop {undefined} lazyLoad\r\n * @prop {{ slide: Slide }} calcBounds\r\n * @prop {{ zoomLevels: ZoomLevel, slideData: SlideData }} zoomLevelsUpdate\r\n *\r\n *\r\n * legacy\r\n *\r\n * @prop {undefined} init\r\n * @prop {undefined} initialZoomIn\r\n * @prop {undefined} initialZoomOut\r\n * @prop {undefined} initialZoomInEnd\r\n * @prop {undefined} initialZoomOutEnd\r\n * @prop {{ dataSource: DataSource | undefined, numItems: number }} numItems\r\n * @prop {{ itemData: SlideData; index: number }} itemData\r\n * @prop {{ index: number, itemData: SlideData, instance: PhotoSwipe }} thumbBounds\r\n */ /**\r\n * @typedef {Object} PhotoSwipeFiltersMap https://photoswipe.com/filters/\r\n *\r\n * @prop {(numItems: number, dataSource: DataSource | undefined) => number} numItems\r\n * Modify the total amount of slides. Example on Data sources page.\r\n * https://photoswipe.com/filters/#numitems\r\n *\r\n * @prop {(itemData: SlideData, index: number) => SlideData} itemData\r\n * Modify slide item data. Example on Data sources page.\r\n * https://photoswipe.com/filters/#itemdata\r\n *\r\n * @prop {(itemData: SlideData, element: HTMLElement, linkEl: HTMLAnchorElement) => SlideData} domItemData\r\n * Modify item data when it's parsed from DOM element. Example on Data sources page.\r\n * https://photoswipe.com/filters/#domitemdata\r\n *\r\n * @prop {(clickedIndex: number, e: MouseEvent, instance: PhotoSwipeLightbox) => number} clickedIndex\r\n * Modify clicked gallery item index.\r\n * https://photoswipe.com/filters/#clickedindex\r\n *\r\n * @prop {(placeholderSrc: string | false, content: Content) => string | false} placeholderSrc\r\n * Modify placeholder image source.\r\n * https://photoswipe.com/filters/#placeholdersrc\r\n *\r\n * @prop {(isContentLoading: boolean, content: Content) => boolean} isContentLoading\r\n * Modify if the content is currently loading.\r\n * https://photoswipe.com/filters/#iscontentloading\r\n *\r\n * @prop {(isContentZoomable: boolean, content: Content) => boolean} isContentZoomable\r\n * Modify if the content can be zoomed.\r\n * https://photoswipe.com/filters/#iscontentzoomable\r\n *\r\n * @prop {(useContentPlaceholder: boolean, content: Content) => boolean} useContentPlaceholder\r\n * Modify if the placeholder should be used for the content.\r\n * https://photoswipe.com/filters/#usecontentplaceholder\r\n *\r\n * @prop {(isKeepingPlaceholder: boolean, content: Content) => boolean} isKeepingPlaceholder\r\n * Modify if the placeholder should be kept after the content is loaded.\r\n * https://photoswipe.com/filters/#iskeepingplaceholder\r\n *\r\n *\r\n * @prop {(contentErrorElement: HTMLElement, content: Content) => HTMLElement} contentErrorElement\r\n * Modify an element when the content has error state (for example, if image cannot be loaded).\r\n * https://photoswipe.com/filters/#contenterrorelement\r\n *\r\n * @prop {(element: HTMLElement, data: UIElementData) => HTMLElement} uiElement\r\n * Modify a UI element that's being created.\r\n * https://photoswipe.com/filters/#uielement\r\n *\r\n * @prop {(thumbnail: HTMLElement | null | undefined, itemData: SlideData, index: number) => HTMLElement} thumbEl\r\n * Modify the thumbnail element from which opening zoom animation starts or ends.\r\n * https://photoswipe.com/filters/#thumbel\r\n *\r\n * @prop {(thumbBounds: Bounds | undefined, itemData: SlideData, index: number) => Bounds} thumbBounds\r\n * Modify the thumbnail bounds from which opening zoom animation starts or ends.\r\n * https://photoswipe.com/filters/#thumbbounds\r\n *\r\n * @prop {(srcsetSizesWidth: number, content: Content) => number} srcsetSizesWidth\r\n *\r\n * @prop {(preventPointerEvent: boolean, event: PointerEvent, pointerType: string) => boolean} preventPointerEvent\r\n *\r\n */ /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @typedef {{ fn: PhotoSwipeFiltersMap[T], priority: number }} Filter\r\n */ /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {PhotoSwipeEventsMap[T] extends undefined ? PhotoSwipeEvent : PhotoSwipeEvent & PhotoSwipeEventsMap[T]} AugmentedEvent\r\n */ /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {(event: AugmentedEvent) => void} EventCallback\r\n */ /**\r\n * Base PhotoSwipe event object\r\n *\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n */ class $e980386d0a2b9ae1$var$PhotoSwipeEvent {\n /**\r\n * @param {T} type\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n */ constructor(type, details){\n this.type = type;\n this.defaultPrevented = false;\n if (details) Object.assign(this, details);\n }\n preventDefault() {\n this.defaultPrevented = true;\n }\n}\n/**\r\n * PhotoSwipe base class that can listen and dispatch for events.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox, extended by base.js\r\n */ class $e980386d0a2b9ae1$var$Eventable {\n constructor(){\n /**\r\n * @type {{ [T in keyof PhotoSwipeEventsMap]?: ((event: AugmentedEvent) => void)[] }}\r\n */ this._listeners = {};\n /**\r\n * @type {{ [T in keyof PhotoSwipeFiltersMap]?: Filter[] }}\r\n */ this._filters = {};\n /** @type {PhotoSwipe | undefined} */ this.pswp = undefined;\n /** @type {PhotoSwipeOptions | undefined} */ this.options = undefined;\n }\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeFiltersMap[T]} fn\r\n * @param {number} priority\r\n */ addFilter(name, fn, priority = 100) {\n if (!this._filters[name]) this._filters[name] = [];\n this._filters[name]?.push({\n fn: fn,\n priority: priority\n });\n this._filters[name]?.sort((f1, f2)=>f1.priority - f2.priority);\n this.pswp?.addFilter(name, fn, priority);\n }\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeFiltersMap[T]} fn\r\n */ removeFilter(name, fn) {\n if (this._filters[name]) // @ts-expect-error\n this._filters[name] = this._filters[name].filter((filter)=>filter.fn !== fn);\n if (this.pswp) this.pswp.removeFilter(name, fn);\n }\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {Parameters} args\r\n * @returns {Parameters[0]}\r\n */ applyFilters(name, ...args) {\n this._filters[name]?.forEach((filter)=>{\n // @ts-expect-error\n args[0] = filter.fn.apply(this, args);\n });\n return args[0];\n }\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */ on(name, fn) {\n if (!this._listeners[name]) this._listeners[name] = [];\n this._listeners[name]?.push(fn);\n // When binding events to lightbox,\n // also bind events to PhotoSwipe Core,\n // if it's open.\n this.pswp?.on(name, fn);\n }\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */ off(name, fn) {\n if (this._listeners[name]) // @ts-expect-error\n this._listeners[name] = this._listeners[name].filter((listener)=>fn !== listener);\n this.pswp?.off(name, fn);\n }\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n * @returns {AugmentedEvent}\r\n */ dispatch(name, details) {\n if (this.pswp) return this.pswp.dispatch(name, details);\n const event = /** @type {AugmentedEvent} */ new $e980386d0a2b9ae1$var$PhotoSwipeEvent(name, details);\n this._listeners[name]?.forEach((listener)=>{\n listener.call(this, event);\n });\n return event;\n }\n}\nvar $e980386d0a2b9ae1$export$2e2bcd8739ae039 = $e980386d0a2b9ae1$var$Eventable;\n\n});\n\nparcelRegister(\"gGYae\", function(module, exports) {\n\n$parcel$export(module.exports, \"default\", () => $c26f3ce87e26857c$export$2e2bcd8739ae039);\n\nvar $lQUwv = parcelRequire(\"lQUwv\");\n\nvar $9ZhPn = parcelRequire(\"9ZhPn\");\n/** @typedef {import('./slide.js').default} Slide */ /** @typedef {import('./slide.js').SlideData} SlideData */ /** @typedef {import('../core/base.js').default} PhotoSwipeBase */ /** @typedef {import('../util/util.js').LoadState} LoadState */ class $c26f3ce87e26857c$var$Content {\n /**\r\n * @param {SlideData} itemData Slide data\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox instance\r\n * @param {number} index\r\n */ constructor(itemData, instance, index){\n this.instance = instance;\n this.data = itemData;\n this.index = index;\n /** @type {HTMLImageElement | HTMLDivElement | undefined} */ this.element = undefined;\n /** @type {Placeholder | undefined} */ this.placeholder = undefined;\n /** @type {Slide | undefined} */ this.slide = undefined;\n this.displayedImageWidth = 0;\n this.displayedImageHeight = 0;\n this.width = Number(this.data.w) || Number(this.data.width) || 0;\n this.height = Number(this.data.h) || Number(this.data.height) || 0;\n this.isAttached = false;\n this.hasSlide = false;\n this.isDecoding = false;\n /** @type {LoadState} */ this.state = (0, $lQUwv.LOAD_STATE).IDLE;\n if (this.data.type) this.type = this.data.type;\n else if (this.data.src) this.type = 'image';\n else this.type = 'html';\n this.instance.dispatch('contentInit', {\n content: this\n });\n }\n removePlaceholder() {\n if (this.placeholder && !this.keepPlaceholder()) // With delay, as image might be loaded, but not rendered\n setTimeout(()=>{\n if (this.placeholder) {\n this.placeholder.destroy();\n this.placeholder = undefined;\n }\n }, 1000);\n }\n /**\r\n * Preload content\r\n *\r\n * @param {boolean} isLazy\r\n * @param {boolean} [reload]\r\n */ load(isLazy, reload) {\n if (this.slide && this.usePlaceholder()) {\n if (!this.placeholder) {\n const placeholderSrc = this.instance.applyFilters('placeholderSrc', // use image-based placeholder only for the first slide,\n // as rendering (even small stretched thumbnail) is an expensive operation\n this.data.msrc && this.slide.isFirstSlide ? this.data.msrc : false, this);\n this.placeholder = new (0, $9ZhPn.default)(placeholderSrc, this.slide.container);\n } else {\n const placeholderEl = this.placeholder.element;\n // Add placeholder to DOM if it was already created\n if (placeholderEl && !placeholderEl.parentElement) this.slide.container.prepend(placeholderEl);\n }\n }\n if (this.element && !reload) return;\n if (this.instance.dispatch('contentLoad', {\n content: this,\n isLazy: isLazy\n }).defaultPrevented) return;\n if (this.isImageContent()) {\n this.element = (0, $lQUwv.createElement)('pswp__img', 'img');\n // Start loading only after width is defined, as sizes might depend on it.\n // Due to Safari feature, we must define sizes before srcset.\n if (this.displayedImageWidth) this.loadImage(isLazy);\n } else {\n this.element = (0, $lQUwv.createElement)('pswp__content', 'div');\n this.element.innerHTML = this.data.html || '';\n }\n if (reload && this.slide) this.slide.updateContentSize(true);\n }\n /**\r\n * Preload image\r\n *\r\n * @param {boolean} isLazy\r\n */ loadImage(isLazy) {\n if (!this.isImageContent() || !this.element || this.instance.dispatch('contentLoadImage', {\n content: this,\n isLazy: isLazy\n }).defaultPrevented) return;\n const imageElement = /** @type HTMLImageElement */ this.element;\n this.updateSrcsetSizes();\n if (this.data.srcset) imageElement.srcset = this.data.srcset;\n imageElement.src = this.data.src ?? '';\n imageElement.alt = this.data.alt ?? '';\n this.state = (0, $lQUwv.LOAD_STATE).LOADING;\n if (imageElement.complete) this.onLoaded();\n else {\n imageElement.onload = ()=>{\n this.onLoaded();\n };\n imageElement.onerror = ()=>{\n this.onError();\n };\n }\n }\n /**\r\n * Assign slide to content\r\n *\r\n * @param {Slide} slide\r\n */ setSlide(slide) {\n this.slide = slide;\n this.hasSlide = true;\n this.instance = slide.pswp;\n // todo: do we need to unset slide?\n }\n /**\r\n * Content load success handler\r\n */ onLoaded() {\n this.state = (0, $lQUwv.LOAD_STATE).LOADED;\n if (this.slide && this.element) {\n this.instance.dispatch('loadComplete', {\n slide: this.slide,\n content: this\n });\n // if content is reloaded\n if (this.slide.isActive && this.slide.heavyAppended && !this.element.parentNode) {\n this.append();\n this.slide.updateContentSize(true);\n }\n if (this.state === (0, $lQUwv.LOAD_STATE).LOADED || this.state === (0, $lQUwv.LOAD_STATE).ERROR) this.removePlaceholder();\n }\n }\n /**\r\n * Content load error handler\r\n */ onError() {\n this.state = (0, $lQUwv.LOAD_STATE).ERROR;\n if (this.slide) {\n this.displayError();\n this.instance.dispatch('loadComplete', {\n slide: this.slide,\n isError: true,\n content: this\n });\n this.instance.dispatch('loadError', {\n slide: this.slide,\n content: this\n });\n }\n }\n /**\r\n * @returns {Boolean} If the content is currently loading\r\n */ isLoading() {\n return this.instance.applyFilters('isContentLoading', this.state === (0, $lQUwv.LOAD_STATE).LOADING, this);\n }\n /**\r\n * @returns {Boolean} If the content is in error state\r\n */ isError() {\n return this.state === (0, $lQUwv.LOAD_STATE).ERROR;\n }\n /**\r\n * @returns {boolean} If the content is image\r\n */ isImageContent() {\n return this.type === 'image';\n }\n /**\r\n * Update content size\r\n *\r\n * @param {Number} width\r\n * @param {Number} height\r\n */ setDisplayedSize(width, height) {\n if (!this.element) return;\n if (this.placeholder) this.placeholder.setDisplayedSize(width, height);\n if (this.instance.dispatch('contentResize', {\n content: this,\n width: width,\n height: height\n }).defaultPrevented) return;\n (0, $lQUwv.setWidthHeight)(this.element, width, height);\n if (this.isImageContent() && !this.isError()) {\n const isInitialSizeUpdate = !this.displayedImageWidth && width;\n this.displayedImageWidth = width;\n this.displayedImageHeight = height;\n if (isInitialSizeUpdate) this.loadImage(false);\n else this.updateSrcsetSizes();\n if (this.slide) this.instance.dispatch('imageSizeChange', {\n slide: this.slide,\n width: width,\n height: height,\n content: this\n });\n }\n }\n /**\r\n * @returns {boolean} If the content can be zoomed\r\n */ isZoomable() {\n return this.instance.applyFilters('isContentZoomable', this.isImageContent() && this.state !== (0, $lQUwv.LOAD_STATE).ERROR, this);\n }\n /**\r\n * Update image srcset sizes attribute based on width and height\r\n */ updateSrcsetSizes() {\n // Handle srcset sizes attribute.\n //\n // Never lower quality, if it was increased previously.\n // Chrome does this automatically, Firefox and Safari do not,\n // so we store largest used size in dataset.\n if (!this.isImageContent() || !this.element || !this.data.srcset) return;\n const image = /** @type HTMLImageElement */ this.element;\n const sizesWidth = this.instance.applyFilters('srcsetSizesWidth', this.displayedImageWidth, this);\n if (!image.dataset.largestUsedSize || sizesWidth > parseInt(image.dataset.largestUsedSize, 10)) {\n image.sizes = sizesWidth + 'px';\n image.dataset.largestUsedSize = String(sizesWidth);\n }\n }\n /**\r\n * @returns {boolean} If content should use a placeholder (from msrc by default)\r\n */ usePlaceholder() {\n return this.instance.applyFilters('useContentPlaceholder', this.isImageContent(), this);\n }\n /**\r\n * Preload content with lazy-loading param\r\n */ lazyLoad() {\n if (this.instance.dispatch('contentLazyLoad', {\n content: this\n }).defaultPrevented) return;\n this.load(true);\n }\n /**\r\n * @returns {boolean} If placeholder should be kept after content is loaded\r\n */ keepPlaceholder() {\n return this.instance.applyFilters('isKeepingPlaceholder', this.isLoading(), this);\n }\n /**\r\n * Destroy the content\r\n */ destroy() {\n this.hasSlide = false;\n this.slide = undefined;\n if (this.instance.dispatch('contentDestroy', {\n content: this\n }).defaultPrevented) return;\n this.remove();\n if (this.placeholder) {\n this.placeholder.destroy();\n this.placeholder = undefined;\n }\n if (this.isImageContent() && this.element) {\n this.element.onload = null;\n this.element.onerror = null;\n this.element = undefined;\n }\n }\n /**\r\n * Display error message\r\n */ displayError() {\n if (this.slide) {\n let errorMsgEl = (0, $lQUwv.createElement)('pswp__error-msg', 'div');\n errorMsgEl.innerText = this.instance.options?.errorMsg ?? '';\n errorMsgEl = /** @type {HTMLDivElement} */ this.instance.applyFilters('contentErrorElement', errorMsgEl, this);\n this.element = (0, $lQUwv.createElement)('pswp__content pswp__error-msg-container', 'div');\n this.element.appendChild(errorMsgEl);\n this.slide.container.innerText = '';\n this.slide.container.appendChild(this.element);\n this.slide.updateContentSize(true);\n this.removePlaceholder();\n }\n }\n /**\r\n * Append the content\r\n */ append() {\n if (this.isAttached || !this.element) return;\n this.isAttached = true;\n if (this.state === (0, $lQUwv.LOAD_STATE).ERROR) {\n this.displayError();\n return;\n }\n if (this.instance.dispatch('contentAppend', {\n content: this\n }).defaultPrevented) return;\n const supportsDecode = 'decode' in this.element;\n if (this.isImageContent()) {\n // Use decode() on nearby slides\n //\n // Nearby slide images are in DOM and not hidden via display:none.\n // However, they are placed offscreen (to the left and right side).\n //\n // Some browsers do not composite the image until it's actually visible,\n // using decode() helps.\n //\n // You might ask \"why dont you just decode() and then append all images\",\n // that's because I want to show image before it's fully loaded,\n // as browser can render parts of image while it is loading.\n // We do not do this in Safari due to partial loading bug.\n if (supportsDecode && this.slide && (!this.slide.isActive || (0, $lQUwv.isSafari)())) {\n this.isDecoding = true;\n // purposefully using finally instead of then,\n // as if srcset sizes changes dynamically - it may cause decode error\n /** @type {HTMLImageElement} */ this.element.decode().catch(()=>{}).finally(()=>{\n this.isDecoding = false;\n this.appendImage();\n });\n } else this.appendImage();\n } else if (this.slide && !this.element.parentNode) this.slide.container.appendChild(this.element);\n }\n /**\r\n * Activate the slide,\r\n * active slide is generally the current one,\r\n * meaning the user can see it.\r\n */ activate() {\n if (this.instance.dispatch('contentActivate', {\n content: this\n }).defaultPrevented || !this.slide) return;\n if (this.isImageContent() && this.isDecoding && !(0, $lQUwv.isSafari)()) // add image to slide when it becomes active,\n // even if it's not finished decoding\n this.appendImage();\n else if (this.isError()) this.load(false, true); // try to reload\n if (this.slide.holderElement) this.slide.holderElement.setAttribute('aria-hidden', 'false');\n }\n /**\r\n * Deactivate the content\r\n */ deactivate() {\n this.instance.dispatch('contentDeactivate', {\n content: this\n });\n if (this.slide && this.slide.holderElement) this.slide.holderElement.setAttribute('aria-hidden', 'true');\n }\n /**\r\n * Remove the content from DOM\r\n */ remove() {\n this.isAttached = false;\n if (this.instance.dispatch('contentRemove', {\n content: this\n }).defaultPrevented) return;\n if (this.element && this.element.parentNode) this.element.remove();\n if (this.placeholder && this.placeholder.element) this.placeholder.element.remove();\n }\n /**\r\n * Append the image content to slide container\r\n */ appendImage() {\n if (!this.isAttached) return;\n if (this.instance.dispatch('contentAppendImage', {\n content: this\n }).defaultPrevented) return;\n // ensure that element exists and is not already appended\n if (this.slide && this.element && !this.element.parentNode) this.slide.container.appendChild(this.element);\n if (this.state === (0, $lQUwv.LOAD_STATE).LOADED || this.state === (0, $lQUwv.LOAD_STATE).ERROR) this.removePlaceholder();\n }\n}\nvar $c26f3ce87e26857c$export$2e2bcd8739ae039 = $c26f3ce87e26857c$var$Content;\n\n});\nparcelRegister(\"9ZhPn\", function(module, exports) {\n\n$parcel$export(module.exports, \"default\", () => $7457a3c8d557c8bf$export$2e2bcd8739ae039);\n\nvar $lQUwv = parcelRequire(\"lQUwv\");\nclass $7457a3c8d557c8bf$var$Placeholder {\n /**\r\n * @param {string | false} imageSrc\r\n * @param {HTMLElement} container\r\n */ constructor(imageSrc, container){\n // Create placeholder\n // (stretched thumbnail or simple div behind the main image)\n /** @type {HTMLImageElement | HTMLDivElement | null} */ this.element = (0, $lQUwv.createElement)('pswp__img pswp__img--placeholder', imageSrc ? 'img' : 'div', container);\n if (imageSrc) {\n const imgEl = /** @type {HTMLImageElement} */ this.element;\n imgEl.decoding = 'async';\n imgEl.alt = '';\n imgEl.src = imageSrc;\n imgEl.setAttribute('role', 'presentation');\n }\n this.element.setAttribute('aria-hidden', 'true');\n }\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */ setDisplayedSize(width, height) {\n if (!this.element) return;\n if (this.element.tagName === 'IMG') {\n // Use transform scale() to modify img placeholder size\n // (instead of changing width/height directly).\n // This helps with performance, specifically in iOS15 Safari.\n (0, $lQUwv.setWidthHeight)(this.element, 250, 'auto');\n this.element.style.transformOrigin = '0 0';\n this.element.style.transform = (0, $lQUwv.toTransformString)(0, 0, width / 250);\n } else (0, $lQUwv.setWidthHeight)(this.element, width, height);\n }\n destroy() {\n if (this.element?.parentNode) this.element.remove();\n this.element = null;\n }\n}\nvar $7457a3c8d557c8bf$export$2e2bcd8739ae039 = $7457a3c8d557c8bf$var$Placeholder;\n\n});\n\n\nparcelRegister(\"ho1E2\", function(module, exports) {\n\n$parcel$export(module.exports, \"lazyLoadData\", () => $ca85f42b9f51fccd$export$8cd05fe15af4c448);\n$parcel$export(module.exports, \"lazyLoadSlide\", () => $ca85f42b9f51fccd$export$917c0bc35382937a);\n\nvar $dsuOl = parcelRequire(\"dsuOl\");\n\nvar $gdKlE = parcelRequire(\"gdKlE\");\n/** @typedef {import('./content.js').default} Content */ /** @typedef {import('./slide.js').default} Slide */ /** @typedef {import('./slide.js').SlideData} SlideData */ /** @typedef {import('../core/base.js').default} PhotoSwipeBase */ /** @typedef {import('../photoswipe.js').default} PhotoSwipe */ const $ca85f42b9f51fccd$var$MIN_SLIDES_TO_CACHE = 5;\nfunction $ca85f42b9f51fccd$export$8cd05fe15af4c448(itemData, instance, index) {\n const content = instance.createContentFromData(itemData, index);\n /** @type {ZoomLevel | undefined} */ let zoomLevel;\n const { options: options } = instance;\n // We need to know dimensions of the image to preload it,\n // as it might use srcset, and we need to define sizes\n if (options) {\n zoomLevel = new (0, $gdKlE.default)(options, itemData, -1);\n let viewportSize;\n if (instance.pswp) viewportSize = instance.pswp.viewportSize;\n else viewportSize = (0, $dsuOl.getViewportSize)(options, instance);\n const panAreaSize = (0, $dsuOl.getPanAreaSize)(options, viewportSize, itemData, index);\n zoomLevel.update(content.width, content.height, panAreaSize);\n }\n content.lazyLoad();\n if (zoomLevel) content.setDisplayedSize(Math.ceil(content.width * zoomLevel.initial), Math.ceil(content.height * zoomLevel.initial));\n return content;\n}\nfunction $ca85f42b9f51fccd$export$917c0bc35382937a(index, instance) {\n const itemData = instance.getItemData(index);\n if (instance.dispatch('lazyLoadSlide', {\n index: index,\n itemData: itemData\n }).defaultPrevented) return;\n return $ca85f42b9f51fccd$export$8cd05fe15af4c448(itemData, instance, index);\n}\nclass $ca85f42b9f51fccd$var$ContentLoader {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */ constructor(pswp){\n this.pswp = pswp;\n // Total amount of cached images\n this.limit = Math.max(pswp.options.preload[0] + pswp.options.preload[1] + 1, $ca85f42b9f51fccd$var$MIN_SLIDES_TO_CACHE);\n /** @type {Content[]} */ this._cachedItems = [];\n }\n /**\r\n * Lazy load nearby slides based on `preload` option.\r\n *\r\n * @param {number} [diff] Difference between slide indexes that was changed recently, or 0.\r\n */ updateLazy(diff) {\n const { pswp: pswp } = this;\n if (pswp.dispatch('lazyLoad').defaultPrevented) return;\n const { preload: preload } = pswp.options;\n const isForward = diff === undefined ? true : diff >= 0;\n let i;\n // preload[1] - num items to preload in forward direction\n for(i = 0; i <= preload[1]; i++)this.loadSlideByIndex(pswp.currIndex + (isForward ? i : -i));\n // preload[0] - num items to preload in backward direction\n for(i = 1; i <= preload[0]; i++)this.loadSlideByIndex(pswp.currIndex + (isForward ? -i : i));\n }\n /**\r\n * @param {number} initialIndex\r\n */ loadSlideByIndex(initialIndex) {\n const index = this.pswp.getLoopedIndex(initialIndex);\n // try to get cached content\n let content = this.getContentByIndex(index);\n if (!content) {\n // no cached content, so try to load from scratch:\n content = $ca85f42b9f51fccd$export$917c0bc35382937a(index, this.pswp);\n // if content can be loaded, add it to cache:\n if (content) this.addToCache(content);\n }\n }\n /**\r\n * @param {Slide} slide\r\n * @returns {Content}\r\n */ getContentBySlide(slide) {\n let content = this.getContentByIndex(slide.index);\n if (!content) {\n // create content if not found in cache\n content = this.pswp.createContentFromData(slide.data, slide.index);\n this.addToCache(content);\n }\n // assign slide to content\n content.setSlide(slide);\n return content;\n }\n /**\r\n * @param {Content} content\r\n */ addToCache(content) {\n // move to the end of array\n this.removeByIndex(content.index);\n this._cachedItems.push(content);\n if (this._cachedItems.length > this.limit) {\n // Destroy the first content that's not attached\n const indexToRemove = this._cachedItems.findIndex((item)=>{\n return !item.isAttached && !item.hasSlide;\n });\n if (indexToRemove !== -1) {\n const removedItem = this._cachedItems.splice(indexToRemove, 1)[0];\n removedItem.destroy();\n }\n }\n }\n /**\r\n * Removes an image from cache, does not destroy() it, just removes.\r\n *\r\n * @param {number} index\r\n */ removeByIndex(index) {\n const indexToRemove = this._cachedItems.findIndex((item)=>item.index === index);\n if (indexToRemove !== -1) this._cachedItems.splice(indexToRemove, 1);\n }\n /**\r\n * @param {number} index\r\n * @returns {Content | undefined}\r\n */ getContentByIndex(index) {\n return this._cachedItems.find((content)=>content.index === index);\n }\n destroy() {\n this._cachedItems.forEach((content)=>content.destroy());\n this._cachedItems = [];\n }\n}\nvar $ca85f42b9f51fccd$export$2e2bcd8739ae039 = $ca85f42b9f51fccd$var$ContentLoader;\n\n});\nparcelRegister(\"dsuOl\", function(module, exports) {\n\n$parcel$export(module.exports, \"getViewportSize\", () => $9cc5ca51babdeaaa$export$125915cfb610b3c2);\n$parcel$export(module.exports, \"getPanAreaSize\", () => $9cc5ca51babdeaaa$export$fe74fc76a188f696);\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */ /** @typedef {import('../core/base.js').default} PhotoSwipeBase */ /** @typedef {import('../photoswipe.js').Point} Point */ /** @typedef {import('../slide/slide.js').SlideData} SlideData */ /**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {PhotoSwipeBase} pswp\r\n * @returns {Point}\r\n */ function $9cc5ca51babdeaaa$export$125915cfb610b3c2(options, pswp) {\n if (options.getViewportSizeFn) {\n const newViewportSize = options.getViewportSizeFn(options, pswp);\n if (newViewportSize) return newViewportSize;\n }\n return {\n x: document.documentElement.clientWidth,\n // TODO: height on mobile is very incosistent due to toolbar\n // find a way to improve this\n //\n // document.documentElement.clientHeight - doesn't seem to work well\n y: window.innerHeight\n };\n}\nfunction $9cc5ca51babdeaaa$export$b09b17ae2adc409d(prop, options, viewportSize, itemData, index) {\n let paddingValue = 0;\n if (options.paddingFn) paddingValue = options.paddingFn(viewportSize, itemData, index)[prop];\n else if (options.padding) paddingValue = options.padding[prop];\n else {\n const legacyPropName = 'padding' + prop[0].toUpperCase() + prop.slice(1);\n // @ts-expect-error\n if (options[legacyPropName]) // @ts-expect-error\n paddingValue = options[legacyPropName];\n }\n return Number(paddingValue) || 0;\n}\nfunction $9cc5ca51babdeaaa$export$fe74fc76a188f696(options, viewportSize, itemData, index) {\n return {\n x: viewportSize.x - $9cc5ca51babdeaaa$export$b09b17ae2adc409d('left', options, viewportSize, itemData, index) - $9cc5ca51babdeaaa$export$b09b17ae2adc409d('right', options, viewportSize, itemData, index),\n y: viewportSize.y - $9cc5ca51babdeaaa$export$b09b17ae2adc409d('top', options, viewportSize, itemData, index) - $9cc5ca51babdeaaa$export$b09b17ae2adc409d('bottom', options, viewportSize, itemData, index)\n };\n}\n\n});\n\nparcelRegister(\"gdKlE\", function(module, exports) {\n\n$parcel$export(module.exports, \"default\", () => $bcf1d005fb788dff$export$2e2bcd8739ae039);\nconst $bcf1d005fb788dff$var$MAX_IMAGE_WIDTH = 4000;\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */ /** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */ /** @typedef {import('../photoswipe.js').Point} Point */ /** @typedef {import('../slide/slide.js').SlideData} SlideData */ /** @typedef {'fit' | 'fill' | number | ((zoomLevelObject: ZoomLevel) => number)} ZoomLevelOption */ /**\r\n * Calculates zoom levels for specific slide.\r\n * Depends on viewport size and image size.\r\n */ class $bcf1d005fb788dff$var$ZoomLevel {\n /**\r\n * @param {PhotoSwipeOptions} options PhotoSwipe options\r\n * @param {SlideData} itemData Slide data\r\n * @param {number} index Slide index\r\n * @param {PhotoSwipe} [pswp] PhotoSwipe instance, can be undefined if not initialized yet\r\n */ constructor(options, itemData, index, pswp){\n this.pswp = pswp;\n this.options = options;\n this.itemData = itemData;\n this.index = index;\n /** @type { Point | null } */ this.panAreaSize = null;\n /** @type { Point | null } */ this.elementSize = null;\n this.fit = 1;\n this.fill = 1;\n this.vFill = 1;\n this.initial = 1;\n this.secondary = 1;\n this.max = 1;\n this.min = 1;\n }\n /**\r\n * Calculate initial, secondary and maximum zoom level for the specified slide.\r\n *\r\n * It should be called when either image or viewport size changes.\r\n *\r\n * @param {number} maxWidth\r\n * @param {number} maxHeight\r\n * @param {Point} panAreaSize\r\n */ update(maxWidth, maxHeight, panAreaSize) {\n /** @type {Point} */ const elementSize = {\n x: maxWidth,\n y: maxHeight\n };\n this.elementSize = elementSize;\n this.panAreaSize = panAreaSize;\n const hRatio = panAreaSize.x / elementSize.x;\n const vRatio = panAreaSize.y / elementSize.y;\n this.fit = Math.min(1, hRatio < vRatio ? hRatio : vRatio);\n this.fill = Math.min(1, hRatio > vRatio ? hRatio : vRatio);\n // zoom.vFill defines zoom level of the image\n // when it has 100% of viewport vertical space (height)\n this.vFill = Math.min(1, vRatio);\n this.initial = this._getInitial();\n this.secondary = this._getSecondary();\n this.max = Math.max(this.initial, this.secondary, this._getMax());\n this.min = Math.min(this.fit, this.initial, this.secondary);\n if (this.pswp) this.pswp.dispatch('zoomLevelsUpdate', {\n zoomLevels: this,\n slideData: this.itemData\n });\n }\n /**\r\n * Parses user-defined zoom option.\r\n *\r\n * @private\r\n * @param {'initial' | 'secondary' | 'max'} optionPrefix Zoom level option prefix (initial, secondary, max)\r\n * @returns { number | undefined }\r\n */ _parseZoomLevelOption(optionPrefix) {\n const optionName = /** @type {'initialZoomLevel' | 'secondaryZoomLevel' | 'maxZoomLevel'} */ optionPrefix + 'ZoomLevel';\n const optionValue = this.options[optionName];\n if (!optionValue) return;\n if (typeof optionValue === 'function') return optionValue(this);\n if (optionValue === 'fill') return this.fill;\n if (optionValue === 'fit') return this.fit;\n return Number(optionValue);\n }\n /**\r\n * Get zoom level to which image will be zoomed after double-tap gesture,\r\n * or when user clicks on zoom icon,\r\n * or mouse-click on image itself.\r\n * If you return 1 image will be zoomed to its original size.\r\n *\r\n * @private\r\n * @return {number}\r\n */ _getSecondary() {\n let currZoomLevel = this._parseZoomLevelOption('secondary');\n if (currZoomLevel) return currZoomLevel;\n // 3x of \"fit\" state, but not larger than original\n currZoomLevel = Math.min(1, this.fit * 3);\n if (this.elementSize && currZoomLevel * this.elementSize.x > $bcf1d005fb788dff$var$MAX_IMAGE_WIDTH) currZoomLevel = $bcf1d005fb788dff$var$MAX_IMAGE_WIDTH / this.elementSize.x;\n return currZoomLevel;\n }\n /**\r\n * Get initial image zoom level.\r\n *\r\n * @private\r\n * @return {number}\r\n */ _getInitial() {\n return this._parseZoomLevelOption('initial') || this.fit;\n }\n /**\r\n * Maximum zoom level when user zooms\r\n * via zoom/pinch gesture,\r\n * via cmd/ctrl-wheel or via trackpad.\r\n *\r\n * @private\r\n * @return {number}\r\n */ _getMax() {\n // max zoom level is x4 from \"fit state\",\n // used for zoom gesture and ctrl/trackpad zoom\n return this._parseZoomLevelOption('max') || Math.max(1, this.fit * 4);\n }\n}\nvar $bcf1d005fb788dff$export$2e2bcd8739ae039 = $bcf1d005fb788dff$var$ZoomLevel;\n\n});\n\n\n\n\n\n//# sourceMappingURL=_channel.b33e9a30.js.map\n","import {\r\n specialKeyUsed,\r\n getElementsFromOption,\r\n isPswpClass\r\n} from '../util/util.js';\r\n\r\nimport PhotoSwipeBase from '../core/base.js';\r\nimport { lazyLoadSlide } from '../slide/loader.js';\r\n\r\n/**\r\n * @template T\r\n * @typedef {import('../types.js').Type} Type\r\n */\r\n\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../photoswipe.js').DataSource} DataSource */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('../slide/content.js').default} Content */\r\n/** @typedef {import('../core/eventable.js').PhotoSwipeEventsMap} PhotoSwipeEventsMap */\r\n/** @typedef {import('../core/eventable.js').PhotoSwipeFiltersMap} PhotoSwipeFiltersMap */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('../core/eventable.js').EventCallback} EventCallback\r\n */\r\n\r\n/**\r\n * PhotoSwipe Lightbox\r\n *\r\n * - If user has unsupported browser it falls back to default browser action (just opens URL)\r\n * - Binds click event to links that should open PhotoSwipe\r\n * - parses DOM strcture for PhotoSwipe (retrieves large image URLs and sizes)\r\n * - Initializes PhotoSwipe\r\n *\r\n *\r\n * Loader options use the same object as PhotoSwipe, and supports such options:\r\n *\r\n * gallery - Element | Element[] | NodeList | string selector for the gallery element\r\n * children - Element | Element[] | NodeList | string selector for the gallery children\r\n *\r\n */\r\nclass PhotoSwipeLightbox extends PhotoSwipeBase {\r\n /**\r\n * @param {PhotoSwipeOptions} [options]\r\n */\r\n constructor(options) {\r\n super();\r\n /** @type {PhotoSwipeOptions} */\r\n this.options = options || {};\r\n this._uid = 0;\r\n this.shouldOpen = false;\r\n /**\r\n * @private\r\n * @type {Content | undefined}\r\n */\r\n this._preloadedContent = undefined;\r\n\r\n this.onThumbnailsClick = this.onThumbnailsClick.bind(this);\r\n }\r\n\r\n /**\r\n * Initialize lightbox, should be called only once.\r\n * It's not included in the main constructor, so you may bind events before it.\r\n */\r\n init() {\r\n // Bind click events to each gallery\r\n getElementsFromOption(this.options.gallery, this.options.gallerySelector)\r\n .forEach((galleryElement) => {\r\n galleryElement.addEventListener('click', this.onThumbnailsClick, false);\r\n });\r\n }\r\n\r\n /**\r\n * @param {MouseEvent} e\r\n */\r\n onThumbnailsClick(e) {\r\n // Exit and allow default browser action if:\r\n if (specialKeyUsed(e) // ... if clicked with a special key (ctrl/cmd...)\r\n || window.pswp) { // ... if PhotoSwipe is already open\r\n return;\r\n }\r\n\r\n // If both clientX and clientY are 0 or not defined,\r\n // the event is likely triggered by keyboard,\r\n // so we do not pass the initialPoint\r\n //\r\n // Note that some screen readers emulate the mouse position,\r\n // so it's not the ideal way to detect them.\r\n //\r\n /** @type {Point | null} */\r\n let initialPoint = { x: e.clientX, y: e.clientY };\r\n\r\n if (!initialPoint.x && !initialPoint.y) {\r\n initialPoint = null;\r\n }\r\n\r\n let clickedIndex = this.getClickedIndex(e);\r\n clickedIndex = this.applyFilters('clickedIndex', clickedIndex, e, this);\r\n /** @type {DataSource} */\r\n const dataSource = {\r\n gallery: /** @type {HTMLElement} */ (e.currentTarget)\r\n };\r\n\r\n if (clickedIndex >= 0) {\r\n e.preventDefault();\r\n this.loadAndOpen(clickedIndex, dataSource, initialPoint);\r\n }\r\n }\r\n\r\n /**\r\n * Get index of gallery item that was clicked.\r\n *\r\n * @param {MouseEvent} e click event\r\n * @returns {number}\r\n */\r\n getClickedIndex(e) {\r\n // legacy option\r\n if (this.options.getClickedIndexFn) {\r\n return this.options.getClickedIndexFn.call(this, e);\r\n }\r\n\r\n const clickedTarget = /** @type {HTMLElement} */ (e.target);\r\n const childElements = getElementsFromOption(\r\n this.options.children,\r\n this.options.childSelector,\r\n /** @type {HTMLElement} */ (e.currentTarget)\r\n );\r\n const clickedChildIndex = childElements.findIndex(\r\n child => child === clickedTarget || child.contains(clickedTarget)\r\n );\r\n\r\n if (clickedChildIndex !== -1) {\r\n return clickedChildIndex;\r\n } else if (this.options.children || this.options.childSelector) {\r\n // click wasn't on a child element\r\n return -1;\r\n }\r\n\r\n // There is only one item (which is the gallery)\r\n return 0;\r\n }\r\n\r\n /**\r\n * Load and open PhotoSwipe\r\n *\r\n * @param {number} index\r\n * @param {DataSource} [dataSource]\r\n * @param {Point | null} [initialPoint]\r\n * @returns {boolean}\r\n */\r\n loadAndOpen(index, dataSource, initialPoint) {\r\n // Check if the gallery is already open\r\n if (window.pswp || !this.options) {\r\n return false;\r\n }\r\n\r\n // Use the first gallery element if dataSource is not provided\r\n if (!dataSource && this.options.gallery && this.options.children) {\r\n const galleryElements = getElementsFromOption(this.options.gallery);\r\n if (galleryElements[0]) {\r\n dataSource = {\r\n gallery: galleryElements[0]\r\n };\r\n }\r\n }\r\n\r\n // set initial index\r\n this.options.index = index;\r\n\r\n // define options for PhotoSwipe constructor\r\n this.options.initialPointerPos = initialPoint;\r\n\r\n this.shouldOpen = true;\r\n this.preload(index, dataSource);\r\n return true;\r\n }\r\n\r\n /**\r\n * Load the main module and the slide content by index\r\n *\r\n * @param {number} index\r\n * @param {DataSource} [dataSource]\r\n */\r\n preload(index, dataSource) {\r\n const { options } = this;\r\n\r\n if (dataSource) {\r\n options.dataSource = dataSource;\r\n }\r\n\r\n // Add the main module\r\n /** @type {Promise>[]} */\r\n const promiseArray = [];\r\n\r\n const pswpModuleType = typeof options.pswpModule;\r\n if (isPswpClass(options.pswpModule)) {\r\n promiseArray.push(Promise.resolve(/** @type {Type} */ (options.pswpModule)));\r\n } else if (pswpModuleType === 'string') {\r\n throw new Error('pswpModule as string is no longer supported');\r\n } else if (pswpModuleType === 'function') {\r\n promiseArray.push(/** @type {() => Promise>} */ (options.pswpModule)());\r\n } else {\r\n throw new Error('pswpModule is not valid');\r\n }\r\n\r\n // Add custom-defined promise, if any\r\n if (typeof options.openPromise === 'function') {\r\n // allow developers to perform some task before opening\r\n promiseArray.push(options.openPromise());\r\n }\r\n\r\n if (options.preloadFirstSlide !== false && index >= 0) {\r\n this._preloadedContent = lazyLoadSlide(index, this);\r\n }\r\n\r\n // Wait till all promises resolve and open PhotoSwipe\r\n const uid = ++this._uid;\r\n Promise.all(promiseArray).then((iterableModules) => {\r\n if (this.shouldOpen) {\r\n const mainModule = iterableModules[0];\r\n this._openPhotoswipe(mainModule, uid);\r\n }\r\n });\r\n }\r\n\r\n /**\r\n * @private\r\n * @param {Type | { default: Type }} module\r\n * @param {number} uid\r\n */\r\n _openPhotoswipe(module, uid) {\r\n // Cancel opening if UID doesn't match the current one\r\n // (if user clicked on another gallery item before current was loaded).\r\n //\r\n // Or if shouldOpen flag is set to false\r\n // (developer may modify it via public API)\r\n if (uid !== this._uid && this.shouldOpen) {\r\n return;\r\n }\r\n\r\n this.shouldOpen = false;\r\n\r\n // PhotoSwipe is already open\r\n if (window.pswp) {\r\n return;\r\n }\r\n\r\n /**\r\n * Pass data to PhotoSwipe and open init\r\n *\r\n * @type {PhotoSwipe}\r\n */\r\n const pswp = typeof module === 'object'\r\n ? new module.default(this.options) // eslint-disable-line\r\n : new module(this.options); // eslint-disable-line\r\n\r\n this.pswp = pswp;\r\n window.pswp = pswp;\r\n\r\n // map listeners from Lightbox to PhotoSwipe Core\r\n /** @type {(keyof PhotoSwipeEventsMap)[]} */\r\n (Object.keys(this._listeners)).forEach((name) => {\r\n this._listeners[name]?.forEach((fn) => {\r\n pswp.on(name, /** @type {EventCallback} */(fn));\r\n });\r\n });\r\n\r\n // same with filters\r\n /** @type {(keyof PhotoSwipeFiltersMap)[]} */\r\n (Object.keys(this._filters)).forEach((name) => {\r\n this._filters[name]?.forEach((filter) => {\r\n pswp.addFilter(name, filter.fn, filter.priority);\r\n });\r\n });\r\n\r\n if (this._preloadedContent) {\r\n pswp.contentLoader.addToCache(this._preloadedContent);\r\n this._preloadedContent = undefined;\r\n }\r\n\r\n pswp.on('destroy', () => {\r\n // clean up public variables\r\n this.pswp = undefined;\r\n delete window.pswp;\r\n });\r\n\r\n pswp.init();\r\n }\r\n\r\n /**\r\n * Unbinds all events, closes PhotoSwipe if it's open.\r\n */\r\n destroy() {\r\n this.pswp?.destroy();\r\n\r\n this.shouldOpen = false;\r\n this._listeners = {};\r\n\r\n getElementsFromOption(this.options.gallery, this.options.gallerySelector)\r\n .forEach((galleryElement) => {\r\n galleryElement.removeEventListener('click', this.onThumbnailsClick, false);\r\n });\r\n }\r\n}\r\n\r\nexport default PhotoSwipeLightbox;\r\n","/** @typedef {import('../photoswipe.js').Point} Point */\r\n\r\n/**\r\n * @template {keyof HTMLElementTagNameMap} T\r\n * @param {string} className\r\n * @param {T} tagName\r\n * @param {Node} [appendToEl]\r\n * @returns {HTMLElementTagNameMap[T]}\r\n */\r\nexport function createElement(className, tagName, appendToEl) {\r\n const el = document.createElement(tagName);\r\n if (className) {\r\n el.className = className;\r\n }\r\n if (appendToEl) {\r\n appendToEl.appendChild(el);\r\n }\r\n return el;\r\n}\r\n\r\n/**\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {Point}\r\n */\r\nexport function equalizePoints(p1, p2) {\r\n p1.x = p2.x;\r\n p1.y = p2.y;\r\n if (p2.id !== undefined) {\r\n p1.id = p2.id;\r\n }\r\n return p1;\r\n}\r\n\r\n/**\r\n * @param {Point} p\r\n */\r\nexport function roundPoint(p) {\r\n p.x = Math.round(p.x);\r\n p.y = Math.round(p.y);\r\n}\r\n\r\n/**\r\n * Returns distance between two points.\r\n *\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {number}\r\n */\r\nexport function getDistanceBetween(p1, p2) {\r\n const x = Math.abs(p1.x - p2.x);\r\n const y = Math.abs(p1.y - p2.y);\r\n return Math.sqrt((x * x) + (y * y));\r\n}\r\n\r\n/**\r\n * Whether X and Y positions of points are equal\r\n *\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {boolean}\r\n */\r\nexport function pointsEqual(p1, p2) {\r\n return p1.x === p2.x && p1.y === p2.y;\r\n}\r\n\r\n/**\r\n * The float result between the min and max values.\r\n *\r\n * @param {number} val\r\n * @param {number} min\r\n * @param {number} max\r\n * @returns {number}\r\n */\r\nexport function clamp(val, min, max) {\r\n return Math.min(Math.max(val, min), max);\r\n}\r\n\r\n/**\r\n * Get transform string\r\n *\r\n * @param {number} x\r\n * @param {number} [y]\r\n * @param {number} [scale]\r\n * @returns {string}\r\n */\r\nexport function toTransformString(x, y, scale) {\r\n let propValue = `translate3d(${x}px,${y || 0}px,0)`;\r\n\r\n if (scale !== undefined) {\r\n propValue += ` scale3d(${scale},${scale},1)`;\r\n }\r\n\r\n return propValue;\r\n}\r\n\r\n/**\r\n * Apply transform:translate(x, y) scale(scale) to element\r\n *\r\n * @param {HTMLElement} el\r\n * @param {number} x\r\n * @param {number} [y]\r\n * @param {number} [scale]\r\n */\r\nexport function setTransform(el, x, y, scale) {\r\n el.style.transform = toTransformString(x, y, scale);\r\n}\r\n\r\nconst defaultCSSEasing = 'cubic-bezier(.4,0,.22,1)';\r\n\r\n/**\r\n * Apply CSS transition to element\r\n *\r\n * @param {HTMLElement} el\r\n * @param {string} [prop] CSS property to animate\r\n * @param {number} [duration] in ms\r\n * @param {string} [ease] CSS easing function\r\n */\r\nexport function setTransitionStyle(el, prop, duration, ease) {\r\n // inOut: 'cubic-bezier(.4, 0, .22, 1)', // for \"toggle state\" transitions\r\n // out: 'cubic-bezier(0, 0, .22, 1)', // for \"show\" transitions\r\n // in: 'cubic-bezier(.4, 0, 1, 1)'// for \"hide\" transitions\r\n el.style.transition = prop\r\n ? `${prop} ${duration}ms ${ease || defaultCSSEasing}`\r\n : 'none';\r\n}\r\n\r\n/**\r\n * Apply width and height CSS properties to element\r\n *\r\n * @param {HTMLElement} el\r\n * @param {string | number} w\r\n * @param {string | number} h\r\n */\r\nexport function setWidthHeight(el, w, h) {\r\n el.style.width = (typeof w === 'number') ? `${w}px` : w;\r\n el.style.height = (typeof h === 'number') ? `${h}px` : h;\r\n}\r\n\r\n/**\r\n * @param {HTMLElement} el\r\n */\r\nexport function removeTransitionStyle(el) {\r\n setTransitionStyle(el);\r\n}\r\n\r\n/**\r\n * @param {HTMLImageElement} img\r\n * @returns {Promise}\r\n */\r\nexport function decodeImage(img) {\r\n if ('decode' in img) {\r\n return img.decode().catch(() => {});\r\n }\r\n\r\n if (img.complete) {\r\n return Promise.resolve(img);\r\n }\r\n\r\n return new Promise((resolve, reject) => {\r\n img.onload = () => resolve(img);\r\n img.onerror = reject;\r\n });\r\n}\r\n\r\n/** @typedef {LOAD_STATE[keyof LOAD_STATE]} LoadState */\r\n/** @type {{ IDLE: 'idle'; LOADING: 'loading'; LOADED: 'loaded'; ERROR: 'error' }} */\r\nexport const LOAD_STATE = {\r\n IDLE: 'idle',\r\n LOADING: 'loading',\r\n LOADED: 'loaded',\r\n ERROR: 'error',\r\n};\r\n\r\n\r\n/**\r\n * Check if click or keydown event was dispatched\r\n * with a special key or via mouse wheel.\r\n *\r\n * @param {MouseEvent | KeyboardEvent} e\r\n * @returns {boolean}\r\n */\r\nexport function specialKeyUsed(e) {\r\n return ('button' in e && e.button === 1) || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey;\r\n}\r\n\r\n/**\r\n * Parse `gallery` or `children` options.\r\n *\r\n * @param {import('../photoswipe.js').ElementProvider} [option]\r\n * @param {string} [legacySelector]\r\n * @param {HTMLElement | Document} [parent]\r\n * @returns HTMLElement[]\r\n */\r\nexport function getElementsFromOption(option, legacySelector, parent = document) {\r\n /** @type {HTMLElement[]} */\r\n let elements = [];\r\n\r\n if (option instanceof Element) {\r\n elements = [option];\r\n } else if (option instanceof NodeList || Array.isArray(option)) {\r\n elements = Array.from(option);\r\n } else {\r\n const selector = typeof option === 'string' ? option : legacySelector;\r\n if (selector) {\r\n elements = Array.from(parent.querySelectorAll(selector));\r\n }\r\n }\r\n\r\n return elements;\r\n}\r\n\r\n/**\r\n * Check if variable is PhotoSwipe class\r\n *\r\n * @param {any} fn\r\n * @returns {boolean}\r\n */\r\nexport function isPswpClass(fn) {\r\n return typeof fn === 'function'\r\n && fn.prototype\r\n && fn.prototype.goTo;\r\n}\r\n\r\n/**\r\n * Check if browser is Safari\r\n *\r\n * @returns {boolean}\r\n */\r\nexport function isSafari() {\r\n return !!(navigator.vendor && navigator.vendor.match(/apple/i));\r\n}\r\n\r\n","import Eventable from './eventable.js';\r\nimport { getElementsFromOption } from '../util/util.js';\r\nimport Content from '../slide/content.js';\r\nimport { lazyLoadData } from '../slide/loader.js';\r\n\r\n/** @typedef {import(\"../photoswipe.js\").default} PhotoSwipe */\r\n/** @typedef {import(\"../slide/slide.js\").SlideData} SlideData */\r\n\r\n/**\r\n * PhotoSwipe base class that can retrieve data about every slide.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox\r\n */\r\nclass PhotoSwipeBase extends Eventable {\r\n /**\r\n * Get total number of slides\r\n *\r\n * @returns {number}\r\n */\r\n getNumItems() {\r\n let numItems = 0;\r\n const dataSource = this.options?.dataSource;\r\n\r\n if (dataSource && 'length' in dataSource) {\r\n // may be an array or just object with length property\r\n numItems = dataSource.length;\r\n } else if (dataSource && 'gallery' in dataSource) {\r\n // query DOM elements\r\n if (!dataSource.items) {\r\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\r\n }\r\n\r\n if (dataSource.items) {\r\n numItems = dataSource.items.length;\r\n }\r\n }\r\n\r\n // legacy event, before filters were introduced\r\n const event = this.dispatch('numItems', {\r\n dataSource,\r\n numItems\r\n });\r\n return this.applyFilters('numItems', event.numItems, dataSource);\r\n }\r\n\r\n /**\r\n * @param {SlideData} slideData\r\n * @param {number} index\r\n * @returns {Content}\r\n */\r\n createContentFromData(slideData, index) {\r\n return new Content(slideData, this, index);\r\n }\r\n\r\n /**\r\n * Get item data by index.\r\n *\r\n * \"item data\" should contain normalized information that PhotoSwipe needs to generate a slide.\r\n * For example, it may contain properties like\r\n * `src`, `srcset`, `w`, `h`, which will be used to generate a slide with image.\r\n *\r\n * @param {number} index\r\n * @returns {SlideData}\r\n */\r\n getItemData(index) {\r\n const dataSource = this.options?.dataSource;\r\n /** @type {SlideData | HTMLElement} */\r\n let dataSourceItem = {};\r\n if (Array.isArray(dataSource)) {\r\n // Datasource is an array of elements\r\n dataSourceItem = dataSource[index];\r\n } else if (dataSource && 'gallery' in dataSource) {\r\n // dataSource has gallery property,\r\n // thus it was created by Lightbox, based on\r\n // gallery and children options\r\n\r\n // query DOM elements\r\n if (!dataSource.items) {\r\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\r\n }\r\n\r\n dataSourceItem = dataSource.items[index];\r\n }\r\n\r\n let itemData = dataSourceItem;\r\n\r\n if (itemData instanceof Element) {\r\n itemData = this._domElementToItemData(itemData);\r\n }\r\n\r\n // Dispatching the itemData event,\r\n // it's a legacy verion before filters were introduced\r\n const event = this.dispatch('itemData', {\r\n itemData: itemData || {},\r\n index\r\n });\r\n\r\n return this.applyFilters('itemData', event.itemData, index);\r\n }\r\n\r\n /**\r\n * Get array of gallery DOM elements,\r\n * based on childSelector and gallery element.\r\n *\r\n * @param {HTMLElement} galleryElement\r\n * @returns {HTMLElement[]}\r\n */\r\n _getGalleryDOMElements(galleryElement) {\r\n if (this.options?.children || this.options?.childSelector) {\r\n return getElementsFromOption(\r\n this.options.children,\r\n this.options.childSelector,\r\n galleryElement\r\n ) || [];\r\n }\r\n\r\n return [galleryElement];\r\n }\r\n\r\n /**\r\n * Converts DOM element to item data object.\r\n *\r\n * @param {HTMLElement} element DOM element\r\n * @returns {SlideData}\r\n */\r\n _domElementToItemData(element) {\r\n /** @type {SlideData} */\r\n const itemData = {\r\n element\r\n };\r\n\r\n const linkEl = /** @type {HTMLAnchorElement} */ (\r\n element.tagName === 'A'\r\n ? element\r\n : element.querySelector('a')\r\n );\r\n\r\n if (linkEl) {\r\n // src comes from data-pswp-src attribute,\r\n // if it's empty link href is used\r\n itemData.src = linkEl.dataset.pswpSrc || linkEl.href;\r\n\r\n if (linkEl.dataset.pswpSrcset) {\r\n itemData.srcset = linkEl.dataset.pswpSrcset;\r\n }\r\n\r\n itemData.width = linkEl.dataset.pswpWidth ? parseInt(linkEl.dataset.pswpWidth, 10) : 0;\r\n itemData.height = linkEl.dataset.pswpHeight ? parseInt(linkEl.dataset.pswpHeight, 10) : 0;\r\n\r\n // support legacy w & h properties\r\n itemData.w = itemData.width;\r\n itemData.h = itemData.height;\r\n\r\n if (linkEl.dataset.pswpType) {\r\n itemData.type = linkEl.dataset.pswpType;\r\n }\r\n\r\n const thumbnailEl = element.querySelector('img');\r\n\r\n if (thumbnailEl) {\r\n // msrc is URL to placeholder image that's displayed before large image is loaded\r\n // by default it's displayed only for the first slide\r\n itemData.msrc = thumbnailEl.currentSrc || thumbnailEl.src;\r\n itemData.alt = thumbnailEl.getAttribute('alt') ?? '';\r\n }\r\n\r\n if (linkEl.dataset.pswpCropped || linkEl.dataset.cropped) {\r\n itemData.thumbCropped = true;\r\n }\r\n }\r\n\r\n return this.applyFilters('domItemData', itemData, element, linkEl);\r\n }\r\n\r\n /**\r\n * Lazy-load by slide data\r\n *\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {number} index\r\n * @returns {Content} Image that is being decoded or false.\r\n */\r\n lazyLoadData(itemData, index) {\r\n return lazyLoadData(itemData, this, index);\r\n }\r\n}\r\n\r\nexport default PhotoSwipeBase;\r\n","/** @typedef {import('../lightbox/lightbox.js').default} PhotoSwipeLightbox */\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../photoswipe.js').DataSource} DataSource */\r\n/** @typedef {import('../ui/ui-element.js').UIElementData} UIElementData */\r\n/** @typedef {import('../slide/content.js').default} ContentDefault */\r\n/** @typedef {import('../slide/slide.js').default} Slide */\r\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\r\n/** @typedef {import('../slide/zoom-level.js').default} ZoomLevel */\r\n/** @typedef {import('../slide/get-thumb-bounds.js').Bounds} Bounds */\r\n\r\n/**\r\n * Allow adding an arbitrary props to the Content\r\n * https://photoswipe.com/custom-content/#using-webp-image-format\r\n * @typedef {ContentDefault & Record} Content\r\n */\r\n/** @typedef {{ x?: number; y?: number }} Point */\r\n\r\n/**\r\n * @typedef {Object} PhotoSwipeEventsMap https://photoswipe.com/events/\r\n *\r\n *\r\n * https://photoswipe.com/adding-ui-elements/\r\n *\r\n * @prop {undefined} uiRegister\r\n * @prop {{ data: UIElementData }} uiElementCreate\r\n *\r\n *\r\n * https://photoswipe.com/events/#initialization-events\r\n *\r\n * @prop {undefined} beforeOpen\r\n * @prop {undefined} firstUpdate\r\n * @prop {undefined} initialLayout\r\n * @prop {undefined} change\r\n * @prop {undefined} afterInit\r\n * @prop {undefined} bindEvents\r\n *\r\n *\r\n * https://photoswipe.com/events/#opening-or-closing-transition-events\r\n *\r\n * @prop {undefined} openingAnimationStart\r\n * @prop {undefined} openingAnimationEnd\r\n * @prop {undefined} closingAnimationStart\r\n * @prop {undefined} closingAnimationEnd\r\n *\r\n *\r\n * https://photoswipe.com/events/#closing-events\r\n *\r\n * @prop {undefined} close\r\n * @prop {undefined} destroy\r\n *\r\n *\r\n * https://photoswipe.com/events/#pointer-and-gesture-events\r\n *\r\n * @prop {{ originalEvent: PointerEvent }} pointerDown\r\n * @prop {{ originalEvent: PointerEvent }} pointerMove\r\n * @prop {{ originalEvent: PointerEvent }} pointerUp\r\n * @prop {{ bgOpacity: number }} pinchClose can be default prevented\r\n * @prop {{ panY: number }} verticalDrag can be default prevented\r\n *\r\n *\r\n * https://photoswipe.com/events/#slide-content-events\r\n *\r\n * @prop {{ content: Content }} contentInit\r\n * @prop {{ content: Content; isLazy: boolean }} contentLoad can be default prevented\r\n * @prop {{ content: Content; isLazy: boolean }} contentLoadImage can be default prevented\r\n * @prop {{ content: Content; slide: Slide; isError?: boolean }} loadComplete\r\n * @prop {{ content: Content; slide: Slide }} loadError\r\n * @prop {{ content: Content; width: number; height: number }} contentResize can be default prevented\r\n * @prop {{ content: Content; width: number; height: number; slide: Slide }} imageSizeChange\r\n * @prop {{ content: Content }} contentLazyLoad can be default prevented\r\n * @prop {{ content: Content }} contentAppend can be default prevented\r\n * @prop {{ content: Content }} contentActivate can be default prevented\r\n * @prop {{ content: Content }} contentDeactivate can be default prevented\r\n * @prop {{ content: Content }} contentRemove can be default prevented\r\n * @prop {{ content: Content }} contentDestroy can be default prevented\r\n *\r\n *\r\n * undocumented\r\n *\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} imageClickAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} bgClickAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} tapAction can be default prevented\r\n * @prop {{ point: Point; originalEvent: PointerEvent }} doubleTapAction can be default prevented\r\n *\r\n * @prop {{ originalEvent: KeyboardEvent }} keydown can be default prevented\r\n * @prop {{ x: number; dragging: boolean }} moveMainScroll\r\n * @prop {{ slide: Slide }} firstZoomPan\r\n * @prop {{ slide: Slide | undefined, data: SlideData, index: number }} gettingData\r\n * @prop {undefined} beforeResize\r\n * @prop {undefined} resize\r\n * @prop {undefined} viewportSize\r\n * @prop {undefined} updateScrollOffset\r\n * @prop {{ slide: Slide }} slideInit\r\n * @prop {{ slide: Slide }} afterSetContent\r\n * @prop {{ slide: Slide }} slideLoad\r\n * @prop {{ slide: Slide }} appendHeavy can be default prevented\r\n * @prop {{ slide: Slide }} appendHeavyContent\r\n * @prop {{ slide: Slide }} slideActivate\r\n * @prop {{ slide: Slide }} slideDeactivate\r\n * @prop {{ slide: Slide }} slideDestroy\r\n * @prop {{ destZoomLevel: number, centerPoint: Point | undefined, transitionDuration: number | false | undefined }} beforeZoomTo\r\n * @prop {{ slide: Slide }} zoomPanUpdate\r\n * @prop {{ slide: Slide }} initialZoomPan\r\n * @prop {{ slide: Slide }} calcSlideSize\r\n * @prop {undefined} resolutionChanged\r\n * @prop {{ originalEvent: WheelEvent }} wheel can be default prevented\r\n * @prop {{ content: Content }} contentAppendImage can be default prevented\r\n * @prop {{ index: number; itemData: SlideData }} lazyLoadSlide can be default prevented\r\n * @prop {undefined} lazyLoad\r\n * @prop {{ slide: Slide }} calcBounds\r\n * @prop {{ zoomLevels: ZoomLevel, slideData: SlideData }} zoomLevelsUpdate\r\n *\r\n *\r\n * legacy\r\n *\r\n * @prop {undefined} init\r\n * @prop {undefined} initialZoomIn\r\n * @prop {undefined} initialZoomOut\r\n * @prop {undefined} initialZoomInEnd\r\n * @prop {undefined} initialZoomOutEnd\r\n * @prop {{ dataSource: DataSource | undefined, numItems: number }} numItems\r\n * @prop {{ itemData: SlideData; index: number }} itemData\r\n * @prop {{ index: number, itemData: SlideData, instance: PhotoSwipe }} thumbBounds\r\n */\r\n\r\n/**\r\n * @typedef {Object} PhotoSwipeFiltersMap https://photoswipe.com/filters/\r\n *\r\n * @prop {(numItems: number, dataSource: DataSource | undefined) => number} numItems\r\n * Modify the total amount of slides. Example on Data sources page.\r\n * https://photoswipe.com/filters/#numitems\r\n *\r\n * @prop {(itemData: SlideData, index: number) => SlideData} itemData\r\n * Modify slide item data. Example on Data sources page.\r\n * https://photoswipe.com/filters/#itemdata\r\n *\r\n * @prop {(itemData: SlideData, element: HTMLElement, linkEl: HTMLAnchorElement) => SlideData} domItemData\r\n * Modify item data when it's parsed from DOM element. Example on Data sources page.\r\n * https://photoswipe.com/filters/#domitemdata\r\n *\r\n * @prop {(clickedIndex: number, e: MouseEvent, instance: PhotoSwipeLightbox) => number} clickedIndex\r\n * Modify clicked gallery item index.\r\n * https://photoswipe.com/filters/#clickedindex\r\n *\r\n * @prop {(placeholderSrc: string | false, content: Content) => string | false} placeholderSrc\r\n * Modify placeholder image source.\r\n * https://photoswipe.com/filters/#placeholdersrc\r\n *\r\n * @prop {(isContentLoading: boolean, content: Content) => boolean} isContentLoading\r\n * Modify if the content is currently loading.\r\n * https://photoswipe.com/filters/#iscontentloading\r\n *\r\n * @prop {(isContentZoomable: boolean, content: Content) => boolean} isContentZoomable\r\n * Modify if the content can be zoomed.\r\n * https://photoswipe.com/filters/#iscontentzoomable\r\n *\r\n * @prop {(useContentPlaceholder: boolean, content: Content) => boolean} useContentPlaceholder\r\n * Modify if the placeholder should be used for the content.\r\n * https://photoswipe.com/filters/#usecontentplaceholder\r\n *\r\n * @prop {(isKeepingPlaceholder: boolean, content: Content) => boolean} isKeepingPlaceholder\r\n * Modify if the placeholder should be kept after the content is loaded.\r\n * https://photoswipe.com/filters/#iskeepingplaceholder\r\n *\r\n *\r\n * @prop {(contentErrorElement: HTMLElement, content: Content) => HTMLElement} contentErrorElement\r\n * Modify an element when the content has error state (for example, if image cannot be loaded).\r\n * https://photoswipe.com/filters/#contenterrorelement\r\n *\r\n * @prop {(element: HTMLElement, data: UIElementData) => HTMLElement} uiElement\r\n * Modify a UI element that's being created.\r\n * https://photoswipe.com/filters/#uielement\r\n *\r\n * @prop {(thumbnail: HTMLElement | null | undefined, itemData: SlideData, index: number) => HTMLElement} thumbEl\r\n * Modify the thumbnail element from which opening zoom animation starts or ends.\r\n * https://photoswipe.com/filters/#thumbel\r\n *\r\n * @prop {(thumbBounds: Bounds | undefined, itemData: SlideData, index: number) => Bounds} thumbBounds\r\n * Modify the thumbnail bounds from which opening zoom animation starts or ends.\r\n * https://photoswipe.com/filters/#thumbbounds\r\n *\r\n * @prop {(srcsetSizesWidth: number, content: Content) => number} srcsetSizesWidth\r\n *\r\n * @prop {(preventPointerEvent: boolean, event: PointerEvent, pointerType: string) => boolean} preventPointerEvent\r\n *\r\n */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @typedef {{ fn: PhotoSwipeFiltersMap[T], priority: number }} Filter\r\n */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {PhotoSwipeEventsMap[T] extends undefined ? PhotoSwipeEvent : PhotoSwipeEvent & PhotoSwipeEventsMap[T]} AugmentedEvent\r\n */\r\n\r\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {(event: AugmentedEvent) => void} EventCallback\r\n */\r\n\r\n/**\r\n * Base PhotoSwipe event object\r\n *\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n */\r\nclass PhotoSwipeEvent {\r\n /**\r\n * @param {T} type\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n */\r\n constructor(type, details) {\r\n this.type = type;\r\n this.defaultPrevented = false;\r\n if (details) {\r\n Object.assign(this, details);\r\n }\r\n }\r\n\r\n preventDefault() {\r\n this.defaultPrevented = true;\r\n }\r\n}\r\n\r\n/**\r\n * PhotoSwipe base class that can listen and dispatch for events.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox, extended by base.js\r\n */\r\nclass Eventable {\r\n constructor() {\r\n /**\r\n * @type {{ [T in keyof PhotoSwipeEventsMap]?: ((event: AugmentedEvent) => void)[] }}\r\n */\r\n this._listeners = {};\r\n\r\n /**\r\n * @type {{ [T in keyof PhotoSwipeFiltersMap]?: Filter[] }}\r\n */\r\n this._filters = {};\r\n\r\n /** @type {PhotoSwipe | undefined} */\r\n this.pswp = undefined;\r\n\r\n /** @type {PhotoSwipeOptions | undefined} */\r\n this.options = undefined;\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeFiltersMap[T]} fn\r\n * @param {number} priority\r\n */\r\n addFilter(name, fn, priority = 100) {\r\n if (!this._filters[name]) {\r\n this._filters[name] = [];\r\n }\r\n\r\n this._filters[name]?.push({ fn, priority });\r\n this._filters[name]?.sort((f1, f2) => f1.priority - f2.priority);\r\n\r\n this.pswp?.addFilter(name, fn, priority);\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeFiltersMap[T]} fn\r\n */\r\n removeFilter(name, fn) {\r\n if (this._filters[name]) {\r\n // @ts-expect-error\r\n this._filters[name] = this._filters[name].filter(filter => (filter.fn !== fn));\r\n }\r\n\r\n if (this.pswp) {\r\n this.pswp.removeFilter(name, fn);\r\n }\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @param {T} name\r\n * @param {Parameters} args\r\n * @returns {Parameters[0]}\r\n */\r\n applyFilters(name, ...args) {\r\n this._filters[name]?.forEach((filter) => {\r\n // @ts-expect-error\r\n args[0] = filter.fn.apply(this, args);\r\n });\r\n return args[0];\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */\r\n on(name, fn) {\r\n if (!this._listeners[name]) {\r\n this._listeners[name] = [];\r\n }\r\n this._listeners[name]?.push(fn);\r\n\r\n // When binding events to lightbox,\r\n // also bind events to PhotoSwipe Core,\r\n // if it's open.\r\n this.pswp?.on(name, fn);\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */\r\n off(name, fn) {\r\n if (this._listeners[name]) {\r\n // @ts-expect-error\r\n this._listeners[name] = this._listeners[name].filter(listener => (fn !== listener));\r\n }\r\n\r\n this.pswp?.off(name, fn);\r\n }\r\n\r\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n * @returns {AugmentedEvent}\r\n */\r\n dispatch(name, details) {\r\n if (this.pswp) {\r\n return this.pswp.dispatch(name, details);\r\n }\r\n\r\n const event = /** @type {AugmentedEvent} */ (new PhotoSwipeEvent(name, details));\r\n\r\n this._listeners[name]?.forEach((listener) => {\r\n listener.call(this, event);\r\n });\r\n\r\n return event;\r\n }\r\n}\r\n\r\nexport default Eventable;\r\n","import { createElement, isSafari, LOAD_STATE, setWidthHeight } from '../util/util.js';\r\nimport Placeholder from './placeholder.js';\r\n\r\n/** @typedef {import('./slide.js').default} Slide */\r\n/** @typedef {import('./slide.js').SlideData} SlideData */\r\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\r\n/** @typedef {import('../util/util.js').LoadState} LoadState */\r\n\r\nclass Content {\r\n /**\r\n * @param {SlideData} itemData Slide data\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox instance\r\n * @param {number} index\r\n */\r\n constructor(itemData, instance, index) {\r\n this.instance = instance;\r\n this.data = itemData;\r\n this.index = index;\r\n\r\n /** @type {HTMLImageElement | HTMLDivElement | undefined} */\r\n this.element = undefined;\r\n /** @type {Placeholder | undefined} */\r\n this.placeholder = undefined;\r\n /** @type {Slide | undefined} */\r\n this.slide = undefined;\r\n\r\n this.displayedImageWidth = 0;\r\n this.displayedImageHeight = 0;\r\n\r\n this.width = Number(this.data.w) || Number(this.data.width) || 0;\r\n this.height = Number(this.data.h) || Number(this.data.height) || 0;\r\n\r\n this.isAttached = false;\r\n this.hasSlide = false;\r\n this.isDecoding = false;\r\n /** @type {LoadState} */\r\n this.state = LOAD_STATE.IDLE;\r\n\r\n if (this.data.type) {\r\n this.type = this.data.type;\r\n } else if (this.data.src) {\r\n this.type = 'image';\r\n } else {\r\n this.type = 'html';\r\n }\r\n\r\n this.instance.dispatch('contentInit', { content: this });\r\n }\r\n\r\n removePlaceholder() {\r\n if (this.placeholder && !this.keepPlaceholder()) {\r\n // With delay, as image might be loaded, but not rendered\r\n setTimeout(() => {\r\n if (this.placeholder) {\r\n this.placeholder.destroy();\r\n this.placeholder = undefined;\r\n }\r\n }, 1000);\r\n }\r\n }\r\n\r\n /**\r\n * Preload content\r\n *\r\n * @param {boolean} isLazy\r\n * @param {boolean} [reload]\r\n */\r\n load(isLazy, reload) {\r\n if (this.slide && this.usePlaceholder()) {\r\n if (!this.placeholder) {\r\n const placeholderSrc = this.instance.applyFilters(\r\n 'placeholderSrc',\r\n // use image-based placeholder only for the first slide,\r\n // as rendering (even small stretched thumbnail) is an expensive operation\r\n (this.data.msrc && this.slide.isFirstSlide) ? this.data.msrc : false,\r\n this\r\n );\r\n this.placeholder = new Placeholder(\r\n placeholderSrc,\r\n this.slide.container\r\n );\r\n } else {\r\n const placeholderEl = this.placeholder.element;\r\n // Add placeholder to DOM if it was already created\r\n if (placeholderEl && !placeholderEl.parentElement) {\r\n this.slide.container.prepend(placeholderEl);\r\n }\r\n }\r\n }\r\n\r\n if (this.element && !reload) {\r\n return;\r\n }\r\n\r\n if (this.instance.dispatch('contentLoad', { content: this, isLazy }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (this.isImageContent()) {\r\n this.element = createElement('pswp__img', 'img');\r\n // Start loading only after width is defined, as sizes might depend on it.\r\n // Due to Safari feature, we must define sizes before srcset.\r\n if (this.displayedImageWidth) {\r\n this.loadImage(isLazy);\r\n }\r\n } else {\r\n this.element = createElement('pswp__content', 'div');\r\n this.element.innerHTML = this.data.html || '';\r\n }\r\n\r\n if (reload && this.slide) {\r\n this.slide.updateContentSize(true);\r\n }\r\n }\r\n\r\n /**\r\n * Preload image\r\n *\r\n * @param {boolean} isLazy\r\n */\r\n loadImage(isLazy) {\r\n if (!this.isImageContent()\r\n || !this.element\r\n || this.instance.dispatch('contentLoadImage', { content: this, isLazy }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n const imageElement = /** @type HTMLImageElement */ (this.element);\r\n\r\n this.updateSrcsetSizes();\r\n\r\n if (this.data.srcset) {\r\n imageElement.srcset = this.data.srcset;\r\n }\r\n\r\n imageElement.src = this.data.src ?? '';\r\n imageElement.alt = this.data.alt ?? '';\r\n\r\n this.state = LOAD_STATE.LOADING;\r\n\r\n if (imageElement.complete) {\r\n this.onLoaded();\r\n } else {\r\n imageElement.onload = () => {\r\n this.onLoaded();\r\n };\r\n\r\n imageElement.onerror = () => {\r\n this.onError();\r\n };\r\n }\r\n }\r\n\r\n /**\r\n * Assign slide to content\r\n *\r\n * @param {Slide} slide\r\n */\r\n setSlide(slide) {\r\n this.slide = slide;\r\n this.hasSlide = true;\r\n this.instance = slide.pswp;\r\n\r\n // todo: do we need to unset slide?\r\n }\r\n\r\n /**\r\n * Content load success handler\r\n */\r\n onLoaded() {\r\n this.state = LOAD_STATE.LOADED;\r\n\r\n if (this.slide && this.element) {\r\n this.instance.dispatch('loadComplete', { slide: this.slide, content: this });\r\n\r\n // if content is reloaded\r\n if (this.slide.isActive\r\n && this.slide.heavyAppended\r\n && !this.element.parentNode) {\r\n this.append();\r\n this.slide.updateContentSize(true);\r\n }\r\n\r\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\r\n this.removePlaceholder();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Content load error handler\r\n */\r\n onError() {\r\n this.state = LOAD_STATE.ERROR;\r\n\r\n if (this.slide) {\r\n this.displayError();\r\n this.instance.dispatch('loadComplete', { slide: this.slide, isError: true, content: this });\r\n this.instance.dispatch('loadError', { slide: this.slide, content: this });\r\n }\r\n }\r\n\r\n /**\r\n * @returns {Boolean} If the content is currently loading\r\n */\r\n isLoading() {\r\n return this.instance.applyFilters(\r\n 'isContentLoading',\r\n this.state === LOAD_STATE.LOADING,\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * @returns {Boolean} If the content is in error state\r\n */\r\n isError() {\r\n return this.state === LOAD_STATE.ERROR;\r\n }\r\n\r\n /**\r\n * @returns {boolean} If the content is image\r\n */\r\n isImageContent() {\r\n return this.type === 'image';\r\n }\r\n\r\n /**\r\n * Update content size\r\n *\r\n * @param {Number} width\r\n * @param {Number} height\r\n */\r\n setDisplayedSize(width, height) {\r\n if (!this.element) {\r\n return;\r\n }\r\n\r\n if (this.placeholder) {\r\n this.placeholder.setDisplayedSize(width, height);\r\n }\r\n\r\n if (this.instance.dispatch(\r\n 'contentResize',\r\n { content: this, width, height }).defaultPrevented\r\n ) {\r\n return;\r\n }\r\n\r\n setWidthHeight(this.element, width, height);\r\n\r\n if (this.isImageContent() && !this.isError()) {\r\n const isInitialSizeUpdate = (!this.displayedImageWidth && width);\r\n\r\n this.displayedImageWidth = width;\r\n this.displayedImageHeight = height;\r\n\r\n if (isInitialSizeUpdate) {\r\n this.loadImage(false);\r\n } else {\r\n this.updateSrcsetSizes();\r\n }\r\n\r\n if (this.slide) {\r\n this.instance.dispatch(\r\n 'imageSizeChange',\r\n { slide: this.slide, width, height, content: this }\r\n );\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @returns {boolean} If the content can be zoomed\r\n */\r\n isZoomable() {\r\n return this.instance.applyFilters(\r\n 'isContentZoomable',\r\n this.isImageContent() && (this.state !== LOAD_STATE.ERROR),\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * Update image srcset sizes attribute based on width and height\r\n */\r\n updateSrcsetSizes() {\r\n // Handle srcset sizes attribute.\r\n //\r\n // Never lower quality, if it was increased previously.\r\n // Chrome does this automatically, Firefox and Safari do not,\r\n // so we store largest used size in dataset.\r\n if (!this.isImageContent() || !this.element || !this.data.srcset) {\r\n return;\r\n }\r\n\r\n const image = /** @type HTMLImageElement */ (this.element);\r\n const sizesWidth = this.instance.applyFilters(\r\n 'srcsetSizesWidth',\r\n this.displayedImageWidth,\r\n this\r\n );\r\n\r\n if (\r\n !image.dataset.largestUsedSize\r\n || sizesWidth > parseInt(image.dataset.largestUsedSize, 10)\r\n ) {\r\n image.sizes = sizesWidth + 'px';\r\n image.dataset.largestUsedSize = String(sizesWidth);\r\n }\r\n }\r\n\r\n /**\r\n * @returns {boolean} If content should use a placeholder (from msrc by default)\r\n */\r\n usePlaceholder() {\r\n return this.instance.applyFilters(\r\n 'useContentPlaceholder',\r\n this.isImageContent(),\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * Preload content with lazy-loading param\r\n */\r\n lazyLoad() {\r\n if (this.instance.dispatch('contentLazyLoad', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n this.load(true);\r\n }\r\n\r\n /**\r\n * @returns {boolean} If placeholder should be kept after content is loaded\r\n */\r\n keepPlaceholder() {\r\n return this.instance.applyFilters(\r\n 'isKeepingPlaceholder',\r\n this.isLoading(),\r\n this\r\n );\r\n }\r\n\r\n /**\r\n * Destroy the content\r\n */\r\n destroy() {\r\n this.hasSlide = false;\r\n this.slide = undefined;\r\n\r\n if (this.instance.dispatch('contentDestroy', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n this.remove();\r\n\r\n if (this.placeholder) {\r\n this.placeholder.destroy();\r\n this.placeholder = undefined;\r\n }\r\n\r\n if (this.isImageContent() && this.element) {\r\n this.element.onload = null;\r\n this.element.onerror = null;\r\n this.element = undefined;\r\n }\r\n }\r\n\r\n /**\r\n * Display error message\r\n */\r\n displayError() {\r\n if (this.slide) {\r\n let errorMsgEl = createElement('pswp__error-msg', 'div');\r\n errorMsgEl.innerText = this.instance.options?.errorMsg ?? '';\r\n errorMsgEl = /** @type {HTMLDivElement} */ (this.instance.applyFilters(\r\n 'contentErrorElement',\r\n errorMsgEl,\r\n this\r\n ));\r\n this.element = createElement('pswp__content pswp__error-msg-container', 'div');\r\n this.element.appendChild(errorMsgEl);\r\n this.slide.container.innerText = '';\r\n this.slide.container.appendChild(this.element);\r\n this.slide.updateContentSize(true);\r\n this.removePlaceholder();\r\n }\r\n }\r\n\r\n /**\r\n * Append the content\r\n */\r\n append() {\r\n if (this.isAttached || !this.element) {\r\n return;\r\n }\r\n\r\n this.isAttached = true;\r\n\r\n if (this.state === LOAD_STATE.ERROR) {\r\n this.displayError();\r\n return;\r\n }\r\n\r\n if (this.instance.dispatch('contentAppend', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n const supportsDecode = ('decode' in this.element);\r\n\r\n if (this.isImageContent()) {\r\n // Use decode() on nearby slides\r\n //\r\n // Nearby slide images are in DOM and not hidden via display:none.\r\n // However, they are placed offscreen (to the left and right side).\r\n //\r\n // Some browsers do not composite the image until it's actually visible,\r\n // using decode() helps.\r\n //\r\n // You might ask \"why dont you just decode() and then append all images\",\r\n // that's because I want to show image before it's fully loaded,\r\n // as browser can render parts of image while it is loading.\r\n // We do not do this in Safari due to partial loading bug.\r\n if (supportsDecode && this.slide && (!this.slide.isActive || isSafari())) {\r\n this.isDecoding = true;\r\n // purposefully using finally instead of then,\r\n // as if srcset sizes changes dynamically - it may cause decode error\r\n /** @type {HTMLImageElement} */\r\n (this.element).decode().catch(() => {}).finally(() => {\r\n this.isDecoding = false;\r\n this.appendImage();\r\n });\r\n } else {\r\n this.appendImage();\r\n }\r\n } else if (this.slide && !this.element.parentNode) {\r\n this.slide.container.appendChild(this.element);\r\n }\r\n }\r\n\r\n /**\r\n * Activate the slide,\r\n * active slide is generally the current one,\r\n * meaning the user can see it.\r\n */\r\n activate() {\r\n if (this.instance.dispatch('contentActivate', { content: this }).defaultPrevented\r\n || !this.slide) {\r\n return;\r\n }\r\n\r\n if (this.isImageContent() && this.isDecoding && !isSafari()) {\r\n // add image to slide when it becomes active,\r\n // even if it's not finished decoding\r\n this.appendImage();\r\n } else if (this.isError()) {\r\n this.load(false, true); // try to reload\r\n }\r\n\r\n if (this.slide.holderElement) {\r\n this.slide.holderElement.setAttribute('aria-hidden', 'false');\r\n }\r\n }\r\n\r\n /**\r\n * Deactivate the content\r\n */\r\n deactivate() {\r\n this.instance.dispatch('contentDeactivate', { content: this });\r\n if (this.slide && this.slide.holderElement) {\r\n this.slide.holderElement.setAttribute('aria-hidden', 'true');\r\n }\r\n }\r\n\r\n\r\n /**\r\n * Remove the content from DOM\r\n */\r\n remove() {\r\n this.isAttached = false;\r\n\r\n if (this.instance.dispatch('contentRemove', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n if (this.element && this.element.parentNode) {\r\n this.element.remove();\r\n }\r\n\r\n if (this.placeholder && this.placeholder.element) {\r\n this.placeholder.element.remove();\r\n }\r\n }\r\n\r\n /**\r\n * Append the image content to slide container\r\n */\r\n appendImage() {\r\n if (!this.isAttached) {\r\n return;\r\n }\r\n\r\n if (this.instance.dispatch('contentAppendImage', { content: this }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n // ensure that element exists and is not already appended\r\n if (this.slide && this.element && !this.element.parentNode) {\r\n this.slide.container.appendChild(this.element);\r\n }\r\n\r\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\r\n this.removePlaceholder();\r\n }\r\n }\r\n}\r\n\r\nexport default Content;\r\n","import { createElement, setWidthHeight, toTransformString } from '../util/util.js';\r\n\r\nclass Placeholder {\r\n /**\r\n * @param {string | false} imageSrc\r\n * @param {HTMLElement} container\r\n */\r\n constructor(imageSrc, container) {\r\n // Create placeholder\r\n // (stretched thumbnail or simple div behind the main image)\r\n /** @type {HTMLImageElement | HTMLDivElement | null} */\r\n this.element = createElement(\r\n 'pswp__img pswp__img--placeholder',\r\n imageSrc ? 'img' : 'div',\r\n container\r\n );\r\n\r\n if (imageSrc) {\r\n const imgEl = /** @type {HTMLImageElement} */ (this.element);\r\n imgEl.decoding = 'async';\r\n imgEl.alt = '';\r\n imgEl.src = imageSrc;\r\n imgEl.setAttribute('role', 'presentation');\r\n }\r\n\r\n this.element.setAttribute('aria-hidden', 'true');\r\n }\r\n\r\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */\r\n setDisplayedSize(width, height) {\r\n if (!this.element) {\r\n return;\r\n }\r\n\r\n if (this.element.tagName === 'IMG') {\r\n // Use transform scale() to modify img placeholder size\r\n // (instead of changing width/height directly).\r\n // This helps with performance, specifically in iOS15 Safari.\r\n setWidthHeight(this.element, 250, 'auto');\r\n this.element.style.transformOrigin = '0 0';\r\n this.element.style.transform = toTransformString(0, 0, width / 250);\r\n } else {\r\n setWidthHeight(this.element, width, height);\r\n }\r\n }\r\n\r\n destroy() {\r\n if (this.element?.parentNode) {\r\n this.element.remove();\r\n }\r\n this.element = null;\r\n }\r\n}\r\n\r\nexport default Placeholder;\r\n","import { getViewportSize, getPanAreaSize } from '../util/viewport-size.js';\r\nimport ZoomLevel from './zoom-level.js';\r\n\r\n/** @typedef {import('./content.js').default} Content */\r\n/** @typedef {import('./slide.js').default} Slide */\r\n/** @typedef {import('./slide.js').SlideData} SlideData */\r\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n\r\nconst MIN_SLIDES_TO_CACHE = 5;\r\n\r\n/**\r\n * Lazy-load an image\r\n * This function is used both by Lightbox and PhotoSwipe core,\r\n * thus it can be called before dialog is opened.\r\n *\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox instance\r\n * @param {number} index\r\n * @returns {Content} Image that is being decoded or false.\r\n */\r\nexport function lazyLoadData(itemData, instance, index) {\r\n const content = instance.createContentFromData(itemData, index);\r\n /** @type {ZoomLevel | undefined} */\r\n let zoomLevel;\r\n\r\n const { options } = instance;\r\n\r\n // We need to know dimensions of the image to preload it,\r\n // as it might use srcset, and we need to define sizes\r\n if (options) {\r\n zoomLevel = new ZoomLevel(options, itemData, -1);\r\n\r\n let viewportSize;\r\n if (instance.pswp) {\r\n viewportSize = instance.pswp.viewportSize;\r\n } else {\r\n viewportSize = getViewportSize(options, instance);\r\n }\r\n\r\n const panAreaSize = getPanAreaSize(options, viewportSize, itemData, index);\r\n zoomLevel.update(content.width, content.height, panAreaSize);\r\n }\r\n\r\n content.lazyLoad();\r\n\r\n if (zoomLevel) {\r\n content.setDisplayedSize(\r\n Math.ceil(content.width * zoomLevel.initial),\r\n Math.ceil(content.height * zoomLevel.initial)\r\n );\r\n }\r\n\r\n return content;\r\n}\r\n\r\n\r\n/**\r\n * Lazy-loads specific slide.\r\n * This function is used both by Lightbox and PhotoSwipe core,\r\n * thus it can be called before dialog is opened.\r\n *\r\n * By default, it loads image based on viewport size and initial zoom level.\r\n *\r\n * @param {number} index Slide index\r\n * @param {PhotoSwipeBase} instance PhotoSwipe or PhotoSwipeLightbox eventable instance\r\n * @returns {Content | undefined}\r\n */\r\nexport function lazyLoadSlide(index, instance) {\r\n const itemData = instance.getItemData(index);\r\n\r\n if (instance.dispatch('lazyLoadSlide', { index, itemData }).defaultPrevented) {\r\n return;\r\n }\r\n\r\n return lazyLoadData(itemData, instance, index);\r\n}\r\n\r\nclass ContentLoader {\r\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\r\n constructor(pswp) {\r\n this.pswp = pswp;\r\n // Total amount of cached images\r\n this.limit = Math.max(\r\n pswp.options.preload[0] + pswp.options.preload[1] + 1,\r\n MIN_SLIDES_TO_CACHE\r\n );\r\n /** @type {Content[]} */\r\n this._cachedItems = [];\r\n }\r\n\r\n /**\r\n * Lazy load nearby slides based on `preload` option.\r\n *\r\n * @param {number} [diff] Difference between slide indexes that was changed recently, or 0.\r\n */\r\n updateLazy(diff) {\r\n const { pswp } = this;\r\n\r\n if (pswp.dispatch('lazyLoad').defaultPrevented) {\r\n return;\r\n }\r\n\r\n const { preload } = pswp.options;\r\n const isForward = diff === undefined ? true : (diff >= 0);\r\n let i;\r\n\r\n // preload[1] - num items to preload in forward direction\r\n for (i = 0; i <= preload[1]; i++) {\r\n this.loadSlideByIndex(pswp.currIndex + (isForward ? i : (-i)));\r\n }\r\n\r\n // preload[0] - num items to preload in backward direction\r\n for (i = 1; i <= preload[0]; i++) {\r\n this.loadSlideByIndex(pswp.currIndex + (isForward ? (-i) : i));\r\n }\r\n }\r\n\r\n /**\r\n * @param {number} initialIndex\r\n */\r\n loadSlideByIndex(initialIndex) {\r\n const index = this.pswp.getLoopedIndex(initialIndex);\r\n // try to get cached content\r\n let content = this.getContentByIndex(index);\r\n if (!content) {\r\n // no cached content, so try to load from scratch:\r\n content = lazyLoadSlide(index, this.pswp);\r\n // if content can be loaded, add it to cache:\r\n if (content) {\r\n this.addToCache(content);\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * @param {Slide} slide\r\n * @returns {Content}\r\n */\r\n getContentBySlide(slide) {\r\n let content = this.getContentByIndex(slide.index);\r\n if (!content) {\r\n // create content if not found in cache\r\n content = this.pswp.createContentFromData(slide.data, slide.index);\r\n this.addToCache(content);\r\n }\r\n\r\n // assign slide to content\r\n content.setSlide(slide);\r\n\r\n return content;\r\n }\r\n\r\n /**\r\n * @param {Content} content\r\n */\r\n addToCache(content) {\r\n // move to the end of array\r\n this.removeByIndex(content.index);\r\n this._cachedItems.push(content);\r\n\r\n if (this._cachedItems.length > this.limit) {\r\n // Destroy the first content that's not attached\r\n const indexToRemove = this._cachedItems.findIndex((item) => {\r\n return !item.isAttached && !item.hasSlide;\r\n });\r\n if (indexToRemove !== -1) {\r\n const removedItem = this._cachedItems.splice(indexToRemove, 1)[0];\r\n removedItem.destroy();\r\n }\r\n }\r\n }\r\n\r\n /**\r\n * Removes an image from cache, does not destroy() it, just removes.\r\n *\r\n * @param {number} index\r\n */\r\n removeByIndex(index) {\r\n const indexToRemove = this._cachedItems.findIndex(item => item.index === index);\r\n if (indexToRemove !== -1) {\r\n this._cachedItems.splice(indexToRemove, 1);\r\n }\r\n }\r\n\r\n /**\r\n * @param {number} index\r\n * @returns {Content | undefined}\r\n */\r\n getContentByIndex(index) {\r\n return this._cachedItems.find(content => content.index === index);\r\n }\r\n\r\n destroy() {\r\n this._cachedItems.forEach(content => content.destroy());\r\n this._cachedItems = [];\r\n }\r\n}\r\n\r\nexport default ContentLoader;\r\n","/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\r\n\r\n/**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {PhotoSwipeBase} pswp\r\n * @returns {Point}\r\n */\r\nexport function getViewportSize(options, pswp) {\r\n if (options.getViewportSizeFn) {\r\n const newViewportSize = options.getViewportSizeFn(options, pswp);\r\n if (newViewportSize) {\r\n return newViewportSize;\r\n }\r\n }\r\n\r\n return {\r\n x: document.documentElement.clientWidth,\r\n\r\n // TODO: height on mobile is very incosistent due to toolbar\r\n // find a way to improve this\r\n //\r\n // document.documentElement.clientHeight - doesn't seem to work well\r\n y: window.innerHeight\r\n };\r\n}\r\n\r\n/**\r\n * Parses padding option.\r\n * Supported formats:\r\n *\r\n * // Object\r\n * padding: {\r\n * top: 0,\r\n * bottom: 0,\r\n * left: 0,\r\n * right: 0\r\n * }\r\n *\r\n * // A function that returns the object\r\n * paddingFn: (viewportSize, itemData, index) => {\r\n * return {\r\n * top: 0,\r\n * bottom: 0,\r\n * left: 0,\r\n * right: 0\r\n * };\r\n * }\r\n *\r\n * // Legacy variant\r\n * paddingLeft: 0,\r\n * paddingRight: 0,\r\n * paddingTop: 0,\r\n * paddingBottom: 0,\r\n *\r\n * @param {'left' | 'top' | 'bottom' | 'right'} prop\r\n * @param {PhotoSwipeOptions} options PhotoSwipe options\r\n * @param {Point} viewportSize PhotoSwipe viewport size, for example: { x:800, y:600 }\r\n * @param {SlideData} itemData Data about the slide\r\n * @param {number} index Slide index\r\n * @returns {number}\r\n */\r\nexport function parsePaddingOption(prop, options, viewportSize, itemData, index) {\r\n let paddingValue = 0;\r\n\r\n if (options.paddingFn) {\r\n paddingValue = options.paddingFn(viewportSize, itemData, index)[prop];\r\n } else if (options.padding) {\r\n paddingValue = options.padding[prop];\r\n } else {\r\n const legacyPropName = 'padding' + prop[0].toUpperCase() + prop.slice(1);\r\n // @ts-expect-error\r\n if (options[legacyPropName]) {\r\n // @ts-expect-error\r\n paddingValue = options[legacyPropName];\r\n }\r\n }\r\n\r\n return Number(paddingValue) || 0;\r\n}\r\n\r\n/**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {Point} viewportSize\r\n * @param {SlideData} itemData\r\n * @param {number} index\r\n * @returns {Point}\r\n */\r\nexport function getPanAreaSize(options, viewportSize, itemData, index) {\r\n return {\r\n x: viewportSize.x\r\n - parsePaddingOption('left', options, viewportSize, itemData, index)\r\n - parsePaddingOption('right', options, viewportSize, itemData, index),\r\n y: viewportSize.y\r\n - parsePaddingOption('top', options, viewportSize, itemData, index)\r\n - parsePaddingOption('bottom', options, viewportSize, itemData, index)\r\n };\r\n}\r\n","const MAX_IMAGE_WIDTH = 4000;\r\n\r\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\r\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\r\n/** @typedef {import('../photoswipe.js').Point} Point */\r\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\r\n\r\n/** @typedef {'fit' | 'fill' | number | ((zoomLevelObject: ZoomLevel) => number)} ZoomLevelOption */\r\n\r\n/**\r\n * Calculates zoom levels for specific slide.\r\n * Depends on viewport size and image size.\r\n */\r\nclass ZoomLevel {\r\n /**\r\n * @param {PhotoSwipeOptions} options PhotoSwipe options\r\n * @param {SlideData} itemData Slide data\r\n * @param {number} index Slide index\r\n * @param {PhotoSwipe} [pswp] PhotoSwipe instance, can be undefined if not initialized yet\r\n */\r\n constructor(options, itemData, index, pswp) {\r\n this.pswp = pswp;\r\n this.options = options;\r\n this.itemData = itemData;\r\n this.index = index;\r\n /** @type { Point | null } */\r\n this.panAreaSize = null;\r\n /** @type { Point | null } */\r\n this.elementSize = null;\r\n this.fit = 1;\r\n this.fill = 1;\r\n this.vFill = 1;\r\n this.initial = 1;\r\n this.secondary = 1;\r\n this.max = 1;\r\n this.min = 1;\r\n }\r\n\r\n /**\r\n * Calculate initial, secondary and maximum zoom level for the specified slide.\r\n *\r\n * It should be called when either image or viewport size changes.\r\n *\r\n * @param {number} maxWidth\r\n * @param {number} maxHeight\r\n * @param {Point} panAreaSize\r\n */\r\n update(maxWidth, maxHeight, panAreaSize) {\r\n /** @type {Point} */\r\n const elementSize = { x: maxWidth, y: maxHeight };\r\n this.elementSize = elementSize;\r\n this.panAreaSize = panAreaSize;\r\n\r\n const hRatio = panAreaSize.x / elementSize.x;\r\n const vRatio = panAreaSize.y / elementSize.y;\r\n\r\n this.fit = Math.min(1, hRatio < vRatio ? hRatio : vRatio);\r\n this.fill = Math.min(1, hRatio > vRatio ? hRatio : vRatio);\r\n\r\n // zoom.vFill defines zoom level of the image\r\n // when it has 100% of viewport vertical space (height)\r\n this.vFill = Math.min(1, vRatio);\r\n\r\n this.initial = this._getInitial();\r\n this.secondary = this._getSecondary();\r\n this.max = Math.max(\r\n this.initial,\r\n this.secondary,\r\n this._getMax()\r\n );\r\n\r\n this.min = Math.min(\r\n this.fit,\r\n this.initial,\r\n this.secondary\r\n );\r\n\r\n if (this.pswp) {\r\n this.pswp.dispatch('zoomLevelsUpdate', { zoomLevels: this, slideData: this.itemData });\r\n }\r\n }\r\n\r\n /**\r\n * Parses user-defined zoom option.\r\n *\r\n * @private\r\n * @param {'initial' | 'secondary' | 'max'} optionPrefix Zoom level option prefix (initial, secondary, max)\r\n * @returns { number | undefined }\r\n */\r\n _parseZoomLevelOption(optionPrefix) {\r\n const optionName = /** @type {'initialZoomLevel' | 'secondaryZoomLevel' | 'maxZoomLevel'} */ (\r\n optionPrefix + 'ZoomLevel'\r\n );\r\n const optionValue = this.options[optionName];\r\n\r\n if (!optionValue) {\r\n return;\r\n }\r\n\r\n if (typeof optionValue === 'function') {\r\n return optionValue(this);\r\n }\r\n\r\n if (optionValue === 'fill') {\r\n return this.fill;\r\n }\r\n\r\n if (optionValue === 'fit') {\r\n return this.fit;\r\n }\r\n\r\n return Number(optionValue);\r\n }\r\n\r\n /**\r\n * Get zoom level to which image will be zoomed after double-tap gesture,\r\n * or when user clicks on zoom icon,\r\n * or mouse-click on image itself.\r\n * If you return 1 image will be zoomed to its original size.\r\n *\r\n * @private\r\n * @return {number}\r\n */\r\n _getSecondary() {\r\n let currZoomLevel = this._parseZoomLevelOption('secondary');\r\n\r\n if (currZoomLevel) {\r\n return currZoomLevel;\r\n }\r\n\r\n // 3x of \"fit\" state, but not larger than original\r\n currZoomLevel = Math.min(1, this.fit * 3);\r\n\r\n if (this.elementSize && currZoomLevel * this.elementSize.x > MAX_IMAGE_WIDTH) {\r\n currZoomLevel = MAX_IMAGE_WIDTH / this.elementSize.x;\r\n }\r\n\r\n return currZoomLevel;\r\n }\r\n\r\n /**\r\n * Get initial image zoom level.\r\n *\r\n * @private\r\n * @return {number}\r\n */\r\n _getInitial() {\r\n return this._parseZoomLevelOption('initial') || this.fit;\r\n }\r\n\r\n /**\r\n * Maximum zoom level when user zooms\r\n * via zoom/pinch gesture,\r\n * via cmd/ctrl-wheel or via trackpad.\r\n *\r\n * @private\r\n * @return {number}\r\n */\r\n _getMax() {\r\n // max zoom level is x4 from \"fit state\",\r\n // used for zoom gesture and ctrl/trackpad zoom\r\n return this._parseZoomLevelOption('max') || Math.max(1, this.fit * 4);\r\n }\r\n}\r\n\r\nexport default ZoomLevel;\r\n"],"names":["$parcel$export","e","n","v","s","Object","defineProperty","get","set","enumerable","configurable","$parcel$global","globalThis","$parcel$modules","$parcel$inits","parcelRequire","id","exports","init","module","call","err","Error","code","register","parcelRegister","$9pQ3o","default","$fe8a4ca7935abc37$export$c8a8987d4410bf2d","className","tagName","appendToEl","el","document","createElement","appendChild","$fe8a4ca7935abc37$export$9ebaeae2c52fdc4c","x","y","scale","propValue","undefined","$fe8a4ca7935abc37$export$9fc2289bf66bbc6a","w","h","style","width","height","$fe8a4ca7935abc37$export$c303146534fe0490","$fe8a4ca7935abc37$export$44619521c4b78f15","$fe8a4ca7935abc37$export$f900bd3a95fb7e3c","$fe8a4ca7935abc37$export$c923a85b9c2e680f","$fe8a4ca7935abc37$export$95df08bae54cb4df","IDLE","LOADING","LOADED","ERROR","button","ctrlKey","metaKey","altKey","shiftKey","option","legacySelector","parent","elements","Element","NodeList","Array","isArray","from","selector","querySelectorAll","fn","prototype","goTo","navigator","vendor","match","$6daed3a2f8f8bac9$export$2e2bcd8739ae039","$k2V0X","$lQUwv","$gGYae","$ho1E2","$6daed3a2f8f8bac9$var$PhotoSwipeBase","getNumItems","numItems","dataSource","options","length","items","_getGalleryDOMElements","gallery","event","dispatch","applyFilters","createContentFromData","slideData","index","getItemData","dataSourceItem","itemData","_domElementToItemData","galleryElement","children","childSelector","getElementsFromOption","element","linkEl","querySelector","src","dataset","pswpSrc","href","pswpSrcset","srcset","pswpWidth","parseInt","pswpHeight","pswpType","type","thumbnailEl","msrc","currentSrc","alt","getAttribute","pswpCropped","cropped","thumbCropped","lazyLoadData","$e980386d0a2b9ae1$export$2e2bcd8739ae039","$e980386d0a2b9ae1$var$PhotoSwipeEvent","constructor","details","defaultPrevented","assign","preventDefault","_listeners","_filters","pswp","addFilter","name","priority","push","sort","f1","f2","removeFilter","filter","args","forEach","apply","on","off","listener","$c26f3ce87e26857c$export$2e2bcd8739ae039","$9ZhPn","instance","data","placeholder","slide","displayedImageWidth","displayedImageHeight","Number","isAttached","hasSlide","isDecoding","state","LOAD_STATE","content","removePlaceholder","keepPlaceholder","setTimeout","destroy","load","isLazy","reload","usePlaceholder","placeholderEl","parentElement","container","prepend","placeholderSrc","isFirstSlide","isImageContent","loadImage","innerHTML","html","updateContentSize","imageElement","updateSrcsetSizes","complete","onLoaded","onload","onerror","onError","setSlide","isActive","heavyAppended","parentNode","append","displayError","isError","isLoading","setDisplayedSize","setWidthHeight","isInitialSizeUpdate","isZoomable","image","sizesWidth","largestUsedSize","sizes","String","lazyLoad","remove","errorMsgEl","innerText","errorMsg","supportsDecode","isSafari","decode","catch","finally","appendImage","activate","holderElement","setAttribute","deactivate","$7457a3c8d557c8bf$export$2e2bcd8739ae039","imageSrc","imgEl","decoding","transformOrigin","transform","toTransformString","$ca85f42b9f51fccd$export$8cd05fe15af4c448","$ca85f42b9f51fccd$export$917c0bc35382937a","$dsuOl","$gdKlE","zoomLevel","viewportSize","getViewportSize","panAreaSize","getPanAreaSize","update","Math","ceil","initial","$9cc5ca51babdeaaa$export$125915cfb610b3c2","getViewportSizeFn","newViewportSize","documentElement","clientWidth","window","innerHeight","$9cc5ca51babdeaaa$export$b09b17ae2adc409d","prop","paddingValue","paddingFn","padding","legacyPropName","toUpperCase","slice","$9cc5ca51babdeaaa$export$fe74fc76a188f696","$bcf1d005fb788dff$export$2e2bcd8739ae039","elementSize","fit","fill","vFill","secondary","max","min","maxWidth","maxHeight","hRatio","vRatio","_getInitial","_getSecondary","_getMax","zoomLevels","_parseZoomLevelOption","optionPrefix","optionValue","currZoomLevel","$bcf1d005fb788dff$var$MAX_IMAGE_WIDTH"],"version":3,"file":"_channel.b33e9a30.js.map"}