PageSourceSearch

https://mremote.org/js/libs/jquery.fancybox.pack.js

js mremote.org collected 2026-10-02 11:48:55 UTC 49,042 bytes, 2,028 lines download raw bytes

vendor: 5,809 bytes, lines 1-214
1/*!
2 * fancyBox - jQuery Plugin
3 * version: 2.1.5 (Fri, 14 Jun 2013)
4 * requires jQuery v1.6 or later
5 *
6 * Examples at http://fancyapps.com/fancybox/
7 * License: www.fancyapps.com/fancybox/#license
8 *
9 * Copyright 2012 Janis Skarnelis - [email protected]
10 *
11 */
12
13;(function (window, document, $, undefined) {
14	"use strict";
15
16	var H = $("html"),
17		W = $(window),
18		D = $(document),
19		F = $.fancybox = function () {
20			F.open.apply( this, arguments );
21		},
22		IE =  navigator.userAgent.match(/msie/i),
23		didUpdate	= null,
24		isTouch		= document.createTouch !== undefined,
25
26		isQuery	= function(obj) {
27			return obj && obj.hasOwnProperty && obj instanceof $;
28		},
29		isString = function(str) {
30			return str && $.type(str) === "string";
31		},
32		isPercentage = function(str) {
33			return isString(str) && str.indexOf('%') > 0;
34		},
35		isScrollable = function(el) {
36			return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
37		},
38		getScalar = function(orig, dim) {
39			var value = parseInt(orig, 10) || 0;
40
41			if (dim && isPercentage(orig)) {
42				value = F.getViewport()[ dim ] / 100 * value;
43			}
44
45			return Math.ceil(value);
46		},
47		getValue = function(value, dim) {
48			return getScalar(value, dim) + 'px';
49		};
50
51	$.extend(F, {
52		// The current version of fancyBox
53		version: '2.1.5',
54
55		defaults: {
56			padding : 15,
57			margin  : 20,
58
59			width     : 800,
60			height    : 600,
61			minWidth  : 100,
62			minHeight : 100,
63			maxWidth  : 9999,
64			maxHeight : 9999,
65			pixelRatio: 1, // Set to 2 for retina display support
66
67			autoSize   : true,
68			autoHeight : false,
69			autoWidth  : false,
70
71			autoResize  : true,
72			autoCenter  : !isTouch,
73			fitToView   : true,
74			aspectRatio : false,
75			topRatio    : 0.5,
76			leftRatio   : 0.5,
77
78			scrolling : 'auto', // 'auto', 'yes' or 'no'
79			wrapCSS   : '',
80
81			arrows     : true,
82			closeBtn   : true,
83			closeClick : false,
84			nextClick  : false,
85			mouseWheel : true,
86			autoPlay   : false,
87			playSpeed  : 3000,
88			preload    : 3,
89			modal      : false,
90			loop       : true,
91
92			ajax  : {
93				dataType : 'html',
94				headers  : { 'X-fancyBox': true }
95			},
96			iframe : {
97				scrolling : 'auto',
98				preload   : true
99			},
100			swf : {
101				wmode: 'transparent',
102				allowfullscreen   : 'true',
103				allowscriptaccess : 'always'
104			},
105
106			keys  : {
107				next : {
108					13 : 'left', // enter
109					34 : 'up',   // page down
110					39 : 'left', // right arrow
111					40 : 'up'    // down arrow
112				},
113				prev : {
114					8  : 'right',  // backspace
115					33 : 'down',   // page up
116					37 : 'right',  // left arrow
117					38 : 'down'    // up arrow
118				},
119				close  : [27], // escape key
120				play   : [32], // space - start/stop slideshow
121				toggle : [70]  // letter "f" - toggle fullscreen
122			},
123
124			direction : {
125				next : 'left',
126				prev : 'right'
127			},
128
129			scrollOutside  : true,
130
131			// Override some properties
132			index   : 0,
133			type    : null,
134			href    : null,
135			content : null,
136			title   : null,
137
138			// HTML templates
139			tpl: {
140				wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
141				image    : '<img class="fancybox-image" src="{href}" alt="" {srcset}/>',
142				iframe   : '<iframe id="fancybox-frame{rnd}" name="fancybox-frame{rnd}" class="fancybox-iframe" frameborder="0" vspace="0" hspace="0" webkitAllowFullScreen mozallowfullscreen allowFullScreen' + (IE ? ' allowtransparency="true"' : '') + '></iframe>',
143				error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
144				closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
145				next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
146				prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>',
147				loading  : '<div id="fancybox-loading"><div></div></div>'
148			},
149
150			// Properties for each animation type
151			// Opening fancyBox
152			openEffect  : 'fade', // 'elastic', 'fade' or 'none'
153			openSpeed   : 250,
154			openEasing  : 'swing',
155			openOpacity : true,
156			openMethod  : 'zoomIn',
157
158			// Closing fancyBox
159			closeEffect  : 'fade', // 'elastic', 'fade' or 'none'
160			closeSpeed   : 250,
161			closeEasing  : 'swing',
162			closeOpacity : true,
163			closeMethod  : 'zoomOut',
164
165			// Changing next gallery item
166			nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
167			nextSpeed  : 250,
168			nextEasing : 'swing',
169			nextMethod : 'changeIn',
170
171			// Changing previous gallery item
172			prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
173			prevSpeed  : 250,
174			prevEasing : 'swing',
175			prevMethod : 'changeOut',
176
177			// Enable default helpers
178			helpers : {
179				overlay : true,
180				title   : true
181			},
182
183			// Callbacks
184			onCancel     : $.noop, // If canceling
185			beforeLoad   : $.noop, // Before loading
186			afterLoad    : $.noop, // After loading
187			beforeShow   : $.noop, // Before changing in current item
188			afterShow    : $.noop, // After opening
189			beforeChange : $.noop, // Before changing gallery item
190			beforeClose  : $.noop, // Before closing
191			afterClose   : $.noop  // After closing
192		},
193
194		//Current state
195		group    : {}, // Selected group
196		opts     : {}, // Group options
197		previous : null,  // Previous element
198		coming   : null,  // Element being loaded
199		current  : null,  // Currently loaded element
200		isActive : false, // Is activated
201		isOpen   : false, // Is currently open
202		isOpened : false, // Have been fully opened at least once
203
204		wrap  : null,
205		skin  : null,
206		outer : null,
207		inner : null,
208
209		player : {
210			timer    : null,
211			isActive : false
212		},
213
214		// Loaders
vendor: 1,197 bytes, lines 215-272
215		ajaxLoad   : null,
216		imgPreload : null,
217
218		// Some collections
219		transitions : {},
220		helpers     : {},
221
222		/*
223		 *	Static methods
224		 */
225
226		open: function (group, opts) {
227			if (!group) {
228				return;
229			}
230
231			if (!$.isPlainObject(opts)) {
232				opts = {};
233			}
234
235			// Close if already active
236			if (false === F.close(true)) {
237				return;
238			}
239
240			// Normalize group
241			if (!$.isArray(group)) {
242				group = isQuery(group) ? $(group).get() : [group];
243			}
244
245			// Recheck if the type of each element is `object` and set content type (image, ajax, etc)
246			$.each(group, function(i, element) {
247				var obj = {},
248					href,
249					title,
250					content,
251					type,
252					rez,
253					hrefParts,
254					selector;
255
256				if ($.type(element) === "object") {
257					// Check if is DOM element
258					if (element.nodeType) {
259						element = $(element);
260					}
261
262					if (isQuery(element)) {
263						obj = {
264							href    : element.data('fancybox-href') || element.attr('href'),
265							title   : $('<div/>').text( element.data('fancybox-title') || element.attr('title') || '' ).html(),
266							isDom   : true,
267							element : element
268						};
269
270						if(element.data('srcset')){
271							obj.srcset = element.data('srcset');
272						}
vendor: 19,097 bytes, lines 272-1130
272
273
274						if ($.metadata) {
275							$.extend(true, obj, element.metadata());
276						}
277
278					} else {
279						obj = element;
280					}
281				}
282
283				href  = opts.href  || obj.href || (isString(element) ? element : null);
284				title = opts.title !== undefined ? opts.title : obj.title || '';
285
286				content = opts.content || obj.content;
287				type    = content ? 'html' : (opts.type  || obj.type);
288
289				if (!type && obj.isDom) {
290					type = element.data('fancybox-type');
291
292					if (!type) {
293						rez  = element.prop('class').match(/fancybox\.(\w+)/);
294						type = rez ? rez[1] : null;
295					}
296				}
297
298				if (isString(href)) {
299					// Try to guess the content type
300					if (!type) {
301						if (F.isImage(href)) {
302							type = 'image';
303
304						} else if (F.isSWF(href)) {
305							type = 'swf';
306
307						} else if (href.charAt(0) === '#') {
308							type = 'inline';
309
310						} else if (isString(element)) {
311							type    = 'html';
312							content = element;
313						}
314					}
315
316					// Split url into two pieces with source url and content selector, e.g,
317					// "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
318					if (type === 'ajax') {
319						hrefParts = href.split(/\s+/, 2);
320						href      = hrefParts.shift();
321						selector  = hrefParts.shift();
322					}
323				}
324
325				if (!content) {
326					if (type === 'inline') {
327						if (href) {
328							content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
329
330						} else if (obj.isDom) {
331							content = element;
332						}
333
334					} else if (type === 'html') {
335						content = href;
336
337					} else if (!type && !href && obj.isDom) {
338						type    = 'inline';
339						content = element;
340					}
341				}
342
343				$.extend(obj, {
344					href     : href,
345					type     : type,
346					content  : content,
347					title    : title,
348					selector : selector
349				});
350
351				group[ i ] = obj;
352			});
353
354			// Extend the defaults
355			F.opts = $.extend(true, {}, F.defaults, opts);
356
357			// All options are merged recursive except keys
358			if (opts.keys !== undefined) {
359				F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
360			}
361
362			F.group = group;
363
364			return F._start(F.opts.index);
365		},
366
367		// Cancel image loading or abort ajax request
368		cancel: function () {
369			var coming = F.coming;
370
371			if (coming && false === F.trigger('onCancel')) {
372				return;
373			}
374
375			F.hideLoading();
376
377			if (!coming) {
378				return;
379			}
380
381			if (F.ajaxLoad) {
382				F.ajaxLoad.abort();
383			}
384
385			F.ajaxLoad = null;
386
387			if (F.imgPreload) {
388				F.imgPreload.onload = F.imgPreload.onerror = null;
389			}
390
391			if (coming.wrap) {
392				coming.wrap.stop(true, true).trigger('onReset').remove();
393			}
394
395			F.coming = null;
396
397			// If the first item has been canceled, then clear everything
398			if (!F.current) {
399				F._afterZoomOut( coming );
400			}
401		},
402
403		// Start closing animation if is open; remove immediately if opening/closing
404		close: function (event) {
405			F.cancel();
406
407			if (false === F.trigger('beforeClose')) {
408				return;
409			}
410
411			F.unbindEvents();
412
413			if (!F.isActive) {
414				return;
415			}
416
417			if (!F.isOpen || event === true) {
418				$('.fancybox-wrap').stop(true).trigger('onReset').remove();
419
420				F._afterZoomOut();
421
422			} else {
423				F.isOpen = F.isOpened = false;
424				F.isClosing = true;
425
426				$('.fancybox-item, .fancybox-nav').remove();
427
428				F.wrap.stop(true, true).removeClass('fancybox-opened');
429
430				F.transitions[ F.current.closeMethod ]();
431			}
432		},
433
434		// Manage slideshow:
435		//   $.fancybox.play(); - toggle slideshow
436		//   $.fancybox.play( true ); - start
437		//   $.fancybox.play( false ); - stop
438		play: function ( action ) {
439			var clear = function () {
440					clearTimeout(F.player.timer);
441				},
442				set = function () {
443					clear();
444
445					if (F.current && F.player.isActive) {
446						F.player.timer = setTimeout(F.next, F.current.playSpeed);
447					}
448				},
449				stop = function () {
450					clear();
451
452					D.unbind('.player');
453
454					F.player.isActive = false;
455
456					F.trigger('onPlayEnd');
457				},
458				start = function () {
459					if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
460						F.player.isActive = true;
461
462						D.bind({
463							'onCancel.player beforeClose.player' : stop,
464							'onUpdate.player'   : set,
465							'beforeLoad.player' : clear
466						});
467
468						set();
469
470						F.trigger('onPlayStart');
471					}
472				};
473
474			if (action === true || (!F.player.isActive && action !== false)) {
475				start();
476			} else {
477				stop();
478			}
479		},
480
481		// Navigate to next gallery item
482		next: function ( direction ) {
483			var current = F.current;
484
485			if (current) {
486				if (!isString(direction)) {
487					direction = current.direction.next;
488				}
489
490				F.jumpto(current.index + 1, direction, 'next');
491			}
492		},
493
494		// Navigate to previous gallery item
495		prev: function ( direction ) {
496			var current = F.current;
497
498			if (current) {
499				if (!isString(direction)) {
500					direction = current.direction.prev;
501				}
502
503				F.jumpto(current.index - 1, direction, 'prev');
504			}
505		},
506
507		// Navigate to gallery item by index
508		jumpto: function ( index, direction, router ) {
509			var current = F.current;
510
511			if (!current) {
512				return;
513			}
514
515			index = getScalar(index);
516
517			F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
518			F.router    = router || 'jumpto';
519
520			if (current.loop) {
521				if (index < 0) {
522					index = current.group.length + (index % current.group.length);
523				}
524
525				index = index % current.group.length;
526			}
527
528			if (current.group[ index ] !== undefined) {
529				F.cancel();
530
531				F._start(index);
532			}
533		},
534
535		// Center inside viewport and toggle position type to fixed or absolute if needed
536		reposition: function (e, onlyAbsolute) {
537			var current = F.current,
538				wrap    = current ? current.wrap : null,
539				pos;
540
541			if (wrap) {
542				pos = F._getPosition(onlyAbsolute);
543
544				if (e && e.type === 'scroll') {
545					delete pos.position;
546
547					wrap.stop(true, true).animate(pos, 200);
548
549				} else {
550					wrap.css(pos);
551
552					current.pos = $.extend({}, current.dim, pos);
553				}
554			}
555		},
556
557		update: function (e) {
558			var type = (e && e.originalEvent && e.originalEvent.type),
559				anyway = !type || type === 'orientationchange';
560
561			if (anyway) {
562				clearTimeout(didUpdate);
563
564				didUpdate = null;
565			}
566
567			if (!F.isOpen || didUpdate) {
568				return;
569			}
570
571			didUpdate = setTimeout(function() {
572				var current = F.current;
573
574				if (!current || F.isClosing) {
575					return;
576				}
577
578				F.wrap.removeClass('fancybox-tmp');
579
580				if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
581					F._setDimension();
582				}
583
584				if (!(type === 'scroll' && current.canShrink)) {
585					F.reposition(e);
586				}
587
588				F.trigger('onUpdate');
589
590				didUpdate = null;
591
592			}, (anyway && !isTouch ? 0 : 300));
593		},
594
595		// Shrink content to fit inside viewport or restore if resized
596		toggle: function ( action ) {
597			if (F.isOpen) {
598				F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
599
600				// Help browser to restore document dimensions
601				if (isTouch) {
602					F.wrap.removeAttr('style').addClass('fancybox-tmp');
603
604					F.trigger('onUpdate');
605				}
606
607				F.update();
608			}
609		},
610
611		hideLoading: function () {
612			D.unbind('.loading');
613
614			$('#fancybox-loading').remove();
615		},
616
617		showLoading: function () {
618			var el, viewport;
619
620			F.hideLoading();
621
622			el = $(F.opts.tpl.loading).click(F.cancel).appendTo('body');
623
624			// If user will press the escape-button, the request will be canceled
625			D.bind('keydown.loading', function(e) {
626				if ((e.which || e.keyCode) === 27) {
627					e.preventDefault();
628
629					F.cancel();
630				}
631			});
632
633			if (!F.defaults.fixed) {
634				viewport = F.getViewport();
635
636				el.css({
637					position : 'absolute',
638					top  : (viewport.h * 0.5) + viewport.y,
639					left : (viewport.w * 0.5) + viewport.x
640				});
641			}
642
643			F.trigger('onLoading');
644		},
645
646		getViewport: function () {
647			var locked = (F.current && F.current.locked) || false,
648				rez    = {
649					x: W.scrollLeft(),
650					y: W.scrollTop()
651				};
652
653			if (locked && locked.length) {
654				rez.w = locked[0].clientWidth;
655				rez.h = locked[0].clientHeight;
656
657			} else {
658				// See http://bugs.jquery.com/ticket/6724
659				rez.w = isTouch && window.innerWidth  ? window.innerWidth  : W.width();
660				rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
661			}
662
663			return rez;
664		},
665
666		// Unbind the keyboard / clicking actions
667		unbindEvents: function () {
668			if (F.wrap && isQuery(F.wrap)) {
669				F.wrap.unbind('.fb');
670			}
671
672			D.unbind('.fb');
673			W.unbind('.fb');
674		},
675
676		bindEvents: function () {
677			var current = F.current,
678				keys;
679
680			if (!current) {
681				return;
682			}
683
684			// Changing document height on iOS devices triggers a 'resize' event,
685			// that can change document height... repeating infinitely
686			W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
687
688			keys = current.keys;
689
690			if (keys) {
691				D.bind('keydown.fb', function (e) {
692					var code   = e.which || e.keyCode,
693						target = e.target || e.srcElement;
694
695					// Skip esc key if loading, because showLoading will cancel preloading
696					if (code === 27 && F.coming) {
697						return false;
698					}
699
700					// Ignore key combinations and key events within form elements
701					if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
702						$.each(keys, function(i, val) {
703							if (current.group.length > 1 && val[ code ] !== undefined) {
704								F[ i ]( val[ code ] );
705
706								e.preventDefault();
707								return false;
708							}
709
710							if ($.inArray(code, val) > -1) {
711								F[ i ] ();
712
713								e.preventDefault();
714								return false;
715							}
716						});
717					}
718				});
719			}
720
721			if ($.fn.mousewheel && current.mouseWheel) {
722				F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
723					var target = e.target || null,
724						parent = $(target),
725						canScroll = false;
726
727					while (parent.length) {
728						if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {
729							break;
730						}
731
732						canScroll = isScrollable( parent[0] );
733						parent    = $(parent).parent();
734					}
735
736					if (delta !== 0 && !canScroll) {
737						if (F.group.length > 1 && !current.canShrink) {
738							if (deltaY > 0 || deltaX > 0) {
739								F.prev( deltaY > 0 ? 'down' : 'left' );
740
741							} else if (deltaY < 0 || deltaX < 0) {
742								F.next( deltaY < 0 ? 'up' : 'right' );
743							}
744
745							e.preventDefault();
746						}
747					}
748				});
749			}
750		},
751
752		trigger: function (event, o) {
753			var ret, obj = o || F.coming || F.current;
754
755			if (obj) {
756				if ($.isFunction( obj[event] )) {
757					ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
758				}
759
760				if (ret === false) {
761					return false;
762				}
763
764				if (obj.helpers) {
765					$.each(obj.helpers, function (helper, opts) {
766						if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
767							F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);
768						}
769					});
770				}
771			}
772
773			D.trigger(event);
774		},
775
776		isImage: function (str) {
777			return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
778		},
779
780		isSWF: function (str) {
781			return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
782		},
783
784		_start: function (index) {
785			var coming = {},
786				obj,
787				href,
788				type,
789				margin,
790				padding;
791
792			index = getScalar( index );
793			obj   = F.group[ index ] || null;
794
795			if (!obj) {
796				return false;
797			}
798
799			coming = $.extend(true, {}, F.opts, obj);
800
801			// Convert margin and padding properties to array - top, right, bottom, left
802			margin  = coming.margin;
803			padding = coming.padding;
804
805			if ($.type(margin) === 'number') {
806				coming.margin = [margin, margin, margin, margin];
807			}
808
809			if ($.type(padding) === 'number') {
810				coming.padding = [padding, padding, padding, padding];
811			}
812
813			// 'modal' propery is just a shortcut
814			if (coming.modal) {
815				$.extend(true, coming, {
816					closeBtn   : false,
817					closeClick : false,
818					nextClick  : false,
819					arrows     : false,
820					mouseWheel : false,
821					keys       : null,
822					helpers: {
823						overlay : {
824							closeClick : false
825						}
826					}
827				});
828			}
829
830			// 'autoSize' property is a shortcut, too
831			if (coming.autoSize) {
832				coming.autoWidth = coming.autoHeight = true;
833			}
834
835			if (coming.width === 'auto') {
836				coming.autoWidth = true;
837			}
838
839			if (coming.height === 'auto') {
840				coming.autoHeight = true;
841			}
842
843			/*
844			 * Add reference to the group, so it`s possible to access from callbacks, example:
845			 * afterLoad : function() {
846			 *     this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
847			 * }
848			 */
849
850			coming.group  = F.group;
851			coming.index  = index;
852
853			// Give a chance for callback or helpers to update coming item (type, title, etc)
854			F.coming = coming;
855
856			if (false === F.trigger('beforeLoad')) {
857				F.coming = null;
858
859				return;
860			}
861
862			type = coming.type;
863			href = coming.href;
864
865			if (!type) {
866				F.coming = null;
867
868				//If we can not determine content type then drop silently or display next/prev item if looping through gallery
869				if (F.current && F.router && F.router !== 'jumpto') {
870					F.current.index = index;
871
872					return F[ F.router ]( F.direction );
873				}
874
875				return false;
876			}
877
878			F.isActive = true;
879
880			if (type === 'image' || type === 'swf') {
881				coming.autoHeight = coming.autoWidth = false;
882				coming.scrolling  = 'visible';
883			}
884
885			if (type === 'image') {
886				coming.aspectRatio = true;
887			}
888
889			if (type === 'iframe' && isTouch) {
890				coming.scrolling = 'scroll';
891			}
892
893			// Build the neccessary markup
894			coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
895
896			$.extend(coming, {
897				skin  : $('.fancybox-skin',  coming.wrap),
898				outer : $('.fancybox-outer', coming.wrap),
899				inner : $('.fancybox-inner', coming.wrap)
900			});
901
902			$.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
903				coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
904			});
905
906			F.trigger('onReady');
907
908			// Check before try to load; 'inline' and 'html' types need content, others - href
909			if (type === 'inline' || type === 'html') {
910				if (!coming.content || !coming.content.length) {
911					return F._error( 'content' );
912				}
913
914			} else if (!href) {
915				return F._error( 'href' );
916			}
917
918			if (type === 'image') {
919				F._loadImage();
920
921			} else if (type === 'ajax') {
922				F._loadAjax();
923
924			} else if (type === 'iframe') {
925				F._loadIframe();
926
927			} else {
928				F._afterLoad();
929			}
930		},
931
932		_error: function ( type ) {
933			$.extend(F.coming, {
934				type       : 'html',
935				autoWidth  : true,
936				autoHeight : true,
937				minWidth   : 0,
938				minHeight  : 0,
939				scrolling  : 'no',
940				hasError   : type,
941				content    : F.coming.tpl.error
942			});
943
944			F._afterLoad();
945		},
946
947		_loadImage: function () {
948			// Reset preload image so it is later possible to check "complete" property
949			var img = F.imgPreload = new Image();
950
951			img.onload = function () {
952				this.onload = this.onerror = null;
953
954				F.coming.width  = this.width / F.opts.pixelRatio;
955				F.coming.height = this.height / F.opts.pixelRatio;
956
957				F._afterLoad();
958			};
959
960			img.onerror = function () {
961				this.onload = this.onerror = null;
962
963				F._error( 'image' );
964			};
965
966			img.src = F.coming.href;
967
968			if (img.complete !== true) {
969				F.showLoading();
970			}
971		},
972
973		_loadAjax: function () {
974			var coming = F.coming;
975
976			F.showLoading();
977
978			F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
979				url: coming.href,
980				error: function (jqXHR, textStatus) {
981					if (F.coming && textStatus !== 'abort') {
982						F._error( 'ajax', jqXHR );
983
984					} else {
985						F.hideLoading();
986					}
987				},
988				success: function (data, textStatus) {
989					if (textStatus === 'success') {
990						coming.content = data;
991
992						F._afterLoad();
993					}
994				}
995			}));
996		},
997
998		_loadIframe: function() {
999			var coming = F.coming,
1000				iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
1001					.attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
1002					.attr('src', coming.href);
1003
1004			// This helps IE
1005			$(coming.wrap).bind('onReset', function () {
1006				try {
1007					$(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
1008				} catch (e) {}
1009			});
1010
1011			if (coming.iframe.preload) {
1012				F.showLoading();
1013
1014				iframe.one('load', function() {
1015					$(this).data('ready', 1);
1016
1017					// iOS will lose scrolling if we resize
1018					if (!isTouch) {
1019						$(this).bind('load.fb', F.update);
1020					}
1021
1022					// Without this trick:
1023					//   - iframe won't scroll on iOS devices
1024					//   - IE7 sometimes displays empty iframe
1025					$(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();
1026
1027					F._afterLoad();
1028				});
1029			}
1030
1031			coming.content = iframe.appendTo( coming.inner );
1032
1033			if (!coming.iframe.preload) {
1034				F._afterLoad();
1035			}
1036		},
1037
1038		_preloadImages: function() {
1039			var group   = F.group,
1040				current = F.current,
1041				len     = group.length,
1042				cnt     = current.preload ? Math.min(current.preload, len - 1) : 0,
1043				item,
1044				i;
1045
1046			for (i = 1; i <= cnt; i += 1) {
1047				item = group[ (current.index + i ) % len ];
1048
1049				if (item.type === 'image' && item.href) {
1050					new Image().src = item.href;
1051				}
1052			}
1053		},
1054
1055		_afterLoad: function () {
1056			var coming   = F.coming,
1057				previous = F.current,
1058				placeholder = 'fancybox-placeholder',
1059				current,
1060				content,
1061				type,
1062				scrolling,
1063				href,
1064				embed;
1065
1066			F.hideLoading();
1067
1068			if (!coming || F.isActive === false) {
1069				return;
1070			}
1071
1072			if (false === F.trigger('afterLoad', coming, previous)) {
1073				coming.wrap.stop(true).trigger('onReset').remove();
1074
1075				F.coming = null;
1076
1077				return;
1078			}
1079
1080			if (previous) {
1081				F.trigger('beforeChange', previous);
1082
1083				previous.wrap.stop(true).removeClass('fancybox-opened')
1084					.find('.fancybox-item, .fancybox-nav')
1085					.remove();
1086			}
1087
1088			F.unbindEvents();
1089
1090			current   = coming;
1091			content   = coming.content;
1092			type      = coming.type;
1093			scrolling = coming.scrolling;
1094
1095			$.extend(F, {
1096				wrap  : current.wrap,
1097				skin  : current.skin,
1098				outer : current.outer,
1099				inner : current.inner,
1100				current  : current,
1101				previous : previous
1102			});
1103
1104			href = current.href;
1105
1106			switch (type) {
1107				case 'inline':
1108				case 'ajax':
1109				case 'html':
1110					if (current.selector) {
1111						content = $('<div>').html(content).find(current.selector);
1112
1113					} else if (isQuery(content)) {
1114						if (!content.data(placeholder)) {
1115							content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
1116						}
1117
1118						content = content.show().detach();
1119
1120						current.wrap.bind('onReset', function () {
1121							if ($(this).find(content).length) {
1122								content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
1123							}
1124						});
1125					}
1126				break;
1127
1128				case 'image':
1129					content = current.tpl.image.replace(/\{href\}/g, href);
1130				
1130	if(current.srcset){
1131						content = content.replace('{srcset}', 'srcset="'+current.srcset+'" ');
1132					}
1133					else{
1134						content = content.replace('{srcset}', '');
1135					}
vendor: 15,936 bytes, lines 1135-1732
1135
1136				break;
1137
1138				case 'swf':
1139					content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
1140					embed   = '';
1141
1142					$.each(current.swf, function(name, val) {
1143						content += '<param name="' + name + '" value="' + val + '"></param>';
1144						embed   += ' ' + name + '="' + val + '"';
1145					});
1146
1147					content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
1148				break;
1149			}
1150
1151			if (!(isQuery(content) && content.parent().is(current.inner))) {
1152				current.inner.append( content );
1153			}
1154
1155			// Give a chance for helpers or callbacks to update elements
1156			F.trigger('beforeShow');
1157
1158			// Set scrolling before calculating dimensions
1159			current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
1160
1161			// Set initial dimensions and start position
1162			F._setDimension();
1163
1164			F.reposition();
1165
1166			F.isOpen = false;
1167			F.coming = null;
1168
1169			F.bindEvents();
1170
1171			if (!F.isOpened) {
1172				$('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
1173
1174			} else if (previous.prevMethod) {
1175				F.transitions[ previous.prevMethod ]();
1176			}
1177
1178			F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
1179
1180			F._preloadImages();
1181		},
1182
1183		_setDimension: function () {
1184			var viewport   = F.getViewport(),
1185				steps      = 0,
1186				canShrink  = false,
1187				canExpand  = false,
1188				wrap       = F.wrap,
1189				skin       = F.skin,
1190				inner      = F.inner,
1191				current    = F.current,
1192				width      = current.width,
1193				height     = current.height,
1194				minWidth   = current.minWidth,
1195				minHeight  = current.minHeight,
1196				maxWidth   = current.maxWidth,
1197				maxHeight  = current.maxHeight,
1198				scrolling  = current.scrolling,
1199				scrollOut  = current.scrollOutside ? current.scrollbarWidth : 0,
1200				margin     = current.margin,
1201				wMargin    = getScalar(margin[1] + margin[3]),
1202				hMargin    = getScalar(margin[0] + margin[2]),
1203				wPadding,
1204				hPadding,
1205				wSpace,
1206				hSpace,
1207				origWidth,
1208				origHeight,
1209				origMaxWidth,
1210				origMaxHeight,
1211				ratio,
1212				width_,
1213				height_,
1214				maxWidth_,
1215				maxHeight_,
1216				iframe,
1217				body;
1218
1219			// Reset dimensions so we could re-check actual size
1220			wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
1221
1222			wPadding = getScalar(skin.outerWidth(true)  - skin.width());
1223			hPadding = getScalar(skin.outerHeight(true) - skin.height());
1224
1225			// Any space between content and viewport (margin, padding, border, title)
1226			wSpace = wMargin + wPadding;
1227			hSpace = hMargin + hPadding;
1228
1229			origWidth  = isPercentage(width)  ? (viewport.w - wSpace) * getScalar(width)  / 100 : width;
1230			origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
1231
1232			if (current.type === 'iframe') {
1233				iframe = current.content;
1234
1235				if (current.autoHeight && iframe.data('ready') === 1) {
1236					try {
1237						if (iframe[0].contentWindow.document.location) {
1238							inner.width( origWidth ).height(9999);
1239
1240							body = iframe.contents().find('body');
1241
1242							if (scrollOut) {
1243								body.css('overflow-x', 'hidden');
1244							}
1245
1246							origHeight = body.outerHeight(true);
1247						}
1248
1249					} catch (e) {}
1250				}
1251
1252			} else if (current.autoWidth || current.autoHeight) {
1253				inner.addClass( 'fancybox-tmp' );
1254
1255				// Set width or height in case we need to calculate only one dimension
1256				if (!current.autoWidth) {
1257					inner.width( origWidth );
1258				}
1259
1260				if (!current.autoHeight) {
1261					inner.height( origHeight );
1262				}
1263
1264				if (current.autoWidth) {
1265					origWidth = inner.width();
1266				}
1267
1268				if (current.autoHeight) {
1269					origHeight = inner.height();
1270				}
1271
1272				inner.removeClass( 'fancybox-tmp' );
1273			}
1274
1275			width  = getScalar( origWidth );
1276			height = getScalar( origHeight );
1277
1278			ratio  = origWidth / origHeight;
1279
1280			// Calculations for the content
1281			minWidth  = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
1282			maxWidth  = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
1283
1284			minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
1285			maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
1286
1287			// These will be used to determine if wrap can fit in the viewport
1288			origMaxWidth  = maxWidth;
1289			origMaxHeight = maxHeight;
1290
1291			if (current.fitToView) {
1292				maxWidth  = Math.min(viewport.w - wSpace, maxWidth);
1293				maxHeight = Math.min(viewport.h - hSpace, maxHeight);
1294			}
1295
1296			maxWidth_  = viewport.w - wMargin;
1297			maxHeight_ = viewport.h - hMargin;
1298
1299			if (current.aspectRatio) {
1300				if (width > maxWidth) {
1301					width  = maxWidth;
1302					height = getScalar(width / ratio);
1303				}
1304
1305				if (height > maxHeight) {
1306					height = maxHeight;
1307					width  = getScalar(height * ratio);
1308				}
1309
1310				if (width < minWidth) {
1311					width  = minWidth;
1312					height = getScalar(width / ratio);
1313				}
1314
1315				if (height < minHeight) {
1316					height = minHeight;
1317					width  = getScalar(height * ratio);
1318				}
1319
1320			} else {
1321				width = Math.max(minWidth, Math.min(width, maxWidth));
1322
1323				if (current.autoHeight && current.type !== 'iframe') {
1324					inner.width( width );
1325
1326					height = inner.height();
1327				}
1328
1329				height = Math.max(minHeight, Math.min(height, maxHeight));
1330			}
1331
1332			// Try to fit inside viewport (including the title)
1333			if (current.fitToView) {
1334				inner.width( width ).height( height );
1335
1336				wrap.width( width + wPadding );
1337
1338				// Real wrap dimensions
1339				width_  = wrap.width();
1340				height_ = wrap.height();
1341
1342				if (current.aspectRatio) {
1343					while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
1344						if (steps++ > 19) {
1345							break;
1346						}
1347
1348						height = Math.max(minHeight, Math.min(maxHeight, height - 10));
1349						width  = getScalar(height * ratio);
1350
1351						if (width < minWidth) {
1352							width  = minWidth;
1353							height = getScalar(width / ratio);
1354						}
1355
1356						if (width > maxWidth) {
1357							width  = maxWidth;
1358							height = getScalar(width / ratio);
1359						}
1360
1361						inner.width( width ).height( height );
1362
1363						wrap.width( width + wPadding );
1364
1365						width_  = wrap.width();
1366						height_ = wrap.height();
1367					}
1368
1369				} else {
1370					width  = Math.max(minWidth,  Math.min(width,  width  - (width_  - maxWidth_)));
1371					height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
1372				}
1373			}
1374
1375			if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
1376				width += scrollOut;
1377			}
1378
1379			inner.width( width ).height( height );
1380
1381			wrap.width( width + wPadding );
1382
1383			width_  = wrap.width();
1384			height_ = wrap.height();
1385
1386			canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
1387			canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
1388
1389			$.extend(current, {
1390				dim : {
1391					width	: getValue( width_ ),
1392					height	: getValue( height_ )
1393				},
1394				origWidth  : origWidth,
1395				origHeight : origHeight,
1396				canShrink  : canShrink,
1397				canExpand  : canExpand,
1398				wPadding   : wPadding,
1399				hPadding   : hPadding,
1400				wrapSpace  : height_ - skin.outerHeight(true),
1401				skinSpace  : skin.height() - height
1402			});
1403
1404			if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
1405				inner.height('auto');
1406			}
1407		},
1408
1409		_getPosition: function (onlyAbsolute) {
1410			var current  = F.current,
1411				viewport = F.getViewport(),
1412				margin   = current.margin,
1413				width    = F.wrap.width()  + margin[1] + margin[3],
1414				height   = F.wrap.height() + margin[0] + margin[2],
1415				rez      = {
1416					position: 'absolute',
1417					top  : margin[0],
1418					left : margin[3]
1419				};
1420
1421			if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
1422				rez.position = 'fixed';
1423
1424			} else if (!current.locked) {
1425				rez.top  += viewport.y;
1426				rez.left += viewport.x;
1427			}
1428
1429			rez.top  = getValue(Math.max(rez.top,  rez.top  + ((viewport.h - height) * current.topRatio)));
1430			rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width)  * current.leftRatio)));
1431
1432			return rez;
1433		},
1434
1435		_afterZoomIn: function () {
1436			var current = F.current;
1437
1438			if (!current) {
1439				return;
1440			}
1441
1442			F.isOpen = F.isOpened = true;
1443
1444			F.wrap.css('overflow', 'visible').addClass('fancybox-opened').hide().show(0);
1445
1446			F.update();
1447
1448			// Assign a click event
1449			if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
1450				F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
1451					if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
1452						e.preventDefault();
1453
1454						F[ current.closeClick ? 'close' : 'next' ]();
1455					}
1456				});
1457			}
1458
1459			// Create a close button
1460			if (current.closeBtn) {
1461				$(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
1462					e.preventDefault();
1463
1464					F.close();
1465				});
1466			}
1467
1468			// Create navigation arrows
1469			if (current.arrows && F.group.length > 1) {
1470				if (current.loop || current.index > 0) {
1471					$(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
1472				}
1473
1474				if (current.loop || current.index < F.group.length - 1) {
1475					$(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
1476				}
1477			}
1478
1479			F.trigger('afterShow');
1480
1481			// Stop the slideshow if this is the last item
1482			if (!current.loop && current.index === current.group.length - 1) {
1483
1484				F.play( false );
1485
1486			} else if (F.opts.autoPlay && !F.player.isActive) {
1487				F.opts.autoPlay = false;
1488
1489				F.play(true);
1490			}
1491		},
1492
1493		_afterZoomOut: function ( obj ) {
1494			obj = obj || F.current;
1495
1496			$('.fancybox-wrap').trigger('onReset').remove();
1497
1498			$.extend(F, {
1499				group  : {},
1500				opts   : {},
1501				router : false,
1502				current   : null,
1503				isActive  : false,
1504				isOpened  : false,
1505				isOpen    : false,
1506				isClosing : false,
1507				wrap   : null,
1508				skin   : null,
1509				outer  : null,
1510				inner  : null
1511			});
1512
1513			F.trigger('afterClose', obj);
1514		}
1515	});
1516
1517	/*
1518	 *	Default transitions
1519	 */
1520
1521	F.transitions = {
1522		getOrigPosition: function () {
1523			var current  = F.current,
1524				element  = current.element,
1525				orig     = current.orig,
1526				pos      = {},
1527				width    = 50,
1528				height   = 50,
1529				hPadding = current.hPadding,
1530				wPadding = current.wPadding,
1531				viewport = F.getViewport();
1532
1533			if (!orig && current.isDom && element.is(':visible')) {
1534				orig = element.find('img:first');
1535
1536				if (!orig.length) {
1537					orig = element;
1538				}
1539			}
1540
1541			if (isQuery(orig)) {
1542				pos = orig.offset();
1543
1544				if (orig.is('img')) {
1545					width  = orig.outerWidth();
1546					height = orig.outerHeight();
1547				}
1548
1549			} else {
1550				pos.top  = viewport.y + (viewport.h - height) * current.topRatio;
1551				pos.left = viewport.x + (viewport.w - width)  * current.leftRatio;
1552			}
1553
1554			if (F.wrap.css('position') === 'fixed' || current.locked) {
1555				pos.top  -= viewport.y;
1556				pos.left -= viewport.x;
1557			}
1558
1559			pos = {
1560				top     : getValue(pos.top  - hPadding * current.topRatio),
1561				left    : getValue(pos.left - wPadding * current.leftRatio),
1562				width   : getValue(width  + wPadding),
1563				height  : getValue(height + hPadding)
1564			};
1565
1566			return pos;
1567		},
1568
1569		step: function (now, fx) {
1570			var ratio,
1571				padding,
1572				value,
1573				prop       = fx.prop,
1574				current    = F.current,
1575				wrapSpace  = current.wrapSpace,
1576				skinSpace  = current.skinSpace;
1577
1578			if (prop === 'width' || prop === 'height') {
1579				ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
1580
1581				if (F.isClosing) {
1582					ratio = 1 - ratio;
1583				}
1584
1585				padding = prop === 'width' ? current.wPadding : current.hPadding;
1586				value   = now - padding;
1587
1588				F.skin[ prop ](  getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) ) );
1589				F.inner[ prop ]( getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
1590			}
1591		},
1592
1593		zoomIn: function () {
1594			var current  = F.current,
1595				startPos = current.pos,
1596				effect   = current.openEffect,
1597				elastic  = effect === 'elastic',
1598				endPos   = $.extend({opacity : 1}, startPos);
1599
1600			// Remove "position" property that breaks older IE
1601			delete endPos.position;
1602
1603			if (elastic) {
1604				startPos = this.getOrigPosition();
1605
1606				if (current.openOpacity) {
1607					startPos.opacity = 0.1;
1608				}
1609
1610			} else if (effect === 'fade') {
1611				startPos.opacity = 0.1;
1612			}
1613
1614			F.wrap.css(startPos).animate(endPos, {
1615				duration : effect === 'none' ? 0 : current.openSpeed,
1616				easing   : current.openEasing,
1617				step     : elastic ? this.step : null,
1618				complete : F._afterZoomIn
1619			});
1620		},
1621
1622		zoomOut: function () {
1623			var current  = F.current,
1624				effect   = current.closeEffect,
1625				elastic  = effect === 'elastic',
1626				endPos   = {opacity : 0.1};
1627
1628			if (elastic) {
1629				endPos = this.getOrigPosition();
1630
1631				if (current.closeOpacity) {
1632					endPos.opacity = 0.1;
1633				}
1634			}
1635
1636			F.wrap.animate(endPos, {
1637				duration : effect === 'none' ? 0 : current.closeSpeed,
1638				easing   : current.closeEasing,
1639				step     : elastic ? this.step : null,
1640				complete : F._afterZoomOut
1641			});
1642		},
1643
1644		changeIn: function () {
1645			var current   = F.current,
1646				effect    = current.nextEffect,
1647				startPos  = current.pos,
1648				endPos    = { opacity : 1 },
1649				direction = F.direction,
1650				distance  = 200,
1651				field;
1652
1653			startPos.opacity = 0.1;
1654
1655			if (effect === 'elastic') {
1656				field = direction === 'down' || direction === 'up' ? 'top' : 'left';
1657
1658				if (direction === 'down' || direction === 'right') {
1659					startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
1660					endPos[ field ]   = '+=' + distance + 'px';
1661
1662				} else {
1663					startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
1664					endPos[ field ]   = '-=' + distance + 'px';
1665				}
1666			}
1667
1668			// Workaround for http://bugs.jquery.com/ticket/12273
1669			if (effect === 'none') {
1670				F._afterZoomIn();
1671
1672			} else {
1673				F.wrap.css(startPos).animate(endPos, {
1674					duration : current.nextSpeed,
1675					easing   : current.nextEasing,
1676					complete : F._afterZoomIn
1677				});
1678			}
1679		},
1680
1681		changeOut: function () {
1682			var previous  = F.previous,
1683				effect    = previous.prevEffect,
1684				endPos    = { opacity : 0.1 },
1685				direction = F.direction,
1686				distance  = 200;
1687
1688			if (effect === 'elastic') {
1689				endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
1690			}
1691
1692			previous.wrap.animate(endPos, {
1693				duration : effect === 'none' ? 0 : previous.prevSpeed,
1694				easing   : previous.prevEasing,
1695				complete : function () {
1696					$(this).trigger('onReset').remove();
1697				}
1698			});
1699		}
1700	};
1701
1702	/*
1703	 *	Overlay helper
1704	 */
1705
1706	F.helpers.overlay = {
1707		defaults : {
1708			closeClick : true,      // if true, fancyBox will be closed when user clicks on the overlay
1709			speedOut   : 200,       // duration of fadeOut animation
1710			showEarly  : true,      // indicates if should be opened immediately or wait until the content is ready
1711			css        : {},        // custom CSS properties
1712			locked     : !isTouch,  // if true, the content will be locked into overlay
1713			fixed      : true       // if false, the overlay CSS position property will not be set to "fixed"
1714		},
1715
1716		overlay : null,      // current handle
1717		fixed   : false,     // indicates if the overlay has position "fixed"
1718		el      : $('html'), // element that contains "the lock"
1719
1720		// Public methods
1721		create : function(opts) {
1722			var parent;
1723
1724			opts = $.extend({}, this.defaults, opts);
1725
1726			if (this.overlay) {
1727				this.close();
1728			}
1729
1730			parent = F.coming ? F.coming.parent : opts.parent;
1731
1732			this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( parent && parent.len
vendor: 3,671 bytes, lines 1732-1900
1732th ? parent : 'body' );
1733			this.fixed   = false;
1734
1735			if (opts.fixed && F.defaults.fixed) {
1736				this.overlay.addClass('fancybox-overlay-fixed');
1737
1738				this.fixed = true;
1739			}
1740		},
1741
1742		open : function(opts) {
1743			var that = this;
1744
1745			opts = $.extend({}, this.defaults, opts);
1746
1747			if (this.overlay) {
1748				this.overlay.unbind('.overlay').width('auto').height('auto');
1749
1750			} else {
1751				this.create(opts);
1752			}
1753
1754			if (!this.fixed) {
1755				W.bind('resize.overlay', $.proxy( this.update, this) );
1756
1757				this.update();
1758			}
1759
1760			if (opts.closeClick) {
1761				this.overlay.bind('click.overlay', function(e) {
1762					if ($(e.target).hasClass('fancybox-overlay')) {
1763						if (F.isActive) {
1764							F.close();
1765						} else {
1766							that.close();
1767						}
1768
1769						return false;
1770					}
1771				});
1772			}
1773
1774			this.overlay.css( opts.css ).show();
1775		},
1776
1777		close : function() {
1778			W.unbind('resize.overlay');
1779
1780			if (this.el.hasClass('fancybox-lock')) {
1781				$('.fancybox-margin').removeClass('fancybox-margin');
1782
1783				this.el.removeClass('fancybox-lock');
1784
1785				W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );
1786			}
1787
1788			$('.fancybox-overlay').remove().hide();
1789
1790			$.extend(this, {
1791				overlay : null,
1792				fixed   : false
1793			});
1794		},
1795
1796		// Private, callbacks
1797
1798		update : function () {
1799			var width = '100%', offsetWidth;
1800
1801			// Reset width/height so it will not mess
1802			this.overlay.width(width).height('100%');
1803
1804			// jQuery does not return reliable result for IE
1805			if (IE) {
1806				offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
1807
1808				if (D.width() > offsetWidth) {
1809					width = D.width();
1810				}
1811
1812			} else if (D.width() > W.width()) {
1813				width = D.width();
1814			}
1815
1816			this.overlay.width(width).height(D.height());
1817		},
1818
1819		// This is where we can manipulate DOM, because later it would cause iframes to reload
1820		onReady : function (opts, obj) {
1821			var overlay = this.overlay;
1822
1823			$('.fancybox-overlay').stop(true, true);
1824
1825			if (!overlay) {
1826				this.create(opts);
1827			}
1828
1829			if (opts.locked && this.fixed && obj.fixed) {
1830				obj.locked = this.overlay.append( obj.wrap );
1831				obj.fixed  = false;
1832			}
1833
1834			if (opts.showEarly === true) {
1835				this.beforeShow.apply(this, arguments);
1836			}
1837		},
1838
1839		beforeShow : function(opts, obj) {
1840			if (obj.locked && !this.el.hasClass('fancybox-lock')) {
1841				if (this.fixPosition !== false) {
1842					$('*').filter(function(){
1843						return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );
1844					}).addClass('fancybox-margin');
1845				}
1846
1847				this.el.addClass('fancybox-margin');
1848
1849				this.scrollV = W.scrollTop();
1850				this.scrollH = W.scrollLeft();
1851
1852				this.el.addClass('fancybox-lock');
1853
1854				W.scrollTop( this.scrollV ).scrollLeft( this.scrollH );
1855			}
1856
1857			this.open(opts);
1858		},
1859
1860		onUpdate : function() {
1861			if (!this.fixed) {
1862				this.update();
1863			}
1864		},
1865
1866		afterClose: function (opts) {
1867			// Remove overlay if exists and fancyBox is not opening
1868			// (e.g., it is not being open using afterClose callback)
1869			if (this.overlay && !F.coming) {
1870				this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
1871			}
1872		}
1873	};
1874
1875	/*
1876	 *	Title helper
1877	 */
1878
1879	F.helpers.title = {
1880		defaults : {
1881			type     : 'float', // 'float', 'inside', 'outside' or 'over',
1882			position : 'bottom' // 'top' or 'bottom'
1883		},
1884
1885		beforeShow: function (opts) {
1886			var current = F.current,
1887				text    = current.title,
1888				type    = opts.type,
1889				title,
1890				target;
1891
1892			if ($.isFunction(text)) {
1893				text = text.call(current.element, current);
1894			}
1895
1896			if (!isString(text) || $.trim(text) === '') {
1897				return;
1898			}
1899
1900			title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
vendor: 3,161 bytes, lines 1900-2028
1900' + text + '</div>');
1901
1902			switch (type) {
1903				case 'inside':
1904					target = F.skin;
1905				break;
1906
1907				case 'outside':
1908					target = F.wrap;
1909				break;
1910
1911				case 'over':
1912					target = F.inner;
1913				break;
1914
1915				default: // 'float'
1916					target = F.skin;
1917
1918					title.appendTo('body');
1919
1920					if (IE) {
1921						title.width( title.width() );
1922					}
1923
1924					title.wrapInner('<span class="child"></span>');
1925
1926					//Increase bottom margin so this title will also fit into viewport
1927					F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
1928				break;
1929			}
1930
1931			title[ (opts.position === 'top' ? 'prependTo'  : 'appendTo') ](target);
1932		}
1933	};
1934
1935	// jQuery plugin initialization
1936	$.fn.fancybox = function (options) {
1937		var index,
1938			that     = $(this),
1939			selector = this.selector || '',
1940			run      = function(e) {
1941				var what = $(this).blur(), idx = index, relType, relVal;
1942
1943				if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
1944					relType = options.groupAttr || 'data-fancybox-group';
1945					relVal  = what.attr(relType);
1946
1947					if (!relVal) {
1948						relType = 'rel';
1949						relVal  = what.get(0)[ relType ];
1950					}
1951
1952					if (relVal && relVal !== '' && relVal !== 'nofollow') {
1953						what = selector.length ? $(selector) : that;
1954						what = what.filter('[' + relType + '="' + relVal + '"]');
1955						idx  = what.index(this);
1956					}
1957
1958					options.index = idx;
1959
1960					// Stop an event from bubbling if everything is fine
1961					if (F.open(what, options) !== false) {
1962						e.preventDefault();
1963					}
1964				}
1965			};
1966
1967		options = options || {};
1968		index   = options.index || 0;
1969
1970		if (!selector || options.live === false) {
1971			that.unbind('click.fb-start').bind('click.fb-start', run);
1972
1973		} else {
1974			D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
1975		}
1976
1977		this.filter('[data-fancybox-start=1]').trigger('click');
1978
1979		return this;
1980	};
1981
1982	// Tests that need a body at doc ready
1983	D.ready(function() {
1984		var w1, w2;
1985
1986		if ( $.scrollbarWidth === undefined ) {
1987			// http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
1988			$.scrollbarWidth = function() {
1989				var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
1990					child  = parent.children(),
1991					width  = child.innerWidth() - child.height( 99 ).innerWidth();
1992
1993				parent.remove();
1994
1995				return width;
1996			};
1997		}
1998
1999		if ( $.support.fixedPosition === undefined ) {
2000			$.support.fixedPosition = (function() {
2001				var elem  = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
2002					fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
2003
2004				elem.remove();
2005
2006				return fixed;
2007			}());
2008		}
2009
2010		$.extend(F.defaults, {
2011			scrollbarWidth : $.scrollbarWidth(),
2012			fixed  : $.support.fixedPosition,
2013			parent : $('body')
2014		});
2015
2016		//Get real width of page scroll-bar
2017		w1 = $(window).width();
2018
2019		H.addClass('fancybox-lock-test');
2020
2021		w2 = $(window).width();
2022
2023		H.removeClass('fancybox-lock-test');
2024
2025		$("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
2026	});
2027
2028}(window, document, 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.