// source --> https://einhausfuerklaus.de/wp-content/plugins/responsive-lightbox/js/sanitizer.js?ver=2.7.6 
(e=>{const t=e.RLG||(e.RLG={}),i=e=>e&&"function"==typeof e.sanitize;t.getPurifier=()=>i(t.DOMPurify)?t.DOMPurify:i(e.DOMPurify)?e.DOMPurify:null,t.sanitizeConfig=t.sanitizeConfig||{ALLOWED_TAGS:["a","abbr","b","br","code","em","i","li","ol","p","pre","small","strong","sub","sup","u","ul","img","div","span"],ALLOWED_ATTR:["href","src","alt","title","width","height","class","id","rel","target","data-*"],ALLOWED_URI_REGEXP:/^(?:(?:https?|mailto|tel):|[^a-z]|data:image\/(?:png|jpeg|gif|webp);base64,)/i},t.isAllowedEmbedUrl=e=>{try{const i=new URL(e,location.href);if(i.hostname===location.hostname)return!0;if(Array.isArray(t.sanitizeAllowedHosts)){const e=i.hostname.toLowerCase();return t.sanitizeAllowedHosts.some(t=>(t=(t||"").toLowerCase(),e===t||e.endsWith("."+t)))}return!1}catch(i){return!1}};const o=t.getPurifier();o&&"function"==typeof o.addHook&&o.addHook("uponSanitizeElement",function(e){if("iframe"===(e&&e.nodeName&&e.nodeName.toLowerCase&&e.nodeName.toLowerCase())){const i=e.getAttribute&&e.getAttribute("src");i&&t.isAllowedEmbedUrl(i)||e.parentNode&&e.parentNode.removeChild(e)}}),t.sanitizeHtml=(e,i=null)=>{const o=t.getPurifier();return o?o.sanitize(e,i||t.sanitizeConfig||{}):e}})(window);
// source --> https://einhausfuerklaus.de/wp-content/plugins/responsive-lightbox/assets/swipebox/jquery.swipebox.js?ver=1.5.2 
/*! Swipebox v1.5.2-patched | Constantin Saguin csag.co | MIT License | github.com/brutaldesign/swipebox */

