PageSourceSearch

https://www.globalfundforwomen.org/wp-content/plugins/bb-plugin/js/libs/jquery.magnificpopup.js?ver=2.11.0.4

js globalfundforwomen.org collected 2026-09-24 08:37:51 UTC 44,375 bytes, 1,967 lines download raw bytes

vendor: 43,945 bytes, lines 1-1946
1/*! Magnific Popup - v1.2.0 - 2024-06-08
2* http://dimsemenov.com/plugins/magnific-popup/
3* Copyright (c) 2024 Dmytro Semenov; */
4;(function (factory) {
5if (typeof define === 'function' && define.amd) {
6 // AMD. Register as an anonymous module.
7 define(['jquery'], factory);
8 } else if (typeof exports === 'object') {
9 // Node/CommonJS
10 factory(require('jquery'));
11 } else {
12 // Browser globals
13 factory(window.jQuery || window.Zepto);
14 }
15 }(function($) {
16
17/*>>core*/
18/**
19 *
20 * Magnific Popup Core JS file
21 *
22 */
23
24
25/**
26 * Private static constants
27 */
28var CLOSE_EVENT = 'Close',
29	BEFORE_CLOSE_EVENT = 'BeforeClose',
30	AFTER_CLOSE_EVENT = 'AfterClose',
31	BEFORE_APPEND_EVENT = 'BeforeAppend',
32	MARKUP_PARSE_EVENT = 'MarkupParse',
33	OPEN_EVENT = 'Open',
34	CHANGE_EVENT = 'Change',
35	NS = 'mfp',
36	EVENT_NS = '.' + NS,
37	READY_CLASS = 'mfp-ready',
38	REMOVING_CLASS = 'mfp-removing',
39	PREVENT_CLOSE_CLASS = 'mfp-prevent-close';
40
41
42/**
43 * Private vars
44 */
45/*jshint -W079 */
46var mfp, // As we have only one instance of MagnificPopup object, we define it locally to not to use 'this'
47	MagnificPopup = function(){},
48	_isJQ = !!(window.jQuery),
49	_prevStatus,
50	_window = $(window),
51	_document,
52	_prevContentType,
53	_wrapClasses,
54	_currPopupType;
55
56
57/**
58 * Private functions
59 */
60var _mfpOn = function(name, f) {
61		mfp.ev.on(NS + name + EVENT_NS, f);
62	},
63	_getEl = function(className, appendTo, html, raw) {
64		var el = document.createElement('div');
65		el.className = 'mfp-'+className;
66		if(html) {
67			el.innerHTML = html;
68		}
69		if(!raw) {
70			el = $(el);
71			if(appendTo) {
72				el.appendTo(appendTo);
73			}
74		} else if(appendTo) {
75			appendTo.appendChild(el);
76		}
77		return el;
78	},
79	_mfpTrigger = function(e, data) {
80		mfp.ev.triggerHandler(NS + e, data);
81
82		if(mfp.st.callbacks) {
83			// converts "mfpEventName" to "eventName" callback and triggers it if it's present
84			e = e.charAt(0).toLowerCase() + e.slice(1);
85			if(mfp.st.callbacks[e]) {
86				mfp.st.callbacks[e].apply(mfp, Array.isArray(data) ? data : [data]);
87			}
88		}
89	},
90	_getCloseBtn = function(type) {
91		if(type !== _currPopupType || !mfp.currTemplate.closeBtn) {
92			mfp.currTemplate.closeBtn = $( mfp.st.closeMarkup.replace(/%title%/g, mfp.st.tClose ) );
93			_currPopupType = type;
94		}
95		return mfp.currTemplate.closeBtn;
96	},
97	// Initialize Magnific Popup only when called at least once
98	_checkInstance = function() {
99		if(!$.magnificPopup.instance) {
100			/*jshint -W020 */
101			mfp = new MagnificPopup();
102			mfp.init();
103			$.magnificPopup.instance = mfp;
104		}
105	},
106	// CSS transition detection, http://stackoverflow.com/questions/7264899/detect-css-transitions-using-javascript-and-without-modernizr
107	supportsTransitions = function() {
108		var s = document.createElement('p').style, // 's' for style. better to create an element if body yet to exist
109			v = ['ms','O','Moz','Webkit']; // 'v' for vendor
110
111		if( s['transition'] !== undefined ) {
112			return true;
113		}
114
115		while( v.length ) {
116			if( v.pop() + 'Transition' in s ) {
117				return true;
118			}
119		}
120
121		return false;
122	};
123
124
125
126/**
127 * Public functions
128 */
129MagnificPopup.prototype = {
130
131	constructor: MagnificPopup,
132
133	/**
134	 * Initializes Magnific Popup plugin.
135	 * This function is triggered only once when $.fn.magnificPopup or $.magnificPopup is executed
136	 */
137	init: function() {
138		var appVersion = navigator.appVersion;
139		mfp.isLowIE = mfp.isIE8 = document.all && !document.addEventListener;
140		mfp.isAndroid = (/android/gi).test(appVersion);
141		mfp.isIOS = (/iphone|ipad|ipod/gi).test(appVersion);
142		mfp.supportsTransition = supportsTransitions();
143
144		// We disable fixed positioned lightbox on devices that don't handle it nicely.
145		// If you know a better way of detecting this - let me know.
146		mfp.probablyMobile = (mfp.isAndroid || mfp.isIOS || /(Opera Mini)|Kindle|webOS|BlackBerry|(Opera Mobi)|(Windows Phone)|IEMobile/i.test(navigator.userAgent) );
147		_document = $(document);
148
149		mfp.popupsCache = {};
150	},
151
152	/**
153	 * Opens popup
154	 * @param  data [description]
155	 */
156	open: function(data) {
157
158		var i;
159
160		if(data.isObj === false) {
161			// convert jQuery collection to array to avoid conflicts later
162			mfp.items = data.items.toArray();
163
164			mfp.index = 0;
165			var items = data.items,
166				item;
167			for(i = 0; i < items.length; i++) {
168				item = items[i];
169				if(item.parsed) {
170					item = item.el[0];
171				}
172				if(item === data.el[0]) {
173					mfp.index = i;
174					break;
175				}
176			}
177		} else {
178			mfp.items = Array.isArray(data.items) ? data.items : [data.items];
179			mfp.index = data.index || 0;
180		}
181
182		// if popup is already opened - we just update the content
183		if(mfp.isOpen) {
184			mfp.updateItemHTML();
185			return;
186		}
187
188		mfp.types = [];
189		_wrapClasses = '';
190		if(data.mainEl && data.mainEl.length) {
191			mfp.ev = data.mainEl.eq(0);
192		} else {
193			mfp.ev = _document;
194		}
195
196		if(data.key) {
197			if(!mfp.popupsCache[data.key]) {
198				mfp.popupsCache[data.key] = {};
199			}
200			mfp.currTemplate = mfp.popupsCache[data.key];
201		} else {
202			mfp.currTemplate = {};
203		}
204
205
206
207		mfp.st = $.extend(true, {}, $.magnificPopup.defaults, data );
208		mfp.fixedContentPos = mfp.st.fixedContentPos === 'auto' ? !mfp.probablyMobile : mfp.st.fixedContentPos;
209
210		if(mfp.st.modal) {
211			mfp.st.closeOnContentClick = false;
212			mfp.st.closeOnBgClick = false;
213			mfp.st.showCloseBtn = false;
214			mfp.st.enableEscapeKey = false;
215		}
216
217
218		// Building markup
219		// main containers are created only once
220		if(!mfp.bgOverlay) {
221
222			// Dark overlay
223			mfp.bgOverlay = _getEl('bg').on('click'+EVENT_NS, function() {
224				mfp.close();
225			});
226
227			mfp.wrap = _getEl('wrap')
228				.attr('tabindex', -1)
229				.attr('role', 'dialog')
230				.attr('aria-modal', true)
231				.attr('aria-label', 'Popup Image')
232				.on('click'+EVENT_NS, function(e) {
233				if(mfp._checkIfClose(e.target)) {
234					mfp.close();
235				}
236			});
237
238			mfp.container = _getEl('container', mfp.wrap);
239		}
240
241		mfp.contentContainer = _getEl('content');
242		if(mfp.st.preloader) {
243			mfp.preloader = _getEl('preloader', mfp.container, mfp.st.tLoading);
244		}
245
246
247		// Initializing modules
248		var modules = $.magnificPopup.modules;
249		for(i = 0; i < modules.length; i++) {
250			var n = modules[i];
251			n = n.charAt(0).toUpperCase() + n.slice(1);
252			mfp['init'+n].call(mfp);
253		}
254		_mfpTrigger('BeforeOpen');
255
256
257		if(mfp.st.showCloseBtn) {
258			// Close button
259			if(!mfp.st.closeBtnInside) {
260				mfp.wrap.append( _getCloseBtn() );
261			} else {
262				_mfpOn(MARKUP_PARSE_EVENT, function(e, template, values, item) {
263					values.close_replaceWith = _getCloseBtn(item.type);
264				});
265				_wrapClasses += ' mfp-close-btn-in';
266			}
267		}
268
269		if(mfp.st.alignTop) {
270			_wrapClasses += ' mfp-align-top';
271		}
272
273
274
275		if(mfp.fixedContentPos) {
276			mfp.wrap.css({
277				overflow: mfp.st.overflowY,
278				overflowX: 'hidden',
279				overflowY: mfp.st.overflowY
280			});
281		} else {
282			mfp.wrap.css({
283				top: _window.scrollTop(),
284				position: 'absolute'
285			});
286		}
287		if( mfp.st.fixedBgPos === false || (mfp.st.fixedBgPos === 'auto' && !mfp.fixedContentPos) ) {
288			mfp.bgOverlay.css({
289				height: _document.height(),
290				position: 'absolute'
291			});
292		}
293
294
295
296		if(mfp.st.enableEscapeKey) {
297			// Close on ESC key
298			_document.on('keyup' + EVENT_NS, function(e) {
299				if(e.keyCode === 27) {
300					mfp.close();
301				}
302			});
303		}
304
305		_window.on('resize' + EVENT_NS, function() {
306			mfp.updateSize();
307		});
308
309
310		if(!mfp.st.closeOnContentClick) {
311			_wrapClasses += ' mfp-auto-cursor';
312		}
313
314		if(_wrapClasses)
315			mfp.wrap.addClass(_wrapClasses);
316
317
318		// this triggers recalculation of layout, so we get it once to not to trigger twice
319		var windowHeight = mfp.wH = _window.height();
320
321
322		var windowStyles = {};
323
324		if( mfp.fixedContentPos ) {
325            if(mfp._hasScrollBar(windowHeight)){
326                var s = mfp._getScrollbarSize();
327                if(s) {
328                    windowStyles.marginRight = s;
329                }
330            }
331        }
332
333		if(mfp.fixedContentPos) {
334			if(!mfp.isIE7) {
335				windowStyles.overflow = 'hidden';
336			} else {
337				// ie7 double-scroll bug
338				$('body, html').css('overflow', 'hidden');
339			}
340		}
341
342
343
344		var classesToadd = mfp.st.mainClass;
345		if(mfp.isIE7) {
346			classesToadd += ' mfp-ie7';
347		}
348		if(classesToadd) {
349			mfp._addClassToMFP( classesToadd );
350		}
351
352		// add content
353		mfp.updateItemHTML();
354
355		_mfpTrigger('BuildControls');
356
357		// remove scrollbar, add margin e.t.c
358		$('html').css(windowStyles);
359
360		// add everything to DOM
361		mfp.bgOverlay.add(mfp.wrap).prependTo( mfp.st.prependTo || $(document.body) );
362
363		// Save last focused element
364		mfp._lastFocusedEl = document.activeElement;
365
366		// Wait for next cycle to allow CSS transition
367		setTimeout(function() {
368
369			if(mfp.content) {
370				mfp._addClassToMFP(READY_CLASS);
371				mfp._setFocus();
372			} else {
373				// if content is not defined (not loaded e.t.c) we add class only for BG
374				mfp.bgOverlay.addClass(READY_CLASS);
375			}
376
377			// Trap the focus in popup
378			_document.on('focusin' + EVENT_NS, mfp._onFocusIn);
379
380		}, 16);
381
382		mfp.isOpen = true;
383		mfp.updateSize(windowHeight);
384		_mfpTrigger(OPEN_EVENT);
385
386		return data;
387	},
388
389	/**
390	 * Closes the popup
391	 */
392	close: function() {
393		if(!mfp.isOpen) return;
394		_mfpTrigger(BEFORE_CLOSE_EVENT);
395
396		mfp.isOpen = false;
397		// for CSS3 animation
398		if(mfp.st.removalDelay && !mfp.isLowIE && mfp.supportsTransition )  {
399			mfp._addClassToMFP(REMOVING_CLASS);
400			setTimeout(function() {
401				mfp._close();
402			}, mfp.st.removalDelay);
403		} else {
404			mfp._close();
405		}
406	},
407
408	/**
409	 * Helper for close() function
410	 */
411	_close: function() {
412		_mfpTrigger(CLOSE_EVENT);
413
414		var classesToRemove = REMOVING_CLASS + ' ' + READY_CLASS + ' ';
415
416		mfp.bgOverlay.detach();
417		mfp.wrap.detach();
418		mfp.container.empty();
419
420		if(mfp.st.mainClass) {
421			classesToRemove += mfp.st.mainClass + ' ';
422		}
423
424		mfp._removeClassFromMFP(classesToRemove);
425
426		if(mfp.fixedContentPos) {
427			var windowStyles = {marginRight: ''};
428			if(mfp.isIE7) {
429				$('body, html').css('overflow', '');
430			} else {
431				windowStyles.overflow = '';
432			}
433			$('html').css(windowStyles);
434		}
435
436		_document.off('keyup' + EVENT_NS + ' focusin' + EVENT_NS);
437		mfp.ev.off(EVENT_NS);
438
439		// clean up DOM elements that aren't removed
440		mfp.wrap.attr('class', 'mfp-wrap').removeAttr('style');
441		mfp.bgOverlay.attr('class', 'mfp-bg');
442		mfp.container.attr('class', 'mfp-container');
443
444		// remove close button from target element
445		if(mfp.st.showCloseBtn &&
446		(!mfp.st.closeBtnInside || mfp.currTemplate[mfp.currItem.type] === true)) {
447			if(mfp.currTemplate.closeBtn)
448				mfp.currTemplate.closeBtn.detach();
449		}
450
451
452		if(mfp.st.autoFocusLast && mfp._lastFocusedEl) {
453			$(mfp._lastFocusedEl).trigger('focus'); // put tab focus back
454		}
455		mfp.currItem = null;
456		mfp.content = null;
457		mfp.currTemplate = null;
458		mfp.prevHeight = 0;
459
460		_mfpTrigger(AFTER_CLOSE_EVENT);
461	},
462
463	updateSize: function(winHeight) {
464
465		if(mfp.isIOS) {
466			// fixes iOS nav bars https://github.com/dimsemenov/Magnific-Popup/issues/2
467			var zoomLevel = document.documentElement.clientWidth / window.innerWidth;
468			var height = window.innerHeight * zoomLevel;
469			mfp.wrap.css('height', height);
470			mfp.wH = height;
471		} else {
472			mfp.wH = winHeight || _window.height();
473		}
474		// Fixes #84: popup incorrectly positioned with position:relative on body
475		if(!mfp.fixedContentPos) {
476			mfp.wrap.css('height', mfp.wH);
477		}
478
479		_mfpTrigger('Resize');
480
481	},
482
483	/**
484	 * Set content of popup based on current index
485	 */
486	updateItemHTML: function() {
487		var item = mfp.items[mfp.index];
488
489		// Detach and perform modifications
490		mfp.contentContainer.detach();
491
492		if(mfp.content)
493			mfp.content.detach();
494
495		if(!item.parsed) {
496			item = mfp.parseEl( mfp.index );
497		}
498
499		var type = item.type;
500
501		_mfpTrigger('BeforeChange', [mfp.currItem ? mfp.currItem.type : '', type]);
502		// BeforeChange event works like so:
503		// _mfpOn('BeforeChange', function(e, prevType, newType) { });
504
505		mfp.currItem = item;
506
507		if(!mfp.currTemplate[type]) {
508			var markup = mfp.st[type] ? mfp.st[type].markup : false;
509
510			// allows to modify markup
511			_mfpTrigger('FirstMarkupParse', markup);
512
513			if(markup) {
514				mfp.currTemplate[type] = $(markup);
515			} else {
516				// if there is no markup found we just define that template is parsed
517				mfp.currTemplate[type] = true;
518			}
519		}
520
521		if(_prevContentType && _prevContentType !== item.type) {
522			mfp.container.removeClass('mfp-'+_prevContentType+'-holder');
523		}
524
525		var newContent = mfp['get' + type.charAt(0).toUpperCase() + type.slice(1)](item, mfp.currTemplate[type]);
526		mfp.appendContent(newContent, type);
527
528		item.preloaded = true;
529
530		_mfpTrigger(CHANGE_EVENT, item);
531		_prevContentType = item.type;
532
533		// Append container back after its content changed
534		mfp.container.prepend(mfp.contentContainer);
535
536		_mfpTrigger('AfterChange');
537	},
538
539
540	/**
541	 * Set HTML content of popup
542	 */
543	appendContent: function(newContent, type) {
544		mfp.content = newContent;
545
546		if(newContent) {
547			if(mfp.st.showCloseBtn && mfp.st.closeBtnInside &&
548				mfp.currTemplate[type] === true) {
549				// if there is no markup, we just append close button element inside
550				if(!mfp.content.find('.mfp-close').length) {
551					mfp.content.append(_getCloseBtn());
552				}
553			} else {
554				mfp.content = newContent;
555			}
556		} else {
557			mfp.content = '';
558		}
559
560		_mfpTrigger(BEFORE_APPEND_EVENT);
561		mfp.container.addClass('mfp-'+type+'-holder');
562
563		mfp.contentContainer.append(mfp.content);
564	},
565
566
567	/**
568	 * Creates Magnific Popup data object based on given data
569	 * @param  {int} index Index of item to parse
570	 */
571	parseEl: function(index) {
572		var item = mfp.items[index],
573			type;
574
575		if(item.tagName) {
576			item = { el: $(item) };
577		} else {
578			type = item.type;
579			item = { data: item, src: item.src };
580		}
581
582		if(item.el) {
583			var types = mfp.types;
584
585			// check for 'mfp-TYPE' class
586			for(var i = 0; i < types.length; i++) {
587				if( item.el.hasClass('mfp-'+types[i]) ) {
588					type = types[i];
589					break;
590				}
591			}
592
593			item.src = item.el.attr('data-mfp-src');
594			if(!item.src) {
595				item.src = item.el.attr('href');
596			}
597		}
598
599		item.type = type || mfp.st.type || 'inline';
600		item.index = index;
601		item.parsed = true;
602		mfp.items[index] = item;
603		_mfpTrigger('ElementParse', item);
604
605		return mfp.items[index];
606	},
607
608
609	/**
610	 * Initializes single popup or a group of popups
611	 */
612	addGroup: function(el, options) {
613		var eHandler = function(e) {
614			e.mfpEl = this;
615			mfp._openClick(e, el, options);
616		};
617
618		if(!options) {
619			options = {};
620		}
621
622		var eName = 'click.magnificPopup';
623		options.mainEl = el;
624
625		if(options.items) {
626			options.isObj = true;
627			el.off(eName).on(eName, eHandler);
628		} else {
629			options.isObj = false;
630			if(options.delegate) {
631				el.off(eName).on(eName, options.delegate , eHandler);
632			} else {
633				options.items = el;
634				el.off(eName).on(eName, eHandler);
635			}
636		}
637	},
638	_openClick: function(e, el, options) {
639		var midClick = options.midClick !== undefined ? options.midClick : $.magnificPopup.defaults.midClick;
640
641
642		if(!midClick && ( e.which === 2 || e.ctrlKey || e.metaKey || e.altKey || e.shiftKey ) ) {
643			return;
644		}
645
646		var disableOn = options.disableOn !== undefined ? options.disableOn : $.magnificPopup.defaults.disableOn;
647
648		if(disableOn) {
649			if(typeof disableOn === "function") {
650				if( !disableOn.call(mfp) ) {
651					return true;
652				}
653			} else { // else it's number
654				if( _window.width() < disableOn ) {
655					return true;
656				}
657			}
658		}
659
660		if(e.type) {
661			e.preventDefault();
662
663			// This will prevent popup from closing if element is inside and popup is already opened
664			if(mfp.isOpen) {
665				e.stopPropagation();
666			}
667		}
668
669		options.el = $(e.mfpEl);
670		if(options.delegate) {
671			options.items = el.find(options.delegate);
672		}
673		mfp.open(options);
674	},
675
676
677	/**
678	 * Updates text on preloader
679	 */
680	updateStatus: function(status, text) {
681
682		if(mfp.preloader) {
683			if(_prevStatus !== status) {
684				mfp.container.removeClass('mfp-s-'+_prevStatus);
685			}
686
687			if(!text && status === 'loading') {
688				text = mfp.st.tLoading;
689			}
690
691			var data = {
692				status: status,
693				text: text
694			};
695			// allows to modify status
696			_mfpTrigger('UpdateStatus', data);
697
698			status = data.status;
699			text = data.text;
700
701			if (mfp.st.allowHTMLInStatusIndicator) {
702				mfp.preloader.html(text);
703			} else {
704				mfp.preloader.text(text);
705			}
706
707			mfp.preloader.find('a').on('click', function(e) {
708				e.stopImmediatePropagation();
709			});
710
711			mfp.container.addClass('mfp-s-'+status);
712			_prevStatus = status;
713		}
714	},
715
716
717	/*
718		"Private" helpers that aren't private at all
719	 */
720	// Check to close popup or not
721	// "target" is an element that was clicked
722	_checkIfClose: function(target) {
723
724		if($(target).closest('.' + PREVENT_CLOSE_CLASS).length) {
725			return;
726		}
727
728		var closeOnContent = mfp.st.closeOnContentClick;
729		var closeOnBg = mfp.st.closeOnBgClick;
730
731		if(closeOnContent && closeOnBg) {
732			return true;
733		} else {
734
735			// We close the popup if click is on close button or on preloader. Or if there is no content.
736			if(!mfp.content || $(target).closest('.mfp-close').length || (mfp.preloader && target === mfp.preloader[0]) ) {
737				return true;
738			}
739
740			// if click is outside the content
741			if(  (target !== mfp.content[0] && !$.contains(mfp.content[0], target))  ) {
742				if(closeOnBg) {
743					// last check, if the clicked element is in DOM, (in case it's removed onclick)
744					if( $.contains(document, target) ) {
745						return true;
746					}
747				}
748			} else if(closeOnContent) {
749				return true;
750			}
751
752		}
753		return false;
754	},
755	_addClassToMFP: function(cName) {
756		mfp.bgOverlay.addClass(cName);
757		mfp.wrap.addClass(cName);
758	},
759	_removeClassFromMFP: function(cName) {
760		this.bgOverlay.removeClass(cName);
761		mfp.wrap.removeClass(cName);
762	},
763	_hasScrollBar: function(winHeight) {
764		return (  (mfp.isIE7 ? _document.height() : document.body.scrollHeight) > (winHeight || _window.height()) );
765	},
766	_setFocus: function() {
767		(mfp.st.focus ? mfp.content.find(mfp.st.focus).eq(0) : mfp.wrap).trigger('focus');
768	},
769	_onFocusIn: function(e) {
770		if( e.target !== mfp.wrap[0] && !$.contains(mfp.wrap[0], e.target) ) {
771			mfp._setFocus();
772			return false;
773		}
774	},
775	_parseMarkup: function(template, values, item) {
776		var arr;
777		if(item.data) {
778			values = $.extend(item.data, values);
779		}
780		_mfpTrigger(MARKUP_PARSE_EVENT, [template, values, item] );
781
782		$.each(values, function(key, value) {
783			if(value === undefined || value === false) {
784				return true;
785			}
786			arr = key.split('_');
787			if(arr.length > 1) {
788				var el = template.find(EVENT_NS + '-'+arr[0]);
789
790				if(el.length > 0) {
791					var attr = arr[1];
792					if(attr === 'replaceWith') {
793						if(el[0] !== value[0]) {
794							el.replaceWith(value);
795						}
796					} else if(attr === 'img') {
797						if(el.is('img')) {
798							el.attr('src', value);
799						} else {
800							el.replaceWith( $('<img>').attr('src', value).attr('class', el.attr('class')) );
801						}
802					} else {
803						el.attr(arr[1], value);
804					}
805				}
806
807			} else {
808				if (mfp.st.allowHTMLInTemplate) {
809					template.find(EVENT_NS + '-'+key).html(value);
810				} else {
811					template.find(EVENT_NS + '-'+key).text(value);
812				}
813			}
814		});
815	},
816
817	_getScrollbarSize: function() {
818		// thx David
819		if(mfp.scrollbarSize === undefined) {
820			var scrollDiv = document.createElement("div");
821			scrollDiv.style.cssText = 'width: 99px; height: 99px; overflow: scroll; position: absolute; top: -9999px;';
822			document.body.appendChild(scrollDiv);
823			mfp.scrollbarSize = scrollDiv.offsetWidth - scrollDiv.clientWidth;
824			document.body.removeChild(scrollDiv);
825		}
826		return mfp.scrollbarSize;
827	}
828
829}; /* MagnificPopup core prototype end */
830
831
832
833
834/**
835 * Public static functions
836 */
837$.magnificPopup = {
838	instance: null,
839	proto: MagnificPopup.prototype,
840	modules: [],
841
842	open: function(options, index) {
843		_checkInstance();
844
845		if(!options) {
846			options = {};
847		} else {
848			options = $.extend(true, {}, options);
849		}
850
851		options.isObj = true;
852		options.index = index || 0;
853		return this.instance.open(options);
854	},
855
856	close: function() {
857		return $.magnificPopup.instance && $.magnificPopup.instance.close();
858	},
859
860	registerModule: function(name, module) {
861		if(module.options) {
862			$.magnificPopup.defaults[name] = module.options;
863		}
864		$.extend(this.proto, module.proto);
865		this.modules.push(name);
866	},
867
868	defaults: {
869
870		// Info about options is in docs:
871		// http://dimsemenov.com/plugins/magnific-popup/documentation.html#options
872
873		disableOn: 0,
874
875		key: null,
876
877		midClick: false,
878
879		mainClass: '',
880
881		preloader: true,
882
883		focus: '', // CSS selector of input to focus after popup is opened
884
885		closeOnContentClick: false,
886
887		closeOnBgClick: true,
888
889		closeBtnInside: true,
890
891		showCloseBtn: true,
892
893		enableEscapeKey: true,
894
895		modal: false,
896
897		alignTop: false,
898
899		removalDelay: 0,
900
901		prependTo: null,
902
903		fixedContentPos: 'auto',
904
905		fixedBgPos: 'auto',
906
907		overflowY: 'auto',
908
909		closeMarkup: '<button title="%title%" type="button" class="mfp-close" aria-label="%title%"><span aria-hidden="true">&times;</span></button>',
910
911		tClose: 'Close (Esc)',
912
913		tLoading: 'Loading...',
914
915		autoFocusLast: true,
916
917		allowHTMLInStatusIndicator: false,
918
919		allowHTMLInTemplate: false
920
921	}
922};
923
924
925
926$.fn.magnificPopup = function(options) {
927	_checkInstance();
928
929	var jqEl = $(this);
930
931	// We call some API method of first param is a string
932	if (typeof options === "string" ) {
933
934		if(options === 'open') {
935			var items,
936				itemOpts = _isJQ ? jqEl.data('magnificPopup') : jqEl[0].magnificPopup,
937				index = parseInt(arguments[1], 10) || 0;
938
939			if(itemOpts.items) {
940				items = itemOpts.items[index];
941			} else {
942				items = jqEl;
943				if(itemOpts.delegate) {
944					items = items.find(itemOpts.delegate);
945				}
946				items = items.eq( index );
947			}
948			mfp._openClick({mfpEl:items}, jqEl, itemOpts);
949		} else {
950			if(mfp.isOpen)
951				mfp[options].apply(mfp, Array.prototype.slice.call(arguments, 1));
952		}
953
954	} else {
955		// clone options obj
956		options = $.extend(true, {}, options);
957
958		/*
959		 * As Zepto doesn't support .data() method for objects
960		 * and it works only in normal browsers
961		 * we assign "options" object directly to the DOM element. FTW!
962		 */
963		if(_isJQ) {
964			jqEl.data('magnificPopup', options);
965		} else {
966			jqEl[0].magnificPopup = options;
967		}
968
969		mfp.addGroup(jqEl, options);
970
971	}
972	return jqEl;
973};
974
975/*>>core*/
976
977/*>>inline*/
978
979var INLINE_NS = 'inline',
980	_hiddenClass,
981	_inlinePlaceholder,
982	_lastInlineElement,
983	_putInlineElementsBack = function() {
984		if(_lastInlineElement) {
985			_inlinePlaceholder.after( _lastInlineElement.addClass(_hiddenClass) ).detach();
986			_lastInlineElement = null;
987		}
988	};
989
990$.magnificPopup.registerModule(INLINE_NS, {
991	options: {
992		hiddenClass: 'hide', // will be appended with `mfp-` prefix
993		markup: '',
994		tNotFound: 'Content not found'
995	},
996	proto: {
997
998		initInline: function() {
999			mfp.types.push(INLINE_NS);
1000
1001			_mfpOn(CLOSE_EVENT+'.'+INLINE_NS, function() {
1002				_putInlineElementsBack();
1003			});
1004		},
1005
1006		getInline: function(item, template) {
1007
1008			_putInlineElementsBack();
1009
1010			if(item.src) {
1011				var inlineSt = mfp.st.inline,
1012					el = $(item.src);
1013
1014				if(el.length) {
1015
1016					// If target element has parent - we replace it with placeholder and put it back after popup is closed
1017					var parent = el[0].parentNode;
1018					if(parent && parent.tagName) {
1019						if(!_inlinePlaceholder) {
1020							_hiddenClass = inlineSt.hiddenClass;
1021							_inlinePlaceholder = _getEl(_hiddenClass);
1022							_hiddenClass = 'mfp-'+_hiddenClass;
1023						}
1024						// replace target inline element with placeholder
1025						_lastInlineElement = el.after(_inlinePlaceholder).detach().removeClass(_hiddenClass);
1026					}
1027
1028					mfp.updateStatus('ready');
1029				} else {
1030					mfp.updateStatus('error', inlineSt.tNotFound);
1031					el = $('<div>');
1032				}
1033
1034				item.inlineElement = el;
1035				return el;
1036			}
1037
1038			mfp.updateStatus('ready');
1039			mfp._parseMarkup(template, {}, item);
1040			return template;
1041		}
1042	}
1043});
1044
1045/*>>inline*/
1046
1047/*>>ajax*/
1048var AJAX_NS = 'ajax',
1049	_ajaxCur,
1050	_removeAjaxCursor = function() {
1051		if(_ajaxCur) {
1052			$(document.body).removeClass(_ajaxCur);
1053		}
1054	},
1055	_destroyAjaxRequest = function() {
1056		_removeAjaxCursor();
1057		if(mfp.req) {
1058			mfp.req.abort();
1059		}
1060	};
1061
1062$.magnificPopup.registerModule(AJAX_NS, {
1063
1064	options: {
1065		settings: null,
1066		cursor: 'mfp-ajax-cur',
1067		tError: 'The content could not be loaded.'
1068	},
1069
1070	proto: {
1071		initAjax: function() {
1072			mfp.types.push(AJAX_NS);
1073			_ajaxCur = mfp.st.ajax.cursor;
1074
1075			_mfpOn(CLOSE_EVENT+'.'+AJAX_NS, _destroyAjaxRequest);
1076			_mfpOn('BeforeChange.' + AJAX_NS, _destroyAjaxRequest);
1077		},
1078		getAjax: function(item) {
1079
1080			if(_ajaxCur) {
1081				$(document.body).addClass(_ajaxCur);
1082			}
1083
1084			mfp.updateStatus('loading');
1085
1086			var opts = $.extend({
1087				url: item.src,
1088				success: function(data, textStatus, jqXHR) {
1089					var temp = {
1090						data:data,
1091						xhr:jqXHR
1092					};
1093
1094					_mfpTrigger('ParseAjax', temp);
1095
1096					mfp.appendContent( $(temp.data), AJAX_NS );
1097
1098					item.finished = true;
1099
1100					_removeAjaxCursor();
1101
1102					mfp._setFocus();
1103
1104					setTimeout(function() {
1105						mfp.wrap.addClass(READY_CLASS);
1106					}, 16);
1107
1108					mfp.updateStatus('ready');
1109
1110					_mfpTrigger('AjaxContentAdded');
1111				},
1112				error: function() {
1113					_removeAjaxCursor();
1114					item.finished = item.loadError = true;
1115					mfp.updateStatus('error', mfp.st.ajax.tError.replace('%url%', item.src));
1116				}
1117			}, mfp.st.ajax.settings);
1118
1119			mfp.req = $.ajax(opts);
1120
1121			return '';
1122		}
1123	}
1124});
1125
1126/*>>ajax*/
1127
1128/*>>image*/
1129var _imgInterval,
1130	_getTitle = function(item) {
1131		if(item.data && item.data.title !== undefined)
1132			return item.data.title;
1133
1134		var src = mfp.st.image.titleSrc;
1135
1136		if(src) {
1137			if(typeof src === "function") {
1138				return src.call(mfp, item);
1139			} else if(item.el) {
1140				return item.el.attr(src) || '';
1141			}
1142		}
1143		return '';
1144	};
1145
1146$.magnificPopup.registerModule('image', {
1147
1148	options: {
1149		markup: '<div class="mfp-figure">'+
1150					'<div class="mfp-close"></div>'+
1151					'<figure>'+
1152						'<div class="mfp-img"></div>'+
1153						'<figcaption>'+
1154							'<div class="mfp-bottom-bar">'+
1155								'<div class="mfp-title"></div>'+
1156								'<div class="mfp-counter"></div>'+
1157							'</div>'+
1158						'</figcaption>'+
1159					'</figure>'+
1160				'</div>',
1161		cursor: 'mfp-zoom-out-cur',
1162		titleSrc: 'title',
1163		verticalFit: true,
1164		tError: 'The image could not be loaded.'
1165	},
1166
1167	proto: {
1168		initImage: function() {
1169			var imgSt = mfp.st.image,
1170				ns = '.image';
1171
1172			mfp.types.push('image');
1173
1174			_mfpOn(OPEN_EVENT+ns, function() {
1175				if(mfp.currItem.type === 'image' && imgSt.cursor) {
1176					$(document.body).addClass(imgSt.cursor);
1177				}
1178			});
1179
1180			_mfpOn(CLOSE_EVENT+ns, function() {
1181				if(imgSt.cursor) {
1182					$(document.body).removeClass(imgSt.cursor);
1183				}
1184				_window.off('resize' + EVENT_NS);
1185			});
1186
1187			_mfpOn('Resize'+ns, mfp.resizeImage);
1188			if(mfp.isLowIE) {
1189				_mfpOn('AfterChange', mfp.resizeImage);
1190			}
1191		},
1192		resizeImage: function() {
1193			var item = mfp.currItem;
1194			if(!item || !item.img) return;
1195
1196			if(mfp.st.image.verticalFit) {
1197				var decr = 0;
1198				// fix box-sizing in ie7/8
1199				if(mfp.isLowIE) {
1200					decr = parseInt(item.img.css('padding-top'), 10) + parseInt(item.img.css('padding-bottom'),10);
1201				}
1202				item.img.css('max-height', mfp.wH-decr);
1203			}
1204		},
1205		_onImageHasSize: function(item) {
1206			if(item.img) {
1207
1208				item.hasSize = true;
1209
1210				if(_imgInterval) {
1211					clearInterval(_imgInterval);
1212				}
1213
1214				item.isCheckingImgSize = false;
1215
1216				_mfpTrigger('ImageHasSize', item);
1217
1218				if(item.imgHidden) {
1219					if(mfp.content)
1220						mfp.content.removeClass('mfp-loading');
1221
1222					item.imgHidden = false;
1223				}
1224
1225			}
1226		},
1227
1228		/**
1229		 * Function that loops until the image has size to display elements that rely on it asap
1230		 */
1231		findImageSize: function(item) {
1232
1233			var counter = 0,
1234				img = item.img[0],
1235				mfpSetInterval = function(delay) {
1236
1237					if(_imgInterval) {
1238						clearInterval(_imgInterval);
1239					}
1240					// decelerating interval that checks for size of an image
1241					_imgInterval = setInterval(function() {
1242						if(img.naturalWidth > 0) {
1243							mfp._onImageHasSize(item);
1244							return;
1245						}
1246
1247						if(counter > 200) {
1248							clearInterval(_imgInterval);
1249						}
1250
1251						counter++;
1252						if(counter === 3) {
1253							mfpSetInterval(10);
1254						} else if(counter === 40) {
1255							mfpSetInterval(50);
1256						} else if(counter === 100) {
1257							mfpSetInterval(500);
1258						}
1259					}, delay);
1260				};
1261
1262			mfpSetInterval(1);
1263		},
1264
1265		getImage: function(item, template) {
1266
1267			var guard = 0,
1268
1269				imgSt = mfp.st.image,
1270
1271				// image error handler
1272				onLoadError = function() {
1273					if(item) {
1274						item.img.off('.mfploader');
1275						if(item === mfp.currItem){
1276							mfp._onImageHasSize(item);
1277							mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
1278						}
1279
1280						item.hasSize = true;
1281						item.loaded = true;
1282						item.loadError = true;
1283					}
1284				},
1285
1286				// image load complete handler
1287				onLoadComplete = function() {
1288					if(item) {
1289						if (item.img[0].complete) {
1290							item.img.off('.mfploader');
1291
1292							if(item === mfp.currItem){
1293								mfp._onImageHasSize(item);
1294
1295								mfp.updateStatus('ready');
1296							}
1297
1298							item.hasSize = true;
1299							item.loaded = true;
1300
1301							_mfpTrigger('ImageLoadComplete');
1302
1303						}
1304						else {
1305							// if image complete check fails 200 times (20 sec), we assume that there was an error.
1306							guard++;
1307							if(guard < 200) {
1308								setTimeout(onLoadComplete,100);
1309							} else {
1310								onLoadError();
1311							}
1312						}
1313					}
1314				};
1315
1316
1317
1318			var el = template.find('.mfp-img');
1319			if(el.length) {
1320				var img = document.createElement('img');
1321				img.className = 'mfp-img';
1322				if(item.el && item.el.find('img').length) {
1323					img.alt = item.el.find('img').attr('alt');
1324				}
1325				item.img = $(img).on('load.mfploader', onLoadComplete).on('error.mfploader', onLoadError);
1326				img.src = item.src;
1327
1328				// without clone() "error" event is not firing when IMG is replaced by new IMG
1329				// TODO: find a way to avoid such cloning
1330				if(el.is('img')) {
1331					item.img = item.img.clone();
1332				}
1333
1334				img = item.img[0];
1335				if(img.naturalWidth > 0) {
1336					item.hasSize = true;
1337				} else if(!img.width) {
1338					item.hasSize = false;
1339				}
1340			}
1341
1342			mfp._parseMarkup(template, {
1343				title: _getTitle(item),
1344				img_replaceWith: item.img
1345			}, item);
1346
1347			mfp.resizeImage();
1348
1349			if(item.hasSize) {
1350				if(_imgInterval) clearInterval(_imgInterval);
1351
1352				if(item.loadError) {
1353					template.addClass('mfp-loading');
1354					mfp.updateStatus('error', imgSt.tError.replace('%url%', item.src) );
1355				} else {
1356					template.removeClass('mfp-loading');
1357					mfp.updateStatus('ready');
1358				}
1359				return template;
1360			}
1361
1362			mfp.updateStatus('loading');
1363			item.loading = true;
1364
1365			if(!item.hasSize) {
1366				item.imgHidden = true;
1367				template.addClass('mfp-loading');
1368				mfp.findImageSize(item);
1369			}
1370
1371			return template;
1372		}
1373	}
1374});
1375
1376/*>>image*/
1377
1378/*>>zoom*/
1379var hasMozTransform,
1380	getHasMozTransform = function() {
1381		if(hasMozTransform === undefined) {
1382			hasMozTransform = document.createElement('p').style.MozTransform !== undefined;
1383		}
1384		return hasMozTransform;
1385	};
1386
1387$.magnificPopup.registerModule('zoom', {
1388
1389	options: {
1390		enabled: false,
1391		easing: 'ease-in-out',
1392		duration: 300,
1393		opener: function(element) {
1394			return element.is('img') ? element : element.find('img');
1395		}
1396	},
1397
1398	proto: {
1399
1400		initZoom: function() {
1401			var zoomSt = mfp.st.zoom,
1402				ns = '.zoom',
1403				image;
1404
1405			if(!zoomSt.enabled || !mfp.supportsTransition) {
1406				return;
1407			}
1408
1409			var duration = zoomSt.duration,
1410				getElToAnimate = function(image) {
1411					var newImg = image.clone().removeAttr('style').removeAttr('class').addClass('mfp-animated-image'),
1412						transition = 'all '+(zoomSt.duration/1000)+'s ' + zoomSt.easing,
1413						cssObj = {
1414							position: 'fixed',
1415							zIndex: 9999,
1416							left: 0,
1417							top: 0,
1418							'-webkit-backface-visibility': 'hidden'
1419						},
1420						t = 'transition';
1421
1422					cssObj['-webkit-'+t] = cssObj['-moz-'+t] = cssObj['-o-'+t] = cssObj[t] = transition;
1423
1424					newImg.css(cssObj);
1425					return newImg;
1426				},
1427				showMainContent = function() {
1428					mfp.content.css('visibility', 'visible');
1429				},
1430				openTimeout,
1431				animatedImg;
1432
1433			_mfpOn('BuildControls'+ns, function() {
1434				if(mfp._allowZoom()) {
1435
1436					clearTimeout(openTimeout);
1437					mfp.content.css('visibility', 'hidden');
1438
1439					// Basically, all code below does is clones existing image, puts in on top of the current one and animated it
1440
1441					image = mfp._getItemToZoom();
1442
1443					if(!image) {
1444						showMainContent();
1445						return;
1446					}
1447
1448					animatedImg = getElToAnimate(image);
1449
1450					animatedImg.css( mfp._getOffset() );
1451
1452					mfp.wrap.append(animatedImg);
1453
1454					openTimeout = setTimeout(function() {
1455						animatedImg.css( mfp._getOffset( true ) );
1456						openTimeout = setTimeout(function() {
1457
1458							showMainContent();
1459
1460							setTimeout(function() {
1461								animatedImg.remove();
1462								image = animatedImg = null;
1463								_mfpTrigger('ZoomAnimationEnded');
1464							}, 16); // avoid blink when switching images
1465
1466						}, duration); // this timeout equals animation duration
1467
1468					}, 16); // by adding this timeout we avoid short glitch at the beginning of animation
1469
1470
1471					// Lots of timeouts...
1472				}
1473			});
1474			_mfpOn(BEFORE_CLOSE_EVENT+ns, function() {
1475				if(mfp._allowZoom()) {
1476
1477					clearTimeout(openTimeout);
1478
1479					mfp.st.removalDelay = duration;
1480
1481					if(!image) {
1482						image = mfp._getItemToZoom();
1483						if(!image) {
1484							return;
1485						}
1486						animatedImg = getElToAnimate(image);
1487					}
1488
1489					animatedImg.css( mfp._getOffset(true) );
1490					mfp.wrap.append(animatedImg);
1491					mfp.content.css('visibility', 'hidden');
1492
1493					setTimeout(function() {
1494						animatedImg.css( mfp._getOffset() );
1495					}, 16);
1496				}
1497
1498			});
1499
1500			_mfpOn(CLOSE_EVENT+ns, function() {
1501				if(mfp._allowZoom()) {
1502					showMainContent();
1503					if(animatedImg) {
1504						animatedImg.remove();
1505					}
1506					image = null;
1507				}
1508			});
1509		},
1510
1511		_allowZoom: function() {
1512			return mfp.currItem.type === 'image';
1513		},
1514
1515		_getItemToZoom: function() {
1516			if(mfp.currItem.hasSize) {
1517				return mfp.currItem.img;
1518			} else {
1519				return false;
1520			}
1521		},
1522
1523		// Get element postion relative to viewport
1524		_getOffset: function(isLarge) {
1525			var el;
1526			if(isLarge) {
1527				el = mfp.currItem.img;
1528			} else {
1529				el = mfp.st.zoom.opener(mfp.currItem.el || mfp.currItem);
1530			}
1531
1532			var offset = el.offset();
1533			var paddingTop = parseInt(el.css('padding-top'),10);
1534			var paddingBottom = parseInt(el.css('padding-bottom'),10);
1535			offset.top -= ( $(window).scrollTop() - paddingTop );
1536
1537
1538			/*
1539
1540			Animating left + top + width/height looks glitchy in Firefox, but perfect in Chrome. And vice-versa.
1541
1542			 */
1543			var obj = {
1544				width: el.width(),
1545				// fix Zepto height+padding issue
1546				height: (_isJQ ? el.innerHeight() : el[0].offsetHeight) - paddingBottom - paddingTop
1547			};
1548
1549			// I hate to do this, but there is no another option
1550			if( getHasMozTransform() ) {
1551				obj['-moz-transform'] = obj['transform'] = 'translate(' + offset.left + 'px,' + offset.top + 'px)';
1552			} else {
1553				obj.left = offset.left;
1554				obj.top = offset.top;
1555			}
1556			return obj;
1557		}
1558
1559	}
1560});
1561
1562
1563
1564/*>>zoom*/
1565
1566/*>>iframe*/
1567
1568var IFRAME_NS = 'iframe',
1569	_emptyPage = '//about:blank',
1570
1571	_fixIframeBugs = function(isShowing) {
1572		if(mfp.currTemplate[IFRAME_NS]) {
1573			var el = mfp.currTemplate[IFRAME_NS].find('iframe');
1574			if(el.length) {
1575				// reset src after the popup is closed to avoid "video keeps playing after popup is closed" bug
1576				if(!isShowing) {
1577					el[0].src = _emptyPage;
1578				}
1579
1580				// IE8 black screen bug fix
1581				if(mfp.isIE8) {
1582					el.css('display', isShowing ? 'block' : 'none');
1583				}
1584			}
1585		}
1586	};
1587
1588$.magnificPopup.registerModule(IFRAME_NS, {
1589
1590	options: {
1591		markup: '<div class="mfp-iframe-scaler">'+
1592					'<div class="mfp-close"></div>'+
1593					'<iframe class="mfp-iframe" src="//about:blank" frameborder="0" allowfullscreen></iframe>'+
1594				'</div>',
1595
1596		srcAction: 'iframe_src',
1597
1598		// we don't care and support only one default type of URL by default
1599		patterns: {
1600			youtube: {
1601				index: 'youtube.com',
1602				id: 'v=',
1603				src: '//www.youtube.com/embed/%id%?autoplay=1'
1604			},
1605			youtu_be: {
1606				index: 'youtu.be',
1607				id: '/',
1608				src: '//www.youtube.com/embed/%id%?autoplay=1',
1609			},
1610			youtube_nocookie: {
1611				index: 'youtube-nocookie.com',
1612				id: '/',
1613				src: '//www.youtube-nocookie.com/embed/%id%?autoplay=1',
1614			},
1615			vimeo: {
1616				index: 'vimeo.com/',
1617				id: '/',
1618				src: '//player.vimeo.com/video/%id%?autoplay=1'
1619			},
1620			gmaps: {
1621				index: '//maps.google.',
1622				src: '%id%&output=embed'
1623			}
1624		}
1625	},
1626
1627	proto: {
1628		initIframe: function() {
1629			mfp.types.push(IFRAME_NS);
1630
1631			_mfpOn('BeforeChange', function(e, prevType, newType) {
1632				if(prevType !== newType) {
1633					if(prevType === IFRAME_NS) {
1634						_fixIframeBugs(); // iframe if removed
1635					} else if(newType === IFRAME_NS) {
1636						_fixIframeBugs(true); // iframe is showing
1637					}
1638				}// else {
1639					// iframe source is switched, don't do anything
1640				//}
1641			});
1642
1643			_mfpOn(CLOSE_EVENT + '.' + IFRAME_NS, function() {
1644				_fixIframeBugs();
1645			});
1646		},
1647
1648		getIframe: function(item, template) {
1649			var embedSrc = item.src;
1650			var iframeSt = mfp.st.iframe;
1651
1652			$.each(iframeSt.patterns, function() {
1653				if(embedSrc.indexOf( this.index ) > -1) {
1654					if(this.id) {
1655						if(typeof this.id === 'string') {
1656							embedSrc = embedSrc.substr(embedSrc.lastIndexOf(this.id)+this.id.length, embedSrc.length);
1657						} else {
1658							embedSrc = this.id.call( this, embedSrc );
1659						}
1660					}
1661					embedSrc = this.src.replace('%id%', embedSrc );
1662					return false; // break;
1663				}
1664			});
1665
1666			var dataObj = {};
1667			if(iframeSt.srcAction) {
1668				dataObj[iframeSt.srcAction] = embedSrc;
1669			}
1670
1671			mfp._parseMarkup(template, dataObj, item);
1672
1673			mfp.updateStatus('ready');
1674
1675			return template;
1676		}
1677	}
1678});
1679
1680
1681
1682/*>>iframe*/
1683
1684/*>>gallery*/
1685/**
1686 * Get looped index depending on number of slides
1687 */
1688var _getLoopedId = function(index) {
1689		var numSlides = mfp.items.length;
1690		if(index > numSlides - 1) {
1691			return index - numSlides;
1692		} else  if(index < 0) {
1693			return numSlides + index;
1694		}
1695		return index;
1696	},
1697	_replaceCurrTotal = function(text, curr, total) {
1698		return text.replace(/%curr%/gi, curr + 1).replace(/%total%/gi, total);
1699	};
1700
1701$.magnificPopup.registerModule('gallery', {
1702
1703	options: {
1704		enabled: false,
1705		arrowMarkup: '<button title="%title%" type="button" class="mfp-arrow mfp-arrow-%dir%"></button>',
1706		preload: [0,2],
1707		navigateByImgClick: true,
1708		arrows: true,
1709
1710		tPrev: 'Previous (Left arrow key)',
1711		tNext: 'Next (Right arrow key)',
1712		tCounter: '%curr% of %total%',
1713
1714		langDir: null,
1715		loop: true,
1716	},
1717
1718	proto: {
1719		initGallery: function() {
1720
1721			var gSt = mfp.st.gallery,
1722				ns = '.mfp-gallery';
1723
1724			mfp.direction = true; // true - next, false - prev
1725
1726			if(!gSt || !gSt.enabled ) return false;
1727
1728			if (!gSt.langDir) {
1729				gSt.langDir = document.dir || 'ltr';
1730			}
1731
1732			_wrapClasses += ' mfp-gallery';
1733
1734			_mfpOn(OPEN_EVENT+ns, function() {
1735
1736				if(gSt.navigateByImgClick) {
1737					mfp.wrap.on('click'+ns, '.mfp-img', function() {
1738						if(mfp.items.length > 1) {
1739							mfp.next();
1740							return false;
1741						}
1742					});
1743				}
1744
1745				_document.on('keydown'+ns, function(e) {
1746					if (e.keyCode === 37) {
1747						if (gSt.langDir === 'rtl') mfp.next();
1748						else mfp.prev();
1749					} else if (e.keyCode === 39) {
1750						if (gSt.langDir === 'rtl') mfp.prev();
1751						else mfp.next();
1752					}
1753				});
1754
1755				mfp.updateGalleryButtons();
1756
1757			});
1758
1759			_mfpOn('UpdateStatus'+ns, function(/*e, data*/) {
1760				mfp.updateGalleryButtons();
1761			});
1762
1763			_mfpOn('UpdateStatus'+ns, function(e, data) {
1764				if(data.text) {
1765					data.text = _replaceCurrTotal(data.text, mfp.currItem.index, mfp.items.length);
1766				}
1767			});
1768
1769			_mfpOn(MARKUP_PARSE_EVENT+ns, function(e, element, values, item) {
1770				var l = mfp.items.length;
1771				values.counter = l > 1 ? _replaceCurrTotal(gSt.tCounter, item.index, l) : '';
1772			});
1773
1774			_mfpOn('BuildControls' + ns, function() {
1775				if(mfp.items.length > 1 && gSt.arrows && !mfp.arrowLeft) {
1776
1777					var arrowLeftDesc, arrowRightDesc, arrowLeftAction, arrowRightAction;
1778
1779					if (gSt.langDir === 'rtl') {
1780						arrowLeftDesc = gSt.tNext;
1781						arrowRightDesc = gSt.tPrev;
1782						arrowLeftAction = 'next';
1783						arrowRightAction = 'prev';
1784					} else {
1785						arrowLeftDesc = gSt.tPrev;
1786						arrowRightDesc = gSt.tNext;
1787						arrowLeftAction = 'prev';
1788						arrowRightAction = 'next';
1789					}
1790
1791					var markup     = gSt.arrowMarkup,
1792							arrowLeft  = mfp.arrowLeft = $( markup.replace(/%title%/gi, arrowLeftDesc)
1793								.replace(/%action%/gi, arrowLeftAction)
1794								.replace(/%dir%/gi, 'left') )
1795								.attr('aria-label', arrowLeftDesc)
1796								.addClass(PREVENT_CLOSE_CLASS),
1797							arrowRight = mfp.arrowRight = $( markup.replace(/%title%/gi, arrowRightDesc)
1798								.replace(/%action%/gi, arrowRightAction)
1799								.replace(/%dir%/gi, 'right') )
1800								.attr('aria-label', arrowRightDesc)
1801								.addClass(PREVENT_CLOSE_CLASS);
1802
1803					if (gSt.langDir === 'rtl') {
1804						mfp.arrowNext = arrowLeft;
1805						mfp.arrowPrev = arrowRight;
1806					} else {
1807						mfp.arrowNext = arrowRight;
1808						mfp.arrowPrev = arrowLeft;
1809					}
1810
1811					arrowLeft.on('click', function() {
1812						if (gSt.langDir === 'rtl') mfp.next();
1813						else mfp.prev();
1814					});
1815					arrowRight.on('click', function() {
1816						if (gSt.langDir === 'rtl') mfp.prev();
1817						else mfp.next();
1818					});
1819
1820					mfp.container.append(arrowLeft.add(arrowRight));
1821					mfp.container
1822						.attr('role', 'region')
1823						.attr('aria-label', 'carousel');
1824				}
1825			});
1826
1827			_mfpOn(CHANGE_EVENT+ns, function() {
1828				if(mfp._preloadTimeout) clearTimeout(mfp._preloadTimeout);
1829
1830				mfp._preloadTimeout = setTimeout(function() {
1831					mfp.preloadNearbyImages();
1832					mfp._preloadTimeout = null;
1833				}, 16);
1834			});
1835
1836
1837			_mfpOn(CLOSE_EVENT+ns, function() {
1838				_document.off(ns);
1839				mfp.wrap.off('click'+ns);
1840				mfp.arrowRight = mfp.arrowLeft = null;
1841			});
1842
1843		},
1844		next: function() {
1845			var newIndex = _getLoopedId(mfp.index + 1);
1846			if (!mfp.st.gallery.loop && newIndex === 0 ) return false;
1847			mfp.direction = true;
1848			mfp.index = newIndex;
1849			mfp.updateItemHTML();
1850		},
1851		prev: function() {
1852			var newIndex = mfp.index - 1;
1853			if (!mfp.st.gallery.loop && newIndex < 0) return false;
1854			mfp.direction = false;
1855			mfp.index = _getLoopedId(newIndex);
1856			mfp.updateItemHTML();
1857		},
1858		goTo: function(newIndex) {
1859			mfp.direction = (newIndex >= mfp.index);
1860			mfp.index = newIndex;
1861			mfp.updateItemHTML();
1862		},
1863		preloadNearbyImages: function() {
1864			var p = mfp.st.gallery.preload,
1865				preloadBefore = Math.min(p[0], mfp.items.length),
1866				preloadAfter = Math.min(p[1], mfp.items.length),
1867				i;
1868
1869			for(i = 1; i <= (mfp.direction ? preloadAfter : preloadBefore); i++) {
1870				mfp._preloadItem(mfp.index+i);
1871			}
1872			for(i = 1; i <= (mfp.direction ? preloadBefore : preloadAfter); i++) {
1873				mfp._preloadItem(mfp.index-i);
1874			}
1875		},
1876		_preloadItem: function(index) {
1877			index = _getLoopedId(index);
1878
1879			if(mfp.items[index].preloaded) {
1880				return;
1881			}
1882
1883			var item = mfp.items[index];
1884			if(!item.parsed) {
1885				item = mfp.parseEl( index );
1886			}
1887
1888			_mfpTrigger('LazyLoad', item);
1889
1890			if(item.type === 'image') {
1891				item.img = $('<img class="mfp-img" />').on('load.mfploader', function() {
1892					item.hasSize = true;
1893				}).on('error.mfploader', function() {
1894					item.hasSize = true;
1895					item.loadError = true;
1896					_mfpTrigger('LazyLoadError', item);
1897				}).attr('src', item.src);
1898			}
1899
1900
1901			item.preloaded = true;
1902		},
1903
1904		/**
1905		 * Show/hide the gallery prev/next buttons if we're at the start/end, if looping is turned off
1906		 * Added by Joloco for Veg
1907		 */
1908		updateGalleryButtons: function() {
1909
1910			if ( !mfp.st.gallery.loop && typeof mfp.arrowPrev === 'object' && mfp.arrowPrev !== null) {
1911
1912				if (mfp.index === 0) mfp.arrowPrev.hide();
1913				else mfp.arrowPrev.show();
1914
1915				if (mfp.index === (mfp.items.length - 1)) mfp.arrowNext.hide();
1916				else mfp.arrowNext.show();
1917
1918			}
1919
1920		},
1921
1922	}
1923
1924});
1925
1926
1927/*>>gallery*/
1928
1929/*>>retina*/
1930
1931var RETINA_NS = 'retina';
1932
1933$.magnificPopup.registerModule(RETINA_NS, {
1934	options: {
1935		replaceSrc: function(item) {
1936			return item.src.replace(/\.\w+$/, function(m) { return '@2x' + m; });
1937		},
1938		ratio: 1 // Function or number.  Set to 1 to disable.
1939	},
1940	proto: {
1941		initRetina: function() {
1942			if(window.devicePixelRatio > 1) {
1943
1944				var st = mfp.st.retina,
1945					ratio = st.ratio;
1946
1947				ratio = !isNaN(ratio) ? ratio : ratio();
1948
1949				if(ratio > 1) {
1950					_mfpOn('ImageHasSize' + '.' + RETINA_NS, function(e, item) {
1951						item.img.css({
1952							'max-width': item.img[0].naturalWidth / ratio,
1953							'width': '100%'
1954						});
1955					});
1956					_mfpOn('ElementParse' + '.' + RETINA_NS, function(e, item) {
1957						item.src = st.replaceSrc(item, ratio);
1958					});
1959				}
1960			}
1961
1962		}
1963	}
1964});
1965
1966/*>>retina*/
1967 _checkInstance(); }));

Line numbers count LF bytes from the start of the resource, as the search results do. Vendor segments are library code the classifier recognised; they are stored but not indexed. Bytes are shown as Latin1 characters, one per byte.