PageSourceSearch

https://threeworldwars.com/js/fancybox.js

js threeworldwars.com collected 2026-10-02 08:17:54 UTC 48,180 bytes, 2,006 lines download raw bytes

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