Blame | Letzte Änderung | Log anzeigen | RSS feed
// ==================================================// fancyBox v3.4.2//// Licensed GPLv3 for open source use// or fancyBox Commercial License for commercial use//// http://fancyapps.com/fancybox/// Copyright 2018 fancyApps//// ==================================================(function(window, document, $, undefined) {"use strict";window.console = window.console || {info: function(stuff) {}};// If there's no jQuery, fancyBox can't work// =========================================if (!$) {return;}// Check if fancyBox is already initialized// ========================================if ($.fn.fancybox) {console.info("fancyBox already initialized");return;}// Private default settings// ========================var defaults = {// Close existing modals// Set this to false if you do not need to stack multiple instancescloseExisting: false,// Enable infinite gallery navigationloop: false,// Horizontal space between slidesgutter: 50,// Enable keyboard navigationkeyboard: true,// Should display navigation arrows at the screen edgesarrows: true,// Should display counter at the top left cornerinfobar: true,// Should display close button (using `btnTpl.smallBtn` template) over the content// Can be true, false, "auto"// If "auto" - will be automatically enabled for "html", "inline" or "ajax" itemssmallBtn: "auto",// Should display toolbar (buttons at the top)// Can be true, false, "auto"// If "auto" - will be automatically hidden if "smallBtn" is enabledtoolbar: "auto",// What buttons should appear in the top right corner.// Buttons will be created using templates from `btnTpl` option// and they will be placed into toolbar (class="fancybox-toolbar"` element)buttons: ["zoom",//"share","slideShow",//"fullScreen",//"download","thumbs","close"],// Detect "idle" time in secondsidleTime: 3,// Disable right-click and use simple image protection for imagesprotect: false,// Shortcut to make content "modal" - disable keyboard navigtion, hide buttons, etcmodal: false,image: {// Wait for images to load before displaying// true - wait for image to load and then display;// false - display thumbnail and load the full-sized image over top,// requires predefined image dimensions (`data-width` and `data-height` attributes)preload: false},ajax: {// Object containing settings for ajax requestsettings: {// This helps to indicate that request comes from the modal// Feel free to change namingdata: {fancybox: true}}},iframe: {// Iframe templatetpl:'<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" allowfullscreen allow="fullscreen autoplay" src=""></iframe>',// Preload iframe before displaying it// This allows to calculate iframe content width and height// (note: Due to "Same Origin Policy", you can't get cross domain data).preload: true,// Custom CSS styling for iframe wrapping element// You can use this to set custom iframe dimensionscss: {},// Iframe tag attributesattr: {scrolling: "auto"}},// For HTML5 video onlyvideo: {tpl:'<video class="fancybox-video" controls controlsList="nodownload">' +'<source src="{{src}}" type="{{format}}" />' +"Your browser doesn't support HTML5 video" +"</video>",format: "", // custom video formatautoStart: true},// Default content type if cannot be detected automaticallydefaultType: "image",// Open/close animation type// Possible values:// false - disable// "zoom" - zoom images from/to thumbnail// "fade"// "zoom-in-out"//animationEffect: "zoom",// Duration in ms for open/close animationanimationDuration: 366,// Should image change opacity while zooming// If opacity is "auto", then opacity will be changed if image and thumbnail have different aspect ratioszoomOpacity: "auto",// Transition effect between slides//// Possible values:// false - disable// "fade'// "slide'// "circular'// "tube'// "zoom-in-out'// "rotate'//transitionEffect: "fade",// Duration in ms for transition animationtransitionDuration: 366,// Custom CSS class for slide elementslideClass: "",// Custom CSS class for layoutbaseClass: "",// Base template for layoutbaseTpl:'<div class="fancybox-container" role="dialog" tabindex="-1">' +'<div class="fancybox-bg"></div>' +'<div class="fancybox-inner">' +'<div class="fancybox-infobar"><span data-fancybox-index></span> / <span data-fancybox-count></span></div>' +'<div class="fancybox-toolbar">{{buttons}}</div>' +'<div class="fancybox-navigation">{{arrows}}</div>' +'<div class="fancybox-stage"></div>' +'<div class="fancybox-caption"></div>' +"</div>" +"</div>",// Loading indicator templatespinnerTpl: '<div class="fancybox-loading"></div>',// Error message templateerrorTpl: '<div class="fancybox-error"><p>{{ERROR}}</p></div>',btnTpl: {download:'<a download data-fancybox-download class="fancybox-button fancybox-button--download" title="{{DOWNLOAD}}" href="javascript:;">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.62 17.09V19H5.38v-1.91zm-2.97-6.96L17 11.45l-5 4.87-5-4.87 1.36-1.32 2.68 2.64V5h1.92v7.77z"/></svg>' +"</a>",zoom:'<button data-fancybox-zoom class="fancybox-button fancybox-button--zoom" title="{{ZOOM}}">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M18.7 17.3l-3-3a5.9 5.9 0 0 0-.6-7.6 5.9 5.9 0 0 0-8.4 0 5.9 5.9 0 0 0 0 8.4 5.9 5.9 0 0 0 7.7.7l3 3a1 1 0 0 0 1.3 0c.4-.5.4-1 0-1.5zM8.1 13.8a4 4 0 0 1 0-5.7 4 4 0 0 1 5.7 0 4 4 0 0 1 0 5.7 4 4 0 0 1-5.7 0z"/></svg>' +"</button>",close:'<button data-fancybox-close class="fancybox-button fancybox-button--close" title="{{CLOSE}}">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M12 10.6L6.6 5.2 5.2 6.6l5.4 5.4-5.4 5.4 1.4 1.4 5.4-5.4 5.4 5.4 1.4-1.4-5.4-5.4 5.4-5.4-1.4-1.4-5.4 5.4z"/></svg>' +"</button>",// ArrowsarrowLeft:'<button data-fancybox-prev class="fancybox-button fancybox-button--arrow_left" title="{{PREV}}">' +'<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M11.28 15.7l-1.34 1.37L5 12l4.94-5.07 1.34 1.38-2.68 2.72H19v1.94H8.6z"/></svg></div>' +"</button>",arrowRight:'<button data-fancybox-next class="fancybox-button fancybox-button--arrow_right" title="{{NEXT}}">' +'<div><svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M15.4 12.97l-2.68 2.72 1.34 1.38L19 12l-4.94-5.07-1.34 1.38 2.68 2.72H5v1.94z"/></svg></div>' +"</button>",// This small close button will be appended to your html/inline/ajax content by default,// if "smallBtn" option is not set to falsesmallBtn:'<button type="button" data-fancybox-close class="fancybox-button fancybox-close-small" title="{{CLOSE}}">' +'<svg xmlns="http://www.w3.org/2000/svg" version="1" viewBox="0 0 24 24"><path d="M13 12l5-5-1-1-5 5-5-5-1 1 5 5-5 5 1 1 5-5 5 5 1-1z"/></svg>' +"</button>"},// Container is injected into this elementparentEl: "body",// Hide browser vertical scrollbars; use at your own riskhideScrollbar: true,// Focus handling// ==============// Try to focus on the first focusable element after openingautoFocus: true,// Put focus back to active element after closingbackFocus: true,// Do not let user to focus on element outside modal contenttrapFocus: true,// Module specific options// =======================fullScreen: {autoStart: false},// Set `touch: false` to disable panning/swipingtouch: {vertical: true, // Allow to drag content verticallymomentum: true // Continue movement after releasing mouse/touch when panning},// Hash value when initializing manually,// set `false` to disable hash changehash: null,// Customize or add new media types// Example:/*media : {youtube : {params : {autoplay : 0}}}*/media: {},slideShow: {autoStart: false,speed: 3000},thumbs: {autoStart: false, // Display thumbnails on openinghideOnClose: true, // Hide thumbnail grid when closing animation startsparentEl: ".fancybox-container", // Container is injected into this elementaxis: "y" // Vertical (y) or horizontal (x) scrolling},// Use mousewheel to navigate gallery// If 'auto' - enabled for images onlywheel: "auto",// Callbacks//==========// See Documentation/API/Events for more information// Example:/*afterShow: function( instance, current ) {console.info( 'Clicked element:' );console.info( current.opts.$orig );}*/onInit: $.noop, // When instance has been initializedbeforeLoad: $.noop, // Before the content of a slide is being loadedafterLoad: $.noop, // When the content of a slide is done loadingbeforeShow: $.noop, // Before open animation startsafterShow: $.noop, // When content is done loading and animatingbeforeClose: $.noop, // Before the instance attempts to close. Return false to cancel the close.afterClose: $.noop, // After instance has been closedonActivate: $.noop, // When instance is brought to frontonDeactivate: $.noop, // When other instance has been activated// Interaction// ===========// Use options below to customize taken action when user clicks or double clicks on the fancyBox area,// each option can be string or method that returns value.//// Possible values:// "close" - close instance// "next" - move to next gallery item// "nextOrClose" - move to next gallery item or close if gallery has only one item// "toggleControls" - show/hide controls// "zoom" - zoom image (if loaded)// false - do nothing// Clicked on the contentclickContent: function(current, event) {return current.type === "image" ? "zoom" : false;},// Clicked on the slideclickSlide: "close",// Clicked on the background (backdrop) element;// if you have not changed the layout, then most likely you need to use `clickSlide` optionclickOutside: "close",// Same as previous two, but for double clickdblclickContent: false,dblclickSlide: false,dblclickOutside: false,// Custom options when mobile device is detected// =============================================mobile: {idleTime: false,clickContent: function(current, event) {return current.type === "image" ? "toggleControls" : false;},clickSlide: function(current, event) {return current.type === "image" ? "toggleControls" : "close";},dblclickContent: function(current, event) {return current.type === "image" ? "zoom" : false;},dblclickSlide: function(current, event) {return current.type === "image" ? "zoom" : false;}},// Internationalization// ====================lang: "en",i18n: {en: {CLOSE: "Close",NEXT: "Next",PREV: "Previous",ERROR: "The requested content cannot be loaded. <br/> Please try again later.",PLAY_START: "Start slideshow",PLAY_STOP: "Pause slideshow",FULL_SCREEN: "Full screen",THUMBS: "Thumbnails",DOWNLOAD: "Download",SHARE: "Share",ZOOM: "Zoom"},de: {CLOSE: "Schliessen",NEXT: "Weiter",PREV: "Zurück",ERROR: "Die angeforderten Daten konnten nicht geladen werden. <br/> Bitte versuchen Sie es später nochmal.",PLAY_START: "Diaschau starten",PLAY_STOP: "Diaschau beenden",FULL_SCREEN: "Vollbild",THUMBS: "Vorschaubilder",DOWNLOAD: "Herunterladen",SHARE: "Teilen",ZOOM: "Maßstab"}}};// Few useful variables and methods// ================================var $W = $(window);var $D = $(document);var called = 0;// Check if an object is a jQuery object and not a native JavaScript object// ========================================================================var isQuery = function(obj) {return obj && obj.hasOwnProperty && obj instanceof $;};// Handle multiple browsers for "requestAnimationFrame" and "cancelAnimationFrame"// ===============================================================================var requestAFrame = (function() {return (window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||// if all else fails, use setTimeoutfunction(callback) {return window.setTimeout(callback, 1000 / 60);});})();// Detect the supported transition-end event property name// =======================================================var transitionEnd = (function() {var el = document.createElement("fakeelement"),t;var transitions = {transition: "transitionend",OTransition: "oTransitionEnd",MozTransition: "transitionend",WebkitTransition: "webkitTransitionEnd"};for (t in transitions) {if (el.style[t] !== undefined) {return transitions[t];}}return "transitionend";})();// Force redraw on an element.// This helps in cases where the browser doesn't redraw an updated element properly// ================================================================================var forceRedraw = function($el) {return $el && $el.length && $el[0].offsetHeight;};// Exclude array (`buttons`) options from deep merging// ===================================================var mergeOpts = function(opts1, opts2) {var rez = $.extend(true, {}, opts1, opts2);$.each(opts2, function(key, value) {if ($.isArray(value)) {rez[key] = value;}});return rez;};// How much of an element is visible in viewport// =============================================var inViewport = function($el) {var element = $el[0],elementRect = element.getBoundingClientRect(),parentRects = [],visibleInAllParents,windowHeight = $(window).height(),pageScroll = $(document).scrollTop(),elementTop = elementRect.top + pageScroll,hiddenBefore = pageScroll - elementTop,hiddenAfter = elementTop + elementRect.height - (pageScroll + windowHeight);// Check if the parent can hide its childrenwhile (element.parentElement !== null) {if ($(element.parentElement).css("overflow") === "hidden" || $(element.parentElement).css("overflow") === "auto") {parentRects.push(element.parentElement.getBoundingClientRect());}element = element.parentElement;}visibleInAllParents = parentRects.every(function(parentRect) {var visiblePixelX = Math.min(elementRect.right, parentRect.right) - Math.max(elementRect.left, parentRect.left);var visiblePixelY = Math.min(elementRect.bottom, parentRect.bottom) - Math.max(elementRect.top, parentRect.top);return visiblePixelX > 0 && visiblePixelY > 0;});if (!visibleInAllParents || pageScroll > elementTop + elementRect.height || elementTop > pageScroll + windowHeight) {return 0;}if (hiddenBefore > 0) {return 100 - (hiddenBefore * 100) / elementRect.height;}if (hiddenAfter > 0) {return 100 - (hiddenAfter * 100) / elementRect.height;}return 100;};// Class definition// ================var FancyBox = function(content, opts, index) {var self = this;self.opts = mergeOpts({index: index}, $.fancybox.defaults);if ($.isPlainObject(opts)) {self.opts = mergeOpts(self.opts, opts);}if ($.fancybox.isMobile) {self.opts = mergeOpts(self.opts, self.opts.mobile);}self.id = self.opts.id || ++called;self.currIndex = parseInt(self.opts.index, 10) || 0;self.prevIndex = null;self.prevPos = null;self.currPos = 0;self.firstRun = true;// All group itemsself.group = [];// Existing slides (for current, next and previous gallery items)self.slides = {};// Create group elementsself.addContent(content);if (!self.group.length) {return;}self.init();};$.extend(FancyBox.prototype, {// Create DOM structure// ====================init: function() {var self = this,firstItem = self.group[self.currIndex],firstItemOpts = firstItem.opts,$container,buttonStr;if (firstItemOpts.closeExisting) {$.fancybox.close(true);}// Hide scrollbars// ===============$("body").addClass("fancybox-active");if (!$.fancybox.getInstance() &&firstItemOpts.hideScrollbar !== false &&!$.fancybox.isMobile &&document.body.scrollHeight > window.innerHeight) {$("head").append('<style id="fancybox-style-noscroll" type="text/css">.compensate-for-scrollbar{margin-right:' +(window.innerWidth - document.documentElement.clientWidth) +"px;}</style>");$("body").addClass("compensate-for-scrollbar");}// Build html markup and set references// ====================================// Build html code for buttons and insert into main templatebuttonStr = "";$.each(firstItemOpts.buttons, function(index, value) {buttonStr += firstItemOpts.btnTpl[value] || "";});// Create markup from base template, it will be initially hidden to// avoid unnecessary work like painting while initializing is not complete$container = $(self.translate(self,firstItemOpts.baseTpl.replace("{{buttons}}", buttonStr).replace("{{arrows}}", firstItemOpts.btnTpl.arrowLeft + firstItemOpts.btnTpl.arrowRight))).attr("id", "fancybox-container-" + self.id).addClass(firstItemOpts.baseClass).data("FancyBox", self).appendTo(firstItemOpts.parentEl);// Create object holding references to jQuery wrapped nodesself.$refs = {container: $container};["bg", "inner", "infobar", "toolbar", "stage", "caption", "navigation"].forEach(function(item) {self.$refs[item] = $container.find(".fancybox-" + item);});self.trigger("onInit");// Enable events, deactive previous instancesself.activate();// Build slides, load and reveal contentself.jumpTo(self.currIndex);},// Simple i18n support - replaces object keys found in template// with corresponding values// ============================================================translate: function(obj, str) {var arr = obj.opts.i18n[obj.opts.lang];return str.replace(/\{\{(\w+)\}\}/g, function(match, n) {var value = arr[n];if (value === undefined) {return match;}return value;});},// Populate current group with fresh content// Check if each object has valid type and content// ===============================================addContent: function(content) {var self = this,items = $.makeArray(content),thumbs;$.each(items, function(i, item) {var obj = {},opts = {},$item,type,found,src,srcParts;// Step 1 - Make sure we have an object// ====================================if ($.isPlainObject(item)) {// We probably have manual usage here, something like// $.fancybox.open( [ { src : "image.jpg", type : "image" } ] )obj = item;opts = item.opts || item;} else if ($.type(item) === "object" && $(item).length) {// Here we probably have jQuery collection returned by some selector$item = $(item);// Support attributes like `data-options='{"touch" : false}'` and `data-touch='false'`opts = $item.data() || {};opts = $.extend(true, {}, opts, opts.options);// Here we store clicked elementopts.$orig = $item;obj.src = self.opts.src || opts.src || $item.attr("href");// Assume that simple syntax is used, for example:// `$.fancybox.open( $("#test"), {} );`if (!obj.type && !obj.src) {obj.type = "inline";obj.src = item;}} else {// Assume we have a simple html code, for example:// $.fancybox.open( '<div><h1>Hi!</h1></div>' );obj = {type: "html",src: item + ""};}// Each gallery object has full collection of optionsobj.opts = $.extend(true, {}, self.opts, opts);// Do not merge buttons arrayif ($.isArray(opts.buttons)) {obj.opts.buttons = opts.buttons;}if ($.fancybox.isMobile && obj.opts.mobile) {obj.opts = mergeOpts(obj.opts, obj.opts.mobile);}// Step 2 - Make sure we have content type, if not - try to guess// ==============================================================type = obj.type || obj.opts.type;src = obj.src || "";if (!type && src) {if ((found = src.match(/\.(mp4|mov|ogv|webm)((\?|#).*)?$/i))) {type = "video";if (!obj.opts.video.format) {obj.opts.video.format = "video/" + (found[1] === "ogv" ? "ogg" : found[1]);}} else if (src.match(/(^data:image\/[a-z0-9+\/=]*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg|ico)((\?|#).*)?$)/i)) {type = "image";} else if (src.match(/\.(pdf)((\?|#).*)?$/i)) {type = "iframe";} else if (src.charAt(0) === "#") {type = "inline";}}if (type) {obj.type = type;} else {self.trigger("objectNeedsType", obj);}if (!obj.contentType) {obj.contentType = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1 ? "html" : obj.type;}// Step 3 - Some adjustments// =========================obj.index = self.group.length;if (obj.opts.smallBtn == "auto") {obj.opts.smallBtn = $.inArray(obj.type, ["html", "inline", "ajax"]) > -1;}if (obj.opts.toolbar === "auto") {obj.opts.toolbar = !obj.opts.smallBtn;}// Find thumbnail imageif (obj.opts.$trigger && obj.index === self.opts.index) {obj.opts.$thumb = obj.opts.$trigger.find("img:first");if (obj.opts.$thumb.length) {obj.opts.$orig = obj.opts.$trigger;}}if ((!obj.opts.$thumb || !obj.opts.$thumb.length) && obj.opts.$orig) {obj.opts.$thumb = obj.opts.$orig.find("img:first");}// "caption" is a "special" option, it can be used to customize caption per gallery item ..if ($.type(obj.opts.caption) === "function") {obj.opts.caption = obj.opts.caption.apply(item, [self, obj]);}if ($.type(self.opts.caption) === "function") {obj.opts.caption = self.opts.caption.apply(item, [self, obj]);}// Make sure we have caption as a string or jQuery objectif (!(obj.opts.caption instanceof $)) {obj.opts.caption = obj.opts.caption === undefined ? "" : obj.opts.caption + "";}// Check if url contains "filter" used to filter the content// Example: "ajax.html #something"if (obj.type === "ajax") {srcParts = src.split(/\s+/, 2);if (srcParts.length > 1) {obj.src = srcParts.shift();obj.opts.filter = srcParts.shift();}}// Hide all buttons and disable interactivity for modal itemsif (obj.opts.modal) {obj.opts = $.extend(true, obj.opts, {trapFocus: true,// Remove buttonsinfobar: 0,toolbar: 0,smallBtn: 0,// Disable keyboard navigationkeyboard: 0,// Disable some modulesslideShow: 0,fullScreen: 0,thumbs: 0,touch: 0,// Disable click event handlersclickContent: false,clickSlide: false,clickOutside: false,dblclickContent: false,dblclickSlide: false,dblclickOutside: false});}// Step 4 - Add processed object to group// ======================================self.group.push(obj);});// Update controls if gallery is already openedif (Object.keys(self.slides).length) {self.updateControls();// Update thumbnails, if neededthumbs = self.Thumbs;if (thumbs && thumbs.isActive) {thumbs.create();thumbs.focus();}}},// Attach an event handler functions for:// - navigation buttons// - browser scrolling, resizing;// - focusing// - keyboard// - detecting inactivity// ======================================addEvents: function() {var self = this;self.removeEvents();// Make navigation elements clickable// ==================================self.$refs.container.on("click.fb-close", "[data-fancybox-close]", function(e) {e.stopPropagation();e.preventDefault();self.close(e);}).on("touchstart.fb-prev click.fb-prev", "[data-fancybox-prev]", function(e) {e.stopPropagation();e.preventDefault();self.previous();}).on("touchstart.fb-next click.fb-next", "[data-fancybox-next]", function(e) {e.stopPropagation();e.preventDefault();self.next();}).on("click.fb", "[data-fancybox-zoom]", function(e) {// Click handler for zoom buttonself[self.isScaledDown() ? "scaleToActual" : "scaleToFit"]();});// Handle page scrolling and browser resizing// ==========================================$W.on("orientationchange.fb resize.fb", function(e) {if (e && e.originalEvent && e.originalEvent.type === "resize") {requestAFrame(function() {self.update();});} else {if (self.current && self.current.type === "iframe") {self.$refs.stage.hide();}setTimeout(function() {self.$refs.stage.show();self.update();}, $.fancybox.isMobile ? 600 : 250);}});$D.on("keydown.fb", function(e) {var instance = $.fancybox ? $.fancybox.getInstance() : null,current = instance.current,keycode = e.keyCode || e.which;// Trap keyboard focus inside of the modal// =======================================if (keycode == 9) {if (current.opts.trapFocus) {self.focus(e);}return;}// Enable keyboard navigation// ==========================if (!current.opts.keyboard || e.ctrlKey || e.altKey || e.shiftKey || $(e.target).is("input") || $(e.target).is("textarea")) {return;}// Backspace and Esc keysif (keycode === 8 || keycode === 27) {e.preventDefault();self.close(e);return;}// Left arrow and Up arrowif (keycode === 37 || keycode === 38) {e.preventDefault();self.previous();return;}// Righ arrow and Down arrowif (keycode === 39 || keycode === 40) {e.preventDefault();self.next();return;}self.trigger("afterKeydown", e, keycode);});// Hide controls after some inactivity periodif (self.group[self.currIndex].opts.idleTime) {self.idleSecondsCounter = 0;$D.on("mousemove.fb-idle mouseleave.fb-idle mousedown.fb-idle touchstart.fb-idle touchmove.fb-idle scroll.fb-idle keydown.fb-idle",function(e) {self.idleSecondsCounter = 0;if (self.isIdle) {self.showControls();}self.isIdle = false;});self.idleInterval = window.setInterval(function() {self.idleSecondsCounter++;if (self.idleSecondsCounter >= self.group[self.currIndex].opts.idleTime && !self.isDragging) {self.isIdle = true;self.idleSecondsCounter = 0;self.hideControls();}}, 1000);}},// Remove events added by the core// ===============================removeEvents: function() {var self = this;$W.off("orientationchange.fb resize.fb");$D.off("keydown.fb .fb-idle");this.$refs.container.off(".fb-close .fb-prev .fb-next");if (self.idleInterval) {window.clearInterval(self.idleInterval);self.idleInterval = null;}},// Change to previous gallery item// ===============================previous: function(duration) {return this.jumpTo(this.currPos - 1, duration);},// Change to next gallery item// ===========================next: function(duration) {return this.jumpTo(this.currPos + 1, duration);},// Switch to selected gallery item// ===============================jumpTo: function(pos, duration) {var self = this,groupLen = self.group.length,firstRun,isMoved,loop,current,previous,slidePos,stagePos,diff;if (self.isDragging || self.isClosing || (self.isAnimating && self.firstRun)) {return;}// Should loop?pos = parseInt(pos, 10);loop = self.current ? self.current.opts.loop : self.opts.loop;if (!loop && (pos < 0 || pos >= groupLen)) {return false;}// Check if opening for the first time; this helps to speed things upfirstRun = self.firstRun = !Object.keys(self.slides).length;// Create slidesprevious = self.current;self.prevIndex = self.currIndex;self.prevPos = self.currPos;current = self.createSlide(pos);if (groupLen > 1) {if (loop || current.index < groupLen - 1) {self.createSlide(pos + 1);}if (loop || current.index > 0) {self.createSlide(pos - 1);}}self.current = current;self.currIndex = current.index;self.currPos = current.pos;self.trigger("beforeShow", firstRun);self.updateControls();// Validate duration lengthcurrent.forcedDuration = undefined;if ($.isNumeric(duration)) {current.forcedDuration = duration;} else {duration = current.opts[firstRun ? "animationDuration" : "transitionDuration"];}duration = parseInt(duration, 10);// Check if user has swiped the slides or if still animatingisMoved = self.isMoved(previous);// Make sure current slide is visiblecurrent.$slide.addClass("fancybox-slide--current");// Fresh start - reveal container, current slide and start loading contentif (firstRun) {if (current.opts.animationEffect && duration) {self.$refs.container.css("transition-duration", duration + "ms");}self.$refs.container.addClass("fancybox-is-open").trigger("focus");// Attempt to load content into slide// This will later call `afterLoad` -> `revealContent`self.loadSlide(current);self.preload("image");return;}// Get actual slide/stage positions (before cleaning up)slidePos = $.fancybox.getTranslate(previous.$slide);stagePos = $.fancybox.getTranslate(self.$refs.stage);// Clean up all slides$.each(self.slides, function(index, slide) {$.fancybox.stop(slide.$slide, true);});if (previous.pos !== current.pos) {previous.isComplete = false;previous.$slide.removeClass("fancybox-slide--complete fancybox-slide--current");}// If slides are out of place, then animate them to correct positionif (isMoved) {// Calculate horizontal swipe distancediff = slidePos.left - (previous.pos * slidePos.width + previous.pos * previous.opts.gutter);$.each(self.slides, function(index, slide) {// Make sure that each slide is in equal distance// This is mostly needed for freshly added slides, because they are not yet positionedvar leftPos = slide.pos * slidePos.width + slide.pos * slide.opts.gutter;$.fancybox.setTranslate(slide.$slide, {top: 0, left: leftPos + diff - stagePos.left});if (slide.pos !== current.pos) {slide.$slide.addClass("fancybox-slide--" + (slide.pos > current.pos ? "next" : "previous"));}// Redraw to make sure that transition will startforceRedraw(slide.$slide);// Animate the sliderequestAFrame(function() {$.fancybox.animate(slide.$slide,{top: 0,left: (slide.pos - current.pos) * slidePos.width + (slide.pos - current.pos) * slide.opts.gutter},duration,function() {slide.$slide.removeAttr("style").removeClass("fancybox-slide--next fancybox-slide--previous");if (slide.pos === self.currPos) {self.complete();}});});});} else {current.$slide.parent().children().removeAttr("style");// Handle previously active slideif (duration && current.opts.transitionEffect) {$.fancybox.animate(previous.$slide,"fancybox-animated fancybox-slide--" +(previous.pos > current.pos ? "next" : "previous") +" fancybox-fx-" +current.opts.transitionEffect,duration,null,false);}}if (current.isLoaded) {self.revealContent(current);} else {self.loadSlide(current);}self.preload("image");},// Create new "slide" element// These are gallery items that are actually added to DOM// =======================================================createSlide: function(pos) {var self = this,$slide,index;index = pos % self.group.length;index = index < 0 ? self.group.length + index : index;if (!self.slides[pos] && self.group[index]) {$slide = $('<div class="fancybox-slide"></div>').appendTo(self.$refs.stage);self.slides[pos] = $.extend(true, {}, self.group[index], {pos: pos,$slide: $slide,isLoaded: false});self.updateSlide(self.slides[pos]);}return self.slides[pos];},// Scale image to the actual size of the image;// x and y values should be relative to the slide// ==============================================scaleToActual: function(x, y, duration) {var self = this,current = self.current,$content = current.$content,canvasWidth = $.fancybox.getTranslate(current.$slide).width,canvasHeight = $.fancybox.getTranslate(current.$slide).height,newImgWidth = current.width,newImgHeight = current.height,imgPos,posX,posY,scaleX,scaleY;if (self.isAnimating || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {return;}$.fancybox.stop($content);self.isAnimating = true;x = x === undefined ? canvasWidth * 0.5 : x;y = y === undefined ? canvasHeight * 0.5 : y;imgPos = $.fancybox.getTranslate($content);imgPos.top -= $.fancybox.getTranslate(current.$slide).top;imgPos.left -= $.fancybox.getTranslate(current.$slide).left;scaleX = newImgWidth / imgPos.width;scaleY = newImgHeight / imgPos.height;// Get center position for original imageposX = canvasWidth * 0.5 - newImgWidth * 0.5;posY = canvasHeight * 0.5 - newImgHeight * 0.5;// Make sure image does not move away from edgesif (newImgWidth > canvasWidth) {posX = imgPos.left * scaleX - (x * scaleX - x);if (posX > 0) {posX = 0;}if (posX < canvasWidth - newImgWidth) {posX = canvasWidth - newImgWidth;}}if (newImgHeight > canvasHeight) {posY = imgPos.top * scaleY - (y * scaleY - y);if (posY > 0) {posY = 0;}if (posY < canvasHeight - newImgHeight) {posY = canvasHeight - newImgHeight;}}self.updateCursor(newImgWidth, newImgHeight);$.fancybox.animate($content,{top: posY,left: posX,scaleX: scaleX,scaleY: scaleY},duration || 330,function() {self.isAnimating = false;});// Stop slideshowif (self.SlideShow && self.SlideShow.isActive) {self.SlideShow.stop();}},// Scale image to fit inside parent element// ========================================scaleToFit: function(duration) {var self = this,current = self.current,$content = current.$content,end;if (self.isAnimating || !$content || !(current.type == "image" && current.isLoaded && !current.hasError)) {return;}$.fancybox.stop($content);self.isAnimating = true;end = self.getFitPos(current);self.updateCursor(end.width, end.height);$.fancybox.animate($content,{top: end.top,left: end.left,scaleX: end.width / $content.width(),scaleY: end.height / $content.height()},duration || 330,function() {self.isAnimating = false;});},// Calculate image size to fit inside viewport// ===========================================getFitPos: function(slide) {var self = this,$content = slide.$content,$slide = slide.$slide,width = slide.width || slide.opts.width,height = slide.height || slide.opts.height,maxWidth,maxHeight,minRatio,aspectRatio,rez = {};if (!slide.isLoaded || !$content || !$content.length) {return false;}maxWidth = $.fancybox.getTranslate(self.$refs.stage).width;maxHeight = $.fancybox.getTranslate(self.$refs.stage).height;maxWidth -=parseFloat($slide.css("paddingLeft")) +parseFloat($slide.css("paddingRight")) +parseFloat($content.css("marginLeft")) +parseFloat($content.css("marginRight"));maxHeight -=parseFloat($slide.css("paddingTop")) +parseFloat($slide.css("paddingBottom")) +parseFloat($content.css("marginTop")) +parseFloat($content.css("marginBottom"));if (!width || !height) {width = maxWidth;height = maxHeight;}minRatio = Math.min(1, maxWidth / width, maxHeight / height);width = minRatio * width;height = minRatio * height;// Adjust width/height to precisely fit into containerif (width > maxWidth - 0.5) {width = maxWidth;}if (height > maxHeight - 0.5) {height = maxHeight;}if (slide.type === "image") {rez.top = Math.floor((maxHeight - height) * 0.5) + parseFloat($slide.css("paddingTop"));rez.left = Math.floor((maxWidth - width) * 0.5) + parseFloat($slide.css("paddingLeft"));} else if (slide.contentType === "video") {// Force aspect ratio for the video// "I say the whole world must learn of our peaceful ways… by force!"aspectRatio = slide.opts.width && slide.opts.height ? width / height : slide.opts.ratio || 16 / 9;if (height > width / aspectRatio) {height = width / aspectRatio;} else if (width > height * aspectRatio) {width = height * aspectRatio;}}rez.width = width;rez.height = height;return rez;},// Update content size and position for all slides// ==============================================update: function() {var self = this;$.each(self.slides, function(key, slide) {self.updateSlide(slide);});},// Update slide content position and size// ======================================updateSlide: function(slide) {var self = this,$content = slide && slide.$content,width = slide.width || slide.opts.width,height = slide.height || slide.opts.height,$slide = slide.$slide;if ($content && (width || height || slide.contentType === "video") && !slide.hasError) {$.fancybox.stop($content);$.fancybox.setTranslate($content, self.getFitPos(slide));if (slide.pos === self.currPos) {self.isAnimating = false;self.updateCursor();}}if ($slide.length) {$slide.trigger("refresh");self.$refs.toolbar.toggleClass("compensate-for-scrollbar", $slide.get(0).scrollHeight > $slide.get(0).clientHeight);}self.trigger("onUpdate", slide);},// Horizontally center slide// =========================centerSlide: function(slide, duration) {var self = this,canvasWidth,pos;if (self.current) {canvasWidth = Math.round(slide.$slide.width());pos = slide.pos - self.current.pos;$.fancybox.animate(slide.$slide,{top: 0,left: pos * canvasWidth + pos * slide.opts.gutter,opacity: 1},duration === undefined ? 0 : duration,function() {// Clean up other slidesslide.$slide.siblings().removeAttr("style").removeClass("fancybox-slide--previous fancybox-slide--next");if (!slide.isComplete) {self.complete();}},false);}},// Check if current slide is moved (swiped)// ========================================isMoved: function(slide) {var current = slide || this.current,slidePos,stagePos;if (!current) {return false;}stagePos = $.fancybox.getTranslate(this.$refs.stage);slidePos = $.fancybox.getTranslate(current.$slide);return ((Math.abs(slidePos.top - stagePos.top) > 0 || Math.abs(slidePos.left - stagePos.left) > 0) &&!current.$slide.hasClass("fancybox-animated"));},// Update cursor style depending if content can be zoomed// ======================================================updateCursor: function(nextWidth, nextHeight) {var self = this,current = self.current,$container = self.$refs.container,isZoomable;if (!current || self.isClosing || !self.Guestures) {return;}$container.removeClass("fancybox-is-zoomable fancybox-can-zoomIn fancybox-can-zoomOut fancybox-can-swipe fancybox-can-pan");isZoomable = self.isZoomable();$container.toggleClass("fancybox-is-zoomable", isZoomable);$("[data-fancybox-zoom]").prop("disabled", !isZoomable);if (self.canPan(nextWidth, nextHeight)) {$container.addClass("fancybox-can-pan");} else if (isZoomable &&(current.opts.clickContent === "zoom" || ($.isFunction(current.opts.clickContent) && current.opts.clickContent(current) == "zoom"))) {$container.addClass("fancybox-can-zoomIn");} else if (current.opts.touch && (current.opts.touch.vertical || self.group.length > 1) && current.contentType !== "video") {$container.addClass("fancybox-can-swipe");}},// Check if current slide is zoomable// ==================================isZoomable: function() {var self = this,current = self.current,fitPos;// Assume that slide is zoomable if:// - image is still loading// - actual size of the image is smaller than available areaif (current && !self.isClosing && current.type === "image" && !current.hasError) {if (!current.isLoaded) {return true;}fitPos = self.getFitPos(current);if (current.width > fitPos.width || current.height > fitPos.height) {return true;}}return false;},// Check if current image dimensions are smaller than actual// =========================================================isScaledDown: function(nextWidth, nextHeight) {var self = this,rez = false,current = self.current,$content = current.$content;if (nextWidth !== undefined && nextHeight !== undefined) {rez = nextWidth < current.width && nextHeight < current.height;} else if ($content) {rez = $.fancybox.getTranslate($content);rez = rez.width < current.width && rez.height < current.height;}return rez;},// Check if image dimensions exceed parent element// ===============================================canPan: function(nextWidth, nextHeight) {var self = this,rez = false,current = self.current,$content,pos;if (current.type === "image" && ($content = current.$content) && !current.hasError) {rez = self.getFitPos(current);if (nextWidth !== undefined && nextHeight !== undefined) {pos = {width: nextWidth, height: nextHeight};} else {pos = $.fancybox.getTranslate($content);}rez = Math.abs(pos.width - rez.width) > 1.5 || Math.abs(pos.height - rez.height) > 1.5;}return rez;},// Load content into the slide// ===========================loadSlide: function(slide) {var self = this,type,$slide,ajaxLoad;if (slide.isLoading || slide.isLoaded) {return;}slide.isLoading = true;if (self.trigger("beforeLoad", slide) === false) {slide.isLoading = false;return false;}type = slide.type;$slide = slide.$slide;$slide.off("refresh").trigger("onReset").addClass(slide.opts.slideClass);// Create content depending on the typeswitch (type) {case "image":self.setImage(slide);break;case "iframe":self.setIframe(slide);break;case "html":self.setContent(slide, slide.src || slide.content);break;case "video":self.setContent(slide,slide.opts.video.tpl.replace("{{src}}", slide.src).replace("{{format}}", slide.opts.videoFormat || slide.opts.video.format));break;case "inline":if ($(slide.src).length) {self.setContent(slide, $(slide.src));} else {self.setError(slide);}break;case "ajax":self.showLoading(slide);ajaxLoad = $.ajax($.extend({}, slide.opts.ajax.settings, {url: slide.src,success: function(data, textStatus) {if (textStatus === "success") {self.setContent(slide, data);}},error: function(jqXHR, textStatus) {if (jqXHR && textStatus !== "abort") {self.setError(slide);}}}));$slide.one("onReset", function() {ajaxLoad.abort();});break;default:self.setError(slide);break;}return true;},// Use thumbnail image, if possible// ================================setImage: function(slide) {var self = this,srcset = slide.opts.srcset || slide.opts.image.srcset,thumbSrc,found,temp,pxRatio,windowWidth;// Check if need to show loading iconrequestAFrame(function() {requestAFrame(function() {var $img = slide.$image;if (!self.isClosing && slide.isLoading && (!$img || !$img.length || !$img[0].complete) && !slide.hasError) {self.showLoading(slide);}});});// If we have "srcset", then we need to find first matching "src" value.// This is necessary, because when you set an src attribute, the browser will preload the image// before any javascript or even CSS is applied.if (srcset) {pxRatio = window.devicePixelRatio || 1;windowWidth = window.innerWidth * pxRatio;temp = srcset.split(",").map(function(el) {var ret = {};el.trim().split(/\s+/).forEach(function(el, i) {var value = parseInt(el.substring(0, el.length - 1), 10);if (i === 0) {return (ret.url = el);}if (value) {ret.value = value;ret.postfix = el[el.length - 1];}});return ret;});// Sort by valuetemp.sort(function(a, b) {return a.value - b.value;});// Ok, now we have an array of all srcset valuesfor (var j = 0; j < temp.length; j++) {var el = temp[j];if ((el.postfix === "w" && el.value >= windowWidth) || (el.postfix === "x" && el.value >= pxRatio)) {found = el;break;}}// If not found, take the last oneif (!found && temp.length) {found = temp[temp.length - 1];}if (found) {slide.src = found.url;// If we have default width/height values, we can calculate height for matching sourceif (slide.width && slide.height && found.postfix == "w") {slide.height = (slide.width / slide.height) * found.value;slide.width = found.value;}slide.opts.srcset = srcset;}}// This will be wrapper containing both ghost and actual imageslide.$content = $('<div class="fancybox-content"></div>').addClass("fancybox-is-hidden").appendTo(slide.$slide.addClass("fancybox-slide--image"));// If we have a thumbnail, we can display it while actual image is loading// Users will not stare at black screen and actual image will appear graduallythumbSrc = slide.opts.thumb || (slide.opts.$thumb && slide.opts.$thumb.length ? slide.opts.$thumb.attr("src") : false);if (slide.opts.preload !== false && slide.opts.width && slide.opts.height && thumbSrc) {slide.width = slide.opts.width;slide.height = slide.opts.height;slide.$ghost = $("<img />").one("error", function() {$(this).remove();slide.$ghost = null;}).one("load", function() {self.afterLoad(slide);}).addClass("fancybox-image").appendTo(slide.$content).attr("src", thumbSrc);}// Start loading actual imageself.setBigImage(slide);},// Create full-size image// ======================setBigImage: function(slide) {var self = this,$img = $("<img />");slide.$image = $img.one("error", function() {self.setError(slide);}).one("load", function() {var sizes;if (!slide.$ghost) {self.resolveImageSlideSize(slide, this.naturalWidth, this.naturalHeight);self.afterLoad(slide);}if (self.isClosing) {return;}if (slide.opts.srcset) {sizes = slide.opts.sizes;if (!sizes || sizes === "auto") {sizes =(slide.width / slide.height > 1 && $W.width() / $W.height() > 1 ? "100" : Math.round((slide.width / slide.height) * 100)) +"vw";}$img.attr("sizes", sizes).attr("srcset", slide.opts.srcset);}// Hide temporary image after some delayif (slide.$ghost) {setTimeout(function() {if (slide.$ghost && !self.isClosing) {slide.$ghost.hide();}}, Math.min(300, Math.max(1000, slide.height / 1600)));}self.hideLoading(slide);}).addClass("fancybox-image").attr("src", slide.src).appendTo(slide.$content);if (($img[0].complete || $img[0].readyState == "complete") && $img[0].naturalWidth && $img[0].naturalHeight) {$img.trigger("load");} else if ($img[0].error) {$img.trigger("error");}},// Computes the slide size from image size and maxWidth/maxHeight// ==============================================================resolveImageSlideSize: function(slide, imgWidth, imgHeight) {var maxWidth = parseInt(slide.opts.width, 10),maxHeight = parseInt(slide.opts.height, 10);// Sets the default values from the imageslide.width = imgWidth;slide.height = imgHeight;if (maxWidth > 0) {slide.width = maxWidth;slide.height = Math.floor((maxWidth * imgHeight) / imgWidth);}if (maxHeight > 0) {slide.width = Math.floor((maxHeight * imgWidth) / imgHeight);slide.height = maxHeight;}},// Create iframe wrapper, iframe and bindings// ==========================================setIframe: function(slide) {var self = this,opts = slide.opts.iframe,$slide = slide.$slide,$iframe;slide.$content = $('<div class="fancybox-content' + (opts.preload ? " fancybox-is-hidden" : "") + '"></div>').css(opts.css).appendTo($slide);$slide.addClass("fancybox-slide--" + slide.contentType);slide.$iframe = $iframe = $(opts.tpl.replace(/\{rnd\}/g, new Date().getTime())).attr(opts.attr).appendTo(slide.$content);if (opts.preload) {self.showLoading(slide);// Unfortunately, it is not always possible to determine if iframe is successfully loaded// (due to browser security policy)$iframe.on("load.fb error.fb", function(e) {this.isReady = 1;slide.$slide.trigger("refresh");self.afterLoad(slide);});// Recalculate iframe content size// ===============================$slide.on("refresh.fb", function() {var $content = slide.$content,frameWidth = opts.css.width,frameHeight = opts.css.height,$contents,$body;if ($iframe[0].isReady !== 1) {return;}try {$contents = $iframe.contents();$body = $contents.find("body");} catch (ignore) {}// Calculate contnet dimensions if it is accessibleif ($body && $body.length && $body.children().length) {// Avoid scrolling to top (if multiple instances)$slide.css("overflow", "visible");$content.css({width: "100%","max-width": "100%",height: "9999px"});if (frameWidth === undefined) {frameWidth = Math.ceil(Math.max($body[0].clientWidth, $body.outerWidth(true)));}$content.css("width", frameWidth ? frameWidth : "").css("max-width", "");if (frameHeight === undefined) {frameHeight = Math.ceil(Math.max($body[0].clientHeight, $body.outerHeight(true)));}$content.css("height", frameHeight ? frameHeight : "");$slide.css("overflow", "auto");}$content.removeClass("fancybox-is-hidden");});} else {this.afterLoad(slide);}$iframe.attr("src", slide.src);// Remove iframe if closing or changing gallery item$slide.one("onReset", function() {// This helps IE not to throw errors when closingtry {$(this).find("iframe").hide().unbind().attr("src", "//about:blank");} catch (ignore) {}$(this).off("refresh.fb").empty();slide.isLoaded = false;slide.isRevealed = false;});},// Wrap and append content to the slide// ======================================setContent: function(slide, content) {var self = this;if (self.isClosing) {return;}self.hideLoading(slide);if (slide.$content) {$.fancybox.stop(slide.$content);}slide.$slide.empty();// If content is a jQuery object, then it will be moved to the slide.// The placeholder is created so we will know where to put it back.if (isQuery(content) && content.parent().length) {// Make sure content is not already moved to fancyBoxif (content.hasClass("fancybox-content")) {content.parent(".fancybox-slide--html").trigger("onReset");}// Create temporary element marking original place of the contentslide.$placeholder = $("<div>").hide().insertAfter(content);// Make sure content is visiblecontent.css("display", "inline-block");} else if (!slide.hasError) {// If content is just a plain text, try to convert it to htmlif ($.type(content) === "string") {content = $("<div>").append($.trim(content)).contents();}// If "filter" option is provided, then filter contentif (slide.opts.filter) {content = $("<div>").html(content).find(slide.opts.filter);}}slide.$slide.one("onReset", function() {// Pause all html5 video/audio$(this).find("video,audio").trigger("pause");// Put content backif (slide.$placeholder) {slide.$placeholder.after(content.removeClass("fancybox-content").hide()).remove();slide.$placeholder = null;}// Remove custom close buttonif (slide.$smallBtn) {slide.$smallBtn.remove();slide.$smallBtn = null;}// Remove content and mark slide as not loadedif (!slide.hasError) {$(this).empty();slide.isLoaded = false;slide.isRevealed = false;}});$(content).appendTo(slide.$slide);if ($(content).is("video,audio")) {$(content).addClass("fancybox-video");$(content).wrap("<div></div>");slide.contentType = "video";slide.opts.width = slide.opts.width || $(content).attr("width");slide.opts.height = slide.opts.height || $(content).attr("height");}slide.$content = slide.$slide.children().filter("div,form,main,video,audio,article,.fancybox-content").first();slide.$content.siblings().hide();// Re-check if there is a valid content// (in some cases, ajax response can contain various elements or plain text)if (!slide.$content.length) {slide.$content = slide.$slide.wrapInner("<div></div>").children().first();}slide.$content.addClass("fancybox-content");slide.$slide.addClass("fancybox-slide--" + slide.contentType);this.afterLoad(slide);},// Display error message// =====================setError: function(slide) {slide.hasError = true;slide.$slide.trigger("onReset").removeClass("fancybox-slide--" + slide.contentType).addClass("fancybox-slide--error");slide.contentType = "html";this.setContent(slide, this.translate(slide, slide.opts.errorTpl));if (slide.pos === this.currPos) {this.isAnimating = false;}},// Show loading icon inside the slide// ==================================showLoading: function(slide) {var self = this;slide = slide || self.current;if (slide && !slide.$spinner) {slide.$spinner = $(self.translate(self, self.opts.spinnerTpl)).appendTo(slide.$slide).hide().fadeIn();}},// Remove loading icon from the slide// ==================================hideLoading: function(slide) {var self = this;slide = slide || self.current;if (slide && slide.$spinner) {slide.$spinner.stop().remove();delete slide.$spinner;}},// Adjustments after slide content has been loaded// ===============================================afterLoad: function(slide) {var self = this;if (self.isClosing) {return;}slide.isLoading = false;slide.isLoaded = true;self.trigger("afterLoad", slide);self.hideLoading(slide);if (slide.pos === self.currPos) {self.updateCursor();}if (slide.opts.smallBtn && (!slide.$smallBtn || !slide.$smallBtn.length)) {slide.$smallBtn = $(self.translate(slide, slide.opts.btnTpl.smallBtn)).appendTo(slide.$content);}if (slide.opts.protect && slide.$content && !slide.hasError) {// Disable right clickslide.$content.on("contextmenu.fb", function(e) {if (e.button == 2) {e.preventDefault();}return true;});// Add fake element on top of the image// This makes a bit harder for user to select imageif (slide.type === "image") {$('<div class="fancybox-spaceball"></div>').appendTo(slide.$content);}}self.revealContent(slide);},// Make content visible// This method is called right after content has been loaded or// user navigates gallery and transition should start// ============================================================revealContent: function(slide) {var self = this,$slide = slide.$slide,end = false,start = false,isMoved = self.isMoved(slide),isRevealed = slide.isRevealed,effect,effectClassName,duration,opacity;slide.isRevealed = true;effect = slide.opts[self.firstRun ? "animationEffect" : "transitionEffect"];duration = slide.opts[self.firstRun ? "animationDuration" : "transitionDuration"];duration = parseInt(slide.forcedDuration === undefined ? duration : slide.forcedDuration, 10);// Do not animate if revealing the same slideif (slide.pos === self.currPos) {if (slide.isComplete) {//effect = false;} else {self.isAnimating = true;}}if (isMoved || slide.pos !== self.currPos || !duration) {effect = false;}// Check if can zoomif (effect === "zoom") {if (slide.pos === self.currPos && duration && slide.type === "image" && !slide.hasError && (start = self.getThumbPos(slide))) {end = self.getFitPos(slide);} else {effect = "fade";}}// Zoom animation// ==============if (effect === "zoom") {end.scaleX = end.width / start.width;end.scaleY = end.height / start.height;// Check if we need to animate opacityopacity = slide.opts.zoomOpacity;if (opacity == "auto") {opacity = Math.abs(slide.width / slide.height - start.width / start.height) > 0.1;}if (opacity) {start.opacity = 0.1;end.opacity = 1;}// Draw image at start position$.fancybox.setTranslate(slide.$content.removeClass("fancybox-is-hidden"), start);// Start animation$.fancybox.animate(slide.$content, end, duration, function() {self.isAnimating = false;self.complete();});return;}self.updateSlide(slide);// Simply show content if no effect// ================================if (!effect) {slide.$content.removeClass("fancybox-is-hidden");if (!isRevealed && isMoved && slide.type === "image" && !slide.hasError) {slide.$content.hide().fadeIn("fast");}return;}// Prepare for CSS transiton// =========================$.fancybox.stop($slide);effectClassName = "fancybox-animated fancybox-slide--" + (slide.pos >= self.prevPos ? "next" : "previous") + " fancybox-fx-" + effect;$slide.removeClass("fancybox-slide--current").addClass(effectClassName);slide.$content.removeClass("fancybox-is-hidden");// Force reflow$slide.hide().show(0);$.fancybox.animate($slide,"fancybox-slide--current",duration,function() {$slide.removeClass(effectClassName).removeAttr("style");if (slide.pos === self.currPos) {self.complete();}},true);},// Check if we can and have to zoom from thumbnail//================================================getThumbPos: function(slide) {var self = this,rez = false,$thumb = slide.opts.$thumb,thumbPos = $thumb && $thumb.length && $thumb[0].ownerDocument === document ? $thumb.offset() : 0,slidePos;if (thumbPos && inViewport($thumb) >= 10) {slidePos = self.$refs.stage.offset();rez = {top: thumbPos.top - slidePos.top + parseFloat($thumb.css("border-top-width") || 0),left: thumbPos.left - slidePos.left + parseFloat($thumb.css("border-left-width") || 0),width: $thumb.width(),height: $thumb.height(),scaleX: 1,scaleY: 1};}return rez;},// Final adjustments after current gallery item is moved to position// and it`s content is loaded// ==================================================================complete: function() {var self = this,current = self.current,slides = {},$el;if (self.isMoved() || !current.isLoaded) {return;}if (!current.isComplete) {current.isComplete = true;current.$slide.siblings().trigger("onReset");self.preload("inline");// Trigger any CSS transiton inside the slideforceRedraw(current.$slide);current.$slide.addClass("fancybox-slide--complete");// Remove unnecessary slides$.each(self.slides, function(key, slide) {if (slide.pos >= self.currPos - 1 && slide.pos <= self.currPos + 1) {slides[slide.pos] = slide;} else if (slide) {$.fancybox.stop(slide.$slide);slide.$slide.off().remove();}});self.slides = slides;}self.isAnimating = false;self.updateCursor();self.trigger("afterShow");// Autoplay first html5 video/audioif (!!current.opts.video.autoStart) {current.$slide.find("video,audio").filter(":visible:first").trigger("play").on("ended", $.proxy(self.next, self));}// Try to focus on the first focusable elementif (current.opts.autoFocus && current.contentType === "html") {// Look for the first input with autofocus attribute$el = current.$content.find("input[autofocus]:enabled:visible:first");if ($el.length) {$el.trigger("focus");} else {self.focus(null, true);}}// Avoid jumpingcurrent.$slide.scrollTop(0).scrollLeft(0);},// Preload next and previous slides// ================================preload: function(type) {var self = this,next = self.slides[self.currPos + 1],prev = self.slides[self.currPos - 1];if (prev && prev.type === type) {self.loadSlide(prev);}if (next && next.type === type) {self.loadSlide(next);}},// Try to find and focus on the first focusable element// ====================================================focus: function(e, firstRun) {var self = this,focusableStr = ["a[href]","area[href]",'input:not([disabled]):not([type="hidden"]):not([aria-hidden])',"select:not([disabled]):not([aria-hidden])","textarea:not([disabled]):not([aria-hidden])","button:not([disabled]):not([aria-hidden])","iframe","object","embed","[contenteditable]",'[tabindex]:not([tabindex^="-"])'].join(","),focusableItems,focusedItemIndex;if (self.isClosing) {return;}if (e || !self.current || !self.current.isComplete) {// Focus on any element inside fancyboxfocusableItems = self.$refs.container.find("*:visible");} else {// Focus inside current slidefocusableItems = self.current.$slide.find("*:visible" + (firstRun ? ":not(.fancybox-close-small)" : ""));}focusableItems = focusableItems.filter(focusableStr).filter(function() {return $(this).css("visibility") !== "hidden" && !$(this).hasClass("disabled");});if (focusableItems.length) {focusedItemIndex = focusableItems.index(document.activeElement);if (e && e.shiftKey) {// Back tabif (focusedItemIndex < 0 || focusedItemIndex == 0) {e.preventDefault();focusableItems.eq(focusableItems.length - 1).trigger("focus");}} else {// Outside or Forward tabif (focusedItemIndex < 0 || focusedItemIndex == focusableItems.length - 1) {if (e) {e.preventDefault();}focusableItems.eq(0).trigger("focus");}}} else {self.$refs.container.trigger("focus");}},// Activates current instance - brings container to the front and enables keyboard,// notifies other instances about deactivating// =================================================================================activate: function() {var self = this;// Deactivate all instances$(".fancybox-container").each(function() {var instance = $(this).data("FancyBox");// Skip self and closing instancesif (instance && instance.id !== self.id && !instance.isClosing) {instance.trigger("onDeactivate");instance.removeEvents();instance.isVisible = false;}});self.isVisible = true;if (self.current || self.isIdle) {self.update();self.updateControls();}self.trigger("onActivate");self.addEvents();},// Start closing procedure// This will start "zoom-out" animation if needed and clean everything up afterwards// =================================================================================close: function(e, d) {var self = this,current = self.current,effect,duration,$content,domRect,opacity,start,end;var done = function() {self.cleanUp(e);};if (self.isClosing) {return false;}self.isClosing = true;// If beforeClose callback prevents closing, make sure content is centeredif (self.trigger("beforeClose", e) === false) {self.isClosing = false;requestAFrame(function() {self.update();});return false;}// Remove all events// If there are multiple instances, they will be set again by "activate" methodself.removeEvents();$content = current.$content;effect = current.opts.animationEffect;duration = $.isNumeric(d) ? d : effect ? current.opts.animationDuration : 0;// Remove other slidescurrent.$slide.off(transitionEnd).removeClass("fancybox-slide--complete fancybox-slide--next fancybox-slide--previous fancybox-animated");current.$slide.siblings().trigger("onReset").remove();// Trigger animationsif (duration) {self.$refs.container.removeClass("fancybox-is-open").addClass("fancybox-is-closing");}// Clean upself.hideLoading(current);self.hideControls();self.updateCursor();// Check if possible to zoom-outif (effect === "zoom" &&!(e !== true && $content && duration && current.type === "image" && !current.hasError && (end = self.getThumbPos(current)))) {effect = "fade";}if (effect === "zoom") {$.fancybox.stop($content);domRect = $.fancybox.getTranslate($content);start = {top: domRect.top,left: domRect.left,scaleX: domRect.width / end.width,scaleY: domRect.height / end.height,width: end.width,height: end.height};// Check if we need to animate opacityopacity = current.opts.zoomOpacity;if (opacity == "auto") {opacity = Math.abs(current.width / current.height - end.width / end.height) > 0.1;}if (opacity) {end.opacity = 0;}$.fancybox.setTranslate($content, start);forceRedraw($content);$.fancybox.animate($content, end, duration, done);return true;}if (effect && duration) {// If skip animationif (e === true) {setTimeout(done, duration);} else {$.fancybox.animate(current.$slide.removeClass("fancybox-slide--current"),"fancybox-animated fancybox-slide--previous fancybox-fx-" + effect,duration,done);}} else {done();}return true;},// Final adjustments after removing the instance// =============================================cleanUp: function(e) {var self = this,instance,$focus = self.current.opts.$orig,x,y;self.current.$slide.trigger("onReset");self.$refs.container.empty().remove();self.trigger("afterClose", e);// Place back focusif (!!self.current.opts.backFocus) {if (!$focus || !$focus.length || !$focus.is(":visible")) {$focus = self.$trigger;}if ($focus && $focus.length) {x = window.scrollX;y = window.scrollY;$focus.trigger("focus");$("html, body").scrollTop(y).scrollLeft(x);}}self.current = null;// Check if there are other instancesinstance = $.fancybox.getInstance();if (instance) {instance.activate();} else {$("body").removeClass("fancybox-active compensate-for-scrollbar");$("#fancybox-style-noscroll").remove();}},// Call callback and trigger an event// ==================================trigger: function(name, slide) {var args = Array.prototype.slice.call(arguments, 1),self = this,obj = slide && slide.opts ? slide : self.current,rez;if (obj) {args.unshift(obj);} else {obj = self;}args.unshift(self);if ($.isFunction(obj.opts[name])) {rez = obj.opts[name].apply(obj, args);}if (rez === false) {return rez;}if (name === "afterClose" || !self.$refs) {$D.trigger(name + ".fb", args);} else {self.$refs.container.trigger(name + ".fb", args);}},// Update infobar values, navigation button states and reveal caption// ==================================================================updateControls: function() {var self = this,current = self.current,index = current.index,caption = current.opts.caption,$container = self.$refs.container,$caption = self.$refs.caption;// Recalculate content dimensionscurrent.$slide.trigger("refresh");self.$caption = caption && caption.length ? $caption.html(caption) : null;if (!self.isHiddenControls && !self.isIdle) {self.showControls();}// Update info and navigation elements$container.find("[data-fancybox-count]").html(self.group.length);$container.find("[data-fancybox-index]").html(index + 1);$container.find("[data-fancybox-prev]").prop("disabled", !current.opts.loop && index <= 0);$container.find("[data-fancybox-next]").prop("disabled", !current.opts.loop && index >= self.group.length - 1);if (current.type === "image") {// Re-enable buttons; update download button source$container.find("[data-fancybox-zoom]").show().end().find("[data-fancybox-download]").attr("href", current.opts.image.src || current.src).show();} else if (current.opts.toolbar) {$container.find("[data-fancybox-download],[data-fancybox-zoom]").hide();}// Make sure focus is not on disabled button/elementif ($(document.activeElement).is(":hidden,[disabled]")) {self.$refs.container.trigger("focus");}},// Hide toolbar and caption// ========================hideControls: function() {this.isHiddenControls = true;this.$refs.container.removeClass("fancybox-show-infobar fancybox-show-toolbar fancybox-show-caption fancybox-show-nav");},showControls: function() {var self = this,opts = self.current ? self.current.opts : self.opts,$container = self.$refs.container;self.isHiddenControls = false;self.idleSecondsCounter = 0;$container.toggleClass("fancybox-show-toolbar", !!(opts.toolbar && opts.buttons)).toggleClass("fancybox-show-infobar", !!(opts.infobar && self.group.length > 1)).toggleClass("fancybox-show-caption", !!self.$caption).toggleClass("fancybox-show-nav", !!(opts.arrows && self.group.length > 1)).toggleClass("fancybox-is-modal", !!opts.modal);},// Toggle toolbar and caption// ==========================toggleControls: function() {if (this.isHiddenControls) {this.showControls();} else {this.hideControls();}}});$.fancybox = {version: "3.4.2",defaults: defaults,// Get current instance and execute a command.//// Examples of usage://// $instance = $.fancybox.getInstance();// $.fancybox.getInstance().jumpTo( 1 );// $.fancybox.getInstance( 'jumpTo', 1 );// $.fancybox.getInstance( function() {// console.info( this.currIndex );// });// ======================================================getInstance: function(command) {var instance = $('.fancybox-container:not(".fancybox-is-closing"):last').data("FancyBox"),args = Array.prototype.slice.call(arguments, 1);if (instance instanceof FancyBox) {if ($.type(command) === "string") {instance[command].apply(instance, args);} else if ($.type(command) === "function") {command.apply(instance, args);}return instance;}return false;},// Create new instance// ===================open: function(items, opts, index) {return new FancyBox(items, opts, index);},// Close current or all instances// ==============================close: function(all) {var instance = this.getInstance();if (instance) {instance.close();// Try to find and close next instanceif (all === true) {this.close(all);}}},// Close all instances and unbind all events// =========================================destroy: function() {this.close(true);$D.add("body").off("click.fb-start", "**");},// Try to detect mobile devices// ============================isMobile: /Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent),// Detect if 'translate3d' support is available// ============================================use3d: (function() {var div = document.createElement("div");return (window.getComputedStyle &&window.getComputedStyle(div) &&window.getComputedStyle(div).getPropertyValue("transform") &&!(document.documentMode && document.documentMode < 11));})(),// Helper function to get current visual state of an element// returns array[ top, left, horizontal-scale, vertical-scale, opacity ]// =====================================================================getTranslate: function($el) {var domRect;if (!$el || !$el.length) {return false;}domRect = $el[0].getBoundingClientRect();return {top: domRect.top || 0,left: domRect.left || 0,width: domRect.width,height: domRect.height,opacity: parseFloat($el.css("opacity"))};},// Shortcut for setting "translate3d" properties for element// Can set be used to set opacity, too// ========================================================setTranslate: function($el, props) {var str = "",css = {};if (!$el || !props) {return;}if (props.left !== undefined || props.top !== undefined) {str =(props.left === undefined ? $el.position().left : props.left) +"px, " +(props.top === undefined ? $el.position().top : props.top) +"px";if (this.use3d) {str = "translate3d(" + str + ", 0px)";} else {str = "translate(" + str + ")";}}if (props.scaleX !== undefined && props.scaleY !== undefined) {str += " scale(" + props.scaleX + ", " + props.scaleY + ")";} else if (props.scaleX !== undefined) {str += " scaleX(" + props.scaleX + ")";}if (str.length) {css.transform = str;}if (props.opacity !== undefined) {css.opacity = props.opacity;}if (props.width !== undefined) {css.width = props.width;}if (props.height !== undefined) {css.height = props.height;}return $el.css(css);},// Simple CSS transition handler// =============================animate: function($el, to, duration, callback, leaveAnimationName) {var self = this,final = false,from;if ($.isFunction(duration)) {callback = duration;duration = null;}if (!$.isPlainObject(to)) {$el.removeAttr("style");}self.stop($el);$el.on(transitionEnd, function(e) {// Skip events from child elements and z-index changeif (e && e.originalEvent && (!$el.is(e.originalEvent.target) || e.originalEvent.propertyName == "z-index")) {return;}self.stop($el);if (final) {self.setTranslate($el, final);}if ($.isNumeric(duration)) {$el.css("transition-duration", "");}if ($.isPlainObject(to)) {if (leaveAnimationName === false) {$el.removeAttr("style");}} else if (leaveAnimationName !== true) {$el.removeClass(to);}if ($.isFunction(callback)) {callback(e);}});if ($.isNumeric(duration)) {$el.css("transition-duration", duration + "ms");}// Start animation by changing CSS properties or class nameif ($.isPlainObject(to)) {if (to.scaleX !== undefined && to.scaleY !== undefined) {from = $.fancybox.getTranslate($el);final = $.extend({}, to, {width: from.width * to.scaleX,height: from.height * to.scaleY,scaleX: 1,scaleY: 1});delete to.width;delete to.height;if ($el.parent().hasClass("fancybox-slide--image")) {$el.parent().addClass("fancybox-is-scaling");}}$.fancybox.setTranslate($el, to);} else {$el.addClass(to);}// Make sure that `transitionend` callback gets fired$el.data("timer",setTimeout(function() {$el.trigger("transitionend");}, duration + 16));},stop: function($el, callback) {if ($el && $el.length) {clearTimeout($el.data("timer"));if (callback) {$el.trigger(transitionEnd);}$el.off(transitionEnd).css("transition-duration", "");$el.parent().removeClass("fancybox-is-scaling");}}};// Default click handler for "fancyboxed" links// ============================================function _run(e, opts) {var items = [],index = 0,$target,value,instance;// Avoid opening multiple timesif (e && e.isDefaultPrevented()) {return;}e.preventDefault();opts = opts || {};if (e && e.data) {opts = mergeOpts(e.data.options, opts);}$target = opts.$target || $(e.currentTarget).trigger("blur");instance = $.fancybox.getInstance();if (instance && instance.$trigger && instance.$trigger.is($target)) {return;}if (opts.selector) {items = $(opts.selector);} else {// Get all related items and find index for clicked onevalue = $target.attr("data-fancybox") || "";if (value) {items = e.data ? e.data.items : [];items = items.length ? items.filter('[data-fancybox="' + value + '"]') : $('[data-fancybox="' + value + '"]');} else {items = [$target];}}index = $(items).index($target);// Sometimes current item can not be foundif (index < 0) {index = 0;}instance = $.fancybox.open(items, opts, index);// Save last active elementinstance.$trigger = $target;}// Create a jQuery plugin// ======================$.fn.fancybox = function(options) {var selector;options = options || {};selector = options.selector || false;if (selector) {// Use body element instead of document so it executes first$("body").off("click.fb-start", selector).on("click.fb-start", selector, {options: options}, _run);} else {this.off("click.fb-start").on("click.fb-start",{items: this,options: options},_run);}return this;};// Self initializing plugin for all elements having `data-fancybox` attribute// ==========================================================================$D.on("click.fb-start", "[data-fancybox]", _run);// Enable "trigger elements"// =========================$D.on("click.fb-start", "[data-fancybox-trigger]", function(e) {$('[data-fancybox="' + $(this).attr("data-fancybox-trigger") + '"]').eq($(this).attr("data-fancybox-index") || 0).trigger("click.fb-start", {$trigger: $(this)});});// Track focus event for better accessibility styling// ==================================================(function() {var buttonStr = ".fancybox-button",focusStr = "fancybox-focus",$pressed = null;$D.on("mousedown mouseup focus blur", buttonStr, function(e) {switch (e.type) {case "mousedown":$pressed = $(this);break;case "mouseup":$pressed = null;break;case "focusin":$(buttonStr).removeClass(focusStr);if (!$(this).is($pressed) && !$(this).is("[disabled]")) {$(this).addClass(focusStr);}break;case "focusout":$(buttonStr).removeClass(focusStr);break;}});})();})(window, document, jQuery);// ==========================================================================//// Media// Adds additional media type support//// ==========================================================================(function($) {"use strict";// Object containing properties for each media typevar defaults = {youtube: {matcher: /(youtube\.com|youtu\.be|youtube\-nocookie\.com)\/(watch\?(.*&)?v=|v\/|u\/|embed\/?)?(videoseries\?list=(.*)|[\w-]{11}|\?listType=(.*)&list=(.*))(.*)/i,params: {autoplay: 1,autohide: 1,fs: 1,rel: 0,hd: 1,wmode: "transparent",enablejsapi: 1,html5: 1},paramPlace: 8,type: "iframe",url: "//www.youtube-nocookie.com/embed/$4",thumb: "//img.youtube.com/vi/$4/hqdefault.jpg"},vimeo: {matcher: /^.+vimeo.com\/(.*\/)?([\d]+)(.*)?/,params: {autoplay: 1,hd: 1,show_title: 1,show_byline: 1,show_portrait: 0,fullscreen: 1},paramPlace: 3,type: "iframe",url: "//player.vimeo.com/video/$2"},instagram: {matcher: /(instagr\.am|instagram\.com)\/p\/([a-zA-Z0-9_\-]+)\/?/i,type: "image",url: "//$1/p/$2/media/?size=l"},// Examples:// http://maps.google.com/?ll=48.857995,2.294297&spn=0.007666,0.021136&t=m&z=16// https://www.google.com/maps/@37.7852006,-122.4146355,14.65z// https://www.google.com/maps/@52.2111123,2.9237542,6.61z?hl=en// https://www.google.com/maps/place/Googleplex/@37.4220041,-122.0833494,17z/data=!4m5!3m4!1s0x0:0x6c296c66619367e0!8m2!3d37.4219998!4d-122.0840572gmap_place: {matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(((maps\/(place\/(.*)\/)?\@(.*),(\d+.?\d+?)z))|(\?ll=))(.*)?/i,type: "iframe",url: function(rez) {return ("//maps.google." +rez[2] +"/?ll=" +(rez[9] ? rez[9] + "&z=" + Math.floor(rez[10]) + (rez[12] ? rez[12].replace(/^\//, "&") : "") : rez[12] + "").replace(/\?/, "&") +"&output=" +(rez[12] && rez[12].indexOf("layer=c") > 0 ? "svembed" : "embed"));}},// Examples:// https://www.google.com/maps/search/Empire+State+Building/// https://www.google.com/maps/search/?api=1&query=centurylink+field// https://www.google.com/maps/search/?api=1&query=47.5951518,-122.3316393gmap_search: {matcher: /(maps\.)?google\.([a-z]{2,3}(\.[a-z]{2})?)\/(maps\/search\/)(.*)/i,type: "iframe",url: function(rez) {return "//maps.google." + rez[2] + "/maps?q=" + rez[5].replace("query=", "q=").replace("api=1", "") + "&output=embed";}}};// Formats matching url to final formvar format = function(url, rez, params) {if (!url) {return;}params = params || "";if ($.type(params) === "object") {params = $.param(params, true);}$.each(rez, function(key, value) {url = url.replace("$" + key, value || "");});if (params.length) {url += (url.indexOf("?") > 0 ? "&" : "?") + params;}return url;};$(document).on("objectNeedsType.fb", function(e, instance, item) {var url = item.src || "",type = false,media,thumb,rez,params,urlParams,paramObj,provider;media = $.extend(true, {}, defaults, item.opts.media);// Look for any matching media type$.each(media, function(providerName, providerOpts) {rez = url.match(providerOpts.matcher);if (!rez) {return;}type = providerOpts.type;provider = providerName;paramObj = {};if (providerOpts.paramPlace && rez[providerOpts.paramPlace]) {urlParams = rez[providerOpts.paramPlace];if (urlParams[0] == "?") {urlParams = urlParams.substring(1);}urlParams = urlParams.split("&");for (var m = 0; m < urlParams.length; ++m) {var p = urlParams[m].split("=", 2);if (p.length == 2) {paramObj[p[0]] = decodeURIComponent(p[1].replace(/\+/g, " "));}}}params = $.extend(true, {}, providerOpts.params, item.opts[providerName], paramObj);url =$.type(providerOpts.url) === "function" ? providerOpts.url.call(this, rez, params, item) : format(providerOpts.url, rez, params);thumb =$.type(providerOpts.thumb) === "function" ? providerOpts.thumb.call(this, rez, params, item) : format(providerOpts.thumb, rez);if (providerName === "youtube") {url = url.replace(/&t=((\d+)m)?(\d+)s/, function(match, p1, m, s) {return "&start=" + ((m ? parseInt(m, 10) * 60 : 0) + parseInt(s, 10));});} else if (providerName === "vimeo") {url = url.replace("&%23", "#");}return false;});// If it is found, then change content type and update the urlif (type) {if (!item.opts.thumb && !(item.opts.$thumb && item.opts.$thumb.length)) {item.opts.thumb = thumb;}if (type === "iframe") {item.opts = $.extend(true, item.opts, {iframe: {preload: false,attr: {scrolling: "no"}}});}$.extend(item, {type: type,src: url,origSrc: item.src,contentSource: provider,contentType: type === "image" ? "image" : provider == "gmap_place" || provider == "gmap_search" ? "map" : "video"});} else if (url) {item.type = item.opts.defaultType;}});// Load YouTube/Video API on request to detect when video finished playingvar VideoAPILoader = {youtube: {src: "https://www.youtube.com/iframe_api",class: "YT",loading: false,loaded: false},vimeo: {src: "https://player.vimeo.com/api/player.js",class: "Vimeo",loading: false,loaded: false},load: function(vendor) {var _this = this,script;if (this[vendor].loaded) {setTimeout(function() {_this.done(vendor);});return;}if (this[vendor].loading) {return;}this[vendor].loading = true;script = document.createElement("script");script.type = "text/javascript";script.src = this[vendor].src;if (vendor === "youtube") {window.onYouTubeIframeAPIReady = function() {_this[vendor].loaded = true;_this.done(vendor);};} else {script.onload = function() {_this[vendor].loaded = true;_this.done(vendor);};}document.body.appendChild(script);},done: function(vendor) {var instance, $el, player;if (vendor === "youtube") {delete window.onYouTubeIframeAPIReady;}instance = $.fancybox.getInstance();if (instance) {$el = instance.current.$content.find("iframe");if (vendor === "youtube" && YT !== undefined && YT) {player = new YT.Player($el.attr("id"), {events: {onStateChange: function(e) {if (e.data == 0) {instance.next();}}}});} else if (vendor === "vimeo" && Vimeo !== undefined && Vimeo) {player = new Vimeo.Player($el);player.on("ended", function() {instance.next();});}}}};$(document).on({"afterShow.fb": function(e, instance, current) {if (instance.group.length > 1 && (current.contentSource === "youtube" || current.contentSource === "vimeo")) {VideoAPILoader.load(current.contentSource);}}});})(jQuery);// ==========================================================================//// Guestures// Adds touch guestures, handles click and tap events//// ==========================================================================(function(window, document, $) {"use strict";var requestAFrame = (function() {return (window.requestAnimationFrame ||window.webkitRequestAnimationFrame ||window.mozRequestAnimationFrame ||window.oRequestAnimationFrame ||// if all else fails, use setTimeoutfunction(callback) {return window.setTimeout(callback, 1000 / 60);});})();var cancelAFrame = (function() {return (window.cancelAnimationFrame ||window.webkitCancelAnimationFrame ||window.mozCancelAnimationFrame ||window.oCancelAnimationFrame ||function(id) {window.clearTimeout(id);});})();var getPointerXY = function(e) {var result = [];e = e.originalEvent || e || window.e;e = e.touches && e.touches.length ? e.touches : e.changedTouches && e.changedTouches.length ? e.changedTouches : [e];for (var key in e) {if (e[key].pageX) {result.push({x: e[key].pageX,y: e[key].pageY});} else if (e[key].clientX) {result.push({x: e[key].clientX,y: e[key].clientY});}}return result;};var distance = function(point2, point1, what) {if (!point1 || !point2) {return 0;}if (what === "x") {return point2.x - point1.x;} else if (what === "y") {return point2.y - point1.y;}return Math.sqrt(Math.pow(point2.x - point1.x, 2) + Math.pow(point2.y - point1.y, 2));};var isClickable = function($el) {if ($el.is('a,area,button,[role="button"],input,label,select,summary,textarea,video,audio') ||$.isFunction($el.get(0).onclick) ||$el.data("selectable")) {return true;}// Check for attributes like data-fancybox-next or data-fancybox-closefor (var i = 0, atts = $el[0].attributes, n = atts.length; i < n; i++) {if (atts[i].nodeName.substr(0, 14) === "data-fancybox-") {return true;}}return false;};var hasScrollbars = function(el) {var overflowY = window.getComputedStyle(el)["overflow-y"],overflowX = window.getComputedStyle(el)["overflow-x"],vertical = (overflowY === "scroll" || overflowY === "auto") && el.scrollHeight > el.clientHeight,horizontal = (overflowX === "scroll" || overflowX === "auto") && el.scrollWidth > el.clientWidth;return vertical || horizontal;};var isScrollable = function($el) {var rez = false;while (true) {rez = hasScrollbars($el.get(0));if (rez) {break;}$el = $el.parent();if (!$el.length || $el.hasClass("fancybox-stage") || $el.is("body")) {break;}}return rez;};var Guestures = function(instance) {var self = this;self.instance = instance;self.$bg = instance.$refs.bg;self.$stage = instance.$refs.stage;self.$container = instance.$refs.container;self.destroy();self.$container.on("touchstart.fb.touch mousedown.fb.touch", $.proxy(self, "ontouchstart"));};Guestures.prototype.destroy = function() {this.$container.off(".fb.touch");};Guestures.prototype.ontouchstart = function(e) {var self = this,$target = $(e.target),instance = self.instance,current = instance.current,$slide = current.$slide,$content = current.$content,isTouchDevice = e.type == "touchstart";// Do not respond to both (touch and mouse) eventsif (isTouchDevice) {self.$container.off("mousedown.fb.touch");}// Ignore right clickif (e.originalEvent && e.originalEvent.button == 2) {return;}// Ignore taping on links, buttons, input elementsif (!$slide.length || !$target.length || isClickable($target) || isClickable($target.parent())) {return;}// Ignore clicks on the scrollbarif (!$target.is("img") && e.originalEvent.clientX > $target[0].clientWidth + $target.offset().left) {return;}// Ignore clicks while zooming or closingif (!current || instance.isAnimating || instance.isClosing) {e.stopPropagation();e.preventDefault();return;}self.realPoints = self.startPoints = getPointerXY(e);if (!self.startPoints.length) {return;}// Allow other scripts to catch touch event if "touch" is set to falseif (current.touch) {e.stopPropagation();}self.startEvent = e;self.canTap = !current.$slide.hasClass("fancybox-animated");self.$target = $target;self.$content = $content;self.opts = current.opts.touch;self.isPanning = false;self.isSwiping = false;self.isZooming = false;self.isScrolling = false;self.canPan = instance.canPan();self.startTime = new Date().getTime();self.distanceX = self.distanceY = self.distance = 0;self.canvasWidth = Math.round($slide[0].clientWidth);self.canvasHeight = Math.round($slide[0].clientHeight);self.contentLastPos = null;self.contentStartPos = $.fancybox.getTranslate(self.$content) || {top: 0, left: 0};self.sliderStartPos = self.sliderLastPos || $.fancybox.getTranslate($slide);// Since position will be absolute, but we need to make it relative to the stageself.stagePos = $.fancybox.getTranslate(instance.$refs.stage);self.sliderStartPos.top -= self.stagePos.top;self.sliderStartPos.left -= self.stagePos.left;self.contentStartPos.top -= self.stagePos.top;self.contentStartPos.left -= self.stagePos.left;$(document).off(".fb.touch").on(isTouchDevice ? "touchend.fb.touch touchcancel.fb.touch" : "mouseup.fb.touch mouseleave.fb.touch", $.proxy(self, "ontouchend")).on(isTouchDevice ? "touchmove.fb.touch" : "mousemove.fb.touch", $.proxy(self, "ontouchmove"));if ($.fancybox.isMobile) {document.addEventListener("scroll", self.onscroll, true);}// Skip if clicked outside the sliding areaif (!(self.opts || self.canPan) || !($target.is(self.$stage) || self.$stage.find($target).length)) {if ($target.is(".fancybox-image")) {e.preventDefault();}return;}self.isScrollable = isScrollable($target) || isScrollable($target.parent());// Check if element is scrollable and try to prevent default behavior (scrolling)if (!($.fancybox.isMobile && self.isScrollable)) {e.preventDefault();}// One finger or mouse click - swipe or pan an imageif (self.startPoints.length === 1 || current.hasError) {if (self.canPan) {$.fancybox.stop(self.$content);self.isPanning = true;} else {self.isSwiping = true;}self.$container.addClass("fancybox-is-grabbing");}// Two fingers - zoom imageif (self.startPoints.length === 2 && current.type === "image" && (current.isLoaded || current.$ghost)) {self.canTap = false;self.isSwiping = false;self.isPanning = false;self.isZooming = true;$.fancybox.stop(self.$content);self.centerPointStartX = (self.startPoints[0].x + self.startPoints[1].x) * 0.5 - $(window).scrollLeft();self.centerPointStartY = (self.startPoints[0].y + self.startPoints[1].y) * 0.5 - $(window).scrollTop();self.percentageOfImageAtPinchPointX = (self.centerPointStartX - self.contentStartPos.left) / self.contentStartPos.width;self.percentageOfImageAtPinchPointY = (self.centerPointStartY - self.contentStartPos.top) / self.contentStartPos.height;self.startDistanceBetweenFingers = distance(self.startPoints[0], self.startPoints[1]);}};Guestures.prototype.onscroll = function(e) {var self = this;self.isScrolling = true;document.removeEventListener("scroll", self.onscroll, true);};Guestures.prototype.ontouchmove = function(e) {var self = this;// Make sure user has not released over iframe or disabled elementif (e.originalEvent.buttons !== undefined && e.originalEvent.buttons === 0) {self.ontouchend(e);return;}if (self.isScrolling) {self.canTap = false;return;}self.newPoints = getPointerXY(e);if (!(self.opts || self.canPan) || !self.newPoints.length || !self.newPoints.length) {return;}if (!(self.isSwiping && self.isSwiping === true)) {e.preventDefault();}self.distanceX = distance(self.newPoints[0], self.startPoints[0], "x");self.distanceY = distance(self.newPoints[0], self.startPoints[0], "y");self.distance = distance(self.newPoints[0], self.startPoints[0]);// Skip false ontouchmove events (Chrome)if (self.distance > 0) {if (self.isSwiping) {self.onSwipe(e);} else if (self.isPanning) {self.onPan();} else if (self.isZooming) {self.onZoom();}}};Guestures.prototype.onSwipe = function(e) {var self = this,instance = self.instance,swiping = self.isSwiping,left = self.sliderStartPos.left || 0,angle;// If direction is not yet determinedif (swiping === true) {// We need at least 10px distance to correctly calculate an angleif (Math.abs(self.distance) > 10) {self.canTap = false;if (instance.group.length < 2 && self.opts.vertical) {self.isSwiping = "y";} else if (instance.isDragging || self.opts.vertical === false || (self.opts.vertical === "auto" && $(window).width() > 800)) {self.isSwiping = "x";} else {angle = Math.abs((Math.atan2(self.distanceY, self.distanceX) * 180) / Math.PI);self.isSwiping = angle > 45 && angle < 135 ? "y" : "x";}if (self.isSwiping === "y" && $.fancybox.isMobile && self.isScrollable) {self.isScrolling = true;return;}instance.isDragging = self.isSwiping;// Reset points to avoid jumping, because we dropped first swipes to calculate the angleself.startPoints = self.newPoints;$.each(instance.slides, function(index, slide) {var slidePos, stagePos;$.fancybox.stop(slide.$slide);slidePos = $.fancybox.getTranslate(slide.$slide);stagePos = $.fancybox.getTranslate(instance.$refs.stage);slide.$slide.removeAttr("style").removeClass("fancybox-animated").removeClass(function(index, className) {return (className.match(/(^|\s)fancybox-fx-\S+/g) || []).join(" ");});if (slide.pos === instance.current.pos) {self.sliderStartPos.left = slidePos.left - stagePos.left;}$.fancybox.setTranslate(slide.$slide, {top: slidePos.top - stagePos.top,left: slidePos.left - stagePos.left});});// Stop slideshowif (instance.SlideShow && instance.SlideShow.isActive) {instance.SlideShow.stop();}}return;}// Sticky edgesif (swiping == "x") {if (self.distanceX > 0 &&(self.instance.group.length < 2 || (self.instance.current.index === 0 && !self.instance.current.opts.loop))) {left = left + Math.pow(self.distanceX, 0.8);} else if (self.distanceX < 0 &&(self.instance.group.length < 2 ||(self.instance.current.index === self.instance.group.length - 1 && !self.instance.current.opts.loop))) {left = left - Math.pow(-self.distanceX, 0.8);} else {left = left + self.distanceX;}}self.sliderLastPos = {top: swiping == "x" ? 0 : self.sliderStartPos.top + self.distanceY,left: left};if (self.requestId) {cancelAFrame(self.requestId);self.requestId = null;}self.requestId = requestAFrame(function() {if (self.sliderLastPos) {$.each(self.instance.slides, function(index, slide) {var pos = slide.pos - self.instance.currPos;$.fancybox.setTranslate(slide.$slide, {top: self.sliderLastPos.top,left: self.sliderLastPos.left + pos * self.canvasWidth + pos * slide.opts.gutter});});self.$container.addClass("fancybox-is-sliding");}});};Guestures.prototype.onPan = function() {var self = this;// Prevent accidental movement (sometimes, when tapping casually, finger can move a bit)if (distance(self.newPoints[0], self.realPoints[0]) < ($.fancybox.isMobile ? 10 : 5)) {self.startPoints = self.newPoints;return;}self.canTap = false;self.contentLastPos = self.limitMovement();if (self.requestId) {cancelAFrame(self.requestId);self.requestId = null;}self.requestId = requestAFrame(function() {$.fancybox.setTranslate(self.$content, self.contentLastPos);});};// Make panning sticky to the edgesGuestures.prototype.limitMovement = function() {var self = this;var canvasWidth = self.canvasWidth;var canvasHeight = self.canvasHeight;var distanceX = self.distanceX;var distanceY = self.distanceY;var contentStartPos = self.contentStartPos;var currentOffsetX = contentStartPos.left;var currentOffsetY = contentStartPos.top;var currentWidth = contentStartPos.width;var currentHeight = contentStartPos.height;var minTranslateX, minTranslateY, maxTranslateX, maxTranslateY, newOffsetX, newOffsetY;if (currentWidth > canvasWidth) {newOffsetX = currentOffsetX + distanceX;} else {newOffsetX = currentOffsetX;}newOffsetY = currentOffsetY + distanceY;// Slow down proportionally to traveled distanceminTranslateX = Math.max(0, canvasWidth * 0.5 - currentWidth * 0.5);minTranslateY = Math.max(0, canvasHeight * 0.5 - currentHeight * 0.5);maxTranslateX = Math.min(canvasWidth - currentWidth, canvasWidth * 0.5 - currentWidth * 0.5);maxTranslateY = Math.min(canvasHeight - currentHeight, canvasHeight * 0.5 - currentHeight * 0.5);// ->if (distanceX > 0 && newOffsetX > minTranslateX) {newOffsetX = minTranslateX - 1 + Math.pow(-minTranslateX + currentOffsetX + distanceX, 0.8) || 0;}// <-if (distanceX < 0 && newOffsetX < maxTranslateX) {newOffsetX = maxTranslateX + 1 - Math.pow(maxTranslateX - currentOffsetX - distanceX, 0.8) || 0;}// \/if (distanceY > 0 && newOffsetY > minTranslateY) {newOffsetY = minTranslateY - 1 + Math.pow(-minTranslateY + currentOffsetY + distanceY, 0.8) || 0;}// /\if (distanceY < 0 && newOffsetY < maxTranslateY) {newOffsetY = maxTranslateY + 1 - Math.pow(maxTranslateY - currentOffsetY - distanceY, 0.8) || 0;}return {top: newOffsetY,left: newOffsetX};};Guestures.prototype.limitPosition = function(newOffsetX, newOffsetY, newWidth, newHeight) {var self = this;var canvasWidth = self.canvasWidth;var canvasHeight = self.canvasHeight;if (newWidth > canvasWidth) {newOffsetX = newOffsetX > 0 ? 0 : newOffsetX;newOffsetX = newOffsetX < canvasWidth - newWidth ? canvasWidth - newWidth : newOffsetX;} else {// Center horizontallynewOffsetX = Math.max(0, canvasWidth / 2 - newWidth / 2);}if (newHeight > canvasHeight) {newOffsetY = newOffsetY > 0 ? 0 : newOffsetY;newOffsetY = newOffsetY < canvasHeight - newHeight ? canvasHeight - newHeight : newOffsetY;} else {// Center verticallynewOffsetY = Math.max(0, canvasHeight / 2 - newHeight / 2);}return {top: newOffsetY,left: newOffsetX};};Guestures.prototype.onZoom = function() {var self = this;// Calculate current distance between points to get pinch ratio and new width and heightvar contentStartPos = self.contentStartPos;var currentWidth = contentStartPos.width;var currentHeight = contentStartPos.height;var currentOffsetX = contentStartPos.left;var currentOffsetY = contentStartPos.top;var endDistanceBetweenFingers = distance(self.newPoints[0], self.newPoints[1]);var pinchRatio = endDistanceBetweenFingers / self.startDistanceBetweenFingers;var newWidth = Math.floor(currentWidth * pinchRatio);var newHeight = Math.floor(currentHeight * pinchRatio);// This is the translation due to pinch-zoomingvar translateFromZoomingX = (currentWidth - newWidth) * self.percentageOfImageAtPinchPointX;var translateFromZoomingY = (currentHeight - newHeight) * self.percentageOfImageAtPinchPointY;// Point between the two touchesvar centerPointEndX = (self.newPoints[0].x + self.newPoints[1].x) / 2 - $(window).scrollLeft();var centerPointEndY = (self.newPoints[0].y + self.newPoints[1].y) / 2 - $(window).scrollTop();// And this is the translation due to translation of the centerpoint// between the two fingersvar translateFromTranslatingX = centerPointEndX - self.centerPointStartX;var translateFromTranslatingY = centerPointEndY - self.centerPointStartY;// The new offset is the old/current one plus the total translationvar newOffsetX = currentOffsetX + (translateFromZoomingX + translateFromTranslatingX);var newOffsetY = currentOffsetY + (translateFromZoomingY + translateFromTranslatingY);var newPos = {top: newOffsetY,left: newOffsetX,scaleX: pinchRatio,scaleY: pinchRatio};self.canTap = false;self.newWidth = newWidth;self.newHeight = newHeight;self.contentLastPos = newPos;if (self.requestId) {cancelAFrame(self.requestId);self.requestId = null;}self.requestId = requestAFrame(function() {$.fancybox.setTranslate(self.$content, self.contentLastPos);});};Guestures.prototype.ontouchend = function(e) {var self = this;var swiping = self.isSwiping;var panning = self.isPanning;var zooming = self.isZooming;var scrolling = self.isScrolling;self.endPoints = getPointerXY(e);self.dMs = Math.max(new Date().getTime() - self.startTime, 1);self.$container.removeClass("fancybox-is-grabbing");$(document).off(".fb.touch");document.removeEventListener("scroll", self.onscroll, true);if (self.requestId) {cancelAFrame(self.requestId);self.requestId = null;}self.isSwiping = false;self.isPanning = false;self.isZooming = false;self.isScrolling = false;self.instance.isDragging = false;if (self.canTap) {return self.onTap(e);}self.speed = 100;// Speed in px/msself.velocityX = (self.distanceX / self.dMs) * 0.5;self.velocityY = (self.distanceY / self.dMs) * 0.5;if (panning) {self.endPanning();} else if (zooming) {self.endZooming();} else {self.endSwiping(swiping, scrolling);}return;};Guestures.prototype.endSwiping = function(swiping, scrolling) {var self = this,ret = false,len = self.instance.group.length,velocityX = Math.abs(self.velocityX),distanceX = Math.abs(self.distanceX),canAdvance = swiping == "x" && len > 1 && ((self.dMs > 130 && distanceX > 10) || distanceX > 50),speedX = Math.abs((velocityX * self.canvasWidth) / self.canvasWidth) > 0.8 ? 366 : 500;self.sliderLastPos = null;// Close if swiped vertically / navigate if horizontallyif (swiping == "y" && !scrolling && Math.abs(self.distanceY) > 50) {// Continue vertical movement$.fancybox.animate(self.instance.current.$slide,{top: self.sliderStartPos.top + self.distanceY + self.velocityY * 150,opacity: 0},200);ret = self.instance.close(true, 200);} else if (canAdvance && self.distanceX > 0) {ret = self.instance.previous(speedX);} else if (canAdvance && self.distanceX < 0) {ret = self.instance.next(speedX);}if (ret === false && (swiping == "x" || swiping == "y")) {self.instance.centerSlide(self.instance.current, 150);}self.$container.removeClass("fancybox-is-sliding");};// Limit panning from edges// ========================Guestures.prototype.endPanning = function() {var self = this,newOffsetX,newOffsetY,newPos;if (!self.contentLastPos) {return;}if (self.opts.momentum === false || self.dMs > 350) {newOffsetX = self.contentLastPos.left;newOffsetY = self.contentLastPos.top;} else {// Continue movementnewOffsetX = self.contentLastPos.left + self.velocityX * 500;newOffsetY = self.contentLastPos.top + self.velocityY * 500;}newPos = self.limitPosition(newOffsetX, newOffsetY, self.contentStartPos.width, self.contentStartPos.height);newPos.width = self.contentStartPos.width;newPos.height = self.contentStartPos.height;$.fancybox.animate(self.$content, newPos, 330);};Guestures.prototype.endZooming = function() {var self = this;var current = self.instance.current;var newOffsetX, newOffsetY, newPos, reset;var newWidth = self.newWidth;var newHeight = self.newHeight;if (!self.contentLastPos) {return;}newOffsetX = self.contentLastPos.left;newOffsetY = self.contentLastPos.top;reset = {top: newOffsetY,left: newOffsetX,width: newWidth,height: newHeight,scaleX: 1,scaleY: 1};// Reset scalex/scaleY values; this helps for perfomance and does not break animation$.fancybox.setTranslate(self.$content, reset);if (newWidth < self.canvasWidth && newHeight < self.canvasHeight) {self.instance.scaleToFit(150);} else if (newWidth > current.width || newHeight > current.height) {self.instance.scaleToActual(self.centerPointStartX, self.centerPointStartY, 150);} else {newPos = self.limitPosition(newOffsetX, newOffsetY, newWidth, newHeight);// Switch from scale() to width/height or animation will not work correctly$.fancybox.setTranslate(self.$content, $.fancybox.getTranslate(self.$content));$.fancybox.animate(self.$content, newPos, 150);}};Guestures.prototype.onTap = function(e) {var self = this;var $target = $(e.target);var instance = self.instance;var current = instance.current;var endPoints = (e && getPointerXY(e)) || self.startPoints;var tapX = endPoints[0] ? endPoints[0].x - $(window).scrollLeft() - self.stagePos.left : 0;var tapY = endPoints[0] ? endPoints[0].y - $(window).scrollTop() - self.stagePos.top : 0;var where;var process = function(prefix) {var action = current.opts[prefix];if ($.isFunction(action)) {action = action.apply(instance, [current, e]);}if (!action) {return;}switch (action) {case "close":instance.close(self.startEvent);break;case "toggleControls":instance.toggleControls(true);break;case "next":instance.next();break;case "nextOrClose":if (instance.group.length > 1) {instance.next();} else {instance.close(self.startEvent);}break;case "zoom":if (current.type == "image" && (current.isLoaded || current.$ghost)) {if (instance.canPan()) {instance.scaleToFit();} else if (instance.isScaledDown()) {instance.scaleToActual(tapX, tapY);} else if (instance.group.length < 2) {instance.close(self.startEvent);}}break;}};// Ignore right clickif (e.originalEvent && e.originalEvent.button == 2) {return;}// Skip if clicked on the scrollbarif (!$target.is("img") && tapX > $target[0].clientWidth + $target.offset().left) {return;}// Check where is clickedif ($target.is(".fancybox-bg,.fancybox-inner,.fancybox-outer,.fancybox-container")) {where = "Outside";} else if ($target.is(".fancybox-slide")) {where = "Slide";} else if (instance.current.$content &&instance.current.$content.find($target).addBack().filter($target).length) {where = "Content";} else {return;}// Check if this is a double tapif (self.tapped) {// Stop previously created single tapclearTimeout(self.tapped);self.tapped = null;// Skip if distance between taps is too bigif (Math.abs(tapX - self.tapX) > 50 || Math.abs(tapY - self.tapY) > 50) {return this;}// OK, now we assume that this is a double-tapprocess("dblclick" + where);} else {// Single tap will be processed if user has not clicked second time within 300ms// or there is no need to wait for double-tapself.tapX = tapX;self.tapY = tapY;if (current.opts["dblclick" + where] && current.opts["dblclick" + where] !== current.opts["click" + where]) {self.tapped = setTimeout(function() {self.tapped = null;process("click" + where);}, 500);} else {process("click" + where);}}return this;};$(document).on("onActivate.fb", function(e, instance) {if (instance && !instance.Guestures) {instance.Guestures = new Guestures(instance);}});})(window, document, jQuery);// ==========================================================================//// SlideShow// Enables slideshow functionality//// Example of usage:// $.fancybox.getInstance().SlideShow.start()//// ==========================================================================(function(document, $) {"use strict";$.extend(true, $.fancybox.defaults, {btnTpl: {slideShow:'<button data-fancybox-play class="fancybox-button fancybox-button--play" title="{{PLAY_START}}">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M6.5 5.4v13.2l11-6.6z"/></svg>' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M8.33 5.75h2.2v12.5h-2.2V5.75zm5.15 0h2.2v12.5h-2.2V5.75z"/></svg>' +"</button>"},slideShow: {autoStart: false,speed: 3000,progress: true}});var SlideShow = function(instance) {this.instance = instance;this.init();};$.extend(SlideShow.prototype, {timer: null,isActive: false,$button: null,init: function() {var self = this,instance = self.instance,opts = instance.group[instance.currIndex].opts.slideShow;self.$button = instance.$refs.toolbar.find("[data-fancybox-play]").on("click", function() {self.toggle();});if (instance.group.length < 2 || !opts) {self.$button.hide();} else if (opts.progress) {self.$progress = $('<div class="fancybox-progress"></div>').appendTo(instance.$refs.inner);}},set: function(force) {var self = this,instance = self.instance,current = instance.current;// Check if reached last elementif (current && (force === true || current.opts.loop || instance.currIndex < instance.group.length - 1)) {if (self.isActive && current.contentType !== "video") {if (self.$progress) {$.fancybox.animate(self.$progress.show(), {scaleX: 1}, current.opts.slideShow.speed);}self.timer = setTimeout(function() {instance.jumpTo((instance.currIndex + 1) % instance.group.length);}, current.opts.slideShow.speed);}} else {self.stop();instance.idleSecondsCounter = 0;instance.showControls();}},clear: function() {var self = this;clearTimeout(self.timer);self.timer = null;if (self.$progress) {self.$progress.removeAttr("style").hide();}},start: function() {var self = this,current = self.instance.current;if (current) {self.$button.attr("title", current.opts.i18n[current.opts.lang].PLAY_STOP).removeClass("fancybox-button--play").addClass("fancybox-button--pause");self.isActive = true;if (current.isComplete) {self.set(true);}self.instance.trigger("onSlideShowChange", true);}},stop: function() {var self = this,current = self.instance.current;self.clear();self.$button.attr("title", current.opts.i18n[current.opts.lang].PLAY_START).removeClass("fancybox-button--pause").addClass("fancybox-button--play");self.isActive = false;self.instance.trigger("onSlideShowChange", false);if (self.$progress) {self.$progress.removeAttr("style").hide();}},toggle: function() {var self = this;if (self.isActive) {self.stop();} else {self.start();}}});$(document).on({"onInit.fb": function(e, instance) {if (instance && !instance.SlideShow) {instance.SlideShow = new SlideShow(instance);}},"beforeShow.fb": function(e, instance, current, firstRun) {var SlideShow = instance && instance.SlideShow;if (firstRun) {if (SlideShow && current.opts.slideShow.autoStart) {SlideShow.start();}} else if (SlideShow && SlideShow.isActive) {SlideShow.clear();}},"afterShow.fb": function(e, instance, current) {var SlideShow = instance && instance.SlideShow;if (SlideShow && SlideShow.isActive) {SlideShow.set();}},"afterKeydown.fb": function(e, instance, current, keypress, keycode) {var SlideShow = instance && instance.SlideShow;// "P" or Spacebarif (SlideShow && current.opts.slideShow && (keycode === 80 || keycode === 32) && !$(document.activeElement).is("button,a,input")) {keypress.preventDefault();SlideShow.toggle();}},"beforeClose.fb onDeactivate.fb": function(e, instance) {var SlideShow = instance && instance.SlideShow;if (SlideShow) {SlideShow.stop();}}});// Page Visibility API to pause slideshow when window is not active$(document).on("visibilitychange", function() {var instance = $.fancybox.getInstance(),SlideShow = instance && instance.SlideShow;if (SlideShow && SlideShow.isActive) {if (document.hidden) {SlideShow.clear();} else {SlideShow.set();}}});})(document, jQuery);// ==========================================================================//// FullScreen// Adds fullscreen functionality//// ==========================================================================(function(document, $) {"use strict";// Collection of methods supported by user browservar fn = (function() {var fnMap = [["requestFullscreen", "exitFullscreen", "fullscreenElement", "fullscreenEnabled", "fullscreenchange", "fullscreenerror"],// new WebKit["webkitRequestFullscreen","webkitExitFullscreen","webkitFullscreenElement","webkitFullscreenEnabled","webkitfullscreenchange","webkitfullscreenerror"],// old WebKit (Safari 5.1)["webkitRequestFullScreen","webkitCancelFullScreen","webkitCurrentFullScreenElement","webkitCancelFullScreen","webkitfullscreenchange","webkitfullscreenerror"],["mozRequestFullScreen","mozCancelFullScreen","mozFullScreenElement","mozFullScreenEnabled","mozfullscreenchange","mozfullscreenerror"],["msRequestFullscreen", "msExitFullscreen", "msFullscreenElement", "msFullscreenEnabled", "MSFullscreenChange", "MSFullscreenError"]];var ret = {};for (var i = 0; i < fnMap.length; i++) {var val = fnMap[i];if (val && val[1] in document) {for (var j = 0; j < val.length; j++) {ret[fnMap[0][j]] = val[j];}return ret;}}return false;})();if (fn) {var FullScreen = {request: function(elem) {elem = elem || document.documentElement;elem[fn.requestFullscreen](elem.ALLOW_KEYBOARD_INPUT);},exit: function() {document[fn.exitFullscreen]();},toggle: function(elem) {elem = elem || document.documentElement;if (this.isFullscreen()) {this.exit();} else {this.request(elem);}},isFullscreen: function() {return Boolean(document[fn.fullscreenElement]);},enabled: function() {return Boolean(document[fn.fullscreenEnabled]);}};$.extend(true, $.fancybox.defaults, {btnTpl: {fullScreen:'<button data-fancybox-fullscreen class="fancybox-button fancybox-button--fsenter" title="{{FULL_SCREEN}}">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M7 14H5v5h5v-2H7v-3zm-2-4h2V7h3V5H5v5zm12 7h-3v2h5v-5h-2v3zM14 5v2h3v3h2V5h-5z"/></svg>' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M5 16h3v3h2v-5H5zm3-8H5v2h5V5H8zm6 11h2v-3h3v-2h-5zm2-11V5h-2v5h5V8z"/></svg>' +"</button>"},fullScreen: {autoStart: false}});$(document).on(fn.fullscreenchange, function() {var isFullscreen = FullScreen.isFullscreen(),instance = $.fancybox.getInstance();if (instance) {// If image is zooming, then force to stop and reposition properlyif (instance.current && instance.current.type === "image" && instance.isAnimating) {instance.current.$content.css("transition", "none");instance.isAnimating = false;instance.update(true, true, 0);}instance.trigger("onFullscreenChange", isFullscreen);instance.$refs.container.toggleClass("fancybox-is-fullscreen", isFullscreen);instance.$refs.toolbar.find("[data-fancybox-fullscreen]").toggleClass("fancybox-button--fsenter", !isFullscreen).toggleClass("fancybox-button--fsexit", isFullscreen);}});}$(document).on({"onInit.fb": function(e, instance) {var $container;if (!fn) {instance.$refs.toolbar.find("[data-fancybox-fullscreen]").remove();return;}if (instance && instance.group[instance.currIndex].opts.fullScreen) {$container = instance.$refs.container;$container.on("click.fb-fullscreen", "[data-fancybox-fullscreen]", function(e) {e.stopPropagation();e.preventDefault();FullScreen.toggle();});if (instance.opts.fullScreen && instance.opts.fullScreen.autoStart === true) {FullScreen.request();}// Expose APIinstance.FullScreen = FullScreen;} else if (instance) {instance.$refs.toolbar.find("[data-fancybox-fullscreen]").hide();}},"afterKeydown.fb": function(e, instance, current, keypress, keycode) {// "F"if (instance && instance.FullScreen && keycode === 70) {keypress.preventDefault();instance.FullScreen.toggle();}},"beforeClose.fb": function(e, instance) {if (instance && instance.FullScreen && instance.$refs.container.hasClass("fancybox-is-fullscreen")) {FullScreen.exit();}}});})(document, jQuery);// ==========================================================================//// Thumbs// Displays thumbnails in a grid//// ==========================================================================(function(document, $) {"use strict";var CLASS = "fancybox-thumbs",CLASS_ACTIVE = CLASS + "-active";// Make sure there are default values$.fancybox.defaults = $.extend(true,{btnTpl: {thumbs:'<button data-fancybox-thumbs class="fancybox-button fancybox-button--thumbs" title="{{THUMBS}}">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M14.59 14.59h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76h-3.76v-3.76zm-4.47 0h3.76v3.76H5.65v-3.76zm8.94-4.47h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76h-3.76V5.65zm-4.47 0h3.76v3.76H5.65V5.65z"/></svg>' +"</button>"},thumbs: {autoStart: false, // Display thumbnails on openinghideOnClose: true, // Hide thumbnail grid when closing animation startsparentEl: ".fancybox-container", // Container is injected into this elementaxis: "y" // Vertical (y) or horizontal (x) scrolling}},$.fancybox.defaults);var FancyThumbs = function(instance) {this.init(instance);};$.extend(FancyThumbs.prototype, {$button: null,$grid: null,$list: null,isVisible: false,isActive: false,init: function(instance) {var self = this,first,second;self.instance = instance;instance.Thumbs = self;self.opts = instance.group[instance.currIndex].opts.thumbs;// Enable thumbs if at least two group items have thumbnailsfirst = instance.group[0];first = first.opts.thumb || (first.opts.$thumb && first.opts.$thumb.length ? first.opts.$thumb.attr("src") : false);if (instance.group.length > 1) {second = instance.group[1];second = second.opts.thumb || (second.opts.$thumb && second.opts.$thumb.length ? second.opts.$thumb.attr("src") : false);}self.$button = instance.$refs.toolbar.find("[data-fancybox-thumbs]");if (self.opts && first && second) {self.$button.show().on("click", function() {self.toggle();});self.isActive = true;} else {self.$button.hide();}},create: function() {var self = this,instance = self.instance,parentEl = self.opts.parentEl,list = [],src;if (!self.$grid) {// Create main elementself.$grid = $('<div class="' + CLASS + " " + CLASS + "-" + self.opts.axis + '"></div>').appendTo(instance.$refs.container.find(parentEl).addBack().filter(parentEl));// Add "click" event that performs gallery navigationself.$grid.on("click", "a", function() {instance.jumpTo($(this).attr("data-index"));});}// Build the listif (!self.$list) {self.$list = $('<div class="' + CLASS + '__list">').appendTo(self.$grid);}$.each(instance.group, function(i, item) {src = item.opts.thumb || (item.opts.$thumb ? item.opts.$thumb.attr("src") : null);if (!src && item.type === "image") {src = item.src;}list.push('<a href="javascript:;" tabindex="0" data-index="' +i +'"' +(src && src.length ? ' style="background-image:url(' + src + ')"' : "") +"></a>");});self.$list[0].innerHTML = list.join("");if (self.opts.axis === "x") {// Set fixed width for list element to enable horizontal scrollingself.$list.width(parseInt(self.$grid.css("padding-right"), 10) +instance.group.length *self.$list.children().eq(0).outerWidth(true));}},focus: function(duration) {var self = this,$list = self.$list,$grid = self.$grid,thumb,thumbPos;if (!self.instance.current) {return;}thumb = $list.children().removeClass(CLASS_ACTIVE).filter('[data-index="' + self.instance.current.index + '"]').addClass(CLASS_ACTIVE);thumbPos = thumb.position();// Check if need to scroll to make current thumb visibleif (self.opts.axis === "y" && (thumbPos.top < 0 || thumbPos.top > $list.height() - thumb.outerHeight())) {$list.stop().animate({scrollTop: $list.scrollTop() + thumbPos.top},duration);} else if (self.opts.axis === "x" &&(thumbPos.left < $grid.scrollLeft() || thumbPos.left > $grid.scrollLeft() + ($grid.width() - thumb.outerWidth()))) {$list.parent().stop().animate({scrollLeft: thumbPos.left},duration);}},update: function() {var that = this;that.instance.$refs.container.toggleClass("fancybox-show-thumbs", this.isVisible);if (that.isVisible) {if (!that.$grid) {that.create();}that.instance.trigger("onThumbsShow");that.focus(0);} else if (that.$grid) {that.instance.trigger("onThumbsHide");}// Update content positionthat.instance.update();},hide: function() {this.isVisible = false;this.update();},show: function() {this.isVisible = true;this.update();},toggle: function() {this.isVisible = !this.isVisible;this.update();}});$(document).on({"onInit.fb": function(e, instance) {var Thumbs;if (instance && !instance.Thumbs) {Thumbs = new FancyThumbs(instance);if (Thumbs.isActive && Thumbs.opts.autoStart === true) {Thumbs.show();}}},"beforeShow.fb": function(e, instance, item, firstRun) {var Thumbs = instance && instance.Thumbs;if (Thumbs && Thumbs.isVisible) {Thumbs.focus(firstRun ? 0 : 250);}},"afterKeydown.fb": function(e, instance, current, keypress, keycode) {var Thumbs = instance && instance.Thumbs;// "G"if (Thumbs && Thumbs.isActive && keycode === 71) {keypress.preventDefault();Thumbs.toggle();}},"beforeClose.fb": function(e, instance) {var Thumbs = instance && instance.Thumbs;if (Thumbs && Thumbs.isVisible && Thumbs.opts.hideOnClose !== false) {Thumbs.$grid.hide();}}});})(document, jQuery);//// ==========================================================================//// Share// Displays simple form for sharing current url//// ==========================================================================(function(document, $) {"use strict";$.extend(true, $.fancybox.defaults, {btnTpl: {share:'<button data-fancybox-share class="fancybox-button fancybox-button--share" title="{{SHARE}}">' +'<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 24 24"><path d="M2.55 19c1.4-8.4 9.1-9.8 11.9-9.8V5l7 7-7 6.3v-3.5c-2.8 0-10.5 2.1-11.9 4.2z"/></svg>' +"</button>"},share: {url: function(instance, item) {return ((!instance.currentHash && !(item.type === "inline" || item.type === "html") ? item.origSrc || item.src : false) || window.location);},tpl:'<div class="fancybox-share">' +"<h1>{{SHARE}}</h1>" +"<p>" +'<a class="fancybox-share__button fancybox-share__button--fb" href="https://www.facebook.com/sharer/sharer.php?u={{url}}">' +'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m287 456v-299c0-21 6-35 35-35h38v-63c-7-1-29-3-55-3-54 0-91 33-91 94v306m143-254h-205v72h196" /></svg>' +"<span>Facebook</span>" +"</a>" +'<a class="fancybox-share__button fancybox-share__button--tw" href="https://twitter.com/intent/tweet?url={{url}}&text={{descr}}">' +'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m456 133c-14 7-31 11-47 13 17-10 30-27 37-46-15 10-34 16-52 20-61-62-157-7-141 75-68-3-129-35-169-85-22 37-11 86 26 109-13 0-26-4-37-9 0 39 28 72 65 80-12 3-25 4-37 2 10 33 41 57 77 57-42 30-77 38-122 34 170 111 378-32 359-208 16-11 30-25 41-42z" /></svg>' +"<span>Twitter</span>" +"</a>" +'<a class="fancybox-share__button fancybox-share__button--pt" href="https://www.pinterest.com/pin/create/button/?url={{url}}&description={{descr}}&media={{media}}">' +'<svg viewBox="0 0 512 512" xmlns="http://www.w3.org/2000/svg"><path d="m265 56c-109 0-164 78-164 144 0 39 15 74 47 87 5 2 10 0 12-5l4-19c2-6 1-8-3-13-9-11-15-25-15-45 0-58 43-110 113-110 62 0 96 38 96 88 0 67-30 122-73 122-24 0-42-19-36-44 6-29 20-60 20-81 0-19-10-35-31-35-25 0-44 26-44 60 0 21 7 36 7 36l-30 125c-8 37-1 83 0 87 0 3 4 4 5 2 2-3 32-39 42-75l16-64c8 16 31 29 56 29 74 0 124-67 124-157 0-69-58-132-146-132z" fill="#fff"/></svg>' +"<span>Pinterest</span>" +"</a>" +"</p>" +'<p><input class="fancybox-share__input" type="text" value="{{url_raw}}" onclick="select()" /></p>' +"</div>"}});function escapeHtml(string) {var entityMap = {"&": "&","<": "<",">": ">",'"': ""","'": "'","/": "/","`": "`","=": "="};return String(string).replace(/[&<>"'`=\/]/g, function(s) {return entityMap[s];});}$(document).on("click", "[data-fancybox-share]", function() {var instance = $.fancybox.getInstance(),current = instance.current || null,url,tpl;if (!current) {return;}if ($.type(current.opts.share.url) === "function") {url = current.opts.share.url.apply(current, [instance, current]);}tpl = current.opts.share.tpl.replace(/\{\{media\}\}/g, current.type === "image" ? encodeURIComponent(current.src) : "").replace(/\{\{url\}\}/g, encodeURIComponent(url)).replace(/\{\{url_raw\}\}/g, escapeHtml(url)).replace(/\{\{descr\}\}/g, instance.$caption ? encodeURIComponent(instance.$caption.text()) : "");$.fancybox.open({src: instance.translate(instance, tpl),type: "html",opts: {touch: false,animationEffect: false,afterLoad: function(shareInstance, shareCurrent) {// Close self if parent instance is closinginstance.$refs.container.one("beforeClose.fb", function() {shareInstance.close(null, 0);});// Opening links in a popup windowshareCurrent.$content.find(".fancybox-share__button").click(function() {window.open(this.href, "Share", "width=550, height=450");return false;});},mobile: {autoFocus: false}}});});})(document, jQuery);// ==========================================================================//// Hash// Enables linking to each modal//// ==========================================================================(function(window, document, $) {"use strict";// Simple $.escapeSelector polyfill (for jQuery prior v3)if (!$.escapeSelector) {$.escapeSelector = function(sel) {var rcssescape = /([\0-\x1f\x7f]|^-?\d)|^-$|[^\x80-\uFFFF\w-]/g;var fcssescape = function(ch, asCodePoint) {if (asCodePoint) {// U+0000 NULL becomes U+FFFD REPLACEMENT CHARACTERif (ch === "\0") {return "\uFFFD";}// Control characters and (dependent upon position) numbers get escaped as code pointsreturn ch.slice(0, -1) + "\\" + ch.charCodeAt(ch.length - 1).toString(16) + " ";}// Other potentially-special ASCII characters get backslash-escapedreturn "\\" + ch;};return (sel + "").replace(rcssescape, fcssescape);};}// Get info about gallery name and current index from urlfunction parseUrl() {var hash = window.location.hash.substr(1),rez = hash.split("-"),index = rez.length > 1 && /^\+?\d+$/.test(rez[rez.length - 1]) ? parseInt(rez.pop(-1), 10) || 1 : 1,gallery = rez.join("-");return {hash: hash,/* Index is starting from 1 */index: index < 1 ? 1 : index,gallery: gallery};}// Trigger click evnt on links to open new fancyBox instancefunction triggerFromUrl(url) {if (url.gallery !== "") {// If we can find element matching 'data-fancybox' atribute,// then triggering click event should start fancyBox$("[data-fancybox='" + $.escapeSelector(url.gallery) + "']").eq(url.index - 1).focus().trigger("click.fb-start");}}// Get gallery name from current instancefunction getGalleryID(instance) {var opts, ret;if (!instance) {return false;}opts = instance.current ? instance.current.opts : instance.opts;ret = opts.hash || (opts.$orig ? opts.$orig.data("fancybox") || opts.$orig.data("fancybox-trigger") : "");return ret === "" ? false : ret;}// Start when DOM becomes ready$(function() {// Check if user has disabled this moduleif ($.fancybox.defaults.hash === false) {return;}// Update hash when opening/closing fancyBox$(document).on({"onInit.fb": function(e, instance) {var url, gallery;if (instance.group[instance.currIndex].opts.hash === false) {return;}url = parseUrl();gallery = getGalleryID(instance);// Make sure gallery start index matches index from hashif (gallery && url.gallery && gallery == url.gallery) {instance.currIndex = url.index - 1;}},"beforeShow.fb": function(e, instance, current, firstRun) {var gallery;if (!current || current.opts.hash === false) {return;}// Check if need to update window hashgallery = getGalleryID(instance);if (!gallery) {return;}// Variable containing last hash value set by fancyBox// It will be used to determine if fancyBox needs to close after hash change is detectedinstance.currentHash = gallery + (instance.group.length > 1 ? "-" + (current.index + 1) : "");// If current hash is the same (this instance most likely is opened by hashchange), then do nothingif (window.location.hash === "#" + instance.currentHash) {return;}if (firstRun && !instance.origHash) {instance.origHash = window.location.hash;}if (instance.hashTimer) {clearTimeout(instance.hashTimer);}// Update hashinstance.hashTimer = setTimeout(function() {if ("replaceState" in window.history) {window.history[firstRun ? "pushState" : "replaceState"]({},document.title,window.location.pathname + window.location.search + "#" + instance.currentHash);if (firstRun) {instance.hasCreatedHistory = true;}} else {window.location.hash = instance.currentHash;}instance.hashTimer = null;}, 300);},"beforeClose.fb": function(e, instance, current) {if (current.opts.hash === false) {return;}clearTimeout(instance.hashTimer);// Goto previous history entryif (instance.currentHash && instance.hasCreatedHistory) {window.history.back();} else if (instance.currentHash) {if ("replaceState" in window.history) {window.history.replaceState({}, document.title, window.location.pathname + window.location.search + (instance.origHash || ""));} else {window.location.hash = instance.origHash;}}instance.currentHash = null;}});// Check if need to start/close after url has changed$(window).on("hashchange.fb", function() {var url = parseUrl(),fb = null;// Find last fancyBox instance that has "hash"$.each($(".fancybox-container").get().reverse(),function(index, value) {var tmp = $(value).data("FancyBox");if (tmp && tmp.currentHash) {fb = tmp;return false;}});if (fb) {// Now, compare hash valuesif (fb.currentHash !== url.gallery + "-" + url.index && !(url.index === 1 && fb.currentHash == url.gallery)) {fb.currentHash = null;fb.close();}} else if (url.gallery !== "") {triggerFromUrl(url);}});// Check current hash and trigger click event on matching element to start fancyBox, if neededsetTimeout(function() {if (!$.fancybox.getInstance()) {triggerFromUrl(parseUrl());}}, 50);});})(window, document, jQuery);// ==========================================================================//// Wheel// Basic mouse weheel support for gallery navigation//// ==========================================================================(function(document, $) {"use strict";var prevTime = new Date().getTime();$(document).on({"onInit.fb": function(e, instance, current) {instance.$refs.stage.on("mousewheel DOMMouseScroll wheel MozMousePixelScroll", function(e) {var current = instance.current,currTime = new Date().getTime();if (instance.group.length < 2 || current.opts.wheel === false || (current.opts.wheel === "auto" && current.type !== "image")) {return;}e.preventDefault();e.stopPropagation();if (current.$slide.hasClass("fancybox-animated")) {return;}e = e.originalEvent || e;if (currTime - prevTime < 250) {return;}prevTime = currTime;instance[(-e.deltaY || -e.deltaX || e.wheelDelta || -e.detail) < 0 ? "next" : "previous"]();});}});})(document, jQuery);