PageSourceSearch

https://gs-urmitz.de/modules/news_img/js/galleries/lightcase/src/js/lightcase.js?1787299200

js gs-urmitz.de collected 2026-10-09 01:20:01 UTC 54,237 bytes, 1,897 lines download raw bytes

1// JavaScript flexImages v1.0.2
2// https://github.com/Pixabay/JavaScript-flexImages
3var flexImages=function(){function e(e){function t(e,r,n,i){function o(e){n.maxRows&&g>n.maxRows||n.truncate&&e&&g>1?c[a][0].style.display="none":(c[a][4]&&(c[a][3].setAttribute("src",c[a][4]),c[a][4]=""),c[a][0].style.width=l+"px",c[a][0].style.height=h+"px",c[a][0].style.display="block")}for(var a,l,s,d,f=1,g=1,u=e.clientWidth-2,c=[],m=0,h=n.rowHeight,w=0;w<r.length;w++)if(c.push(r[w]),m+=r[w][2]+n.margin,m>=u){var p=c.length*n.margin;for(f=(u-p)/(m-p),h=Math.ceil(n.rowHeight*f),s=0,l,a=0;a<c.length;a++)l=Math.ceil(c[a][2]*f),s+=l+n.margin,s>u&&(l-=s-u),o();c=[],m=0,g++}for(a=0;a<c.length;a++)l=Math.floor(c[a][2]*f),d=Math.floor(n.rowHeight*f),o(!0);i||u==e.clientWidth||t(e,r,n,!0)}if(document.querySelector){var r={selector:0,container:".item",object:"img",rowHeight:180,maxRows:0,truncate:0};for(var n in e)e.hasOwnProperty(n)&&(r[n]=e[n]);for(var i="object"==typeof r.selector?[r.selector]:document.querySelectorAll(r.selector),o=0;o<i.length;o++){var a=i[o],l=a.querySelectorAll(r.container),s=[],d=(new Date).getTime();if(l.length){var f=window.getComputedStyle?getComputedStyle(l[0],null):l[0].currentStyle;r.margin=(parseInt(f.marginLeft)||0)+(parseInt(f.marginRight)||0)+(Math.round(parseFloat(f.borderLeftWidth))||0)+(Math.round(parseFloat(f.borderRightWidth))||0);for(var g=0;g<l.length;g++){var u=l[g],c=parseInt(u.getAttribute("data-w")),m=c*(r.rowHeight/parseInt(u.getAttribute("data-h"))),h=u.querySelector(r.object);s.push([u,c,m,h,h.getAttribute("data-src")])}t(a,s,r);var w=function(){t(a,s,r)};document.addEventListener?(window["flexImages_listener"+d]=w,window.removeEventListener("resize",window["flexImages_listener"+a.getAttribute("data-flex-t")]),delete window["flexImages_listener"+a.getAttribute("data-flex-t")],window.addEventListener("resize",window["flexImages_listener"+d])):a.onresize=w,a.setAttribute("data-flex-t",d)}}}}return e}();!function(){"function"==typeof define&&define.amd?define("flexImages",function(){return flexImages}):"undefined"!=typeof module&&module.exports?module.exports=flexImages:window.flexImages=flexImages}();
4
5/*
6 * Lightcase - jQuery Plugin
7 * The smart and flexible Lightbox Plugin.
8 *
9 * @author		Cornel Boppart <[email protected]>
10 * @copyright	Author
11 *
12 * @version		2.5.0 (11/03/2018)
13 */
14
15;(function ($) {
16
17	'use strict';
18
19	var _self = {
20		cache: {},
21
22		support: {},
23
24		objects: {},
25
26		/**
27		 * Initializes the plugin
28		 *
29		 * @param	{object}	options
30		 * @return	{object}
31		 */
32		init: function (options) {
33			return this.each(function () {
34				$(this).unbind('click.lightcase').bind('click.lightcase', function (event) {
35					event.preventDefault();
36					$(this).lightcase('start', options);
37				});
38			});
39		},
40
41		/**
42		 * Starts the plugin
43		 *
44		 * @param	{object}	options
45		 * @return	{void}
46		 */
47		start: function (options) {
48			_self.origin = lightcase.origin = this;
49
50			_self.settings = lightcase.settings = $.extend(true, {
51				idPrefix: 'lightcase-',
52				classPrefix: 'lightcase-',
53				attrPrefix: 'lc-',
54				transition: 'elastic',
55				transitionOpen: null,
56				transitionClose: null,
57				transitionIn: null,
58				transitionOut: null,
59				cssTransitions: true,
60				speedIn: 250,
61				speedOut: 250,
62				width: null,
63				height: null,
64				maxWidth: 800,
65				maxHeight: 500,
66				forceWidth: false,
67				forceHeight: false,
68				liveResize: true,
69				fullScreenModeForMobile: true,
70				mobileMatchExpression: /(iphone|ipod|ipad|android|blackberry|symbian)/,
71				disableShrink: false,
72				fixedRatio: true,
73				shrinkFactor: .75,
74				overlayOpacity: .9,
75				slideshow: false,
76				slideshowAutoStart: true,
77				breakBeforeShow: false,
78				timeout: 5000,
79				swipe: true,
80				useKeys: true,
81				useCategories: true,
82				useAsCollection: false,
83				navigateEndless: true,
84				closeOnOverlayClick: true,
85				title: null,
86				caption: null,
87				showTitle: true,
88				showCaption: true,
89				showSequenceInfo: true,
90				inline: {
91					width: 'auto',
92					height: 'auto'
93				},
94				ajax: {
95					width: 'auto',
96					height: 'auto',
97					type: 'get',
98					dataType: 'html',
99					data: {}
100				},
101				iframe: {
102					width: 800,
103					height: 500,
104					frameborder: 0
105				},
106				flash: {
107					width: 400,
108					height: 205,
109					wmode: 'transparent'
110				},
111				video: {
112					width: 400,
113					height: 225,
114					poster: '',
115					preload: 'auto',
116					controls: true,
117					autobuffer: true,
118					autoplay: true,
119					loop: false
120				},
121				attr: 'data-rel',
122				href: null,
123				type: null,
124				typeMapping: {
125					'image': 'jpg,jpeg,gif,png,bmp',
126					'flash': 'swf',
127					'video': 'mp4,mov,ogv,ogg,webm',
128					'iframe': 'html,php',
129					'ajax': 'json,txt',
130					'inline': '#'
131				},
132				errorMessage: function () {
133					return '<p class="' + _self.settings.classPrefix + 'error">' + _self.settings.labels['errorMessage'] + '</p>';
134				},
135				labels: {
136					'errorMessage': 'Source could not be found...',
137					'sequenceInfo.of': ' of ',
138					'close': 'Close',
139					'navigator.prev': 'Prev',
140					'navigator.next': 'Next',
141 					'navigator.play': 'Play',
142					'navigator.pause': 'Pause'
143				},
144				markup: function () {
145					_self.objects.body.append(
146						_self.objects.overlay = $('<div id="' + _self.settings.idPrefix + 'overlay"></div>'),
147						_self.objects.loading = $('<div id="' + _self.settings.idPrefix + 'loading" class="' + _self.settings.classPrefix + 'icon-spin"></div>'),
148						_self.objects.case = $('<div id="' + _self.settings.idPrefix + 'case" aria-hidden="true" role="dialog"></div>')
149					);
150					_self.objects.case.after(
151						_self.objects.close = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-close"><span>' + _self.settings.labels['close'] + '</span></a>'),
152						_self.objects.nav = $('<div id="' + _self.settings.idPrefix + 'nav"></div>')
153					);
154					_self.objects.nav.append(
155						_self.objects.prev = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-prev"><span>' + _self.settings.labels['navigator.prev'] + '</span></a>').hide(),
156						_self.objects.next = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-next"><span>' + _self.settings.labels['navigator.next'] + '</span></a>').hide(),
157						_self.objects.play = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-play"><span>' + _self.settings.labels['navigator.play'] + '</span></a>').hide(),
158						_self.objects.pause = $('<a href="#" class="' + _self.settings.classPrefix + 'icon-pause"><span>' + _self.settings.labels['navigator.pause'] + '</span></a>').hide()
159					);
160					_self.objects.case.append(
161						_self.objects.content = $('<div id="' + _self.settings.idPrefix + 'content"></div>'),
162						_self.objects.info = $('<div id="' + _self.settings.idPrefix + 'info"></div>')
163					);
164					_self.objects.content.append(
165						_self.objects.contentInner = $('<div class="' + _self.settings.classPrefix + 'contentInner"></div>')
166					);
167					_self.objects.info.append(
168						_self.objects.sequenceInfo = $('<div id="' + _self.settings.idPrefix + 'sequenceInfo"></div>'),
169						_self.objects.title = $('<h4 id="' + _self.settings.idPrefix + 'title"></h4>'),
170						_self.objects.caption = $('<p id="' + _self.settings.idPrefix + 'caption"></p>')
171					);
172				},
173				onInit: {},
174				onStart: {},
175				onBeforeCalculateDimensions: {},
176				onAfterCalculateDimensions: {},
177				onBeforeShow: {},
178				onFinish: {},
179				onResize: {},
180				onClose: {},
181				onCleanup: {}
182			},
183			options,
184			// Load options from data-lc-options attribute
185			_self.origin.data ? _self.origin.data('lc-options') : {});
186
187			_self.objects.document = $('html');
188			_self.objects.body = $('body');
189
190			// Call onInit hook functions
191			_self._callHooks(_self.settings.onInit);
192
193			_self.objectData = _self._setObjectData(this);
194
195			_self._addElements();
196			_self._open();
197
198			_self.dimensions = _self.getViewportDimensions();
199		},
200
201		/**
202		 * Getter method for objects
203		 *
204		 * @param	{string}	name
205		 * @return	{object}
206		 */
207		get: function (name) {
208			return _self.objects[name];
209		},
210
211		/**
212		 * Getter method for objectData
213		 *
214		 * @return	{object}
215		 */
216		getObjectData: function () {
217			return _self.objectData;
218		},
219
220		/**
221		 * Sets the object data
222		 *
223		 * @param	{object}	object
224		 * @return	{object}	objectData
225		 */
226		_setObjectData: function (object) {
227		 	var $object = $(object),
228				objectData = {
229				this: $(object),
230				title: _self.settings.title || $object.attr(_self._prefixAttributeName('title')) || $object.attr('title'),
231				caption: _self.settings.caption || $object.attr(_self._prefixAttributeName('caption')) || $object.children('img').attr('alt'),
232				url: _self._determineUrl(),
233				requestType: _self.settings.ajax.type,
234				requestData: _self.settings.ajax.data,
235				requestDataType: _self.settings.ajax.dataType,
236				rel: $object.attr(_self._determineAttributeSelector()),
237				type: _self.settings.type || _self._verifyDataType(_self._determineUrl()),
238				isPartOfSequence: _self.settings.useAsCollection || _self._isPartOfSequence($object.attr(_self.settings.attr), ':'),
239				isPartOfSequenceWithSlideshow: _self._isPartOfSequence($object.attr(_self.settings.attr), ':slideshow'),
240				currentIndex: $(_self._determineAttributeSelector()).index($object),
241				sequenceLength: $(_self._determineAttributeSelector()).length
242			};
243
244			// Add sequence info to objectData
245			objectData.sequenceInfo = (objectData.currentIndex + 1) + _self.settings.labels['sequenceInfo.of'] + objectData.sequenceLength;
246
247			// Add next/prev index
248			objectData.prevIndex = objectData.currentIndex - 1;
249			objectData.nextIndex = objectData.currentIndex + 1;
250
251			return objectData;
252		},
253
254		/**
255		 * Prefixes a data attribute name with defined name from 'settings.attrPrefix'
256		 * to ensure more uniqueness for all lightcase related/used attributes.
257		 *
258		 * @param	{string}	name
259		 * @return	{string}
260		 */
261		_prefixAttributeName: function (name) {
262			return 'data-' + _self.settings.attrPrefix + name;
263		},
264
265		/**
266		 * Determines the link target considering 'settings.href' and data attributes
267		 * but also with a fallback to the default 'href' value.
268		 *
269		 * @return	{string}
270		 */
271		_determineLinkTarget: function () {
272			return _self.settings.href || $(_self.origin).attr(_self._prefixAttributeName('href')) || $(_self.origin).attr('href');
273		},
274
275		/**
276		 * Determines the attribute selector to use, depending on
277		 * whether categorized collections are beeing used or not.
278		 *
279		 * @return	{string}	selector
280		 */
281		_determineAttributeSelector: function () {
282			var	$origin = $(_self.origin),
283				selector = '';
284
285			if (typeof _self.cache.selector !== 'undefined') {
286				selector = _self.cache.selector;
287			} else if (_self.settings.useCategories === true && $origin.attr(_self._prefixAttributeName('categories'))) {
288				var	categories = $origin.attr(_self._prefixAttributeName('categories')).split(' ');
289
290				$.each(categories, function (index, category) {
291					if (index > 0) {
292						selector += ',';
293					}
294					selector += '[' + _self._prefixAttributeName('categories') + '~="' + category + '"]';
295				});
296			} else {
297				selector = '[' + _self.settings.attr + '="' + $origin.attr(_self.settings.attr) + '"]';
298			}
299
300			_self.cache.selector = selector;
301
302			return selector;
303		},
304
305		/**
306		 * Determines the correct resource according to the
307		 * current viewport and density.
308		 *
309		 * @return	{string}	url
310		 */
311		_determineUrl: function () {
312			var	dataUrl = _self._verifyDataUrl(_self._determineLinkTarget()),
313				width = 0,
314				density = 0,
315				supportLevel = '',
316				url;
317
318			$.each(dataUrl, function (index, src) {
319				switch (_self._verifyDataType(src.url)) {
320					case 'video':
321						var	video = document.createElement('video'),
322							videoType = _self._verifyDataType(src.url) + '/' + _self._getFileUrlSuffix(src.url);
323
324						// Check if browser can play this type of video format
325						if (supportLevel !== 'probably' && supportLevel !== video.canPlayType(videoType) && video.canPlayType(videoType) !== '') {
326							supportLevel = video.canPlayType(videoType);
327							url = src.url;
328						}
329						break;
330					default:
331						if (
332							// Check density
333							_self._devicePixelRatio() >= src.density &&
334							src.density >= density &&
335							// Check viewport width
336							_self._matchMedia()('screen and (min-width:' + src.width + 'px)').matches &&
337							src.width >= width
338						) {
339							width = src.width;
340							density = src.density;
341							url = src.url;
342						}
343						break;
344				}
345			});
346
347			return url;
348		},
349
350		/**
351		 * Normalizes an url and returns information about the resource path,
352		 * the viewport width as well as density if defined.
353		 *
354		 * @param	{string}	url	Path to resource in format of an url or srcset
355		 * @return	{object}
356		 */
357		_normalizeUrl: function (url) {
358			var srcExp = /^\d+$/;
359
360			return url.split(',').map(function (str) {
361				var src = {
362					width: 0,
363					density: 0
364				};
365
366				str.trim().split(/\s+/).forEach(function (url, i) {
367					if (i === 0) {
368						return src.url = url;
369					}
370
371					var value = url.substring(0, url.length - 1),
372						lastChar = url[url.length - 1],
373						intVal = parseInt(value, 10),
374						floatVal = parseFloat(value);
375					if (lastChar === 'w' && srcExp.test(value)) {
376						src.width = intVal;
377					} else if (lastChar === 'h' && srcExp.test(value)) {
378						src.height = intVal;
379					} else if (lastChar === 'x' && !isNaN(floatVal)) {
380						src.density = floatVal;
381					}
382				});
383
384				return src;
385			});
386		},
387
388		/**
389		 * Verifies if the link is part of a sequence
390		 *
391		 * @param	{string}	rel
392		 * @param	{string}	expression
393		 * @return	{boolean}
394		 */
395		_isPartOfSequence: function (rel, expression) {
396			var getSimilarLinks = $('[' + _self.settings.attr + '="' + rel + '"]'),
397				regexp = new RegExp(expression);
398
399			return (regexp.test(rel) && getSimilarLinks.length > 1);
400		},
401
402		/**
403		 * Verifies if the slideshow should be enabled
404		 *
405		 * @return	{boolean}
406		 */
407		isSlideshowEnabled: function () {
408			return (_self.objectData.isPartOfSequence && (_self.settings.slideshow === true || _self.objectData.isPartOfSequenceWithSlideshow === true));
409		},
410
411		/**
412		 * Loads the new content to show
413		 *
414		 * @return	{void}
415		 */
416		_loadContent: function () {
417			if (_self.cache.originalObject) {
418				_self._restoreObject();
419			}
420
421			_self._createObject();
422		},
423
424		/**
425		 * Creates a new object
426		 *
427		 * @return	{void}
428		 */
429		_createObject: function () {
430			var $object;
431
432			// Create object
433			switch (_self.objectData.type) {
434				case 'image':
435					$object = $(new Image());
436					$object.attr({
437						// The time expression is required to prevent the binding of an image load
438						'src': _self.objectData.url,
439						'alt': _self.objectData.title
440					});
441					break;
442				case 'inline':
443					$object = $('<div class="' + _self.settings.classPrefix + 'inlineWrap"></div>');
444					$object.html(_self._cloneObject($(_self.objectData.url)));
445
446					// Add custom attributes from _self.settings
447					$.each(_self.settings.inline, function (name, value) {
448						$object.attr(_self._prefixAttributeName(name), value);
449					});
450					break;
451				case 'ajax':
452					$object = $('<div class="' + _self.settings.classPrefix + 'inlineWrap"></div>');
453
454					// Add custom attributes from _self.settings
455					$.each(_self.settings.ajax, function (name, value) {
456						if (name !== 'data') {
457							$object.attr(_self._prefixAttributeName(name), value);
458						}
459					});
460					break;
461				case 'flash':
462					$object = $('<embed src="' + _self.objectData.url + '" type="application/x-shockwave-flash"></embed>');
463
464					// Add custom attributes from _self.settings
465					$.each(_self.settings.flash, function (name, value) {
466						$object.attr(name, value);
467					});
468					break;
469				case 'video':
470					$object = $('<video></video>');
471					$object.attr('src', _self.objectData.url);
472
473					// Add custom attributes from _self.settings
474					$.each(_self.settings.video, function (name, value) {
475						$object.attr(name, value);
476					});
477					break;
478				default:
479					$object = $('<iframe></iframe>');
480					$object.attr({
481						'src': _self.objectData.url
482					});
483
484					// Add custom attributes from _self.settings
485					$.each(_self.settings.iframe, function (name, value) {
486						$object.attr(name, value);
487					});
488					break;
489			}
490
491			_self._addObject($object);
492			_self._loadObject($object);
493		},
494
495		/**
496		 * Adds the new object to the markup
497		 *
498		 * @param	{object}	$object
499		 * @return	{void}
500		 */
501		_addObject: function ($object) {
502			// Add object to content holder
503			_self.objects.contentInner.html($object);
504
505			// Start loading
506			_self._loading('start');
507
508			// Call onStart hook functions
509			_self._callHooks(_self.settings.onStart);
510
511			// Add sequenceInfo to the content holder or hide if its empty
512			if (_self.settings.showSequenceInfo === true && _self.objectData.isPartOfSequence) {
513				_self.objects.sequenceInfo.html(_self.objectData.sequenceInfo);
514				_self.objects.sequenceInfo.show();
515			} else {
516				_self.objects.sequenceInfo.empty();
517				_self.objects.sequenceInfo.hide();
518			}
519			// Add title to the content holder or hide if its empty
520			if (_self.settings.showTitle === true && _self.objectData.title !== undefined && _self.objectData.title !== '') {
521				_self.objects.title.html(_self.objectData.title);
522				_self.objects.title.show();
523			} else {
524				_self.objects.title.empty();
525				_self.objects.title.hide();
526			}
527			// Add caption to the content holder or hide if its empty
528			if (_self.settings.showCaption === true && _self.objectData.caption !== undefined && _self.objectData.caption !== '') {
529				_self.objects.caption.html(_self.objectData.caption);
530				_self.objects.caption.show();
531			} else {
532				_self.objects.caption.empty();
533				_self.objects.caption.hide();
534			}
535		},
536
537		/**
538		 * Loads the new object
539		 *
540		 * @param	{object}	$object
541		 * @return	{void}
542		 */
543		_loadObject: function ($object) {
544			// Load the object
545			switch (_self.objectData.type) {
546				case 'inline':
547					if ($(_self.objectData.url)) {
548						_self._showContent($object);
549					} else {
550						_self.error();
551					}
552					break;
553				case 'ajax':
554					$.ajax(
555						$.extend({}, _self.settings.ajax, {
556							url: _self.objectData.url,
557							type: _self.objectData.requestType,
558							dataType: _self.objectData.requestDataType,
559							data: _self.objectData.requestData,
560							success: function (data, textStatus, jqXHR) {
561								// Check for X-Ajax-Location
562								if (jqXHR.getResponseHeader('X-Ajax-Location')) {
563									_self.objectData.url = jqXHR.getResponseHeader('X-Ajax-Location');
564									_self._loadObject($object);
565								}
566								else {
567									// Unserialize if data is transferred as json
568									if (_self.objectData.requestDataType === 'json') {
569										_self.objectData.data = data;
570									} else {
571										$object.html(data);
572									}
573									_self._showContent($object);
574								}
575							},
576							error: function (jqXHR, textStatus, errorThrown) {
577								_self.error();
578							}
579						})
580					);
581					break;
582				case 'flash':
583					_self._showContent($object);
584					break;
585				case 'video':
586					if (typeof($object.get(0).canPlayType) === 'function' || _self.objects.case.find('video').length === 0) {
587						_self._showContent($object);
588					} else {
589						_self.error();
590					}
591					break;
592				default:
593					if (_self.objectData.url) {
594						$object.on('load', function () {
595							_self._showContent($object);
596						});
597						$object.on('error', function () {
598							_self.error();
599						});
600					} else {
601						_self.error();
602					}
603					break;
604			}
605		},
606
607		/**
608		 * Throws an error message if something went wrong
609		 *
610		 * @return	{void}
611		 */
612		error: function () {
613			_self.objectData.type = 'error';
614			var $object = $('<div class="' + _self.settings.classPrefix + 'inlineWrap"></div>');
615
616			$object.html(_self.settings.errorMessage);
617			_self.objects.contentInner.html($object);
618
619			_self._showContent(_self.objects.contentInner);
620		},
621
622		/**
623		 * Calculates the dimensions to fit content
624		 *
625		 * @param	{object}	$object
626		 * @return	{void}
627		 */
628		_calculateDimensions: function ($object) {
629			_self._cleanupDimensions();
630
631			if (!$object) return;
632
633			// Set default dimensions
634			var dimensions = {
635				ratio: 1,
636				objectWidth: $object.attr('width') ? $object.attr('width') : $object.attr(_self._prefixAttributeName('width')),
637				objectHeight: $object.attr('height') ? $object.attr('height') : $object.attr(_self._prefixAttributeName('height'))
638			};
639
640			if (!_self.settings.disableShrink) {
641				// Add calculated maximum width/height to dimensions
642				dimensions.maxWidth = parseInt(_self.dimensions.windowWidth * _self.settings.shrinkFactor);
643				dimensions.maxHeight = parseInt(_self.dimensions.windowHeight * _self.settings.shrinkFactor);
644
645				// If the auto calculated maxWidth/maxHeight greather than the user-defined one, use that.
646				if (dimensions.maxWidth > _self.settings.maxWidth) {
647					dimensions.maxWidth = _self.settings.maxWidth;
648				}
649				if (dimensions.maxHeight > _self.settings.maxHeight) {
650					dimensions.maxHeight = _self.settings.maxHeight;
651				}
652
653				// Calculate the difference between screen width/height and image width/height
654				dimensions.differenceWidthAsPercent = parseInt(100 / dimensions.maxWidth * dimensions.objectWidth);
655				dimensions.differenceHeightAsPercent = parseInt(100 / dimensions.maxHeight * dimensions.objectHeight);
656
657				switch (_self.objectData.type) {
658					case 'image':
659					case 'flash':
660					case 'video':
661					case 'iframe':
662					case 'ajax':
663					case 'inline':
664						if (_self.objectData.type === 'image' || _self.settings.fixedRatio === true) {
665							if (dimensions.differenceWidthAsPercent > 100 && dimensions.differenceWidthAsPercent > dimensions.differenceHeightAsPercent) {
666								dimensions.objectWidth = dimensions.maxWidth;
667								dimensions.objectHeight = parseInt(dimensions.objectHeight / dimensions.differenceWidthAsPercent * 100);
668							}
669							if (dimensions.differenceHeightAsPercent > 100 && dimensions.differenceHeightAsPercent > dimensions.differenceWidthAsPercent) {
670								dimensions.objectWidth = parseInt(dimensions.objectWidth / dimensions.differenceHeightAsPercent * 100);
671								dimensions.objectHeight = dimensions.maxHeight;
672							}
673							if (dimensions.differenceHeightAsPercent > 100 && dimensions.differenceWidthAsPercent < dimensions.differenceHeightAsPercent) {
674								dimensions.objectWidth = parseInt(dimensions.maxWidth / dimensions.differenceHeightAsPercent * dimensions.differenceWidthAsPercent);
675								dimensions.objectHeight = dimensions.maxHeight;
676							}
677							break;
678						}
679					case 'error':
680						if (!isNaN(dimensions.objectWidth) && dimensions.objectWidth > dimensions.maxWidth) {
681							dimensions.objectWidth = dimensions.maxWidth;
682						}
683						break;
684					default:
685						if ((isNaN(dimensions.objectWidth) || dimensions.objectWidth > dimensions.maxWidth) && !_self.settings.forceWidth) {
686							dimensions.objectWidth = dimensions.maxWidth;
687						}
688						if (((isNaN(dimensions.objectHeight) && dimensions.objectHeight !== 'auto') || dimensions.objectHeight > dimensions.maxHeight) && !_self.settings.forceHeight) {
689							dimensions.objectHeight = dimensions.maxHeight;
690						}
691						break;
692				}
693			}
694
695			if (_self.settings.forceWidth) {
696				try {
697					dimensions.objectWidth = _self.settings[_self.objectData.type].width;
698				} catch (e) {
699					dimensions.objectWidth = _self.settings.width || dimensions.objectWidth;
700				}
701
702				dimensions.maxWidth = null;
703			}
704			if ($object.attr(_self._prefixAttributeName('max-width'))) {
705				dimensions.maxWidth = $object.attr(_self._prefixAttributeName('max-width'));
706			}
707
708			if (_self.settings.forceHeight) {
709				try {
710					dimensions.objectHeight = _self.settings[_self.objectData.type].height;
711				} catch (e) {
712					dimensions.objectHeight = _self.settings.height || dimensions.objectHeight;
713				}
714
715				dimensions.maxHeight = null;
716			}
717			if ($object.attr(_self._prefixAttributeName('max-height'))) {
718				dimensions.maxHeight = $object.attr(_self._prefixAttributeName('max-height'));
719			}
720			_self._adjustDimensions($object, dimensions);
721		},
722
723		/**
724		 * Adjusts the dimensions
725		 *
726		 * @param	{object}	$object
727		 * @param	{object}	dimensions
728		 * @return	{void}
729		 */
730		_adjustDimensions: function ($object, dimensions) {
731			// Adjust width and height
732			$object.css({
733				'width': dimensions.objectWidth,
734				'height': dimensions.objectHeight,
735				'max-width': dimensions.maxWidth,
736				'max-height': dimensions.maxHeight
737			});
738
739			_self.objects.contentInner.css({
740				'width': $object.outerWidth(),
741				'height': $object.outerHeight(),
742				'max-width': '100%'
743			});
744
745			_self.objects.case.css({
746				'width': _self.objects.contentInner.outerWidth(),
747				'max-width': '100%'
748			});
749
750			// Adjust margin
751			_self.objects.case.css({
752				'margin-top': parseInt(-(_self.objects.case.outerHeight() / 2)),
753				'margin-left': parseInt(-(_self.objects.case.outerWidth() / 2))
754			});
755		},
756
757		/**
758		 * Handles the _loading
759		 *
760		 * @param	{string}	process
761		 * @return	{void}
762		 */
763		_loading: function (process) {
764			if (process === 'start') {
765				_self.objects.case.addClass(_self.settings.classPrefix + 'loading');
766				_self.objects.loading.show();
767			} else if (process === 'end') {
768				_self.objects.case.removeClass(_self.settings.classPrefix + 'loading');
769				_self.objects.loading.hide();
770			}
771		},
772
773
774		/**
775		 * Gets the client screen dimensions
776		 *
777		 * @return	{object}	dimensions
778		 */
779		getViewportDimensions: function () {
780			return {
781				windowWidth: $(window).innerWidth(),
782				windowHeight: $(window).innerHeight()
783			};
784		},
785
786		/**
787		 * Verifies the url
788		 *
789		 * @param	{string}	dataUrl
790		 * @return	{object}	dataUrl	Clean url for processing content
791		 */
792		_verifyDataUrl: function (dataUrl) {
793			if (!dataUrl || dataUrl === undefined || dataUrl === '') {
794				return false;
795			}
796
797			if (dataUrl.indexOf('#') > -1) {
798				dataUrl = dataUrl.split('#');
799				dataUrl = '#' + dataUrl[dataUrl.length - 1];
800			}
801
802			return _self._normalizeUrl(dataUrl.toString());
803		},
804
805			//
806		/**
807		 * Tries to get the (file) suffix of an url
808		 *
809		 * @param	{string}	url
810		 * @return	{string}
811		 */
812		_getFileUrlSuffix: function (url) {
813			var re = /(?:\.([^.]+))?$/;
814			return re.exec(url.toLowerCase())[1];
815		},
816
817		/**
818		 * Verifies the data type of the content to load
819		 *
820		 * @param	{string}			url
821		 * @return	{string|boolean}	Array key if expression matched, else false
822		 */
823		_verifyDataType: function (url) {
824			var typeMapping = _self.settings.typeMapping;
825
826			// Early abort if dataUrl couldn't be verified
827			if (!url) {
828				return false;
829			}
830
831			// Verify the dataType of url according to typeMapping which
832			// has been defined in settings.
833			for (var key in typeMapping) {
834				if (typeMapping.hasOwnProperty(key)) {
835					var suffixArr = typeMapping[key].split(',');
836
837					for (var i = 0; i < suffixArr.length; i++) {
838						var suffix = suffixArr[i].toLowerCase(),
839							regexp = new RegExp('\.(' + suffix + ')$', 'i'),
840							str = url.toLowerCase().split('?')[0].substr(-5);
841
842						if (regexp.test(str) === true || (key === 'inline' && (url.indexOf(suffix) > -1))) {
843							return key;
844						}
845					}
846				}
847			}
848
849			// If no expression matched, return 'iframe'.
850			return 'iframe';
851		},
852
853		/**
854		 * Extends html markup with the essential tags
855		 *
856		 * @return	{void}
857		 */
858		_addElements: function () {
859			if (typeof _self.objects.case !== 'undefined' && $('#' + _self.objects.case.attr('id')).length) {
860				return;
861			}
862
863			_self.settings.markup();
864		},
865
866		/**
867		 * Shows the loaded content
868		 *
869		 * @param	{object}	$object
870		 * @return	{void}
871		 */
872		_showContent: function ($object) {
873			// Add data attribute with the object type
874			_self.objects.document.attr(_self._prefixAttributeName('type'), _self.objectData.type);
875
876			_self.cache.object = $object;
877
878			// Call onBeforeShow hook functions
879			_self._callHooks(_self.settings.onBeforeShow);
880
881			if (_self.settings.breakBeforeShow) return;
882			_self.show();
883		},
884
885		/**
886		 * Starts the 'inTransition'
887		 * @return	{void}
888		 */
889		_startInTransition: function () {
890			switch (_self.transition.in()) {
891				case 'scrollTop':
892				case 'scrollRight':
893				case 'scrollBottom':
894				case 'scrollLeft':
895				case 'scrollHorizontal':
896				case 'scrollVertical':
897					_self.transition.scroll(_self.objects.case, 'in', _self.settings.speedIn);
898					_self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn);
899					break;
900				case 'elastic':
901					if (_self.objects.case.css('opacity') < 1) {
902						_self.transition.zoom(_self.objects.case, 'in', _self.settings.speedIn);
903						_self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn);
904				}
905				case 'fade':
906				case 'fadeInline':
907					_self.transition.fade(_self.objects.case, 'in', _self.settings.speedIn);
908					_self.transition.fade(_self.objects.contentInner, 'in', _self.settings.speedIn);
909					break;
910				default:
911					_self.transition.fade(_self.objects.case, 'in', 0);
912					break;
913			}
914
915			// End loading.
916			_self._loading('end');
917			_self.isBusy = false;
918
919			// Set index of the first item opened
920			if (!_self.cache.firstOpened) {
921				_self.cache.firstOpened = _self.objectData.this;
922			}
923
924			// Fade in the info with delay
925			_self.objects.info.hide();
926			setTimeout(function () {
927				 _self.transition.fade(_self.objects.info, 'in', _self.settings.speedIn);
928			}, _self.settings.speedIn);
929
930			// Call onFinish hook functions
931			_self._callHooks(_self.settings.onFinish);
932		},
933
934		/**
935		 * Processes the content to show
936		 *
937		 * @return	{void}
938		 */
939		_processContent: function () {
940			_self.isBusy = true;
941
942			// Fade out the info at first
943			_self.transition.fade(_self.objects.info, 'out', 0);
944
945			switch (_self.settings.transitionOut) {
946				case 'scrollTop':
947				case 'scrollRight':
948				case 'scrollBottom':
949				case 'scrollLeft':
950				case 'scrollVertical':
951				case 'scrollHorizontal':
952					if (_self.objects.case.is(':hidden')) {
953						_self.transition.fade(_self.objects.contentInner, 'out', 0);
954						_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
955							_self._loadContent();
956						});
957					} else {
958						_self.transition.scroll(_self.objects.case, 'out', _self.settings.speedOut, function () {
959							_self._loadContent();
960						});
961					}
962					break;
963				case 'fade':
964					if (_self.objects.case.is(':hidden')) {
965						_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
966							_self._loadContent();
967						});
968					} else {
969						_self.transition.fade(_self.objects.case, 'out', _self.settings.speedOut, 0, function () {
970							_self._loadContent();
971						});
972					}
973					break;
974				case 'fadeInline':
975				case 'elastic':
976					if (_self.objects.case.is(':hidden')) {
977						_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
978							_self._loadContent();
979						});
980					} else {
981						_self.transition.fade(_self.objects.contentInner, 'out', _self.settings.speedOut, 0, function () {
982							_self._loadContent();
983						});
984					}
985					break;
986				default:
987					_self.transition.fade(_self.objects.case, 'out', 0, 0, function () {
988						_self._loadContent();
989					});
990					break;
991			}
992		},
993
994		/**
995		 * Handles events for gallery buttons
996		 *
997		 * @return	{void}
998		 */
999		_handleEvents: function () {
1000			_self._unbindEvents();
1001
1002			_self.objects.nav.children().not(_self.objects.close).hide();
1003
1004			// If slideshow is enabled, show play/pause and start timeout.
1005			if (_self.isSlideshowEnabled()) {
1006				// Only start the timeout if slideshow autostart is enabled and slideshow is not pausing
1007				if (
1008					(_self.settings.slideshowAutoStart === true || _self.isSlideshowStarted) &&
1009					!_self.objects.nav.hasClass(_self.settings.classPrefix + 'paused')
1010				) {
1011					_self._startTimeout();
1012				} else {
1013					_self._stopTimeout();
1014				}
1015			}
1016
1017			if (_self.settings.liveResize) {
1018				_self._watchResizeInteraction();
1019			}
1020
1021			_self.objects.close.click(function (event) {
1022				event.preventDefault();
1023				_self.close();
1024			});
1025
1026			if (_self.settings.closeOnOverlayClick === true) {
1027				_self.objects.overlay.css('cursor', 'pointer').click(function (event) {
1028					event.preventDefault();
1029
1030					_self.close();
1031				});
1032			}
1033
1034			if (_self.settings.useKeys === true) {
1035				_self._addKeyEvents();
1036			}
1037
1038			if (_self.objectData.isPartOfSequence) {
1039				_self.objects.nav.attr(_self._prefixAttributeName('ispartofsequence'), true);
1040				_self.objects.nav.data('items', _self._setNavigation());
1041
1042				_self.objects.prev.click(function (event) {
1043					event.preventDefault();
1044
1045					if (_self.settings.navigateEndless === true || !_self.item.isFirst()) {
1046						_self.objects.prev.unbind('click');
1047						_self.cache.action = 'prev';
1048						_self.objects.nav.data('items').prev.click();
1049
1050						if (_self.isSlideshowEnabled()) {
1051							_self._stopTimeout();
1052						}
1053					}
1054				});
1055
1056				_self.objects.next.click(function (event) {
1057					event.preventDefault();
1058
1059					if (_self.settings.navigateEndless === true || !_self.item.isLast()) {
1060						_self.objects.next.unbind('click');
1061						_self.cache.action = 'next';
1062						_self.objects.nav.data('items').next.click();
1063
1064						if (_self.isSlideshowEnabled()) {
1065							_self._stopTimeout();
1066						}
1067					}
1068				});
1069
1070				if (_self.isSlideshowEnabled()) {
1071					_self.objects.play.click(function (event) {
1072						event.preventDefault();
1073						_self._startTimeout();
1074					});
1075					_self.objects.pause.click(function (event) {
1076						event.preventDefault();
1077						_self._stopTimeout();
1078					});
1079				}
1080
1081				// Enable swiping if activated
1082				if (_self.settings.swipe === true) {
1083					if ($.isPlainObject($.event.special.swipeleft)) {
1084						_self.objects.case.on('swipeleft', function (event) {
1085							event.preventDefault();
1086							_self.objects.next.click();
1087							if (_self.isSlideshowEnabled()) {
1088								_self._stopTimeout();
1089							}
1090						});
1091					}
1092					if ($.isPlainObject($.event.special.swiperight)) {
1093						_self.objects.case.on('swiperight', function (event) {
1094							event.preventDefault();
1095							_self.objects.prev.click();
1096							if (_self.isSlideshowEnabled()) {
1097								_self._stopTimeout();
1098							}
1099						});
1100					}
1101				}
1102			}
1103		},
1104
1105		/**
1106		 * Adds the key events
1107		 *
1108		 * @return	{void}
1109		 */
1110		_addKeyEvents: function () {
1111			$(document).bind('keyup.lightcase', function (event) {
1112				// Do nothing if lightcase is in process
1113				if (_self.isBusy) {
1114					return;
1115				}
1116
1117				switch (event.keyCode) {
1118					// Escape key
1119					case 27:
1120						_self.objects.close.click();
1121						break;
1122					// Backward key
1123					case 37:
1124						if (_self.objectData.isPartOfSequence) {
1125							_self.objects.prev.click();
1126						}
1127						break;
1128					// Forward key
1129					case 39:
1130						if (_self.objectData.isPartOfSequence) {
1131							_self.objects.next.click();
1132						}
1133						break;
1134				}
1135			});
1136		},
1137
1138		/**
1139		 * Starts the slideshow timeout
1140		 *
1141		 * @return	{void}
1142		 */
1143		_startTimeout: function () {
1144			_self.isSlideshowStarted = true;
1145
1146			_self.objects.play.hide();
1147			_self.objects.pause.show();
1148
1149			_self.cache.action = 'next';
1150			_self.objects.nav.removeClass(_self.settings.classPrefix + 'paused');
1151
1152			_self.timeout = setTimeout(function () {
1153				_self.objects.nav.data('items').next.click();
1154			}, _self.settings.timeout);
1155		},
1156
1157		/**
1158		 * Stops the slideshow timeout
1159		 *
1160		 * @return	{void}
1161		 */
1162		_stopTimeout: function () {
1163			_self.objects.play.show();
1164			_self.objects.pause.hide();
1165
1166			_self.objects.nav.addClass(_self.settings.classPrefix + 'paused');
1167
1168			clearTimeout(_self.timeout);
1169		},
1170
1171		/**
1172		 * Sets the navigator buttons (prev/next)
1173		 *
1174		 * @return	{object}	items
1175		 */
1176		_setNavigation: function () {
1177			var $links = $((_self.cache.selector || _self.settings.attr)),
1178				sequenceLength = _self.objectData.sequenceLength - 1,
1179				items = {
1180					prev: $links.eq(_self.objectData.prevIndex),
1181					next: $links.eq(_self.objectData.nextIndex)
1182				};
1183
1184			if (_self.objectData.currentIndex > 0) {
1185				_self.objects.prev.show();
1186			} else {
1187				items.prevItem = $links.eq(sequenceLength);
1188			}
1189			if (_self.objectData.nextIndex <= sequenceLength) {
1190				_self.objects.next.show();
1191			} else {
1192				items.next = $links.eq(0);
1193			}
1194
1195			if (_self.settings.navigateEndless === true) {
1196				_self.objects.prev.show();
1197				_self.objects.next.show();
1198			}
1199
1200			return items;
1201		},
1202
1203		/**
1204		 * Item information/status
1205		 *
1206		 */
1207		item: {
1208			/**
1209			 * Verifies if the current item is first item.
1210			 *
1211			 * @return	{boolean}
1212			 */
1213			isFirst: function () {
1214				return (_self.objectData.currentIndex === 0);
1215			},
1216
1217			/**
1218			 * Verifies if the current item is first item opened.
1219			 *
1220			 * @return	{boolean}
1221			 */
1222			isFirstOpened: function () {
1223				return _self.objectData.this.is(_self.cache.firstOpened);
1224			},
1225
1226			/**
1227			 * Verifies if the current item is last item.
1228			 *
1229			 * @return	{boolean}
1230			 */
1231			isLast: function () {
1232				return (_self.objectData.currentIndex === (_self.objectData.sequenceLength - 1));
1233			}
1234		},
1235
1236		/**
1237		 * Clones the object for inline elements
1238		 *
1239		 * @param	{object}	$object
1240		 * @return	{object}	$clone
1241		 */
1242		_cloneObject: function ($object) {
1243			var $clone = $object.clone(),
1244				objectId = $object.attr('id');
1245
1246			// If element is hidden, cache the object and remove
1247			if ($object.is(':hidden')) {
1248				_self._cacheObjectData($object);
1249				$object.attr('id', _self.settings.idPrefix + 'temp-' + objectId).empty();
1250			} else {
1251				// Prevent duplicated id's
1252				$clone.removeAttr('id');
1253			}
1254
1255			return $clone.show();
1256		},
1257
1258		/**
1259		 * Verifies if it is a mobile device
1260		 *
1261		 * @return	{boolean}
1262		 */
1263		isMobileDevice: function () {
1264			var deviceAgent = navigator.userAgent.toLowerCase(),
1265				agentId = deviceAgent.match(_self.settings.mobileMatchExpression);
1266
1267			return agentId ? true : false;
1268		},
1269
1270		/**
1271		 * Verifies if css transitions are supported
1272		 *
1273		 * @return	{string|boolean}	The transition prefix if supported, else false.
1274		 */
1275		isTransitionSupported: function () {
1276			var body = _self.objects.body.get(0),
1277				isTransitionSupported = false,
1278				transitionMapping = {
1279					'transition': '',
1280					'WebkitTransition': '-webkit-',
1281					'MozTransition': '-moz-',
1282					'OTransition': '-o-',
1283					'MsTransition': '-ms-'
1284				};
1285
1286			for (var key in transitionMapping) {
1287				if (transitionMapping.hasOwnProperty(key) && key in body.style) {
1288					_self.support.transition = transitionMapping[key];
1289					isTransitionSupported = true;
1290				}
1291			}
1292
1293			return isTransitionSupported;
1294		},
1295
1296		/**
1297		 * Transition types
1298		 *
1299		 */
1300		transition: {
1301			/**
1302			 * Returns the correct transition type according to the status of interaction.
1303			 *
1304			 * @return	{string}	Transition type
1305			 */
1306			in: function () {
1307				if (_self.settings.transitionOpen && !_self.cache.firstOpened) {
1308					return _self.settings.transitionOpen;
1309				}
1310				return _self.settings.transitionIn;
1311			},
1312
1313			/**
1314			 * Fades in/out the object
1315			 *
1316			 * @param	{object}	$object
1317			 * @param	{string}	type
1318			 * @param	{number}	speed
1319			 * @param	{number}	opacity
1320			 * @param	{function}	callback
1321			 * @return	{void}		Animates an object
1322			 */
1323			fade: function ($object, type, speed, opacity, callback) {
1324				var isInTransition = type === 'in',
1325					startTransition = {},
1326					startOpacity = $object.css('opacity'),
1327					endTransition = {},
1328					endOpacity = opacity ? opacity: isInTransition ? 1 : 0;
1329
1330				if (!_self.isOpen && isInTransition) return;
1331
1332				startTransition['opacity'] = startOpacity;
1333				endTransition['opacity'] = endOpacity;
1334
1335				$object.css(_self.support.transition + 'transition', 'none');
1336				$object.css(startTransition).show();
1337
1338				// Css transition
1339				if (_self.support.transitions) {
1340					endTransition[_self.support.transition + 'transition'] = speed + 'ms ease';
1341
1342					setTimeout(function () {
1343						$object.css(endTransition);
1344
1345						setTimeout(function () {
1346							$object.css(_self.support.transition + 'transition', '');
1347
1348							if (callback && (_self.isOpen || !isInTransition)) {
1349								callback();
1350							}
1351						}, speed);
1352					}, 15);
1353				} else {
1354					// Fallback to js transition
1355					$object.stop();
1356					$object.animate(endTransition, speed, callback);
1357				}
1358			},
1359
1360			/**
1361			 * Scrolls in/out the object
1362			 *
1363			 * @param	{object}	$object
1364			 * @param	{string}	type
1365			 * @param	{number}	speed
1366			 * @param	{function}	callback
1367			 * @return	{void}		Animates an object
1368			 */
1369			scroll: function ($object, type, speed, callback) {
1370				var isInTransition = type === 'in',
1371					transition = isInTransition ? _self.settings.transitionIn : _self.settings.transitionOut,
1372					direction = 'left',
1373					startTransition = {},
1374					startOpacity = isInTransition ? 0 : 1,
1375					startOffset = isInTransition ? '-50%' : '50%',
1376					endTransition = {},
1377					endOpacity = isInTransition ? 1 : 0,
1378					endOffset = isInTransition ? '50%' : '-50%';
1379
1380				if (!_self.isOpen && isInTransition) return;
1381
1382				switch (transition) {
1383					case 'scrollTop':
1384						direction = 'top';
1385						break;
1386					case 'scrollRight':
1387						startOffset = isInTransition ? '150%' : '50%';
1388						endOffset = isInTransition ? '50%' : '150%';
1389						break;
1390					case 'scrollBottom':
1391						direction = 'top';
1392						startOffset = isInTransition ? '150%' : '50%';
1393						endOffset = isInTransition ? '50%' : '150%';
1394						break;
1395					case 'scrollHorizontal':
1396						startOffset = isInTransition ? '150%' : '50%';
1397						endOffset = isInTransition ? '50%' : '-50%';
1398						break;
1399					case 'scrollVertical':
1400						direction = 'top';
1401						startOffset = isInTransition ? '-50%' : '50%';
1402						endOffset = isInTransition ? '50%' : '150%';
1403						break;
1404				}
1405
1406				if (_self.cache.action === 'prev') {
1407					switch (transition) {
1408						case 'scrollHorizontal':
1409							startOffset = isInTransition ? '-50%' : '50%';
1410							endOffset = isInTransition ? '50%' : '150%';
1411							break;
1412						case 'scrollVertical':
1413							startOffset = isInTransition ? '150%' : '50%';
1414							endOffset = isInTransition ? '50%' : '-50%';
1415							break;
1416					}
1417				}
1418
1419				startTransition['opacity'] = startOpacity;
1420				startTransition[direction] = startOffset;
1421
1422				endTransition['opacity'] = endOpacity;
1423				endTransition[direction] = endOffset;
1424
1425				$object.css(_self.support.transition + 'transition', 'none');
1426				$object.css(startTransition).show();
1427
1428				// Css transition
1429				if (_self.support.transitions) {
1430					endTransition[_self.support.transition + 'transition'] = speed + 'ms ease';
1431
1432					setTimeout(function () {
1433						$object.css(endTransition);
1434
1435						setTimeout(function () {
1436							$object.css(_self.support.transition + 'transition', '');
1437
1438							if (callback && (_self.isOpen || !isInTransition)) {
1439								callback();
1440							}
1441						}, speed);
1442					}, 15);
1443				} else {
1444					// Fallback to js transition
1445					$object.stop();
1446					$object.animate(endTransition, speed, callback);
1447				}
1448			},
1449
1450			/**
1451			 * Zooms in/out the object
1452			 *
1453			 * @param	{object}	$object
1454			 * @param	{string}	type
1455			 * @param	{number}	speed
1456			 * @param	{function}	callback
1457			 * @return	{void}		Animates an object
1458			 */
1459			zoom: function ($object, type, speed, callback) {
1460				var isInTransition = type === 'in',
1461					startTransition = {},
1462					startOpacity = $object.css('opacity'),
1463					startScale = isInTransition ? 'scale(0.75)' : 'scale(1)',
1464					endTransition = {},
1465					endOpacity = isInTransition ? 1 : 0,
1466					endScale = isInTransition ? 'scale(1)' : 'scale(0.75)';
1467
1468				if (!_self.isOpen && isInTransition) return;
1469
1470				startTransition['opacity'] = startOpacity;
1471				startTransition[_self.support.transition + 'transform'] = startScale;
1472
1473				endTransition['opacity'] = endOpacity;
1474
1475				$object.css(_self.support.transition + 'transition', 'none');
1476				$object.css(startTransition).show();
1477
1478				// Css transition
1479				if (_self.support.transitions) {
1480					endTransition[_self.support.transition + 'transform'] = endScale;
1481					endTransition[_self.support.transition + 'transition'] = speed + 'ms ease';
1482
1483					setTimeout(function () {
1484						$object.css(endTransition);
1485
1486						setTimeout(function () {
1487							$object.css(_self.support.transition + 'transform', '');
1488							$object.css(_self.support.transition + 'transition', '');
1489
1490							if (callback && (_self.isOpen || !isInTransition)) {
1491								callback();
1492							}
1493						}, speed);
1494					}, 15);
1495				} else {
1496					// Fallback to js transition
1497					$object.stop();
1498					$object.animate(endTransition, speed, callback);
1499				}
1500			}
1501		},
1502
1503		/**
1504		 * Calls all the registered functions of a specific hook
1505		 *
1506		 * @param	{object}	hooks
1507		 * @return	{void}
1508		 */
1509		_callHooks: function (hooks) {
1510			if (typeof(hooks) === 'object') {
1511				$.each(hooks, function(index, hook) {
1512					if (typeof(hook) === 'function') {
1513						hook.call(_self.origin);
1514					}
1515				});
1516			}
1517		},
1518
1519		/**
1520		 * Caches the object data
1521		 *
1522		 * @param	{object}	$object
1523		 * @return	{void}
1524		 */
1525		_cacheObjectData: function ($object) {
1526			$.data($object, 'cache', {
1527				id: $object.attr('id'),
1528				content: $object.html()
1529			});
1530
1531			_self.cache.originalObject = $object;
1532		},
1533
1534		/**
1535		 * Restores the object from cache
1536		 *
1537		 * @return	void
1538		 */
1539		_restoreObject: function () {
1540			var $object = $('[id^="' + _self.settings.idPrefix + 'temp-"]');
1541
1542			$object.attr('id', $.data(_self.cache.originalObject, 'cache').id);
1543			$object.html($.data(_self.cache.originalObject, 'cache').content);
1544		},
1545
1546		/**
1547		 * Executes functions for a window resize.
1548		 * It stops an eventual timeout and recalculates dimensions.
1549		 *
1550		 * @param	{object}	dimensions
1551		 * @return	{void}
1552		 */
1553		resize: function (event, dimensions) {
1554			if (!_self.isOpen) return;
1555
1556			if (_self.isSlideshowEnabled()) {
1557				_self._stopTimeout();
1558			}
1559
1560			if (typeof dimensions === 'object' && dimensions !== null) {
1561				if (dimensions.width) {
1562					_self.cache.object.attr(
1563						_self._prefixAttributeName('width'),
1564						dimensions.width
1565					);
1566				}
1567				if (dimensions.maxWidth) {
1568					_self.cache.object.attr(
1569						_self._prefixAttributeName('max-width'),
1570						dimensions.maxWidth
1571					);
1572				}
1573				if (dimensions.height) {
1574					_self.cache.object.attr(
1575						_self._prefixAttributeName('height'),
1576						dimensions.height
1577					);
1578				}
1579				if (dimensions.maxHeight) {
1580					_self.cache.object.attr(
1581						_self._prefixAttributeName('max-height'),
1582						dimensions.maxHeight
1583					);
1584				}
1585			}
1586
1587			_self.dimensions = _self.getViewportDimensions();
1588			_self._calculateDimensions(_self.cache.object);
1589
1590			// Call onResize hook functions
1591			_self._callHooks(_self.settings.onResize);
1592		},
1593
1594		/**
1595		 * Watches for any resize interaction and caches the new sizes.
1596		 *
1597		 * @return	{void}
1598		 */
1599		_watchResizeInteraction: function () {
1600			$(window).resize(_self.resize);
1601		},
1602
1603		/**
1604		 * Stop watching any resize interaction related to _self.
1605		 *
1606		 * @return	{void}
1607		 */
1608		_unwatchResizeInteraction: function () {
1609			$(window).off('resize', _self.resize);
1610		},
1611
1612		/**
1613		 * Switches to the fullscreen mode
1614		 *
1615		 * @return	{void}
1616		 */
1617		_switchToFullScreenMode: function () {
1618			_self.settings.shrinkFactor = 1;
1619			_self.settings.overlayOpacity = 1;
1620
1621			$('html').addClass(_self.settings.classPrefix + 'fullScreenMode');
1622		},
1623
1624		/**
1625		 * Enters into the lightcase view
1626		 *
1627		 * @return	{void}
1628		 */
1629		_open: function () {
1630			_self.isOpen = true;
1631
1632			_self.support.transitions = _self.settings.cssTransitions ? _self.isTransitionSupported() : false;
1633			_self.support.mobileDevice = _self.isMobileDevice();
1634
1635			if (_self.support.mobileDevice) {
1636				$('html').addClass(_self.settings.classPrefix + 'isMobileDevice');
1637
1638				if (_self.settings.fullScreenModeForMobile) {
1639					_self._switchToFullScreenMode();
1640				}
1641			}
1642
1643			if (!_self.settings.transitionIn) {
1644				_self.settings.transitionIn = _self.settings.transition;
1645			}
1646			if (!_self.settings.transitionOut) {
1647				_self.settings.transitionOut = _self.settings.transition;
1648			}
1649
1650			switch (_self.transition.in()) {
1651				case 'fade':
1652				case 'fadeInline':
1653				case 'elastic':
1654				case 'scrollTop':
1655				case 'scrollRight':
1656				case 'scrollBottom':
1657				case 'scrollLeft':
1658				case 'scrollVertical':
1659				case 'scrollHorizontal':
1660					if (_self.objects.case.is(':hidden')) {
1661						_self.objects.close.css('opacity', 0);
1662						_self.objects.overlay.css('opacity', 0);
1663						_self.objects.case.css('opacity', 0);
1664						_self.objects.contentInner.css('opacity', 0);
1665					}
1666					_self.transition.fade(_self.objects.overlay, 'in', _self.settings.speedIn, _self.settings.overlayOpacity, function () {
1667						_self.transition.fade(_self.objects.close, 'in', _self.settings.speedIn);
1668						_self._handleEvents();
1669						_self._processContent();
1670					});
1671					break;
1672				default:
1673					_self.transition.fade(_self.objects.overlay, 'in', 0, _self.settings.overlayOpacity, function () {
1674						_self.transition.fade(_self.objects.close, 'in', 0);
1675						_self._handleEvents();
1676						_self._processContent();
1677					});
1678					break;
1679			}
1680
1681			_self.objects.document.addClass(_self.settings.classPrefix + 'open');
1682			_self.objects.case.attr('aria-hidden', 'false');
1683		},
1684
1685		/**
1686		 * Shows the lightcase by starting the transition
1687		 */
1688		show: function () {
1689			// Call onCalculateDimensions hook functions
1690			_self._callHooks(_self.settings.onBeforeCalculateDimensions);
1691
1692			_self._calculateDimensions(_self.cache.object);
1693
1694			// Call onAfterCalculateDimensions hook functions
1695			_self._callHooks(_self.settings.onAfterCalculateDimensions);
1696
1697			_self._startInTransition();
1698		},
1699
1700		/**
1701		 * Escapes from the lightcase view
1702		 *
1703		 * @return	{void}
1704		 */
1705		close: function () {
1706			_self.isOpen = false;
1707
1708			if (_self.isSlideshowEnabled()) {
1709				_self._stopTimeout();
1710				_self.isSlideshowStarted = false;
1711				_self.objects.nav.removeClass(_self.settings.classPrefix + 'paused');
1712			}
1713
1714			_self.objects.loading.hide();
1715
1716			_self._unbindEvents();
1717
1718			_self._unwatchResizeInteraction();
1719
1720			$('html').removeClass(_self.settings.classPrefix + 'open');
1721			_self.objects.case.attr('aria-hidden', 'true');
1722
1723			_self.objects.nav.children().hide();
1724			_self.objects.close.hide();
1725
1726			// Call onClose hook functions
1727			_self._callHooks(_self.settings.onClose);
1728
1729			// Fade out the info at first
1730			_self.transition.fade(_self.objects.info, 'out', 0);
1731
1732			switch (_self.settings.transitionClose || _self.settings.transitionOut) {
1733				case 'fade':
1734				case 'fadeInline':
1735				case 'scrollTop':
1736				case 'scrollRight':
1737				case 'scrollBottom':
1738				case 'scrollLeft':
1739				case 'scrollHorizontal':
1740				case 'scrollVertical':
1741					_self.transition.fade(_self.objects.case, 'out', _self.settings.speedOut, 0, function () {
1742						_self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedOut, 0, function () {
1743							_self.cleanup();
1744						});
1745					});
1746					break;
1747				case 'elastic':
1748					_self.transition.zoom(_self.objects.case, 'out', _self.settings.speedOut, function () {
1749						_self.transition.fade(_self.objects.overlay, 'out', _self.settings.speedOut, 0, function () {
1750							_self.cleanup();
1751						});
1752					});
1753					break;
1754				default:
1755					_self.cleanup();
1756					break;
1757			}
1758		},
1759
1760		/**
1761		 * Unbinds all given events
1762		 *
1763		 * @return	{void}
1764		 */
1765		_unbindEvents: function () {
1766			// Unbind overlay event
1767			_self.objects.overlay.unbind('click');
1768
1769			// Unbind key events
1770			$(document).unbind('keyup.lightcase');
1771
1772			// Unbind swipe events
1773			_self.objects.case.unbind('swipeleft').unbind('swiperight');
1774
1775			// Unbind navigator events
1776			_self.objects.prev.unbind('click');
1777			_self.objects.next.unbind('click');
1778			_self.objects.play.unbind('click');
1779			_self.objects.pause.unbind('click');
1780
1781			// Unbind close event
1782			_self.objects.close.unbind('click');
1783		},
1784
1785		/**
1786		 * Cleans up the dimensions
1787		 *
1788		 * @return	{void}
1789		 */
1790		_cleanupDimensions: function () {
1791			var opacity = _self.objects.contentInner.css('opacity');
1792
1793			_self.objects.case.css({
1794				'width': '',
1795				'height': '',
1796				'top': '',
1797				'left': '',
1798				'margin-top': '',
1799				'margin-left': ''
1800			});
1801
1802			_self.objects.contentInner.removeAttr('style').css('opacity', opacity);
1803			_self.objects.contentInner.children().removeAttr('style');
1804		},
1805
1806		/**
1807		 * Cleanup after aborting lightcase
1808		 *
1809		 * @return	{void}
1810		 */
1811		cleanup: function () {
1812			_self._cleanupDimensions();
1813
1814			_self.objects.loading.hide();
1815			_self.objects.overlay.hide();
1816			_self.objects.case.hide();
1817			_self.objects.prev.hide();
1818			_self.objects.next.hide();
1819			_self.objects.play.hide();
1820			_self.objects.pause.hide();
1821
1822			_self.objects.document.removeAttr(_self._prefixAttributeName('type'));
1823			_self.objects.nav.removeAttr(_self._prefixAttributeName('ispartofsequence'));
1824
1825			_self.objects.contentInner.empty().hide();
1826			_self.objects.info.children().empty();
1827
1828			if (_self.cache.originalObject) {
1829				_self._restoreObject();
1830			}
1831
1832			// Call onCleanup hook functions
1833			_self._callHooks(_self.settings.onCleanup);
1834
1835			// Restore cache
1836			_self.cache = {};
1837		},
1838
1839		/**
1840		 * Returns the supported match media or undefined if the browser
1841		 * doesn't support match media.
1842		 *
1843		 * @return	{mixed}
1844		 */
1845		_matchMedia: function () {
1846			return window.matchMedia || window.msMatchMedia;
1847		},
1848
1849		/**
1850		 * Returns the devicePixelRatio if supported. Else, it simply returns
1851		 * 1 as the default.
1852		 *
1853		 * @return	{number}
1854		 */
1855		_devicePixelRatio: function () {
1856			return window.devicePixelRatio || 1;
1857		},
1858
1859		/**
1860		 * Checks if method is public
1861		 *
1862		 * @return	{boolean}
1863		 */
1864		_isPublicMethod: function (method) {
1865			return (typeof _self[method] === 'function' && method.charAt(0) !== '_');
1866		},
1867
1868		/**
1869		 * Exports all public methods to be accessible, callable
1870		 * from global scope.
1871		 *
1872		 * @return	{void}
1873		 */
1874		_export: function () {
1875			window.lightcase = {};
1876
1877			$.each(_self, function (property) {
1878				if (_self._isPublicMethod(property)) {
1879					lightcase[property] = _self[property];
1880				}
1881			});
1882		}
1883	};
1884
1885	_self._export();
1886
1887	$.fn.lightcase = function (method) {
1888		// Method calling logic (only public methods are applied)
1889		if (_self._isPublicMethod(method)) {
1890			return _self[method].apply(this, Array.prototype.slice.call(arguments, 1));
1891		} else if (typeof method === 'object' || !method) {
1892			return _self.init.apply(this, arguments);
1893		} else {
1894			$.error('Method ' + method + ' does not exist on jQuery.lightcase');
1895		}
1896	};
1897})(jQuery);

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.