(function (window, document, $, undefined) {
	$.swipebox = function (elem, options) {
		$(elem).addClass('swipebox'); // fugly but yea, swipebox class all the things

		// Default options
		var ui,
			defaults = {
				useCSS: true,
				useSVG: true,
				initialIndexOnArray: 0,
				removeBarsOnMobile: true,
				hideCloseButtonOnMobile: false,
				hideBarsDelay: 3000,
				videoMaxWidth: 1140,
				vimeoColor: 'cccccc',
				beforeOpen: null,
				afterOpen: null,
				afterClose: null,
				afterMedia: null,
				nextSlide: null,
				prevSlide: null,
				loopAtEnd: false,
				autoplayVideos: false,
				queryStringData: {},
				toggleClassOnLoad: '',
			},
			plugin = this,
			elements = [], // slides array [ { href:'...', title:'...' }, ...],
			$elem,
			selector = '.swipebox',
			isMobile = navigator.userAgent.match(
				/(iPad)|(iPhone)|(iPod)|(Android)|(PlayBook)|(BB10)|(BlackBerry)|(Opera Mini)|(IEMobile)|(webOS)|(MeeGo)/i
			),
			isTouch =
				isMobile !== null ||
				document.createTouch !== undefined ||
				'ontouchstart' in window ||
				'onmsgesturechange' in window ||
				navigator.msMaxTouchPoints,
			supportSVG =
				!!document.createElementNS &&
				!!document.createElementNS('http://www.w3.org/2000/svg', 'svg').createSVGRect,
			winWidth = window.innerWidth ? window.innerWidth : $(window).width(),
			winHeight = window.innerHeight ? window.innerHeight : $(window).height(),
			currentX = 0,
			/* jshint multistr: true */
			html =
				'<div id="swipebox-overlay">\
					<div id="swipebox-container">\
						<div id="swipebox-slider"></div>\
						<div id="swipebox-top-bar">\
							<div id="swipebox-title"></div>\
						</div>\
						<div id="swipebox-bottom-bar">\
							<div id="swipebox-arrows">\
								<a id="swipebox-prev"></a>\
								<a id="swipebox-next"></a>\
							</div>\
						</div>\
						<a id="swipebox-close"></a>\
					</div>\
			</div>';

		plugin.settings = {};

		$.swipebox.close = function () {
			ui.closeSlide();
		};

		$.swipebox.extend = function () {
			return ui;
		};

		plugin.init = function () {
			plugin.settings = $.extend({}, defaults, options);

			if (Array.isArray(elem)) {
				elements = elem;
				ui.target = $(window);
				ui.init(plugin.settings.initialIndexOnArray);
			} else {
				$(document).on('click', selector, function (event) {
					// console.log( isTouch );

					if (event.target.parentNode.className === 'slide current') {
						return false;
					}

					if (!Array.isArray(elem)) {
						ui.destroy();
						$elem = $(selector);
						ui.actions();
					}

					elements = [];
					var index, relType, relVal;

					// Allow for HTML5 compliant attribute before legacy use of rel
					if (!relVal) {
						relType = 'data-rel';
						relVal = $(this).attr(relType);
					}

					if (!relVal) {
						relType = 'rel';
						relVal = $(this).attr(relType);
					}

					if (relVal && relVal !== '' && relVal !== 'nofollow') {
						$elem = $(selector).filter('[' + relType + '="' + relVal + '"]');
					} else {
						$elem = $(selector);
					}

					$elem.each(function () {
						var title = null,
							href = null;

						if ($(this).attr('title')) {
							title = $(this).attr('title');
						}

						if ($(this).attr('href')) {
							href = $(this).attr('href');
						}

						elements.push({
							href: href,
							title: title,
						});
					});

					index = $elem.index($(this));
					event.preventDefault();
					event.stopPropagation();
					ui.target = $(event.target);
					ui.init(index);
				});
			}
		};

		ui = {
			/**
			 * Initiate Swipebox
			 */
			init: function (index) {
				if (plugin.settings.beforeOpen) {
					plugin.settings.beforeOpen();
				}
				this.target.trigger('swipebox-start');
				$.swipebox.isOpen = true;
				this.build();
				this.openSlide(index);
				this.openMedia(index);
				this.preloadMedia(index + 1);
				this.preloadMedia(index - 1);
				if (plugin.settings.afterOpen) {
					plugin.settings.afterOpen(index);
				}
			},

			/**
			 * Built HTML containers and fire main functions
			 */
			build: function () {
				var $this = this,
					bg;

				$('body').append(html);

				if (supportSVG && plugin.settings.useSVG === true) {
					bg = $('#swipebox-close').css('background-image');
					bg = bg.replace('png', 'svg');
					$('#swipebox-prev, #swipebox-next, #swipebox-close').css({
						'background-image': bg,
					});
				}

				if (isMobile && plugin.settings.removeBarsOnMobile) {
					$('#swipebox-bottom-bar, #swipebox-top-bar').remove();
				}

				$.each(elements, function () {
					$('#swipebox-slider').append('<div class="slide"></div>');
				});

				$this.setDim();
				$this.actions();

				if (isTouch) {
					$this.gesture();
				}

				// Devices can have both touch and keyboard input so always allow key events
				$this.keyboard();

				$this.animBars();
				$this.resize();
			},

			/**
			 * Set dimensions depending on windows width and height
			 */
			setDim: function () {
				var width,
					height,
					sliderCss = {};

				// Reset dimensions on mobile orientation change
				if ('onorientationchange' in window) {
					window.addEventListener(
						'orientationchange',
						function () {
							if (window.orientation === 0) {
								width = winWidth;
								height = winHeight;
							} else if (window.orientation === 90 || window.orientation === -90) {
								width = winHeight;
								height = winWidth;
							}
						},
						false
					);
				} else {
					width = window.innerWidth ? window.innerWidth : $(window).width();
					height = window.innerHeight ? window.innerHeight : $(window).height();
				}

				sliderCss = {
					width: width,
					height: height,
				};

				$('#swipebox-overlay').css(sliderCss);
			},

			/**
			 * Reset dimensions on window resize envent
			 */
			resize: function () {
				var $this = this;

				$(window)
					.on('resize', function () {
						$this.setDim();
					})
					.trigger('resize');
			},

			/**
			 * Check if device supports CSS transitions
			 */
			supportTransition: function () {
				var prefixes =
						'transition WebkitTransition MozTransition OTransition msTransition KhtmlTransition'.split(
							' '
						),
					i;

				for (i = 0; i < prefixes.length; i++) {
					if (document.createElement('div').style[prefixes[i]] !== undefined) {
						return prefixes[i];
					}
				}
				return false;
			},

			/**
			 * Check if CSS transitions are allowed (options + devicesupport)
			 */
			doCssTrans: function () {
				if (plugin.settings.useCSS && this.supportTransition()) {
					return true;
				}
			},

			/**
			 * Touch navigation
			 */
			gesture: function () {
				var $this = this,
					index,
					hDistance,
					vDistance,
					hDistanceLast,
					vDistanceLast,
					hDistancePercent,
					vSwipe = false,
					hSwipe = false,
					hSwipMinDistance = 10,
					vSwipMinDistance = 50,
					startCoords = {},
					endCoords = {},
					bars = $('#swipebox-top-bar, #swipebox-bottom-bar'),
					slider = $('#swipebox-slider');

				bars.addClass('visible-bars');
				$this.setTimeout();

				$('body')
					.on('touchstart', function (event) {
						$(this).addClass('touching');
						index = $('#swipebox-slider .slide').index(
							$('#swipebox-slider .slide.current')
						);
						endCoords = event.originalEvent.targetTouches[0];
						startCoords.pageX = event.originalEvent.targetTouches[0].pageX;
						startCoords.pageY = event.originalEvent.targetTouches[0].pageY;

						$('#swipebox-slider').css({
							'-webkit-transform': 'translate3d(' + currentX + '%, 0, 0)',
							transform: 'translate3d(' + currentX + '%, 0, 0)',
						});

						$('.touching').on('touchmove', function (event) {
							event.preventDefault();
							event.stopPropagation();
							endCoords = event.originalEvent.targetTouches[0];

							if (!hSwipe) {
								vDistanceLast = vDistance;
								vDistance = endCoords.pageY - startCoords.pageY;
								if (Math.abs(vDistance) >= vSwipMinDistance || vSwipe) {
									var opacity = 0.75 - Math.abs(vDistance) / slider.height();

									slider.css({ top: vDistance + 'px' });
									slider.css({ opacity: opacity });

									vSwipe = true;
								}
							}

							hDistanceLast = hDistance;
							hDistance = endCoords.pageX - startCoords.pageX;
							hDistancePercent = (hDistance * 100) / winWidth;

							if (!hSwipe && !vSwipe && Math.abs(hDistance) >= hSwipMinDistance) {
								$('#swipebox-slider').css({
									'-webkit-transition': '',
									transition: '',
								});
								hSwipe = true;
							}

							if (hSwipe) {
								// swipe left
								if (0 < hDistance) {
									// first slide
									if (0 === index) {
										// console.log( 'first' );
										$('#swipebox-overlay').addClass('leftSpringTouch');
									} else {
										// Follow gesture
										$('#swipebox-overlay')
											.removeClass('leftSpringTouch')
											.removeClass('rightSpringTouch');
										$('#swipebox-slider').css({
											'-webkit-transform':
												'translate3d(' +
												(currentX + hDistancePercent) +
												'%, 0, 0)',
											transform:
												'translate3d(' +
												(currentX + hDistancePercent) +
												'%, 0, 0)',
										});
									}

									// swipe right
								} else if (0 > hDistance) {
									// last Slide
									if (elements.length === index + 1) {
										// console.log( 'last' );
										$('#swipebox-overlay').addClass('rightSpringTouch');
									} else {
										$('#swipebox-overlay')
											.removeClass('leftSpringTouch')
											.removeClass('rightSpringTouch');
										$('#swipebox-slider').css({
											'-webkit-transform':
												'translate3d(' +
												(currentX + hDistancePercent) +
												'%, 0, 0)',
											transform:
												'translate3d(' +
												(currentX + hDistancePercent) +
												'%, 0, 0)',
										});
									}
								}
							}
						});

						return false;
					})
					.on('touchend', function (event) {
						event.preventDefault();
						event.stopPropagation();

						$('#swipebox-slider').css({
							'-webkit-transition': '-webkit-transform 0.4s ease',
							transition: 'transform 0.4s ease',
						});

						vDistance = endCoords.pageY - startCoords.pageY;
						hDistance = endCoords.pageX - startCoords.pageX;
						hDistancePercent = (hDistance * 100) / winWidth;

						// Swipe to bottom to close
						if (vSwipe) {
							vSwipe = false;
							if (
								Math.abs(vDistance) >= 2 * vSwipMinDistance &&
								Math.abs(vDistance) > Math.abs(vDistanceLast)
							) {
								var vOffset = vDistance > 0 ? slider.height() : -slider.height();
								slider.animate(
									{ top: vOffset + 'px', opacity: 0 },
									300,
									function () {
										$this.closeSlide();
									}
								);
							} else {
								slider.animate({ top: 0, opacity: 1 }, 300);
							}
						} else if (hSwipe) {
							hSwipe = false;

							// swipeLeft
							if (hDistance >= hSwipMinDistance && hDistance >= hDistanceLast) {
								$this.getPrev();

								// swipeRight
							} else if (
								hDistance <= -hSwipMinDistance &&
								hDistance <= hDistanceLast
							) {
								$this.getNext();
							}
						} else {
							// Top and bottom bars have been removed on touchable devices
							// tap
							if (!bars.hasClass('visible-bars')) {
								$this.showBars();
								$this.setTimeout();
							} else {
								$this.clearTimeout();
								$this.hideBars();
							}
						}

						$('#swipebox-slider').css({
							'-webkit-transform': 'translate3d(' + currentX + '%, 0, 0)',
							transform: 'translate3d(' + currentX + '%, 0, 0)',
						});

						$('#swipebox-overlay')
							.removeClass('leftSpringTouch')
							.removeClass('rightSpringTouch');
						$('.touching').off('touchmove').removeClass('touching');
					});
			},

			/**
			 * Set timer to hide the action bars
			 */
			setTimeout: function () {
				if (plugin.settings.hideBarsDelay > 0) {
					var $this = this;
					$this.clearTimeout();
					$this.timeout = window.setTimeout(
						function () {
							$this.hideBars();
						},

						plugin.settings.hideBarsDelay
					);
				}
			},

			/**
			 * Clear timer
			 */
			clearTimeout: function () {
				window.clearTimeout(this.timeout);
				this.timeout = null;
			},

			/**
			 * Show navigation and title bars
			 */
			showBars: function () {
				var bars = $('#swipebox-top-bar, #swipebox-bottom-bar');
				if (this.doCssTrans()) {
					bars.addClass('visible-bars');
				} else {
					$('#swipebox-top-bar').animate({ top: 0 }, 500);
					$('#swipebox-bottom-bar').animate({ bottom: 0 }, 500);
					setTimeout(function () {
						bars.addClass('visible-bars');
					}, 1000);
				}
			},

			/**
			 * Hide navigation and title bars
			 */
			hideBars: function () {
				var bars = $('#swipebox-top-bar, #swipebox-bottom-bar');
				if (this.doCssTrans()) {
					bars.removeClass('visible-bars');
				} else {
					$('#swipebox-top-bar').animate({ top: '-50px' }, 500);
					$('#swipebox-bottom-bar').animate({ bottom: '-50px' }, 500);
					setTimeout(function () {
						bars.removeClass('visible-bars');
					}, 1000);
				}
			},

			/**
			 * Animate navigation and top bars
			 */
			animBars: function () {
				var $this = this,
					bars = $('#swipebox-top-bar, #swipebox-bottom-bar');

				bars.addClass('visible-bars');
				$this.setTimeout();

				$('#swipebox-slider').on('click', function () {
					if (!bars.hasClass('visible-bars')) {
						$this.showBars();
						$this.setTimeout();
					}
				});

				$('#swipebox-bottom-bar')
					.on('mouseenter', function () {
						$this.showBars();
						bars.addClass('visible-bars');
						$this.clearTimeout();
					})
					.on('mouseleave', function () {
						if (plugin.settings.hideBarsDelay > 0) {
							bars.removeClass('visible-bars');
							$this.setTimeout();
						}
					});
			},

			/**
			 * Keyboard navigation
			 */
			keyboard: function () {
				var $this = this;
				$(window).on('keyup', function (event) {
					event.preventDefault();
					event.stopPropagation();

					if (event.keyCode === 37) {
						$this.getPrev();
					} else if (event.keyCode === 39) {
						$this.getNext();
					} else if (event.keyCode === 27) {
						$this.closeSlide();
					}
				});
			},

			/**
			 * Navigation events : go to next slide, go to prevous slide and close
			 */
			actions: function () {
				var $this = this,
					action = 'touchend click'; // Just detect for both event types to allow for multi-input

				if (elements.length < 2) {
					$('#swipebox-bottom-bar').hide();

					if (undefined === elements[1]) {
						$('#swipebox-top-bar').hide();
					}
				} else {
					$('#swipebox-prev').on(action, function (event) {
						event.preventDefault();
						event.stopPropagation();
						$this.getPrev();
						$this.setTimeout();
					});

					$('#swipebox-next').on(action, function (event) {
						event.preventDefault();
						event.stopPropagation();
						$this.getNext();
						$this.setTimeout();
					});
				}

				$('#swipebox-close').on(action, function (event) {
					event.preventDefault();
					event.stopPropagation();
					$this.closeSlide();
				});
			},

			/**
			 * Set current slide
			 */
			setSlide: function (index, isFirst) {
				isFirst = isFirst || false;

				var slider = $('#swipebox-slider');

				currentX = -index * 100;

				if (this.doCssTrans()) {
					slider.css({
						'-webkit-transform': 'translate3d(' + -index * 100 + '%, 0, 0)',
						transform: 'translate3d(' + -index * 100 + '%, 0, 0)',
					});
				} else {
					slider.animate({ left: -index * 100 + '%' });
				}

				$('#swipebox-slider .slide').removeClass('current');
				$('#swipebox-slider .slide').eq(index).addClass('current');
				this.setTitle(index);

				if (isFirst) {
					slider.fadeIn();
				}

				$('#swipebox-prev, #swipebox-next').removeClass('disabled');

				if (index === 0) {
					$('#swipebox-prev').addClass('disabled');
				} else if (index === elements.length - 1 && plugin.settings.loopAtEnd !== true) {
					$('#swipebox-next').addClass('disabled');
				}
			},

			/**
			 * Open slide
			 */
			openSlide: function (index) {
				$('html').addClass('swipebox-html');
				if (isTouch) {
					$('html').addClass('swipebox-touch');

					if (plugin.settings.hideCloseButtonOnMobile) {
						$('html').addClass('swipebox-no-close-button');
					}
				} else {
					$('html').addClass('swipebox-no-touch');
				}
				$(window).trigger('resize'); // fix scroll bar visibility on desktop
				this.setSlide(index, true);
			},

			/**
			 * Set a time out if the media is a video
			 */
			preloadMedia: function (index) {
				var $this = this,
					src = null;

				if (elements[index] !== undefined) {
					src = elements[index].href;
				}

				if (!$this.isVideo(src)) {
					setTimeout(function () {
						$this.openMedia(index);
					}, 1000);
				} else {
					$this.openMedia(index);
				}
			},

			/**
			 * Open
			 */
			openMedia: function (index) {
				var $this = this,
					src,
					slide;

				if (elements[index] !== undefined) {
					src = elements[index].href;
				}

				if (index < 0 || index >= elements.length) {
					return false;
				}

				slide = $('#swipebox-slider .slide').eq(index);

				if (!$this.isVideo(src)) {
					slide.addClass('slide-loading');
					$this.loadMedia(src, function () {
						slide.removeClass('slide-loading');
						slide.html(this);

						if (plugin.settings.afterMedia) {
							plugin.settings.afterMedia(index);
						}
					});
				} else {
					slide.html($this.getVideo(src));

					if (plugin.settings.afterMedia) {
						plugin.settings.afterMedia(index);
					}
				}
			},

			/**
			 * Set link title attribute as caption
			 */
			setTitle: function (index) {
				var title = null;

				$('#swipebox-title').empty();

				if (elements[index] !== undefined) {
					title = elements[index].title;
				}

				if (title) {
					title = title.replace(/[^]/g, function (c) {
						return '&#' + c.charCodeAt(0) + ';';
					});
					$('#swipebox-top-bar').show();
					$('#swipebox-title').append(title);
				} else {
					$('#swipebox-top-bar').hide();
				}
			},

			/**
			 * Check if the URL is a video
			 */
			isVideo: function (src) {
				if (src) {
					if (
						src.match(
							/(youtube\.com|youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/
						) ||
						src.match(/vimeo\.com\/([0-9]*)/) ||
						src.match(/youtu\.be\/([a-zA-Z0-9\-_]+)/)
					) {
						return true;
					}

					if (src.toLowerCase().indexOf('swipeboxvideo=1') >= 0) {
						// For custom video URLs, check if embedding is allowed
						if (
							window.RLG &&
							window.RLG.isAllowedEmbedUrl &&
							window.RLG.isAllowedEmbedUrl(src)
						) {
							return true;
						}
					}
				}
			},

			/**
			 * Parse URI querystring and:
			 * - overrides value provided via dictionary
			 * - rebuild it again returning a string
			 */
			parseUri: function (uri, customData) {
				var a = document.createElement('a'),
					qs = {};

				try {
					// Decode the URI
					a.href = decodeURIComponent(uri);
				} catch (e) {
					// Malformed URI, return empty
					a.href = '';
				}

				// QueryString to Object
				if (a.search) {
					try {
						if (window.URLSearchParams) {
							var params = new URLSearchParams(a.search);
							params.forEach(function (value, key) {
								qs[key] = value;
							});
						} else {
							// Fallback: safer parsing without JSON
							var pairs = a.search.slice(1).split('&');
							for (var i = 0; i < pairs.length; i++) {
								var pair = pairs[i].split('=');
								if (pair[0]) {
									qs[decodeURIComponent(pair[0])] = pair[1]
										? decodeURIComponent(pair[1])
										: '';
								}
							}
						}
					} catch (e) {
						// Parsing failed, use empty qs
					}
				}

				// Extend with custom data
				if ($.isPlainObject(customData)) {
					qs = $.extend(qs, customData, plugin.settings.queryStringData); // The dev has always the final word
				}

				// Return querystring as a string
				return $.map(qs, function (val, key) {
					if (val && val > '') {
						return encodeURIComponent(key) + '=' + encodeURIComponent(val);
					}
				}).join('&');
			},

			/**
			 * Get video iframe code from URL
			 */
			getVideo: function (url) {
				var iframe = '',
					youtubeUrl = url.match(
						/((?:www\.)?youtube\.com|(?:www\.)?youtube-nocookie\.com)\/watch\?v=([a-zA-Z0-9\-_]+)/
					),
					youtubeShortUrl = url.match(/(?:www\.)?youtu\.be\/([a-zA-Z0-9\-_]+)/),
					vimeoUrl = url.match(/(?:www\.)?vimeo\.com\/([0-9]*)/),
					qs = '';

				if (youtubeUrl || youtubeShortUrl) {
					if (youtubeShortUrl) {
						youtubeUrl = youtubeShortUrl;
					}

					qs = ui.parseUri(url, {
						autoplay: plugin.settings.autoplayVideos ? '1' : '0',
						v: '',
					});
					iframe =
						'<iframe width="560" height="315" src="https://' +
						youtubeUrl[1] +
						'/embed/' +
						youtubeUrl[2] +
						'?' +
						qs +
						'" frameborder="0" allowfullscreen></iframe>';
				} else if (vimeoUrl) {
					qs = ui.parseUri(url, {
						autoplay: plugin.settings.autoplayVideos ? '1' : '0',
						byline: '0',
						portrait: '0',
						color: plugin.settings.vimeoColor,
					});
					iframe =
						'<iframe width="560" height="315"  src="https://player.vimeo.com/video/' +
						vimeoUrl[1] +
						'?' +
						qs +
						'" frameborder="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen></iframe>';
				} else {
					if (
						window.RLG &&
						window.RLG.isAllowedEmbedUrl &&
						window.RLG.isAllowedEmbedUrl(url)
					) {
						iframe =
							'<iframe width="560" height="315" src="' +
							url +
							'" frameborder="0" allowfullscreen></iframe>';
					} else {
						iframe =
							'<div class="swipebox-video-error">Video embedding not allowed for this URL.</div>';
					}
				}

				return (
					'<div class="swipebox-video-container" style="max-width:' +
					plugin.settings.videoMaxWidth +
					'px"><div class="swipebox-video">' +
					iframe +
					'</div></div>'
				);
			},

			/**
			 * Load image
			 */
			loadMedia: function (src, callback) {
				// Inline content
				if (src.trim().indexOf('#') === 0) {
					var $target = $(src);
					if ($target.length > 0) {
						var cloned = $target.clone().toggleClass(plugin.settings.toggleClassOnLoad);
						if (cloned[0]) {
							var sanitizedHtml =
								window.RLG && window.RLG.sanitizeHtml
									? window.RLG.sanitizeHtml(cloned[0].outerHTML)
									: cloned[0].outerHTML;
							callback.call(
								$('<div>', {
									class: 'swipebox-inline-container',
								}).append($(sanitizedHtml))
							);
						} else {
							callback.call(
								$('<div>', { class: 'swipebox-inline-container' }).append(
									$('<div>Content not found</div>')
								)
							);
						}
					} else {
						callback.call(
							$('<div>', { class: 'swipebox-inline-container' }).append(
								$('<div>Content not found</div>')
							)
						);
					}
				}
				// Everything else
				else {
					if (!this.isVideo(src)) {
						if (
							window.RLG &&
							window.RLG.sanitizeConfig &&
							window.RLG.sanitizeConfig.ALLOWED_URI_REGEXP &&
							window.RLG.sanitizeConfig.ALLOWED_URI_REGEXP.test(src)
						) {
							var img = $('<img>')
								.on('load', function () {
									callback.call(img);
								})
								.on('error', function () {
									callback.call($('<div>Image could not be loaded</div>'));
								});

							img.attr('src', src);
						} else {
							// Invalid image source, call callback with placeholder
							callback.call($('<div>Invalid image source</div>'));
						}
					}
				}
			},

			/**
			 * Get next slide
			 */
			getNext: function () {
				var $this = this,
					src,
					index = $('#swipebox-slider .slide').index(
						$('#swipebox-slider .slide.current')
					);
				if (index + 1 < elements.length) {
					src = $('#swipebox-slider .slide')
						.eq(index)
						.contents()
						.find('iframe')
						.attr('src');
					$('#swipebox-slider .slide')
						.eq(index)
						.contents()
						.find('iframe')
						.attr('src', src);
					index++;
					$this.setSlide(index);
					$this.preloadMedia(index + 1);
					if (plugin.settings.nextSlide) {
						plugin.settings.nextSlide(index);
					}
				} else {
					if (plugin.settings.loopAtEnd === true) {
						src = $('#swipebox-slider .slide')
							.eq(index)
							.contents()
							.find('iframe')
							.attr('src');
						$('#swipebox-slider .slide')
							.eq(index)
							.contents()
							.find('iframe')
							.attr('src', src);
						index = 0;
						$this.preloadMedia(index);
						$this.setSlide(index);
						$this.preloadMedia(index + 1);
						if (plugin.settings.nextSlide) {
							plugin.settings.nextSlide(index);
						}
					} else {
						$('#swipebox-overlay').addClass('rightSpring');
						setTimeout(function () {
							$('#swipebox-overlay').removeClass('rightSpring');
						}, 500);
					}
				}
			},

			/**
			 * Get previous slide
			 */
			getPrev: function () {
				var index = $('#swipebox-slider .slide').index(
						$('#swipebox-slider .slide.current')
					),
					src;
				if (index > 0) {
					src = $('#swipebox-slider .slide')
						.eq(index)
						.contents()
						.find('iframe')
						.attr('src');
					$('#swipebox-slider .slide')
						.eq(index)
						.contents()
						.find('iframe')
						.attr('src', src);
					index--;
					this.setSlide(index);
					this.preloadMedia(index - 1);
					if (plugin.settings.prevSlide) {
						plugin.settings.prevSlide(index);
					}
				} else {
					$('#swipebox-overlay').addClass('leftSpring');
					setTimeout(function () {
						$('#swipebox-overlay').removeClass('leftSpring');
					}, 500);
				}
			},
			/* jshint unused:false */
			nextSlide: function (index) {
				// Callback for next slide
			},

			prevSlide: function (index) {
				// Callback for prev slide
			},

			/**
			 * Close
			 */
			closeSlide: function () {
				$('html').removeClass('swipebox-html');
				$('html').removeClass('swipebox-touch');
				$(window).trigger('resize');
				this.destroy();
			},

			/**
			 * Destroy the whole thing
			 */
			destroy: function () {
				$(window).off('keyup');
				$('body').off('touchstart');
				$('body').off('touchmove');
				$('body').off('touchend');
				$('#swipebox-slider').off();
				$('#swipebox-overlay').remove();

				if (!Array.isArray(elem)) {
					elem.removeData('_swipebox');
				}

				if (this.target) {
					this.target.trigger('swipebox-destroy');
				}

				$.swipebox.isOpen = false;

				if (plugin.settings.afterClose) {
					plugin.settings.afterClose();
				}
			},
		};

		plugin.init();
	};

	$.fn.swipebox = function (options) {
		if (!$.data(this, '_swipebox')) {
			var swipebox = new $.swipebox(this, options);
			this.data('_swipebox', swipebox);
		}
		return this.data('_swipebox');
	};
})(window, document, jQuery);
// source --> https://einhausfuerklaus.de/wp-includes/js/underscore.min.js?ver=1.13.7 
/*! This file is auto-generated */
!function(n,t){var r,e;"object"==typeof exports&&"undefined"!=typeof module?module.exports=t():"function"==typeof define&&define.amd?define("underscore",t):(n="undefined"!=typeof globalThis?globalThis:n||self,r=n._,(e=n._=t()).noConflict=function(){return n._=r,e})}(this,function(){var n="1.13.7",t="object"==typeof self&&self.self===self&&self||"object"==typeof global&&global.global===global&&global||Function("return this")()||{},e=Array.prototype,V=Object.prototype,F="undefined"!=typeof Symbol?Symbol.prototype:null,P=e.push,f=e.slice,s=V.toString,q=V.hasOwnProperty,r="undefined"!=typeof ArrayBuffer,u="undefined"!=typeof DataView,U=Array.isArray,W=Object.keys,z=Object.create,L=r&&ArrayBuffer.isView,$=isNaN,C=isFinite,K=!{toString:null}.propertyIsEnumerable("toString"),J=["valueOf","isPrototypeOf","toString","propertyIsEnumerable","hasOwnProperty","toLocaleString"],G=Math.pow(2,53)-1;function l(u,o){return o=null==o?u.length-1:+o,function(){for(var n=Math.max(arguments.length-o,0),t=Array(n),r=0;r<n;r++)t[r]=arguments[r+o];switch(o){case 0:return u.call(this,t);case 1:return u.call(this,arguments[0],t);case 2:return u.call(this,arguments[0],arguments[1],t)}for(var e=Array(o+1),r=0;r<o;r++)e[r]=arguments[r];return e[o]=t,u.apply(this,e)}}function o(n){var t=typeof n;return"function"==t||"object"==t&&!!n}function H(n){return void 0===n}function Q(n){return!0===n||!1===n||"[object Boolean]"===s.call(n)}function i(n){var t="[object "+n+"]";return function(n){return s.call(n)===t}}var X=i("String"),Y=i("Number"),Z=i("Date"),nn=i("RegExp"),tn=i("Error"),rn=i("Symbol"),en=i("ArrayBuffer"),a=i("Function"),t=t.document&&t.document.childNodes,p=a="function"!=typeof/./&&"object"!=typeof Int8Array&&"function"!=typeof t?function(n){return"function"==typeof n||!1}:a,t=i("Object"),un=u&&(!/\[native code\]/.test(String(DataView))||t(new DataView(new ArrayBuffer(8)))),a="undefined"!=typeof Map&&t(new Map),u=i("DataView");var h=un?function(n){return null!=n&&p(n.getInt8)&&en(n.buffer)}:u,v=U||i("Array");function y(n,t){return null!=n&&q.call(n,t)}var on=i("Arguments"),an=(!function(){on(arguments)||(on=function(n){return y(n,"callee")})}(),on);function fn(n){return Y(n)&&$(n)}function cn(n){return function(){return n}}function ln(t){return function(n){n=t(n);return"number"==typeof n&&0<=n&&n<=G}}function sn(t){return function(n){return null==n?void 0:n[t]}}var d=sn("byteLength"),pn=ln(d),hn=/\[object ((I|Ui)nt(8|16|32)|Float(32|64)|Uint8Clamped|Big(I|Ui)nt64)Array\]/;var vn=r?function(n){return L?L(n)&&!h(n):pn(n)&&hn.test(s.call(n))}:cn(!1),g=sn("length");function yn(n,t){t=function(t){for(var r={},n=t.length,e=0;e<n;++e)r[t[e]]=!0;return{contains:function(n){return!0===r[n]},push:function(n){return r[n]=!0,t.push(n)}}}(t);var r=J.length,e=n.constructor,u=p(e)&&e.prototype||V,o="constructor";for(y(n,o)&&!t.contains(o)&&t.push(o);r--;)(o=J[r])in n&&n[o]!==u[o]&&!t.contains(o)&&t.push(o)}function b(n){if(!o(n))return[];if(W)return W(n);var t,r=[];for(t in n)y(n,t)&&r.push(t);return K&&yn(n,r),r}function dn(n,t){var r=b(t),e=r.length;if(null==n)return!e;for(var u=Object(n),o=0;o<e;o++){var i=r[o];if(t[i]!==u[i]||!(i in u))return!1}return!0}function m(n){return n instanceof m?n:this instanceof m?void(this._wrapped=n):new m(n)}function gn(n){return new Uint8Array(n.buffer||n,n.byteOffset||0,d(n))}m.VERSION=n,m.prototype.valueOf=m.prototype.toJSON=m.prototype.value=function(){return this._wrapped},m.prototype.toString=function(){return String(this._wrapped)};var bn="[object DataView]";function mn(n,t,r,e){var u;return n===t?0!==n||1/n==1/t:null!=n&&null!=t&&(n!=n?t!=t:("function"==(u=typeof n)||"object"==u||"object"==typeof t)&&function n(t,r,e,u){t instanceof m&&(t=t._wrapped);r instanceof m&&(r=r._wrapped);var o=s.call(t);if(o!==s.call(r))return!1;if(un&&"[object Object]"==o&&h(t)){if(!h(r))return!1;o=bn}switch(o){case"[object RegExp]":case"[object String]":return""+t==""+r;case"[object Number]":return+t!=+t?+r!=+r:0==+t?1/+t==1/r:+t==+r;case"[object Date]":case"[object Boolean]":return+t==+r;case"[object Symbol]":return F.valueOf.call(t)===F.valueOf.call(r);case"[object ArrayBuffer]":case bn:return n(gn(t),gn(r),e,u)}o="[object Array]"===o;if(!o&&vn(t)){var i=d(t);if(i!==d(r))return!1;if(t.buffer===r.buffer&&t.byteOffset===r.byteOffset)return!0;o=!0}if(!o){if("object"!=typeof t||"object"!=typeof r)return!1;var i=t.constructor,a=r.constructor;if(i!==a&&!(p(i)&&i instanceof i&&p(a)&&a instanceof a)&&"constructor"in t&&"constructor"in r)return!1}e=e||[];u=u||[];var f=e.length;for(;f--;)if(e[f]===t)return u[f]===r;e.push(t);u.push(r);if(o){if((f=t.length)!==r.length)return!1;for(;f--;)if(!mn(t[f],r[f],e,u))return!1}else{var c,l=b(t);if(f=l.length,b(r).length!==f)return!1;for(;f--;)if(c=l[f],!y(r,c)||!mn(t[c],r[c],e,u))return!1}e.pop();u.pop();return!0}(n,t,r,e))}function c(n){if(!o(n))return[];var t,r=[];for(t in n)r.push(t);return K&&yn(n,r),r}function jn(e){var u=g(e);return function(n){if(null==n)return!1;var t=c(n);if(g(t))return!1;for(var r=0;r<u;r++)if(!p(n[e[r]]))return!1;return e!==_n||!p(n[wn])}}var wn="forEach",t=["clear","delete"],u=["get","has","set"],U=t.concat(wn,u),_n=t.concat(u),r=["add"].concat(t,wn,"has"),u=a?jn(U):i("Map"),t=a?jn(_n):i("WeakMap"),U=a?jn(r):i("Set"),a=i("WeakSet");function j(n){for(var t=b(n),r=t.length,e=Array(r),u=0;u<r;u++)e[u]=n[t[u]];return e}function An(n){for(var t={},r=b(n),e=0,u=r.length;e<u;e++)t[n[r[e]]]=r[e];return t}function xn(n){var t,r=[];for(t in n)p(n[t])&&r.push(t);return r.sort()}function Sn(f,c){return function(n){var t=arguments.length;if(c&&(n=Object(n)),!(t<2||null==n))for(var r=1;r<t;r++)for(var e=arguments[r],u=f(e),o=u.length,i=0;i<o;i++){var a=u[i];c&&void 0!==n[a]||(n[a]=e[a])}return n}}var On=Sn(c),w=Sn(b),Mn=Sn(c,!0);function En(n){var t;return o(n)?z?z(n):((t=function(){}).prototype=n,n=new t,t.prototype=null,n):{}}function Bn(n){return v(n)?n:[n]}function _(n){return m.toPath(n)}function Nn(n,t){for(var r=t.length,e=0;e<r;e++){if(null==n)return;n=n[t[e]]}return r?n:void 0}function In(n,t,r){n=Nn(n,_(t));return H(n)?r:n}function Tn(n){return n}function A(t){return t=w({},t),function(n){return dn(n,t)}}function kn(t){return t=_(t),function(n){return Nn(n,t)}}function x(u,o,n){if(void 0===o)return u;switch(null==n?3:n){case 1:return function(n){return u.call(o,n)};case 3:return function(n,t,r){return u.call(o,n,t,r)};case 4:return function(n,t,r,e){return u.call(o,n,t,r,e)}}return function(){return u.apply(o,arguments)}}function Dn(n,t,r){return null==n?Tn:p(n)?x(n,t,r):(o(n)&&!v(n)?A:kn)(n)}function Rn(n,t){return Dn(n,t,1/0)}function S(n,t,r){return m.iteratee!==Rn?m.iteratee(n,t):Dn(n,t,r)}function Vn(){}function Fn(n,t){return null==t&&(t=n,n=0),n+Math.floor(Math.random()*(t-n+1))}m.toPath=Bn,m.iteratee=Rn;var O=Date.now||function(){return(new Date).getTime()};function Pn(t){function r(n){return t[n]}var n="(?:"+b(t).join("|")+")",e=RegExp(n),u=RegExp(n,"g");return function(n){return e.test(n=null==n?"":""+n)?n.replace(u,r):n}}var r={"&":"&amp;","<":"&lt;",">":"&gt;",'"':"&quot;","'":"&#x27;","`":"&#x60;"},qn=Pn(r),r=Pn(An(r)),Un=m.templateSettings={evaluate:/<%([\s\S]+?)%>/g,interpolate:/<%=([\s\S]+?)%>/g,escape:/<%-([\s\S]+?)%>/g},Wn=/(.)^/,zn={"'":"'","\\":"\\","\r":"r","\n":"n","\u2028":"u2028","\u2029":"u2029"},Ln=/\\|'|\r|\n|\u2028|\u2029/g;function $n(n){return"\\"+zn[n]}var Cn=/^\s*(\w|\$)+\s*$/;var Kn=0;function Jn(n,t,r,e,u){return e instanceof t?(e=En(n.prototype),o(t=n.apply(e,u))?t:e):n.apply(r,u)}var M=l(function(u,o){function i(){for(var n=0,t=o.length,r=Array(t),e=0;e<t;e++)r[e]=o[e]===a?arguments[n++]:o[e];for(;n<arguments.length;)r.push(arguments[n++]);return Jn(u,i,this,this,r)}var a=M.placeholder;return i}),Gn=(M.placeholder=m,l(function(t,r,e){var u;if(p(t))return u=l(function(n){return Jn(t,u,r,this,e.concat(n))});throw new TypeError("Bind must be called on a function")})),E=ln(g);function B(n,t,r,e){if(e=e||[],t||0===t){if(t<=0)return e.concat(n)}else t=1/0;for(var u=e.length,o=0,i=g(n);o<i;o++){var a=n[o];if(E(a)&&(v(a)||an(a)))if(1<t)B(a,t-1,r,e),u=e.length;else for(var f=0,c=a.length;f<c;)e[u++]=a[f++];else r||(e[u++]=a)}return e}var Hn=l(function(n,t){var r=(t=B(t,!1,!1)).length;if(r<1)throw new Error("bindAll must be passed function names");for(;r--;){var e=t[r];n[e]=Gn(n[e],n)}return n});var Qn=l(function(n,t,r){return setTimeout(function(){return n.apply(null,r)},t)}),Xn=M(Qn,m,1);function Yn(n){return function(){return!n.apply(this,arguments)}}function Zn(n,t){var r;return function(){return 0<--n&&(r=t.apply(this,arguments)),n<=1&&(t=null),r}}var nt=M(Zn,2);function tt(n,t,r){t=S(t,r);for(var e,u=b(n),o=0,i=u.length;o<i;o++)if(t(n[e=u[o]],e,n))return e}function rt(o){return function(n,t,r){t=S(t,r);for(var e=g(n),u=0<o?0:e-1;0<=u&&u<e;u+=o)if(t(n[u],u,n))return u;return-1}}var et=rt(1),ut=rt(-1);function ot(n,t,r,e){for(var u=(r=S(r,e,1))(t),o=0,i=g(n);o<i;){var a=Math.floor((o+i)/2);r(n[a])<u?o=a+1:i=a}return o}function it(o,i,a){return function(n,t,r){var e=0,u=g(n);if("number"==typeof r)0<o?e=0<=r?r:Math.max(r+u,e):u=0<=r?Math.min(r+1,u):r+u+1;else if(a&&r&&u)return n[r=a(n,t)]===t?r:-1;if(t!=t)return 0<=(r=i(f.call(n,e,u),fn))?r+e:-1;for(r=0<o?e:u-1;0<=r&&r<u;r+=o)if(n[r]===t)return r;return-1}}var at=it(1,et,ot),ft=it(-1,ut);function ct(n,t,r){t=(E(n)?et:tt)(n,t,r);if(void 0!==t&&-1!==t)return n[t]}function N(n,t,r){if(t=x(t,r),E(n))for(u=0,o=n.length;u<o;u++)t(n[u],u,n);else for(var e=b(n),u=0,o=e.length;u<o;u++)t(n[e[u]],e[u],n);return n}function I(n,t,r){t=S(t,r);for(var e=!E(n)&&b(n),u=(e||n).length,o=Array(u),i=0;i<u;i++){var a=e?e[i]:i;o[i]=t(n[a],a,n)}return o}function lt(f){return function(n,t,r,e){var u=3<=arguments.length;return function(n,t,r,e){var u=!E(n)&&b(n),o=(u||n).length,i=0<f?0:o-1;for(e||(r=n[u?u[i]:i],i+=f);0<=i&&i<o;i+=f){var a=u?u[i]:i;r=t(r,n[a],a,n)}return r}(n,x(t,e,4),r,u)}}var st=lt(1),pt=lt(-1);function T(n,e,t){var u=[];return e=S(e,t),N(n,function(n,t,r){e(n,t,r)&&u.push(n)}),u}function ht(n,t,r){t=S(t,r);for(var e=!E(n)&&b(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(!t(n[i],i,n))return!1}return!0}function vt(n,t,r){t=S(t,r);for(var e=!E(n)&&b(n),u=(e||n).length,o=0;o<u;o++){var i=e?e[o]:o;if(t(n[i],i,n))return!0}return!1}function k(n,t,r,e){return E(n)||(n=j(n)),0<=at(n,t,r="number"==typeof r&&!e?r:0)}var yt=l(function(n,r,e){var u,o;return p(r)?o=r:(r=_(r),u=r.slice(0,-1),r=r[r.length-1]),I(n,function(n){var t=o;if(!t){if(null==(n=u&&u.length?Nn(n,u):n))return;t=n[r]}return null==t?t:t.apply(n,e)})});function dt(n,t){return I(n,kn(t))}function gt(n,e,t){var r,u,o=-1/0,i=-1/0;if(null==e||"number"==typeof e&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=E(n)?n:j(n)).length;a<f;a++)null!=(r=n[a])&&o<r&&(o=r);else e=S(e,t),N(n,function(n,t,r){u=e(n,t,r),(i<u||u===-1/0&&o===-1/0)&&(o=n,i=u)});return o}var bt=/[^\ud800-\udfff]|[\ud800-\udbff][\udc00-\udfff]|[\ud800-\udfff]/g;function mt(n){return n?v(n)?f.call(n):X(n)?n.match(bt):E(n)?I(n,Tn):j(n):[]}function jt(n,t,r){if(null==t||r)return(n=E(n)?n:j(n))[Fn(n.length-1)];for(var e=mt(n),r=g(e),u=(t=Math.max(Math.min(t,r),0),r-1),o=0;o<t;o++){var i=Fn(o,u),a=e[o];e[o]=e[i],e[i]=a}return e.slice(0,t)}function D(o,t){return function(r,e,n){var u=t?[[],[]]:{};return e=S(e,n),N(r,function(n,t){t=e(n,t,r);o(u,n,t)}),u}}var wt=D(function(n,t,r){y(n,r)?n[r].push(t):n[r]=[t]}),_t=D(function(n,t,r){n[r]=t}),At=D(function(n,t,r){y(n,r)?n[r]++:n[r]=1}),xt=D(function(n,t,r){n[r?0:1].push(t)},!0);function St(n,t,r){return t in r}var Ot=l(function(n,t){var r={},e=t[0];if(null!=n){p(e)?(1<t.length&&(e=x(e,t[1])),t=c(n)):(e=St,t=B(t,!1,!1),n=Object(n));for(var u=0,o=t.length;u<o;u++){var i=t[u],a=n[i];e(a,i,n)&&(r[i]=a)}}return r}),Mt=l(function(n,r){var t,e=r[0];return p(e)?(e=Yn(e),1<r.length&&(t=r[1])):(r=I(B(r,!1,!1),String),e=function(n,t){return!k(r,t)}),Ot(n,e,t)});function Et(n,t,r){return f.call(n,0,Math.max(0,n.length-(null==t||r?1:t)))}function Bt(n,t,r){return null==n||n.length<1?null==t||r?void 0:[]:null==t||r?n[0]:Et(n,n.length-t)}function R(n,t,r){return f.call(n,null==t||r?1:t)}var Nt=l(function(n,t){return t=B(t,!0,!0),T(n,function(n){return!k(t,n)})}),It=l(function(n,t){return Nt(n,t)});function Tt(n,t,r,e){Q(t)||(e=r,r=t,t=!1),null!=r&&(r=S(r,e));for(var u=[],o=[],i=0,a=g(n);i<a;i++){var f=n[i],c=r?r(f,i,n):f;t&&!r?(i&&o===c||u.push(f),o=c):r?k(o,c)||(o.push(c),u.push(f)):k(u,f)||u.push(f)}return u}var kt=l(function(n){return Tt(B(n,!0,!0))});function Dt(n){for(var t=n&&gt(n,g).length||0,r=Array(t),e=0;e<t;e++)r[e]=dt(n,e);return r}var Rt=l(Dt);function Vt(n,t){return n._chain?m(t).chain():t}function Ft(r){return N(xn(r),function(n){var t=m[n]=r[n];m.prototype[n]=function(){var n=[this._wrapped];return P.apply(n,arguments),Vt(this,t.apply(m,n))}}),m}N(["pop","push","reverse","shift","sort","splice","unshift"],function(t){var r=e[t];m.prototype[t]=function(){var n=this._wrapped;return null!=n&&(r.apply(n,arguments),"shift"!==t&&"splice"!==t||0!==n.length||delete n[0]),Vt(this,n)}}),N(["concat","join","slice"],function(n){var t=e[n];m.prototype[n]=function(){var n=this._wrapped;return Vt(this,n=null!=n?t.apply(n,arguments):n)}});n=Ft({__proto__:null,VERSION:n,restArguments:l,isObject:o,isNull:function(n){return null===n},isUndefined:H,isBoolean:Q,isElement:function(n){return!(!n||1!==n.nodeType)},isString:X,isNumber:Y,isDate:Z,isRegExp:nn,isError:tn,isSymbol:rn,isArrayBuffer:en,isDataView:h,isArray:v,isFunction:p,isArguments:an,isFinite:function(n){return!rn(n)&&C(n)&&!isNaN(parseFloat(n))},isNaN:fn,isTypedArray:vn,isEmpty:function(n){var t;return null==n||("number"==typeof(t=g(n))&&(v(n)||X(n)||an(n))?0===t:0===g(b(n)))},isMatch:dn,isEqual:function(n,t){return mn(n,t)},isMap:u,isWeakMap:t,isSet:U,isWeakSet:a,keys:b,allKeys:c,values:j,pairs:function(n){for(var t=b(n),r=t.length,e=Array(r),u=0;u<r;u++)e[u]=[t[u],n[t[u]]];return e},invert:An,functions:xn,methods:xn,extend:On,extendOwn:w,assign:w,defaults:Mn,create:function(n,t){return n=En(n),t&&w(n,t),n},clone:function(n){return o(n)?v(n)?n.slice():On({},n):n},tap:function(n,t){return t(n),n},get:In,has:function(n,t){for(var r=(t=_(t)).length,e=0;e<r;e++){var u=t[e];if(!y(n,u))return!1;n=n[u]}return!!r},mapObject:function(n,t,r){t=S(t,r);for(var e=b(n),u=e.length,o={},i=0;i<u;i++){var a=e[i];o[a]=t(n[a],a,n)}return o},identity:Tn,constant:cn,noop:Vn,toPath:Bn,property:kn,propertyOf:function(t){return null==t?Vn:function(n){return In(t,n)}},matcher:A,matches:A,times:function(n,t,r){var e=Array(Math.max(0,n));t=x(t,r,1);for(var u=0;u<n;u++)e[u]=t(u);return e},random:Fn,now:O,escape:qn,unescape:r,templateSettings:Un,template:function(o,n,t){n=Mn({},n=!n&&t?t:n,m.templateSettings);var r,t=RegExp([(n.escape||Wn).source,(n.interpolate||Wn).source,(n.evaluate||Wn).source].join("|")+"|$","g"),i=0,a="__p+='";if(o.replace(t,function(n,t,r,e,u){return a+=o.slice(i,u).replace(Ln,$n),i=u+n.length,t?a+="'+\n((__t=("+t+"))==null?'':_.escape(__t))+\n'":r?a+="'+\n((__t=("+r+"))==null?'':__t)+\n'":e&&(a+="';\n"+e+"\n__p+='"),n}),a+="';\n",t=n.variable){if(!Cn.test(t))throw new Error("variable is not a bare identifier: "+t)}else a="with(obj||{}){\n"+a+"}\n",t="obj";a="var __t,__p='',__j=Array.prototype.join,print=function(){__p+=__j.call(arguments,'');};\n"+a+"return __p;\n";try{r=new Function(t,"_",a)}catch(n){throw n.source=a,n}function e(n){return r.call(this,n,m)}return e.source="function("+t+"){\n"+a+"}",e},result:function(n,t,r){var e=(t=_(t)).length;if(!e)return p(r)?r.call(n):r;for(var u=0;u<e;u++){var o=null==n?void 0:n[t[u]];void 0===o&&(o=r,u=e),n=p(o)?o.call(n):o}return n},uniqueId:function(n){var t=++Kn+"";return n?n+t:t},chain:function(n){return(n=m(n))._chain=!0,n},iteratee:Rn,partial:M,bind:Gn,bindAll:Hn,memoize:function(e,u){function o(n){var t=o.cache,r=""+(u?u.apply(this,arguments):n);return y(t,r)||(t[r]=e.apply(this,arguments)),t[r]}return o.cache={},o},delay:Qn,defer:Xn,throttle:function(r,e,u){function o(){l=!1===u.leading?0:O(),i=null,c=r.apply(a,f),i||(a=f=null)}function n(){var n=O(),t=(l||!1!==u.leading||(l=n),e-(n-l));return a=this,f=arguments,t<=0||e<t?(i&&(clearTimeout(i),i=null),l=n,c=r.apply(a,f),i||(a=f=null)):i||!1===u.trailing||(i=setTimeout(o,t)),c}var i,a,f,c,l=0;return u=u||{},n.cancel=function(){clearTimeout(i),l=0,i=a=f=null},n},debounce:function(t,r,e){function u(){var n=O()-i;n<r?o=setTimeout(u,r-n):(o=null,e||(f=t.apply(c,a)),o||(a=c=null))}var o,i,a,f,c,n=l(function(n){return c=this,a=n,i=O(),o||(o=setTimeout(u,r),e&&(f=t.apply(c,a))),f});return n.cancel=function(){clearTimeout(o),o=a=c=null},n},wrap:function(n,t){return M(t,n)},negate:Yn,compose:function(){var r=arguments,e=r.length-1;return function(){for(var n=e,t=r[e].apply(this,arguments);n--;)t=r[n].call(this,t);return t}},after:function(n,t){return function(){if(--n<1)return t.apply(this,arguments)}},before:Zn,once:nt,findKey:tt,findIndex:et,findLastIndex:ut,sortedIndex:ot,indexOf:at,lastIndexOf:ft,find:ct,detect:ct,findWhere:function(n,t){return ct(n,A(t))},each:N,forEach:N,map:I,collect:I,reduce:st,foldl:st,inject:st,reduceRight:pt,foldr:pt,filter:T,select:T,reject:function(n,t,r){return T(n,Yn(S(t)),r)},every:ht,all:ht,some:vt,any:vt,contains:k,includes:k,include:k,invoke:yt,pluck:dt,where:function(n,t){return T(n,A(t))},max:gt,min:function(n,e,t){var r,u,o=1/0,i=1/0;if(null==e||"number"==typeof e&&"object"!=typeof n[0]&&null!=n)for(var a=0,f=(n=E(n)?n:j(n)).length;a<f;a++)null!=(r=n[a])&&r<o&&(o=r);else e=S(e,t),N(n,function(n,t,r){((u=e(n,t,r))<i||u===1/0&&o===1/0)&&(o=n,i=u)});return o},shuffle:function(n){return jt(n,1/0)},sample:jt,sortBy:function(n,e,t){var u=0;return e=S(e,t),dt(I(n,function(n,t,r){return{value:n,index:u++,criteria:e(n,t,r)}}).sort(function(n,t){var r=n.criteria,e=t.criteria;if(r!==e){if(e<r||void 0===r)return 1;if(r<e||void 0===e)return-1}return n.index-t.index}),"value")},groupBy:wt,indexBy:_t,countBy:At,partition:xt,toArray:mt,size:function(n){return null==n?0:(E(n)?n:b(n)).length},pick:Ot,omit:Mt,first:Bt,head:Bt,take:Bt,initial:Et,last:function(n,t,r){return null==n||n.length<1?null==t||r?void 0:[]:null==t||r?n[n.length-1]:R(n,Math.max(0,n.length-t))},rest:R,tail:R,drop:R,compact:function(n){return T(n,Boolean)},flatten:function(n,t){return B(n,t,!1)},without:It,uniq:Tt,unique:Tt,union:kt,intersection:function(n){for(var t=[],r=arguments.length,e=0,u=g(n);e<u;e++){var o=n[e];if(!k(t,o)){for(var i=1;i<r&&k(arguments[i],o);i++);i===r&&t.push(o)}}return t},difference:Nt,unzip:Dt,transpose:Dt,zip:Rt,object:function(n,t){for(var r={},e=0,u=g(n);e<u;e++)t?r[n[e]]=t[e]:r[n[e][0]]=n[e][1];return r},range:function(n,t,r){null==t&&(t=n||0,n=0),r=r||(t<n?-1:1);for(var e=Math.max(Math.ceil((t-n)/r),0),u=Array(e),o=0;o<e;o++,n+=r)u[o]=n;return u},chunk:function(n,t){if(null==t||t<1)return[];for(var r=[],e=0,u=n.length;e<u;)r.push(f.call(n,e,e+=t));return r},mixin:Ft,default:m});return n._=n});
// source --> https://einhausfuerklaus.de/wp-content/plugins/responsive-lightbox/assets/infinitescroll/infinite-scroll.pkgd.js?ver=4.0.1 
/*!
 * Infinite Scroll PACKAGED v5.0.0
 * Automatically add next page
 * MIT License
 * https://infinite-scroll.com
 * Copyright 2018-2025 Metafizzy
 */

/**
 * Bridget makes jQuery widgets
 * v3.0.0
 * MIT license
 */

( function( window, factory ) {
  // module definition
 if ( typeof module == 'object' && module.exports ) {
   // CommonJS
   module.exports = factory(
       window,
       require('jquery'),
   );
 } else {
   // browser global
   window.jQueryBridget = factory(
       window,
       window.jQuery,
   );
 }

}( window, function factory( window, jQuery ) {

// ----- utils ----- //

// helper function for logging errors
// $.error breaks jQuery chaining
let console = window.console;
let logError = typeof console == 'undefined' ? function() {} :
  function( message ) {
    console.error( message );
  };

// ----- jQueryBridget ----- //

function jQueryBridget( namespace, PluginClass, $ ) {
  $ = $ || jQuery || window.jQuery;
  if ( !$ ) {
    return;
  }

  // add option method -> $().plugin('option', {...})
  if ( !PluginClass.prototype.option ) {
    // option setter
    PluginClass.prototype.option = function( opts ) {
      if ( !opts ) return;

      this.options = Object.assign( this.options || {}, opts );
    };
  }

  // make jQuery plugin
  $.fn[ namespace ] = function( arg0, ...args ) {
    if ( typeof arg0 == 'string' ) {
      // method call $().plugin( 'methodName', { options } )
      return methodCall( this, arg0, args );
    }
    // just $().plugin({ options })
    plainCall( this, arg0 );
    return this;
  };

  // $().plugin('methodName')
  function methodCall( $elems, methodName, args ) {
    let returnValue;
    let pluginMethodStr = `$().${namespace}("${methodName}")`;

    $elems.each( function( i, elem ) {
      // get instance
      let instance = $.data( elem, namespace );
      if ( !instance ) {
        logError( `${namespace} not initialized.` +
          ` Cannot call method ${pluginMethodStr}` );
        return;
      }

      let method = instance[ methodName ];
      if ( !method || methodName.charAt( 0 ) == '_' ) {
        logError(`${pluginMethodStr} is not a valid method`);
        return;
      }

      // apply method, get return value
      let value = method.apply( instance, args );
      // set return value if value is returned, use only first value
      returnValue = returnValue === undefined ? value : returnValue;
    } );

    return returnValue !== undefined ? returnValue : $elems;
  }

  function plainCall( $elems, options ) {
    $elems.each( function( i, elem ) {
      let instance = $.data( elem, namespace );
      if ( instance ) {
        // set options & init
        instance.option( options );
        instance._init();
      } else {
        // initialize new instance
        instance = new PluginClass( elem, options );
        $.data( elem, namespace, instance );
      }
    } );
  }

}

// -----  ----- //

return jQueryBridget;

} ) );
/**
 * EvEmitter v2.0.0
 * Lil' event emitter
 * MIT License
 */

( function( global, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS - Browserify, Webpack
    module.exports = factory();
  } else {
    // Browser globals
    global.EvEmitter = factory();
  }

}( typeof window != 'undefined' ? window : this, function() {

function EvEmitter() {}

let proto = EvEmitter.prototype;

proto.on = function( eventName, listener ) {
  if ( !eventName || !listener ) return this;

  // set events hash
  let events = this._events = this._events || {};
  // set listeners array
  let listeners = events[ eventName ] = events[ eventName ] || [];
  // only add once
  if ( !listeners.includes( listener ) ) {
    listeners.push( listener );
  }

  return this;
};

proto.once = function( eventName, listener ) {
  if ( !eventName || !listener ) return this;

  // add event
  this.on( eventName, listener );
  // set once flag
  // set onceEvents hash
  let onceEvents = this._onceEvents = this._onceEvents || {};
  // set onceListeners object
  let onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
  // set flag
  onceListeners[ listener ] = true;

  return this;
};

proto.off = function( eventName, listener ) {
  let listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) return this;

  let index = listeners.indexOf( listener );
  if ( index != -1 ) {
    listeners.splice( index, 1 );
  }

  return this;
};

proto.emitEvent = function( eventName, args ) {
  let listeners = this._events && this._events[ eventName ];
  if ( !listeners || !listeners.length ) return this;

  // copy over to avoid interference if .off() in listener
  listeners = listeners.slice( 0 );
  args = args || [];
  // once stuff
  let onceListeners = this._onceEvents && this._onceEvents[ eventName ];

  for ( let listener of listeners ) {
    let isOnce = onceListeners && onceListeners[ listener ];
    if ( isOnce ) {
      // remove listener
      // remove before trigger to prevent recursion
      this.off( eventName, listener );
      // unset once flag
      delete onceListeners[ listener ];
    }
    // trigger listener
    listener.apply( this, args );
  }

  return this;
};

proto.allOff = function() {
  delete this._events;
  delete this._onceEvents;
  return this;
};

return EvEmitter;

} ) );
/**
 * Fizzy UI utils v3.0.0
 * MIT license
 */

( function( global, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory( global );
  } else {
    // browser global
    global.fizzyUIUtils = factory( global );
  }

}( this, function factory( global ) {

let utils = {};

// ----- extend ----- //

// extends objects
utils.extend = function( a, b ) {
  return Object.assign( a, b );
};

// ----- modulo ----- //

utils.modulo = function( num, div ) {
  return ( ( num % div ) + div ) % div;
};

// ----- makeArray ----- //

// turn element or nodeList into an array
utils.makeArray = function( obj ) {
  // use object if already an array
  if ( Array.isArray( obj ) ) return obj;

  // return empty array if undefined or null. #6
  if ( obj === null || obj === undefined ) return [];

  let isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
  // convert nodeList to array
  if ( isArrayLike ) return [ ...obj ];

  // array of single index
  return [ obj ];
};

// ----- removeFrom ----- //

utils.removeFrom = function( ary, obj ) {
  let index = ary.indexOf( obj );
  if ( index != -1 ) {
    ary.splice( index, 1 );
  }
};

// ----- getParent ----- //

utils.getParent = function( elem, selector ) {
  while ( elem.parentNode && elem != document.body ) {
    elem = elem.parentNode;
    if ( elem.matches( selector ) ) return elem;
  }
};

// ----- getQueryElement ----- //

// use element as selector string
utils.getQueryElement = function( elem ) {
  if ( typeof elem == 'string' ) {
    return document.querySelector( elem );
  }
  return elem;
};

// ----- handleEvent ----- //

// enable .ontype to trigger from .addEventListener( elem, 'type' )
utils.handleEvent = function( event ) {
  let method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

// ----- filterFindElements ----- //

utils.filterFindElements = function( elems, selector ) {
  // make array of elems
  elems = utils.makeArray( elems );

  return elems
    // check that elem is an actual element
    .filter( ( elem ) => elem instanceof HTMLElement )
    .reduce( ( ffElems, elem ) => {
      // add elem if no selector
      if ( !selector ) {
        ffElems.push( elem );
        return ffElems;
      }
      // filter & find items if we have a selector
      // filter
      if ( elem.matches( selector ) ) {
        ffElems.push( elem );
      }
      // find children
      let childElems = elem.querySelectorAll( selector );
      // concat childElems to filterFound array
      ffElems = ffElems.concat( ...childElems );
      return ffElems;
    }, [] );
};

// ----- debounceMethod ----- //

utils.debounceMethod = function( _class, methodName, threshold ) {
  threshold = threshold || 100;
  // original method
  let method = _class.prototype[ methodName ];
  let timeoutName = methodName + 'Timeout';

  _class.prototype[ methodName ] = function() {
    clearTimeout( this[ timeoutName ] );

    let args = arguments;
    this[ timeoutName ] = setTimeout( () => {
      method.apply( this, args );
      delete this[ timeoutName ];
    }, threshold );
  };
};

// ----- docReady ----- //

utils.docReady = function( onDocReady ) {
  let readyState = document.readyState;
  if ( readyState == 'complete' || readyState == 'interactive' ) {
    // do async to allow for other scripts to run. metafizzy/flickity#441
    setTimeout( onDocReady );
  } else {
    document.addEventListener( 'DOMContentLoaded', onDocReady );
  }
};

// ----- htmlInit ----- //

// http://bit.ly/3oYLusc
utils.toDashed = function( str ) {
  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
    return $1 + '-' + $2;
  } ).toLowerCase();
};

let console = global.console;

// allow user to initialize classes via [data-namespace] or .js-namespace class
// htmlInit( Widget, 'widgetName' )
// options are parsed from data-namespace-options
utils.htmlInit = function( WidgetClass, namespace ) {
  utils.docReady( function() {
    let dashedNamespace = utils.toDashed( namespace );
    let dataAttr = 'data-' + dashedNamespace;
    let dataAttrElems = document.querySelectorAll( `[${dataAttr}]` );
    let jQuery = global.jQuery;

    [ ...dataAttrElems ].forEach( ( elem ) => {
      let attr = elem.getAttribute( dataAttr );
      let options;
      try {
        options = attr && JSON.parse( attr );
      } catch ( error ) {
        // log error, do not initialize
        if ( console ) {
          console.error( `Error parsing ${dataAttr} on ${elem.className}: ${error}` );
        }
        return;
      }
      // initialize
      let instance = new WidgetClass( elem, options );
      // make available via $().data('namespace')
      if ( jQuery ) {
        jQuery.data( elem, namespace, instance );
      }
    } );

  } );
};

// -----  ----- //

return utils;

} ) );
// core
( function( window, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
        window,
        require('ev-emitter'),
        require('fizzy-ui-utils'),
    );
  } else {
    // browser global
    window.InfiniteScroll = factory(
        window,
        window.EvEmitter,
        window.fizzyUIUtils,
    );
  }

}( window, function factory( window, EvEmitter, utils ) {

let jQuery = window.jQuery;
// internal store of all InfiniteScroll intances
let instances = {};

function InfiniteScroll( element, options ) {
  let queryElem = utils.getQueryElement( element );

  if ( !queryElem ) {
    console.error( 'Bad element for InfiniteScroll: ' + ( queryElem || element ) );
    return;
  }
  element = queryElem;
  // do not initialize twice on same element
  if ( element.infiniteScrollGUID ) {
    let instance = instances[ element.infiniteScrollGUID ];
    instance.option( options );
    return instance;
  }

  this.element = element;
  // options
  this.options = { ...InfiniteScroll.defaults };
  this.option( options );
  // add jQuery
  if ( jQuery ) {
    this.$element = jQuery( this.element );
  }

  this.create();
}

// defaults
InfiniteScroll.defaults = {
  // path: null,
  // hideNav: null,
  // debug: false,
};

// create & destroy methods
InfiniteScroll.create = {};
InfiniteScroll.destroy = {};

let proto = InfiniteScroll.prototype;
// inherit EvEmitter
Object.assign( proto, EvEmitter.prototype );

// --------------------------  -------------------------- //

// globally unique identifiers
let GUID = 0;

proto.create = function() {
  // create core
  // add id for InfiniteScroll.data
  let id = this.guid = ++GUID;
  this.element.infiniteScrollGUID = id; // expando
  instances[ id ] = this; // associate via id
  // properties
  this.pageIndex = 1; // default to first page
  this.loadCount = 0;
  this.updateGetPath();
  // bail if getPath not set, or returns falsey #776
  let hasPath = this.getPath && this.getPath();
  if ( !hasPath ) {
    console.error('Disabling InfiniteScroll');
    return;
  }
  this.updateGetAbsolutePath();
  this.log( 'initialized', [ this.element.className ] );
  this.callOnInit();
  // create features
  for ( let method in InfiniteScroll.create ) {
    InfiniteScroll.create[ method ].call( this );
  }
};

proto.option = function( opts ) {
  Object.assign( this.options, opts );
};

// call onInit option, used for binding events on init
proto.callOnInit = function() {
  let onInit = this.options.onInit;
  if ( onInit ) {
    onInit.call( this, this );
  }
};

// ----- events ----- //

proto.dispatchEvent = function( type, event, args ) {
  this.log( type, args );
  let emitArgs = event ? [ event ].concat( args ) : args;
  this.emitEvent( type, emitArgs );
  // trigger jQuery event
  if ( !jQuery || !this.$element ) {
    return;
  }
  // namespace jQuery event
  type += '.infiniteScroll';
  let $event = type;
  if ( event ) {
    // create jQuery event
    /* eslint-disable-next-line new-cap */
    let jQEvent = jQuery.Event( event );
    jQEvent.type = type;
    $event = jQEvent;
  }
  this.$element.trigger( $event, args );
};

let loggers = {
  initialized: ( className ) => `on ${className}`,
  request: ( path ) => `URL: ${path}`,
  load: ( response, path ) => `${response.title || ''}. URL: ${path}`,
  error: ( error, path ) => `${error}. URL: ${path}`,
  append: ( response, path, items ) => `${items.length} items. URL: ${path}`,
  last: ( response, path ) => `URL: ${path}`,
  history: ( title, path ) => `URL: ${path}`,
  pageIndex: function( index, origin ) {
    return `current page determined to be: ${index} from ${origin}`;
  },
};

// log events
proto.log = function( type, args ) {
  if ( !this.options.debug ) return;

  let message = `[InfiniteScroll] ${type}`;
  let logger = loggers[ type ];
  if ( logger ) message += '. ' + logger.apply( this, args );
  console.log( message );
};

// -------------------------- methods used amoung features -------------------------- //

proto.updateMeasurements = function() {
  this.windowHeight = window.innerHeight;
  let rect = this.element.getBoundingClientRect();
  this.top = rect.top + window.scrollY;
};

proto.updateScroller = function() {
  let elementScroll = this.options.elementScroll;
  if ( !elementScroll ) {
    // default, use window
    this.scroller = window;
    return;
  }
  // if true, set to element, otherwise use option
  this.scroller = elementScroll === true ? this.element :
    utils.getQueryElement( elementScroll );
  if ( !this.scroller ) {
    throw new Error(`Unable to find elementScroll: ${elementScroll}`);
  }
};

// -------------------------- page path -------------------------- //

proto.updateGetPath = function() {
  let optPath = this.options.path;
  if ( !optPath ) {
    console.error(`InfiniteScroll path option required. Set as: ${optPath}`);
    return;
  }
  // function
  let type = typeof optPath;
  if ( type == 'function' ) {
    this.getPath = optPath;
    return;
  }
  // template string: '/pages/{{#}}.html'
  let templateMatch = type == 'string' && optPath.match('{{#}}');
  if ( templateMatch ) {
    this.updateGetPathTemplate( optPath );
    return;
  }
  // selector: '.next-page-selector'
  this.updateGetPathSelector( optPath );
};

proto.updateGetPathTemplate = function( optPath ) {
  // set getPath with template string
  this.getPath = () => {
    let nextIndex = this.pageIndex + 1;
    return optPath.replace( '{{#}}', nextIndex );
  };
  // get pageIndex from location
  // convert path option into regex to look for pattern in location
  // escape query (?) in url, allows for parsing GET parameters
  let regexString = optPath
    .replace( /(\\\?|\?)/, '\\?' )
    .replace( '{{#}}', '(\\d\\d?\\d?)' );
  let templateRe = new RegExp( regexString );
  let match = location.href.match( templateRe );

  if ( match ) {
    this.pageIndex = parseInt( match[1], 10 );
    this.log( 'pageIndex', [ this.pageIndex, 'template string' ] );
  }
};

let pathRegexes = [
  // WordPress & Tumblr - example.com/page/2
  // Jekyll - example.com/page2
  /^(.*?\/?page\/?)(\d\d?\d?)(.*?$)/,
  // Drupal - example.com/?page=1
  /^(.*?\/?\?page=)(\d\d?\d?)(.*?$)/,
  // catch all, last occurence of a number
  /(.*?)(\d\d?\d?)(?!.*\d)(.*?$)/,
];

// try matching href to pathRegexes patterns
let getPathParts = InfiniteScroll.getPathParts = function( href ) {
  if ( !href ) return;
  for ( let regex of pathRegexes ) {
    let match = href.match( regex );
    if ( match ) {
      let [ , begin, index, end ] = match;
      return { begin, index, end };
    }
  }
};

proto.updateGetPathSelector = function( optPath ) {
  // parse href of link: '.next-page-link'
  let hrefElem = document.querySelector( optPath );
  if ( !hrefElem ) {
    console.error(`Bad InfiniteScroll path option. Next link not found: ${optPath}`);
    return;
  }

  let href = hrefElem.getAttribute('href');
  let pathParts = getPathParts( href );
  if ( !pathParts ) {
    console.error(`InfiniteScroll unable to parse next link href: ${href}`);
    return;
  }

  let { begin, index, end } = pathParts;
  this.isPathSelector = true; // flag for checkLastPage()
  this.getPath = () => begin + ( this.pageIndex + 1 ) + end;
  // get pageIndex from href
  this.pageIndex = parseInt( index, 10 ) - 1;
  this.log( 'pageIndex', [ this.pageIndex, 'next link' ] );
};

proto.updateGetAbsolutePath = function() {
  let path = this.getPath();
  // path doesn't start with http or /
  let isAbsolute = path.match( /^http/ ) || path.match( /^\// );
  if ( isAbsolute ) {
    this.getAbsolutePath = this.getPath;
    return;
  }

  let { pathname } = location;
  // query parameter #829. example.com/?pg=2
  let isQuery = path.match( /^\?/ );
  // /foo/bar/index.html => /foo/bar
  let directory = pathname.substring( 0, pathname.lastIndexOf('/') );
  let pathStart = isQuery ? pathname : directory + '/';

  this.getAbsolutePath = () => pathStart + this.getPath();
};

// -------------------------- nav -------------------------- //

// hide navigation
InfiniteScroll.create.hideNav = function() {
  let nav = utils.getQueryElement( this.options.hideNav );
  if ( !nav ) return;

  nav.style.display = 'none';
  this.nav = nav;
};

InfiniteScroll.destroy.hideNav = function() {
  if ( this.nav ) this.nav.style.display = '';
};

// -------------------------- destroy -------------------------- //

proto.destroy = function() {
  this.allOff(); // remove all event listeners
  // call destroy methods
  for ( let method in InfiniteScroll.destroy ) {
    InfiniteScroll.destroy[ method ].call( this );
  }

  delete this.element.infiniteScrollGUID;
  delete instances[ this.guid ];
  // remove jQuery data. #807
  if ( jQuery && this.$element ) {
    jQuery.removeData( this.element, 'infiniteScroll' );
  }
};

// -------------------------- utilities -------------------------- //

// https://remysharp.com/2010/07/21/throttling-function-calls
InfiniteScroll.throttle = function( fn, threshold ) {
  threshold = threshold || 200;
  let last, timeout;

  return function() {
    let now = +new Date();
    let args = arguments;
    let trigger = () => {
      last = now;
      fn.apply( this, args );
    };
    if ( last && now < last + threshold ) {
      // hold on to it
      clearTimeout( timeout );
      timeout = setTimeout( trigger, threshold );
    } else {
      trigger();
    }
  };
};

InfiniteScroll.data = function( elem ) {
  elem = utils.getQueryElement( elem );
  let id = elem && elem.infiniteScrollGUID;
  return id && instances[ id ];
};

// set internal jQuery, for Webpack + jQuery v3
InfiniteScroll.setJQuery = function( jqry ) {
  jQuery = jqry;
};

// -------------------------- setup -------------------------- //

utils.htmlInit( InfiniteScroll, 'infinite-scroll' );

// add noop _init method for jQuery Bridget. #768
proto._init = function() {};

let { jQueryBridget } = window;
if ( jQuery && jQueryBridget ) {
  jQueryBridget( 'infiniteScroll', InfiniteScroll, jQuery );
}

// --------------------------  -------------------------- //

return InfiniteScroll;

} ) );
// page-load
( function( window, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
        window,
        require('./core'),
    );
  } else {
    // browser global
    factory(
        window,
        window.InfiniteScroll,
    );
  }

}( window, function factory( window, InfiniteScroll ) {

let proto = InfiniteScroll.prototype;

Object.assign( InfiniteScroll.defaults, {
  // append: false,
  loadOnScroll: true,
  checkLastPage: true,
  responseBody: 'text',
  domParseResponse: true,
  // prefill: false,
  // outlayer: null,
} );

InfiniteScroll.create.pageLoad = function() {
  this.canLoad = true;
  this.on( 'scrollThreshold', this.onScrollThresholdLoad );
  this.on( 'load', this.checkLastPage );
  if ( this.options.outlayer ) {
    this.on( 'append', this.onAppendOutlayer );
  }
};

proto.onScrollThresholdLoad = function() {
  if ( this.options.loadOnScroll ) this.loadNextPage();
};

let domParser = new DOMParser();

proto.loadNextPage = function() {
  if ( this.isLoading || !this.canLoad ) return;

  let { responseBody, domParseResponse, fetchOptions } = this.options;
  let path = this.getAbsolutePath();
  this.isLoading = true;
  if ( typeof fetchOptions == 'function' ) fetchOptions = fetchOptions();

  let fetchPromise = fetch( path, fetchOptions )
    .then( ( response ) => {
      if ( !response.ok ) {
        let error = new Error( response.statusText );
        this.onPageError( error, path, response );
        return { response };
      }

      return response[ responseBody ]().then( ( body ) => {
        let canDomParse = responseBody == 'text' && domParseResponse;
        if ( canDomParse ) {
          body = domParser.parseFromString( body, 'text/html' );
        }
        if ( response.status == 204 ) {
          this.lastPageReached( body, path );
          return { body, response };
        } else {
          return this.onPageLoad( body, path, response );
        }
      } );
    } )
    .catch( ( error ) => {
      this.onPageError( error, path );
    } );

  this.dispatchEvent( 'request', null, [ path, fetchPromise ] );

  return fetchPromise;
};

proto.onPageLoad = function( body, path, response ) {
  // done loading if not appending
  if ( !this.options.append ) {
    this.isLoading = false;
  }
  this.pageIndex++;
  this.loadCount++;
  this.dispatchEvent( 'load', null, [ body, path, response ] );
  return this.appendNextPage( body, path, response );
};

proto.appendNextPage = function( body, path, response ) {
  let { append, responseBody, domParseResponse } = this.options;
  // do not append json
  let isDocument = responseBody == 'text' && domParseResponse;
  if ( !isDocument || !append ) return { body, response };

  let items = body.querySelectorAll( append );
  let promiseValue = { body, response, items };
  // last page hit if no items. #840
  if ( !items || !items.length ) {
    this.lastPageReached( body, path );
    return promiseValue;
  }

  let fragment = getItemsFragment( items );
  let appendReady = () => {
    this.appendItems( items, fragment );
    this.isLoading = false;
    this.dispatchEvent( 'append', null, [ body, path, items, response ] );
    return promiseValue;
  };

  // TODO add hook for option to trigger appendReady
  if ( this.options.outlayer ) {
    return this.appendOutlayerItems( fragment, appendReady );
  } else {
    return appendReady();
  }
};

proto.appendItems = function( items, fragment ) {
  if ( !items || !items.length ) return;

  // get fragment if not provided
  fragment = fragment || getItemsFragment( items );
  refreshScripts( fragment );
  this.element.appendChild( fragment );
};

function getItemsFragment( items ) {
  // add items to fragment
  let fragment = document.createDocumentFragment();
  if ( items ) fragment.append( ...items );
  return fragment;
}

// replace <script>s with copies so they load
// <script>s added by InfiniteScroll will not load
// similar to https://stackoverflow.com/questions/610995
function refreshScripts( fragment ) {
  let scripts = fragment.querySelectorAll('script');
  for ( let script of scripts ) {
    let freshScript = document.createElement('script');
    // copy attributes
    let attrs = script.attributes;
    for ( let attr of attrs ) {
      freshScript.setAttribute( attr.name, attr.value );
    }
    // copy inner script code. #718, #782
    freshScript.innerHTML = script.innerHTML;
    script.parentNode.replaceChild( freshScript, script );
  }
}

// ----- outlayer ----- //

proto.appendOutlayerItems = function( fragment, appendReady ) {
  let imagesLoaded = InfiniteScroll.imagesLoaded || window.imagesLoaded;
  if ( !imagesLoaded ) {
    console.error('[InfiniteScroll] imagesLoaded required for outlayer option');
    this.isLoading = false;
    return;
  }
  // append once images loaded
  return new Promise( function( resolve ) {
    imagesLoaded( fragment, function() {
      let bodyResponse = appendReady();
      resolve( bodyResponse );
    } );
  } );
};

proto.onAppendOutlayer = function( response, path, items ) {
  this.options.outlayer.appended( items );
};

// ----- checkLastPage ----- //

// check response for next element
proto.checkLastPage = function( body, path ) {
  let { checkLastPage, path: pathOpt } = this.options;
  if ( !checkLastPage ) return;

  // if path is function, check if next path is truthy
  if ( typeof pathOpt == 'function' ) {
    let nextPath = this.getPath();
    if ( !nextPath ) {
      this.lastPageReached( body, path );
      return;
    }
  }
  // get selector from checkLastPage or path option
  let selector;
  if ( typeof checkLastPage == 'string' ) {
    selector = checkLastPage;
  } else if ( this.isPathSelector ) {
    // path option is selector string
    selector = pathOpt;
  }
  // check last page for selector
  // bail if no selector or not document response
  if ( !selector || !body.querySelector ) return;

  // check if response has selector
  let nextElem = body.querySelector( selector );
  if ( !nextElem ) this.lastPageReached( body, path );
};

proto.lastPageReached = function( body, path ) {
  this.canLoad = false;
  this.dispatchEvent( 'last', null, [ body, path ] );
};

// ----- error ----- //

proto.onPageError = function( error, path, response ) {
  this.isLoading = false;
  this.canLoad = false;
  this.dispatchEvent( 'error', null, [ error, path, response ] );
  return error;
};

// -------------------------- prefill -------------------------- //

InfiniteScroll.create.prefill = function() {
  if ( !this.options.prefill ) return;

  let append = this.options.append;
  if ( !append ) {
    console.error(`append option required for prefill. Set as :${append}`);
    return;
  }
  this.updateMeasurements();
  this.updateScroller();
  this.isPrefilling = true;
  this.on( 'append', this.prefill );
  this.once( 'error', this.stopPrefill );
  this.once( 'last', this.stopPrefill );
  this.prefill();
};

proto.prefill = function() {
  let distance = this.getPrefillDistance();
  this.isPrefilling = distance >= 0;
  if ( this.isPrefilling ) {
    this.log('prefill');
    this.loadNextPage();
  } else {
    this.stopPrefill();
  }
};

proto.getPrefillDistance = function() {
  // element scroll
  if ( this.options.elementScroll ) {
    return this.scroller.clientHeight - this.scroller.scrollHeight;
  }
  // window
  return this.windowHeight - this.element.clientHeight;
};

proto.stopPrefill = function() {
  this.log('stopPrefill');
  this.off( 'append', this.prefill );
};

// --------------------------  -------------------------- //

return InfiniteScroll;

} ) );
// scroll-watch
( function( window, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
        window,
        require('./core'),
        require('fizzy-ui-utils'),
    );
  } else {
    // browser global
    factory(
        window,
        window.InfiniteScroll,
        window.fizzyUIUtils,
    );
  }

}( window, function factory( window, InfiniteScroll, utils ) {

let proto = InfiniteScroll.prototype;

// default options
Object.assign( InfiniteScroll.defaults, {
  scrollThreshold: 400,
  // elementScroll: null,
} );

InfiniteScroll.create.scrollWatch = function() {
  // events
  this.pageScrollHandler = this.onPageScroll.bind( this );
  this.resizeHandler = this.onResize.bind( this );

  let scrollThreshold = this.options.scrollThreshold;
  let isEnable = scrollThreshold || scrollThreshold === 0;
  if ( isEnable ) this.enableScrollWatch();
};

InfiniteScroll.destroy.scrollWatch = function() {
  this.disableScrollWatch();
};

proto.enableScrollWatch = function() {
  if ( this.isScrollWatching ) return;

  this.isScrollWatching = true;
  this.updateMeasurements();
  this.updateScroller();
  // TODO disable after error?
  this.on( 'last', this.disableScrollWatch );
  this.bindScrollWatchEvents( true );
};

proto.disableScrollWatch = function() {
  if ( !this.isScrollWatching ) return;

  this.bindScrollWatchEvents( false );
  delete this.isScrollWatching;
};

proto.bindScrollWatchEvents = function( isBind ) {
  let addRemove = isBind ? 'addEventListener' : 'removeEventListener';
  this.scroller[ addRemove ]( 'scroll', this.pageScrollHandler );
  window[ addRemove ]( 'resize', this.resizeHandler );
};

proto.onPageScroll = InfiniteScroll.throttle( function() {
  let distance = this.getBottomDistance();
  if ( distance <= this.options.scrollThreshold ) {
    this.dispatchEvent('scrollThreshold');
  }
} );

proto.getBottomDistance = function() {
  let bottom, scrollY;
  if ( this.options.elementScroll ) {
    bottom = this.scroller.scrollHeight;
    scrollY = this.scroller.scrollTop + this.scroller.clientHeight;
  } else {
    bottom = this.top + this.element.clientHeight;
    scrollY = window.scrollY + this.windowHeight;
  }
  return bottom - scrollY;
};

proto.onResize = function() {
  this.updateMeasurements();
};

utils.debounceMethod( InfiniteScroll, 'onResize', 150 );

// --------------------------  -------------------------- //

return InfiniteScroll;

} ) );
// history
( function( window, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
        window,
        require('./core'),
        require('fizzy-ui-utils'),
    );
  } else {
    // browser global
    factory(
        window,
        window.InfiniteScroll,
        window.fizzyUIUtils,
    );
  }

}( window, function factory( window, InfiniteScroll, utils ) {

let proto = InfiniteScroll.prototype;

Object.assign( InfiniteScroll.defaults, {
  history: 'replace',
  // historyTitle: false,
} );

let link = document.createElement('a');

// ----- create/destroy ----- //

InfiniteScroll.create.history = function() {
  if ( !this.options.history ) return;

  // check for same origin
  link.href = this.getAbsolutePath();
  // MS Edge does not have origin on link
  // https://developer.microsoft.com/en-us/microsoft-edge/platform/issues/12236493/
  let linkOrigin = link.origin || link.protocol + '//' + link.host;
  let isSameOrigin = linkOrigin == location.origin;
  if ( !isSameOrigin ) {
    console.error( '[InfiniteScroll] cannot set history with different origin: ' +
      `${link.origin} on ${location.origin} . History behavior disabled.` );
    return;
  }

  // two ways to handle changing history
  if ( this.options.append ) {
    this.createHistoryAppend();
  } else {
    this.createHistoryPageLoad();
  }
};

proto.createHistoryAppend = function() {
  this.updateMeasurements();
  this.updateScroller();
  // array of scroll positions of appended pages
  this.scrollPages = [
    // first page
    {
      top: 0,
      path: location.href,
      title: document.title,
    },
  ];
  this.scrollPage = this.scrollPages[0];
  // events
  this.scrollHistoryHandler = this.onScrollHistory.bind( this );
  this.unloadHandler = this.onUnload.bind( this );
  this.scroller.addEventListener( 'scroll', this.scrollHistoryHandler );
  this.on( 'append', this.onAppendHistory );
  this.bindHistoryAppendEvents( true );
};

proto.bindHistoryAppendEvents = function( isBind ) {
  let addRemove = isBind ? 'addEventListener' : 'removeEventListener';
  this.scroller[ addRemove ]( 'scroll', this.scrollHistoryHandler );
  window[ addRemove ]( 'unload', this.unloadHandler );
};

proto.createHistoryPageLoad = function() {
  this.on( 'load', this.onPageLoadHistory );
};

InfiniteScroll.destroy.history =
proto.destroyHistory = function() {
  let isHistoryAppend = this.options.history && this.options.append;
  if ( isHistoryAppend ) {
    this.bindHistoryAppendEvents( false );
  }
};

// ----- append history ----- //

proto.onAppendHistory = function( response, path, items ) {
  // do not proceed if no items. #779
  if ( !items || !items.length ) return;

  let firstItem = items[0];
  let elemScrollY = this.getElementScrollY( firstItem );
  // resolve path
  link.href = path;
  // add page data to hash
  this.scrollPages.push({
    top: elemScrollY,
    path: link.href,
    title: response.title,
  });
};

proto.getElementScrollY = function( elem ) {
  if ( this.options.elementScroll ) {
    return elem.offsetTop - this.top;
  } else {
    let rect = elem.getBoundingClientRect();
    return rect.top + window.scrollY;
  }
};

proto.onScrollHistory = function() {
  // cycle through positions, find biggest without going over
  let scrollPage = this.getClosestScrollPage();
  // set history if changed
  if ( scrollPage != this.scrollPage ) {
    this.scrollPage = scrollPage;
    this.setHistory( scrollPage.title, scrollPage.path );
  }
};

utils.debounceMethod( InfiniteScroll, 'onScrollHistory', 150 );

proto.getClosestScrollPage = function() {
  let scrollViewY;
  if ( this.options.elementScroll ) {
    scrollViewY = this.scroller.scrollTop + this.scroller.clientHeight / 2;
  } else {
    scrollViewY = window.scrollY + this.windowHeight / 2;
  }

  let scrollPage;
  for ( let page of this.scrollPages ) {
    if ( page.top >= scrollViewY ) break;

    scrollPage = page;
  }
  return scrollPage;
};

proto.setHistory = function( title, path ) {
  let optHistory = this.options.history;
  let historyMethod = optHistory && history[ optHistory + 'State' ];
  if ( !historyMethod ) return;

  history[ optHistory + 'State' ]( null, title, path );
  if ( this.options.historyTitle ) document.title = title;
  this.dispatchEvent( 'history', null, [ title, path ] );
};

// scroll to top to prevent initial scroll-reset after page refresh
// https://stackoverflow.com/a/18633915/182183
proto.onUnload = function() {
  if ( this.scrollPage.top === 0 ) return;

  // calculate where scroll position would be on refresh
  let scrollY = window.scrollY - this.scrollPage.top + this.top;
  // disable scroll event before setting scroll #679
  this.destroyHistory();
  scrollTo( 0, scrollY );
};

// ----- load history ----- //

// update URL
proto.onPageLoadHistory = function( response, path ) {
  this.setHistory( response.title, path );
};

// --------------------------  -------------------------- //

return InfiniteScroll;

} ) );
// button
( function( window, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
        window,
        require('./core'),
        require('fizzy-ui-utils'),
    );
  } else {
    // browser global
    factory(
        window,
        window.InfiniteScroll,
        window.fizzyUIUtils,
    );
  }

}( window, function factory( window, InfiniteScroll, utils ) {

// -------------------------- InfiniteScrollButton -------------------------- //

class InfiniteScrollButton {
  constructor( element, infScroll ) {
    this.element = element;
    this.infScroll = infScroll;
    // events
    this.clickHandler = this.onClick.bind( this );
    this.element.addEventListener( 'click', this.clickHandler );
    infScroll.on( 'request', this.disable.bind( this ) );
    infScroll.on( 'load', this.enable.bind( this ) );
    infScroll.on( 'error', this.hide.bind( this ) );
    infScroll.on( 'last', this.hide.bind( this ) );
  }

  onClick( event ) {
    event.preventDefault();
    this.infScroll.loadNextPage();
  }

  enable() {
    this.element.removeAttribute('disabled');
  }

  disable() {
    this.element.disabled = 'disabled';
  }

  hide() {
    this.element.style.display = 'none';
  }

  destroy() {
    this.element.removeEventListener( 'click', this.clickHandler );
  }

}

// -------------------------- InfiniteScroll methods -------------------------- //

// InfiniteScroll.defaults.button = null;

InfiniteScroll.create.button = function() {
  let buttonElem = utils.getQueryElement( this.options.button );
  if ( buttonElem ) {
    this.button = new InfiniteScrollButton( buttonElem, this );
  }
};

InfiniteScroll.destroy.button = function() {
  if ( this.button ) this.button.destroy();
};

// --------------------------  -------------------------- //

InfiniteScroll.Button = InfiniteScrollButton;

return InfiniteScroll;

} ) );
// status
( function( window, factory ) {
  // universal module definition
  if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
        window,
        require('./core'),
        require('fizzy-ui-utils'),
    );
  } else {
    // browser global
    factory(
        window,
        window.InfiniteScroll,
        window.fizzyUIUtils,
    );
  }

}( window, function factory( window, InfiniteScroll, utils ) {

let proto = InfiniteScroll.prototype;

// InfiniteScroll.defaults.status = null;

InfiniteScroll.create.status = function() {
  let statusElem = utils.getQueryElement( this.options.status );
  if ( !statusElem ) return;

  // elements
  this.statusElement = statusElem;
  this.statusEventElements = {
    request: statusElem.querySelector('.infinite-scroll-request'),
    error: statusElem.querySelector('.infinite-scroll-error'),
    last: statusElem.querySelector('.infinite-scroll-last'),
  };
  // events
  this.on( 'request', this.showRequestStatus );
  this.on( 'error', this.showErrorStatus );
  this.on( 'last', this.showLastStatus );
  this.bindHideStatus('on');
};

proto.bindHideStatus = function( bindMethod ) {
  let hideEvent = this.options.append ? 'append' : 'load';
  this[ bindMethod ]( hideEvent, this.hideAllStatus );
};

proto.showRequestStatus = function() {
  this.showStatus('request');
};

proto.showErrorStatus = function() {
  this.showStatus('error');
};

proto.showLastStatus = function() {
  this.showStatus('last');
  // prevent last then append event race condition from showing last status #706
  this.bindHideStatus('off');
};

proto.showStatus = function( eventName ) {
  show( this.statusElement );
  this.hideStatusEventElements();
  let eventElem = this.statusEventElements[ eventName ];
  show( eventElem );
};

proto.hideAllStatus = function() {
  hide( this.statusElement );
  this.hideStatusEventElements();
};

proto.hideStatusEventElements = function() {
  for ( let type in this.statusEventElements ) {
    let eventElem = this.statusEventElements[ type ];
    hide( eventElem );
  }
};

// --------------------------  -------------------------- //

function hide( elem ) {
  setDisplay( elem, 'none' );
}

function show( elem ) {
  setDisplay( elem, 'block' );
}

function setDisplay( elem, value ) {
  if ( elem ) {
    elem.style.display = value;
  }
}

// --------------------------  -------------------------- //

return InfiniteScroll;

} ) );
/*!
 * imagesLoaded v4.1.4
 * JavaScript is all like "You images are done yet or what?"
 * MIT License
 */

