{"version":3,"file":"application-DMjCEK1z.js","sources":["../../../node_modules/file-saver/dist/FileSaver.min.js","../../../node_modules/photoswipe/dist/photoswipe.esm.js","../../../node_modules/photoswipe/dist/photoswipe-lightbox.esm.js","../../../node_modules/scroll-into-view/scrollIntoView.js","../../../app/javascript/javascript/justified-gallery.ts","../../../node_modules/waypoints/lib/noframework.waypoints.js","../../../app/javascript/javascript/waypoints-infinite.ts","../../../app/javascript/controllers/album-gallery-controller.ts","../../../app/javascript/controllers/home-feed-controller.ts","../../../app/javascript/entrypoints/application.ts"],"sourcesContent":["(function(a,b){if(\"function\"==typeof define&&define.amd)define([],b);else if(\"undefined\"!=typeof exports)b();else{b(),a.FileSaver={exports:{}}.exports}})(this,function(){\"use strict\";function b(a,b){return\"undefined\"==typeof b?b={autoBom:!1}:\"object\"!=typeof b&&(console.warn(\"Deprecated: Expected third argument to be a object\"),b={autoBom:!b}),b.autoBom&&/^\\s*(?:text\\/\\S*|application\\/xml|\\S*\\/\\S*\\+xml)\\s*;.*charset\\s*=\\s*utf-8/i.test(a.type)?new Blob([\"\\uFEFF\",a],{type:a.type}):a}function c(a,b,c){var d=new XMLHttpRequest;d.open(\"GET\",a),d.responseType=\"blob\",d.onload=function(){g(d.response,b,c)},d.onerror=function(){console.error(\"could not download file\")},d.send()}function d(a){var b=new XMLHttpRequest;b.open(\"HEAD\",a,!1);try{b.send()}catch(a){}return 200<=b.status&&299>=b.status}function e(a){try{a.dispatchEvent(new MouseEvent(\"click\"))}catch(c){var b=document.createEvent(\"MouseEvents\");b.initMouseEvent(\"click\",!0,!0,window,0,0,0,80,20,!1,!1,!1,!1,0,null),a.dispatchEvent(b)}}var f=\"object\"==typeof window&&window.window===window?window:\"object\"==typeof self&&self.self===self?self:\"object\"==typeof global&&global.global===global?global:void 0,a=f.navigator&&/Macintosh/.test(navigator.userAgent)&&/AppleWebKit/.test(navigator.userAgent)&&!/Safari/.test(navigator.userAgent),g=f.saveAs||(\"object\"!=typeof window||window!==f?function(){}:\"download\"in HTMLAnchorElement.prototype&&!a?function(b,g,h){var i=f.URL||f.webkitURL,j=document.createElement(\"a\");g=g||b.name||\"download\",j.download=g,j.rel=\"noopener\",\"string\"==typeof b?(j.href=b,j.origin===location.origin?e(j):d(j.href)?c(b,g,h):e(j,j.target=\"_blank\")):(j.href=i.createObjectURL(b),setTimeout(function(){i.revokeObjectURL(j.href)},4E4),setTimeout(function(){e(j)},0))}:\"msSaveOrOpenBlob\"in navigator?function(f,g,h){if(g=g||f.name||\"download\",\"string\"!=typeof f)navigator.msSaveOrOpenBlob(b(f,h),g);else if(d(f))c(f,g,h);else{var i=document.createElement(\"a\");i.href=f,i.target=\"_blank\",setTimeout(function(){e(i)})}}:function(b,d,e,g){if(g=g||open(\"\",\"_blank\"),g&&(g.document.title=g.document.body.innerText=\"downloading...\"),\"string\"==typeof b)return c(b,d,e);var h=\"application/octet-stream\"===b.type,i=/constructor/i.test(f.HTMLElement)||f.safari,j=/CriOS\\/[\\d]+/.test(navigator.userAgent);if((j||h&&i||a)&&\"undefined\"!=typeof FileReader){var k=new FileReader;k.onloadend=function(){var a=k.result;a=j?a:a.replace(/^data:[^;]*;/,\"data:attachment/file;\"),g?g.location.href=a:location=a,g=null},k.readAsDataURL(b)}else{var l=f.URL||f.webkitURL,m=l.createObjectURL(b);g?g.location=m:location.href=m,g=null,setTimeout(function(){l.revokeObjectURL(m)},4E4)}});f.saveAs=g.saveAs=g,\"undefined\"!=typeof module&&(module.exports=g)});\n\n//# sourceMappingURL=FileSaver.min.js.map","/*!\n * PhotoSwipe 5.4.4 - https://photoswipe.com\n * (c) 2024 Dmytro Semenov\n */\n/** @typedef {import('../photoswipe.js').Point} Point */\n\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 */\nfunction createElement(className, tagName, appendToEl) {\n const el = document.createElement(tagName);\n\n if (className) {\n el.className = className;\n }\n\n if (appendToEl) {\n appendToEl.appendChild(el);\n }\n\n return el;\n}\n/**\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {Point}\r\n */\n\nfunction equalizePoints(p1, p2) {\n p1.x = p2.x;\n p1.y = p2.y;\n\n if (p2.id !== undefined) {\n p1.id = p2.id;\n }\n\n return p1;\n}\n/**\r\n * @param {Point} p\r\n */\n\nfunction roundPoint(p) {\n p.x = Math.round(p.x);\n p.y = Math.round(p.y);\n}\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 */\n\nfunction getDistanceBetween(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}\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 */\n\nfunction pointsEqual(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\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 */\n\nfunction clamp(val, min, max) {\n return Math.min(Math.max(val, min), max);\n}\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 */\n\nfunction toTransformString(x, y, scale) {\n let propValue = `translate3d(${x}px,${y || 0}px,0)`;\n\n if (scale !== undefined) {\n propValue += ` scale3d(${scale},${scale},1)`;\n }\n\n return propValue;\n}\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 */\n\nfunction setTransform(el, x, y, scale) {\n el.style.transform = toTransformString(x, y, scale);\n}\nconst defaultCSSEasing = 'cubic-bezier(.4,0,.22,1)';\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 */\n\nfunction setTransitionStyle(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 || defaultCSSEasing}` : 'none';\n}\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 */\n\nfunction setWidthHeight(el, w, h) {\n el.style.width = typeof w === 'number' ? `${w}px` : w;\n el.style.height = typeof h === 'number' ? `${h}px` : h;\n}\n/**\r\n * @param {HTMLElement} el\r\n */\n\nfunction removeTransitionStyle(el) {\n setTransitionStyle(el);\n}\n/**\r\n * @param {HTMLImageElement} img\r\n * @returns {Promise}\r\n */\n\nfunction decodeImage(img) {\n if ('decode' in img) {\n return img.decode().catch(() => {});\n }\n\n if (img.complete) {\n return Promise.resolve(img);\n }\n\n return new Promise((resolve, reject) => {\n img.onload = () => resolve(img);\n\n img.onerror = reject;\n });\n}\n/** @typedef {LOAD_STATE[keyof LOAD_STATE]} LoadState */\n\n/** @type {{ IDLE: 'idle'; LOADING: 'loading'; LOADED: 'loaded'; ERROR: 'error' }} */\n\nconst LOAD_STATE = {\n IDLE: 'idle',\n LOADING: 'loading',\n LOADED: 'loaded',\n ERROR: 'error'\n};\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 */\n\nfunction specialKeyUsed(e) {\n return 'button' in e && e.button === 1 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey;\n}\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 */\n\nfunction getElementsFromOption(option, legacySelector, parent = document) {\n /** @type {HTMLElement[]} */\n let elements = [];\n\n if (option instanceof Element) {\n elements = [option];\n } else if (option instanceof NodeList || Array.isArray(option)) {\n elements = Array.from(option);\n } else {\n const selector = typeof option === 'string' ? option : legacySelector;\n\n if (selector) {\n elements = Array.from(parent.querySelectorAll(selector));\n }\n }\n\n return elements;\n}\n/**\r\n * Check if browser is Safari\r\n *\r\n * @returns {boolean}\r\n */\n\nfunction isSafari() {\n return !!(navigator.vendor && navigator.vendor.match(/apple/i));\n}\n\n// Detect passive event listener support\nlet supportsPassive = false;\n/* eslint-disable */\n\ntry {\n /* @ts-ignore */\n window.addEventListener('test', null, Object.defineProperty({}, 'passive', {\n get: () => {\n supportsPassive = true;\n }\n }));\n} catch (e) {}\n/* eslint-enable */\n\n/**\r\n * @typedef {Object} PoolItem\r\n * @prop {HTMLElement | Window | Document | undefined | null} target\r\n * @prop {string} type\r\n * @prop {EventListenerOrEventListenerObject} listener\r\n * @prop {boolean} [passive]\r\n */\n\n\nclass DOMEvents {\n constructor() {\n /**\r\n * @type {PoolItem[]}\r\n * @private\r\n */\n this._pool = [];\n }\n /**\r\n * Adds event listeners\r\n *\r\n * @param {PoolItem['target']} target\r\n * @param {PoolItem['type']} type Can be multiple, separated by space.\r\n * @param {PoolItem['listener']} listener\r\n * @param {PoolItem['passive']} [passive]\r\n */\n\n\n add(target, type, listener, passive) {\n this._toggleListener(target, type, listener, passive);\n }\n /**\r\n * Removes event listeners\r\n *\r\n * @param {PoolItem['target']} target\r\n * @param {PoolItem['type']} type\r\n * @param {PoolItem['listener']} listener\r\n * @param {PoolItem['passive']} [passive]\r\n */\n\n\n remove(target, type, listener, passive) {\n this._toggleListener(target, type, listener, passive, true);\n }\n /**\r\n * Removes all bound events\r\n */\n\n\n removeAll() {\n this._pool.forEach(poolItem => {\n this._toggleListener(poolItem.target, poolItem.type, poolItem.listener, poolItem.passive, true, true);\n });\n\n this._pool = [];\n }\n /**\r\n * Adds or removes event\r\n *\r\n * @private\r\n * @param {PoolItem['target']} target\r\n * @param {PoolItem['type']} type\r\n * @param {PoolItem['listener']} listener\r\n * @param {PoolItem['passive']} [passive]\r\n * @param {boolean} [unbind] Whether the event should be added or removed\r\n * @param {boolean} [skipPool] Whether events pool should be skipped\r\n */\n\n\n _toggleListener(target, type, listener, passive, unbind, skipPool) {\n if (!target) {\n return;\n }\n\n const methodName = unbind ? 'removeEventListener' : 'addEventListener';\n const types = type.split(' ');\n types.forEach(eType => {\n if (eType) {\n // Events pool is used to easily unbind all events when PhotoSwipe is closed,\n // so developer doesn't need to do this manually\n if (!skipPool) {\n if (unbind) {\n // Remove from the events pool\n this._pool = this._pool.filter(poolItem => {\n return poolItem.type !== eType || poolItem.listener !== listener || poolItem.target !== target;\n });\n } else {\n // Add to the events pool\n this._pool.push({\n target,\n type: eType,\n listener,\n passive\n });\n }\n } // most PhotoSwipe events call preventDefault,\n // and we do not need browser to scroll the page\n\n\n const eventOptions = supportsPassive ? {\n passive: passive || false\n } : false;\n target[methodName](eType, listener, eventOptions);\n }\n });\n }\n\n}\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\n\n/**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {PhotoSwipeBase} pswp\r\n * @returns {Point}\r\n */\nfunction getViewportSize(options, pswp) {\n if (options.getViewportSizeFn) {\n const newViewportSize = options.getViewportSizeFn(options, pswp);\n\n if (newViewportSize) {\n return newViewportSize;\n }\n }\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}\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 */\n\nfunction parsePaddingOption(prop, options, viewportSize, itemData, index) {\n let paddingValue = 0;\n\n if (options.paddingFn) {\n paddingValue = options.paddingFn(viewportSize, itemData, index)[prop];\n } else if (options.padding) {\n paddingValue = options.padding[prop];\n } else {\n const legacyPropName = 'padding' + prop[0].toUpperCase() + prop.slice(1); // @ts-expect-error\n\n if (options[legacyPropName]) {\n // @ts-expect-error\n paddingValue = options[legacyPropName];\n }\n }\n\n return Number(paddingValue) || 0;\n}\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 */\n\nfunction getPanAreaSize(options, viewportSize, itemData, index) {\n return {\n x: viewportSize.x - parsePaddingOption('left', options, viewportSize, itemData, index) - parsePaddingOption('right', options, viewportSize, itemData, index),\n y: viewportSize.y - parsePaddingOption('top', options, viewportSize, itemData, index) - parsePaddingOption('bottom', options, viewportSize, itemData, index)\n };\n}\n\n/** @typedef {import('./slide.js').default} Slide */\n\n/** @typedef {Record} Point */\n\n/** @typedef {'x' | 'y'} Axis */\n\n/**\r\n * Calculates minimum, maximum and initial (center) bounds of a slide\r\n */\n\nclass PanBounds {\n /**\r\n * @param {Slide} slide\r\n */\n constructor(slide) {\n this.slide = slide;\n this.currZoomLevel = 1;\n this.center =\n /** @type {Point} */\n {\n x: 0,\n y: 0\n };\n this.max =\n /** @type {Point} */\n {\n x: 0,\n y: 0\n };\n this.min =\n /** @type {Point} */\n {\n x: 0,\n y: 0\n };\n }\n /**\r\n * _getItemBounds\r\n *\r\n * @param {number} currZoomLevel\r\n */\n\n\n update(currZoomLevel) {\n this.currZoomLevel = currZoomLevel;\n\n if (!this.slide.width) {\n this.reset();\n } else {\n this._updateAxis('x');\n\n this._updateAxis('y');\n\n this.slide.pswp.dispatch('calcBounds', {\n slide: this.slide\n });\n }\n }\n /**\r\n * _calculateItemBoundsForAxis\r\n *\r\n * @param {Axis} axis\r\n */\n\n\n _updateAxis(axis) {\n const {\n pswp\n } = this.slide;\n const elSize = this.slide[axis === 'x' ? 'width' : 'height'] * this.currZoomLevel;\n const paddingProp = axis === 'x' ? 'left' : 'top';\n const padding = parsePaddingOption(paddingProp, pswp.options, pswp.viewportSize, this.slide.data, this.slide.index);\n const panAreaSize = this.slide.panAreaSize[axis]; // Default position of element.\n // By default, it is center of viewport:\n\n this.center[axis] = Math.round((panAreaSize - elSize) / 2) + padding; // maximum pan position\n\n this.max[axis] = elSize > panAreaSize ? Math.round(panAreaSize - elSize) + padding : this.center[axis]; // minimum pan position\n\n this.min[axis] = elSize > panAreaSize ? padding : this.center[axis];\n } // _getZeroBounds\n\n\n reset() {\n this.center.x = 0;\n this.center.y = 0;\n this.max.x = 0;\n this.max.y = 0;\n this.min.x = 0;\n this.min.y = 0;\n }\n /**\r\n * Correct pan position if it's beyond the bounds\r\n *\r\n * @param {Axis} axis x or y\r\n * @param {number} panOffset\r\n * @returns {number}\r\n */\n\n\n correctPan(axis, panOffset) {\n // checkPanBounds\n return clamp(panOffset, this.max[axis], this.min[axis]);\n }\n\n}\n\nconst MAX_IMAGE_WIDTH = 4000;\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\n\n/** @typedef {'fit' | 'fill' | number | ((zoomLevelObject: ZoomLevel) => number)} ZoomLevelOption */\n\n/**\r\n * Calculates zoom levels for specific slide.\r\n * Depends on viewport size and image size.\r\n */\n\nclass 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 */\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 } */\n\n this.panAreaSize = null;\n /** @type { Point | null } */\n\n 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 */\n\n\n update(maxWidth, maxHeight, panAreaSize) {\n /** @type {Point} */\n 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); // zoom.vFill defines zoom level of the image\n // when it has 100% of viewport vertical space (height)\n\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\n if (this.pswp) {\n this.pswp.dispatch('zoomLevelsUpdate', {\n zoomLevels: this,\n slideData: this.itemData\n });\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 */\n\n\n _parseZoomLevelOption(optionPrefix) {\n const optionName =\n /** @type {'initialZoomLevel' | 'secondaryZoomLevel' | 'maxZoomLevel'} */\n optionPrefix + 'ZoomLevel';\n const optionValue = this.options[optionName];\n\n if (!optionValue) {\n return;\n }\n\n if (typeof optionValue === 'function') {\n return optionValue(this);\n }\n\n if (optionValue === 'fill') {\n return this.fill;\n }\n\n if (optionValue === 'fit') {\n return this.fit;\n }\n\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 */\n\n\n _getSecondary() {\n let currZoomLevel = this._parseZoomLevelOption('secondary');\n\n if (currZoomLevel) {\n return currZoomLevel;\n } // 3x of \"fit\" state, but not larger than original\n\n\n currZoomLevel = Math.min(1, this.fit * 3);\n\n if (this.elementSize && currZoomLevel * this.elementSize.x > MAX_IMAGE_WIDTH) {\n currZoomLevel = MAX_IMAGE_WIDTH / this.elementSize.x;\n }\n\n return currZoomLevel;\n }\n /**\r\n * Get initial image zoom level.\r\n *\r\n * @private\r\n * @return {number}\r\n */\n\n\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 */\n\n\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\n}\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n/**\r\n * Renders and allows to control a single slide\r\n */\n\nclass Slide {\n /**\r\n * @param {SlideData} data\r\n * @param {number} index\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(data, index, pswp) {\n this.data = data;\n this.index = index;\n this.pswp = pswp;\n this.isActive = index === pswp.currIndex;\n this.currentResolution = 0;\n /** @type {Point} */\n\n this.panAreaSize = {\n x: 0,\n y: 0\n };\n /** @type {Point} */\n\n this.pan = {\n x: 0,\n y: 0\n };\n this.isFirstSlide = this.isActive && !pswp.opener.isOpen;\n this.zoomLevels = new ZoomLevel(pswp.options, data, index, pswp);\n this.pswp.dispatch('gettingData', {\n slide: this,\n data: this.data,\n index\n });\n this.content = this.pswp.contentLoader.getContentBySlide(this);\n this.container = createElement('pswp__zoom-wrap', 'div');\n /** @type {HTMLElement | null} */\n\n this.holderElement = null;\n this.currZoomLevel = 1;\n /** @type {number} */\n\n this.width = this.content.width;\n /** @type {number} */\n\n this.height = this.content.height;\n this.heavyAppended = false;\n this.bounds = new PanBounds(this);\n this.prevDisplayedWidth = -1;\n this.prevDisplayedHeight = -1;\n this.pswp.dispatch('slideInit', {\n slide: this\n });\n }\n /**\r\n * If this slide is active/current/visible\r\n *\r\n * @param {boolean} isActive\r\n */\n\n\n setIsActive(isActive) {\n if (isActive && !this.isActive) {\n // slide just became active\n this.activate();\n } else if (!isActive && this.isActive) {\n // slide just became non-active\n this.deactivate();\n }\n }\n /**\r\n * Appends slide content to DOM\r\n *\r\n * @param {HTMLElement} holderElement\r\n */\n\n\n append(holderElement) {\n this.holderElement = holderElement;\n this.container.style.transformOrigin = '0 0'; // Slide appended to DOM\n\n if (!this.data) {\n return;\n }\n\n this.calculateSize();\n this.load();\n this.updateContentSize();\n this.appendHeavy();\n this.holderElement.appendChild(this.container);\n this.zoomAndPanToInitial();\n this.pswp.dispatch('firstZoomPan', {\n slide: this\n });\n this.applyCurrentZoomPan();\n this.pswp.dispatch('afterSetContent', {\n slide: this\n });\n\n if (this.isActive) {\n this.activate();\n }\n }\n\n load() {\n this.content.load(false);\n this.pswp.dispatch('slideLoad', {\n slide: this\n });\n }\n /**\r\n * Append \"heavy\" DOM elements\r\n *\r\n * This may depend on a type of slide,\r\n * but generally these are large images.\r\n */\n\n\n appendHeavy() {\n const {\n pswp\n } = this;\n const appendHeavyNearby = true; // todo\n // Avoid appending heavy elements during animations\n\n if (this.heavyAppended || !pswp.opener.isOpen || pswp.mainScroll.isShifted() || !this.isActive && !appendHeavyNearby) {\n return;\n }\n\n if (this.pswp.dispatch('appendHeavy', {\n slide: this\n }).defaultPrevented) {\n return;\n }\n\n this.heavyAppended = true;\n this.content.append();\n this.pswp.dispatch('appendHeavyContent', {\n slide: this\n });\n }\n /**\r\n * Triggered when this slide is active (selected).\r\n *\r\n * If it's part of opening/closing transition -\r\n * activate() will trigger after the transition is ended.\r\n */\n\n\n activate() {\n this.isActive = true;\n this.appendHeavy();\n this.content.activate();\n this.pswp.dispatch('slideActivate', {\n slide: this\n });\n }\n /**\r\n * Triggered when this slide becomes inactive.\r\n *\r\n * Slide can become inactive only after it was active.\r\n */\n\n\n deactivate() {\n this.isActive = false;\n this.content.deactivate();\n\n if (this.currZoomLevel !== this.zoomLevels.initial) {\n // allow filtering\n this.calculateSize();\n } // reset zoom level\n\n\n this.currentResolution = 0;\n this.zoomAndPanToInitial();\n this.applyCurrentZoomPan();\n this.updateContentSize();\n this.pswp.dispatch('slideDeactivate', {\n slide: this\n });\n }\n /**\r\n * The slide should destroy itself, it will never be used again.\r\n * (unbind all events and destroy internal components)\r\n */\n\n\n destroy() {\n this.content.hasSlide = false;\n this.content.remove();\n this.container.remove();\n this.pswp.dispatch('slideDestroy', {\n slide: this\n });\n }\n\n resize() {\n if (this.currZoomLevel === this.zoomLevels.initial || !this.isActive) {\n // Keep initial zoom level if it was before the resize,\n // as well as when this slide is not active\n // Reset position and scale to original state\n this.calculateSize();\n this.currentResolution = 0;\n this.zoomAndPanToInitial();\n this.applyCurrentZoomPan();\n this.updateContentSize();\n } else {\n // readjust pan position if it's beyond the bounds\n this.calculateSize();\n this.bounds.update(this.currZoomLevel);\n this.panTo(this.pan.x, this.pan.y);\n }\n }\n /**\r\n * Apply size to current slide content,\r\n * based on the current resolution and scale.\r\n *\r\n * @param {boolean} [force] if size should be updated even if dimensions weren't changed\r\n */\n\n\n updateContentSize(force) {\n // Use initial zoom level\n // if resolution is not defined (user didn't zoom yet)\n const scaleMultiplier = this.currentResolution || this.zoomLevels.initial;\n\n if (!scaleMultiplier) {\n return;\n }\n\n const width = Math.round(this.width * scaleMultiplier) || this.pswp.viewportSize.x;\n const height = Math.round(this.height * scaleMultiplier) || this.pswp.viewportSize.y;\n\n if (!this.sizeChanged(width, height) && !force) {\n return;\n }\n\n this.content.setDisplayedSize(width, height);\n }\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */\n\n\n sizeChanged(width, height) {\n if (width !== this.prevDisplayedWidth || height !== this.prevDisplayedHeight) {\n this.prevDisplayedWidth = width;\n this.prevDisplayedHeight = height;\n return true;\n }\n\n return false;\n }\n /** @returns {HTMLImageElement | HTMLDivElement | null | undefined} */\n\n\n getPlaceholderElement() {\n var _this$content$placeho;\n\n return (_this$content$placeho = this.content.placeholder) === null || _this$content$placeho === void 0 ? void 0 : _this$content$placeho.element;\n }\n /**\r\n * Zoom current slide image to...\r\n *\r\n * @param {number} destZoomLevel Destination zoom level.\r\n * @param {Point} [centerPoint]\r\n * Transform origin center point, or false if viewport center should be used.\r\n * @param {number | false} [transitionDuration] Transition duration, may be set to 0.\r\n * @param {boolean} [ignoreBounds] Minimum and maximum zoom levels will be ignored.\r\n */\n\n\n zoomTo(destZoomLevel, centerPoint, transitionDuration, ignoreBounds) {\n const {\n pswp\n } = this;\n\n if (!this.isZoomable() || pswp.mainScroll.isShifted()) {\n return;\n }\n\n pswp.dispatch('beforeZoomTo', {\n destZoomLevel,\n centerPoint,\n transitionDuration\n }); // stop all pan and zoom transitions\n\n pswp.animations.stopAllPan(); // if (!centerPoint) {\n // centerPoint = pswp.getViewportCenterPoint();\n // }\n\n const prevZoomLevel = this.currZoomLevel;\n\n if (!ignoreBounds) {\n destZoomLevel = clamp(destZoomLevel, this.zoomLevels.min, this.zoomLevels.max);\n } // if (transitionDuration === undefined) {\n // transitionDuration = this.pswp.options.zoomAnimationDuration;\n // }\n\n\n this.setZoomLevel(destZoomLevel);\n this.pan.x = this.calculateZoomToPanOffset('x', centerPoint, prevZoomLevel);\n this.pan.y = this.calculateZoomToPanOffset('y', centerPoint, prevZoomLevel);\n roundPoint(this.pan);\n\n const finishTransition = () => {\n this._setResolution(destZoomLevel);\n\n this.applyCurrentZoomPan();\n };\n\n if (!transitionDuration) {\n finishTransition();\n } else {\n pswp.animations.startTransition({\n isPan: true,\n name: 'zoomTo',\n target: this.container,\n transform: this.getCurrentTransform(),\n onComplete: finishTransition,\n duration: transitionDuration,\n easing: pswp.options.easing\n });\n }\n }\n /**\r\n * @param {Point} [centerPoint]\r\n */\n\n\n toggleZoom(centerPoint) {\n this.zoomTo(this.currZoomLevel === this.zoomLevels.initial ? this.zoomLevels.secondary : this.zoomLevels.initial, centerPoint, this.pswp.options.zoomAnimationDuration);\n }\n /**\r\n * Updates zoom level property and recalculates new pan bounds,\r\n * unlike zoomTo it does not apply transform (use applyCurrentZoomPan)\r\n *\r\n * @param {number} currZoomLevel\r\n */\n\n\n setZoomLevel(currZoomLevel) {\n this.currZoomLevel = currZoomLevel;\n this.bounds.update(this.currZoomLevel);\n }\n /**\r\n * Get pan position after zoom at a given `point`.\r\n *\r\n * Always call setZoomLevel(newZoomLevel) beforehand to recalculate\r\n * pan bounds according to the new zoom level.\r\n *\r\n * @param {'x' | 'y'} axis\r\n * @param {Point} [point]\r\n * point based on which zoom is performed, usually refers to the current mouse position,\r\n * if false - viewport center will be used.\r\n * @param {number} [prevZoomLevel] Zoom level before new zoom was applied.\r\n * @returns {number}\r\n */\n\n\n calculateZoomToPanOffset(axis, point, prevZoomLevel) {\n const totalPanDistance = this.bounds.max[axis] - this.bounds.min[axis];\n\n if (totalPanDistance === 0) {\n return this.bounds.center[axis];\n }\n\n if (!point) {\n point = this.pswp.getViewportCenterPoint();\n }\n\n if (!prevZoomLevel) {\n prevZoomLevel = this.zoomLevels.initial;\n }\n\n const zoomFactor = this.currZoomLevel / prevZoomLevel;\n return this.bounds.correctPan(axis, (this.pan[axis] - point[axis]) * zoomFactor + point[axis]);\n }\n /**\r\n * Apply pan and keep it within bounds.\r\n *\r\n * @param {number} panX\r\n * @param {number} panY\r\n */\n\n\n panTo(panX, panY) {\n this.pan.x = this.bounds.correctPan('x', panX);\n this.pan.y = this.bounds.correctPan('y', panY);\n this.applyCurrentZoomPan();\n }\n /**\r\n * If the slide in the current state can be panned by the user\r\n * @returns {boolean}\r\n */\n\n\n isPannable() {\n return Boolean(this.width) && this.currZoomLevel > this.zoomLevels.fit;\n }\n /**\r\n * If the slide can be zoomed\r\n * @returns {boolean}\r\n */\n\n\n isZoomable() {\n return Boolean(this.width) && this.content.isZoomable();\n }\n /**\r\n * Apply transform and scale based on\r\n * the current pan position (this.pan) and zoom level (this.currZoomLevel)\r\n */\n\n\n applyCurrentZoomPan() {\n this._applyZoomTransform(this.pan.x, this.pan.y, this.currZoomLevel);\n\n if (this === this.pswp.currSlide) {\n this.pswp.dispatch('zoomPanUpdate', {\n slide: this\n });\n }\n }\n\n zoomAndPanToInitial() {\n this.currZoomLevel = this.zoomLevels.initial; // pan according to the zoom level\n\n this.bounds.update(this.currZoomLevel);\n equalizePoints(this.pan, this.bounds.center);\n this.pswp.dispatch('initialZoomPan', {\n slide: this\n });\n }\n /**\r\n * Set translate and scale based on current resolution\r\n *\r\n * @param {number} x\r\n * @param {number} y\r\n * @param {number} zoom\r\n * @private\r\n */\n\n\n _applyZoomTransform(x, y, zoom) {\n zoom /= this.currentResolution || this.zoomLevels.initial;\n setTransform(this.container, x, y, zoom);\n }\n\n calculateSize() {\n const {\n pswp\n } = this;\n equalizePoints(this.panAreaSize, getPanAreaSize(pswp.options, pswp.viewportSize, this.data, this.index));\n this.zoomLevels.update(this.width, this.height, this.panAreaSize);\n pswp.dispatch('calcSlideSize', {\n slide: this\n });\n }\n /** @returns {string} */\n\n\n getCurrentTransform() {\n const scale = this.currZoomLevel / (this.currentResolution || this.zoomLevels.initial);\n return toTransformString(this.pan.x, this.pan.y, scale);\n }\n /**\r\n * Set resolution and re-render the image.\r\n *\r\n * For example, if the real image size is 2000x1500,\r\n * and resolution is 0.5 - it will be rendered as 1000x750.\r\n *\r\n * Image with zoom level 2 and resolution 0.5 is\r\n * the same as image with zoom level 1 and resolution 1.\r\n *\r\n * Used to optimize animations and make\r\n * sure that browser renders image in the highest quality.\r\n * Also used by responsive images to load the correct one.\r\n *\r\n * @param {number} newResolution\r\n */\n\n\n _setResolution(newResolution) {\n if (newResolution === this.currentResolution) {\n return;\n }\n\n this.currentResolution = newResolution;\n this.updateContentSize();\n this.pswp.dispatch('resolutionChanged');\n }\n\n}\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('./gestures.js').default} Gestures */\n\nconst PAN_END_FRICTION = 0.35;\nconst VERTICAL_DRAG_FRICTION = 0.6; // 1 corresponds to the third of viewport height\n\nconst MIN_RATIO_TO_CLOSE = 0.4; // Minimum speed required to navigate\n// to next or previous slide\n\nconst MIN_NEXT_SLIDE_SPEED = 0.5;\n/**\r\n * @param {number} initialVelocity\r\n * @param {number} decelerationRate\r\n * @returns {number}\r\n */\n\nfunction project(initialVelocity, decelerationRate) {\n return initialVelocity * decelerationRate / (1 - decelerationRate);\n}\n/**\r\n * Handles single pointer dragging\r\n */\n\n\nclass DragHandler {\n /**\r\n * @param {Gestures} gestures\r\n */\n constructor(gestures) {\n this.gestures = gestures;\n this.pswp = gestures.pswp;\n /** @type {Point} */\n\n this.startPan = {\n x: 0,\n y: 0\n };\n }\n\n start() {\n if (this.pswp.currSlide) {\n equalizePoints(this.startPan, this.pswp.currSlide.pan);\n }\n\n this.pswp.animations.stopAll();\n }\n\n change() {\n const {\n p1,\n prevP1,\n dragAxis\n } = this.gestures;\n const {\n currSlide\n } = this.pswp;\n\n if (dragAxis === 'y' && this.pswp.options.closeOnVerticalDrag && currSlide && currSlide.currZoomLevel <= currSlide.zoomLevels.fit && !this.gestures.isMultitouch) {\n // Handle vertical drag to close\n const panY = currSlide.pan.y + (p1.y - prevP1.y);\n\n if (!this.pswp.dispatch('verticalDrag', {\n panY\n }).defaultPrevented) {\n this._setPanWithFriction('y', panY, VERTICAL_DRAG_FRICTION);\n\n const bgOpacity = 1 - Math.abs(this._getVerticalDragRatio(currSlide.pan.y));\n this.pswp.applyBgOpacity(bgOpacity);\n currSlide.applyCurrentZoomPan();\n }\n } else {\n const mainScrollChanged = this._panOrMoveMainScroll('x');\n\n if (!mainScrollChanged) {\n this._panOrMoveMainScroll('y');\n\n if (currSlide) {\n roundPoint(currSlide.pan);\n currSlide.applyCurrentZoomPan();\n }\n }\n }\n }\n\n end() {\n const {\n velocity\n } = this.gestures;\n const {\n mainScroll,\n currSlide\n } = this.pswp;\n let indexDiff = 0;\n this.pswp.animations.stopAll(); // Handle main scroll if it's shifted\n\n if (mainScroll.isShifted()) {\n // Position of the main scroll relative to the viewport\n const mainScrollShiftDiff = mainScroll.x - mainScroll.getCurrSlideX(); // Ratio between 0 and 1:\n // 0 - slide is not visible at all,\n // 0.5 - half of the slide is visible\n // 1 - slide is fully visible\n\n const currentSlideVisibilityRatio = mainScrollShiftDiff / this.pswp.viewportSize.x; // Go next slide.\n //\n // - if velocity and its direction is matched,\n // and we see at least tiny part of the next slide\n //\n // - or if we see less than 50% of the current slide\n // and velocity is close to 0\n //\n\n if (velocity.x < -MIN_NEXT_SLIDE_SPEED && currentSlideVisibilityRatio < 0 || velocity.x < 0.1 && currentSlideVisibilityRatio < -0.5) {\n // Go to next slide\n indexDiff = 1;\n velocity.x = Math.min(velocity.x, 0);\n } else if (velocity.x > MIN_NEXT_SLIDE_SPEED && currentSlideVisibilityRatio > 0 || velocity.x > -0.1 && currentSlideVisibilityRatio > 0.5) {\n // Go to prev slide\n indexDiff = -1;\n velocity.x = Math.max(velocity.x, 0);\n }\n\n mainScroll.moveIndexBy(indexDiff, true, velocity.x);\n } // Restore zoom level\n\n\n if (currSlide && currSlide.currZoomLevel > currSlide.zoomLevels.max || this.gestures.isMultitouch) {\n this.gestures.zoomLevels.correctZoomPan(true);\n } else {\n // we run two animations instead of one,\n // as each axis has own pan boundaries and thus different spring function\n // (correctZoomPan does not have this functionality,\n // it animates all properties with single timing function)\n this._finishPanGestureForAxis('x');\n\n this._finishPanGestureForAxis('y');\n }\n }\n /**\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n */\n\n\n _finishPanGestureForAxis(axis) {\n const {\n velocity\n } = this.gestures;\n const {\n currSlide\n } = this.pswp;\n\n if (!currSlide) {\n return;\n }\n\n const {\n pan,\n bounds\n } = currSlide;\n const panPos = pan[axis];\n const restoreBgOpacity = this.pswp.bgOpacity < 1 && axis === 'y'; // 0.995 means - scroll view loses 0.5% of its velocity per millisecond\n // Increasing this number will reduce travel distance\n\n const decelerationRate = 0.995; // 0.99\n // Pan position if there is no bounds\n\n const projectedPosition = panPos + project(velocity[axis], decelerationRate);\n\n if (restoreBgOpacity) {\n const vDragRatio = this._getVerticalDragRatio(panPos);\n\n const projectedVDragRatio = this._getVerticalDragRatio(projectedPosition); // If we are above and moving upwards,\n // or if we are below and moving downwards\n\n\n if (vDragRatio < 0 && projectedVDragRatio < -MIN_RATIO_TO_CLOSE || vDragRatio > 0 && projectedVDragRatio > MIN_RATIO_TO_CLOSE) {\n this.pswp.close();\n return;\n }\n } // Pan position with corrected bounds\n\n\n const correctedPanPosition = bounds.correctPan(axis, projectedPosition); // Exit if pan position should not be changed\n // or if speed it too low\n\n if (panPos === correctedPanPosition) {\n return;\n } // Overshoot if the final position is out of pan bounds\n\n\n const dampingRatio = correctedPanPosition === projectedPosition ? 1 : 0.82;\n const initialBgOpacity = this.pswp.bgOpacity;\n const totalPanDist = correctedPanPosition - panPos;\n this.pswp.animations.startSpring({\n name: 'panGesture' + axis,\n isPan: true,\n start: panPos,\n end: correctedPanPosition,\n velocity: velocity[axis],\n dampingRatio,\n onUpdate: pos => {\n // Animate opacity of background relative to Y pan position of an image\n if (restoreBgOpacity && this.pswp.bgOpacity < 1) {\n // 0 - start of animation, 1 - end of animation\n const animationProgressRatio = 1 - (correctedPanPosition - pos) / totalPanDist; // We clamp opacity to keep it between 0 and 1.\n // As progress ratio can be larger than 1 due to overshoot,\n // and we do not want to bounce opacity.\n\n this.pswp.applyBgOpacity(clamp(initialBgOpacity + (1 - initialBgOpacity) * animationProgressRatio, 0, 1));\n }\n\n pan[axis] = Math.floor(pos);\n currSlide.applyCurrentZoomPan();\n }\n });\n }\n /**\r\n * Update position of the main scroll,\r\n * or/and update pan position of the current slide.\r\n *\r\n * Should return true if it changes (or can change) main scroll.\r\n *\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @returns {boolean}\r\n */\n\n\n _panOrMoveMainScroll(axis) {\n const {\n p1,\n dragAxis,\n prevP1,\n isMultitouch\n } = this.gestures;\n const {\n currSlide,\n mainScroll\n } = this.pswp;\n const delta = p1[axis] - prevP1[axis];\n const newMainScrollX = mainScroll.x + delta;\n\n if (!delta || !currSlide) {\n return false;\n } // Always move main scroll if image can not be panned\n\n\n if (axis === 'x' && !currSlide.isPannable() && !isMultitouch) {\n mainScroll.moveTo(newMainScrollX, true);\n return true; // changed main scroll\n }\n\n const {\n bounds\n } = currSlide;\n const newPan = currSlide.pan[axis] + delta;\n\n if (this.pswp.options.allowPanToNext && dragAxis === 'x' && axis === 'x' && !isMultitouch) {\n const currSlideMainScrollX = mainScroll.getCurrSlideX(); // Position of the main scroll relative to the viewport\n\n const mainScrollShiftDiff = mainScroll.x - currSlideMainScrollX;\n const isLeftToRight = delta > 0;\n const isRightToLeft = !isLeftToRight;\n\n if (newPan > bounds.min[axis] && isLeftToRight) {\n // Panning from left to right, beyond the left edge\n // Wether the image was at minimum pan position (or less)\n // when this drag gesture started.\n // Minimum pan position refers to the left edge of the image.\n const wasAtMinPanPosition = bounds.min[axis] <= this.startPan[axis];\n\n if (wasAtMinPanPosition) {\n mainScroll.moveTo(newMainScrollX, true);\n return true;\n } else {\n this._setPanWithFriction(axis, newPan); //currSlide.pan[axis] = newPan;\n\n }\n } else if (newPan < bounds.max[axis] && isRightToLeft) {\n // Paning from right to left, beyond the right edge\n // Maximum pan position refers to the right edge of the image.\n const wasAtMaxPanPosition = this.startPan[axis] <= bounds.max[axis];\n\n if (wasAtMaxPanPosition) {\n mainScroll.moveTo(newMainScrollX, true);\n return true;\n } else {\n this._setPanWithFriction(axis, newPan); //currSlide.pan[axis] = newPan;\n\n }\n } else {\n // If main scroll is shifted\n if (mainScrollShiftDiff !== 0) {\n // If main scroll is shifted right\n if (mainScrollShiftDiff > 0\n /*&& isRightToLeft*/\n ) {\n mainScroll.moveTo(Math.max(newMainScrollX, currSlideMainScrollX), true);\n return true;\n } else if (mainScrollShiftDiff < 0\n /*&& isLeftToRight*/\n ) {\n // Main scroll is shifted left (Position is less than 0 comparing to the viewport 0)\n mainScroll.moveTo(Math.min(newMainScrollX, currSlideMainScrollX), true);\n return true;\n }\n } else {\n // We are within pan bounds, so just pan\n this._setPanWithFriction(axis, newPan);\n }\n }\n } else {\n if (axis === 'y') {\n // Do not pan vertically if main scroll is shifted o\n if (!mainScroll.isShifted() && bounds.min.y !== bounds.max.y) {\n this._setPanWithFriction(axis, newPan);\n }\n } else {\n this._setPanWithFriction(axis, newPan);\n }\n }\n\n return false;\n } // If we move above - the ratio is negative\n // If we move below the ratio is positive\n\n /**\r\n * Relation between pan Y position and third of viewport height.\r\n *\r\n * When we are at initial position (center bounds) - the ratio is 0,\r\n * if position is shifted upwards - the ratio is negative,\r\n * if position is shifted downwards - the ratio is positive.\r\n *\r\n * @private\r\n * @param {number} panY The current pan Y position.\r\n * @returns {number}\r\n */\n\n\n _getVerticalDragRatio(panY) {\n var _this$pswp$currSlide$, _this$pswp$currSlide;\n\n return (panY - ((_this$pswp$currSlide$ = (_this$pswp$currSlide = this.pswp.currSlide) === null || _this$pswp$currSlide === void 0 ? void 0 : _this$pswp$currSlide.bounds.center.y) !== null && _this$pswp$currSlide$ !== void 0 ? _this$pswp$currSlide$ : 0)) / (this.pswp.viewportSize.y / 3);\n }\n /**\r\n * Set pan position of the current slide.\r\n * Apply friction if the position is beyond the pan bounds,\r\n * or if custom friction is defined.\r\n *\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @param {number} potentialPan\r\n * @param {number} [customFriction] (0.1 - 1)\r\n */\n\n\n _setPanWithFriction(axis, potentialPan, customFriction) {\n const {\n currSlide\n } = this.pswp;\n\n if (!currSlide) {\n return;\n }\n\n const {\n pan,\n bounds\n } = currSlide;\n const correctedPan = bounds.correctPan(axis, potentialPan); // If we are out of pan bounds\n\n if (correctedPan !== potentialPan || customFriction) {\n const delta = Math.round(potentialPan - pan[axis]);\n pan[axis] += delta * (customFriction || PAN_END_FRICTION);\n } else {\n pan[axis] = potentialPan;\n }\n }\n\n}\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('./gestures.js').default} Gestures */\n\nconst UPPER_ZOOM_FRICTION = 0.05;\nconst LOWER_ZOOM_FRICTION = 0.15;\n/**\r\n * Get center point between two points\r\n *\r\n * @param {Point} p\r\n * @param {Point} p1\r\n * @param {Point} p2\r\n * @returns {Point}\r\n */\n\nfunction getZoomPointsCenter(p, p1, p2) {\n p.x = (p1.x + p2.x) / 2;\n p.y = (p1.y + p2.y) / 2;\n return p;\n}\n\nclass ZoomHandler {\n /**\r\n * @param {Gestures} gestures\r\n */\n constructor(gestures) {\n this.gestures = gestures;\n /**\r\n * @private\r\n * @type {Point}\r\n */\n\n this._startPan = {\n x: 0,\n y: 0\n };\n /**\r\n * @private\r\n * @type {Point}\r\n */\n\n this._startZoomPoint = {\n x: 0,\n y: 0\n };\n /**\r\n * @private\r\n * @type {Point}\r\n */\n\n this._zoomPoint = {\n x: 0,\n y: 0\n };\n /** @private */\n\n this._wasOverFitZoomLevel = false;\n /** @private */\n\n this._startZoomLevel = 1;\n }\n\n start() {\n const {\n currSlide\n } = this.gestures.pswp;\n\n if (currSlide) {\n this._startZoomLevel = currSlide.currZoomLevel;\n equalizePoints(this._startPan, currSlide.pan);\n }\n\n this.gestures.pswp.animations.stopAllPan();\n this._wasOverFitZoomLevel = false;\n }\n\n change() {\n const {\n p1,\n startP1,\n p2,\n startP2,\n pswp\n } = this.gestures;\n const {\n currSlide\n } = pswp;\n\n if (!currSlide) {\n return;\n }\n\n const minZoomLevel = currSlide.zoomLevels.min;\n const maxZoomLevel = currSlide.zoomLevels.max;\n\n if (!currSlide.isZoomable() || pswp.mainScroll.isShifted()) {\n return;\n }\n\n getZoomPointsCenter(this._startZoomPoint, startP1, startP2);\n getZoomPointsCenter(this._zoomPoint, p1, p2);\n\n let currZoomLevel = 1 / getDistanceBetween(startP1, startP2) * getDistanceBetween(p1, p2) * this._startZoomLevel; // slightly over the zoom.fit\n\n\n if (currZoomLevel > currSlide.zoomLevels.initial + currSlide.zoomLevels.initial / 15) {\n this._wasOverFitZoomLevel = true;\n }\n\n if (currZoomLevel < minZoomLevel) {\n if (pswp.options.pinchToClose && !this._wasOverFitZoomLevel && this._startZoomLevel <= currSlide.zoomLevels.initial) {\n // fade out background if zooming out\n const bgOpacity = 1 - (minZoomLevel - currZoomLevel) / (minZoomLevel / 1.2);\n\n if (!pswp.dispatch('pinchClose', {\n bgOpacity\n }).defaultPrevented) {\n pswp.applyBgOpacity(bgOpacity);\n }\n } else {\n // Apply the friction if zoom level is below the min\n currZoomLevel = minZoomLevel - (minZoomLevel - currZoomLevel) * LOWER_ZOOM_FRICTION;\n }\n } else if (currZoomLevel > maxZoomLevel) {\n // Apply the friction if zoom level is above the max\n currZoomLevel = maxZoomLevel + (currZoomLevel - maxZoomLevel) * UPPER_ZOOM_FRICTION;\n }\n\n currSlide.pan.x = this._calculatePanForZoomLevel('x', currZoomLevel);\n currSlide.pan.y = this._calculatePanForZoomLevel('y', currZoomLevel);\n currSlide.setZoomLevel(currZoomLevel);\n currSlide.applyCurrentZoomPan();\n }\n\n end() {\n const {\n pswp\n } = this.gestures;\n const {\n currSlide\n } = pswp;\n\n if ((!currSlide || currSlide.currZoomLevel < currSlide.zoomLevels.initial) && !this._wasOverFitZoomLevel && pswp.options.pinchToClose) {\n pswp.close();\n } else {\n this.correctZoomPan();\n }\n }\n /**\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @param {number} currZoomLevel\r\n * @returns {number}\r\n */\n\n\n _calculatePanForZoomLevel(axis, currZoomLevel) {\n const zoomFactor = currZoomLevel / this._startZoomLevel;\n return this._zoomPoint[axis] - (this._startZoomPoint[axis] - this._startPan[axis]) * zoomFactor;\n }\n /**\r\n * Correct currZoomLevel and pan if they are\r\n * beyond minimum or maximum values.\r\n * With animation.\r\n *\r\n * @param {boolean} [ignoreGesture]\r\n * Wether gesture coordinates should be ignored when calculating destination pan position.\r\n */\n\n\n correctZoomPan(ignoreGesture) {\n const {\n pswp\n } = this.gestures;\n const {\n currSlide\n } = pswp;\n\n if (!(currSlide !== null && currSlide !== void 0 && currSlide.isZoomable())) {\n return;\n }\n\n if (this._zoomPoint.x === 0) {\n ignoreGesture = true;\n }\n\n const prevZoomLevel = currSlide.currZoomLevel;\n /** @type {number} */\n\n let destinationZoomLevel;\n let currZoomLevelNeedsChange = true;\n\n if (prevZoomLevel < currSlide.zoomLevels.initial) {\n destinationZoomLevel = currSlide.zoomLevels.initial; // zoom to min\n } else if (prevZoomLevel > currSlide.zoomLevels.max) {\n destinationZoomLevel = currSlide.zoomLevels.max; // zoom to max\n } else {\n currZoomLevelNeedsChange = false;\n destinationZoomLevel = prevZoomLevel;\n }\n\n const initialBgOpacity = pswp.bgOpacity;\n const restoreBgOpacity = pswp.bgOpacity < 1;\n const initialPan = equalizePoints({\n x: 0,\n y: 0\n }, currSlide.pan);\n let destinationPan = equalizePoints({\n x: 0,\n y: 0\n }, initialPan);\n\n if (ignoreGesture) {\n this._zoomPoint.x = 0;\n this._zoomPoint.y = 0;\n this._startZoomPoint.x = 0;\n this._startZoomPoint.y = 0;\n this._startZoomLevel = prevZoomLevel;\n equalizePoints(this._startPan, initialPan);\n }\n\n if (currZoomLevelNeedsChange) {\n destinationPan = {\n x: this._calculatePanForZoomLevel('x', destinationZoomLevel),\n y: this._calculatePanForZoomLevel('y', destinationZoomLevel)\n };\n } // set zoom level, so pan bounds are updated according to it\n\n\n currSlide.setZoomLevel(destinationZoomLevel);\n destinationPan = {\n x: currSlide.bounds.correctPan('x', destinationPan.x),\n y: currSlide.bounds.correctPan('y', destinationPan.y)\n }; // return zoom level and its bounds to initial\n\n currSlide.setZoomLevel(prevZoomLevel);\n const panNeedsChange = !pointsEqual(destinationPan, initialPan);\n\n if (!panNeedsChange && !currZoomLevelNeedsChange && !restoreBgOpacity) {\n // update resolution after gesture\n currSlide._setResolution(destinationZoomLevel);\n\n currSlide.applyCurrentZoomPan(); // nothing to animate\n\n return;\n }\n\n pswp.animations.stopAllPan();\n pswp.animations.startSpring({\n isPan: true,\n start: 0,\n end: 1000,\n velocity: 0,\n dampingRatio: 1,\n naturalFrequency: 40,\n onUpdate: now => {\n now /= 1000; // 0 - start, 1 - end\n\n if (panNeedsChange || currZoomLevelNeedsChange) {\n if (panNeedsChange) {\n currSlide.pan.x = initialPan.x + (destinationPan.x - initialPan.x) * now;\n currSlide.pan.y = initialPan.y + (destinationPan.y - initialPan.y) * now;\n }\n\n if (currZoomLevelNeedsChange) {\n const newZoomLevel = prevZoomLevel + (destinationZoomLevel - prevZoomLevel) * now;\n currSlide.setZoomLevel(newZoomLevel);\n }\n\n currSlide.applyCurrentZoomPan();\n } // Restore background opacity\n\n\n if (restoreBgOpacity && pswp.bgOpacity < 1) {\n // We clamp opacity to keep it between 0 and 1.\n // As progress ratio can be larger than 1 due to overshoot,\n // and we do not want to bounce opacity.\n pswp.applyBgOpacity(clamp(initialBgOpacity + (1 - initialBgOpacity) * now, 0, 1));\n }\n },\n onComplete: () => {\n // update resolution after transition ends\n currSlide._setResolution(destinationZoomLevel);\n\n currSlide.applyCurrentZoomPan();\n }\n });\n }\n\n}\n\n/**\r\n * @template {string} T\r\n * @template {string} P\r\n * @typedef {import('../types.js').AddPostfix} AddPostfix\r\n */\n\n/** @typedef {import('./gestures.js').default} Gestures */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {'imageClick' | 'bgClick' | 'tap' | 'doubleTap'} Actions */\n\n/**\r\n * Whether the tap was performed on the main slide\r\n * (rather than controls or caption).\r\n *\r\n * @param {PointerEvent} event\r\n * @returns {boolean}\r\n */\nfunction didTapOnMainContent(event) {\n return !!\n /** @type {HTMLElement} */\n event.target.closest('.pswp__container');\n}\n/**\r\n * Tap, double-tap handler.\r\n */\n\n\nclass TapHandler {\n /**\r\n * @param {Gestures} gestures\r\n */\n constructor(gestures) {\n this.gestures = gestures;\n }\n /**\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\n\n\n click(point, originalEvent) {\n const targetClassList =\n /** @type {HTMLElement} */\n originalEvent.target.classList;\n const isImageClick = targetClassList.contains('pswp__img');\n const isBackgroundClick = targetClassList.contains('pswp__item') || targetClassList.contains('pswp__zoom-wrap');\n\n if (isImageClick) {\n this._doClickOrTapAction('imageClick', point, originalEvent);\n } else if (isBackgroundClick) {\n this._doClickOrTapAction('bgClick', point, originalEvent);\n }\n }\n /**\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\n\n\n tap(point, originalEvent) {\n if (didTapOnMainContent(originalEvent)) {\n this._doClickOrTapAction('tap', point, originalEvent);\n }\n }\n /**\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\n\n\n doubleTap(point, originalEvent) {\n if (didTapOnMainContent(originalEvent)) {\n this._doClickOrTapAction('doubleTap', point, originalEvent);\n }\n }\n /**\r\n * @private\r\n * @param {Actions} actionName\r\n * @param {Point} point\r\n * @param {PointerEvent} originalEvent\r\n */\n\n\n _doClickOrTapAction(actionName, point, originalEvent) {\n var _this$gestures$pswp$e;\n\n const {\n pswp\n } = this.gestures;\n const {\n currSlide\n } = pswp;\n const actionFullName =\n /** @type {AddPostfix} */\n actionName + 'Action';\n const optionValue = pswp.options[actionFullName];\n\n if (pswp.dispatch(actionFullName, {\n point,\n originalEvent\n }).defaultPrevented) {\n return;\n }\n\n if (typeof optionValue === 'function') {\n optionValue.call(pswp, point, originalEvent);\n return;\n }\n\n switch (optionValue) {\n case 'close':\n case 'next':\n pswp[optionValue]();\n break;\n\n case 'zoom':\n currSlide === null || currSlide === void 0 || currSlide.toggleZoom(point);\n break;\n\n case 'zoom-or-close':\n // by default click zooms current image,\n // if it can not be zoomed - gallery will be closed\n if (currSlide !== null && currSlide !== void 0 && currSlide.isZoomable() && currSlide.zoomLevels.secondary !== currSlide.zoomLevels.initial) {\n currSlide.toggleZoom(point);\n } else if (pswp.options.clickToCloseNonZoomable) {\n pswp.close();\n }\n\n break;\n\n case 'toggle-controls':\n (_this$gestures$pswp$e = this.gestures.pswp.element) === null || _this$gestures$pswp$e === void 0 || _this$gestures$pswp$e.classList.toggle('pswp--ui-visible'); // if (_controlsVisible) {\n // _ui.hideControls();\n // } else {\n // _ui.showControls();\n // }\n\n break;\n }\n }\n\n}\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n// How far should user should drag\n// until we can determine that the gesture is swipe and its direction\n\nconst AXIS_SWIPE_HYSTERISIS = 10; //const PAN_END_FRICTION = 0.35;\n\nconst DOUBLE_TAP_DELAY = 300; // ms\n\nconst MIN_TAP_DISTANCE = 25; // px\n\n/**\r\n * Gestures class bind touch, pointer or mouse events\r\n * and emits drag to drag-handler and zoom events zoom-handler.\r\n *\r\n * Drag and zoom events are emited in requestAnimationFrame,\r\n * and only when one of pointers was actually changed.\r\n */\n\nclass Gestures {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp;\n /** @type {'x' | 'y' | null} */\n\n this.dragAxis = null; // point objects are defined once and reused\n // PhotoSwipe keeps track only of two pointers, others are ignored\n\n /** @type {Point} */\n\n this.p1 = {\n x: 0,\n y: 0\n }; // the first pressed pointer\n\n /** @type {Point} */\n\n this.p2 = {\n x: 0,\n y: 0\n }; // the second pressed pointer\n\n /** @type {Point} */\n\n this.prevP1 = {\n x: 0,\n y: 0\n };\n /** @type {Point} */\n\n this.prevP2 = {\n x: 0,\n y: 0\n };\n /** @type {Point} */\n\n this.startP1 = {\n x: 0,\n y: 0\n };\n /** @type {Point} */\n\n this.startP2 = {\n x: 0,\n y: 0\n };\n /** @type {Point} */\n\n this.velocity = {\n x: 0,\n y: 0\n };\n /** @type {Point}\r\n * @private\r\n */\n\n this._lastStartP1 = {\n x: 0,\n y: 0\n };\n /** @type {Point}\r\n * @private\r\n */\n\n this._intervalP1 = {\n x: 0,\n y: 0\n };\n /** @private */\n\n this._numActivePoints = 0;\n /** @type {Point[]}\r\n * @private\r\n */\n\n this._ongoingPointers = [];\n /** @private */\n\n this._touchEventEnabled = 'ontouchstart' in window;\n /** @private */\n\n this._pointerEventEnabled = !!window.PointerEvent;\n this.supportsTouch = this._touchEventEnabled || this._pointerEventEnabled && navigator.maxTouchPoints > 1;\n /** @private */\n\n this._numActivePoints = 0;\n /** @private */\n\n this._intervalTime = 0;\n /** @private */\n\n this._velocityCalculated = false;\n this.isMultitouch = false;\n this.isDragging = false;\n this.isZooming = false;\n /** @type {number | null} */\n\n this.raf = null;\n /** @type {NodeJS.Timeout | null}\r\n * @private\r\n */\n\n this._tapTimer = null;\n\n if (!this.supportsTouch) {\n // disable pan to next slide for non-touch devices\n pswp.options.allowPanToNext = false;\n }\n\n this.drag = new DragHandler(this);\n this.zoomLevels = new ZoomHandler(this);\n this.tapHandler = new TapHandler(this);\n pswp.on('bindEvents', () => {\n pswp.events.add(pswp.scrollWrap, 'click',\n /** @type EventListener */\n this._onClick.bind(this));\n\n if (this._pointerEventEnabled) {\n this._bindEvents('pointer', 'down', 'up', 'cancel');\n } else if (this._touchEventEnabled) {\n this._bindEvents('touch', 'start', 'end', 'cancel'); // In previous versions we also bound mouse event here,\n // in case device supports both touch and mouse events,\n // but newer versions of browsers now support PointerEvent.\n // on iOS10 if you bind touchmove/end after touchstart,\n // and you don't preventDefault touchstart (which PhotoSwipe does),\n // preventDefault will have no effect on touchmove and touchend.\n // Unless you bind it previously.\n\n\n if (pswp.scrollWrap) {\n pswp.scrollWrap.ontouchmove = () => {};\n\n pswp.scrollWrap.ontouchend = () => {};\n }\n } else {\n this._bindEvents('mouse', 'down', 'up');\n }\n });\n }\n /**\r\n * @private\r\n * @param {'mouse' | 'touch' | 'pointer'} pref\r\n * @param {'down' | 'start'} down\r\n * @param {'up' | 'end'} up\r\n * @param {'cancel'} [cancel]\r\n */\n\n\n _bindEvents(pref, down, up, cancel) {\n const {\n pswp\n } = this;\n const {\n events\n } = pswp;\n const cancelEvent = cancel ? pref + cancel : '';\n events.add(pswp.scrollWrap, pref + down,\n /** @type EventListener */\n this.onPointerDown.bind(this));\n events.add(window, pref + 'move',\n /** @type EventListener */\n this.onPointerMove.bind(this));\n events.add(window, pref + up,\n /** @type EventListener */\n this.onPointerUp.bind(this));\n\n if (cancelEvent) {\n events.add(pswp.scrollWrap, cancelEvent,\n /** @type EventListener */\n this.onPointerUp.bind(this));\n }\n }\n /**\r\n * @param {PointerEvent} e\r\n */\n\n\n onPointerDown(e) {\n // We do not call preventDefault for touch events\n // to allow browser to show native dialog on longpress\n // (the one that allows to save image or open it in new tab).\n //\n // Desktop Safari allows to drag images when preventDefault isn't called on mousedown,\n // even though preventDefault IS called on mousemove. That's why we preventDefault mousedown.\n const isMousePointer = e.type === 'mousedown' || e.pointerType === 'mouse'; // Allow dragging only via left mouse button.\n // http://www.quirksmode.org/js/events_properties.html\n // https://developer.mozilla.org/en-US/docs/Web/API/event.button\n\n if (isMousePointer && e.button > 0) {\n return;\n }\n\n const {\n pswp\n } = this; // if PhotoSwipe is opening or closing\n\n if (!pswp.opener.isOpen) {\n e.preventDefault();\n return;\n }\n\n if (pswp.dispatch('pointerDown', {\n originalEvent: e\n }).defaultPrevented) {\n return;\n }\n\n if (isMousePointer) {\n pswp.mouseDetected(); // preventDefault mouse event to prevent\n // browser image drag feature\n\n this._preventPointerEventBehaviour(e, 'down');\n }\n\n pswp.animations.stopAll();\n\n this._updatePoints(e, 'down');\n\n if (this._numActivePoints === 1) {\n this.dragAxis = null; // we need to store initial point to determine the main axis,\n // drag is activated only after the axis is determined\n\n equalizePoints(this.startP1, this.p1);\n }\n\n if (this._numActivePoints > 1) {\n // Tap or double tap should not trigger if more than one pointer\n this._clearTapTimer();\n\n this.isMultitouch = true;\n } else {\n this.isMultitouch = false;\n }\n }\n /**\r\n * @param {PointerEvent} e\r\n */\n\n\n onPointerMove(e) {\n this._preventPointerEventBehaviour(e, 'move');\n\n if (!this._numActivePoints) {\n return;\n }\n\n this._updatePoints(e, 'move');\n\n if (this.pswp.dispatch('pointerMove', {\n originalEvent: e\n }).defaultPrevented) {\n return;\n }\n\n if (this._numActivePoints === 1 && !this.isDragging) {\n if (!this.dragAxis) {\n this._calculateDragDirection();\n } // Drag axis was detected, emit drag.start\n\n\n if (this.dragAxis && !this.isDragging) {\n if (this.isZooming) {\n this.isZooming = false;\n this.zoomLevels.end();\n }\n\n this.isDragging = true;\n\n this._clearTapTimer(); // Tap can not trigger after drag\n // Adjust starting point\n\n\n this._updateStartPoints();\n\n this._intervalTime = Date.now(); //this._startTime = this._intervalTime;\n\n this._velocityCalculated = false;\n equalizePoints(this._intervalP1, this.p1);\n this.velocity.x = 0;\n this.velocity.y = 0;\n this.drag.start();\n\n this._rafStopLoop();\n\n this._rafRenderLoop();\n }\n } else if (this._numActivePoints > 1 && !this.isZooming) {\n this._finishDrag();\n\n this.isZooming = true; // Adjust starting points\n\n this._updateStartPoints();\n\n this.zoomLevels.start();\n\n this._rafStopLoop();\n\n this._rafRenderLoop();\n }\n }\n /**\r\n * @private\r\n */\n\n\n _finishDrag() {\n if (this.isDragging) {\n this.isDragging = false; // Try to calculate velocity,\n // if it wasn't calculated yet in drag.change\n\n if (!this._velocityCalculated) {\n this._updateVelocity(true);\n }\n\n this.drag.end();\n this.dragAxis = null;\n }\n }\n /**\r\n * @param {PointerEvent} e\r\n */\n\n\n onPointerUp(e) {\n if (!this._numActivePoints) {\n return;\n }\n\n this._updatePoints(e, 'up');\n\n if (this.pswp.dispatch('pointerUp', {\n originalEvent: e\n }).defaultPrevented) {\n return;\n }\n\n if (this._numActivePoints === 0) {\n this._rafStopLoop();\n\n if (this.isDragging) {\n this._finishDrag();\n } else if (!this.isZooming && !this.isMultitouch) {\n //this.zoomLevels.correctZoomPan();\n this._finishTap(e);\n }\n }\n\n if (this._numActivePoints < 2 && this.isZooming) {\n this.isZooming = false;\n this.zoomLevels.end();\n\n if (this._numActivePoints === 1) {\n // Since we have 1 point left, we need to reinitiate drag\n this.dragAxis = null;\n\n this._updateStartPoints();\n }\n }\n }\n /**\r\n * @private\r\n */\n\n\n _rafRenderLoop() {\n if (this.isDragging || this.isZooming) {\n this._updateVelocity();\n\n if (this.isDragging) {\n // make sure that pointer moved since the last update\n if (!pointsEqual(this.p1, this.prevP1)) {\n this.drag.change();\n }\n } else\n /* if (this.isZooming) */\n {\n if (!pointsEqual(this.p1, this.prevP1) || !pointsEqual(this.p2, this.prevP2)) {\n this.zoomLevels.change();\n }\n }\n\n this._updatePrevPoints();\n\n this.raf = requestAnimationFrame(this._rafRenderLoop.bind(this));\n }\n }\n /**\r\n * Update velocity at 50ms interval\r\n *\r\n * @private\r\n * @param {boolean} [force]\r\n */\n\n\n _updateVelocity(force) {\n const time = Date.now();\n const duration = time - this._intervalTime;\n\n if (duration < 50 && !force) {\n return;\n }\n\n this.velocity.x = this._getVelocity('x', duration);\n this.velocity.y = this._getVelocity('y', duration);\n this._intervalTime = time;\n equalizePoints(this._intervalP1, this.p1);\n this._velocityCalculated = true;\n }\n /**\r\n * @private\r\n * @param {PointerEvent} e\r\n */\n\n\n _finishTap(e) {\n const {\n mainScroll\n } = this.pswp; // Do not trigger tap events if main scroll is shifted\n\n if (mainScroll.isShifted()) {\n // restore main scroll position\n // (usually happens if stopped in the middle of animation)\n mainScroll.moveIndexBy(0, true);\n return;\n } // Do not trigger tap for touchcancel or pointercancel\n\n\n if (e.type.indexOf('cancel') > 0) {\n return;\n } // Trigger click instead of tap for mouse events\n\n\n if (e.type === 'mouseup' || e.pointerType === 'mouse') {\n this.tapHandler.click(this.startP1, e);\n return;\n } // Disable delay if there is no doubleTapAction\n\n\n const tapDelay = this.pswp.options.doubleTapAction ? DOUBLE_TAP_DELAY : 0; // If tapTimer is defined - we tapped recently,\n // check if the current tap is close to the previous one,\n // if yes - trigger double tap\n\n if (this._tapTimer) {\n this._clearTapTimer(); // Check if two taps were more or less on the same place\n\n\n if (getDistanceBetween(this._lastStartP1, this.startP1) < MIN_TAP_DISTANCE) {\n this.tapHandler.doubleTap(this.startP1, e);\n }\n } else {\n equalizePoints(this._lastStartP1, this.startP1);\n this._tapTimer = setTimeout(() => {\n this.tapHandler.tap(this.startP1, e);\n\n this._clearTapTimer();\n }, tapDelay);\n }\n }\n /**\r\n * @private\r\n */\n\n\n _clearTapTimer() {\n if (this._tapTimer) {\n clearTimeout(this._tapTimer);\n this._tapTimer = null;\n }\n }\n /**\r\n * Get velocity for axis\r\n *\r\n * @private\r\n * @param {'x' | 'y'} axis\r\n * @param {number} duration\r\n * @returns {number}\r\n */\n\n\n _getVelocity(axis, duration) {\n // displacement is like distance, but can be negative.\n const displacement = this.p1[axis] - this._intervalP1[axis];\n\n if (Math.abs(displacement) > 1 && duration > 5) {\n return displacement / duration;\n }\n\n return 0;\n }\n /**\r\n * @private\r\n */\n\n\n _rafStopLoop() {\n if (this.raf) {\n cancelAnimationFrame(this.raf);\n this.raf = null;\n }\n }\n /**\r\n * @private\r\n * @param {PointerEvent} e\r\n * @param {'up' | 'down' | 'move'} pointerType Normalized pointer type\r\n */\n\n\n _preventPointerEventBehaviour(e, pointerType) {\n const preventPointerEvent = this.pswp.applyFilters('preventPointerEvent', true, e, pointerType);\n\n if (preventPointerEvent) {\n e.preventDefault();\n }\n }\n /**\r\n * Parses and normalizes points from the touch, mouse or pointer event.\r\n * Updates p1 and p2.\r\n *\r\n * @private\r\n * @param {PointerEvent | TouchEvent} e\r\n * @param {'up' | 'down' | 'move'} pointerType Normalized pointer type\r\n */\n\n\n _updatePoints(e, pointerType) {\n if (this._pointerEventEnabled) {\n const pointerEvent =\n /** @type {PointerEvent} */\n e; // Try to find the current pointer in ongoing pointers by its ID\n\n const pointerIndex = this._ongoingPointers.findIndex(ongoingPointer => {\n return ongoingPointer.id === pointerEvent.pointerId;\n });\n\n if (pointerType === 'up' && pointerIndex > -1) {\n // release the pointer - remove it from ongoing\n this._ongoingPointers.splice(pointerIndex, 1);\n } else if (pointerType === 'down' && pointerIndex === -1) {\n // add new pointer\n this._ongoingPointers.push(this._convertEventPosToPoint(pointerEvent, {\n x: 0,\n y: 0\n }));\n } else if (pointerIndex > -1) {\n // update existing pointer\n this._convertEventPosToPoint(pointerEvent, this._ongoingPointers[pointerIndex]);\n }\n\n this._numActivePoints = this._ongoingPointers.length; // update points that PhotoSwipe uses\n // to calculate position and scale\n\n if (this._numActivePoints > 0) {\n equalizePoints(this.p1, this._ongoingPointers[0]);\n }\n\n if (this._numActivePoints > 1) {\n equalizePoints(this.p2, this._ongoingPointers[1]);\n }\n } else {\n const touchEvent =\n /** @type {TouchEvent} */\n e;\n this._numActivePoints = 0;\n\n if (touchEvent.type.indexOf('touch') > -1) {\n // Touch Event\n // https://developer.mozilla.org/en-US/docs/Web/API/TouchEvent\n if (touchEvent.touches && touchEvent.touches.length > 0) {\n this._convertEventPosToPoint(touchEvent.touches[0], this.p1);\n\n this._numActivePoints++;\n\n if (touchEvent.touches.length > 1) {\n this._convertEventPosToPoint(touchEvent.touches[1], this.p2);\n\n this._numActivePoints++;\n }\n }\n } else {\n // Mouse Event\n this._convertEventPosToPoint(\n /** @type {PointerEvent} */\n e, this.p1);\n\n if (pointerType === 'up') {\n // clear all points on mouseup\n this._numActivePoints = 0;\n } else {\n this._numActivePoints++;\n }\n }\n }\n }\n /** update points that were used during previous rAF tick\r\n * @private\r\n */\n\n\n _updatePrevPoints() {\n equalizePoints(this.prevP1, this.p1);\n equalizePoints(this.prevP2, this.p2);\n }\n /** update points at the start of gesture\r\n * @private\r\n */\n\n\n _updateStartPoints() {\n equalizePoints(this.startP1, this.p1);\n equalizePoints(this.startP2, this.p2);\n\n this._updatePrevPoints();\n }\n /** @private */\n\n\n _calculateDragDirection() {\n if (this.pswp.mainScroll.isShifted()) {\n // if main scroll position is shifted – direction is always horizontal\n this.dragAxis = 'x';\n } else {\n // calculate delta of the last touchmove tick\n const diff = Math.abs(this.p1.x - this.startP1.x) - Math.abs(this.p1.y - this.startP1.y);\n\n if (diff !== 0) {\n // check if pointer was shifted horizontally or vertically\n const axisToCheck = diff > 0 ? 'x' : 'y';\n\n if (Math.abs(this.p1[axisToCheck] - this.startP1[axisToCheck]) >= AXIS_SWIPE_HYSTERISIS) {\n this.dragAxis = axisToCheck;\n }\n }\n }\n }\n /**\r\n * Converts touch, pointer or mouse event\r\n * to PhotoSwipe point.\r\n *\r\n * @private\r\n * @param {Touch | PointerEvent} e\r\n * @param {Point} p\r\n * @returns {Point}\r\n */\n\n\n _convertEventPosToPoint(e, p) {\n p.x = e.pageX - this.pswp.offset.x;\n p.y = e.pageY - this.pswp.offset.y;\n\n if ('pointerId' in e) {\n p.id = e.pointerId;\n } else if (e.identifier !== undefined) {\n p.id = e.identifier;\n }\n\n return p;\n }\n /**\r\n * @private\r\n * @param {PointerEvent} e\r\n */\n\n\n _onClick(e) {\n // Do not allow click event to pass through after drag\n if (this.pswp.mainScroll.isShifted()) {\n e.preventDefault();\n e.stopPropagation();\n }\n }\n\n}\n\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('./slide/slide.js').default} Slide */\n\n/** @typedef {{ el: HTMLDivElement; slide?: Slide }} ItemHolder */\n\nconst MAIN_SCROLL_END_FRICTION = 0.35; // const MIN_SWIPE_TRANSITION_DURATION = 250;\n// const MAX_SWIPE_TRABSITION_DURATION = 500;\n// const DEFAULT_SWIPE_TRANSITION_DURATION = 333;\n\n/**\r\n * Handles movement of the main scrolling container\r\n * (for example, it repositions when user swipes left or right).\r\n *\r\n * Also stores its state.\r\n */\n\nclass MainScroll {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp;\n this.x = 0;\n this.slideWidth = 0;\n /** @private */\n\n this._currPositionIndex = 0;\n /** @private */\n\n this._prevPositionIndex = 0;\n /** @private */\n\n this._containerShiftIndex = -1;\n /** @type {ItemHolder[]} */\n\n this.itemHolders = [];\n }\n /**\r\n * Position the scroller and slide containers\r\n * according to viewport size.\r\n *\r\n * @param {boolean} [resizeSlides] Whether slides content should resized\r\n */\n\n\n resize(resizeSlides) {\n const {\n pswp\n } = this;\n const newSlideWidth = Math.round(pswp.viewportSize.x + pswp.viewportSize.x * pswp.options.spacing); // Mobile browsers might trigger a resize event during a gesture.\n // (due to toolbar appearing or hiding).\n // Avoid re-adjusting main scroll position if width wasn't changed\n\n const slideWidthChanged = newSlideWidth !== this.slideWidth;\n\n if (slideWidthChanged) {\n this.slideWidth = newSlideWidth;\n this.moveTo(this.getCurrSlideX());\n }\n\n this.itemHolders.forEach((itemHolder, index) => {\n if (slideWidthChanged) {\n setTransform(itemHolder.el, (index + this._containerShiftIndex) * this.slideWidth);\n }\n\n if (resizeSlides && itemHolder.slide) {\n itemHolder.slide.resize();\n }\n });\n }\n /**\r\n * Reset X position of the main scroller to zero\r\n */\n\n\n resetPosition() {\n // Position on the main scroller (offset)\n // it is independent from slide index\n this._currPositionIndex = 0;\n this._prevPositionIndex = 0; // This will force recalculation of size on next resize()\n\n this.slideWidth = 0; // _containerShiftIndex*viewportSize will give you amount of transform of the current slide\n\n this._containerShiftIndex = -1;\n }\n /**\r\n * Create and append array of three items\r\n * that hold data about slides in DOM\r\n */\n\n\n appendHolders() {\n this.itemHolders = []; // append our three slide holders -\n // previous, current, and next\n\n for (let i = 0; i < 3; i++) {\n const el = createElement('pswp__item', 'div', this.pswp.container);\n el.setAttribute('role', 'group');\n el.setAttribute('aria-roledescription', 'slide');\n el.setAttribute('aria-hidden', 'true'); // hide nearby item holders until initial zoom animation finishes (to avoid extra Paints)\n\n el.style.display = i === 1 ? 'block' : 'none';\n this.itemHolders.push({\n el //index: -1\n\n });\n }\n }\n /**\r\n * Whether the main scroll can be horizontally swiped to the next or previous slide.\r\n * @returns {boolean}\r\n */\n\n\n canBeSwiped() {\n return this.pswp.getNumItems() > 1;\n }\n /**\r\n * Move main scroll by X amount of slides.\r\n * For example:\r\n * `-1` will move to the previous slide,\r\n * `0` will reset the scroll position of the current slide,\r\n * `3` will move three slides forward\r\n *\r\n * If loop option is enabled - index will be automatically looped too,\r\n * (for example `-1` will move to the last slide of the gallery).\r\n *\r\n * @param {number} diff\r\n * @param {boolean} [animate]\r\n * @param {number} [velocityX]\r\n * @returns {boolean} whether index was changed or not\r\n */\n\n\n moveIndexBy(diff, animate, velocityX) {\n const {\n pswp\n } = this;\n let newIndex = pswp.potentialIndex + diff;\n const numSlides = pswp.getNumItems();\n\n if (pswp.canLoop()) {\n newIndex = pswp.getLoopedIndex(newIndex);\n const distance = (diff + numSlides) % numSlides;\n\n if (distance <= numSlides / 2) {\n // go forward\n diff = distance;\n } else {\n // go backwards\n diff = distance - numSlides;\n }\n } else {\n if (newIndex < 0) {\n newIndex = 0;\n } else if (newIndex >= numSlides) {\n newIndex = numSlides - 1;\n }\n\n diff = newIndex - pswp.potentialIndex;\n }\n\n pswp.potentialIndex = newIndex;\n this._currPositionIndex -= diff;\n pswp.animations.stopMainScroll();\n const destinationX = this.getCurrSlideX();\n\n if (!animate) {\n this.moveTo(destinationX);\n this.updateCurrItem();\n } else {\n pswp.animations.startSpring({\n isMainScroll: true,\n start: this.x,\n end: destinationX,\n velocity: velocityX || 0,\n naturalFrequency: 30,\n dampingRatio: 1,\n //0.7,\n onUpdate: x => {\n this.moveTo(x);\n },\n onComplete: () => {\n this.updateCurrItem();\n pswp.appendHeavy();\n }\n });\n let currDiff = pswp.potentialIndex - pswp.currIndex;\n\n if (pswp.canLoop()) {\n const currDistance = (currDiff + numSlides) % numSlides;\n\n if (currDistance <= numSlides / 2) {\n // go forward\n currDiff = currDistance;\n } else {\n // go backwards\n currDiff = currDistance - numSlides;\n }\n } // Force-append new slides during transition\n // if difference between slides is more than 1\n\n\n if (Math.abs(currDiff) > 1) {\n this.updateCurrItem();\n }\n }\n\n return Boolean(diff);\n }\n /**\r\n * X position of the main scroll for the current slide\r\n * (ignores position during dragging)\r\n * @returns {number}\r\n */\n\n\n getCurrSlideX() {\n return this.slideWidth * this._currPositionIndex;\n }\n /**\r\n * Whether scroll position is shifted.\r\n * For example, it will return true if the scroll is being dragged or animated.\r\n * @returns {boolean}\r\n */\n\n\n isShifted() {\n return this.x !== this.getCurrSlideX();\n }\n /**\r\n * Update slides X positions and set their content\r\n */\n\n\n updateCurrItem() {\n var _this$itemHolders$;\n\n const {\n pswp\n } = this;\n const positionDifference = this._prevPositionIndex - this._currPositionIndex;\n\n if (!positionDifference) {\n return;\n }\n\n this._prevPositionIndex = this._currPositionIndex;\n pswp.currIndex = pswp.potentialIndex;\n let diffAbs = Math.abs(positionDifference);\n /** @type {ItemHolder | undefined} */\n\n let tempHolder;\n\n if (diffAbs >= 3) {\n this._containerShiftIndex += positionDifference + (positionDifference > 0 ? -3 : 3);\n diffAbs = 3; // If slides are changed by 3 screens or more - clean up previous slides\n\n this.itemHolders.forEach(itemHolder => {\n var _itemHolder$slide;\n\n (_itemHolder$slide = itemHolder.slide) === null || _itemHolder$slide === void 0 || _itemHolder$slide.destroy();\n itemHolder.slide = undefined;\n });\n }\n\n for (let i = 0; i < diffAbs; i++) {\n if (positionDifference > 0) {\n tempHolder = this.itemHolders.shift();\n\n if (tempHolder) {\n this.itemHolders[2] = tempHolder; // move first to last\n\n this._containerShiftIndex++;\n setTransform(tempHolder.el, (this._containerShiftIndex + 2) * this.slideWidth);\n pswp.setContent(tempHolder, pswp.currIndex - diffAbs + i + 2);\n }\n } else {\n tempHolder = this.itemHolders.pop();\n\n if (tempHolder) {\n this.itemHolders.unshift(tempHolder); // move last to first\n\n this._containerShiftIndex--;\n setTransform(tempHolder.el, this._containerShiftIndex * this.slideWidth);\n pswp.setContent(tempHolder, pswp.currIndex + diffAbs - i - 2);\n }\n }\n } // Reset transfrom every 50ish navigations in one direction.\n //\n // Otherwise transform will keep growing indefinitely,\n // which might cause issues as browsers have a maximum transform limit.\n // I wasn't able to reach it, but just to be safe.\n // This should not cause noticable lag.\n\n\n if (Math.abs(this._containerShiftIndex) > 50 && !this.isShifted()) {\n this.resetPosition();\n this.resize();\n } // Pan transition might be running (and consntantly updating pan position)\n\n\n pswp.animations.stopAllPan();\n this.itemHolders.forEach((itemHolder, i) => {\n if (itemHolder.slide) {\n // Slide in the 2nd holder is always active\n itemHolder.slide.setIsActive(i === 1);\n }\n });\n pswp.currSlide = (_this$itemHolders$ = this.itemHolders[1]) === null || _this$itemHolders$ === void 0 ? void 0 : _this$itemHolders$.slide;\n pswp.contentLoader.updateLazy(positionDifference);\n\n if (pswp.currSlide) {\n pswp.currSlide.applyCurrentZoomPan();\n }\n\n pswp.dispatch('change');\n }\n /**\r\n * Move the X position of the main scroll container\r\n *\r\n * @param {number} x\r\n * @param {boolean} [dragging]\r\n */\n\n\n moveTo(x, dragging) {\n if (!this.pswp.canLoop() && dragging) {\n // Apply friction\n let newSlideIndexOffset = (this.slideWidth * this._currPositionIndex - x) / this.slideWidth;\n newSlideIndexOffset += this.pswp.currIndex;\n const delta = Math.round(x - this.x);\n\n if (newSlideIndexOffset < 0 && delta > 0 || newSlideIndexOffset >= this.pswp.getNumItems() - 1 && delta < 0) {\n x = this.x + delta * MAIN_SCROLL_END_FRICTION;\n }\n }\n\n this.x = x;\n\n if (this.pswp.container) {\n setTransform(this.pswp.container, x);\n }\n\n this.pswp.dispatch('moveMainScroll', {\n x,\n dragging: dragging !== null && dragging !== void 0 ? dragging : false\n });\n }\n\n}\n\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\n\n/**\r\n * @template T\r\n * @typedef {import('./types.js').Methods} Methods\r\n */\n\nconst KeyboardKeyCodesMap = {\n Escape: 27,\n z: 90,\n ArrowLeft: 37,\n ArrowUp: 38,\n ArrowRight: 39,\n ArrowDown: 40,\n Tab: 9\n};\n/**\r\n * @template {keyof KeyboardKeyCodesMap} T\r\n * @param {T} key\r\n * @param {boolean} isKeySupported\r\n * @returns {T | number | undefined}\r\n */\n\nconst getKeyboardEventKey = (key, isKeySupported) => {\n return isKeySupported ? key : KeyboardKeyCodesMap[key];\n};\n/**\r\n * - Manages keyboard shortcuts.\r\n * - Helps trap focus within photoswipe.\r\n */\n\n\nclass Keyboard {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp;\n /** @private */\n\n this._wasFocused = false;\n pswp.on('bindEvents', () => {\n if (pswp.options.trapFocus) {\n // Dialog was likely opened by keyboard if initial point is not defined\n if (!pswp.options.initialPointerPos) {\n // focus causes layout,\n // which causes lag during the animation,\n // that's why we delay it until the opener transition ends\n this._focusRoot();\n }\n\n pswp.events.add(document, 'focusin',\n /** @type EventListener */\n this._onFocusIn.bind(this));\n }\n\n pswp.events.add(document, 'keydown',\n /** @type EventListener */\n this._onKeyDown.bind(this));\n });\n const lastActiveElement =\n /** @type {HTMLElement} */\n document.activeElement;\n pswp.on('destroy', () => {\n if (pswp.options.returnFocus && lastActiveElement && this._wasFocused) {\n lastActiveElement.focus();\n }\n });\n }\n /** @private */\n\n\n _focusRoot() {\n if (!this._wasFocused && this.pswp.element) {\n this.pswp.element.focus();\n this._wasFocused = true;\n }\n }\n /**\r\n * @private\r\n * @param {KeyboardEvent} e\r\n */\n\n\n _onKeyDown(e) {\n const {\n pswp\n } = this;\n\n if (pswp.dispatch('keydown', {\n originalEvent: e\n }).defaultPrevented) {\n return;\n }\n\n if (specialKeyUsed(e)) {\n // don't do anything if special key pressed\n // to prevent from overriding default browser actions\n // for example, in Chrome on Mac cmd+arrow-left returns to previous page\n return;\n }\n /** @type {Methods | undefined} */\n\n\n let keydownAction;\n /** @type {'x' | 'y' | undefined} */\n\n let axis;\n let isForward = false;\n const isKeySupported = ('key' in e);\n\n switch (isKeySupported ? e.key : e.keyCode) {\n case getKeyboardEventKey('Escape', isKeySupported):\n if (pswp.options.escKey) {\n keydownAction = 'close';\n }\n\n break;\n\n case getKeyboardEventKey('z', isKeySupported):\n keydownAction = 'toggleZoom';\n break;\n\n case getKeyboardEventKey('ArrowLeft', isKeySupported):\n axis = 'x';\n break;\n\n case getKeyboardEventKey('ArrowUp', isKeySupported):\n axis = 'y';\n break;\n\n case getKeyboardEventKey('ArrowRight', isKeySupported):\n axis = 'x';\n isForward = true;\n break;\n\n case getKeyboardEventKey('ArrowDown', isKeySupported):\n isForward = true;\n axis = 'y';\n break;\n\n case getKeyboardEventKey('Tab', isKeySupported):\n this._focusRoot();\n\n break;\n } // if left/right/top/bottom key\n\n\n if (axis) {\n // prevent page scroll\n e.preventDefault();\n const {\n currSlide\n } = pswp;\n\n if (pswp.options.arrowKeys && axis === 'x' && pswp.getNumItems() > 1) {\n keydownAction = isForward ? 'next' : 'prev';\n } else if (currSlide && currSlide.currZoomLevel > currSlide.zoomLevels.fit) {\n // up/down arrow keys pan the image vertically\n // left/right arrow keys pan horizontally.\n // Unless there is only one image,\n // or arrowKeys option is disabled\n currSlide.pan[axis] += isForward ? -80 : 80;\n currSlide.panTo(currSlide.pan.x, currSlide.pan.y);\n }\n }\n\n if (keydownAction) {\n e.preventDefault(); // @ts-ignore\n\n pswp[keydownAction]();\n }\n }\n /**\r\n * Trap focus inside photoswipe\r\n *\r\n * @private\r\n * @param {FocusEvent} e\r\n */\n\n\n _onFocusIn(e) {\n const {\n template\n } = this.pswp;\n\n if (template && document !== e.target && template !== e.target && !template.contains(\n /** @type {Node} */\n e.target)) {\n // focus root element\n template.focus();\n }\n }\n\n}\n\nconst DEFAULT_EASING = 'cubic-bezier(.4,0,.22,1)';\n/** @typedef {import('./animations.js').SharedAnimationProps} SharedAnimationProps */\n\n/** @typedef {Object} DefaultCssAnimationProps\r\n *\r\n * @prop {HTMLElement} target\r\n * @prop {number} [duration]\r\n * @prop {string} [easing]\r\n * @prop {string} [transform]\r\n * @prop {string} [opacity]\r\n * */\n\n/** @typedef {SharedAnimationProps & DefaultCssAnimationProps} CssAnimationProps */\n\n/**\r\n * Runs CSS transition.\r\n */\n\nclass CSSAnimation {\n /**\r\n * onComplete can be unpredictable, be careful about current state\r\n *\r\n * @param {CssAnimationProps} props\r\n */\n constructor(props) {\n var _props$prop;\n\n this.props = props;\n const {\n target,\n onComplete,\n transform,\n onFinish = () => {},\n duration = 333,\n easing = DEFAULT_EASING\n } = props;\n this.onFinish = onFinish; // support only transform and opacity\n\n const prop = transform ? 'transform' : 'opacity';\n const propValue = (_props$prop = props[prop]) !== null && _props$prop !== void 0 ? _props$prop : '';\n /** @private */\n\n this._target = target;\n /** @private */\n\n this._onComplete = onComplete;\n /** @private */\n\n this._finished = false;\n /** @private */\n\n this._onTransitionEnd = this._onTransitionEnd.bind(this); // Using timeout hack to make sure that animation\n // starts even if the animated property was changed recently,\n // otherwise transitionend might not fire or transition won't start.\n // https://drafts.csswg.org/css-transitions/#starting\n //\n // ¯\\_(ツ)_/¯\n\n /** @private */\n\n this._helperTimeout = setTimeout(() => {\n setTransitionStyle(target, prop, duration, easing);\n this._helperTimeout = setTimeout(() => {\n target.addEventListener('transitionend', this._onTransitionEnd, false);\n target.addEventListener('transitioncancel', this._onTransitionEnd, false); // Safari occasionally does not emit transitionend event\n // if element property was modified during the transition,\n // which may be caused by resize or third party component,\n // using timeout as a safety fallback\n\n this._helperTimeout = setTimeout(() => {\n this._finalizeAnimation();\n }, duration + 500);\n target.style[prop] = propValue;\n }, 30); // Do not reduce this number\n }, 0);\n }\n /**\r\n * @private\r\n * @param {TransitionEvent} e\r\n */\n\n\n _onTransitionEnd(e) {\n if (e.target === this._target) {\n this._finalizeAnimation();\n }\n }\n /**\r\n * @private\r\n */\n\n\n _finalizeAnimation() {\n if (!this._finished) {\n this._finished = true;\n this.onFinish();\n\n if (this._onComplete) {\n this._onComplete();\n }\n }\n } // Destroy is called automatically onFinish\n\n\n destroy() {\n if (this._helperTimeout) {\n clearTimeout(this._helperTimeout);\n }\n\n removeTransitionStyle(this._target);\n\n this._target.removeEventListener('transitionend', this._onTransitionEnd, false);\n\n this._target.removeEventListener('transitioncancel', this._onTransitionEnd, false);\n\n if (!this._finished) {\n this._finalizeAnimation();\n }\n }\n\n}\n\nconst DEFAULT_NATURAL_FREQUENCY = 12;\nconst DEFAULT_DAMPING_RATIO = 0.75;\n/**\r\n * Spring easing helper\r\n */\n\nclass SpringEaser {\n /**\r\n * @param {number} initialVelocity Initial velocity, px per ms.\r\n *\r\n * @param {number} [dampingRatio]\r\n * Determines how bouncy animation will be.\r\n * From 0 to 1, 0 - always overshoot, 1 - do not overshoot.\r\n * \"overshoot\" refers to part of animation that\r\n * goes beyond the final value.\r\n *\r\n * @param {number} [naturalFrequency]\r\n * Determines how fast animation will slow down.\r\n * The higher value - the stiffer the transition will be,\r\n * and the faster it will slow down.\r\n * Recommended value from 10 to 50\r\n */\n constructor(initialVelocity, dampingRatio, naturalFrequency) {\n this.velocity = initialVelocity * 1000; // convert to \"pixels per second\"\n // https://en.wikipedia.org/wiki/Damping_ratio\n\n this._dampingRatio = dampingRatio || DEFAULT_DAMPING_RATIO; // https://en.wikipedia.org/wiki/Natural_frequency\n\n this._naturalFrequency = naturalFrequency || DEFAULT_NATURAL_FREQUENCY;\n this._dampedFrequency = this._naturalFrequency;\n\n if (this._dampingRatio < 1) {\n this._dampedFrequency *= Math.sqrt(1 - this._dampingRatio * this._dampingRatio);\n }\n }\n /**\r\n * @param {number} deltaPosition Difference between current and end position of the animation\r\n * @param {number} deltaTime Frame duration in milliseconds\r\n *\r\n * @returns {number} Displacement, relative to the end position.\r\n */\n\n\n easeFrame(deltaPosition, deltaTime) {\n // Inspired by Apple Webkit and Android spring function implementation\n // https://en.wikipedia.org/wiki/Oscillation\n // https://en.wikipedia.org/wiki/Damping_ratio\n // we ignore mass (assume that it's 1kg)\n let displacement = 0;\n let coeff;\n deltaTime /= 1000;\n const naturalDumpingPow = Math.E ** (-this._dampingRatio * this._naturalFrequency * deltaTime);\n\n if (this._dampingRatio === 1) {\n coeff = this.velocity + this._naturalFrequency * deltaPosition;\n displacement = (deltaPosition + coeff * deltaTime) * naturalDumpingPow;\n this.velocity = displacement * -this._naturalFrequency + coeff * naturalDumpingPow;\n } else if (this._dampingRatio < 1) {\n coeff = 1 / this._dampedFrequency * (this._dampingRatio * this._naturalFrequency * deltaPosition + this.velocity);\n const dumpedFCos = Math.cos(this._dampedFrequency * deltaTime);\n const dumpedFSin = Math.sin(this._dampedFrequency * deltaTime);\n displacement = naturalDumpingPow * (deltaPosition * dumpedFCos + coeff * dumpedFSin);\n this.velocity = displacement * -this._naturalFrequency * this._dampingRatio + naturalDumpingPow * (-this._dampedFrequency * deltaPosition * dumpedFSin + this._dampedFrequency * coeff * dumpedFCos);\n } // Overdamped (>1) damping ratio is not supported\n\n\n return displacement;\n }\n\n}\n\n/** @typedef {import('./animations.js').SharedAnimationProps} SharedAnimationProps */\n\n/**\r\n * @typedef {Object} DefaultSpringAnimationProps\r\n *\r\n * @prop {number} start\r\n * @prop {number} end\r\n * @prop {number} velocity\r\n * @prop {number} [dampingRatio]\r\n * @prop {number} [naturalFrequency]\r\n * @prop {(end: number) => void} onUpdate\r\n */\n\n/** @typedef {SharedAnimationProps & DefaultSpringAnimationProps} SpringAnimationProps */\n\nclass SpringAnimation {\n /**\r\n * @param {SpringAnimationProps} props\r\n */\n constructor(props) {\n this.props = props;\n this._raf = 0;\n const {\n start,\n end,\n velocity,\n onUpdate,\n onComplete,\n onFinish = () => {},\n dampingRatio,\n naturalFrequency\n } = props;\n this.onFinish = onFinish;\n const easer = new SpringEaser(velocity, dampingRatio, naturalFrequency);\n let prevTime = Date.now();\n let deltaPosition = start - end;\n\n const animationLoop = () => {\n if (this._raf) {\n deltaPosition = easer.easeFrame(deltaPosition, Date.now() - prevTime); // Stop the animation if velocity is low and position is close to end\n\n if (Math.abs(deltaPosition) < 1 && Math.abs(easer.velocity) < 50) {\n // Finalize the animation\n onUpdate(end);\n\n if (onComplete) {\n onComplete();\n }\n\n this.onFinish();\n } else {\n prevTime = Date.now();\n onUpdate(deltaPosition + end);\n this._raf = requestAnimationFrame(animationLoop);\n }\n }\n };\n\n this._raf = requestAnimationFrame(animationLoop);\n } // Destroy is called automatically onFinish\n\n\n destroy() {\n if (this._raf >= 0) {\n cancelAnimationFrame(this._raf);\n }\n\n this._raf = 0;\n }\n\n}\n\n/** @typedef {import('./css-animation.js').CssAnimationProps} CssAnimationProps */\n\n/** @typedef {import('./spring-animation.js').SpringAnimationProps} SpringAnimationProps */\n\n/** @typedef {Object} SharedAnimationProps\r\n * @prop {string} [name]\r\n * @prop {boolean} [isPan]\r\n * @prop {boolean} [isMainScroll]\r\n * @prop {VoidFunction} [onComplete]\r\n * @prop {VoidFunction} [onFinish]\r\n */\n\n/** @typedef {SpringAnimation | CSSAnimation} Animation */\n\n/** @typedef {SpringAnimationProps | CssAnimationProps} AnimationProps */\n\n/**\r\n * Manages animations\r\n */\n\nclass Animations {\n constructor() {\n /** @type {Animation[]} */\n this.activeAnimations = [];\n }\n /**\r\n * @param {SpringAnimationProps} props\r\n */\n\n\n startSpring(props) {\n this._start(props, true);\n }\n /**\r\n * @param {CssAnimationProps} props\r\n */\n\n\n startTransition(props) {\n this._start(props);\n }\n /**\r\n * @private\r\n * @param {AnimationProps} props\r\n * @param {boolean} [isSpring]\r\n * @returns {Animation}\r\n */\n\n\n _start(props, isSpring) {\n const animation = isSpring ? new SpringAnimation(\n /** @type SpringAnimationProps */\n props) : new CSSAnimation(\n /** @type CssAnimationProps */\n props);\n this.activeAnimations.push(animation);\n\n animation.onFinish = () => this.stop(animation);\n\n return animation;\n }\n /**\r\n * @param {Animation} animation\r\n */\n\n\n stop(animation) {\n animation.destroy();\n const index = this.activeAnimations.indexOf(animation);\n\n if (index > -1) {\n this.activeAnimations.splice(index, 1);\n }\n }\n\n stopAll() {\n // _stopAllAnimations\n this.activeAnimations.forEach(animation => {\n animation.destroy();\n });\n this.activeAnimations = [];\n }\n /**\r\n * Stop all pan or zoom transitions\r\n */\n\n\n stopAllPan() {\n this.activeAnimations = this.activeAnimations.filter(animation => {\n if (animation.props.isPan) {\n animation.destroy();\n return false;\n }\n\n return true;\n });\n }\n\n stopMainScroll() {\n this.activeAnimations = this.activeAnimations.filter(animation => {\n if (animation.props.isMainScroll) {\n animation.destroy();\n return false;\n }\n\n return true;\n });\n }\n /**\r\n * Returns true if main scroll transition is running\r\n */\n // isMainScrollRunning() {\n // return this.activeAnimations.some((animation) => {\n // return animation.props.isMainScroll;\n // });\n // }\n\n /**\r\n * Returns true if any pan or zoom transition is running\r\n */\n\n\n isPanRunning() {\n return this.activeAnimations.some(animation => {\n return animation.props.isPan;\n });\n }\n\n}\n\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\n\n/**\r\n * Handles scroll wheel.\r\n * Can pan and zoom current slide image.\r\n */\nclass ScrollWheel {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp;\n pswp.events.add(pswp.element, 'wheel',\n /** @type EventListener */\n this._onWheel.bind(this));\n }\n /**\r\n * @private\r\n * @param {WheelEvent} e\r\n */\n\n\n _onWheel(e) {\n e.preventDefault();\n const {\n currSlide\n } = this.pswp;\n let {\n deltaX,\n deltaY\n } = e;\n\n if (!currSlide) {\n return;\n }\n\n if (this.pswp.dispatch('wheel', {\n originalEvent: e\n }).defaultPrevented) {\n return;\n }\n\n if (e.ctrlKey || this.pswp.options.wheelToZoom) {\n // zoom\n if (currSlide.isZoomable()) {\n let zoomFactor = -deltaY;\n\n if (e.deltaMode === 1\n /* DOM_DELTA_LINE */\n ) {\n zoomFactor *= 0.05;\n } else {\n zoomFactor *= e.deltaMode ? 1 : 0.002;\n }\n\n zoomFactor = 2 ** zoomFactor;\n const destZoomLevel = currSlide.currZoomLevel * zoomFactor;\n currSlide.zoomTo(destZoomLevel, {\n x: e.clientX,\n y: e.clientY\n });\n }\n } else {\n // pan\n if (currSlide.isPannable()) {\n if (e.deltaMode === 1\n /* DOM_DELTA_LINE */\n ) {\n // 18 - average line height\n deltaX *= 18;\n deltaY *= 18;\n }\n\n currSlide.panTo(currSlide.pan.x - deltaX, currSlide.pan.y - deltaY);\n }\n }\n }\n\n}\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/**\r\n * @template T\r\n * @typedef {import('../types.js').Methods} Methods\r\n */\n\n/**\r\n * @typedef {Object} UIElementMarkupProps\r\n * @prop {boolean} [isCustomSVG]\r\n * @prop {string} inner\r\n * @prop {string} [outlineID]\r\n * @prop {number | string} [size]\r\n */\n\n/**\r\n * @typedef {Object} UIElementData\r\n * @prop {DefaultUIElements | string} [name]\r\n * @prop {string} [className]\r\n * @prop {UIElementMarkup} [html]\r\n * @prop {boolean} [isButton]\r\n * @prop {keyof HTMLElementTagNameMap} [tagName]\r\n * @prop {string} [title]\r\n * @prop {string} [ariaLabel]\r\n * @prop {(element: HTMLElement, pswp: PhotoSwipe) => void} [onInit]\r\n * @prop {Methods | ((e: MouseEvent, element: HTMLElement, pswp: PhotoSwipe) => void)} [onClick]\r\n * @prop {'bar' | 'wrapper' | 'root'} [appendTo]\r\n * @prop {number} [order]\r\n */\n\n/** @typedef {'arrowPrev' | 'arrowNext' | 'close' | 'zoom' | 'counter'} DefaultUIElements */\n\n/** @typedef {string | UIElementMarkupProps} UIElementMarkup */\n\n/**\r\n * @param {UIElementMarkup} [htmlData]\r\n * @returns {string}\r\n */\n\nfunction addElementHTML(htmlData) {\n if (typeof htmlData === 'string') {\n // Allow developers to provide full svg,\n // For example:\n // \n // \n // \n // \n // Can also be any HTML string.\n return htmlData;\n }\n\n if (!htmlData || !htmlData.isCustomSVG) {\n return '';\n }\n\n const svgData = htmlData;\n let out = ''; // replace all %d with size\n\n out = out.split('%d').join(\n /** @type {string} */\n svgData.size || 32); // Icons may contain outline/shadow,\n // to make it we \"clone\" base icon shape and add border to it.\n // Icon itself and border are styled via CSS.\n //\n // Property shadowID defines ID of element that should be cloned.\n\n if (svgData.outlineID) {\n out += '';\n }\n\n out += svgData.inner;\n out += '';\n return out;\n}\n\nclass UIElement {\n /**\r\n * @param {PhotoSwipe} pswp\r\n * @param {UIElementData} data\r\n */\n constructor(pswp, data) {\n var _container;\n\n const name = data.name || data.className;\n let elementHTML = data.html; // @ts-expect-error lookup only by `data.name` maybe?\n\n if (pswp.options[name] === false) {\n // exit if element is disabled from options\n return;\n } // Allow to override SVG icons from options\n // @ts-expect-error lookup only by `data.name` maybe?\n\n\n if (typeof pswp.options[name + 'SVG'] === 'string') {\n // arrowPrevSVG\n // arrowNextSVG\n // closeSVG\n // zoomSVG\n // @ts-expect-error lookup only by `data.name` maybe?\n elementHTML = pswp.options[name + 'SVG'];\n }\n\n pswp.dispatch('uiElementCreate', {\n data\n });\n let className = '';\n\n if (data.isButton) {\n className += 'pswp__button ';\n className += data.className || `pswp__button--${data.name}`;\n } else {\n className += data.className || `pswp__${data.name}`;\n }\n\n let tagName = data.isButton ? data.tagName || 'button' : data.tagName || 'div';\n tagName =\n /** @type {keyof HTMLElementTagNameMap} */\n tagName.toLowerCase();\n /** @type {HTMLElement} */\n\n const element = createElement(className, tagName);\n\n if (data.isButton) {\n if (tagName === 'button') {\n /** @type {HTMLButtonElement} */\n element.type = 'button';\n }\n\n let {\n title\n } = data;\n const {\n ariaLabel\n } = data; // @ts-expect-error lookup only by `data.name` maybe?\n\n if (typeof pswp.options[name + 'Title'] === 'string') {\n // @ts-expect-error lookup only by `data.name` maybe?\n title = pswp.options[name + 'Title'];\n }\n\n if (title) {\n element.title = title;\n }\n\n const ariaText = ariaLabel || title;\n\n if (ariaText) {\n element.setAttribute('aria-label', ariaText);\n }\n }\n\n element.innerHTML = addElementHTML(elementHTML);\n\n if (data.onInit) {\n data.onInit(element, pswp);\n }\n\n if (data.onClick) {\n element.onclick = e => {\n if (typeof data.onClick === 'string') {\n // @ts-ignore\n pswp[data.onClick]();\n } else if (typeof data.onClick === 'function') {\n data.onClick(e, element, pswp);\n }\n };\n } // Top bar is default position\n\n\n const appendTo = data.appendTo || 'bar';\n /** @type {HTMLElement | undefined} root element by default */\n\n let container = pswp.element;\n\n if (appendTo === 'bar') {\n if (!pswp.topBar) {\n pswp.topBar = createElement('pswp__top-bar pswp__hide-on-close', 'div', pswp.scrollWrap);\n }\n\n container = pswp.topBar;\n } else {\n // element outside of top bar gets a secondary class\n // that makes element fade out on close\n element.classList.add('pswp__hide-on-close');\n\n if (appendTo === 'wrapper') {\n container = pswp.scrollWrap;\n }\n }\n\n (_container = container) === null || _container === void 0 || _container.appendChild(pswp.applyFilters('uiElement', element, data));\n }\n\n}\n\n/*\r\n Backward and forward arrow buttons\r\n */\n\n/** @typedef {import('./ui-element.js').UIElementData} UIElementData */\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/**\r\n *\r\n * @param {HTMLElement} element\r\n * @param {PhotoSwipe} pswp\r\n * @param {boolean} [isNextButton]\r\n */\nfunction initArrowButton(element, pswp, isNextButton) {\n element.classList.add('pswp__button--arrow'); // TODO: this should point to a unique id for this instance\n\n element.setAttribute('aria-controls', 'pswp__items');\n pswp.on('change', () => {\n if (!pswp.options.loop) {\n if (isNextButton) {\n /** @type {HTMLButtonElement} */\n element.disabled = !(pswp.currIndex < pswp.getNumItems() - 1);\n } else {\n /** @type {HTMLButtonElement} */\n element.disabled = !(pswp.currIndex > 0);\n }\n }\n });\n}\n/** @type {UIElementData} */\n\n\nconst arrowPrev = {\n name: 'arrowPrev',\n className: 'pswp__button--arrow--prev',\n title: 'Previous',\n order: 10,\n isButton: true,\n appendTo: 'wrapper',\n html: {\n isCustomSVG: true,\n size: 60,\n inner: '',\n outlineID: 'pswp__icn-arrow'\n },\n onClick: 'prev',\n onInit: initArrowButton\n};\n/** @type {UIElementData} */\n\nconst arrowNext = {\n name: 'arrowNext',\n className: 'pswp__button--arrow--next',\n title: 'Next',\n order: 11,\n isButton: true,\n appendTo: 'wrapper',\n html: {\n isCustomSVG: true,\n size: 60,\n inner: '',\n outlineID: 'pswp__icn-arrow'\n },\n onClick: 'next',\n onInit: (el, pswp) => {\n initArrowButton(el, pswp, true);\n }\n};\n\n/** @type {import('./ui-element.js').UIElementData} UIElementData */\nconst closeButton = {\n name: 'close',\n title: 'Close',\n order: 20,\n isButton: true,\n html: {\n isCustomSVG: true,\n inner: '',\n outlineID: 'pswp__icn-close'\n },\n onClick: 'close'\n};\n\n/** @type {import('./ui-element.js').UIElementData} UIElementData */\nconst zoomButton = {\n name: 'zoom',\n title: 'Zoom',\n order: 10,\n isButton: true,\n html: {\n isCustomSVG: true,\n // eslint-disable-next-line max-len\n inner: '' + '' + '',\n outlineID: 'pswp__icn-zoom'\n },\n onClick: 'toggleZoom'\n};\n\n/** @type {import('./ui-element.js').UIElementData} UIElementData */\nconst loadingIndicator = {\n name: 'preloader',\n appendTo: 'bar',\n order: 7,\n html: {\n isCustomSVG: true,\n // eslint-disable-next-line max-len\n inner: '',\n outlineID: 'pswp__icn-loading'\n },\n onInit: (indicatorElement, pswp) => {\n /** @type {boolean | undefined} */\n let isVisible;\n /** @type {NodeJS.Timeout | null} */\n\n let delayTimeout = null;\n /**\r\n * @param {string} className\r\n * @param {boolean} add\r\n */\n\n const toggleIndicatorClass = (className, add) => {\n indicatorElement.classList.toggle('pswp__preloader--' + className, add);\n };\n /**\r\n * @param {boolean} visible\r\n */\n\n\n const setIndicatorVisibility = visible => {\n if (isVisible !== visible) {\n isVisible = visible;\n toggleIndicatorClass('active', visible);\n }\n };\n\n const updatePreloaderVisibility = () => {\n var _pswp$currSlide;\n\n if (!((_pswp$currSlide = pswp.currSlide) !== null && _pswp$currSlide !== void 0 && _pswp$currSlide.content.isLoading())) {\n setIndicatorVisibility(false);\n\n if (delayTimeout) {\n clearTimeout(delayTimeout);\n delayTimeout = null;\n }\n\n return;\n }\n\n if (!delayTimeout) {\n // display loading indicator with delay\n delayTimeout = setTimeout(() => {\n var _pswp$currSlide2;\n\n setIndicatorVisibility(Boolean((_pswp$currSlide2 = pswp.currSlide) === null || _pswp$currSlide2 === void 0 ? void 0 : _pswp$currSlide2.content.isLoading()));\n delayTimeout = null;\n }, pswp.options.preloaderDelay);\n }\n };\n\n pswp.on('change', updatePreloaderVisibility);\n pswp.on('loadComplete', e => {\n if (pswp.currSlide === e.slide) {\n updatePreloaderVisibility();\n }\n }); // expose the method\n\n if (pswp.ui) {\n pswp.ui.updatePreloaderVisibility = updatePreloaderVisibility;\n }\n }\n};\n\n/** @type {import('./ui-element.js').UIElementData} UIElementData */\nconst counterIndicator = {\n name: 'counter',\n order: 5,\n onInit: (counterElement, pswp) => {\n pswp.on('change', () => {\n counterElement.innerText = pswp.currIndex + 1 + pswp.options.indexIndicatorSep + pswp.getNumItems();\n });\n }\n};\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('./ui-element.js').UIElementData} UIElementData */\n\n/**\r\n * Set special class on element when image is zoomed.\r\n *\r\n * By default, it is used to adjust\r\n * zoom icon and zoom cursor via CSS.\r\n *\r\n * @param {HTMLElement} el\r\n * @param {boolean} isZoomedIn\r\n */\n\nfunction setZoomedIn(el, isZoomedIn) {\n el.classList.toggle('pswp--zoomed-in', isZoomedIn);\n}\n\nclass UI {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp;\n this.isRegistered = false;\n /** @type {UIElementData[]} */\n\n this.uiElementsData = [];\n /** @type {(UIElement | UIElementData)[]} */\n\n this.items = [];\n /** @type {() => void} */\n\n this.updatePreloaderVisibility = () => {};\n /**\r\n * @private\r\n * @type {number | undefined}\r\n */\n\n\n this._lastUpdatedZoomLevel = undefined;\n }\n\n init() {\n const {\n pswp\n } = this;\n this.isRegistered = false;\n this.uiElementsData = [closeButton, arrowPrev, arrowNext, zoomButton, loadingIndicator, counterIndicator];\n pswp.dispatch('uiRegister'); // sort by order\n\n this.uiElementsData.sort((a, b) => {\n // default order is 0\n return (a.order || 0) - (b.order || 0);\n });\n this.items = [];\n this.isRegistered = true;\n this.uiElementsData.forEach(uiElementData => {\n this.registerElement(uiElementData);\n });\n pswp.on('change', () => {\n var _pswp$element;\n\n (_pswp$element = pswp.element) === null || _pswp$element === void 0 || _pswp$element.classList.toggle('pswp--one-slide', pswp.getNumItems() === 1);\n });\n pswp.on('zoomPanUpdate', () => this._onZoomPanUpdate());\n }\n /**\r\n * @param {UIElementData} elementData\r\n */\n\n\n registerElement(elementData) {\n if (this.isRegistered) {\n this.items.push(new UIElement(this.pswp, elementData));\n } else {\n this.uiElementsData.push(elementData);\n }\n }\n /**\r\n * Fired each time zoom or pan position is changed.\r\n * Update classes that control visibility of zoom button and cursor icon.\r\n *\r\n * @private\r\n */\n\n\n _onZoomPanUpdate() {\n const {\n template,\n currSlide,\n options\n } = this.pswp;\n\n if (this.pswp.opener.isClosing || !template || !currSlide) {\n return;\n }\n\n let {\n currZoomLevel\n } = currSlide; // if not open yet - check against initial zoom level\n\n if (!this.pswp.opener.isOpen) {\n currZoomLevel = currSlide.zoomLevels.initial;\n }\n\n if (currZoomLevel === this._lastUpdatedZoomLevel) {\n return;\n }\n\n this._lastUpdatedZoomLevel = currZoomLevel;\n const currZoomLevelDiff = currSlide.zoomLevels.initial - currSlide.zoomLevels.secondary; // Initial and secondary zoom levels are almost equal\n\n if (Math.abs(currZoomLevelDiff) < 0.01 || !currSlide.isZoomable()) {\n // disable zoom\n setZoomedIn(template, false);\n template.classList.remove('pswp--zoom-allowed');\n return;\n }\n\n template.classList.add('pswp--zoom-allowed');\n const potentialZoomLevel = currZoomLevel === currSlide.zoomLevels.initial ? currSlide.zoomLevels.secondary : currSlide.zoomLevels.initial;\n setZoomedIn(template, potentialZoomLevel <= currZoomLevel);\n\n if (options.imageClickAction === 'zoom' || options.imageClickAction === 'zoom-or-close') {\n template.classList.add('pswp--click-to-zoom');\n }\n }\n\n}\n\n/** @typedef {import('./slide.js').SlideData} SlideData */\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {{ x: number; y: number; w: number; innerRect?: { w: number; h: number; x: number; y: number } }} Bounds */\n\n/**\r\n * @param {HTMLElement} el\r\n * @returns Bounds\r\n */\nfunction getBoundsByElement(el) {\n const thumbAreaRect = el.getBoundingClientRect();\n return {\n x: thumbAreaRect.left,\n y: thumbAreaRect.top,\n w: thumbAreaRect.width\n };\n}\n/**\r\n * @param {HTMLElement} el\r\n * @param {number} imageWidth\r\n * @param {number} imageHeight\r\n * @returns Bounds\r\n */\n\n\nfunction getCroppedBoundsByElement(el, imageWidth, imageHeight) {\n const thumbAreaRect = el.getBoundingClientRect(); // fill image into the area\n // (do they same as object-fit:cover does to retrieve coordinates)\n\n const hRatio = thumbAreaRect.width / imageWidth;\n const vRatio = thumbAreaRect.height / imageHeight;\n const fillZoomLevel = hRatio > vRatio ? hRatio : vRatio;\n const offsetX = (thumbAreaRect.width - imageWidth * fillZoomLevel) / 2;\n const offsetY = (thumbAreaRect.height - imageHeight * fillZoomLevel) / 2;\n /**\r\n * Coordinates of the image,\r\n * as if it was not cropped,\r\n * height is calculated automatically\r\n *\r\n * @type {Bounds}\r\n */\n\n const bounds = {\n x: thumbAreaRect.left + offsetX,\n y: thumbAreaRect.top + offsetY,\n w: imageWidth * fillZoomLevel\n }; // Coordinates of inner crop area\n // relative to the image\n\n bounds.innerRect = {\n w: thumbAreaRect.width,\n h: thumbAreaRect.height,\n x: offsetX,\n y: offsetY\n };\n return bounds;\n}\n/**\r\n * Get dimensions of thumbnail image\r\n * (click on which opens photoswipe or closes photoswipe to)\r\n *\r\n * @param {number} index\r\n * @param {SlideData} itemData\r\n * @param {PhotoSwipe} instance PhotoSwipe instance\r\n * @returns {Bounds | undefined}\r\n */\n\n\nfunction getThumbBounds(index, itemData, instance) {\n // legacy event, before filters were introduced\n const event = instance.dispatch('thumbBounds', {\n index,\n itemData,\n instance\n }); // @ts-expect-error\n\n if (event.thumbBounds) {\n // @ts-expect-error\n return event.thumbBounds;\n }\n\n const {\n element\n } = itemData;\n /** @type {Bounds | undefined} */\n\n let thumbBounds;\n /** @type {HTMLElement | null | undefined} */\n\n let thumbnail;\n\n if (element && instance.options.thumbSelector !== false) {\n const thumbSelector = instance.options.thumbSelector || 'img';\n thumbnail = element.matches(thumbSelector) ? element :\n /** @type {HTMLElement | null} */\n element.querySelector(thumbSelector);\n }\n\n thumbnail = instance.applyFilters('thumbEl', thumbnail, itemData, index);\n\n if (thumbnail) {\n if (!itemData.thumbCropped) {\n thumbBounds = getBoundsByElement(thumbnail);\n } else {\n thumbBounds = getCroppedBoundsByElement(thumbnail, itemData.width || itemData.w || 0, itemData.height || itemData.h || 0);\n }\n }\n\n return instance.applyFilters('thumbBounds', thumbBounds, itemData, index);\n}\n\n/** @typedef {import('../lightbox/lightbox.js').default} PhotoSwipeLightbox */\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../photoswipe.js').DataSource} DataSource */\n\n/** @typedef {import('../ui/ui-element.js').UIElementData} UIElementData */\n\n/** @typedef {import('../slide/content.js').default} ContentDefault */\n\n/** @typedef {import('../slide/slide.js').default} Slide */\n\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\n\n/** @typedef {import('../slide/zoom-level.js').default} ZoomLevel */\n\n/** @typedef {import('../slide/get-thumb-bounds.js').Bounds} Bounds */\n\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 */\n\n/** @typedef {{ x?: number; y?: number }} Point */\n\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 */\n\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 */\n\n/**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @typedef {{ fn: PhotoSwipeFiltersMap[T], priority: number }} Filter\r\n */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {PhotoSwipeEventsMap[T] extends undefined ? PhotoSwipeEvent : PhotoSwipeEvent & PhotoSwipeEventsMap[T]} AugmentedEvent\r\n */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {(event: AugmentedEvent) => void} EventCallback\r\n */\n\n/**\r\n * Base PhotoSwipe event object\r\n *\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n */\nclass PhotoSwipeEvent {\n /**\r\n * @param {T} type\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n */\n constructor(type, details) {\n this.type = type;\n this.defaultPrevented = false;\n\n if (details) {\n Object.assign(this, details);\n }\n }\n\n preventDefault() {\n this.defaultPrevented = true;\n }\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 */\n\n\nclass Eventable {\n constructor() {\n /**\r\n * @type {{ [T in keyof PhotoSwipeEventsMap]?: ((event: AugmentedEvent) => void)[] }}\r\n */\n this._listeners = {};\n /**\r\n * @type {{ [T in keyof PhotoSwipeFiltersMap]?: Filter[] }}\r\n */\n\n this._filters = {};\n /** @type {PhotoSwipe | undefined} */\n\n this.pswp = undefined;\n /** @type {PhotoSwipeOptions | undefined} */\n\n 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 */\n\n\n addFilter(name, fn, priority = 100) {\n var _this$_filters$name, _this$_filters$name2, _this$pswp;\n\n if (!this._filters[name]) {\n this._filters[name] = [];\n }\n\n (_this$_filters$name = this._filters[name]) === null || _this$_filters$name === void 0 || _this$_filters$name.push({\n fn,\n priority\n });\n (_this$_filters$name2 = this._filters[name]) === null || _this$_filters$name2 === void 0 || _this$_filters$name2.sort((f1, f2) => f1.priority - f2.priority);\n (_this$pswp = this.pswp) === null || _this$pswp === void 0 || _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 */\n\n\n removeFilter(name, fn) {\n if (this._filters[name]) {\n // @ts-expect-error\n this._filters[name] = this._filters[name].filter(filter => filter.fn !== fn);\n }\n\n if (this.pswp) {\n this.pswp.removeFilter(name, fn);\n }\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 */\n\n\n applyFilters(name, ...args) {\n var _this$_filters$name3;\n\n (_this$_filters$name3 = this._filters[name]) === null || _this$_filters$name3 === void 0 || _this$_filters$name3.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 */\n\n\n on(name, fn) {\n var _this$_listeners$name, _this$pswp2;\n\n if (!this._listeners[name]) {\n this._listeners[name] = [];\n }\n\n (_this$_listeners$name = this._listeners[name]) === null || _this$_listeners$name === void 0 || _this$_listeners$name.push(fn); // When binding events to lightbox,\n // also bind events to PhotoSwipe Core,\n // if it's open.\n\n (_this$pswp2 = this.pswp) === null || _this$pswp2 === void 0 || _this$pswp2.on(name, fn);\n }\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */\n\n\n off(name, fn) {\n var _this$pswp3;\n\n if (this._listeners[name]) {\n // @ts-expect-error\n this._listeners[name] = this._listeners[name].filter(listener => fn !== listener);\n }\n\n (_this$pswp3 = this.pswp) === null || _this$pswp3 === void 0 || _this$pswp3.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 */\n\n\n dispatch(name, details) {\n var _this$_listeners$name2;\n\n if (this.pswp) {\n return this.pswp.dispatch(name, details);\n }\n\n const event =\n /** @type {AugmentedEvent} */\n new PhotoSwipeEvent(name, details);\n (_this$_listeners$name2 = this._listeners[name]) === null || _this$_listeners$name2 === void 0 || _this$_listeners$name2.forEach(listener => {\n listener.call(this, event);\n });\n return event;\n }\n\n}\n\nclass Placeholder {\n /**\r\n * @param {string | false} imageSrc\r\n * @param {HTMLElement} container\r\n */\n constructor(imageSrc, container) {\n // Create placeholder\n // (stretched thumbnail or simple div behind the main image)\n\n /** @type {HTMLImageElement | HTMLDivElement | null} */\n this.element = createElement('pswp__img pswp__img--placeholder', imageSrc ? 'img' : 'div', container);\n\n if (imageSrc) {\n const imgEl =\n /** @type {HTMLImageElement} */\n this.element;\n imgEl.decoding = 'async';\n imgEl.alt = '';\n imgEl.src = imageSrc;\n imgEl.setAttribute('role', 'presentation');\n }\n\n this.element.setAttribute('aria-hidden', 'true');\n }\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */\n\n\n setDisplayedSize(width, height) {\n if (!this.element) {\n return;\n }\n\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 setWidthHeight(this.element, 250, 'auto');\n this.element.style.transformOrigin = '0 0';\n this.element.style.transform = toTransformString(0, 0, width / 250);\n } else {\n setWidthHeight(this.element, width, height);\n }\n }\n\n destroy() {\n var _this$element;\n\n if ((_this$element = this.element) !== null && _this$element !== void 0 && _this$element.parentNode) {\n this.element.remove();\n }\n\n this.element = null;\n }\n\n}\n\n/** @typedef {import('./slide.js').default} Slide */\n\n/** @typedef {import('./slide.js').SlideData} SlideData */\n\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\n\n/** @typedef {import('../util/util.js').LoadState} LoadState */\n\nclass 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 */\n constructor(itemData, instance, index) {\n this.instance = instance;\n this.data = itemData;\n this.index = index;\n /** @type {HTMLImageElement | HTMLDivElement | undefined} */\n\n this.element = undefined;\n /** @type {Placeholder | undefined} */\n\n this.placeholder = undefined;\n /** @type {Slide | undefined} */\n\n 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} */\n\n this.state = LOAD_STATE.IDLE;\n\n if (this.data.type) {\n this.type = this.data.type;\n } else if (this.data.src) {\n this.type = 'image';\n } else {\n this.type = 'html';\n }\n\n this.instance.dispatch('contentInit', {\n content: this\n });\n }\n\n removePlaceholder() {\n if (this.placeholder && !this.keepPlaceholder()) {\n // 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 }\n /**\r\n * Preload content\r\n *\r\n * @param {boolean} isLazy\r\n * @param {boolean} [reload]\r\n */\n\n\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 Placeholder(placeholderSrc, this.slide.container);\n } else {\n const placeholderEl = this.placeholder.element; // Add placeholder to DOM if it was already created\n\n if (placeholderEl && !placeholderEl.parentElement) {\n this.slide.container.prepend(placeholderEl);\n }\n }\n }\n\n if (this.element && !reload) {\n return;\n }\n\n if (this.instance.dispatch('contentLoad', {\n content: this,\n isLazy\n }).defaultPrevented) {\n return;\n }\n\n if (this.isImageContent()) {\n this.element = createElement('pswp__img', 'img'); // 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\n if (this.displayedImageWidth) {\n this.loadImage(isLazy);\n }\n } else {\n this.element = createElement('pswp__content', 'div');\n this.element.innerHTML = this.data.html || '';\n }\n\n if (reload && this.slide) {\n this.slide.updateContentSize(true);\n }\n }\n /**\r\n * Preload image\r\n *\r\n * @param {boolean} isLazy\r\n */\n\n\n loadImage(isLazy) {\n var _this$data$src, _this$data$alt;\n\n if (!this.isImageContent() || !this.element || this.instance.dispatch('contentLoadImage', {\n content: this,\n isLazy\n }).defaultPrevented) {\n return;\n }\n\n const imageElement =\n /** @type HTMLImageElement */\n this.element;\n this.updateSrcsetSizes();\n\n if (this.data.srcset) {\n imageElement.srcset = this.data.srcset;\n }\n\n imageElement.src = (_this$data$src = this.data.src) !== null && _this$data$src !== void 0 ? _this$data$src : '';\n imageElement.alt = (_this$data$alt = this.data.alt) !== null && _this$data$alt !== void 0 ? _this$data$alt : '';\n this.state = LOAD_STATE.LOADING;\n\n if (imageElement.complete) {\n this.onLoaded();\n } else {\n imageElement.onload = () => {\n this.onLoaded();\n };\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 */\n\n\n setSlide(slide) {\n this.slide = slide;\n this.hasSlide = true;\n this.instance = slide.pswp; // todo: do we need to unset slide?\n }\n /**\r\n * Content load success handler\r\n */\n\n\n onLoaded() {\n this.state = LOAD_STATE.LOADED;\n\n if (this.slide && this.element) {\n this.instance.dispatch('loadComplete', {\n slide: this.slide,\n content: this\n }); // if content is reloaded\n\n if (this.slide.isActive && this.slide.heavyAppended && !this.element.parentNode) {\n this.append();\n this.slide.updateContentSize(true);\n }\n\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\n this.removePlaceholder();\n }\n }\n }\n /**\r\n * Content load error handler\r\n */\n\n\n onError() {\n this.state = LOAD_STATE.ERROR;\n\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 */\n\n\n isLoading() {\n return this.instance.applyFilters('isContentLoading', this.state === LOAD_STATE.LOADING, this);\n }\n /**\r\n * @returns {Boolean} If the content is in error state\r\n */\n\n\n isError() {\n return this.state === LOAD_STATE.ERROR;\n }\n /**\r\n * @returns {boolean} If the content is image\r\n */\n\n\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 */\n\n\n setDisplayedSize(width, height) {\n if (!this.element) {\n return;\n }\n\n if (this.placeholder) {\n this.placeholder.setDisplayedSize(width, height);\n }\n\n if (this.instance.dispatch('contentResize', {\n content: this,\n width,\n height\n }).defaultPrevented) {\n return;\n }\n\n setWidthHeight(this.element, width, height);\n\n if (this.isImageContent() && !this.isError()) {\n const isInitialSizeUpdate = !this.displayedImageWidth && width;\n this.displayedImageWidth = width;\n this.displayedImageHeight = height;\n\n if (isInitialSizeUpdate) {\n this.loadImage(false);\n } else {\n this.updateSrcsetSizes();\n }\n\n if (this.slide) {\n this.instance.dispatch('imageSizeChange', {\n slide: this.slide,\n width,\n height,\n content: this\n });\n }\n }\n }\n /**\r\n * @returns {boolean} If the content can be zoomed\r\n */\n\n\n isZoomable() {\n return this.instance.applyFilters('isContentZoomable', this.isImageContent() && this.state !== LOAD_STATE.ERROR, this);\n }\n /**\r\n * Update image srcset sizes attribute based on width and height\r\n */\n\n\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) {\n return;\n }\n\n const image =\n /** @type HTMLImageElement */\n this.element;\n const sizesWidth = this.instance.applyFilters('srcsetSizesWidth', this.displayedImageWidth, this);\n\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 */\n\n\n usePlaceholder() {\n return this.instance.applyFilters('useContentPlaceholder', this.isImageContent(), this);\n }\n /**\r\n * Preload content with lazy-loading param\r\n */\n\n\n lazyLoad() {\n if (this.instance.dispatch('contentLazyLoad', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n this.load(true);\n }\n /**\r\n * @returns {boolean} If placeholder should be kept after content is loaded\r\n */\n\n\n keepPlaceholder() {\n return this.instance.applyFilters('isKeepingPlaceholder', this.isLoading(), this);\n }\n /**\r\n * Destroy the content\r\n */\n\n\n destroy() {\n this.hasSlide = false;\n this.slide = undefined;\n\n if (this.instance.dispatch('contentDestroy', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n this.remove();\n\n if (this.placeholder) {\n this.placeholder.destroy();\n this.placeholder = undefined;\n }\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 */\n\n\n displayError() {\n if (this.slide) {\n var _this$instance$option, _this$instance$option2;\n\n let errorMsgEl = createElement('pswp__error-msg', 'div');\n errorMsgEl.innerText = (_this$instance$option = (_this$instance$option2 = this.instance.options) === null || _this$instance$option2 === void 0 ? void 0 : _this$instance$option2.errorMsg) !== null && _this$instance$option !== void 0 ? _this$instance$option : '';\n errorMsgEl =\n /** @type {HTMLDivElement} */\n this.instance.applyFilters('contentErrorElement', errorMsgEl, this);\n this.element = 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 */\n\n\n append() {\n if (this.isAttached || !this.element) {\n return;\n }\n\n this.isAttached = true;\n\n if (this.state === LOAD_STATE.ERROR) {\n this.displayError();\n return;\n }\n\n if (this.instance.dispatch('contentAppend', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n const supportsDecode = ('decode' in this.element);\n\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 || isSafari())) {\n this.isDecoding = true; // purposefully using finally instead of then,\n // as if srcset sizes changes dynamically - it may cause decode error\n\n /** @type {HTMLImageElement} */\n\n this.element.decode().catch(() => {}).finally(() => {\n this.isDecoding = false;\n this.appendImage();\n });\n } else {\n this.appendImage();\n }\n } else if (this.slide && !this.element.parentNode) {\n this.slide.container.appendChild(this.element);\n }\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 */\n\n\n activate() {\n if (this.instance.dispatch('contentActivate', {\n content: this\n }).defaultPrevented || !this.slide) {\n return;\n }\n\n if (this.isImageContent() && this.isDecoding && !isSafari()) {\n // add image to slide when it becomes active,\n // even if it's not finished decoding\n this.appendImage();\n } else if (this.isError()) {\n this.load(false, true); // try to reload\n }\n\n if (this.slide.holderElement) {\n this.slide.holderElement.setAttribute('aria-hidden', 'false');\n }\n }\n /**\r\n * Deactivate the content\r\n */\n\n\n deactivate() {\n this.instance.dispatch('contentDeactivate', {\n content: this\n });\n\n if (this.slide && this.slide.holderElement) {\n this.slide.holderElement.setAttribute('aria-hidden', 'true');\n }\n }\n /**\r\n * Remove the content from DOM\r\n */\n\n\n remove() {\n this.isAttached = false;\n\n if (this.instance.dispatch('contentRemove', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n if (this.element && this.element.parentNode) {\n this.element.remove();\n }\n\n if (this.placeholder && this.placeholder.element) {\n this.placeholder.element.remove();\n }\n }\n /**\r\n * Append the image content to slide container\r\n */\n\n\n appendImage() {\n if (!this.isAttached) {\n return;\n }\n\n if (this.instance.dispatch('contentAppendImage', {\n content: this\n }).defaultPrevented) {\n return;\n } // ensure that element exists and is not already appended\n\n\n if (this.slide && this.element && !this.element.parentNode) {\n this.slide.container.appendChild(this.element);\n }\n\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\n this.removePlaceholder();\n }\n }\n\n}\n\n/** @typedef {import('./content.js').default} Content */\n\n/** @typedef {import('./slide.js').default} Slide */\n\n/** @typedef {import('./slide.js').SlideData} SlideData */\n\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\nconst MIN_SLIDES_TO_CACHE = 5;\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 */\n\nfunction lazyLoadData(itemData, instance, index) {\n const content = instance.createContentFromData(itemData, index);\n /** @type {ZoomLevel | undefined} */\n\n let zoomLevel;\n const {\n options\n } = instance; // We need to know dimensions of the image to preload it,\n // as it might use srcset, and we need to define sizes\n\n if (options) {\n zoomLevel = new ZoomLevel(options, itemData, -1);\n let viewportSize;\n\n if (instance.pswp) {\n viewportSize = instance.pswp.viewportSize;\n } else {\n viewportSize = getViewportSize(options, instance);\n }\n\n const panAreaSize = getPanAreaSize(options, viewportSize, itemData, index);\n zoomLevel.update(content.width, content.height, panAreaSize);\n }\n\n content.lazyLoad();\n\n if (zoomLevel) {\n content.setDisplayedSize(Math.ceil(content.width * zoomLevel.initial), Math.ceil(content.height * zoomLevel.initial));\n }\n\n return content;\n}\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 */\n\nfunction lazyLoadSlide(index, instance) {\n const itemData = instance.getItemData(index);\n\n if (instance.dispatch('lazyLoadSlide', {\n index,\n itemData\n }).defaultPrevented) {\n return;\n }\n\n return lazyLoadData(itemData, instance, index);\n}\n\nclass ContentLoader {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp; // Total amount of cached images\n\n this.limit = Math.max(pswp.options.preload[0] + pswp.options.preload[1] + 1, MIN_SLIDES_TO_CACHE);\n /** @type {Content[]} */\n\n 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 */\n\n\n updateLazy(diff) {\n const {\n pswp\n } = this;\n\n if (pswp.dispatch('lazyLoad').defaultPrevented) {\n return;\n }\n\n const {\n preload\n } = pswp.options;\n const isForward = diff === undefined ? true : diff >= 0;\n let i; // preload[1] - num items to preload in forward direction\n\n for (i = 0; i <= preload[1]; i++) {\n this.loadSlideByIndex(pswp.currIndex + (isForward ? i : -i));\n } // preload[0] - num items to preload in backward direction\n\n\n for (i = 1; i <= preload[0]; i++) {\n this.loadSlideByIndex(pswp.currIndex + (isForward ? -i : i));\n }\n }\n /**\r\n * @param {number} initialIndex\r\n */\n\n\n loadSlideByIndex(initialIndex) {\n const index = this.pswp.getLoopedIndex(initialIndex); // try to get cached content\n\n let content = this.getContentByIndex(index);\n\n if (!content) {\n // no cached content, so try to load from scratch:\n content = lazyLoadSlide(index, this.pswp); // if content can be loaded, add it to cache:\n\n if (content) {\n this.addToCache(content);\n }\n }\n }\n /**\r\n * @param {Slide} slide\r\n * @returns {Content}\r\n */\n\n\n getContentBySlide(slide) {\n let content = this.getContentByIndex(slide.index);\n\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 } // assign slide to content\n\n\n content.setSlide(slide);\n return content;\n }\n /**\r\n * @param {Content} content\r\n */\n\n\n addToCache(content) {\n // move to the end of array\n this.removeByIndex(content.index);\n\n this._cachedItems.push(content);\n\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\n if (indexToRemove !== -1) {\n const removedItem = this._cachedItems.splice(indexToRemove, 1)[0];\n\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 */\n\n\n removeByIndex(index) {\n const indexToRemove = this._cachedItems.findIndex(item => item.index === index);\n\n if (indexToRemove !== -1) {\n this._cachedItems.splice(indexToRemove, 1);\n }\n }\n /**\r\n * @param {number} index\r\n * @returns {Content | undefined}\r\n */\n\n\n getContentByIndex(index) {\n return this._cachedItems.find(content => content.index === index);\n }\n\n destroy() {\n this._cachedItems.forEach(content => content.destroy());\n\n this._cachedItems = [];\n }\n\n}\n\n/** @typedef {import(\"../photoswipe.js\").default} PhotoSwipe */\n\n/** @typedef {import(\"../slide/slide.js\").SlideData} SlideData */\n\n/**\r\n * PhotoSwipe base class that can retrieve data about every slide.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox\r\n */\n\nclass PhotoSwipeBase extends Eventable {\n /**\r\n * Get total number of slides\r\n *\r\n * @returns {number}\r\n */\n getNumItems() {\n var _this$options;\n\n let numItems = 0;\n const dataSource = (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.dataSource;\n\n if (dataSource && 'length' in dataSource) {\n // 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) {\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\n }\n\n if (dataSource.items) {\n numItems = dataSource.items.length;\n }\n } // legacy event, before filters were introduced\n\n\n const event = this.dispatch('numItems', {\n dataSource,\n 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 */\n\n\n createContentFromData(slideData, index) {\n return new Content(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 */\n\n\n getItemData(index) {\n var _this$options2;\n\n const dataSource = (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.dataSource;\n /** @type {SlideData | HTMLElement} */\n\n let dataSourceItem = {};\n\n if (Array.isArray(dataSource)) {\n // 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) {\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\n }\n\n dataSourceItem = dataSource.items[index];\n }\n\n let itemData = dataSourceItem;\n\n if (itemData instanceof Element) {\n itemData = this._domElementToItemData(itemData);\n } // Dispatching the itemData event,\n // it's a legacy verion before filters were introduced\n\n\n const event = this.dispatch('itemData', {\n itemData: itemData || {},\n 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 */\n\n\n _getGalleryDOMElements(galleryElement) {\n var _this$options3, _this$options4;\n\n if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.children || (_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.childSelector) {\n return getElementsFromOption(this.options.children, this.options.childSelector, galleryElement) || [];\n }\n\n return [galleryElement];\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 */\n\n\n _domElementToItemData(element) {\n /** @type {SlideData} */\n const itemData = {\n element\n };\n const linkEl =\n /** @type {HTMLAnchorElement} */\n element.tagName === 'A' ? element : element.querySelector('a');\n\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\n if (linkEl.dataset.pswpSrcset) {\n itemData.srcset = linkEl.dataset.pswpSrcset;\n }\n\n itemData.width = linkEl.dataset.pswpWidth ? parseInt(linkEl.dataset.pswpWidth, 10) : 0;\n itemData.height = linkEl.dataset.pswpHeight ? parseInt(linkEl.dataset.pswpHeight, 10) : 0; // support legacy w & h properties\n\n itemData.w = itemData.width;\n itemData.h = itemData.height;\n\n if (linkEl.dataset.pswpType) {\n itemData.type = linkEl.dataset.pswpType;\n }\n\n const thumbnailEl = element.querySelector('img');\n\n if (thumbnailEl) {\n var _thumbnailEl$getAttri;\n\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$getAttri = thumbnailEl.getAttribute('alt')) !== null && _thumbnailEl$getAttri !== void 0 ? _thumbnailEl$getAttri : '';\n }\n\n if (linkEl.dataset.pswpCropped || linkEl.dataset.cropped) {\n itemData.thumbCropped = true;\n }\n }\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 */\n\n\n lazyLoadData(itemData, index) {\n return lazyLoadData(itemData, this, index);\n }\n\n}\n\n/** @typedef {import('./photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('./slide/get-thumb-bounds.js').Bounds} Bounds */\n\n/** @typedef {import('./util/animations.js').AnimationProps} AnimationProps */\n// some browsers do not paint\n// elements which opacity is set to 0,\n// since we need to pre-render elements for the animation -\n// we set it to the minimum amount\n\nconst MIN_OPACITY = 0.003;\n/**\r\n * Manages opening and closing transitions of the PhotoSwipe.\r\n *\r\n * It can perform zoom, fade or no transition.\r\n */\n\nclass Opener {\n /**\r\n * @param {PhotoSwipe} pswp\r\n */\n constructor(pswp) {\n this.pswp = pswp;\n this.isClosed = true;\n this.isOpen = false;\n this.isClosing = false;\n this.isOpening = false;\n /**\r\n * @private\r\n * @type {number | false | undefined}\r\n */\n\n this._duration = undefined;\n /** @private */\n\n this._useAnimation = false;\n /** @private */\n\n this._croppedZoom = false;\n /** @private */\n\n this._animateRootOpacity = false;\n /** @private */\n\n this._animateBgOpacity = false;\n /**\r\n * @private\r\n * @type { HTMLDivElement | HTMLImageElement | null | undefined }\r\n */\n\n this._placeholder = undefined;\n /**\r\n * @private\r\n * @type { HTMLDivElement | undefined }\r\n */\n\n this._opacityElement = undefined;\n /**\r\n * @private\r\n * @type { HTMLDivElement | undefined }\r\n */\n\n this._cropContainer1 = undefined;\n /**\r\n * @private\r\n * @type { HTMLElement | null | undefined }\r\n */\n\n this._cropContainer2 = undefined;\n /**\r\n * @private\r\n * @type {Bounds | undefined}\r\n */\n\n this._thumbBounds = undefined;\n this._prepareOpen = this._prepareOpen.bind(this); // Override initial zoom and pan position\n\n pswp.on('firstZoomPan', this._prepareOpen);\n }\n\n open() {\n this._prepareOpen();\n\n this._start();\n }\n\n close() {\n if (this.isClosed || this.isClosing || this.isOpening) {\n // if we close during opening animation\n // for now do nothing,\n // browsers aren't good at changing the direction of the CSS transition\n return;\n }\n\n const slide = this.pswp.currSlide;\n this.isOpen = false;\n this.isOpening = false;\n this.isClosing = true;\n this._duration = this.pswp.options.hideAnimationDuration;\n\n if (slide && slide.currZoomLevel * slide.width >= this.pswp.options.maxWidthToAnimate) {\n this._duration = 0;\n }\n\n this._applyStartProps();\n\n setTimeout(() => {\n this._start();\n }, this._croppedZoom ? 30 : 0);\n }\n /** @private */\n\n\n _prepareOpen() {\n this.pswp.off('firstZoomPan', this._prepareOpen);\n\n if (!this.isOpening) {\n const slide = this.pswp.currSlide;\n this.isOpening = true;\n this.isClosing = false;\n this._duration = this.pswp.options.showAnimationDuration;\n\n if (slide && slide.zoomLevels.initial * slide.width >= this.pswp.options.maxWidthToAnimate) {\n this._duration = 0;\n }\n\n this._applyStartProps();\n }\n }\n /** @private */\n\n\n _applyStartProps() {\n const {\n pswp\n } = this;\n const slide = this.pswp.currSlide;\n const {\n options\n } = pswp;\n\n if (options.showHideAnimationType === 'fade') {\n options.showHideOpacity = true;\n this._thumbBounds = undefined;\n } else if (options.showHideAnimationType === 'none') {\n options.showHideOpacity = false;\n this._duration = 0;\n this._thumbBounds = undefined;\n } else if (this.isOpening && pswp._initialThumbBounds) {\n // Use initial bounds if defined\n this._thumbBounds = pswp._initialThumbBounds;\n } else {\n this._thumbBounds = this.pswp.getThumbBounds();\n }\n\n this._placeholder = slide === null || slide === void 0 ? void 0 : slide.getPlaceholderElement();\n pswp.animations.stopAll(); // Discard animations when duration is less than 50ms\n\n this._useAnimation = Boolean(this._duration && this._duration > 50);\n this._animateZoom = Boolean(this._thumbBounds) && (slide === null || slide === void 0 ? void 0 : slide.content.usePlaceholder()) && (!this.isClosing || !pswp.mainScroll.isShifted());\n\n if (!this._animateZoom) {\n this._animateRootOpacity = true;\n\n if (this.isOpening && slide) {\n slide.zoomAndPanToInitial();\n slide.applyCurrentZoomPan();\n }\n } else {\n var _options$showHideOpac;\n\n this._animateRootOpacity = (_options$showHideOpac = options.showHideOpacity) !== null && _options$showHideOpac !== void 0 ? _options$showHideOpac : false;\n }\n\n this._animateBgOpacity = !this._animateRootOpacity && this.pswp.options.bgOpacity > MIN_OPACITY;\n this._opacityElement = this._animateRootOpacity ? pswp.element : pswp.bg;\n\n if (!this._useAnimation) {\n this._duration = 0;\n this._animateZoom = false;\n this._animateBgOpacity = false;\n this._animateRootOpacity = true;\n\n if (this.isOpening) {\n if (pswp.element) {\n pswp.element.style.opacity = String(MIN_OPACITY);\n }\n\n pswp.applyBgOpacity(1);\n }\n\n return;\n }\n\n if (this._animateZoom && this._thumbBounds && this._thumbBounds.innerRect) {\n var _this$pswp$currSlide;\n\n // Properties are used when animation from cropped thumbnail\n this._croppedZoom = true;\n this._cropContainer1 = this.pswp.container;\n this._cropContainer2 = (_this$pswp$currSlide = this.pswp.currSlide) === null || _this$pswp$currSlide === void 0 ? void 0 : _this$pswp$currSlide.holderElement;\n\n if (pswp.container) {\n pswp.container.style.overflow = 'hidden';\n pswp.container.style.width = pswp.viewportSize.x + 'px';\n }\n } else {\n this._croppedZoom = false;\n }\n\n if (this.isOpening) {\n // Apply styles before opening transition\n if (this._animateRootOpacity) {\n if (pswp.element) {\n pswp.element.style.opacity = String(MIN_OPACITY);\n }\n\n pswp.applyBgOpacity(1);\n } else {\n if (this._animateBgOpacity && pswp.bg) {\n pswp.bg.style.opacity = String(MIN_OPACITY);\n }\n\n if (pswp.element) {\n pswp.element.style.opacity = '1';\n }\n }\n\n if (this._animateZoom) {\n this._setClosedStateZoomPan();\n\n if (this._placeholder) {\n // tell browser that we plan to animate the placeholder\n this._placeholder.style.willChange = 'transform'; // hide placeholder to allow hiding of\n // elements that overlap it (such as icons over the thumbnail)\n\n this._placeholder.style.opacity = String(MIN_OPACITY);\n }\n }\n } else if (this.isClosing) {\n // hide nearby slides to make sure that\n // they are not painted during the transition\n if (pswp.mainScroll.itemHolders[0]) {\n pswp.mainScroll.itemHolders[0].el.style.display = 'none';\n }\n\n if (pswp.mainScroll.itemHolders[2]) {\n pswp.mainScroll.itemHolders[2].el.style.display = 'none';\n }\n\n if (this._croppedZoom) {\n if (pswp.mainScroll.x !== 0) {\n // shift the main scroller to zero position\n pswp.mainScroll.resetPosition();\n pswp.mainScroll.resize();\n }\n }\n }\n }\n /** @private */\n\n\n _start() {\n if (this.isOpening && this._useAnimation && this._placeholder && this._placeholder.tagName === 'IMG') {\n // To ensure smooth animation\n // we wait till the current slide image placeholder is decoded,\n // but no longer than 250ms,\n // and no shorter than 50ms\n // (just using requestanimationframe is not enough in Firefox,\n // for some reason)\n new Promise(resolve => {\n let decoded = false;\n let isDelaying = true;\n decodeImage(\n /** @type {HTMLImageElement} */\n this._placeholder).finally(() => {\n decoded = true;\n\n if (!isDelaying) {\n resolve(true);\n }\n });\n setTimeout(() => {\n isDelaying = false;\n\n if (decoded) {\n resolve(true);\n }\n }, 50);\n setTimeout(resolve, 250);\n }).finally(() => this._initiate());\n } else {\n this._initiate();\n }\n }\n /** @private */\n\n\n _initiate() {\n var _this$pswp$element, _this$pswp$element2;\n\n (_this$pswp$element = this.pswp.element) === null || _this$pswp$element === void 0 || _this$pswp$element.style.setProperty('--pswp-transition-duration', this._duration + 'ms');\n this.pswp.dispatch(this.isOpening ? 'openingAnimationStart' : 'closingAnimationStart'); // legacy event\n\n this.pswp.dispatch(\n /** @type {'initialZoomIn' | 'initialZoomOut'} */\n 'initialZoom' + (this.isOpening ? 'In' : 'Out'));\n (_this$pswp$element2 = this.pswp.element) === null || _this$pswp$element2 === void 0 || _this$pswp$element2.classList.toggle('pswp--ui-visible', this.isOpening);\n\n if (this.isOpening) {\n if (this._placeholder) {\n // unhide the placeholder\n this._placeholder.style.opacity = '1';\n }\n\n this._animateToOpenState();\n } else if (this.isClosing) {\n this._animateToClosedState();\n }\n\n if (!this._useAnimation) {\n this._onAnimationComplete();\n }\n }\n /** @private */\n\n\n _onAnimationComplete() {\n const {\n pswp\n } = this;\n this.isOpen = this.isOpening;\n this.isClosed = this.isClosing;\n this.isOpening = false;\n this.isClosing = false;\n pswp.dispatch(this.isOpen ? 'openingAnimationEnd' : 'closingAnimationEnd'); // legacy event\n\n pswp.dispatch(\n /** @type {'initialZoomInEnd' | 'initialZoomOutEnd'} */\n 'initialZoom' + (this.isOpen ? 'InEnd' : 'OutEnd'));\n\n if (this.isClosed) {\n pswp.destroy();\n } else if (this.isOpen) {\n var _pswp$currSlide;\n\n if (this._animateZoom && pswp.container) {\n pswp.container.style.overflow = 'visible';\n pswp.container.style.width = '100%';\n }\n\n (_pswp$currSlide = pswp.currSlide) === null || _pswp$currSlide === void 0 || _pswp$currSlide.applyCurrentZoomPan();\n }\n }\n /** @private */\n\n\n _animateToOpenState() {\n const {\n pswp\n } = this;\n\n if (this._animateZoom) {\n if (this._croppedZoom && this._cropContainer1 && this._cropContainer2) {\n this._animateTo(this._cropContainer1, 'transform', 'translate3d(0,0,0)');\n\n this._animateTo(this._cropContainer2, 'transform', 'none');\n }\n\n if (pswp.currSlide) {\n pswp.currSlide.zoomAndPanToInitial();\n\n this._animateTo(pswp.currSlide.container, 'transform', pswp.currSlide.getCurrentTransform());\n }\n }\n\n if (this._animateBgOpacity && pswp.bg) {\n this._animateTo(pswp.bg, 'opacity', String(pswp.options.bgOpacity));\n }\n\n if (this._animateRootOpacity && pswp.element) {\n this._animateTo(pswp.element, 'opacity', '1');\n }\n }\n /** @private */\n\n\n _animateToClosedState() {\n const {\n pswp\n } = this;\n\n if (this._animateZoom) {\n this._setClosedStateZoomPan(true);\n } // do not animate opacity if it's already at 0\n\n\n if (this._animateBgOpacity && pswp.bgOpacity > 0.01 && pswp.bg) {\n this._animateTo(pswp.bg, 'opacity', '0');\n }\n\n if (this._animateRootOpacity && pswp.element) {\n this._animateTo(pswp.element, 'opacity', '0');\n }\n }\n /**\r\n * @private\r\n * @param {boolean} [animate]\r\n */\n\n\n _setClosedStateZoomPan(animate) {\n if (!this._thumbBounds) return;\n const {\n pswp\n } = this;\n const {\n innerRect\n } = this._thumbBounds;\n const {\n currSlide,\n viewportSize\n } = pswp;\n\n if (this._croppedZoom && innerRect && this._cropContainer1 && this._cropContainer2) {\n const containerOnePanX = -viewportSize.x + (this._thumbBounds.x - innerRect.x) + innerRect.w;\n const containerOnePanY = -viewportSize.y + (this._thumbBounds.y - innerRect.y) + innerRect.h;\n const containerTwoPanX = viewportSize.x - innerRect.w;\n const containerTwoPanY = viewportSize.y - innerRect.h;\n\n if (animate) {\n this._animateTo(this._cropContainer1, 'transform', toTransformString(containerOnePanX, containerOnePanY));\n\n this._animateTo(this._cropContainer2, 'transform', toTransformString(containerTwoPanX, containerTwoPanY));\n } else {\n setTransform(this._cropContainer1, containerOnePanX, containerOnePanY);\n setTransform(this._cropContainer2, containerTwoPanX, containerTwoPanY);\n }\n }\n\n if (currSlide) {\n equalizePoints(currSlide.pan, innerRect || this._thumbBounds);\n currSlide.currZoomLevel = this._thumbBounds.w / currSlide.width;\n\n if (animate) {\n this._animateTo(currSlide.container, 'transform', currSlide.getCurrentTransform());\n } else {\n currSlide.applyCurrentZoomPan();\n }\n }\n }\n /**\r\n * @private\r\n * @param {HTMLElement} target\r\n * @param {'transform' | 'opacity'} prop\r\n * @param {string} propValue\r\n */\n\n\n _animateTo(target, prop, propValue) {\n if (!this._duration) {\n target.style[prop] = propValue;\n return;\n }\n\n const {\n animations\n } = this.pswp;\n /** @type {AnimationProps} */\n\n const animProps = {\n duration: this._duration,\n easing: this.pswp.options.easing,\n onComplete: () => {\n if (!animations.activeAnimations.length) {\n this._onAnimationComplete();\n }\n },\n target\n };\n animProps[prop] = propValue;\n animations.startTransition(animProps);\n }\n\n}\n\n/**\r\n * @template T\r\n * @typedef {import('./types.js').Type} Type\r\n */\n\n/** @typedef {import('./slide/slide.js').SlideData} SlideData */\n\n/** @typedef {import('./slide/zoom-level.js').ZoomLevelOption} ZoomLevelOption */\n\n/** @typedef {import('./ui/ui-element.js').UIElementData} UIElementData */\n\n/** @typedef {import('./main-scroll.js').ItemHolder} ItemHolder */\n\n/** @typedef {import('./core/eventable.js').PhotoSwipeEventsMap} PhotoSwipeEventsMap */\n\n/** @typedef {import('./core/eventable.js').PhotoSwipeFiltersMap} PhotoSwipeFiltersMap */\n\n/** @typedef {import('./slide/get-thumb-bounds').Bounds} Bounds */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('./core/eventable.js').EventCallback} EventCallback\r\n */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('./core/eventable.js').AugmentedEvent} AugmentedEvent\r\n */\n\n/** @typedef {{ x: number; y: number; id?: string | number }} Point */\n\n/** @typedef {{ top: number; bottom: number; left: number; right: number }} Padding */\n\n/** @typedef {SlideData[]} DataSourceArray */\n\n/** @typedef {{ gallery: HTMLElement; items?: HTMLElement[] }} DataSourceObject */\n\n/** @typedef {DataSourceArray | DataSourceObject} DataSource */\n\n/** @typedef {(point: Point, originalEvent: PointerEvent) => void} ActionFn */\n\n/** @typedef {'close' | 'next' | 'zoom' | 'zoom-or-close' | 'toggle-controls'} ActionType */\n\n/** @typedef {Type | { default: Type }} PhotoSwipeModule */\n\n/** @typedef {PhotoSwipeModule | Promise | (() => Promise)} PhotoSwipeModuleOption */\n\n/**\r\n * @typedef {string | NodeListOf | HTMLElement[] | HTMLElement} ElementProvider\r\n */\n\n/** @typedef {Partial} PhotoSwipeOptions https://photoswipe.com/options/ */\n\n/**\r\n * @typedef {Object} PreparedPhotoSwipeOptions\r\n *\r\n * @prop {DataSource} [dataSource]\r\n * Pass an array of any items via dataSource option. Its length will determine amount of slides\r\n * (which may be modified further from numItems event).\r\n *\r\n * Each item should contain data that you need to generate slide\r\n * (for image slide it would be src (image URL), width (image width), height, srcset, alt).\r\n *\r\n * If these properties are not present in your initial array, you may \"pre-parse\" each item from itemData filter.\r\n *\r\n * @prop {number} bgOpacity\r\n * Background backdrop opacity, always define it via this option and not via CSS rgba color.\r\n *\r\n * @prop {number} spacing\r\n * Spacing between slides. Defined as ratio relative to the viewport width (0.1 = 10% of viewport).\r\n *\r\n * @prop {boolean} allowPanToNext\r\n * Allow swipe navigation to the next slide when the current slide is zoomed. Does not apply to mouse events.\r\n *\r\n * @prop {boolean} loop\r\n * If set to true you'll be able to swipe from the last to the first image.\r\n * Option is always false when there are less than 3 slides.\r\n *\r\n * @prop {boolean} [wheelToZoom]\r\n * By default PhotoSwipe zooms image with ctrl-wheel, if you enable this option - image will zoom just via wheel.\r\n *\r\n * @prop {boolean} pinchToClose\r\n * Pinch touch gesture to close the gallery.\r\n *\r\n * @prop {boolean} closeOnVerticalDrag\r\n * Vertical drag gesture to close the PhotoSwipe.\r\n *\r\n * @prop {Padding} [padding]\r\n * Slide area padding (in pixels).\r\n *\r\n * @prop {(viewportSize: Point, itemData: SlideData, index: number) => Padding} [paddingFn]\r\n * The option is checked frequently, so make sure it's performant. Overrides padding option if defined. For example:\r\n *\r\n * @prop {number | false} hideAnimationDuration\r\n * Transition duration in milliseconds, can be 0.\r\n *\r\n * @prop {number | false} showAnimationDuration\r\n * Transition duration in milliseconds, can be 0.\r\n *\r\n * @prop {number | false} zoomAnimationDuration\r\n * Transition duration in milliseconds, can be 0.\r\n *\r\n * @prop {string} easing\r\n * String, 'cubic-bezier(.4,0,.22,1)'. CSS easing function for open/close/zoom transitions.\r\n *\r\n * @prop {boolean} escKey\r\n * Esc key to close.\r\n *\r\n * @prop {boolean} arrowKeys\r\n * Left/right arrow keys for navigation.\r\n *\r\n * @prop {boolean} trapFocus\r\n * Trap focus within PhotoSwipe element while it's open.\r\n *\r\n * @prop {boolean} returnFocus\r\n * Restore focus the last active element after PhotoSwipe is closed.\r\n *\r\n * @prop {boolean} clickToCloseNonZoomable\r\n * If image is not zoomable (for example, smaller than viewport) it can be closed by clicking on it.\r\n *\r\n * @prop {ActionType | ActionFn | false} imageClickAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {ActionType | ActionFn | false} bgClickAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {ActionType | ActionFn | false} tapAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {ActionType | ActionFn | false} doubleTapAction\r\n * Refer to click and tap actions page.\r\n *\r\n * @prop {number} preloaderDelay\r\n * Delay before the loading indicator will be displayed,\r\n * if image is loaded during it - the indicator will not be displayed at all. Can be zero.\r\n *\r\n * @prop {string} indexIndicatorSep\r\n * Used for slide count indicator (\"1 of 10 \").\r\n *\r\n * @prop {(options: PhotoSwipeOptions, pswp: PhotoSwipeBase) => Point} [getViewportSizeFn]\r\n * A function that should return slide viewport width and height, in format {x: 100, y: 100}.\r\n *\r\n * @prop {string} errorMsg\r\n * Message to display when the image wasn't able to load. If you need to display HTML - use contentErrorElement filter.\r\n *\r\n * @prop {[number, number]} preload\r\n * Lazy loading of nearby slides based on direction of movement. Should be an array with two integers,\r\n * first one - number of items to preload before the current image, second one - after the current image.\r\n * Two nearby images are always loaded.\r\n *\r\n * @prop {string} [mainClass]\r\n * Class that will be added to the root element of PhotoSwipe, may contain multiple separated by space.\r\n * Example on Styling page.\r\n *\r\n * @prop {HTMLElement} [appendToEl]\r\n * Element to which PhotoSwipe dialog will be appended when it opens.\r\n *\r\n * @prop {number} maxWidthToAnimate\r\n * Maximum width of image to animate, if initial rendered image width\r\n * is larger than this value - the opening/closing transition will be automatically disabled.\r\n *\r\n * @prop {string} [closeTitle]\r\n * Translating\r\n *\r\n * @prop {string} [zoomTitle]\r\n * Translating\r\n *\r\n * @prop {string} [arrowPrevTitle]\r\n * Translating\r\n *\r\n * @prop {string} [arrowNextTitle]\r\n * Translating\r\n *\r\n * @prop {'zoom' | 'fade' | 'none'} [showHideAnimationType]\r\n * To adjust opening or closing transition type use lightbox option `showHideAnimationType` (`String`).\r\n * It supports three values - `zoom` (default), `fade` (default if there is no thumbnail) and `none`.\r\n *\r\n * Animations are automatically disabled if user `(prefers-reduced-motion: reduce)`.\r\n *\r\n * @prop {number} index\r\n * Defines start slide index.\r\n *\r\n * @prop {(e: MouseEvent) => number} [getClickedIndexFn]\r\n *\r\n * @prop {boolean} [arrowPrev]\r\n * @prop {boolean} [arrowNext]\r\n * @prop {boolean} [zoom]\r\n * @prop {boolean} [close]\r\n * @prop {boolean} [counter]\r\n *\r\n * @prop {string} [arrowPrevSVG]\r\n * @prop {string} [arrowNextSVG]\r\n * @prop {string} [zoomSVG]\r\n * @prop {string} [closeSVG]\r\n * @prop {string} [counterSVG]\r\n *\r\n * @prop {string} [arrowPrevTitle]\r\n * @prop {string} [arrowNextTitle]\r\n * @prop {string} [zoomTitle]\r\n * @prop {string} [closeTitle]\r\n * @prop {string} [counterTitle]\r\n *\r\n * @prop {ZoomLevelOption} [initialZoomLevel]\r\n * @prop {ZoomLevelOption} [secondaryZoomLevel]\r\n * @prop {ZoomLevelOption} [maxZoomLevel]\r\n *\r\n * @prop {boolean} [mouseMovePan]\r\n * @prop {Point | null} [initialPointerPos]\r\n * @prop {boolean} [showHideOpacity]\r\n *\r\n * @prop {PhotoSwipeModuleOption} [pswpModule]\r\n * @prop {() => Promise} [openPromise]\r\n * @prop {boolean} [preloadFirstSlide]\r\n * @prop {ElementProvider} [gallery]\r\n * @prop {string} [gallerySelector]\r\n * @prop {ElementProvider} [children]\r\n * @prop {string} [childSelector]\r\n * @prop {string | false} [thumbSelector]\r\n */\n\n/** @type {PreparedPhotoSwipeOptions} */\n\nconst defaultOptions = {\n allowPanToNext: true,\n spacing: 0.1,\n loop: true,\n pinchToClose: true,\n closeOnVerticalDrag: true,\n hideAnimationDuration: 333,\n showAnimationDuration: 333,\n zoomAnimationDuration: 333,\n escKey: true,\n arrowKeys: true,\n trapFocus: true,\n returnFocus: true,\n maxWidthToAnimate: 4000,\n clickToCloseNonZoomable: true,\n imageClickAction: 'zoom-or-close',\n bgClickAction: 'close',\n tapAction: 'toggle-controls',\n doubleTapAction: 'zoom',\n indexIndicatorSep: ' / ',\n preloaderDelay: 2000,\n bgOpacity: 0.8,\n index: 0,\n errorMsg: 'The image cannot be loaded',\n preload: [1, 2],\n easing: 'cubic-bezier(.4,0,.22,1)'\n};\n/**\r\n * PhotoSwipe Core\r\n */\n\nclass PhotoSwipe extends PhotoSwipeBase {\n /**\r\n * @param {PhotoSwipeOptions} [options]\r\n */\n constructor(options) {\n super();\n this.options = this._prepareOptions(options || {});\n /**\r\n * offset of viewport relative to document\r\n *\r\n * @type {Point}\r\n */\n\n this.offset = {\n x: 0,\n y: 0\n };\n /**\r\n * @type {Point}\r\n * @private\r\n */\n\n this._prevViewportSize = {\n x: 0,\n y: 0\n };\n /**\r\n * Size of scrollable PhotoSwipe viewport\r\n *\r\n * @type {Point}\r\n */\n\n this.viewportSize = {\n x: 0,\n y: 0\n };\n /**\r\n * background (backdrop) opacity\r\n */\n\n this.bgOpacity = 1;\n this.currIndex = 0;\n this.potentialIndex = 0;\n this.isOpen = false;\n this.isDestroying = false;\n this.hasMouse = false;\n /**\r\n * @private\r\n * @type {SlideData}\r\n */\n\n this._initialItemData = {};\n /** @type {Bounds | undefined} */\n\n this._initialThumbBounds = undefined;\n /** @type {HTMLDivElement | undefined} */\n\n this.topBar = undefined;\n /** @type {HTMLDivElement | undefined} */\n\n this.element = undefined;\n /** @type {HTMLDivElement | undefined} */\n\n this.template = undefined;\n /** @type {HTMLDivElement | undefined} */\n\n this.container = undefined;\n /** @type {HTMLElement | undefined} */\n\n this.scrollWrap = undefined;\n /** @type {Slide | undefined} */\n\n this.currSlide = undefined;\n this.events = new DOMEvents();\n this.animations = new Animations();\n this.mainScroll = new MainScroll(this);\n this.gestures = new Gestures(this);\n this.opener = new Opener(this);\n this.keyboard = new Keyboard(this);\n this.contentLoader = new ContentLoader(this);\n }\n /** @returns {boolean} */\n\n\n init() {\n if (this.isOpen || this.isDestroying) {\n return false;\n }\n\n this.isOpen = true;\n this.dispatch('init'); // legacy\n\n this.dispatch('beforeOpen');\n\n this._createMainStructure(); // add classes to the root element of PhotoSwipe\n\n\n let rootClasses = 'pswp--open';\n\n if (this.gestures.supportsTouch) {\n rootClasses += ' pswp--touch';\n }\n\n if (this.options.mainClass) {\n rootClasses += ' ' + this.options.mainClass;\n }\n\n if (this.element) {\n this.element.className += ' ' + rootClasses;\n }\n\n this.currIndex = this.options.index || 0;\n this.potentialIndex = this.currIndex;\n this.dispatch('firstUpdate'); // starting index can be modified here\n // initialize scroll wheel handler to block the scroll\n\n this.scrollWheel = new ScrollWheel(this); // sanitize index\n\n if (Number.isNaN(this.currIndex) || this.currIndex < 0 || this.currIndex >= this.getNumItems()) {\n this.currIndex = 0;\n }\n\n if (!this.gestures.supportsTouch) {\n // enable mouse features if no touch support detected\n this.mouseDetected();\n } // causes forced synchronous layout\n\n\n this.updateSize();\n this.offset.y = window.pageYOffset;\n this._initialItemData = this.getItemData(this.currIndex);\n this.dispatch('gettingData', {\n index: this.currIndex,\n data: this._initialItemData,\n slide: undefined\n }); // *Layout* - calculate size and position of elements here\n\n this._initialThumbBounds = this.getThumbBounds();\n this.dispatch('initialLayout');\n this.on('openingAnimationEnd', () => {\n const {\n itemHolders\n } = this.mainScroll; // Add content to the previous and next slide\n\n if (itemHolders[0]) {\n itemHolders[0].el.style.display = 'block';\n this.setContent(itemHolders[0], this.currIndex - 1);\n }\n\n if (itemHolders[2]) {\n itemHolders[2].el.style.display = 'block';\n this.setContent(itemHolders[2], this.currIndex + 1);\n }\n\n this.appendHeavy();\n this.contentLoader.updateLazy();\n this.events.add(window, 'resize', this._handlePageResize.bind(this));\n this.events.add(window, 'scroll', this._updatePageScrollOffset.bind(this));\n this.dispatch('bindEvents');\n }); // set content for center slide (first time)\n\n if (this.mainScroll.itemHolders[1]) {\n this.setContent(this.mainScroll.itemHolders[1], this.currIndex);\n }\n\n this.dispatch('change');\n this.opener.open();\n this.dispatch('afterInit');\n return true;\n }\n /**\r\n * Get looped slide index\r\n * (for example, -1 will return the last slide)\r\n *\r\n * @param {number} index\r\n * @returns {number}\r\n */\n\n\n getLoopedIndex(index) {\n const numSlides = this.getNumItems();\n\n if (this.options.loop) {\n if (index > numSlides - 1) {\n index -= numSlides;\n }\n\n if (index < 0) {\n index += numSlides;\n }\n }\n\n return clamp(index, 0, numSlides - 1);\n }\n\n appendHeavy() {\n this.mainScroll.itemHolders.forEach(itemHolder => {\n var _itemHolder$slide;\n\n (_itemHolder$slide = itemHolder.slide) === null || _itemHolder$slide === void 0 || _itemHolder$slide.appendHeavy();\n });\n }\n /**\r\n * Change the slide\r\n * @param {number} index New index\r\n */\n\n\n goTo(index) {\n this.mainScroll.moveIndexBy(this.getLoopedIndex(index) - this.potentialIndex);\n }\n /**\r\n * Go to the next slide.\r\n */\n\n\n next() {\n this.goTo(this.potentialIndex + 1);\n }\n /**\r\n * Go to the previous slide.\r\n */\n\n\n prev() {\n this.goTo(this.potentialIndex - 1);\n }\n /**\r\n * @see slide/slide.js zoomTo\r\n *\r\n * @param {Parameters} args\r\n */\n\n\n zoomTo(...args) {\n var _this$currSlide;\n\n (_this$currSlide = this.currSlide) === null || _this$currSlide === void 0 || _this$currSlide.zoomTo(...args);\n }\n /**\r\n * @see slide/slide.js toggleZoom\r\n */\n\n\n toggleZoom() {\n var _this$currSlide2;\n\n (_this$currSlide2 = this.currSlide) === null || _this$currSlide2 === void 0 || _this$currSlide2.toggleZoom();\n }\n /**\r\n * Close the gallery.\r\n * After closing transition ends - destroy it\r\n */\n\n\n close() {\n if (!this.opener.isOpen || this.isDestroying) {\n return;\n }\n\n this.isDestroying = true;\n this.dispatch('close');\n this.events.removeAll();\n this.opener.close();\n }\n /**\r\n * Destroys the gallery:\r\n * - instantly closes the gallery\r\n * - unbinds events,\r\n * - cleans intervals and timeouts\r\n * - removes elements from DOM\r\n */\n\n\n destroy() {\n var _this$element;\n\n if (!this.isDestroying) {\n this.options.showHideAnimationType = 'none';\n this.close();\n return;\n }\n\n this.dispatch('destroy');\n this._listeners = {};\n\n if (this.scrollWrap) {\n this.scrollWrap.ontouchmove = null;\n this.scrollWrap.ontouchend = null;\n }\n\n (_this$element = this.element) === null || _this$element === void 0 || _this$element.remove();\n this.mainScroll.itemHolders.forEach(itemHolder => {\n var _itemHolder$slide2;\n\n (_itemHolder$slide2 = itemHolder.slide) === null || _itemHolder$slide2 === void 0 || _itemHolder$slide2.destroy();\n });\n this.contentLoader.destroy();\n this.events.removeAll();\n }\n /**\r\n * Refresh/reload content of a slide by its index\r\n *\r\n * @param {number} slideIndex\r\n */\n\n\n refreshSlideContent(slideIndex) {\n this.contentLoader.removeByIndex(slideIndex);\n this.mainScroll.itemHolders.forEach((itemHolder, i) => {\n var _this$currSlide$index, _this$currSlide3;\n\n let potentialHolderIndex = ((_this$currSlide$index = (_this$currSlide3 = this.currSlide) === null || _this$currSlide3 === void 0 ? void 0 : _this$currSlide3.index) !== null && _this$currSlide$index !== void 0 ? _this$currSlide$index : 0) - 1 + i;\n\n if (this.canLoop()) {\n potentialHolderIndex = this.getLoopedIndex(potentialHolderIndex);\n }\n\n if (potentialHolderIndex === slideIndex) {\n // set the new slide content\n this.setContent(itemHolder, slideIndex, true); // activate the new slide if it's current\n\n if (i === 1) {\n var _itemHolder$slide3;\n\n this.currSlide = itemHolder.slide;\n (_itemHolder$slide3 = itemHolder.slide) === null || _itemHolder$slide3 === void 0 || _itemHolder$slide3.setIsActive(true);\n }\n }\n });\n this.dispatch('change');\n }\n /**\r\n * Set slide content\r\n *\r\n * @param {ItemHolder} holder mainScroll.itemHolders array item\r\n * @param {number} index Slide index\r\n * @param {boolean} [force] If content should be set even if index wasn't changed\r\n */\n\n\n setContent(holder, index, force) {\n if (this.canLoop()) {\n index = this.getLoopedIndex(index);\n }\n\n if (holder.slide) {\n if (holder.slide.index === index && !force) {\n // exit if holder already contains this slide\n // this could be common when just three slides are used\n return;\n } // destroy previous slide\n\n\n holder.slide.destroy();\n holder.slide = undefined;\n } // exit if no loop and index is out of bounds\n\n\n if (!this.canLoop() && (index < 0 || index >= this.getNumItems())) {\n return;\n }\n\n const itemData = this.getItemData(index);\n holder.slide = new Slide(itemData, index, this); // set current slide\n\n if (index === this.currIndex) {\n this.currSlide = holder.slide;\n }\n\n holder.slide.append(holder.el);\n }\n /** @returns {Point} */\n\n\n getViewportCenterPoint() {\n return {\n x: this.viewportSize.x / 2,\n y: this.viewportSize.y / 2\n };\n }\n /**\r\n * Update size of all elements.\r\n * Executed on init and on page resize.\r\n *\r\n * @param {boolean} [force] Update size even if size of viewport was not changed.\r\n */\n\n\n updateSize(force) {\n // let item;\n // let itemIndex;\n if (this.isDestroying) {\n // exit if PhotoSwipe is closed or closing\n // (to avoid errors, as resize event might be delayed)\n return;\n } //const newWidth = this.scrollWrap.clientWidth;\n //const newHeight = this.scrollWrap.clientHeight;\n\n\n const newViewportSize = getViewportSize(this.options, this);\n\n if (!force && pointsEqual(newViewportSize, this._prevViewportSize)) {\n // Exit if dimensions were not changed\n return;\n } //this._prevViewportSize.x = newWidth;\n //this._prevViewportSize.y = newHeight;\n\n\n equalizePoints(this._prevViewportSize, newViewportSize);\n this.dispatch('beforeResize');\n equalizePoints(this.viewportSize, this._prevViewportSize);\n\n this._updatePageScrollOffset();\n\n this.dispatch('viewportSize'); // Resize slides only after opener animation is finished\n // and don't re-calculate size on inital size update\n\n this.mainScroll.resize(this.opener.isOpen);\n\n if (!this.hasMouse && window.matchMedia('(any-hover: hover)').matches) {\n this.mouseDetected();\n }\n\n this.dispatch('resize');\n }\n /**\r\n * @param {number} opacity\r\n */\n\n\n applyBgOpacity(opacity) {\n this.bgOpacity = Math.max(opacity, 0);\n\n if (this.bg) {\n this.bg.style.opacity = String(this.bgOpacity * this.options.bgOpacity);\n }\n }\n /**\r\n * Whether mouse is detected\r\n */\n\n\n mouseDetected() {\n if (!this.hasMouse) {\n var _this$element2;\n\n this.hasMouse = true;\n (_this$element2 = this.element) === null || _this$element2 === void 0 || _this$element2.classList.add('pswp--has_mouse');\n }\n }\n /**\r\n * Page resize event handler\r\n *\r\n * @private\r\n */\n\n\n _handlePageResize() {\n this.updateSize(); // In iOS webview, if element size depends on document size,\n // it'll be measured incorrectly in resize event\n //\n // https://bugs.webkit.org/show_bug.cgi?id=170595\n // https://hackernoon.com/onresize-event-broken-in-mobile-safari-d8469027bf4d\n\n if (/iPhone|iPad|iPod/i.test(window.navigator.userAgent)) {\n setTimeout(() => {\n this.updateSize();\n }, 500);\n }\n }\n /**\r\n * Page scroll offset is used\r\n * to get correct coordinates\r\n * relative to PhotoSwipe viewport.\r\n *\r\n * @private\r\n */\n\n\n _updatePageScrollOffset() {\n this.setScrollOffset(0, window.pageYOffset);\n }\n /**\r\n * @param {number} x\r\n * @param {number} y\r\n */\n\n\n setScrollOffset(x, y) {\n this.offset.x = x;\n this.offset.y = y;\n this.dispatch('updateScrollOffset');\n }\n /**\r\n * Create main HTML structure of PhotoSwipe,\r\n * and add it to DOM\r\n *\r\n * @private\r\n */\n\n\n _createMainStructure() {\n // root DOM element of PhotoSwipe (.pswp)\n this.element = createElement('pswp', 'div');\n this.element.setAttribute('tabindex', '-1');\n this.element.setAttribute('role', 'dialog'); // template is legacy prop\n\n this.template = this.element; // Background is added as a separate element,\n // as animating opacity is faster than animating rgba()\n\n this.bg = createElement('pswp__bg', 'div', this.element);\n this.scrollWrap = createElement('pswp__scroll-wrap', 'section', this.element);\n this.container = createElement('pswp__container', 'div', this.scrollWrap); // aria pattern: carousel\n\n this.scrollWrap.setAttribute('aria-roledescription', 'carousel');\n this.container.setAttribute('aria-live', 'off');\n this.container.setAttribute('id', 'pswp__items');\n this.mainScroll.appendHolders();\n this.ui = new UI(this);\n this.ui.init(); // append to DOM\n\n (this.options.appendToEl || document.body).appendChild(this.element);\n }\n /**\r\n * Get position and dimensions of small thumbnail\r\n * {x:,y:,w:}\r\n *\r\n * Height is optional (calculated based on the large image)\r\n *\r\n * @returns {Bounds | undefined}\r\n */\n\n\n getThumbBounds() {\n return getThumbBounds(this.currIndex, this.currSlide ? this.currSlide.data : this._initialItemData, this);\n }\n /**\r\n * If the PhotoSwipe can have continuous loop\r\n * @returns Boolean\r\n */\n\n\n canLoop() {\n return this.options.loop && this.getNumItems() > 2;\n }\n /**\r\n * @private\r\n * @param {PhotoSwipeOptions} options\r\n * @returns {PreparedPhotoSwipeOptions}\r\n */\n\n\n _prepareOptions(options) {\n if (window.matchMedia('(prefers-reduced-motion), (update: slow)').matches) {\n options.showHideAnimationType = 'none';\n options.zoomAnimationDuration = 0;\n }\n /** @type {PreparedPhotoSwipeOptions} */\n\n\n return { ...defaultOptions,\n ...options\n };\n }\n\n}\n\nexport { PhotoSwipe as default };\n//# sourceMappingURL=photoswipe.esm.js.map\n","/*!\n * PhotoSwipe Lightbox 5.4.4 - https://photoswipe.com\n * (c) 2024 Dmytro Semenov\n */\n/** @typedef {import('../photoswipe.js').Point} Point */\n\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 */\nfunction createElement(className, tagName, appendToEl) {\n const el = document.createElement(tagName);\n\n if (className) {\n el.className = className;\n }\n\n if (appendToEl) {\n appendToEl.appendChild(el);\n }\n\n return el;\n}\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 */\n\nfunction toTransformString(x, y, scale) {\n let propValue = `translate3d(${x}px,${y || 0}px,0)`;\n\n if (scale !== undefined) {\n propValue += ` scale3d(${scale},${scale},1)`;\n }\n\n return propValue;\n}\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 */\n\nfunction setWidthHeight(el, w, h) {\n el.style.width = typeof w === 'number' ? `${w}px` : w;\n el.style.height = typeof h === 'number' ? `${h}px` : h;\n}\n/** @typedef {LOAD_STATE[keyof LOAD_STATE]} LoadState */\n\n/** @type {{ IDLE: 'idle'; LOADING: 'loading'; LOADED: 'loaded'; ERROR: 'error' }} */\n\nconst LOAD_STATE = {\n IDLE: 'idle',\n LOADING: 'loading',\n LOADED: 'loaded',\n ERROR: 'error'\n};\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 */\n\nfunction specialKeyUsed(e) {\n return 'button' in e && e.button === 1 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey;\n}\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 */\n\nfunction getElementsFromOption(option, legacySelector, parent = document) {\n /** @type {HTMLElement[]} */\n let elements = [];\n\n if (option instanceof Element) {\n elements = [option];\n } else if (option instanceof NodeList || Array.isArray(option)) {\n elements = Array.from(option);\n } else {\n const selector = typeof option === 'string' ? option : legacySelector;\n\n if (selector) {\n elements = Array.from(parent.querySelectorAll(selector));\n }\n }\n\n return elements;\n}\n/**\r\n * Check if variable is PhotoSwipe class\r\n *\r\n * @param {any} fn\r\n * @returns {boolean}\r\n */\n\nfunction isPswpClass(fn) {\n return typeof fn === 'function' && fn.prototype && fn.prototype.goTo;\n}\n/**\r\n * Check if browser is Safari\r\n *\r\n * @returns {boolean}\r\n */\n\nfunction isSafari() {\n return !!(navigator.vendor && navigator.vendor.match(/apple/i));\n}\n\n/** @typedef {import('../lightbox/lightbox.js').default} PhotoSwipeLightbox */\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../photoswipe.js').DataSource} DataSource */\n\n/** @typedef {import('../ui/ui-element.js').UIElementData} UIElementData */\n\n/** @typedef {import('../slide/content.js').default} ContentDefault */\n\n/** @typedef {import('../slide/slide.js').default} Slide */\n\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\n\n/** @typedef {import('../slide/zoom-level.js').default} ZoomLevel */\n\n/** @typedef {import('../slide/get-thumb-bounds.js').Bounds} Bounds */\n\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 */\n\n/** @typedef {{ x?: number; y?: number }} Point */\n\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 */\n\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 */\n\n/**\r\n * @template {keyof PhotoSwipeFiltersMap} T\r\n * @typedef {{ fn: PhotoSwipeFiltersMap[T], priority: number }} Filter\r\n */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {PhotoSwipeEventsMap[T] extends undefined ? PhotoSwipeEvent : PhotoSwipeEvent & PhotoSwipeEventsMap[T]} AugmentedEvent\r\n */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {(event: AugmentedEvent) => void} EventCallback\r\n */\n\n/**\r\n * Base PhotoSwipe event object\r\n *\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n */\nclass PhotoSwipeEvent {\n /**\r\n * @param {T} type\r\n * @param {PhotoSwipeEventsMap[T]} [details]\r\n */\n constructor(type, details) {\n this.type = type;\n this.defaultPrevented = false;\n\n if (details) {\n Object.assign(this, details);\n }\n }\n\n preventDefault() {\n this.defaultPrevented = true;\n }\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 */\n\n\nclass Eventable {\n constructor() {\n /**\r\n * @type {{ [T in keyof PhotoSwipeEventsMap]?: ((event: AugmentedEvent) => void)[] }}\r\n */\n this._listeners = {};\n /**\r\n * @type {{ [T in keyof PhotoSwipeFiltersMap]?: Filter[] }}\r\n */\n\n this._filters = {};\n /** @type {PhotoSwipe | undefined} */\n\n this.pswp = undefined;\n /** @type {PhotoSwipeOptions | undefined} */\n\n 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 */\n\n\n addFilter(name, fn, priority = 100) {\n var _this$_filters$name, _this$_filters$name2, _this$pswp;\n\n if (!this._filters[name]) {\n this._filters[name] = [];\n }\n\n (_this$_filters$name = this._filters[name]) === null || _this$_filters$name === void 0 || _this$_filters$name.push({\n fn,\n priority\n });\n (_this$_filters$name2 = this._filters[name]) === null || _this$_filters$name2 === void 0 || _this$_filters$name2.sort((f1, f2) => f1.priority - f2.priority);\n (_this$pswp = this.pswp) === null || _this$pswp === void 0 || _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 */\n\n\n removeFilter(name, fn) {\n if (this._filters[name]) {\n // @ts-expect-error\n this._filters[name] = this._filters[name].filter(filter => filter.fn !== fn);\n }\n\n if (this.pswp) {\n this.pswp.removeFilter(name, fn);\n }\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 */\n\n\n applyFilters(name, ...args) {\n var _this$_filters$name3;\n\n (_this$_filters$name3 = this._filters[name]) === null || _this$_filters$name3 === void 0 || _this$_filters$name3.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 */\n\n\n on(name, fn) {\n var _this$_listeners$name, _this$pswp2;\n\n if (!this._listeners[name]) {\n this._listeners[name] = [];\n }\n\n (_this$_listeners$name = this._listeners[name]) === null || _this$_listeners$name === void 0 || _this$_listeners$name.push(fn); // When binding events to lightbox,\n // also bind events to PhotoSwipe Core,\n // if it's open.\n\n (_this$pswp2 = this.pswp) === null || _this$pswp2 === void 0 || _this$pswp2.on(name, fn);\n }\n /**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @param {T} name\r\n * @param {EventCallback} fn\r\n */\n\n\n off(name, fn) {\n var _this$pswp3;\n\n if (this._listeners[name]) {\n // @ts-expect-error\n this._listeners[name] = this._listeners[name].filter(listener => fn !== listener);\n }\n\n (_this$pswp3 = this.pswp) === null || _this$pswp3 === void 0 || _this$pswp3.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 */\n\n\n dispatch(name, details) {\n var _this$_listeners$name2;\n\n if (this.pswp) {\n return this.pswp.dispatch(name, details);\n }\n\n const event =\n /** @type {AugmentedEvent} */\n new PhotoSwipeEvent(name, details);\n (_this$_listeners$name2 = this._listeners[name]) === null || _this$_listeners$name2 === void 0 || _this$_listeners$name2.forEach(listener => {\n listener.call(this, event);\n });\n return event;\n }\n\n}\n\nclass Placeholder {\n /**\r\n * @param {string | false} imageSrc\r\n * @param {HTMLElement} container\r\n */\n constructor(imageSrc, container) {\n // Create placeholder\n // (stretched thumbnail or simple div behind the main image)\n\n /** @type {HTMLImageElement | HTMLDivElement | null} */\n this.element = createElement('pswp__img pswp__img--placeholder', imageSrc ? 'img' : 'div', container);\n\n if (imageSrc) {\n const imgEl =\n /** @type {HTMLImageElement} */\n this.element;\n imgEl.decoding = 'async';\n imgEl.alt = '';\n imgEl.src = imageSrc;\n imgEl.setAttribute('role', 'presentation');\n }\n\n this.element.setAttribute('aria-hidden', 'true');\n }\n /**\r\n * @param {number} width\r\n * @param {number} height\r\n */\n\n\n setDisplayedSize(width, height) {\n if (!this.element) {\n return;\n }\n\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 setWidthHeight(this.element, 250, 'auto');\n this.element.style.transformOrigin = '0 0';\n this.element.style.transform = toTransformString(0, 0, width / 250);\n } else {\n setWidthHeight(this.element, width, height);\n }\n }\n\n destroy() {\n var _this$element;\n\n if ((_this$element = this.element) !== null && _this$element !== void 0 && _this$element.parentNode) {\n this.element.remove();\n }\n\n this.element = null;\n }\n\n}\n\n/** @typedef {import('./slide.js').default} Slide */\n\n/** @typedef {import('./slide.js').SlideData} SlideData */\n\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\n\n/** @typedef {import('../util/util.js').LoadState} LoadState */\n\nclass 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 */\n constructor(itemData, instance, index) {\n this.instance = instance;\n this.data = itemData;\n this.index = index;\n /** @type {HTMLImageElement | HTMLDivElement | undefined} */\n\n this.element = undefined;\n /** @type {Placeholder | undefined} */\n\n this.placeholder = undefined;\n /** @type {Slide | undefined} */\n\n 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} */\n\n this.state = LOAD_STATE.IDLE;\n\n if (this.data.type) {\n this.type = this.data.type;\n } else if (this.data.src) {\n this.type = 'image';\n } else {\n this.type = 'html';\n }\n\n this.instance.dispatch('contentInit', {\n content: this\n });\n }\n\n removePlaceholder() {\n if (this.placeholder && !this.keepPlaceholder()) {\n // 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 }\n /**\r\n * Preload content\r\n *\r\n * @param {boolean} isLazy\r\n * @param {boolean} [reload]\r\n */\n\n\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 Placeholder(placeholderSrc, this.slide.container);\n } else {\n const placeholderEl = this.placeholder.element; // Add placeholder to DOM if it was already created\n\n if (placeholderEl && !placeholderEl.parentElement) {\n this.slide.container.prepend(placeholderEl);\n }\n }\n }\n\n if (this.element && !reload) {\n return;\n }\n\n if (this.instance.dispatch('contentLoad', {\n content: this,\n isLazy\n }).defaultPrevented) {\n return;\n }\n\n if (this.isImageContent()) {\n this.element = createElement('pswp__img', 'img'); // 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\n if (this.displayedImageWidth) {\n this.loadImage(isLazy);\n }\n } else {\n this.element = createElement('pswp__content', 'div');\n this.element.innerHTML = this.data.html || '';\n }\n\n if (reload && this.slide) {\n this.slide.updateContentSize(true);\n }\n }\n /**\r\n * Preload image\r\n *\r\n * @param {boolean} isLazy\r\n */\n\n\n loadImage(isLazy) {\n var _this$data$src, _this$data$alt;\n\n if (!this.isImageContent() || !this.element || this.instance.dispatch('contentLoadImage', {\n content: this,\n isLazy\n }).defaultPrevented) {\n return;\n }\n\n const imageElement =\n /** @type HTMLImageElement */\n this.element;\n this.updateSrcsetSizes();\n\n if (this.data.srcset) {\n imageElement.srcset = this.data.srcset;\n }\n\n imageElement.src = (_this$data$src = this.data.src) !== null && _this$data$src !== void 0 ? _this$data$src : '';\n imageElement.alt = (_this$data$alt = this.data.alt) !== null && _this$data$alt !== void 0 ? _this$data$alt : '';\n this.state = LOAD_STATE.LOADING;\n\n if (imageElement.complete) {\n this.onLoaded();\n } else {\n imageElement.onload = () => {\n this.onLoaded();\n };\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 */\n\n\n setSlide(slide) {\n this.slide = slide;\n this.hasSlide = true;\n this.instance = slide.pswp; // todo: do we need to unset slide?\n }\n /**\r\n * Content load success handler\r\n */\n\n\n onLoaded() {\n this.state = LOAD_STATE.LOADED;\n\n if (this.slide && this.element) {\n this.instance.dispatch('loadComplete', {\n slide: this.slide,\n content: this\n }); // if content is reloaded\n\n if (this.slide.isActive && this.slide.heavyAppended && !this.element.parentNode) {\n this.append();\n this.slide.updateContentSize(true);\n }\n\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\n this.removePlaceholder();\n }\n }\n }\n /**\r\n * Content load error handler\r\n */\n\n\n onError() {\n this.state = LOAD_STATE.ERROR;\n\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 */\n\n\n isLoading() {\n return this.instance.applyFilters('isContentLoading', this.state === LOAD_STATE.LOADING, this);\n }\n /**\r\n * @returns {Boolean} If the content is in error state\r\n */\n\n\n isError() {\n return this.state === LOAD_STATE.ERROR;\n }\n /**\r\n * @returns {boolean} If the content is image\r\n */\n\n\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 */\n\n\n setDisplayedSize(width, height) {\n if (!this.element) {\n return;\n }\n\n if (this.placeholder) {\n this.placeholder.setDisplayedSize(width, height);\n }\n\n if (this.instance.dispatch('contentResize', {\n content: this,\n width,\n height\n }).defaultPrevented) {\n return;\n }\n\n setWidthHeight(this.element, width, height);\n\n if (this.isImageContent() && !this.isError()) {\n const isInitialSizeUpdate = !this.displayedImageWidth && width;\n this.displayedImageWidth = width;\n this.displayedImageHeight = height;\n\n if (isInitialSizeUpdate) {\n this.loadImage(false);\n } else {\n this.updateSrcsetSizes();\n }\n\n if (this.slide) {\n this.instance.dispatch('imageSizeChange', {\n slide: this.slide,\n width,\n height,\n content: this\n });\n }\n }\n }\n /**\r\n * @returns {boolean} If the content can be zoomed\r\n */\n\n\n isZoomable() {\n return this.instance.applyFilters('isContentZoomable', this.isImageContent() && this.state !== LOAD_STATE.ERROR, this);\n }\n /**\r\n * Update image srcset sizes attribute based on width and height\r\n */\n\n\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) {\n return;\n }\n\n const image =\n /** @type HTMLImageElement */\n this.element;\n const sizesWidth = this.instance.applyFilters('srcsetSizesWidth', this.displayedImageWidth, this);\n\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 */\n\n\n usePlaceholder() {\n return this.instance.applyFilters('useContentPlaceholder', this.isImageContent(), this);\n }\n /**\r\n * Preload content with lazy-loading param\r\n */\n\n\n lazyLoad() {\n if (this.instance.dispatch('contentLazyLoad', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n this.load(true);\n }\n /**\r\n * @returns {boolean} If placeholder should be kept after content is loaded\r\n */\n\n\n keepPlaceholder() {\n return this.instance.applyFilters('isKeepingPlaceholder', this.isLoading(), this);\n }\n /**\r\n * Destroy the content\r\n */\n\n\n destroy() {\n this.hasSlide = false;\n this.slide = undefined;\n\n if (this.instance.dispatch('contentDestroy', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n this.remove();\n\n if (this.placeholder) {\n this.placeholder.destroy();\n this.placeholder = undefined;\n }\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 */\n\n\n displayError() {\n if (this.slide) {\n var _this$instance$option, _this$instance$option2;\n\n let errorMsgEl = createElement('pswp__error-msg', 'div');\n errorMsgEl.innerText = (_this$instance$option = (_this$instance$option2 = this.instance.options) === null || _this$instance$option2 === void 0 ? void 0 : _this$instance$option2.errorMsg) !== null && _this$instance$option !== void 0 ? _this$instance$option : '';\n errorMsgEl =\n /** @type {HTMLDivElement} */\n this.instance.applyFilters('contentErrorElement', errorMsgEl, this);\n this.element = 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 */\n\n\n append() {\n if (this.isAttached || !this.element) {\n return;\n }\n\n this.isAttached = true;\n\n if (this.state === LOAD_STATE.ERROR) {\n this.displayError();\n return;\n }\n\n if (this.instance.dispatch('contentAppend', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n const supportsDecode = ('decode' in this.element);\n\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 || isSafari())) {\n this.isDecoding = true; // purposefully using finally instead of then,\n // as if srcset sizes changes dynamically - it may cause decode error\n\n /** @type {HTMLImageElement} */\n\n this.element.decode().catch(() => {}).finally(() => {\n this.isDecoding = false;\n this.appendImage();\n });\n } else {\n this.appendImage();\n }\n } else if (this.slide && !this.element.parentNode) {\n this.slide.container.appendChild(this.element);\n }\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 */\n\n\n activate() {\n if (this.instance.dispatch('contentActivate', {\n content: this\n }).defaultPrevented || !this.slide) {\n return;\n }\n\n if (this.isImageContent() && this.isDecoding && !isSafari()) {\n // add image to slide when it becomes active,\n // even if it's not finished decoding\n this.appendImage();\n } else if (this.isError()) {\n this.load(false, true); // try to reload\n }\n\n if (this.slide.holderElement) {\n this.slide.holderElement.setAttribute('aria-hidden', 'false');\n }\n }\n /**\r\n * Deactivate the content\r\n */\n\n\n deactivate() {\n this.instance.dispatch('contentDeactivate', {\n content: this\n });\n\n if (this.slide && this.slide.holderElement) {\n this.slide.holderElement.setAttribute('aria-hidden', 'true');\n }\n }\n /**\r\n * Remove the content from DOM\r\n */\n\n\n remove() {\n this.isAttached = false;\n\n if (this.instance.dispatch('contentRemove', {\n content: this\n }).defaultPrevented) {\n return;\n }\n\n if (this.element && this.element.parentNode) {\n this.element.remove();\n }\n\n if (this.placeholder && this.placeholder.element) {\n this.placeholder.element.remove();\n }\n }\n /**\r\n * Append the image content to slide container\r\n */\n\n\n appendImage() {\n if (!this.isAttached) {\n return;\n }\n\n if (this.instance.dispatch('contentAppendImage', {\n content: this\n }).defaultPrevented) {\n return;\n } // ensure that element exists and is not already appended\n\n\n if (this.slide && this.element && !this.element.parentNode) {\n this.slide.container.appendChild(this.element);\n }\n\n if (this.state === LOAD_STATE.LOADED || this.state === LOAD_STATE.ERROR) {\n this.removePlaceholder();\n }\n }\n\n}\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../core/base.js').default} PhotoSwipeBase */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\n\n/**\r\n * @param {PhotoSwipeOptions} options\r\n * @param {PhotoSwipeBase} pswp\r\n * @returns {Point}\r\n */\nfunction getViewportSize(options, pswp) {\n if (options.getViewportSizeFn) {\n const newViewportSize = options.getViewportSizeFn(options, pswp);\n\n if (newViewportSize) {\n return newViewportSize;\n }\n }\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}\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 */\n\nfunction parsePaddingOption(prop, options, viewportSize, itemData, index) {\n let paddingValue = 0;\n\n if (options.paddingFn) {\n paddingValue = options.paddingFn(viewportSize, itemData, index)[prop];\n } else if (options.padding) {\n paddingValue = options.padding[prop];\n } else {\n const legacyPropName = 'padding' + prop[0].toUpperCase() + prop.slice(1); // @ts-expect-error\n\n if (options[legacyPropName]) {\n // @ts-expect-error\n paddingValue = options[legacyPropName];\n }\n }\n\n return Number(paddingValue) || 0;\n}\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 */\n\nfunction getPanAreaSize(options, viewportSize, itemData, index) {\n return {\n x: viewportSize.x - parsePaddingOption('left', options, viewportSize, itemData, index) - parsePaddingOption('right', options, viewportSize, itemData, index),\n y: viewportSize.y - parsePaddingOption('top', options, viewportSize, itemData, index) - parsePaddingOption('bottom', options, viewportSize, itemData, index)\n };\n}\n\nconst MAX_IMAGE_WIDTH = 4000;\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('../slide/slide.js').SlideData} SlideData */\n\n/** @typedef {'fit' | 'fill' | number | ((zoomLevelObject: ZoomLevel) => number)} ZoomLevelOption */\n\n/**\r\n * Calculates zoom levels for specific slide.\r\n * Depends on viewport size and image size.\r\n */\n\nclass 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 */\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 } */\n\n this.panAreaSize = null;\n /** @type { Point | null } */\n\n 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 */\n\n\n update(maxWidth, maxHeight, panAreaSize) {\n /** @type {Point} */\n 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); // zoom.vFill defines zoom level of the image\n // when it has 100% of viewport vertical space (height)\n\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\n if (this.pswp) {\n this.pswp.dispatch('zoomLevelsUpdate', {\n zoomLevels: this,\n slideData: this.itemData\n });\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 */\n\n\n _parseZoomLevelOption(optionPrefix) {\n const optionName =\n /** @type {'initialZoomLevel' | 'secondaryZoomLevel' | 'maxZoomLevel'} */\n optionPrefix + 'ZoomLevel';\n const optionValue = this.options[optionName];\n\n if (!optionValue) {\n return;\n }\n\n if (typeof optionValue === 'function') {\n return optionValue(this);\n }\n\n if (optionValue === 'fill') {\n return this.fill;\n }\n\n if (optionValue === 'fit') {\n return this.fit;\n }\n\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 */\n\n\n _getSecondary() {\n let currZoomLevel = this._parseZoomLevelOption('secondary');\n\n if (currZoomLevel) {\n return currZoomLevel;\n } // 3x of \"fit\" state, but not larger than original\n\n\n currZoomLevel = Math.min(1, this.fit * 3);\n\n if (this.elementSize && currZoomLevel * this.elementSize.x > MAX_IMAGE_WIDTH) {\n currZoomLevel = MAX_IMAGE_WIDTH / this.elementSize.x;\n }\n\n return currZoomLevel;\n }\n /**\r\n * Get initial image zoom level.\r\n *\r\n * @private\r\n * @return {number}\r\n */\n\n\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 */\n\n\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\n}\n\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 */\n\nfunction lazyLoadData(itemData, instance, index) {\n const content = instance.createContentFromData(itemData, index);\n /** @type {ZoomLevel | undefined} */\n\n let zoomLevel;\n const {\n options\n } = instance; // We need to know dimensions of the image to preload it,\n // as it might use srcset, and we need to define sizes\n\n if (options) {\n zoomLevel = new ZoomLevel(options, itemData, -1);\n let viewportSize;\n\n if (instance.pswp) {\n viewportSize = instance.pswp.viewportSize;\n } else {\n viewportSize = getViewportSize(options, instance);\n }\n\n const panAreaSize = getPanAreaSize(options, viewportSize, itemData, index);\n zoomLevel.update(content.width, content.height, panAreaSize);\n }\n\n content.lazyLoad();\n\n if (zoomLevel) {\n content.setDisplayedSize(Math.ceil(content.width * zoomLevel.initial), Math.ceil(content.height * zoomLevel.initial));\n }\n\n return content;\n}\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 */\n\nfunction lazyLoadSlide(index, instance) {\n const itemData = instance.getItemData(index);\n\n if (instance.dispatch('lazyLoadSlide', {\n index,\n itemData\n }).defaultPrevented) {\n return;\n }\n\n return lazyLoadData(itemData, instance, index);\n}\n\n/** @typedef {import(\"../photoswipe.js\").default} PhotoSwipe */\n\n/** @typedef {import(\"../slide/slide.js\").SlideData} SlideData */\n\n/**\r\n * PhotoSwipe base class that can retrieve data about every slide.\r\n * Shared by PhotoSwipe Core and PhotoSwipe Lightbox\r\n */\n\nclass PhotoSwipeBase extends Eventable {\n /**\r\n * Get total number of slides\r\n *\r\n * @returns {number}\r\n */\n getNumItems() {\n var _this$options;\n\n let numItems = 0;\n const dataSource = (_this$options = this.options) === null || _this$options === void 0 ? void 0 : _this$options.dataSource;\n\n if (dataSource && 'length' in dataSource) {\n // 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) {\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\n }\n\n if (dataSource.items) {\n numItems = dataSource.items.length;\n }\n } // legacy event, before filters were introduced\n\n\n const event = this.dispatch('numItems', {\n dataSource,\n 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 */\n\n\n createContentFromData(slideData, index) {\n return new Content(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 */\n\n\n getItemData(index) {\n var _this$options2;\n\n const dataSource = (_this$options2 = this.options) === null || _this$options2 === void 0 ? void 0 : _this$options2.dataSource;\n /** @type {SlideData | HTMLElement} */\n\n let dataSourceItem = {};\n\n if (Array.isArray(dataSource)) {\n // 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) {\n dataSource.items = this._getGalleryDOMElements(dataSource.gallery);\n }\n\n dataSourceItem = dataSource.items[index];\n }\n\n let itemData = dataSourceItem;\n\n if (itemData instanceof Element) {\n itemData = this._domElementToItemData(itemData);\n } // Dispatching the itemData event,\n // it's a legacy verion before filters were introduced\n\n\n const event = this.dispatch('itemData', {\n itemData: itemData || {},\n 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 */\n\n\n _getGalleryDOMElements(galleryElement) {\n var _this$options3, _this$options4;\n\n if ((_this$options3 = this.options) !== null && _this$options3 !== void 0 && _this$options3.children || (_this$options4 = this.options) !== null && _this$options4 !== void 0 && _this$options4.childSelector) {\n return getElementsFromOption(this.options.children, this.options.childSelector, galleryElement) || [];\n }\n\n return [galleryElement];\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 */\n\n\n _domElementToItemData(element) {\n /** @type {SlideData} */\n const itemData = {\n element\n };\n const linkEl =\n /** @type {HTMLAnchorElement} */\n element.tagName === 'A' ? element : element.querySelector('a');\n\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\n if (linkEl.dataset.pswpSrcset) {\n itemData.srcset = linkEl.dataset.pswpSrcset;\n }\n\n itemData.width = linkEl.dataset.pswpWidth ? parseInt(linkEl.dataset.pswpWidth, 10) : 0;\n itemData.height = linkEl.dataset.pswpHeight ? parseInt(linkEl.dataset.pswpHeight, 10) : 0; // support legacy w & h properties\n\n itemData.w = itemData.width;\n itemData.h = itemData.height;\n\n if (linkEl.dataset.pswpType) {\n itemData.type = linkEl.dataset.pswpType;\n }\n\n const thumbnailEl = element.querySelector('img');\n\n if (thumbnailEl) {\n var _thumbnailEl$getAttri;\n\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$getAttri = thumbnailEl.getAttribute('alt')) !== null && _thumbnailEl$getAttri !== void 0 ? _thumbnailEl$getAttri : '';\n }\n\n if (linkEl.dataset.pswpCropped || linkEl.dataset.cropped) {\n itemData.thumbCropped = true;\n }\n }\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 */\n\n\n lazyLoadData(itemData, index) {\n return lazyLoadData(itemData, this, index);\n }\n\n}\n\n/**\r\n * @template T\r\n * @typedef {import('../types.js').Type} Type\r\n */\n\n/** @typedef {import('../photoswipe.js').default} PhotoSwipe */\n\n/** @typedef {import('../photoswipe.js').PhotoSwipeOptions} PhotoSwipeOptions */\n\n/** @typedef {import('../photoswipe.js').DataSource} DataSource */\n\n/** @typedef {import('../photoswipe.js').Point} Point */\n\n/** @typedef {import('../slide/content.js').default} Content */\n\n/** @typedef {import('../core/eventable.js').PhotoSwipeEventsMap} PhotoSwipeEventsMap */\n\n/** @typedef {import('../core/eventable.js').PhotoSwipeFiltersMap} PhotoSwipeFiltersMap */\n\n/**\r\n * @template {keyof PhotoSwipeEventsMap} T\r\n * @typedef {import('../core/eventable.js').EventCallback} EventCallback\r\n */\n\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 */\n\nclass PhotoSwipeLightbox extends PhotoSwipeBase {\n /**\r\n * @param {PhotoSwipeOptions} [options]\r\n */\n constructor(options) {\n super();\n /** @type {PhotoSwipeOptions} */\n\n this.options = options || {};\n this._uid = 0;\n this.shouldOpen = false;\n /**\r\n * @private\r\n * @type {Content | undefined}\r\n */\n\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 */\n\n\n init() {\n // Bind click events to each gallery\n 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 */\n\n\n onThumbnailsClick(e) {\n // Exit and allow default browser action if:\n if (specialKeyUsed(e) // ... if clicked with a special key (ctrl/cmd...)\n || window.pswp) {\n // ... if PhotoSwipe is already open\n 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\n /** @type {Point | null} */\n\n\n let initialPoint = {\n x: e.clientX,\n y: e.clientY\n };\n\n if (!initialPoint.x && !initialPoint.y) {\n initialPoint = null;\n }\n\n let clickedIndex = this.getClickedIndex(e);\n clickedIndex = this.applyFilters('clickedIndex', clickedIndex, e, this);\n /** @type {DataSource} */\n\n const dataSource = {\n gallery:\n /** @type {HTMLElement} */\n e.currentTarget\n };\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 */\n\n\n getClickedIndex(e) {\n // legacy option\n if (this.options.getClickedIndexFn) {\n return this.options.getClickedIndexFn.call(this, e);\n }\n\n const clickedTarget =\n /** @type {HTMLElement} */\n e.target;\n const childElements = getElementsFromOption(this.options.children, this.options.childSelector,\n /** @type {HTMLElement} */\n e.currentTarget);\n const clickedChildIndex = childElements.findIndex(child => child === clickedTarget || child.contains(clickedTarget));\n\n if (clickedChildIndex !== -1) {\n return clickedChildIndex;\n } else if (this.options.children || this.options.childSelector) {\n // click wasn't on a child element\n return -1;\n } // There is only one item (which is the gallery)\n\n\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 */\n\n\n loadAndOpen(index, dataSource, initialPoint) {\n // Check if the gallery is already open\n if (window.pswp || !this.options) {\n return false;\n } // Use the first gallery element if dataSource is not provided\n\n\n if (!dataSource && this.options.gallery && this.options.children) {\n const galleryElements = getElementsFromOption(this.options.gallery);\n\n if (galleryElements[0]) {\n dataSource = {\n gallery: galleryElements[0]\n };\n }\n } // set initial index\n\n\n this.options.index = index; // define options for PhotoSwipe constructor\n\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 */\n\n\n preload(index, dataSource) {\n const {\n options\n } = this;\n\n if (dataSource) {\n options.dataSource = dataSource;\n } // Add the main module\n\n /** @type {Promise>[]} */\n\n\n const promiseArray = [];\n const pswpModuleType = typeof options.pswpModule;\n\n if (isPswpClass(options.pswpModule)) {\n promiseArray.push(Promise.resolve(\n /** @type {Type} */\n options.pswpModule));\n } else if (pswpModuleType === 'string') {\n throw new Error('pswpModule as string is no longer supported');\n } else if (pswpModuleType === 'function') {\n promiseArray.push(\n /** @type {() => Promise>} */\n options.pswpModule());\n } else {\n throw new Error('pswpModule is not valid');\n } // Add custom-defined promise, if any\n\n\n if (typeof options.openPromise === 'function') {\n // allow developers to perform some task before opening\n promiseArray.push(options.openPromise());\n }\n\n if (options.preloadFirstSlide !== false && index >= 0) {\n this._preloadedContent = lazyLoadSlide(index, this);\n } // Wait till all promises resolve and open PhotoSwipe\n\n\n const uid = ++this._uid;\n Promise.all(promiseArray).then(iterableModules => {\n if (this.shouldOpen) {\n const mainModule = iterableModules[0];\n\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 */\n\n\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) {\n return;\n }\n\n this.shouldOpen = false; // PhotoSwipe is already open\n\n if (window.pswp) {\n return;\n }\n /**\r\n * Pass data to PhotoSwipe and open init\r\n *\r\n * @type {PhotoSwipe}\r\n */\n\n\n const pswp = typeof module === 'object' ? new module.default(this.options) // eslint-disable-line\n : new module(this.options); // eslint-disable-line\n\n this.pswp = pswp;\n window.pswp = pswp; // map listeners from Lightbox to PhotoSwipe Core\n\n /** @type {(keyof PhotoSwipeEventsMap)[]} */\n\n Object.keys(this._listeners).forEach(name => {\n var _this$_listeners$name;\n\n (_this$_listeners$name = this._listeners[name]) === null || _this$_listeners$name === void 0 || _this$_listeners$name.forEach(fn => {\n pswp.on(name,\n /** @type {EventCallback} */\n fn);\n });\n }); // same with filters\n\n /** @type {(keyof PhotoSwipeFiltersMap)[]} */\n\n Object.keys(this._filters).forEach(name => {\n var _this$_filters$name;\n\n (_this$_filters$name = this._filters[name]) === null || _this$_filters$name === void 0 || _this$_filters$name.forEach(filter => {\n pswp.addFilter(name, filter.fn, filter.priority);\n });\n });\n\n if (this._preloadedContent) {\n pswp.contentLoader.addToCache(this._preloadedContent);\n this._preloadedContent = undefined;\n }\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 */\n\n\n destroy() {\n var _this$pswp;\n\n (_this$pswp = this.pswp) === null || _this$pswp === void 0 || _this$pswp.destroy();\n this.shouldOpen = false;\n this._listeners = {};\n getElementsFromOption(this.options.gallery, this.options.gallerySelector).forEach(galleryElement => {\n galleryElement.removeEventListener('click', this.onThumbnailsClick, false);\n });\n }\n\n}\n\nexport { PhotoSwipeLightbox as default };\n//# sourceMappingURL=photoswipe-lightbox.esm.js.map\n","var COMPLETE = 'complete',\n CANCELED = 'canceled';\n\nfunction raf(task){\n if('requestAnimationFrame' in window){\n return window.requestAnimationFrame(task);\n }\n\n setTimeout(task, 16);\n}\n\nfunction setElementScroll(element, x, y){\n Math.max(0, x);\n Math.max(0, y);\n\n if(element.self === element){\n element.scrollTo(x, y);\n }else{\n element.scrollLeft = x;\n element.scrollTop = y;\n }\n}\n\nfunction getTargetScrollLocation(scrollSettings, parent){\n var align = scrollSettings.align,\n target = scrollSettings.target,\n targetPosition = target.getBoundingClientRect(),\n parentPosition,\n x,\n y,\n differenceX,\n differenceY,\n targetWidth,\n targetHeight,\n leftAlign = align && align.left != null ? align.left : 0.5,\n topAlign = align && align.top != null ? align.top : 0.5,\n leftOffset = align && align.leftOffset != null ? align.leftOffset : 0,\n topOffset = align && align.topOffset != null ? align.topOffset : 0,\n leftScalar = leftAlign,\n topScalar = topAlign;\n\n if(scrollSettings.isWindow(parent)){\n targetWidth = Math.min(targetPosition.width, parent.innerWidth);\n targetHeight = Math.min(targetPosition.height, parent.innerHeight);\n x = targetPosition.left + parent.pageXOffset - parent.innerWidth * leftScalar + targetWidth * leftScalar;\n y = targetPosition.top + parent.pageYOffset - parent.innerHeight * topScalar + targetHeight * topScalar;\n x -= leftOffset;\n y -= topOffset;\n x = scrollSettings.align.lockX ? parent.pageXOffset : x;\n y = scrollSettings.align.lockY ? parent.pageYOffset : y;\n differenceX = x - parent.pageXOffset;\n differenceY = y - parent.pageYOffset;\n }else{\n targetWidth = targetPosition.width;\n targetHeight = targetPosition.height;\n parentPosition = parent.getBoundingClientRect();\n var offsetLeft = targetPosition.left - (parentPosition.left - parent.scrollLeft);\n var offsetTop = targetPosition.top - (parentPosition.top - parent.scrollTop);\n x = offsetLeft + (targetWidth * leftScalar) - parent.clientWidth * leftScalar;\n y = offsetTop + (targetHeight * topScalar) - parent.clientHeight * topScalar;\n x -= leftOffset;\n y -= topOffset;\n x = Math.max(Math.min(x, parent.scrollWidth - parent.clientWidth), 0);\n y = Math.max(Math.min(y, parent.scrollHeight - parent.clientHeight), 0);\n x = scrollSettings.align.lockX ? parent.scrollLeft : x;\n y = scrollSettings.align.lockY ? parent.scrollTop : y;\n differenceX = x - parent.scrollLeft;\n differenceY = y - parent.scrollTop;\n }\n\n return {\n x: x,\n y: y,\n differenceX: differenceX,\n differenceY: differenceY\n };\n}\n\nfunction animate(parent){\n var scrollSettings = parent._scrollSettings;\n\n if(!scrollSettings){\n return;\n }\n\n var maxSynchronousAlignments = scrollSettings.maxSynchronousAlignments;\n\n var location = getTargetScrollLocation(scrollSettings, parent),\n time = Date.now() - scrollSettings.startTime,\n timeValue = Math.min(1 / scrollSettings.time * time, 1);\n\n if(scrollSettings.endIterations >= maxSynchronousAlignments){\n setElementScroll(parent, location.x, location.y);\n parent._scrollSettings = null;\n return scrollSettings.end(COMPLETE);\n }\n\n var easeValue = 1 - scrollSettings.ease(timeValue);\n\n setElementScroll(parent,\n location.x - location.differenceX * easeValue,\n location.y - location.differenceY * easeValue\n );\n\n if(time >= scrollSettings.time){\n scrollSettings.endIterations++;\n // Align ancestor synchronously\n scrollSettings.scrollAncestor && animate(scrollSettings.scrollAncestor);\n animate(parent);\n return;\n }\n\n raf(animate.bind(null, parent));\n}\n\nfunction defaultIsWindow(target){\n return target.self === target\n}\n\nfunction transitionScrollTo(target, parent, settings, scrollAncestor, callback){\n var idle = !parent._scrollSettings,\n lastSettings = parent._scrollSettings,\n now = Date.now(),\n cancelHandler,\n passiveOptions = { passive: true };\n\n if(lastSettings){\n lastSettings.end(CANCELED);\n }\n\n function end(endType){\n parent._scrollSettings = null;\n\n if(parent.parentElement && parent.parentElement._scrollSettings){\n parent.parentElement._scrollSettings.end(endType);\n }\n\n if(settings.debug){\n console.log('Scrolling ended with type', endType, 'for', parent)\n }\n\n callback(endType);\n if(cancelHandler){\n parent.removeEventListener('touchstart', cancelHandler, passiveOptions);\n parent.removeEventListener('wheel', cancelHandler, passiveOptions);\n }\n }\n\n var maxSynchronousAlignments = settings.maxSynchronousAlignments;\n\n if(maxSynchronousAlignments == null){\n maxSynchronousAlignments = 3;\n }\n\n parent._scrollSettings = {\n startTime: now,\n endIterations: 0,\n target: target,\n time: settings.time,\n ease: settings.ease,\n align: settings.align,\n isWindow: settings.isWindow || defaultIsWindow,\n maxSynchronousAlignments: maxSynchronousAlignments,\n end: end,\n scrollAncestor\n };\n\n if(!('cancellable' in settings) || settings.cancellable){\n cancelHandler = end.bind(null, CANCELED);\n parent.addEventListener('touchstart', cancelHandler, passiveOptions);\n parent.addEventListener('wheel', cancelHandler, passiveOptions);\n }\n\n if(idle){\n animate(parent);\n }\n\n return cancelHandler\n}\n\nfunction defaultIsScrollable(element){\n return (\n 'pageXOffset' in element ||\n (\n element.scrollHeight !== element.clientHeight ||\n element.scrollWidth !== element.clientWidth\n ) &&\n getComputedStyle(element).overflow !== 'hidden'\n );\n}\n\nfunction defaultValidTarget(){\n return true;\n}\n\nfunction findParentElement(el){\n if (el.assignedSlot) {\n return findParentElement(el.assignedSlot);\n }\n\n if (el.parentElement) {\n if(el.parentElement.tagName.toLowerCase() === 'body'){\n return el.parentElement.ownerDocument.defaultView || el.parentElement.ownerDocument.ownerWindow;\n }\n return el.parentElement;\n }\n\n if (el.getRootNode){\n var parent = el.getRootNode()\n if(parent.nodeType === 11) {\n return parent.host;\n }\n }\n}\n\nmodule.exports = function(target, settings, callback){\n if(!target){\n return;\n }\n\n if(typeof settings === 'function'){\n callback = settings;\n settings = null;\n }\n\n if(!settings){\n settings = {};\n }\n\n settings.time = isNaN(settings.time) ? 1000 : settings.time;\n settings.ease = settings.ease || function(v){return 1 - Math.pow(1 - v, v / 2);};\n settings.align = settings.align || {};\n\n var parent = findParentElement(target),\n parents = 1;\n\n function done(endType){\n parents--;\n if(!parents){\n callback && callback(endType);\n }\n }\n\n var validTarget = settings.validTarget || defaultValidTarget;\n var isScrollable = settings.isScrollable;\n\n if(settings.debug){\n console.log('About to scroll to', target)\n\n if(!parent){\n console.error('Target did not have a parent, is it mounted in the DOM?')\n }\n }\n\n var scrollingElements = [];\n\n while(parent){\n if(settings.debug){\n console.log('Scrolling parent node', parent)\n }\n\n if(validTarget(parent, parents) && (isScrollable ? isScrollable(parent, defaultIsScrollable) : defaultIsScrollable(parent))){\n parents++;\n scrollingElements.push(parent);\n }\n\n parent = findParentElement(parent);\n\n if(!parent){\n done(COMPLETE)\n break;\n }\n }\n\n return scrollingElements.reduce((cancel, parent, index) => transitionScrollTo(target, parent, settings, scrollingElements[index + 1], done), null);\n};\n","/**\n * Based on Justified Gallery - v3.8.1\n * http://miromannino.github.io/Justified-Gallery/\n *\n * Copyright (c) 2019 Miro Mannino\n * Licensed under the MIT license.\n */\n\nexport interface Options {\n // required? required to be > 0?\n rowHeight?: number;\n\n // false or negative value to deactivate. Positive number to express the value in pixels,\n // A string '[0-9]+%' to express in percentage (e.g. 300% means that the row height\n // can't exceed 3 * rowHeight)\n maxRowHeight?: string | number | false;\n\n // maximum number of rows to be displayed (0 = disabled)\n maxRowsCount?: number;\n\n // … which is the same as 'left', or can be 'justify', 'center', 'right' or 'hide'\n lastRow?: 'justify' | 'nojustify' | 'left' | 'center' | 'right' | 'hide';\n\n margins?: number;\n\n // negative value = same as margins, 0 = disabled, any other value to set the border\n border?: number;\n\n waitThumbnailsLoad?: boolean;\n\n // randomize order of photos\n randomize?: boolean;\n\n // The selector that is used to know what are the entries of the gallery\n selector?: string;\n\n // The selector that is used to know what are the images of each entry\n imgSelector?: string;\n\n // regexp to capture the extension of an image\n extension?: RegExp;\n\n // time interval (in ms) to check if the page changes its width\n refreshTime?: number;\n\n // change in width allowed (in px) without re-building the gallery\n refreshSensitivity?: number;\n\n // rewrite the rel of each analyzed links\n rel?: string;\n\n // rewrite the target of all links\n target?: string;\n\n // if row width / available space > 0.90 it will be always justified\n // (i.e. lastRow setting is not considered)\n // justifyThreshold must be in the interval [0,1]\n justifyThreshold?: number;\n\n // This is called to trigger events, the default behavior is to call $.trigger\n // Consider that 'this' is this set to the JustifiedGallery object, so it can\n // access to fields such as $gallery, useful to trigger events with jQuery.\n // Events\n // - jg.complete : called when all the gallery has been created\n // - jg.resize : called when the gallery has been resized\n // - jg.rowflush : when a new row appears\n triggerEvent?: (event: 'jg.complete' | 'jg.resize' | 'jg.rowflush' | 'jg.destroy') => void;\n}\n\nexport default class JustifiedGallery {\n private settings: Required;\n private imgAnalyzerTimeout?: NodeJS.Timeout;\n private entries: HTMLElement[] = [];\n private buildingRow = {\n entriesBuff: [] as HTMLElement[],\n width: 0,\n height: 0,\n aspectRatio: 0,\n };\n private lastFetchedEntry = 0;\n private lastAnalyzedIndex = -1;\n private yield = {\n every: 2, // do a flush every n flushes (must be greater than 1)\n flushed: 0, // flushed rows without a yield\n };\n private border: number;\n private maxRowHeight: number | false | undefined;\n private offY: number;\n private rows = 0;\n private checkWidthIntervalId?: NodeJS.Timeout;\n private galleryWidth: number;\n private gallery: HTMLElement;\n private galleryHeightToSet?: number;\n\n private entryWidths = new WeakMap();\n private entryHeights = new WeakMap();\n private entryJWidths = new WeakMap();\n private entryJHeights = new WeakMap();\n private entryLoaded = new WeakMap();\n\n private defaults: Options = {\n rowHeight: 120,\n maxRowHeight: false,\n maxRowsCount: 0,\n margins: 1,\n border: -1,\n lastRow: 'nojustify',\n justifyThreshold: 0.9,\n waitThumbnailsLoad: false,\n rel: undefined,\n target: undefined,\n extension: /\\.[^./\\\\]+$/,\n refreshTime: 200,\n refreshSensitivity: 0,\n randomize: false,\n selector: 'div.photo',\n imgSelector: ':scope > img, :scope > a > img, :scope > svg, :scope > a > svg',\n triggerEvent: function (this: JustifiedGallery, event) {\n this.gallery.dispatchEvent(new Event(event));\n },\n };\n\n /**\n * Justified Gallery controller constructor\n *\n * @param gallery the gallery to build\n * @param settings the settings (the defaults are in JustifiedGallery.defaults)\n * @constructor\n */\n constructor(gallery: HTMLElement, settings: Options) {\n this.settings = { ...this.defaults, ...settings } as Required;\n\n this.gallery = gallery;\n this.gallery.classList.add('justified-gallery');\n\n this.border = this.settings.border >= 0 ? this.settings.border : this.settings.margins;\n this.offY = this.border;\n this.maxRowHeight = this.retrieveMaxRowHeight();\n this.galleryWidth = this.gallery.getBoundingClientRect().width;\n }\n\n private get galleryHeight(): number {\n return this.gallery.getBoundingClientRect().height;\n }\n\n private set galleryHeight(height: number) {\n this.gallery.style.height = `${height}px`;\n }\n\n /** @returns the image in the given entry */\n private imgFromEntry(entry: HTMLElement): HTMLImageElement | null {\n return entry.querySelector(this.settings.imgSelector);\n }\n\n /**\n * Display the entry\n *\n * @param $entry the entry to display\n * @param x the x position where the entry must be positioned\n * @param y the y position where the entry must be positioned\n * @param rowHeight the row height of the row that owns the entry\n */\n private displayEntry(entry: HTMLElement, x: number, y: number, rowHeight: number) {\n const imgWidth = this.entryJWidths.get(entry) ?? 0;\n const imgHeight = this.entryJHeights.get(entry) ?? 0;\n\n entry.style.width = `${imgWidth}px`;\n entry.style.height = `${rowHeight}px`;\n entry.style.top = `${y}px`;\n entry.style.left = `${x}px`;\n\n const image = this.imgFromEntry(entry);\n if (image) {\n image.style.width = `${imgWidth}px`;\n image.style.height = `${imgHeight}px`;\n image.style.marginLeft = `${-imgWidth / 2}px`;\n image.style.marginTop = `${-imgHeight / 2}px`;\n }\n\n entry.classList.add('jg-entry-visible');\n }\n\n /**\n * Clear the building row data to be used for a new row\n */\n private clearBuildingRow() {\n this.buildingRow.entriesBuff = [];\n this.buildingRow.aspectRatio = 0;\n this.buildingRow.width = 0;\n }\n\n /**\n * Justify the building row, preparing it to\n *\n * @param isLastRow\n * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.\n * @returns a boolean to know if the row has been justified or not\n */\n private prepareBuildingRow(isLastRow: boolean, hiddenRow: boolean) {\n let newImgW;\n let newImgH;\n let justify = true;\n let minHeight = 0;\n let availableWidth =\n this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * this.settings.margins;\n const rowHeight = availableWidth / this.buildingRow.aspectRatio;\n let defaultRowHeight = this.settings.rowHeight;\n const justifiable = this.buildingRow.width / availableWidth > this.settings.justifyThreshold;\n\n // Skip the last row if we can't justify it and the lastRow == 'hide'\n if (hiddenRow || (isLastRow && this.settings.lastRow === 'hide' && !justifiable)) {\n for (const entry of this.buildingRow.entriesBuff) {\n entry.classList.remove('jg-entry-visible');\n }\n return -1;\n }\n\n // With lastRow = nojustify, justify if is justifiable (the images will not become too big)\n if (isLastRow && !justifiable && this.settings.lastRow !== 'justify' && this.settings.lastRow !== 'hide') {\n justify = false;\n\n if (this.rows > 0) {\n defaultRowHeight = (this.offY - this.border - this.settings.margins * this.rows) / this.rows;\n justify = (defaultRowHeight * this.buildingRow.aspectRatio) / availableWidth > this.settings.justifyThreshold;\n }\n }\n\n for (let index = 0; index < this.buildingRow.entriesBuff.length; index++) {\n const entry = this.buildingRow.entriesBuff[index];\n const imgAspectRatio = (this.entryWidths.get(entry) ?? 1) / (this.entryHeights.get(entry) ?? 1);\n\n if (justify) {\n newImgW = index === this.buildingRow.entriesBuff.length - 1 ? availableWidth : rowHeight * imgAspectRatio;\n newImgH = rowHeight;\n } else {\n newImgW = defaultRowHeight * imgAspectRatio;\n newImgH = defaultRowHeight;\n }\n\n availableWidth -= Math.round(newImgW);\n this.entryJWidths.set(entry, Math.round(newImgW));\n this.entryJHeights.set(entry, Math.ceil(newImgH));\n if (index === 0 || minHeight > newImgH) minHeight = newImgH;\n }\n\n this.buildingRow.height = minHeight;\n return justify;\n }\n\n /**\n * Flush a row: justify it, modify the gallery height accordingly to the row height\n *\n * @param isLastRow\n * @param hiddenRow undefined or false for normal behavior. hiddenRow = true to hide the row.\n */\n private flushRow(isLastRow: boolean, hiddenRow: boolean) {\n const settings = this.settings;\n let offX = this.border;\n\n const buildingRowResult = this.prepareBuildingRow(isLastRow, hiddenRow);\n if (hiddenRow || (isLastRow && settings.lastRow === 'hide' && buildingRowResult === -1)) {\n this.clearBuildingRow();\n return;\n }\n\n if (this.maxRowHeight && this.maxRowHeight < this.buildingRow.height) {\n this.buildingRow.height = this.maxRowHeight;\n }\n\n // Align last (unjustified) row\n if (isLastRow && (settings.lastRow === 'center' || settings.lastRow === 'right')) {\n let availableWidth =\n this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * settings.margins;\n\n for (const entry of this.buildingRow.entriesBuff) {\n availableWidth -= this.entryJWidths.get(entry) ?? 0;\n }\n\n if (settings.lastRow === 'center') offX += Math.round(availableWidth / 2);\n else if (settings.lastRow === 'right') offX += availableWidth;\n }\n\n for (const entry of this.buildingRow.entriesBuff) {\n this.displayEntry(entry, offX, this.offY, this.buildingRow.height);\n offX += (this.entryJWidths.get(entry) ?? 0) + settings.margins;\n }\n\n // Gallery Height\n this.galleryHeightToSet = this.offY + this.buildingRow.height + this.border;\n this.setGalleryTempHeight(this.galleryHeightToSet);\n\n if (!isLastRow || (this.buildingRow.height <= settings.rowHeight && buildingRowResult)) {\n // Ready for a new row\n this.offY += this.buildingRow.height + settings.margins;\n this.rows += 1;\n this.clearBuildingRow();\n this.settings.triggerEvent.call(this, 'jg.rowflush');\n }\n }\n\n // Scroll position not restoring: https://github.com/miromannino/Justified-Gallery/issues/221\n galleryPrevStaticHeight = 0;\n\n private rememberGalleryHeight() {\n this.galleryPrevStaticHeight = this.galleryHeight;\n this.galleryHeight = this.galleryPrevStaticHeight;\n }\n\n // grow only\n private setGalleryTempHeight(height: number) {\n this.galleryPrevStaticHeight = Math.max(height, this.galleryPrevStaticHeight);\n this.galleryHeight = this.galleryPrevStaticHeight;\n }\n\n private setGalleryFinalHeight(height: number) {\n this.galleryPrevStaticHeight = height;\n this.galleryHeight = height;\n }\n\n /**\n * Checks the width of the gallery container, to know if a new justification is needed\n */\n private checkWidth() {\n this.checkWidthIntervalId = setInterval(() => {\n // if the gallery is not currently visible, abort.\n if (!(this.gallery.offsetWidth || this.gallery.offsetHeight || this.gallery.getClientRects().length > 0)) return;\n\n const galleryWidth = this.gallery.getBoundingClientRect().width;\n if (Math.abs(galleryWidth - this.galleryWidth) > this.settings.refreshSensitivity) {\n this.galleryWidth = galleryWidth;\n this.rewind();\n\n this.rememberGalleryHeight();\n\n // Restart to analyze\n this.startImgAnalyzer(true);\n }\n }, this.settings.refreshTime);\n }\n\n /**\n * Rewind the image analysis to start from the first entry.\n */\n rewind() {\n this.lastFetchedEntry = 0;\n this.lastAnalyzedIndex = -1;\n this.offY = this.border;\n this.rows = 0;\n this.clearBuildingRow();\n }\n\n /**\n * @returns {Array} all entries matched by `settings.selector`\n */\n private getAllEntries() {\n return [...this.gallery.querySelectorAll(this.settings.selector)];\n }\n\n /**\n * Update the entries searching it from the justified gallery HTML element\n *\n * @param norewind if norewind only the new entries will be changed (i.e. randomized)\n * @returns {boolean} true if some entries has been founded\n */\n updateEntries(norewind: boolean) {\n const allEntries = this.getAllEntries();\n let newEntries: HTMLElement[];\n\n if (norewind && this.lastFetchedEntry > 0) {\n newEntries = allEntries.slice(this.lastFetchedEntry);\n } else {\n this.entries = [];\n newEntries = allEntries;\n }\n\n if (newEntries.length > 0) {\n // If randomize\n if (this.settings.randomize) {\n newEntries = this.shuffleArray(newEntries);\n }\n\n this.entries = [...this.entries, ...newEntries];\n\n this.lastFetchedEntry = this.entries.length;\n\n return true;\n }\n\n return false;\n }\n\n /**\n * Apply the entries order to the DOM, iterating the entries and appending the images\n *\n * @param entries the entries that has been modified and that must be re-ordered in the DOM\n */\n private insertToGallery(entries: HTMLElement[]) {\n for (const entry of entries) {\n this.gallery.append(entry);\n }\n }\n\n /**\n * Shuffle the array using the Fisher-Yates shuffle algorithm\n *\n * @param array the array to shuffle\n * @return the shuffled array\n */\n private shuffleArray(array: HTMLElement[]): HTMLElement[] {\n for (let index = array.length - 1; index > 0; index--) {\n const random = Math.floor(Math.random() * (index + 1));\n const temporary = array[index];\n array[index] = array[random];\n array[random] = temporary;\n }\n this.insertToGallery(array);\n return array;\n }\n\n /**\n * Destroy the Justified Gallery instance.\n *\n * It clears all the css properties added in the style attributes. We doesn't backup the original\n * values for those css attributes, because it costs (performance) and because in general one\n * shouldn't use the style attribute for an uniform set of images (where we suppose the use of\n * classes). Creating a backup is also difficult because JG could be called multiple times and\n * with different style attributes.\n */\n destroy() {\n clearInterval(this.checkWidthIntervalId);\n this.stopImgAnalyzerStarter();\n\n // Get fresh entries list since filtered entries are absent in `this.entries`\n for (const entry of this.getAllEntries()) {\n // Reset entry style\n entry.style.width = '';\n entry.style.height = '';\n entry.style.top = '';\n entry.style.left = '';\n entry.classList.remove('jg-entry', 'jg-entry-visible');\n\n // Reset image style\n const image = this.imgFromEntry(entry);\n if (image) {\n image.style.width = '';\n image.style.height = '';\n image.style.marginLeft = '';\n image.style.marginTop = '';\n }\n }\n\n this.gallery.style.height = '';\n this.gallery.classList.remove('justified-gallery');\n this.settings.triggerEvent.call(this, 'jg.destroy');\n }\n\n /**\n * Analyze the images and builds the rows. It returns if it found an image that is not loaded.\n *\n * @param isForResize if the image analyzer is called for resizing or not, to call a different callback at the end\n */\n private analyzeImages(isForResize: boolean) {\n for (let index = this.lastAnalyzedIndex + 1; index < this.entries.length; index++) {\n const entry = this.entries[index];\n if (this.entryLoaded.get(entry) === 'true' || this.entryLoaded.get(entry) === 'skipped') {\n const availableWidth =\n this.galleryWidth - 2 * this.border - (this.buildingRow.entriesBuff.length - 1) * this.settings.margins;\n const imgAspectRatio = (this.entryWidths.get(entry) ?? 1) / (this.entryHeights.get(entry) ?? 1);\n\n this.buildingRow.entriesBuff.push(entry);\n this.buildingRow.aspectRatio += imgAspectRatio;\n this.buildingRow.width += imgAspectRatio * this.settings.rowHeight;\n this.lastAnalyzedIndex = index;\n\n if (availableWidth / (this.buildingRow.aspectRatio + imgAspectRatio) < this.settings.rowHeight) {\n this.flushRow(false, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);\n\n if (++this.yield.flushed >= this.yield.every) {\n this.startImgAnalyzer(isForResize);\n return;\n }\n }\n } else if (this.entryLoaded.get(entry) !== 'error') {\n return;\n }\n }\n\n // Last row flush (the row is not full)\n if (this.buildingRow.entriesBuff.length > 0) {\n this.flushRow(true, this.settings.maxRowsCount > 0 && this.rows === this.settings.maxRowsCount);\n }\n\n /* Stop, if there is, the timeout to start the analyzeImages.\n This is because an image can be set loaded, and the timeout can be set,\n but this image can be analyzed yet.\n */\n this.stopImgAnalyzerStarter();\n\n this.setGalleryFinalHeight(this.galleryHeightToSet ?? 0);\n\n // On complete callback\n this.settings.triggerEvent.call(this, isForResize ? 'jg.resize' : 'jg.complete');\n }\n\n /**\n * Stops any ImgAnalyzer starter (that has an assigned timeout)\n */\n private stopImgAnalyzerStarter() {\n this.yield.flushed = 0;\n if (this.imgAnalyzerTimeout !== undefined) {\n clearTimeout(this.imgAnalyzerTimeout);\n this.imgAnalyzerTimeout = undefined;\n }\n }\n\n /**\n * Starts the image analyzer. It is not immediately called to let the browser to update the view\n *\n * @param isForResize specifies if the image analyzer must be called for resizing or not\n */\n private startImgAnalyzer(isForResize: boolean) {\n this.stopImgAnalyzerStarter();\n this.imgAnalyzerTimeout = setTimeout(() => {\n this.analyzeImages(isForResize);\n }, 0.001); // we can't start it immediately due to a IE different behavior\n }\n\n /**\n * Checks if the image is loaded or not using another image object. We cannot use the 'complete' image property,\n * because some browsers, with a 404 set complete = true.\n *\n * @param image the image to load\n * @param onLoad callback that is called when the image has been loaded\n * @param onError callback that is called in case of an error\n */\n private onImageEvent(image: HTMLImageElement, onLoad: (image: HTMLImageElement) => void, onError?: () => void) {\n if (!onLoad && !onError) return;\n\n if (image.complete) {\n onLoad(image);\n return;\n }\n\n if (onLoad) {\n image.addEventListener(\n 'load',\n () => {\n onLoad(image);\n },\n { once: true },\n );\n }\n if (onError) {\n image.addEventListener(\n 'error',\n () => {\n onError();\n },\n { once: true },\n );\n }\n }\n\n /**\n * Init of Justified Gallery controlled\n * It analyzes all the entries starting theirs loading and calling the image analyzer (that works with loaded images)\n */\n init() {\n let imagesToLoad = false;\n let skippedImages = false;\n\n for (const entry of this.entries) {\n const image = this.imgFromEntry(entry);\n\n entry.classList.add('jg-entry');\n\n if (this.entryLoaded.get(entry) !== 'true' && this.entryLoaded.get(entry) !== 'skipped') {\n // Link Rel global overwrite\n if (this.settings.rel) entry.setAttribute('rel', this.settings.rel);\n\n // Link Target global overwrite\n if (this.settings.target) entry.setAttribute('target', this.settings.target);\n\n if (image) {\n /* If we have the height and the width, we don't wait that the image is loaded,\n but we start directly with the justification */\n if (this.settings.waitThumbnailsLoad === false) {\n const width = Number.parseFloat(image.getAttribute('width') ?? '0');\n const height = Number.parseFloat(image.getAttribute('height') ?? '0');\n\n if (!Number.isNaN(width) && !Number.isNaN(height)) {\n this.entryWidths.set(entry, width);\n this.entryHeights.set(entry, height);\n this.entryLoaded.set(entry, 'skipped');\n skippedImages = true;\n this.startImgAnalyzer(false);\n continue; // continue\n }\n }\n\n this.entryLoaded.set(entry, 'false');\n imagesToLoad = true;\n\n this.onImageEvent(\n image,\n (loadImg) => {\n // image loaded\n this.entryWidths.set(entry, loadImg.width);\n this.entryHeights.set(entry, loadImg.height);\n this.entryLoaded.set(entry, 'true');\n this.startImgAnalyzer(false);\n },\n () => {\n // image load error\n this.entryLoaded.set(entry, 'error');\n this.startImgAnalyzer(false);\n },\n );\n } else {\n this.entryWidths.set(entry, entry.getBoundingClientRect().width ?? 1);\n this.entryHeights.set(entry, entry.getBoundingClientRect().height ?? 1);\n this.entryLoaded.set(entry, 'true');\n }\n }\n }\n\n if (!imagesToLoad && !skippedImages) this.startImgAnalyzer(false);\n this.checkWidth();\n }\n\n /**\n * check and convert the maxRowHeight setting\n * requires rowHeight to be already set\n * TODO: should be always called when only rowHeight is changed\n * @return number or null\n */\n private retrieveMaxRowHeight(): number | undefined {\n let newMaxRowHeight;\n const rowHeight = this.settings.rowHeight;\n\n if (typeof this.settings.maxRowHeight === 'string') {\n newMaxRowHeight = /^\\d+%$/.test(this.settings.maxRowHeight)\n ? (rowHeight * Number.parseFloat(/^(\\d+)%$/.exec(this.settings.maxRowHeight)![1])) / 100\n : Number.parseFloat(this.settings.maxRowHeight);\n } else if (typeof this.settings.maxRowHeight === 'number') {\n newMaxRowHeight = this.settings.maxRowHeight;\n } else if (this.settings.maxRowHeight === false || this.settings.maxRowHeight === undefined) {\n return undefined;\n } else {\n throw new Error('maxRowHeight must be a number or a percentage');\n }\n\n // check if the converted value is not a number\n if (Number.isNaN(newMaxRowHeight)) throw new Error('invalid number for maxRowHeight');\n\n // check values, maxRowHeight must be >= rowHeight\n if (newMaxRowHeight < rowHeight) newMaxRowHeight = rowHeight;\n\n return newMaxRowHeight;\n }\n}\n","/*!\nWaypoints - 4.0.1\nCopyright © 2011-2016 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blob/master/licenses.txt\n*/\n(function() {\n 'use strict'\n\n var keyCounter = 0\n var allWaypoints = {}\n\n /* http://imakewebthings.com/waypoints/api/waypoint */\n function Waypoint(options) {\n if (!options) {\n throw new Error('No options passed to Waypoint constructor')\n }\n if (!options.element) {\n throw new Error('No element option passed to Waypoint constructor')\n }\n if (!options.handler) {\n throw new Error('No handler option passed to Waypoint constructor')\n }\n\n this.key = 'waypoint-' + keyCounter\n this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)\n this.element = this.options.element\n this.adapter = new Waypoint.Adapter(this.element)\n this.callback = options.handler\n this.axis = this.options.horizontal ? 'horizontal' : 'vertical'\n this.enabled = this.options.enabled\n this.triggerPoint = null\n this.group = Waypoint.Group.findOrCreate({\n name: this.options.group,\n axis: this.axis\n })\n this.context = Waypoint.Context.findOrCreateByElement(this.options.context)\n\n if (Waypoint.offsetAliases[this.options.offset]) {\n this.options.offset = Waypoint.offsetAliases[this.options.offset]\n }\n this.group.add(this)\n this.context.add(this)\n allWaypoints[this.key] = this\n keyCounter += 1\n }\n\n /* Private */\n Waypoint.prototype.queueTrigger = function(direction) {\n this.group.queueTrigger(this, direction)\n }\n\n /* Private */\n Waypoint.prototype.trigger = function(args) {\n if (!this.enabled) {\n return\n }\n if (this.callback) {\n this.callback.apply(this, args)\n }\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/destroy */\n Waypoint.prototype.destroy = function() {\n this.context.remove(this)\n this.group.remove(this)\n delete allWaypoints[this.key]\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/disable */\n Waypoint.prototype.disable = function() {\n this.enabled = false\n return this\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/enable */\n Waypoint.prototype.enable = function() {\n this.context.refresh()\n this.enabled = true\n return this\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/next */\n Waypoint.prototype.next = function() {\n return this.group.next(this)\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/previous */\n Waypoint.prototype.previous = function() {\n return this.group.previous(this)\n }\n\n /* Private */\n Waypoint.invokeAll = function(method) {\n var allWaypointsArray = []\n for (var waypointKey in allWaypoints) {\n allWaypointsArray.push(allWaypoints[waypointKey])\n }\n for (var i = 0, end = allWaypointsArray.length; i < end; i++) {\n allWaypointsArray[i][method]()\n }\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/destroy-all */\n Waypoint.destroyAll = function() {\n Waypoint.invokeAll('destroy')\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/disable-all */\n Waypoint.disableAll = function() {\n Waypoint.invokeAll('disable')\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/enable-all */\n Waypoint.enableAll = function() {\n Waypoint.Context.refreshAll()\n for (var waypointKey in allWaypoints) {\n allWaypoints[waypointKey].enabled = true\n }\n return this\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/refresh-all */\n Waypoint.refreshAll = function() {\n Waypoint.Context.refreshAll()\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/viewport-height */\n Waypoint.viewportHeight = function() {\n return window.innerHeight || document.documentElement.clientHeight\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/viewport-width */\n Waypoint.viewportWidth = function() {\n return document.documentElement.clientWidth\n }\n\n Waypoint.adapters = []\n\n Waypoint.defaults = {\n context: window,\n continuous: true,\n enabled: true,\n group: 'default',\n horizontal: false,\n offset: 0\n }\n\n Waypoint.offsetAliases = {\n 'bottom-in-view': function() {\n return this.context.innerHeight() - this.adapter.outerHeight()\n },\n 'right-in-view': function() {\n return this.context.innerWidth() - this.adapter.outerWidth()\n }\n }\n\n window.Waypoint = Waypoint\n}())\n;(function() {\n 'use strict'\n\n function requestAnimationFrameShim(callback) {\n window.setTimeout(callback, 1000 / 60)\n }\n\n var keyCounter = 0\n var contexts = {}\n var Waypoint = window.Waypoint\n var oldWindowLoad = window.onload\n\n /* http://imakewebthings.com/waypoints/api/context */\n function Context(element) {\n this.element = element\n this.Adapter = Waypoint.Adapter\n this.adapter = new this.Adapter(element)\n this.key = 'waypoint-context-' + keyCounter\n this.didScroll = false\n this.didResize = false\n this.oldScroll = {\n x: this.adapter.scrollLeft(),\n y: this.adapter.scrollTop()\n }\n this.waypoints = {\n vertical: {},\n horizontal: {}\n }\n\n element.waypointContextKey = this.key\n contexts[element.waypointContextKey] = this\n keyCounter += 1\n if (!Waypoint.windowContext) {\n Waypoint.windowContext = true\n Waypoint.windowContext = new Context(window)\n }\n\n this.createThrottledScrollHandler()\n this.createThrottledResizeHandler()\n }\n\n /* Private */\n Context.prototype.add = function(waypoint) {\n var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'\n this.waypoints[axis][waypoint.key] = waypoint\n this.refresh()\n }\n\n /* Private */\n Context.prototype.checkEmpty = function() {\n var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)\n var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)\n var isWindow = this.element == this.element.window\n if (horizontalEmpty && verticalEmpty && !isWindow) {\n this.adapter.off('.waypoints')\n delete contexts[this.key]\n }\n }\n\n /* Private */\n Context.prototype.createThrottledResizeHandler = function() {\n var self = this\n\n function resizeHandler() {\n self.handleResize()\n self.didResize = false\n }\n\n this.adapter.on('resize.waypoints', function() {\n if (!self.didResize) {\n self.didResize = true\n Waypoint.requestAnimationFrame(resizeHandler)\n }\n })\n }\n\n /* Private */\n Context.prototype.createThrottledScrollHandler = function() {\n var self = this\n function scrollHandler() {\n self.handleScroll()\n self.didScroll = false\n }\n\n this.adapter.on('scroll.waypoints', function() {\n if (!self.didScroll || Waypoint.isTouch) {\n self.didScroll = true\n Waypoint.requestAnimationFrame(scrollHandler)\n }\n })\n }\n\n /* Private */\n Context.prototype.handleResize = function() {\n Waypoint.Context.refreshAll()\n }\n\n /* Private */\n Context.prototype.handleScroll = function() {\n var triggeredGroups = {}\n var axes = {\n horizontal: {\n newScroll: this.adapter.scrollLeft(),\n oldScroll: this.oldScroll.x,\n forward: 'right',\n backward: 'left'\n },\n vertical: {\n newScroll: this.adapter.scrollTop(),\n oldScroll: this.oldScroll.y,\n forward: 'down',\n backward: 'up'\n }\n }\n\n for (var axisKey in axes) {\n var axis = axes[axisKey]\n var isForward = axis.newScroll > axis.oldScroll\n var direction = isForward ? axis.forward : axis.backward\n\n for (var waypointKey in this.waypoints[axisKey]) {\n var waypoint = this.waypoints[axisKey][waypointKey]\n if (waypoint.triggerPoint === null) {\n continue\n }\n var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint\n var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint\n var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint\n var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint\n if (crossedForward || crossedBackward) {\n waypoint.queueTrigger(direction)\n triggeredGroups[waypoint.group.id] = waypoint.group\n }\n }\n }\n\n for (var groupKey in triggeredGroups) {\n triggeredGroups[groupKey].flushTriggers()\n }\n\n this.oldScroll = {\n x: axes.horizontal.newScroll,\n y: axes.vertical.newScroll\n }\n }\n\n /* Private */\n Context.prototype.innerHeight = function() {\n /*eslint-disable eqeqeq */\n if (this.element == this.element.window) {\n return Waypoint.viewportHeight()\n }\n /*eslint-enable eqeqeq */\n return this.adapter.innerHeight()\n }\n\n /* Private */\n Context.prototype.remove = function(waypoint) {\n delete this.waypoints[waypoint.axis][waypoint.key]\n this.checkEmpty()\n }\n\n /* Private */\n Context.prototype.innerWidth = function() {\n /*eslint-disable eqeqeq */\n if (this.element == this.element.window) {\n return Waypoint.viewportWidth()\n }\n /*eslint-enable eqeqeq */\n return this.adapter.innerWidth()\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/context-destroy */\n Context.prototype.destroy = function() {\n var allWaypoints = []\n for (var axis in this.waypoints) {\n for (var waypointKey in this.waypoints[axis]) {\n allWaypoints.push(this.waypoints[axis][waypointKey])\n }\n }\n for (var i = 0, end = allWaypoints.length; i < end; i++) {\n allWaypoints[i].destroy()\n }\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/context-refresh */\n Context.prototype.refresh = function() {\n /*eslint-disable eqeqeq */\n var isWindow = this.element == this.element.window\n /*eslint-enable eqeqeq */\n var contextOffset = isWindow ? undefined : this.adapter.offset()\n var triggeredGroups = {}\n var axes\n\n this.handleScroll()\n axes = {\n horizontal: {\n contextOffset: isWindow ? 0 : contextOffset.left,\n contextScroll: isWindow ? 0 : this.oldScroll.x,\n contextDimension: this.innerWidth(),\n oldScroll: this.oldScroll.x,\n forward: 'right',\n backward: 'left',\n offsetProp: 'left'\n },\n vertical: {\n contextOffset: isWindow ? 0 : contextOffset.top,\n contextScroll: isWindow ? 0 : this.oldScroll.y,\n contextDimension: this.innerHeight(),\n oldScroll: this.oldScroll.y,\n forward: 'down',\n backward: 'up',\n offsetProp: 'top'\n }\n }\n\n for (var axisKey in axes) {\n var axis = axes[axisKey]\n for (var waypointKey in this.waypoints[axisKey]) {\n var waypoint = this.waypoints[axisKey][waypointKey]\n var adjustment = waypoint.options.offset\n var oldTriggerPoint = waypoint.triggerPoint\n var elementOffset = 0\n var freshWaypoint = oldTriggerPoint == null\n var contextModifier, wasBeforeScroll, nowAfterScroll\n var triggeredBackward, triggeredForward\n\n if (waypoint.element !== waypoint.element.window) {\n elementOffset = waypoint.adapter.offset()[axis.offsetProp]\n }\n\n if (typeof adjustment === 'function') {\n adjustment = adjustment.apply(waypoint)\n }\n else if (typeof adjustment === 'string') {\n adjustment = parseFloat(adjustment)\n if (waypoint.options.offset.indexOf('%') > - 1) {\n adjustment = Math.ceil(axis.contextDimension * adjustment / 100)\n }\n }\n\n contextModifier = axis.contextScroll - axis.contextOffset\n waypoint.triggerPoint = Math.floor(elementOffset + contextModifier - adjustment)\n wasBeforeScroll = oldTriggerPoint < axis.oldScroll\n nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll\n triggeredBackward = wasBeforeScroll && nowAfterScroll\n triggeredForward = !wasBeforeScroll && !nowAfterScroll\n\n if (!freshWaypoint && triggeredBackward) {\n waypoint.queueTrigger(axis.backward)\n triggeredGroups[waypoint.group.id] = waypoint.group\n }\n else if (!freshWaypoint && triggeredForward) {\n waypoint.queueTrigger(axis.forward)\n triggeredGroups[waypoint.group.id] = waypoint.group\n }\n else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {\n waypoint.queueTrigger(axis.forward)\n triggeredGroups[waypoint.group.id] = waypoint.group\n }\n }\n }\n\n Waypoint.requestAnimationFrame(function() {\n for (var groupKey in triggeredGroups) {\n triggeredGroups[groupKey].flushTriggers()\n }\n })\n\n return this\n }\n\n /* Private */\n Context.findOrCreateByElement = function(element) {\n return Context.findByElement(element) || new Context(element)\n }\n\n /* Private */\n Context.refreshAll = function() {\n for (var contextId in contexts) {\n contexts[contextId].refresh()\n }\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/context-find-by-element */\n Context.findByElement = function(element) {\n return contexts[element.waypointContextKey]\n }\n\n window.onload = function() {\n if (oldWindowLoad) {\n oldWindowLoad()\n }\n Context.refreshAll()\n }\n\n\n Waypoint.requestAnimationFrame = function(callback) {\n var requestFn = window.requestAnimationFrame ||\n window.mozRequestAnimationFrame ||\n window.webkitRequestAnimationFrame ||\n requestAnimationFrameShim\n requestFn.call(window, callback)\n }\n Waypoint.Context = Context\n}())\n;(function() {\n 'use strict'\n\n function byTriggerPoint(a, b) {\n return a.triggerPoint - b.triggerPoint\n }\n\n function byReverseTriggerPoint(a, b) {\n return b.triggerPoint - a.triggerPoint\n }\n\n var groups = {\n vertical: {},\n horizontal: {}\n }\n var Waypoint = window.Waypoint\n\n /* http://imakewebthings.com/waypoints/api/group */\n function Group(options) {\n this.name = options.name\n this.axis = options.axis\n this.id = this.name + '-' + this.axis\n this.waypoints = []\n this.clearTriggerQueues()\n groups[this.axis][this.name] = this\n }\n\n /* Private */\n Group.prototype.add = function(waypoint) {\n this.waypoints.push(waypoint)\n }\n\n /* Private */\n Group.prototype.clearTriggerQueues = function() {\n this.triggerQueues = {\n up: [],\n down: [],\n left: [],\n right: []\n }\n }\n\n /* Private */\n Group.prototype.flushTriggers = function() {\n for (var direction in this.triggerQueues) {\n var waypoints = this.triggerQueues[direction]\n var reverse = direction === 'up' || direction === 'left'\n waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)\n for (var i = 0, end = waypoints.length; i < end; i += 1) {\n var waypoint = waypoints[i]\n if (waypoint.options.continuous || i === waypoints.length - 1) {\n waypoint.trigger([direction])\n }\n }\n }\n this.clearTriggerQueues()\n }\n\n /* Private */\n Group.prototype.next = function(waypoint) {\n this.waypoints.sort(byTriggerPoint)\n var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n var isLast = index === this.waypoints.length - 1\n return isLast ? null : this.waypoints[index + 1]\n }\n\n /* Private */\n Group.prototype.previous = function(waypoint) {\n this.waypoints.sort(byTriggerPoint)\n var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n return index ? this.waypoints[index - 1] : null\n }\n\n /* Private */\n Group.prototype.queueTrigger = function(waypoint, direction) {\n this.triggerQueues[direction].push(waypoint)\n }\n\n /* Private */\n Group.prototype.remove = function(waypoint) {\n var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)\n if (index > -1) {\n this.waypoints.splice(index, 1)\n }\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/first */\n Group.prototype.first = function() {\n return this.waypoints[0]\n }\n\n /* Public */\n /* http://imakewebthings.com/waypoints/api/last */\n Group.prototype.last = function() {\n return this.waypoints[this.waypoints.length - 1]\n }\n\n /* Private */\n Group.findOrCreate = function(options) {\n return groups[options.axis][options.name] || new Group(options)\n }\n\n Waypoint.Group = Group\n}())\n;(function() {\n 'use strict'\n\n var Waypoint = window.Waypoint\n\n function isWindow(element) {\n return element === element.window\n }\n\n function getWindow(element) {\n if (isWindow(element)) {\n return element\n }\n return element.defaultView\n }\n\n function NoFrameworkAdapter(element) {\n this.element = element\n this.handlers = {}\n }\n\n NoFrameworkAdapter.prototype.innerHeight = function() {\n var isWin = isWindow(this.element)\n return isWin ? this.element.innerHeight : this.element.clientHeight\n }\n\n NoFrameworkAdapter.prototype.innerWidth = function() {\n var isWin = isWindow(this.element)\n return isWin ? this.element.innerWidth : this.element.clientWidth\n }\n\n NoFrameworkAdapter.prototype.off = function(event, handler) {\n function removeListeners(element, listeners, handler) {\n for (var i = 0, end = listeners.length - 1; i < end; i++) {\n var listener = listeners[i]\n if (!handler || handler === listener) {\n element.removeEventListener(listener)\n }\n }\n }\n\n var eventParts = event.split('.')\n var eventType = eventParts[0]\n var namespace = eventParts[1]\n var element = this.element\n\n if (namespace && this.handlers[namespace] && eventType) {\n removeListeners(element, this.handlers[namespace][eventType], handler)\n this.handlers[namespace][eventType] = []\n }\n else if (eventType) {\n for (var ns in this.handlers) {\n removeListeners(element, this.handlers[ns][eventType] || [], handler)\n this.handlers[ns][eventType] = []\n }\n }\n else if (namespace && this.handlers[namespace]) {\n for (var type in this.handlers[namespace]) {\n removeListeners(element, this.handlers[namespace][type], handler)\n }\n this.handlers[namespace] = {}\n }\n }\n\n /* Adapted from jQuery 1.x offset() */\n NoFrameworkAdapter.prototype.offset = function() {\n if (!this.element.ownerDocument) {\n return null\n }\n\n var documentElement = this.element.ownerDocument.documentElement\n var win = getWindow(this.element.ownerDocument)\n var rect = {\n top: 0,\n left: 0\n }\n\n if (this.element.getBoundingClientRect) {\n rect = this.element.getBoundingClientRect()\n }\n\n return {\n top: rect.top + win.pageYOffset - documentElement.clientTop,\n left: rect.left + win.pageXOffset - documentElement.clientLeft\n }\n }\n\n NoFrameworkAdapter.prototype.on = function(event, handler) {\n var eventParts = event.split('.')\n var eventType = eventParts[0]\n var namespace = eventParts[1] || '__default'\n var nsHandlers = this.handlers[namespace] = this.handlers[namespace] || {}\n var nsTypeList = nsHandlers[eventType] = nsHandlers[eventType] || []\n\n nsTypeList.push(handler)\n this.element.addEventListener(eventType, handler)\n }\n\n NoFrameworkAdapter.prototype.outerHeight = function(includeMargin) {\n var height = this.innerHeight()\n var computedStyle\n\n if (includeMargin && !isWindow(this.element)) {\n computedStyle = window.getComputedStyle(this.element)\n height += parseInt(computedStyle.marginTop, 10)\n height += parseInt(computedStyle.marginBottom, 10)\n }\n\n return height\n }\n\n NoFrameworkAdapter.prototype.outerWidth = function(includeMargin) {\n var width = this.innerWidth()\n var computedStyle\n\n if (includeMargin && !isWindow(this.element)) {\n computedStyle = window.getComputedStyle(this.element)\n width += parseInt(computedStyle.marginLeft, 10)\n width += parseInt(computedStyle.marginRight, 10)\n }\n\n return width\n }\n\n NoFrameworkAdapter.prototype.scrollLeft = function() {\n var win = getWindow(this.element)\n return win ? win.pageXOffset : this.element.scrollLeft\n }\n\n NoFrameworkAdapter.prototype.scrollTop = function() {\n var win = getWindow(this.element)\n return win ? win.pageYOffset : this.element.scrollTop\n }\n\n NoFrameworkAdapter.extend = function() {\n var args = Array.prototype.slice.call(arguments)\n\n function merge(target, obj) {\n if (typeof target === 'object' && typeof obj === 'object') {\n for (var key in obj) {\n if (obj.hasOwnProperty(key)) {\n target[key] = obj[key]\n }\n }\n }\n\n return target\n }\n\n for (var i = 1, end = args.length; i < end; i++) {\n merge(args[0], args[i])\n }\n return args[0]\n }\n\n NoFrameworkAdapter.inArray = function(element, array, i) {\n return array == null ? -1 : array.indexOf(element, i)\n }\n\n NoFrameworkAdapter.isEmptyObject = function(obj) {\n /* eslint no-unused-vars: 0 */\n for (var name in obj) {\n return false\n }\n return true\n }\n\n Waypoint.adapters.push({\n name: 'noframework',\n Adapter: NoFrameworkAdapter\n })\n Waypoint.Adapter = NoFrameworkAdapter\n}())\n;","/*\nWaypoints Infinite Scroll Shortcut - 4.0.0\nhttp://imakewebthings.com/waypoints/shortcuts/infinite-scroll\nCopyright © 2011-2015 Caleb Troughton\nLicensed under the MIT license.\nhttps://github.com/imakewebthings/waypoints/blob/master/licenses.txt\n*/\n\nimport 'waypoints/lib/noframework.waypoints';\n\ndeclare global {\n interface Window {\n Waypoint: new (options: WaypointOptions) => Waypoint;\n }\n}\n\ninterface BaseInfiniteOptions {\n container: 'auto' | HTMLElement;\n items: string;\n loadingClass: string;\n more: string;\n offset: string;\n onBeforePageLoad: () => void;\n onAfterPageLoad: (items: HTMLElement[]) => void;\n}\n\ninterface InfiniteOptions extends Partial {\n element: HTMLElement;\n}\n\ntype InfiniteWaypointOptions = BaseInfiniteOptions & WaypointOptions;\n\ntype WaypointHandler = (this: Waypoint, direction?: string) => void;\n\nfunction parseHTML(html: string): HTMLElement {\n const element = document.implementation.createHTMLDocument();\n element.body.innerHTML = html;\n return element.body;\n}\n\ntype PartialBy = Omit & Partial>;\n\nexport default class Infinite {\n private defaults: BaseInfiniteOptions = {\n container: 'auto',\n items: '.infinite-item',\n more: '.infinite-more-link',\n offset: 'bottom-in-view',\n loadingClass: 'infinite-loading',\n onBeforePageLoad() {\n return;\n },\n onAfterPageLoad() {\n return;\n },\n };\n\n private options: BaseInfiniteOptions & PartialBy;\n private container?: HTMLElement;\n private more?: HTMLElement | null;\n private waypoint?: Waypoint;\n private handler?: WaypointHandler;\n\n constructor(options: InfiniteOptions) {\n this.options = Object.assign({}, this.defaults, options);\n this.container = this.options.container === 'auto' ? this.options.element : this.options.container;\n this.more = document.querySelector(this.options.more);\n\n if (!this.container) return;\n if (this.options.container !== 'auto') this.container = this.options.container;\n\n if (this.more) {\n this.options.handler = this.handler = this.setupHandler();\n this.waypoint = new window.Waypoint(this.options as InfiniteWaypointOptions);\n }\n }\n\n triggerHandler(): void {\n if (this.handler && this.waypoint) this.handler.apply(this.waypoint);\n }\n\n /* Private */\n private setupHandler(): WaypointHandler {\n return () => {\n this.options.onBeforePageLoad();\n this.destroy();\n\n const more = this.more;\n const url = more?.getAttribute('href');\n\n if (more && url) {\n this.more = undefined;\n\n this.container?.classList.add(this.options.loadingClass);\n\n fetch(url)\n .then((data) => data.text())\n .then((html) => {\n const data = parseHTML(html);\n const newMore = data.querySelector(this.options.more);\n const items = [...data.querySelectorAll(this.options.items)];\n\n if (items.length > 0) this.container?.append(...items);\n\n this.container?.classList.remove(this.options.loadingClass);\n\n if (newMore) {\n more.replaceWith(newMore);\n this.more = newMore;\n\n // Delay adding the new waypoint for half a second to let the gallery update properly.\n setTimeout(() => {\n this.waypoint = new window.Waypoint(this.options as InfiniteWaypointOptions);\n }, 250);\n } else {\n more.remove();\n }\n\n this.options.onAfterPageLoad(items);\n })\n .catch(() => {\n alert('Unable to load more photos');\n });\n }\n };\n }\n\n canLoadMore(): boolean {\n return !!this.more;\n }\n\n destroy(): void {\n if (this.waypoint) {\n this.waypoint.destroy();\n }\n }\n}\n","import { Controller } from '@hotwired/stimulus';\nimport { Modal } from 'bootstrap';\nimport { saveAs } from 'file-saver';\nimport PhotoSwipe, { SlideData } from 'photoswipe';\nimport PhotoSwipeLightbox from 'photoswipe/lightbox';\nimport scrollIntoView from 'scroll-into-view';\nimport Swal from 'sweetalert2';\n\nimport csrfToken from '../javascript/csrf.ts';\nimport JustifiedGallery from '../javascript/justified-gallery.ts';\nimport Infinite from '../javascript/waypoints-infinite.ts';\n\ninterface GalleryItem extends SlideData {\n /**\n * Photo ID\n */\n id: number;\n\n /**\n * Download URL\n */\n download?: string;\n}\n\ninterface JSONMessageResponse {\n message: string;\n}\n\ninterface JSONSuccessResponse {\n success: boolean;\n}\n\nexport default class AlbumGalleryController extends Controller {\n private justifiedGallery?: JustifiedGallery;\n private photoswipeItems: GalleryItem[] = [];\n private infinite?: Infinite;\n private lightbox?: PhotoSwipeLightbox;\n private emailPhotoModalElement?: HTMLElement;\n private emailPhotoModal?: Modal;\n private addToAlbumModalElement?: HTMLElement;\n private addToAlbumModal?: Modal;\n\n connect() {\n this.emailPhotoModalElement = document.querySelector('#emailPhotoModal') ?? undefined;\n this.addToAlbumModalElement = document.querySelector('#addToAlbumModal') ?? undefined;\n\n if (this.emailPhotoModalElement) this.emailPhotoModal = new Modal(this.emailPhotoModalElement);\n if (this.addToAlbumModalElement) this.addToAlbumModal = new Modal(this.addToAlbumModalElement);\n\n this.setupButtonHandlers();\n\n for (const item of this.element.querySelectorAll('.photo')) {\n this.addPhoto(item);\n }\n\n this.justifiedGallery = new JustifiedGallery(this.element, {\n rowHeight: 170,\n maxRowHeight: 350,\n margins: 5,\n triggerEvent: this.justifiedGalleryEventHandler.bind(this),\n });\n\n this.justifiedGalleryRender(false);\n }\n\n teardown(): void {\n this.element.style.visibility = 'hidden';\n\n this.justifiedGallery?.destroy();\n }\n\n private justifiedGalleryEventHandler(event: string) {\n if (event === 'jg.complete') {\n this.element.style.visibility = 'visible';\n\n // Don't initialize infinite scroll until we render the gallery at least once\n if (!this.infinite) {\n this.infinite = new Infinite({\n element: this.element,\n more: '.next-link',\n items: '.photo',\n onAfterPageLoad: (images) => {\n this.addPhotos(images);\n this.justifiedGalleryRender(false);\n },\n });\n }\n }\n }\n\n private justifiedGalleryRender(rewind = true) {\n if (!this.justifiedGallery) return;\n\n if (rewind) {\n this.justifiedGallery.rewind();\n }\n\n // Update the entries list\n if (!this.justifiedGallery.updateEntries(!rewind)) return;\n\n // Init justified gallery\n this.justifiedGallery.init();\n }\n\n private addPhotos(images: HTMLElement[]) {\n for (const image of images) {\n this.addPhoto(image);\n }\n }\n\n private addPhoto(image: HTMLElement) {\n // push the item to the photoswipe list\n this.photoswipeItems.push({\n id: image.dataset.id ? Number.parseInt(image.dataset.id, 10) : -1,\n src: image.dataset.src,\n srcset: image.dataset.srcset,\n download: image.dataset.original,\n width: Number.parseInt(image.dataset.width ?? '', 10),\n height: Number.parseInt(image.dataset.height ?? '', 10),\n element: image,\n });\n\n const imageTag = image.querySelector('img');\n if (imageTag) {\n imageTag.addEventListener('click', () => this.startPhotoSwipe(image));\n }\n\n const deleteButton = image.querySelector('.btn-delete');\n if (deleteButton) {\n deleteButton.addEventListener('click', () => this.deleteImage(image));\n }\n\n const hideButton = image.querySelector('.btn-hide');\n if (hideButton) {\n hideButton.addEventListener('click', () => this.hideImage(image));\n }\n }\n\n startPhotoSwipe(image: HTMLElement) {\n if (!image.dataset.id) return;\n\n // Get the index of the photo we need to launch at\n const index = this.photoswipeItems.findIndex((item) => {\n return item.id === Number.parseInt(image.dataset.id ?? '', 10);\n });\n\n this.lightbox = new PhotoSwipeLightbox({\n dataSource: this.photoswipeItems,\n loop: false,\n preload: [3, 3],\n pswpModule: PhotoSwipe,\n bgOpacity: 1,\n clickToCloseNonZoomable: false,\n secondaryZoomLevel: 1,\n maxZoomLevel: 2,\n trapFocus: false,\n });\n\n // Add listener to see when we get near the end of the album\n this.lightbox.on('change', () => {\n if (!this.lightbox?.pswp) return;\n\n const index = this.lightbox.pswp.currIndex;\n\n if (index > this.photoswipeItems.length - 5 && this.infinite?.canLoadMore()) {\n this.infinite.triggerHandler();\n }\n\n const item = this.photoswipeItems[index];\n\n if (item?.element) {\n scrollIntoView(item.element);\n }\n });\n\n this.lightbox.on('close', () => {\n if (!this.lightbox?.pswp) return;\n\n if (this.lightbox.pswp.currIndex) {\n const index = this.lightbox.pswp.currIndex;\n const item = this.photoswipeItems[index || 0];\n\n if (item?.element) {\n scrollIntoView(item.element);\n }\n }\n });\n\n this.lightbox.addFilter('numItems', () => {\n return Number.parseInt(this.element.dataset.count ?? '0');\n });\n\n this.lightbox.on('uiRegister', () => {\n this.lightbox?.pswp?.ui?.registerElement({\n name: 'album-button',\n order: 8,\n isButton: true,\n html: {\n isCustomSVG: true,\n inner:\n '',\n outlineID: 'pswp__icn-album',\n },\n onClick: () => {\n this.showAddToAlbum();\n },\n });\n });\n\n this.lightbox.on('uiRegister', () => {\n this.lightbox?.pswp?.ui?.registerElement({\n name: 'email-button',\n order: 8,\n isButton: true,\n html: {\n isCustomSVG: true,\n inner:\n '',\n outlineID: 'pswp__icn-email',\n },\n onClick: () => {\n this.showEmailPhoto();\n },\n });\n });\n\n this.lightbox.on('uiRegister', () => {\n this.lightbox?.pswp?.ui?.registerElement({\n name: 'download-button',\n order: 8,\n isButton: true,\n html: {\n isCustomSVG: true,\n inner:\n '',\n outlineID: 'pswp__icn-download',\n },\n onClick: () => {\n this.downloadPhoto();\n },\n });\n });\n\n this.lightbox.init();\n this.lightbox.loadAndOpen(index);\n }\n\n private setupButtonHandlers() {\n const emailSubmitButton = this.emailPhotoModalElement?.querySelector('#email-photo');\n const addToAlbumButton = this.addToAlbumModalElement?.querySelector('#add-to-album');\n\n emailSubmitButton?.addEventListener('click', () => {\n this.emailPhoto();\n });\n\n addToAlbumButton?.addEventListener('click', () => {\n this.addToAlbum();\n });\n }\n\n showAddToAlbum() {\n this.addToAlbumModal?.show();\n }\n\n showEmailPhoto() {\n if (!this.emailPhotoModalElement || !this.emailPhotoModal) return;\n\n const destinationNameField = this.emailPhotoModalElement.querySelector('#email-dest-name');\n const destinationEmailField = this.emailPhotoModalElement.querySelector('#email-dest-email');\n const noteField = this.emailPhotoModalElement.querySelector('#email-note');\n\n if (destinationNameField) destinationNameField.value = '';\n if (destinationEmailField) destinationEmailField.value = '';\n if (noteField) noteField.value = '';\n\n this.emailPhotoModal.show();\n }\n\n downloadPhoto() {\n const item = this.lightbox?.pswp?.currSlide?.data as GalleryItem;\n\n if (item.download) {\n if (window.webkit?.messageHandlers?.colemanApp) {\n const message = JSON.stringify({ action: 'downloadPhoto', url: item.download });\n window.webkit.messageHandlers.colemanApp.postMessage(message);\n } else if (window.ReactNativeWebView) {\n window.ReactNativeWebView.postMessage(JSON.stringify({ action: 'downloadPhoto', url: item.download }));\n } else if (/(iPad|iPhone|iPod)/g.test(navigator.userAgent)) {\n window.open(item.download);\n } else {\n const filename = item.download.split('/').pop();\n saveAs(item.download, filename);\n }\n }\n }\n\n async addToAlbum() {\n if (!this.addToAlbumModal || !this.addToAlbumModalElement) return;\n\n const item = this.lightbox?.pswp?.currSlide?.data as GalleryItem;\n\n const photoId = item.id;\n\n const albumSelect = this.addToAlbumModalElement.querySelector('#add-to-album-select');\n const albumId = albumSelect?.value;\n\n try {\n const response = await fetch('/myalbums/add', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': csrfToken(),\n },\n body: JSON.stringify({\n album: albumId,\n photo: photoId,\n }),\n });\n const json = (await response.json()) as JSONMessageResponse;\n\n Swal.fire({\n text: `${json.message}`,\n icon: response.ok ? 'success' : 'error',\n timer: response.ok ? 2000 : undefined,\n });\n if (response.ok) this.addToAlbumModal.hide();\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n Swal.fire({ icon: 'error', text: `An unknown error ocurred while adding to the album: ${error}` });\n }\n }\n\n async emailPhoto() {\n if (!this.emailPhotoModalElement || !this.emailPhotoModal) return;\n\n const item = this.lightbox?.pswp?.currSlide?.data as GalleryItem;\n\n const photoId = item.id;\n const destinationNameField = this.emailPhotoModalElement.querySelector('#email-dest-name');\n const destinationEmailField = this.emailPhotoModalElement.querySelector('#email-dest-email');\n const noteField = this.emailPhotoModalElement.querySelector('#email-note');\n\n try {\n const response = await fetch('/photos/share/email', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': csrfToken(),\n },\n body: JSON.stringify({\n photo: photoId,\n destination_name: destinationNameField?.value,\n destination_email: destinationEmailField?.value,\n note: noteField?.value,\n }),\n });\n const json = (await response.json()) as JSONMessageResponse;\n\n Swal.fire({\n text: `${json.message}`,\n icon: response.ok ? 'success' : 'error',\n });\n if (response.ok) this.emailPhotoModal.hide();\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n Swal.fire({ icon: 'error', text: `An unknown error ocurred while sending the photo: ${error}` });\n }\n }\n\n async deleteImage(image: HTMLElement) {\n try {\n const confirmation = await Swal.fire({\n title: 'Remove Photo',\n text: 'Are you sure you would like to remove this photo?',\n icon: 'warning',\n showCancelButton: true,\n focusConfirm: false,\n focusCancel: true,\n confirmButtonColor: '#3085d6',\n cancelButtonColor: '#d33',\n confirmButtonText: 'Yes, remove!',\n });\n\n if (!confirmation.isConfirmed) return;\n\n const response = await fetch('/myalbums/remove', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': csrfToken(),\n },\n body: JSON.stringify({\n id: image.dataset.personalId,\n }),\n });\n const json = (await response.json()) as JSONSuccessResponse;\n\n if (json.success) {\n image.remove();\n this.justifiedGalleryRender();\n this.decrementPhotoCount();\n Swal.fire({\n text: 'Photo was removed from the album',\n icon: 'success',\n timer: 2000,\n showConfirmButton: false,\n });\n }\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n Swal.fire({ icon: 'error', text: `An unknown error ocurred while removing this photo: ${error}` });\n }\n }\n\n async hideImage(image: HTMLElement) {\n try {\n const confirmation = await Swal.fire({\n title: 'Hide Photo',\n text: 'Are you sure you would like to hide this photo?',\n icon: 'warning',\n showCancelButton: true,\n focusConfirm: false,\n focusCancel: true,\n confirmButtonColor: '#3085d6',\n cancelButtonColor: '#d33',\n confirmButtonText: 'Yes, hide!',\n });\n\n if (!confirmation.isConfirmed) return;\n\n const response = await fetch('/faces/hide', {\n method: 'POST',\n headers: {\n 'Content-Type': 'application/json',\n 'X-CSRF-Token': csrfToken(),\n },\n body: JSON.stringify({\n person: image.dataset.personId,\n face: image.dataset.faceId,\n }),\n });\n const json = (await response.json()) as JSONSuccessResponse;\n\n if (json.success) {\n image.remove();\n this.justifiedGalleryRender();\n this.decrementPhotoCount();\n Swal.fire({\n text: 'Photo was removed from the album',\n icon: 'success',\n timer: 2000,\n showConfirmButton: false,\n });\n }\n } catch (error: unknown) {\n // eslint-disable-next-line @typescript-eslint/restrict-template-expressions\n Swal.fire({ icon: 'error', text: `An unknown error ocurred while hiding this photo: ${error}` });\n }\n }\n\n private decrementPhotoCount() {\n const counts = document.querySelectorAll('.photo-count');\n\n for (const countElement of counts) {\n const text = countElement.innerHTML;\n const count = /\\d+/.exec(text);\n if (text && count) {\n const newCount = Number.parseInt(count[0], 10) - 1;\n countElement.innerHTML = text.replace(/\\d+/, newCount.toString());\n }\n }\n }\n}\n","import { Controller } from '@hotwired/stimulus';\n\nimport Infinite from '../javascript/waypoints-infinite.ts';\n\nexport default class HomeFeedController extends Controller {\n connect() {\n new Infinite({\n element: this.element as HTMLElement,\n more: '.next-link',\n items: '.feed-element',\n });\n }\n}\n","import { Application } from '@hotwired/stimulus';\nimport { Turbo } from '@hotwired/turbo-rails';\nimport ahoy from 'ahoy.js';\nimport * as Bootstrap from 'bootstrap';\nimport Swal from 'sweetalert2';\n\nimport AlbumGalleryController from '../controllers/album-gallery-controller.ts';\nimport FaceCropperController from '../controllers/face-cropper-controller.ts';\nimport HomeFeedController from '../controllers/home-feed-controller.ts';\nimport VideoController from '../controllers/video-controller.ts';\n\nconst stimulus = Application.start();\nstimulus.register('album-gallery', AlbumGalleryController);\nstimulus.register('face-cropper', FaceCropperController);\nstimulus.register('home-feed', HomeFeedController);\nstimulus.register('video', VideoController);\n\ndocument.addEventListener('turbo:before-cache', function () {\n // Teardown Stimulus controllers\n for (const controller of stimulus.controllers) {\n if ('teardown' in controller && typeof controller.teardown === 'function') {\n // eslint-disable-next-line @typescript-eslint/no-unsafe-call\n controller.teardown();\n }\n }\n\n // Close the navbar\n const navbarCollapse = document.querySelector('#navbarCollapse');\n if (navbarCollapse) {\n const bsCollapse = Bootstrap.Collapse.getInstance(navbarCollapse);\n bsCollapse?.hide();\n }\n});\n\nTurbo.config.forms.confirm = async (message: string) => {\n const result = await Swal.fire({\n text: message,\n icon: 'warning',\n showCancelButton: true,\n focusConfirm: false,\n focusCancel: true,\n confirmButtonColor: '#3085d6',\n cancelButtonColor: '#d33',\n confirmButtonText: 'Yes!',\n });\n\n return result.isConfirmed;\n};\n\nTurbo.StreamActions.redirect = function () {\n Turbo.visit(this.target ?? '/');\n};\n\n// Email Hiding\nfunction setupEmails() {\n const at = / at /;\n const dot = / dot /g;\n const emails = document.querySelectorAll('span.mailme');\n for (const element of emails) {\n if (element.textContent?.replaceAll !== undefined) {\n const addr = element.textContent.replace(at, '@').replaceAll(dot, '.');\n element.innerHTML = '' + addr + '';\n }\n }\n}\n\ndocument.addEventListener('turbo:load', setupEmails);\ndocument.addEventListener('turbo:frame-load', setupEmails);\n\ndocument.addEventListener('turbo:load', function () {\n ahoy.trackView();\n});\n"],"names":["a","b","this","c","g","d","e","f","global","h","i","j","k","l","m","module","createElement","className","tagName","appendToEl","el","equalizePoints","p1","p2","roundPoint","p","getDistanceBetween","x","y","pointsEqual","clamp","val","min","max","toTransformString","scale","propValue","setTransform","defaultCSSEasing","setTransitionStyle","prop","duration","ease","setWidthHeight","w","removeTransitionStyle","decodeImage","img","resolve","reject","LOAD_STATE","specialKeyUsed","getElementsFromOption","option","legacySelector","parent","elements","selector","isSafari","supportsPassive","DOMEvents","target","type","listener","passive","poolItem","unbind","skipPool","methodName","eType","eventOptions","getViewportSize","options","pswp","newViewportSize","parsePaddingOption","viewportSize","itemData","index","paddingValue","legacyPropName","getPanAreaSize","PanBounds","slide","currZoomLevel","axis","elSize","padding","panAreaSize","panOffset","MAX_IMAGE_WIDTH","ZoomLevel$1","maxWidth","maxHeight","elementSize","hRatio","vRatio","optionPrefix","optionName","optionValue","Slide","data","ZoomLevel","isActive","holderElement","force","scaleMultiplier","width","height","_this$content$placeho","destZoomLevel","centerPoint","transitionDuration","ignoreBounds","prevZoomLevel","finishTransition","point","zoomFactor","panX","panY","zoom","newResolution","PAN_END_FRICTION","VERTICAL_DRAG_FRICTION","MIN_RATIO_TO_CLOSE","MIN_NEXT_SLIDE_SPEED","project","initialVelocity","decelerationRate","DragHandler","gestures","prevP1","dragAxis","currSlide","bgOpacity","velocity","mainScroll","indexDiff","currentSlideVisibilityRatio","pan","bounds","panPos","restoreBgOpacity","projectedPosition","vDragRatio","projectedVDragRatio","correctedPanPosition","dampingRatio","initialBgOpacity","totalPanDist","pos","animationProgressRatio","isMultitouch","delta","newMainScrollX","newPan","currSlideMainScrollX","mainScrollShiftDiff","isLeftToRight","isRightToLeft","_this$pswp$currSlide$","_this$pswp$currSlide","potentialPan","customFriction","UPPER_ZOOM_FRICTION","LOWER_ZOOM_FRICTION","getZoomPointsCenter","ZoomHandler","startP1","startP2","minZoomLevel","maxZoomLevel","ignoreGesture","destinationZoomLevel","currZoomLevelNeedsChange","initialPan","destinationPan","panNeedsChange","now","newZoomLevel","didTapOnMainContent","event","TapHandler","originalEvent","targetClassList","isImageClick","isBackgroundClick","actionName","_this$gestures$pswp$e","actionFullName","AXIS_SWIPE_HYSTERISIS","DOUBLE_TAP_DELAY","MIN_TAP_DISTANCE","Gestures","pref","down","up","cancel","events","cancelEvent","isMousePointer","time","tapDelay","displacement","pointerType","pointerEvent","pointerIndex","ongoingPointer","touchEvent","diff","axisToCheck","MAIN_SCROLL_END_FRICTION","MainScroll","resizeSlides","newSlideWidth","slideWidthChanged","itemHolder","animate","velocityX","newIndex","numSlides","distance","destinationX","currDiff","currDistance","_this$itemHolders$","positionDifference","diffAbs","tempHolder","_itemHolder$slide","dragging","newSlideIndexOffset","KeyboardKeyCodesMap","getKeyboardEventKey","key","isKeySupported","Keyboard","lastActiveElement","keydownAction","isForward","template","DEFAULT_EASING","CSSAnimation","props","_props$prop","onComplete","transform","onFinish","easing","DEFAULT_NATURAL_FREQUENCY","DEFAULT_DAMPING_RATIO","SpringEaser","naturalFrequency","deltaPosition","deltaTime","coeff","naturalDumpingPow","dumpedFCos","dumpedFSin","SpringAnimation","start","end","onUpdate","easer","prevTime","animationLoop","Animations","isSpring","animation","ScrollWheel","deltaX","deltaY","addElementHTML","htmlData","svgData","out","UIElement","_container","name","elementHTML","element","title","ariaLabel","ariaText","appendTo","container","initArrowButton","isNextButton","arrowPrev","arrowNext","closeButton","zoomButton","loadingIndicator","indicatorElement","isVisible","delayTimeout","toggleIndicatorClass","add","setIndicatorVisibility","visible","updatePreloaderVisibility","_pswp$currSlide","_pswp$currSlide2","counterIndicator","counterElement","setZoomedIn","isZoomedIn","UI","uiElementData","_pswp$element","elementData","currZoomLevelDiff","potentialZoomLevel","getBoundsByElement","thumbAreaRect","getCroppedBoundsByElement","imageWidth","imageHeight","fillZoomLevel","offsetX","offsetY","getThumbBounds","instance","thumbBounds","thumbnail","thumbSelector","PhotoSwipeEvent$1","details","Eventable$1","fn","priority","_this$_filters$name","_this$_filters$name2","_this$pswp","f1","f2","filter","args","_this$_filters$name3","_this$_listeners$name","_this$pswp2","_this$pswp3","_this$_listeners$name2","PhotoSwipeEvent","Placeholder$1","imageSrc","imgEl","_this$element","Content$1","isLazy","reload","placeholderEl","placeholderSrc","Placeholder","_this$data$src","_this$data$alt","imageElement","isInitialSizeUpdate","image","sizesWidth","_this$instance$option","_this$instance$option2","errorMsgEl","supportsDecode","MIN_SLIDES_TO_CACHE","lazyLoadData","content","zoomLevel","lazyLoadSlide","ContentLoader","preload","initialIndex","indexToRemove","item","Eventable","_this$options","numItems","dataSource","slideData","Content","_this$options2","dataSourceItem","galleryElement","_this$options3","_this$options4","linkEl","thumbnailEl","_thumbnailEl$getAttri","MIN_OPACITY","Opener","_options$showHideOpac","decoded","isDelaying","_this$pswp$element","_this$pswp$element2","innerRect","containerOnePanX","containerOnePanY","containerTwoPanX","containerTwoPanY","animations","animProps","defaultOptions","PhotoSwipe","PhotoSwipeBase","rootClasses","itemHolders","_this$currSlide","_this$currSlide2","_itemHolder$slide2","slideIndex","_this$currSlide$index","_this$currSlide3","potentialHolderIndex","_itemHolder$slide3","holder","opacity","_this$element2","isPswpClass","PhotoSwipeLightbox","initialPoint","clickedIndex","clickedTarget","clickedChildIndex","child","galleryElements","promiseArray","pswpModuleType","uid","iterableModules","mainModule","COMPLETE","CANCELED","raf","task","setElementScroll","getTargetScrollLocation","scrollSettings","align","targetPosition","parentPosition","differenceX","differenceY","targetWidth","targetHeight","leftAlign","topAlign","leftOffset","topOffset","leftScalar","topScalar","offsetLeft","offsetTop","maxSynchronousAlignments","location","timeValue","easeValue","defaultIsWindow","transitionScrollTo","settings","scrollAncestor","callback","idle","lastSettings","cancelHandler","passiveOptions","endType","defaultIsScrollable","defaultValidTarget","findParentElement","scrollIntoView","v","parents","done","validTarget","isScrollable","scrollingElements","JustifiedGallery","gallery","__publicField","entry","rowHeight","imgWidth","_a","imgHeight","_b","isLastRow","hiddenRow","newImgW","newImgH","justify","minHeight","availableWidth","defaultRowHeight","justifiable","imgAspectRatio","offX","buildingRowResult","galleryWidth","norewind","allEntries","newEntries","entries","array","random","temporary","isForResize","_c","onLoad","onError","imagesToLoad","skippedImages","loadImg","_d","newMaxRowHeight","keyCounter","allWaypoints","Waypoint","direction","method","allWaypointsArray","waypointKey","requestAnimationFrameShim","contexts","oldWindowLoad","Context","waypoint","horizontalEmpty","verticalEmpty","isWindow","self","resizeHandler","scrollHandler","triggeredGroups","axes","axisKey","wasBeforeTriggerPoint","nowAfterTriggerPoint","crossedForward","crossedBackward","groupKey","contextOffset","adjustment","oldTriggerPoint","elementOffset","freshWaypoint","contextModifier","wasBeforeScroll","nowAfterScroll","triggeredBackward","triggeredForward","contextId","requestFn","byTriggerPoint","byReverseTriggerPoint","groups","Group","waypoints","reverse","isLast","getWindow","NoFrameworkAdapter","isWin","handler","removeListeners","listeners","eventParts","eventType","namespace","ns","documentElement","win","rect","nsHandlers","nsTypeList","includeMargin","computedStyle","merge","obj","parseHTML","html","Infinite","more","url","newMore","items","AlbumGalleryController","Controller","Modal","images","rewind","imageTag","deleteButton","hideButton","emailSubmitButton","addToAlbumButton","destinationNameField","destinationEmailField","noteField","_e","message","filename","saveAs","photoId","albumSelect","albumId","response","csrfToken","json","Swal","error","counts","countElement","text","count","newCount","HomeFeedController","stimulus","Application","FaceCropperController","VideoController","controller","navbarCollapse","bsCollapse","Bootstrap.Collapse","Turbo.config","Turbo.StreamActions","Turbo.visit","setupEmails","at","dot","emails","addr","ahoy"],"mappings":"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","x_google_ignoreList":[0,1,2,3,5]}