( function( window, factory ) { 'use strict';
  // universal module definition

  /*global define: false, module: false, require: false */

  if ( typeof define == 'function' && define.amd ) {
    // AMD
    define( [
      'ev-emitter/ev-emitter'
    ], function( EvEmitter ) {
      return factory( window, EvEmitter );
    });
  } else if ( typeof module == 'object' && module.exports ) {
    // CommonJS
    module.exports = factory(
      window,
      require('ev-emitter')
    );
  } else {
    // browser global
    window.imagesLoaded = factory(
      window,
      window.EvEmitter
    );
  }

})( typeof window !== 'undefined' ? window : this,

// --------------------------  factory -------------------------- //

function factory( window, EvEmitter ) {

'use strict';

var $ = window.jQuery;
var console = window.console;

// -------------------------- helpers -------------------------- //

// extend objects
function extend( a, b ) {
  for ( var prop in b ) {
    a[ prop ] = b[ prop ];
  }
  return a;
}

var arraySlice = Array.prototype.slice;

// turn element or nodeList into an array
function makeArray( obj ) {
  if ( Array.isArray( obj ) ) {
    // use object if already an array
    return obj;
  }

  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
  if ( isArrayLike ) {
    // convert nodeList to array
    return arraySlice.call( obj );
  }

  // array of single index
  return [ obj ];
}

// -------------------------- imagesLoaded -------------------------- //

/**
 * @param {Array, Element, NodeList, String} elem
 * @param {Object or Function} options - if function, use as callback
 * @param {Function} onAlways - callback function
 */
function ImagesLoaded( elem, options, onAlways ) {
  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
  if ( !( this instanceof ImagesLoaded ) ) {
    return new ImagesLoaded( elem, options, onAlways );
  }
  // use elem as selector string
  var queryElem = elem;
  if ( typeof elem == 'string' ) {
    queryElem = document.querySelectorAll( elem );
  }
  // bail if bad element
  if ( !queryElem ) {
    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
    return;
  }

  this.elements = makeArray( queryElem );
  this.options = extend( {}, this.options );
  // shift arguments if no options set
  if ( typeof options == 'function' ) {
    onAlways = options;
  } else {
    extend( this.options, options );
  }

  if ( onAlways ) {
    this.on( 'always', onAlways );
  }

  this.getImages();

  if ( $ ) {
    // add jQuery Deferred object
    this.jqDeferred = new $.Deferred();
  }

  // HACK check async to allow time to bind listeners
  setTimeout( this.check.bind( this ) );
}

ImagesLoaded.prototype = Object.create( EvEmitter.prototype );

ImagesLoaded.prototype.options = {};

ImagesLoaded.prototype.getImages = function() {
  this.images = [];

  // filter & find items if we have an item selector
  this.elements.forEach( this.addElementImages, this );
};

/**
 * @param {Node} element
 */
ImagesLoaded.prototype.addElementImages = function( elem ) {
  // filter siblings
  if ( elem.nodeName == 'IMG' ) {
    this.addImage( elem );
  }
  // get background image on element
  if ( this.options.background === true ) {
    this.addElementBackgroundImages( elem );
  }

  // find children
  // no non-element nodes, #143
  var nodeType = elem.nodeType;
  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
    return;
  }
  var childImgs = elem.querySelectorAll('img');
  // concat childElems to filterFound array
  for ( var i=0; i < childImgs.length; i++ ) {
    var img = childImgs[i];
    this.addImage( img );
  }

  // get child background images
  if ( typeof this.options.background == 'string' ) {
    var children = elem.querySelectorAll( this.options.background );
    for ( i=0; i < children.length; i++ ) {
      var child = children[i];
      this.addElementBackgroundImages( child );
    }
  }
};

var elementNodeTypes = {
  1: true,
  9: true,
  11: true
};

ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
  var style = getComputedStyle( elem );
  if ( !style ) {
    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
    return;
  }
  // get url inside url("...")
  var reURL = /url\((['"])?(.*?)\1\)/gi;
  var matches = reURL.exec( style.backgroundImage );
  while ( matches !== null ) {
    var url = matches && matches[2];
    if ( url ) {
      this.addBackground( url, elem );
    }
    matches = reURL.exec( style.backgroundImage );
  }
};

/**
 * @param {Image} img
 */
ImagesLoaded.prototype.addImage = function( img ) {
  var loadingImage = new LoadingImage( img );
  this.images.push( loadingImage );
};

ImagesLoaded.prototype.addBackground = function( url, elem ) {
  var background = new Background( url, elem );
  this.images.push( background );
};

ImagesLoaded.prototype.check = function() {
  var _this = this;
  this.progressedCount = 0;
  this.hasAnyBroken = false;
  // complete if no images
  if ( !this.images.length ) {
    this.complete();
    return;
  }

  function onProgress( image, elem, message ) {
    // HACK - Chrome triggers event before object properties have changed. #83
    setTimeout( function() {
      _this.progress( image, elem, message );
    });
  }

  this.images.forEach( function( loadingImage ) {
    loadingImage.once( 'progress', onProgress );
    loadingImage.check();
  });
};

ImagesLoaded.prototype.progress = function( image, elem, message ) {
  this.progressedCount++;
  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
  // progress event
  this.emitEvent( 'progress', [ this, image, elem ] );
  if ( this.jqDeferred && this.jqDeferred.notify ) {
    this.jqDeferred.notify( this, image );
  }
  // check if completed
  if ( this.progressedCount == this.images.length ) {
    this.complete();
  }

  if ( this.options.debug && console ) {
    console.log( 'progress: ' + message, image, elem );
  }
};

ImagesLoaded.prototype.complete = function() {
  var eventName = this.hasAnyBroken ? 'fail' : 'done';
  this.isComplete = true;
  this.emitEvent( eventName, [ this ] );
  this.emitEvent( 'always', [ this ] );
  if ( this.jqDeferred ) {
    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
    this.jqDeferred[ jqMethod ]( this );
  }
};

// --------------------------  -------------------------- //

function LoadingImage( img ) {
  this.img = img;
}

LoadingImage.prototype = Object.create( EvEmitter.prototype );

LoadingImage.prototype.check = function() {
  // If complete is true and browser supports natural sizes,
  // try to check for image status manually.
  var isComplete = this.getIsImageComplete();
  if ( isComplete ) {
    // report based on naturalWidth
    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
    return;
  }

  // If none of the checks above matched, simulate loading on detached element.
  this.proxyImage = new Image();
  this.proxyImage.addEventListener( 'load', this );
  this.proxyImage.addEventListener( 'error', this );
  // bind to image as well for Firefox. #191
  this.img.addEventListener( 'load', this );
  this.img.addEventListener( 'error', this );
  this.proxyImage.src = this.img.src;
};

LoadingImage.prototype.getIsImageComplete = function() {
  // check for non-zero, non-undefined naturalWidth
  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
  return this.img.complete && this.img.naturalWidth;
};

LoadingImage.prototype.confirm = function( isLoaded, message ) {
  this.isLoaded = isLoaded;
  this.emitEvent( 'progress', [ this, this.img, message ] );
};

// ----- events ----- //

// trigger specified handler for event type
LoadingImage.prototype.handleEvent = function( event ) {
  var method = 'on' + event.type;
  if ( this[ method ] ) {
    this[ method ]( event );
  }
};

LoadingImage.prototype.onload = function() {
  this.confirm( true, 'onload' );
  this.unbindEvents();
};

LoadingImage.prototype.onerror = function() {
  this.confirm( false, 'onerror' );
  this.unbindEvents();
};

LoadingImage.prototype.unbindEvents = function() {
  this.proxyImage.removeEventListener( 'load', this );
  this.proxyImage.removeEventListener( 'error', this );
  this.img.removeEventListener( 'load', this );
  this.img.removeEventListener( 'error', this );
};

// -------------------------- Background -------------------------- //

function Background( url, element ) {
  this.url = url;
  this.element = element;
  this.img = new Image();
}

// inherit LoadingImage prototype
Background.prototype = Object.create( LoadingImage.prototype );

Background.prototype.check = function() {
  this.img.addEventListener( 'load', this );
  this.img.addEventListener( 'error', this );
  this.img.src = this.url;
  // check if image is already complete
  var isComplete = this.getIsImageComplete();
  if ( isComplete ) {
    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
    this.unbindEvents();
  }
};

Background.prototype.unbindEvents = function() {
  this.img.removeEventListener( 'load', this );
  this.img.removeEventListener( 'error', this );
};

Background.prototype.confirm = function( isLoaded, message ) {
  this.isLoaded = isLoaded;
  this.emitEvent( 'progress', [ this, this.element, message ] );
};

// -------------------------- jQuery -------------------------- //

ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
  jQuery = jQuery || window.jQuery;
  if ( !jQuery ) {
    return;
  }
  // set local variable
  $ = jQuery;
  // $().imagesLoaded()
  $.fn.imagesLoaded = function( options, callback ) {
    var instance = new ImagesLoaded( this, options, callback );
    return instance.jqDeferred.promise( $(this) );
  };
};
// try making plugin
ImagesLoaded.makeJQueryPlugin();

// --------------------------  -------------------------- //

return ImagesLoaded;

});