PageSourceSearch

https://kplt.in.ua/wp-content/themes/universe_theme/core/js/plugins.js?ver=5.2.21

js kplt.in.ua collected 2026-09-24 11:56:10 UTC 158,579 bytes, 5,066 lines download raw bytes

1/*
2 * jQuery Superfish Menu Plugin
3 * Copyright (c) 2013 Joel Birch
4 *
5 * Dual licensed under the MIT and GPL licenses:
6 *	http://www.opensource.org/licenses/mit-license.php
7 *	http://www.gnu.org/licenses/gpl.html
8 */
9
10(function ($) {
11	"use strict";
12
13	var methods = (function () {
14		// private properties and methods go here
15		var c = {
16				bcClass: 'sf-breadcrumb',
17				menuClass: 'sf-js-enabled',
18				anchorClass: 'sf-with-ul',
19				menuArrowClass: 'sf-arrows'
20			},
21			ios = (function () {
22				var ios = /iPhone|iPad|iPod/i.test(navigator.userAgent);
23				if (ios) {
24					// iOS clicks only bubble as far as body children
25					$(window).load(function () {
26						$('body').children().on('click', $.noop);
27					});
28				}
29				return ios;
30			})(),
31			wp7 = (function () {
32				var style = document.documentElement.style;
33				return ('behavior' in style && 'fill' in style && /iemobile/i.test(navigator.userAgent));
34			})(),
35			toggleMenuClasses = function ($menu, o) {
36				var classes = c.menuClass;
37				if (o.cssArrows) {
38					classes += ' ' + c.menuArrowClass;
39				}
40				$menu.toggleClass(classes);
41			},
42			setPathToCurrent = function ($menu, o) {
43				return $menu.find('li.' + o.pathClass).slice(0, o.pathLevels)
44					.addClass(o.hoverClass + ' ' + c.bcClass)
45						.filter(function () {
46							return ($(this).children(o.popUpSelector).hide().show().length);
47						}).removeClass(o.pathClass);
48			},
49			toggleAnchorClass = function ($li) {
50				$li.children('a').toggleClass(c.anchorClass);
51			},
52			toggleTouchAction = function ($menu) {
53				var touchAction = $menu.css('ms-touch-action');
54				touchAction = (touchAction === 'pan-y') ? 'auto' : 'pan-y';
55				$menu.css('ms-touch-action', touchAction);
56			},
57			applyHandlers = function ($menu, o) {
58				var targets = 'li:has(' + o.popUpSelector + ')';
59				if ($.fn.hoverIntent && !o.disableHI) {
60					$menu.hoverIntent(over, out, targets);
61				}
62				else {
63					$menu
64						.on('mouseenter.superfish', targets, over)
65						.on('mouseleave.superfish', targets, out);
66				}
67				var touchevent = 'MSPointerDown.superfish';
68				if (!ios) {
69					touchevent += ' touchend.superfish';
70				}
71				if (wp7) {
72					touchevent += ' mousedown.superfish';
73				}
74				$menu
75					.on('focusin.superfish', 'li', over)
76					.on('focusout.superfish', 'li', out)
77					.on(touchevent, 'a', o, touchHandler);
78			},
79			touchHandler = function (e) {
80				var $this = $(this),
81					$ul = $this.siblings(e.data.popUpSelector);
82
83				if ($ul.length > 0 && $ul.is(':hidden')) {
84					$this.one('click.superfish', false);
85					if (e.type === 'MSPointerDown') {
86						$this.trigger('focus');
87					} else {
88						$.proxy(over, $this.parent('li'))();
89					}
90				}
91			},
92			over = function () {
93				var $this = $(this),
94					o = getOptions($this);
95				clearTimeout(o.sfTimer);
96				$this.siblings().superfish('hide').end().superfish('show');
97			},
98			out = function () {
99				var $this = $(this),
100					o = getOptions($this);
101				if (ios) {
102					$.proxy(close, $this, o)();
103				}
104				else {
105					clearTimeout(o.sfTimer);
106					o.sfTimer = setTimeout($.proxy(close, $this, o), o.delay);
107				}
108			},
109			close = function (o) {
110				o.retainPath = ($.inArray(this[0], o.$path) > -1);
111				this.superfish('hide');
112
113				if (!this.parents('.' + o.hoverClass).length) {
114					o.onIdle.call(getMenu(this));
115					if (o.$path.length) {
116						$.proxy(over, o.$path)();
117					}
118				}
119			},
120			getMenu = function ($el) {
121				return $el.closest('.' + c.menuClass);
122			},
123			getOptions = function ($el) {
124				return getMenu($el).data('sf-options');
125			};
126
127		return {
128			// public methods
129			hide: function (instant) {
130				if (this.length) {
131					var $this = this,
132						o = getOptions($this);
133					if (!o) {
134						return this;
135					}
136					var not = (o.retainPath === true) ? o.$path : '',
137						$ul = $this.find('li.' + o.hoverClass).add(this).not(not).removeClass(o.hoverClass).children(o.popUpSelector),
138						speed = o.speedOut;
139
140					if (instant) {
141						$ul.show();
142						speed = 0;
143					}
144					o.retainPath = false;
145					o.onBeforeHide.call($ul);
146					$ul.stop(true, true).animate(o.animationOut, speed, function () {
147						var $this = $(this);
148						o.onHide.call($this);
149					});
150				}
151				return this;
152			},
153			show: function () {
154				var o = getOptions(this);
155				if (!o) {
156					return this;
157				}
158				var $this = this.addClass(o.hoverClass),
159					$ul = $this.children(o.popUpSelector);
160
161				o.onBeforeShow.call($ul);
162				$ul.stop(true, true).animate(o.animation, o.speed, function () {
163					o.onShow.call($ul);
164				});
165				return this;
166			},
167			destroy: function () {
168				return this.each(function () {
169					var $this = $(this),
170						o = $this.data('sf-options'),
171						$hasPopUp;
172					if (!o) {
173						return false;
174					}
175					$hasPopUp = $this.find(o.popUpSelector).parent('li');
176					clearTimeout(o.sfTimer);
177					toggleMenuClasses($this, o);
178					toggleAnchorClass($hasPopUp);
179					toggleTouchAction($this);
180					// remove event handlers
181					$this.off('.superfish').off('.hoverIntent');
182					// clear animation's inline display style
183					$hasPopUp.children(o.popUpSelector).attr('style', function (i, style) {
184						return style.replace(/display[^;]+;?/g, '');
185					});
186					// reset 'current' path classes
187					o.$path.removeClass(o.hoverClass + ' ' + c.bcClass).addClass(o.pathClass);
188					$this.find('.' + o.hoverClass).removeClass(o.hoverClass);
189					o.onDestroy.call($this);
190					$this.removeData('sf-options');
191				});
192			},
193			init: function (op) {
194				return this.each(function () {
195					var $this = $(this);
196					if ($this.data('sf-options')) {
197						return false;
198					}
199					var o = $.extend({}, $.fn.superfish.defaults, op),
200						$hasPopUp = $this.find(o.popUpSelector).parent('li');
201					o.$path = setPathToCurrent($this, o);
202
203					$this.data('sf-options', o);
204
205					toggleMenuClasses($this, o);
206					toggleAnchorClass($hasPopUp);
207					toggleTouchAction($this);
208					applyHandlers($this, o);
209
210					$hasPopUp.not('.' + c.bcClass).superfish('hide', true);
211
212					o.onInit.call(this);
213				});
214			}
215		};
216	})();
217
218	$.fn.superfish = function (method, args) {
219		if (methods[method]) {
220			return methods[method].apply(this, Array.prototype.slice.call(arguments, 1));
221		}
222		else if (typeof method === 'object' || ! method) {
223			return methods.init.apply(this, arguments);
224		}
225		else {
226			return $.error('Method ' +  method + ' does not exist on jQuery.fn.superfish');
227		}
228	};
229
230	$.fn.superfish.defaults = {
231		popUpSelector: 'ul,.sf-mega', // within menu context
232		hoverClass: 'sfHover',
233		pathClass: 'overrideThisToUse',
234		pathLevels: 1,
235		delay: 800,
236		animation: {opacity: 'show'},
237		animationOut: {opacity: 'hide'},
238		speed: 'normal',
239		speedOut: 'fast',
240		cssArrows: true,
241		disableHI: false,
242		onInit: $.noop,
243		onBeforeShow: $.noop,
244		onShow: $.noop,
245		onBeforeHide: $.noop,
246		onHide: $.noop,
247		onIdle: $.noop,
248		onDestroy: $.noop
249	};
250
251	// soon to be deprecated
252	$.fn.extend({
253		hideSuperfishUl: methods.hide,
254		showSuperfishUl: methods.show
255	});
256
257})(jQuery);
258
259
260
261/*
262 * jQuery FlexSlider v2.2.0
263 * Copyright 2012 WooThemes
264 * Contributing Author: Tyler Smith
265 */
266;
267(function ($) {
268
269  //FlexSlider: Object Instance
270  $.flexslider = function(el, options) {
271    var slider = $(el);
272
273    // making variables public
274    slider.vars = $.extend({}, $.flexslider.defaults, options);
275
276    var namespace = slider.vars.namespace,
277        msGesture = window.navigator && window.navigator.msPointerEnabled && window.MSGesture,
278        touch = (( "ontouchstart" in window ) || msGesture || window.DocumentTouch && document instanceof DocumentTouch) && slider.vars.touch,
279        // depricating this idea, as devices are being released with both of these events
280        //eventType = (touch) ? "touchend" : "click",
281        eventType = "click touchend MSPointerUp",
282        watchedEvent = "",
283        watchedEventClearTimer,
284        vertical = slider.vars.direction === "vertical",
285        reverse = slider.vars.reverse,
286        carousel = (slider.vars.itemWidth > 0),
287        fade = slider.vars.animation === "fade",
288        asNav = slider.vars.asNavFor !== "",
289        methods = {},
290        focused = true;
291
292    // Store a reference to the slider object
293    $.data(el, "flexslider", slider);
294
295    // Private slider methods
296    methods = {
297      init: function() {
298        slider.animating = false;
299        // Get current slide and make sure it is a number
300        slider.currentSlide = parseInt( ( slider.vars.startAt ? slider.vars.startAt : 0) );
301        if ( isNaN( slider.currentSlide ) ) slider.currentSlide = 0;
302        slider.animatingTo = slider.currentSlide;
303        slider.atEnd = (slider.currentSlide === 0 || slider.currentSlide === slider.last);
304        slider.containerSelector = slider.vars.selector.substr(0,slider.vars.selector.search(' '));
305        slider.slides = $(slider.vars.selector, slider);
306        slider.container = $(slider.containerSelector, slider);
307        slider.count = slider.slides.length;
308        // SYNC:
309        slider.syncExists = $(slider.vars.sync).length > 0;
310        // SLIDE:
311        if (slider.vars.animation === "slide") slider.vars.animation = "swing";
312        slider.prop = (vertical) ? "top" : "marginLeft";
313        slider.args = {};
314        // SLIDESHOW:
315        slider.manualPause = false;
316        slider.stopped = false;
317        //PAUSE WHEN INVISIBLE
318        slider.started = false;
319        slider.startTimeout = null;
320        // TOUCH/USECSS:
321        slider.transitions = !slider.vars.video && !fade && slider.vars.useCSS && (function() {
322          var obj = document.createElement('div'),
323              props = ['perspectiveProperty', 'WebkitPerspective', 'MozPerspective', 'OPerspective', 'msPerspective'];
324          for (var i in props) {
325            if ( obj.style[ props[i] ] !== undefined ) {
326              slider.pfx = props[i].replace('Perspective','').toLowerCase();
327              slider.prop = "-" + slider.pfx + "-transform";
328              return true;
329            }
330          }
331          return false;
332        }());
333        // CONTROLSCONTAINER:
334        if (slider.vars.controlsContainer !== "") slider.controlsContainer = $(slider.vars.controlsContainer).length > 0 && $(slider.vars.controlsContainer);
335        // MANUAL:
336        if (slider.vars.manualControls !== "") slider.manualControls = $(slider.vars.manualControls).length > 0 && $(slider.vars.manualControls);
337
338        // RANDOMIZE:
339        if (slider.vars.randomize) {
340          slider.slides.sort(function() { return (Math.round(Math.random())-0.5); });
341          slider.container.empty().append(slider.slides);
342        }
343
344        slider.doMath();
345
346        // INIT
347        slider.setup("init");
348
349        // CONTROLNAV:
350        if (slider.vars.controlNav) methods.controlNav.setup();
351
352        // DIRECTIONNAV:
353        if (slider.vars.directionNav) methods.directionNav.setup();
354
355        // KEYBOARD:
356        if (slider.vars.keyboard && ($(slider.containerSelector).length === 1 || slider.vars.multipleKeyboard)) {
357          $(document).bind('keyup', function(event) {
358            var keycode = event.keyCode;
359            if (!slider.animating && (keycode === 39 || keycode === 37)) {
360              var target = (keycode === 39) ? slider.getTarget('next') :
361                           (keycode === 37) ? slider.getTarget('prev') : false;
362              slider.flexAnimate(target, slider.vars.pauseOnAction);
363            }
364          });
365        }
366        // MOUSEWHEEL:
367        if (slider.vars.mousewheel) {
368          slider.bind('mousewheel', function(event, delta, deltaX, deltaY) {
369            event.preventDefault();
370            var target = (delta < 0) ? slider.getTarget('next') : slider.getTarget('prev');
371            slider.flexAnimate(target, slider.vars.pauseOnAction);
372          });
373        }
374
375        // PAUSEPLAY
376        if (slider.vars.pausePlay) methods.pausePlay.setup();
377
378        //PAUSE WHEN INVISIBLE
379        if (slider.vars.slideshow && slider.vars.pauseInvisible) methods.pauseInvisible.init();
380
381        // SLIDSESHOW
382        if (slider.vars.slideshow) {
383          if (slider.vars.pauseOnHover) {
384            slider.hover(function() {
385              if (!slider.manualPlay && !slider.manualPause) slider.pause();
386            }, function() {
387              if (!slider.manualPause && !slider.manualPlay && !slider.stopped) slider.play();
388            });
389          }
390          // initialize animation
391          //If we're visible, or we don't use PageVisibility API
392          if(!slider.vars.pauseInvisible || !methods.pauseInvisible.isHidden()) {
393            (slider.vars.initDelay > 0) ? slider.startTimeout = setTimeout(slider.play, slider.vars.initDelay) : slider.play();
394          }
395        }
396
397        // ASNAV:
398        if (asNav) methods.asNav.setup();
399
400        // TOUCH
401        if (touch && slider.vars.touch) methods.touch();
402
403        // FADE&&SMOOTHHEIGHT || SLIDE:
404        if (!fade || (fade && slider.vars.smoothHeight)) $(window).bind("resize orientationchange focus", methods.resize);
405
406        slider.find("img").attr("draggable", "false");
407
408        // API: start() Callback
409        setTimeout(function(){
410          slider.vars.start(slider);
411        }, 200);
412      },
413      asNav: {
414        setup: function() {
415          slider.asNav = true;
416          slider.animatingTo = Math.floor(slider.currentSlide/slider.move);
417          slider.currentItem = slider.currentSlide;
418          slider.slides.removeClass(namespace + "active-slide").eq(slider.currentItem).addClass(namespace + "active-slide");
419          if(!msGesture){
420              slider.slides.click(function(e){
421                e.preventDefault();
422                var $slide = $(this),
423                    target = $slide.index();
424                var posFromLeft = $slide.offset().left - $(slider).scrollLeft(); // Find position of slide relative to left of slider container
425                if( posFromLeft <= 0 && $slide.hasClass( namespace + 'active-slide' ) ) {
426                  slider.flexAnimate(slider.getTarget("prev"), true);
427                } else if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass(namespace + "active-slide")) {
428                  slider.direction = (slider.currentItem < target) ? "next" : "prev";
429                  slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
430                }
431              });
432          }else{
433              el._slider = slider;
434              slider.slides.each(function (){
435                  var that = this;
436                  that._gesture = new MSGesture();
437                  that._gesture.target = that;
438                  that.addEventListener("MSPointerDown", function (e){
439                      e.preventDefault();
440                      if(e.currentTarget._gesture)
441                          e.currentTarget._gesture.addPointer(e.pointerId);
442                  }, false);
443                  that.addEventListener("MSGestureTap", function (e){
444                      e.preventDefault();
445                      var $slide = $(this),
446                          target = $slide.index();
447                      if (!$(slider.vars.asNavFor).data('flexslider').animating && !$slide.hasClass('active')) {
448                          slider.direction = (slider.currentItem < target) ? "next" : "prev";
449                          slider.flexAnimate(target, slider.vars.pauseOnAction, false, true, true);
450                      }
451                  });
452              });
453          }
454        }
455      },
456      controlNav: {
457        setup: function() {
458          if (!slider.manualControls) {
459            methods.controlNav.setupPaging();
460          } else { // MANUALCONTROLS:
461            methods.controlNav.setupManual();
462          }
463        },
464        setupPaging: function() {
465          var type = (slider.vars.controlNav === "thumbnails") ? 'control-thumbs' : 'control-paging',
466              j = 1,
467              item,
468              slide;
469
470          slider.controlNavScaffold = $('<ol class="'+ namespace + 'control-nav ' + namespace + type + '"></ol>');
471
472          if (slider.pagingCount > 1) {
473            for (var i = 0; i < slider.pagingCount; i++) {
474              slide = slider.slides.eq(i);
475              item = (slider.vars.controlNav === "thumbnails") ? '<img src="' + slide.attr( 'data-thumb' ) + '"/>' : '<a>' + j + '</a>';
476              if ( 'thumbnails' === slider.vars.controlNav && true === slider.vars.thumbCaptions ) {
477                var captn = slide.attr( 'data-thumbcaption' );
478                if ( '' != captn && undefined != captn ) item += '<span class="' + namespace + 'caption">' + captn + '</span>';
479              }
480              slider.controlNavScaffold.append('<li>' + item + '</li>');
481              j++;
482            }
483          }
484
485          // CONTROLSCONTAINER:
486          (slider.controlsContainer) ? $(slider.controlsContainer).append(slider.controlNavScaffold) : slider.append(slider.controlNavScaffold);
487          methods.controlNav.set();
488
489          methods.controlNav.active();
490
491          slider.controlNavScaffold.delegate('a, img', eventType, function(event) {
492            event.preventDefault();
493
494            if (watchedEvent === "" || watchedEvent === event.type) {
495              var $this = $(this),
496                  target = slider.controlNav.index($this);
497
498              if (!$this.hasClass(namespace + 'active')) {
499                slider.direction = (target > slider.currentSlide) ? "next" : "prev";
500                slider.flexAnimate(target, slider.vars.pauseOnAction);
501              }
502            }
503
504            // setup flags to prevent event duplication
505            if (watchedEvent === "") {
506              watchedEvent = event.type;
507            }
508            methods.setToClearWatchedEvent();
509
510          });
511        },
512        setupManual: function() {
513          slider.controlNav = slider.manualControls;
514          methods.controlNav.active();
515
516          slider.controlNav.bind(eventType, function(event) {
517            event.preventDefault();
518
519            if (watchedEvent === "" || watchedEvent === event.type) {
520              var $this = $(this),
521                  target = slider.controlNav.index($this);
522
523              if (!$this.hasClass(namespace + 'active')) {
524                (target > slider.currentSlide) ? slider.direction = "next" : slider.direction = "prev";
525                slider.flexAnimate(target, slider.vars.pauseOnAction);
526              }
527            }
528
529            // setup flags to prevent event duplication
530            if (watchedEvent === "") {
531              watchedEvent = event.type;
532            }
533            methods.setToClearWatchedEvent();
534          });
535        },
536        set: function() {
537          var selector = (slider.vars.controlNav === "thumbnails") ? 'img' : 'a';
538          slider.controlNav = $('.' + namespace + 'control-nav li ' + selector, (slider.controlsContainer) ? slider.controlsContainer : slider);
539        },
540        active: function() {
541          slider.controlNav.removeClass(namespace + "active").eq(slider.animatingTo).addClass(namespace + "active");
542        },
543        update: function(action, pos) {
544          if (slider.pagingCount > 1 && action === "add") {
545            slider.controlNavScaffold.append($('<li><a>' + slider.count + '</a></li>'));
546          } else if (slider.pagingCount === 1) {
547            slider.controlNavScaffold.find('li').remove();
548          } else {
549            slider.controlNav.eq(pos).closest('li').remove();
550          }
551          methods.controlNav.set();
552          (slider.pagingCount > 1 && slider.pagingCount !== slider.controlNav.length) ? slider.update(pos, action) : methods.controlNav.active();
553        }
554      },
555      directionNav: {
556        setup: function() {
557          var directionNavScaffold = $('<ul class="' + namespace + 'direction-nav"><li><a class="' + namespace + 'prev" href="#">
vendor: 9,251 bytes, lines 557-760
557' + slider.vars.prevText + '</a></li><li><a class="' + namespace + 'next" href="#">' + slider.vars.nextText + '</a></li></ul>');
558
559          // CONTROLSCONTAINER:
560          if (slider.controlsContainer) {
561            $(slider.controlsContainer).append(directionNavScaffold);
562            slider.directionNav = $('.' + namespace + 'direction-nav li a', slider.controlsContainer);
563          } else {
564            slider.append(directionNavScaffold);
565            slider.directionNav = $('.' + namespace + 'direction-nav li a', slider);
566          }
567
568          methods.directionNav.update();
569
570          slider.directionNav.bind(eventType, function(event) {
571            event.preventDefault();
572            var target;
573
574            if (watchedEvent === "" || watchedEvent === event.type) {
575              target = ($(this).hasClass(namespace + 'next')) ? slider.getTarget('next') : slider.getTarget('prev');
576              slider.flexAnimate(target, slider.vars.pauseOnAction);
577            }
578
579            // setup flags to prevent event duplication
580            if (watchedEvent === "") {
581              watchedEvent = event.type;
582            }
583            methods.setToClearWatchedEvent();
584          });
585        },
586        update: function() {
587          var disabledClass = namespace + 'disabled';
588          if (slider.pagingCount === 1) {
589            slider.directionNav.addClass(disabledClass).attr('tabindex', '-1');
590          } else if (!slider.vars.animationLoop) {
591            if (slider.animatingTo === 0) {
592              slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "prev").addClass(disabledClass).attr('tabindex', '-1');
593            } else if (slider.animatingTo === slider.last) {
594              slider.directionNav.removeClass(disabledClass).filter('.' + namespace + "next").addClass(disabledClass).attr('tabindex', '-1');
595            } else {
596              slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
597            }
598          } else {
599            slider.directionNav.removeClass(disabledClass).removeAttr('tabindex');
600          }
601        }
602      },
603      pausePlay: {
604        setup: function() {
605          var pausePlayScaffold = $('<div class="' + namespace + 'pauseplay"><a></a></div>');
606
607          // CONTROLSCONTAINER:
608          if (slider.controlsContainer) {
609            slider.controlsContainer.append(pausePlayScaffold);
610            slider.pausePlay = $('.' + namespace + 'pauseplay a', slider.controlsContainer);
611          } else {
612            slider.append(pausePlayScaffold);
613            slider.pausePlay = $('.' + namespace + 'pauseplay a', slider);
614          }
615
616          methods.pausePlay.update((slider.vars.slideshow) ? namespace + 'pause' : namespace + 'play');
617
618          slider.pausePlay.bind(eventType, function(event) {
619            event.preventDefault();
620
621            if (watchedEvent === "" || watchedEvent === event.type) {
622              if ($(this).hasClass(namespace + 'pause')) {
623                slider.manualPause = true;
624                slider.manualPlay = false;
625                slider.pause();
626              } else {
627                slider.manualPause = false;
628                slider.manualPlay = true;
629                slider.play();
630              }
631            }
632
633            // setup flags to prevent event duplication
634            if (watchedEvent === "") {
635              watchedEvent = event.type;
636            }
637            methods.setToClearWatchedEvent();
638          });
639        },
640        update: function(state) {
641          (state === "play") ? slider.pausePlay.removeClass(namespace + 'pause').addClass(namespace + 'play').html(slider.vars.playText) : slider.pausePlay.removeClass(namespace + 'play').addClass(namespace + 'pause').html(slider.vars.pauseText);
642        }
643      },
644      touch: function() {
645        var startX,
646          startY,
647          offset,
648          cwidth,
649          dx,
650          startT,
651          scrolling = false,
652          localX = 0,
653          localY = 0,
654          accDx = 0;
655
656        if(!msGesture){
657            el.addEventListener('touchstart', onTouchStart, false);
658
659            function onTouchStart(e) {
660              if (slider.animating) {
661                e.preventDefault();
662              } else if ( ( window.navigator.msPointerEnabled ) || e.touches.length === 1 ) {
663                slider.pause();
664                // CAROUSEL:
665                cwidth = (vertical) ? slider.h : slider. w;
666                startT = Number(new Date());
667                // CAROUSEL:
668
669                // Local vars for X and Y points.
670                localX = e.touches[0].pageX;
671                localY = e.touches[0].pageY;
672
673                offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
674                         (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
675                         (carousel && slider.currentSlide === slider.last) ? slider.limit :
676                         (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
677                         (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
678                startX = (vertical) ? localY : localX;
679                startY = (vertical) ? localX : localY;
680
681                el.addEventListener('touchmove', onTouchMove, false);
682                el.addEventListener('touchend', onTouchEnd, false);
683              }
684            }
685
686            function onTouchMove(e) {
687              // Local vars for X and Y points.
688
689              localX = e.touches[0].pageX;
690              localY = e.touches[0].pageY;
691
692              dx = (vertical) ? startX - localY : startX - localX;
693              scrolling = (vertical) ? (Math.abs(dx) < Math.abs(localX - startY)) : (Math.abs(dx) < Math.abs(localY - startY));
694
695              var fxms = 500;
696
697              if ( ! scrolling || Number( new Date() ) - startT > fxms ) {
698                e.preventDefault();
699                if (!fade && slider.transitions) {
700                  if (!slider.vars.animationLoop) {
701                    dx = dx/((slider.currentSlide === 0 && dx < 0 || slider.currentSlide === slider.last && dx > 0) ? (Math.abs(dx)/cwidth+2) : 1);
702                  }
703                  slider.setProps(offset + dx, "setTouch");
704                }
705              }
706            }
707
708            function onTouchEnd(e) {
709              // finish the touch by undoing the touch session
710              el.removeEventListener('touchmove', onTouchMove, false);
711
712              if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
713                var updateDx = (reverse) ? -dx : dx,
714                    target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
715
716                if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
717                  slider.flexAnimate(target, slider.vars.pauseOnAction);
718                } else {
719                  if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true);
720                }
721              }
722              el.removeEventListener('touchend', onTouchEnd, false);
723
724              startX = null;
725              startY = null;
726              dx = null;
727              offset = null;
728            }
729        }else{
730            el.style.msTouchAction = "none";
731            el._gesture = new MSGesture();
732            el._gesture.target = el;
733            el.addEventListener("MSPointerDown", onMSPointerDown, false);
734            el._slider = slider;
735            el.addEventListener("MSGestureChange", onMSGestureChange, false);
736            el.addEventListener("MSGestureEnd", onMSGestureEnd, false);
737
738            function onMSPointerDown(e){
739                e.stopPropagation();
740                if (slider.animating) {
741                    e.preventDefault();
742                }else{
743                    slider.pause();
744                    el._gesture.addPointer(e.pointerId);
745                    accDx = 0;
746                    cwidth = (vertical) ? slider.h : slider. w;
747                    startT = Number(new Date());
748                    // CAROUSEL:
749
750                    offset = (carousel && reverse && slider.animatingTo === slider.last) ? 0 :
751                        (carousel && reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
752                            (carousel && slider.currentSlide === slider.last) ? slider.limit :
753                                (carousel) ? ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.currentSlide :
754                                    (reverse) ? (slider.last - slider.currentSlide + slider.cloneOffset) * cwidth : (slider.currentSlide + slider.cloneOffset) * cwidth;
755                }
756            }
757
758            function onMSGestureChange(e) {
759                e.stopPropagation();
760                var slider = e.target._slider;
761                if(!slider){
762                    return;
763                }
764                var transX = -e.translationX,
765                    transY = -e.translationY;
766
767                //Accumulate translations.
768                accDx = accDx + ((vertical) ? transY : transX);
769                dx = accDx;
770                scrolling = (vertical) ? (Math.abs(accDx) < Math.abs(-transX)) : (Math.abs(accDx) < Math.abs(-transY));
771
772                if(e.detail === e.MSGESTURE_FLAG_INERTIA){
773                    setImmediate(function (){
774                        el._gesture.stop();
775                    });
776
777                    return;
778                }
779
780                if (!scrolling || Number(new Date()) - startT > 500) {
781                    e.preventDefault();
782                    if (!fade && slider.transitions) {
783                        if (!slider.vars.animationLoop) {
784                            dx = accDx / ((slider.currentSlide === 0 && accDx < 0 || slider.currentSlide === slider.last && accDx > 0) ? (Math.abs(accDx) / cwidth + 2) : 1);
785                        }
786                        slider.setProps(offset + dx, "setTouch");
787                    }
788                }
789            }
790
791            function onMSGestureEnd(e) {
792                e.stopPropagation();
793                var slider = e.target._slider;
794                if(!slider){
795                    return;
796                }
797                if (slider.animatingTo === slider.currentSlide && !scrolling && !(dx === null)) {
798                    var updateDx = (reverse) ? -dx : dx,
799                        target = (updateDx > 0) ? slider.getTarget('next') : slider.getTarget('prev');
800
801                    if (slider.canAdvance(target) && (Number(new Date()) - startT < 550 && Math.abs(updateDx) > 50 || Math.abs(updateDx) > cwidth/2)) {
802                        slider.flexAnimate(target, slider.vars.pauseOnAction);
803                    } else {
804                        if (!fade) slider.flexAnimate(slider.currentSlide, slider.vars.pauseOnAction, true);
805                    }
806                }
807
808                startX = null;
809                startY = null;
810                dx = null;
811                offset = null;
812                accDx = 0;
813            }
814        }
815      },
816      resize: function() {
817        if (!slider.animating && slider.is(':visible')) {
818          if (!carousel) slider.doMath();
819
820          if (fade) {
821            // SMOOTH HEIGHT:
822            methods.smoothHeight();
823          } else if (carousel) { //CAROUSEL:
824            slider.slides.width(slider.computedW);
825            slider.update(slider.pagingCount);
826            slider.setProps();
827          }
828          else if (vertical) { //VERTICAL:
829            slider.viewport.height(slider.h);
830            slider.setProps(slider.h, "setTotal");
831          } else {
832            // SMOOTH HEIGHT:
833            if (slider.vars.smoothHeight) methods.smoothHeight();
834            slider.newSlides.width(slider.computedW);
835            slider.setProps(slider.computedW, "setTotal");
836          }
837        }
838      },
839      smoothHeight: function(dur) {
840        if (!vertical || fade) {
841          var $obj = (fade) ? slider : slider.viewport;
842          (dur) ? $obj.animate({"height": slider.slides.eq(slider.animatingTo).height()}, dur) : $obj.height(slider.slides.eq(slider.animatingTo).height());
843        }
844      },
845      sync: function(action) {
846        var $obj = $(slider.vars.sync).data("flexslider"),
847            target = slider.animatingTo;
848
849        switch (action) {
850          case "animate": $obj.flexAnimate(target, slider.vars.pauseOnAction, false, true); break;
851          case "play": if (!$obj.playing && !$obj.asNav) { $obj.play(); } break;
852          case "pause": $obj.pause(); break;
853        }
854      },
855      pauseInvisible: {
856        visProp: null,
857        init: function() {
858          var prefixes = ['webkit','moz','ms','o'];
859
860          if ('hidden' in document) return 'hidden';
861          for (var i = 0; i < prefixes.length; i++) {
862            if ((prefixes[i] + 'Hidden') in document) 
863            methods.pauseInvisible.visProp = prefixes[i] + 'Hidden';
864          }
865          if (methods.pauseInvisible.visProp) {
866            var evtname = methods.pauseInvisible.visProp.replace(/[H|h]idden/,'') + 'visibilitychange';
867            document.addEventListener(evtname, function() {
868              if (methods.pauseInvisible.isHidden()) {
869                if(slider.startTimeout) clearTimeout(slider.startTimeout); //If clock is ticking, stop timer and prevent from starting while invisible
870                else slider.pause(); //Or just pause
871              }
872              else {
873                if(slider.started) slider.play(); //Initiated before, just play
874                else (slider.vars.initDelay > 0) ? setTimeout(slider.play, slider.vars.initDelay) : slider.play(); //Didn't init before: simply init or wait for it
875              }
876            });
877          }       
878        },
879        isHidden: function() {
880          return document[methods.pauseInvisible.visProp] || false;
881        }
882      },
883      setToClearWatchedEvent: function() {
884        clearTimeout(watchedEventClearTimer);
885        watchedEventClearTimer = setTimeout(function() {
886          watchedEvent = "";
887        }, 3000);
888      }
889    }
890
891    // public methods
892    slider.flexAnimate = function(target, pause, override, withSync, fromNav) {
893      if (!slider.vars.animationLoop && target !== slider.currentSlide) {
894        slider.direction = (target > slider.currentSlide) ? "next" : "prev";
895      }
896
897      if (asNav && slider.pagingCount === 1) slider.direction = (slider.currentItem < target) ? "next" : "prev";
898
899      if (!slider.animating && (slider.canAdvance(target, fromNav) || override) && slider.is(":visible")) {
900        if (asNav && withSync) {
901          var master = $(slider.vars.asNavFor).data('flexslider');
902          slider.atEnd = target === 0 || target === slider.count - 1;
903          master.flexAnimate(target, true, false, true, fromNav);
904          slider.direction = (slider.currentItem < target) ? "next" : "prev";
905          master.direction = slider.direction;
906
907          if (Math.ceil((target + 1)/slider.visible) - 1 !== slider.currentSlide && target !== 0) {
908            slider.currentItem = target;
909            slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
910            target = Math.floor(target/slider.visible);
911          } else {
912            slider.currentItem = target;
913            slider.slides.removeClass(namespace + "active-slide").eq(target).addClass(namespace + "active-slide");
914            return false;
915          }
916        }
917
918        slider.animating = true;
919        slider.animatingTo = target;
920
921        // SLIDESHOW:
922        if (pause) slider.pause();
923
924        // API: before() animation Callback
925        slider.vars.before(slider);
926
927        // SYNC:
928        if (slider.syncExists && !fromNav) methods.sync("animate");
929
930        // CONTROLNAV
931        if (slider.vars.controlNav) methods.controlNav.active();
932
933        // !CAROUSEL:
934        // CANDIDATE: slide active class (for add/remove slide)
935        if (!carousel) slider.slides.removeClass(namespace + 'active-slide').eq(target).addClass(namespace + 'active-slide');
936
937        // INFINITE LOOP:
938        // CANDIDATE: atEnd
939        slider.atEnd = target === 0 || target === slider.last;
940
941        // DIRECTIONNAV:
942        if (slider.vars.directionNav) methods.directionNav.update();
943
944        if (target === slider.last) {
945          // API: end() of cycle Callback
946          slider.vars.end(slider);
947          // SLIDESHOW && !INFINITE LOOP:
948          if (!slider.vars.animationLoop) slider.pause();
949        }
950
951        // SLIDE:
952        if (!fade) {
953          var dimension = (vertical) ? slider.slides.filter(':first').height() : slider.computedW,
954              margin, slideString, calcNext;
955
956          // INFINITE LOOP / REVERSE:
957          if (carousel) {
958            //margin = (slider.vars.itemWidth > slider.w) ? slider.vars.itemMargin * 2 : slider.vars.itemMargin;
959            margin = slider.vars.itemMargin;
960            calcNext = ((slider.itemW + margin) * slider.move) * slider.animatingTo;
961            slideString = (calcNext > slider.limit && slider.visible !== 1) ? slider.limit : calcNext;
962          } else if (slider.currentSlide === 0 && target === slider.count - 1 && slider.vars.animationLoop && slider.direction !== "next") {
963            slideString = (reverse) ? (slider.count + slider.cloneOffset) * dimension : 0;
964          } else if (slider.currentSlide === slider.last && target === 0 && slider.vars.animationLoop && slider.direction !== "prev") {
965            slideString = (reverse) ? 0 : (slider.count + 1) * dimension;
966          } else {
967            slideString = (reverse) ? ((slider.count - 1) - target + slider.cloneOffset) * dimension : (target + slider.cloneOffset) * dimension;
968          }
969          slider.setProps(slideString, "", slider.vars.animationSpeed);
970          if (slider.transitions) {
971            if (!slider.vars.animationLoop || !slider.atEnd) {
972              slider.animating = false;
973              slider.currentSlide = slider.animatingTo;
974            }
975            slider.container.unbind("webkitTransitionEnd transitionend");
976            slider.container.bind("webkitTransitionEnd transitionend", function() {
977              slider.wrapup(dimension);
978            });
979          } else {
980            slider.container.animate(slider.args, slider.vars.animationSpeed, slider.vars.easing, function(){
981              slider.wrapup(dimension);
982            });
983          }
984        } else { // FADE:
985          if (!touch) {
986            //slider.slides.eq(slider.currentSlide).fadeOut(slider.vars.animationSpeed, slider.vars.easing);
987            //slider.slides.eq(target).fadeIn(slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);
988
989            slider.slides.eq(slider.currentSlide).css({"zIndex": 1}).animate({"opacity": 0}, slider.vars.animationSpeed, slider.vars.easing);
990            slider.slides.eq(target).css({"zIndex": 2}).animate({"opacity": 1}, slider.vars.animationSpeed, slider.vars.easing, slider.wrapup);
991
992          } else {
993            slider.slides.eq(slider.currentSlide).css({ "opacity": 0, "zIndex": 1 });
994            slider.slides.eq(target).css({ "opacity": 1, "zIndex": 2 });
995            slider.wrapup(dimension);
996          }
997        }
998        // SMOOTH HEIGHT:
999        if (slider.vars.smoothHeight) methods.smoothHeight(slider.vars.animationSpeed);
1000      }
1001    }
1002    slider.wrapup = function(dimension) {
1003      // SLIDE:
1004      if (!fade && !carousel) {
1005        if (slider.currentSlide === 0 && slider.animatingTo === slider.last && slider.vars.animationLoop) {
1006          slider.setProps(dimension, "jumpEnd");
1007        } else if (slider.currentSlide === slider.last && slider.animatingTo === 0 && slider.vars.animationLoop) {
1008          slider.setProps(dimension, "jumpStart");
1009        }
1010      }
1011      slider.animating = false;
1012      slider.currentSlide = slider.animatingTo;
1013      // API: after() animation Callback
1014      slider.vars.after(slider);
1015    }
1016
1017    // SLIDESHOW:
1018    slider.animateSlides = function() {
1019      if (!slider.animating && focused ) slider.flexAnimate(slider.getTarget("next"));
1020    }
1021    // SLIDESHOW:
1022    slider.pause = function() {
1023      clearInterval(slider.animatedSlides);
1024      slider.animatedSlides = null;
1025      slider.playing = false;
1026      // PAUSEPLAY:
1027      if (slider.vars.pausePlay) methods.pausePlay.update("play");
1028      // SYNC:
1029      if (slider.syncExists) methods.sync("pause");
1030    }
1031    // SLIDESHOW:
1032    slider.play = function() {
1033      if (slider.playing) clearInterval(slider.animatedSlides);
1034      slider.animatedSlides = slider.animatedSlides || setInterval(slider.animateSlides, slider.vars.slideshowSpeed);
1035      slider.started = slider.playing = true;
1036      // PAUSEPLAY:
1037      if (slider.vars.pausePlay) methods.pausePlay.update("pause");
1038      // SYNC:
1039      if (slider.syncExists) methods.sync("play");
1040    }
1041    // STOP:
1042    slider.stop = function () {
1043      slider.pause();
1044      slider.stopped = true;
1045    }
1046    slider.canAdvance = function(target, fromNav) {
1047      // ASNAV:
1048      var last = (asNav) ? slider.pagingCount - 1 : slider.last;
1049      return (fromNav) ? true :
1050             (asNav && slider.currentItem === slider.count - 1 && target === 0 && slider.direction === "prev") ? true :
1051             (asNav && slider.currentItem === 0 && target === slider.pagingCount - 1 && slider.direction !== "next") ? false :
1052             (target === slider.currentSlide && !asNav) ? false :
1053             (slider.vars.animationLoop) ? true :
1054             (slider.atEnd && slider.currentSlide === 0 && target === last && slider.direction !== "next") ? false :
1055             (slider.atEnd && slider.currentSlide === last && target === 0 && slider.direction === "next") ? false :
1056             true;
1057    }
1058    slider.getTarget = function(dir) {
1059      slider.direction = dir;
1060      if (dir === "next") {
1061        return (slider.currentSlide === slider.last) ? 0 : slider.currentSlide + 1;
1062      } else {
1063        return (slider.currentSlide === 0) ? slider.last : slider.currentSlide - 1;
1064      }
1065    }
1066
1067    // SLIDE:
1068    slider.setProps = function(pos, special, dur) {
1069      var target = (function() {
1070        var posCheck = (pos) ? pos : ((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo,
1071            posCalc = (function() {
1072              if (carousel) {
1073                return (special === "setTouch") ? pos :
1074                       (reverse && slider.animatingTo === slider.last) ? 0 :
1075                       (reverse) ? slider.limit - (((slider.itemW + slider.vars.itemMargin) * slider.move) * slider.animatingTo) :
1076                       (slider.animatingTo === slider.last) ? slider.limit : posCheck;
1077              } else {
1078                switch (special) {
1079                  case "setTotal": return (reverse) ? ((slider.count - 1) - slider.currentSlide + slider.cloneOffset) * pos : (slider.currentSlide + slider.cloneOffset) * pos;
1080                  case "setTouch": return (reverse) ? pos : pos;
1081                  case "jumpEnd": return (reverse) ? pos : slider.count * pos;
1082                  case "jumpStart": return (reverse) ? slider.count * pos : pos;
1083                  default: return pos;
1084                }
1085              }
1086            }());
1087
1088            return (posCalc * -1) + "px";
1089          }());
1090
1091      if (slider.transitions) {
1092        target = (vertical) ? "translate3d(0," + target + ",0)" : "translate3d(" + target + ",0,0)";
1093        dur = (dur !== undefined) ? (dur/1000) + "s" : "0s";
1094        slider.container.css("-" + slider.pfx + "-transition-duration", dur);
1095      }
1096
1097      slider.args[slider.prop] = target;
1098      if (slider.transitions || dur === undefined) slider.container.css(slider.args);
1099    }
1100
1101    slider.setup = function(type) {
1102      // SLIDE:
1103      if (!fade) {
1104        var sliderOffset, arr;
1105
1106        if (type === "init") {
1107          slider.viewport = $('<div class="' + namespace + 'viewport"></div>').css({"overflow": "hidden", "position": "relative"}).appendTo(slider).append(slider.container);
1108          // INFINITE LOOP:
1109          slider.cloneCount = 0;
1110          slider.cloneOffset = 0;
1111          // REVERSE:
1112          if (reverse) {
1113            arr = $.makeArray(slider.slides).reverse();
1114            slider.slides = $(arr);
1115            slider.container.empty().append(slider.slides);
1116          }
1117        }
1118        // INFINITE LOOP && !CAROUSEL:
1119        if (slider.vars.animationLoop && !carousel) {
1120          slider.cloneCount = 2;
1121          slider.cloneOffset = 1;
1122          // clear out old clones
1123          if (type !== "init") slider.container.find('.clone').remove();
1124          slider.container.append(slider.slides.first().clone().addClass('clone').attr('aria-hidden', 'true')).prepend(slider.slides.last().clone().addClass('clone').attr('aria-hidden', 'true'));
1125        }
1126        slider.newSlides = $(slider.vars.selector, slider);
1127
1128        sliderOffset = (reverse) ? slider.count - 1 - slider.currentSlide + slider.cloneOffset : slider.currentSlide + slider.cloneOffset;
1129        // VERTICAL:
1130        if (vertical && !carousel) {
1131          slider.container.height((slider.count + slider.cloneCount) * 200 + "%").css("position", "absolute").width("100%");
1132          setTimeout(function(){
1133            slider.newSlides.css({"display": "block"});
1134            slider.doMath();
1135            slider.viewport.height(slider.h);
1136            slider.setProps(sliderOffset * slider.h, "init");
1137          }, (type === "init") ? 100 : 0);
1138        } else {
1139          slider.container.width((slider.count + slider.cloneCount) * 200 + "%");
1140          slider.setProps(sliderOffset * slider.computedW, "init");
1141          setTimeout(function(){
1142            slider.doMath();
1143            slider.newSlides.css({"width": slider.computedW, "float": "left", "display": "block"});
1144            // SMOOTH HEIGHT:
1145            if (slider.vars.smoothHeight) methods.smoothHeight();
1146          }, (type === "init") ? 100 : 0);
1147        }
1148      } else { // FADE:
1149        slider.slides.css({"width": "100%", "float": "left", "marginRight": "-100%", "position": "relative"});
1150        if (type === "init") {
1151          if (!touch) {
1152            //slider.slides.eq(slider.currentSlide).fadeIn(slider.vars.animationSpeed, slider.vars.easing);
1153            slider.slides.css({ "opacity": 0, "display": "block", "zIndex": 1 }).eq(slider.currentSlide).css({"zIndex": 2}).animate({"opacity": 1},slider.vars.animationSpeed,slider.vars.easing);
1154          } else {
1155            slider.slides.css({ "opacity": 0, "display": "block", "webkitTransition": "opacity " + slider.vars.animationSpeed / 1000 + "s ease", "zIndex": 1 }).eq(slider.currentSlide).css({ "opacity": 1, "zIndex": 2});
1156          }
1157        }
1158        // SMOOTH HEIGHT:
1159        if (slider.vars.smoothHeight) methods.smoothHeight();
1160      }
1161      // !CAROUSEL:
1162      // CANDIDATE: active slide
1163      if (!carousel) slider.slides.removeClass(namespace + "active-slide").eq(slider.currentSlide).addClass(namespace + "active-slide");
1164    }
1165
1166
1167    slider.doMath = function() {
1168      var slide = slider.slides.first(),
1169          slideMargin = slider.vars.itemMargin,
1170          minItems = slider.vars.minItems,
1171          maxItems = slider.vars.maxItems;
1172
vendor: 8,049 bytes, lines 1173-1328
1173      slider.w = (slider.viewport===undefined) ? slider.width() : slider.viewport.width();
1174      slider.h = slide.height();
1175      slider.boxPadding = slide.outerWidth() - slide.width();
1176
1177      // CAROUSEL:
1178      if (carousel) {
1179        slider.itemT = slider.vars.itemWidth + slideMargin;
1180        slider.minW = (minItems) ? minItems * slider.itemT : slider.w;
1181        slider.maxW = (maxItems) ? (maxItems * slider.itemT) - slideMargin : slider.w;
1182        slider.itemW = (slider.minW > slider.w) ? (slider.w - (slideMargin * (minItems - 1)))/minItems :
1183                       (slider.maxW < slider.w) ? (slider.w - (slideMargin * (maxItems - 1)))/maxItems :
1184                       (slider.vars.itemWidth > slider.w) ? slider.w : slider.vars.itemWidth;
1185
1186        slider.visible = Math.floor(slider.w/(slider.itemW));
1187        slider.move = (slider.vars.move > 0 && slider.vars.move < slider.visible ) ? slider.vars.move : slider.visible;
1188        slider.pagingCount = Math.ceil(((slider.count - slider.visible)/slider.move) + 1);
1189        slider.last =  slider.pagingCount - 1;
1190        slider.limit = (slider.pagingCount === 1) ? 0 :
1191                       (slider.vars.itemWidth > slider.w) ? (slider.itemW * (slider.count - 1)) + (slideMargin * (slider.count - 1)) : ((slider.itemW + slideMargin) * slider.count) - slider.w - slideMargin;
1192      } else {
1193        slider.itemW = slider.w;
1194        slider.pagingCount = slider.count;
1195        slider.last = slider.count - 1;
1196      }
1197      slider.computedW = slider.itemW - slider.boxPadding;
1198    }
1199
1200
1201    slider.update = function(pos, action) {
1202      slider.doMath();
1203
1204      // update currentSlide and slider.animatingTo if necessary
1205      if (!carousel) {
1206        if (pos < slider.currentSlide) {
1207          slider.currentSlide += 1;
1208        } else if (pos <= slider.currentSlide && pos !== 0) {
1209          slider.currentSlide -= 1;
1210        }
1211        slider.animatingTo = slider.currentSlide;
1212      }
1213
1214      // update controlNav
1215      if (slider.vars.controlNav && !slider.manualControls) {
1216        if ((action === "add" && !carousel) || slider.pagingCount > slider.controlNav.length) {
1217          methods.controlNav.update("add");
1218        } else if ((action === "remove" && !carousel) || slider.pagingCount < slider.controlNav.length) {
1219          if (carousel && slider.currentSlide > slider.last) {
1220            slider.currentSlide -= 1;
1221            slider.animatingTo -= 1;
1222          }
1223          methods.controlNav.update("remove", slider.last);
1224        }
1225      }
1226      // update directionNav
1227      if (slider.vars.directionNav) methods.directionNav.update();
1228
1229    }
1230
1231    slider.addSlide = function(obj, pos) {
1232      var $obj = $(obj);
1233
1234      slider.count += 1;
1235      slider.last = slider.count - 1;
1236
1237      // append new slide
1238      if (vertical && reverse) {
1239        (pos !== undefined) ? slider.slides.eq(slider.count - pos).after($obj) : slider.container.prepend($obj);
1240      } else {
1241        (pos !== undefined) ? slider.slides.eq(pos).before($obj) : slider.container.append($obj);
1242      }
1243
1244      // update currentSlide, animatingTo, controlNav, and directionNav
1245      slider.update(pos, "add");
1246
1247      // update slider.slides
1248      slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
1249      // re-setup the slider to accomdate new slide
1250      slider.setup();
1251
1252      //FlexSlider: added() Callback
1253      slider.vars.added(slider);
1254    }
1255    slider.removeSlide = function(obj) {
1256      var pos = (isNaN(obj)) ? slider.slides.index($(obj)) : obj;
1257
1258      // update count
1259      slider.count -= 1;
1260      slider.last = slider.count - 1;
1261
1262      // remove slide
1263      if (isNaN(obj)) {
1264        $(obj, slider.slides).remove();
1265      } else {
1266        (vertical && reverse) ? slider.slides.eq(slider.last).remove() : slider.slides.eq(obj).remove();
1267      }
1268
1269      // update currentSlide, animatingTo, controlNav, and directionNav
1270      slider.doMath();
1271      slider.update(pos, "remove");
1272
1273      // update slider.slides
1274      slider.slides = $(slider.vars.selector + ':not(.clone)', slider);
1275      // re-setup the slider to accomdate new slide
1276      slider.setup();
1277
1278      // FlexSlider: removed() Callback
1279      slider.vars.removed(slider);
1280    }
1281
1282    //FlexSlider: Initialize
1283    methods.init();
1284  }
1285
1286  // Ensure the slider isn't focussed if the window loses focus.
1287  $( window ).blur( function ( e ) {
1288    focused = false;
1289  }).focus( function ( e ) {
1290    focused = true;
1291  });
1292
1293  //FlexSlider: Default Settings
1294  $.flexslider.defaults = {
1295    namespace: "flex-",             //{NEW} String: Prefix string attached to the class of every element generated by the plugin
1296    selector: ".slides > li",       //{NEW} Selector: Must match a simple pattern. '{container} > {slide}' -- Ignore pattern at your own peril
1297    animation: "fade",              //String: Select your animation type, "fade" or "slide"
1298    easing: "swing",                //{NEW} String: Determines the easing method used in jQuery transitions. jQuery easing plugin is supported!
1299    direction: "horizontal",        //String: Select the sliding direction, "horizontal" or "vertical"
1300    reverse: false,                 //{NEW} Boolean: Reverse the animation direction
1301    animationLoop: true,            //Boolean: Should the animation loop? If false, directionNav will received "disable" classes at either end
1302    smoothHeight: false,            //{NEW} Boolean: Allow height of the slider to animate smoothly in horizontal mode
1303    startAt: 0,                     //Integer: The slide that the slider should start on. Array notation (0 = first slide)
1304    slideshow: true,                //Boolean: Animate slider automatically
1305    slideshowSpeed: 7000,           //Integer: Set the speed of the slideshow cycling, in milliseconds
1306    animationSpeed: 600,            //Integer: Set the speed of animations, in milliseconds
1307    initDelay: 0,                   //{NEW} Integer: Set an initialization delay, in milliseconds
1308    randomize: false,               //Boolean: Randomize slide order
1309    thumbCaptions: false,           //Boolean: Whether or not to put captions on thumbnails when using the "thumbnails" controlNav.
1310
1311    // Usability features
1312    pauseOnAction: true,            //Boolean: Pause the slideshow when interacting with control elements, highly recommended.
1313    pauseOnHover: false,            //Boolean: Pause the slideshow when hovering over slider, then resume when no longer hovering
1314    pauseInvisible: true,   		//{NEW} Boolean: Pause the slideshow when tab is invisible, resume when visible. Provides better UX, lower CPU usage.
1315    useCSS: true,                   //{NEW} Boolean: Slider will use CSS3 transitions if available
1316    touch: true,                    //{NEW} Boolean: Allow touch swipe navigation of the slider on touch-enabled devices
1317    video: false,                   //{NEW} Boolean: If using video in the slider, will prevent CSS3 3D Transforms to avoid graphical glitches
1318
1319    // Primary Controls
1320    controlNav: true,               //Boolean: Create navigation for paging control of each clide? Note: Leave true for manualControls usage
1321    directionNav: true,             //Boolean: Create navigation for previous/next navigation? (true/false)
1322    prevText: "Previous",           //String: Set the text for the "previous" directionNav item
1323    nextText: "Next",               //String: Set the text for the "next" directionNav item
1324
1325    // Secondary Navigation
1326    keyboard: true,                 //Boolean: Allow slider navigating via keyboard left/right keys
1327    multipleKeyboard: false,        //{NEW} Boolean: Allow keyboard navigation to affect multiple sliders. Default behavior cuts out keyboard navigation with more than one slider present.
1328    mousewheel: false,              //{UPDATED} Boolean: Requires jquery.mousewheel.js (https://github.com/brandonaaron/jquery-mousewheel) - Allows slider navigating via mousewheel
1329    pausePlay: false,               //Boolean: Create pause/play dynamic element
1330    pauseText: "Pause",             //String: Set the text for the "pause" pausePlay item
1331    playText: "Play",               //String: Set the text for the "play" pausePlay item
1332
1333    // Special properties
1334    controlsContainer: "",          //{UPDATED} jQuery Object/Selector: Declare which container the navigation elements should be appended too. Default container is the FlexSlider element. Example use would be $(".flexslider-container"). Property is ignored if given element is not found.
1335    manualControls: "",             //{UPDATED} jQuery Object/Selector: Declare custom control navigation. Examples would be $(".flex-control-nav li") or "#tabs-nav li img", etc. The number of elements in your controlNav should match the number of slides/tabs.
1336    sync: "",                       //{NEW} Selector: Mirror the actions performed on this slider with another slider. Use with care.
1337    asNavFor: "",                   //{NEW} Selector: Internal property exposed for turning the slider into a thumbnail navigation for another slider
1338
1339    // Carousel Options
1340    itemWidth: 0,                   //{NEW} Integer: Box-model width of individual carousel items, including horizontal borders and padding.
1341    itemMargin: 0,                  //{NEW} Integer: Margin between carousel items.
1342    minItems: 1,                    //{NEW} Integer: Minimum number of carousel items that should be visible. Items will resize fluidly when below this.
1343    maxItems: 0,                    //{NEW} Integer: Maxmimum number of carousel items that should be visible. Items will resize fluidly when above this limit.
1344    move: 0,                        //{NEW} Integer: Number of carousel items that should move on animation. If 0, slider will move all visible items.
1345    allowOneSlide: true,           //{NEW} Boolean: Whether or not to allow a slider comprised of a single slide
1346
1347    // Callback API
1348    start: function(){},            //Callback: function(slider) - Fires when the slider loads the first slide
1349    before: function(){},           //Callback: function(slider) - Fires asynchronously with each slider animation
1350    after: function(){},            //Callback: function(slider) - Fires after each slider animation completes
1351    end: function(){},              //Callback: function(slider) - Fires when the slider reaches the last slide (asynchronous)
1352    added: function(){},            //{NEW} Callback: function(slider) - Fires after a slide is added
1353    removed: function(){}           //{NEW} Callback: function(slider) - Fires after a slide is removed
1354  }
1355
1356
1357  //FlexSlider: Plugin Function
1358  $.fn.flexslider = function(options) {
1359    if (options === undefined) options = {};
1360
1361    if (typeof options === "object") {
1362      return this.each(function() {
1363        var $this = $(this),
1364            selector = (options.selector) ? options.selector : ".slides > li",
1365            $slides = $this.find(selector);
1366
1367      if ( ( $slides.length === 1 && options.allowOneSlide === true ) || $slides.length === 0 ) {
1368          $slides.fadeIn(400);
1369          if (options.start) options.start($this);
1370        } else if ($this.data('flexslider') === undefined) {
1371          new $.flexslider(this, options);
1372        }
1373      });
1374    } else {
1375      // Helper strings to quickly perform functions on the slider
1376      var $slider = $(this).data('flexslider');
1377      switch (options) {
1378        case "play": $slider.play(); break;
1379        case "pause": $slider.pause(); break;
1380        case "stop": $slider.stop(); break;
1381        case "next": $slider.flexAnimate($slider.getTarget("next"), true); break;
1382        case "prev":
1383        case "previous": $slider.flexAnimate($slider.getTarget("prev"), true); break;
1384        default: if (typeof options === "number") $slider.flexAnimate(options, true);
1385      }
1386    }
1387  }
1388})(jQuery);
1389
1390
1391/**
1392 * Tayfun Erbilen - jQuery Slider Plugin (pSlider)
1393 */
1394jQuery.fn.pSlider = function(settings){
1395
1396    // eklenti ayarları
1397    var config = jQuery.extend({
1398        slider: null,
1399        button: {
1400            prev: null,
1401            next: null
1402        },
1403        visible: 1,
1404        width: null,
1405        height: null,
1406        extra: 0,
1407        direction: 'horizontal',
1408        duration: 1000,
1409        loop: false,
1410        easing: null,
1411        start: null,
1412        animation: true,
1413        skip: 1,
1414        auto: false,
1415        time: 1000,
1416        keyboard: false,
1417        pagination: null,
1418        list: null,
1419        callback: function(){},
1420        callbackStart: function(){},
1421        callbackEnd: function(){}
1422    }, settings);
1423
1424    var that = this;
1425
1426    // callback
1427    if ( config.start === 0 || config.start === null ) config.callbackStart();
1428
1429    // eğer genişlik değeri verilmemiş ise otomatik al
1430    if ( config.direction === 'horizontal' && config.width === null )
1431        config.width = config.slider.outerWidth() + config.extra;
1432
1433    // eğer yükseklik değeri verilmemiş ise otomatik al
1434    if ( config.direction === 'vertical' && config.height === null )
1435        config.height = config.slider.outerHeight() + config.extra;
1436
1437    // animasyon çalışırken değeri true, çalışmıyorken değeri false olacak
1438    this.animated = false;
1439
1440    // slider için toplam eleman sayısı
1441    this.total = config.slider.length;
1442
1443    // slider elemanlarının üst nesnesi
1444    this.parent = config.slider.parent();
1445
1446    // ana slider nesnesini her ihtimale karşı gizleyelim
1447    this.css('overflow', 'hidden');
1448
1449    // slider nesnelerine genişlik ve ya yükseklik ata
1450    if ( config.direction === 'horizontal' ) config.slider.width( config.width );
1451    else if ( config.direction === 'vertical' ) config.slider.height( config.height );
1452
1453    // eğer yatay slider ise
1454    if ( config.direction === 'horizontal' ){
1455
1456        // slider elemanlarını yan yana getirelim
1457        config.slider.css('float','left');
1458
1459        // slider elemanlarının üst nesnesine toplam genişliği verelim
1460        this.parent.width( (config.width * this.total) + (config.extra * this.total) );
1461
1462    }
1463
1464    // eğer dikey slider ise
1465    else if ( config.direction === 'vertical' ){
1466
1467        // slider elemanlarının üst nesnesine toplam yüksekliği verelim
1468        this.parent.height( (config.height * this.total) + (config.extra * this.total) );
1469
1470    }
1471
1472    // eğer sayfalama seçilmiş ise
1473    if ( config.pagination ){
1474        if ( that.total === 1 ){
1475            config.pagination.hide();
1476        } else {
1477
1478            for ( var i = 1; i <= that.total; i++ ){
1479                config.pagination.append('<a href="#"' + (i === 1 ? ' class="active"' : null) + '>' + i + '</a>');
1480            }
1481
1482            config.pagination.find('a').on('click', function(e){
1483                config.start = $(this).index();
1484                that.animation('text');
1485                e.preventDefault();
1486            });
1487
1488        }
1489    }
1490
1491    // eğer liste seçilmiş ise
1492    if ( config.list ){
1493        config.list.filter(':first').addClass('active');
1494        config.list.on('click', function(e){
1495            config.start = $(this).index();
1496            that.animation('text');
1497            e.preventDefault();
1498        });
1499    }
1500
1501    // animasyon işlemi
1502    this.animation = function(button){
1503
1504        // eğer animasyon çalışmıyorsa
1505        if ( that.animated === false ){
1506
1507            // animasyonun çalıştığını söyle
1508            that.animated = true;
1509
1510            if ( button === 'next' ){
1511
1512                // eğer mevcut değer toplam - görünen elemanlardan küçük ise işleme devam et
1513                if ( config.start < that.total - config.visible ){
1514
1515                    // mevcut değeri hesapla
1516                    config.start = config.start + config.skip;
1517
1518                    // eğer hesaplanan değer toplam - görünen eleman sayısından büyük ise tekrardan değer ataması yap
1519                    if ( config.start > that.total - config.visible ) config.start = that.total - config.visible;
1520
1521                }
1522                // değilse ve döngü var ise mevcut değeri 0'a eşitle
1523                else {
1524                    if ( config.loop ) config.start = 0;
1525                    else that.animated = false;
1526                }
1527
1528            } else if ( button === 'prev' ){
1529
1530                // eğer mevcut değer 0'dan büyük ise azaltmaya devam et
1531                if ( config.start > 0 ){
1532
1533                    // mevcut değeri hesapla
1534                    config.start = config.start - config.skip;
1535
1536                    // eğer hesaplanan değer 0'dan küçük ise değeri tekrar 0'a eşitle
1537                    if ( config.start < 0 ) config.start = 0;
1538
1539                }
1540                // değilse ve döngü var ise mevcut değeri toplam eksik görünen eleman sayısıne eşitle
1541                else {
1542                    if ( config.loop ) config.start = that.total - config.visible;
1543                    else that.animated = false;
1544                }
1545
1546            }
1547
1548            if ( config.direction === 'horizontal' ){
1549                that.obj = {marginLeft: '-' + ( (config.start * config.width) + (config.extra * config.start) )};
1550            }
1551            else if ( config.direction === 'vertical' ){
1552                that.obj = {marginTop: '-' + ( (config.start * config.height)  + (config.extra * config.start) )};
1553            }
1554
1555            that.parent.stop().animate(that.obj, {
1556                duration: config.duration,
1557                complete: function(){
1558
1559                    // animasyonun çalışmadığını söyle
1560                    that.animated = false;
1561
1562                    // sayfalama aktif ise
1563                    if ( config.pagination ){
1564                        config.pagination.find('a').removeClass('active').eq(config.start).addClass('active');
1565                    }
1566
1567                    // liste aktif ise
1568                    if ( config.list ){
1569                        config.list.removeClass('active').eq(config.start).addClass('active');
1570                    }
1571
1572                },
1573                easing: (config.easing) ? config.easing : null
1574            });
1575
1576            // callback
1577            if ( config.start === that.total - config.visible ) config.callbackEnd();
1578            else if ( config.start === 0 || config.start === null ) config.callbackStart();
1579            else config.callback();
1580
1581        }
1582
1583    };
1584
1585    if ( config.button.next ){
1586        config.button.next.on('click', function(e){
1587            that.animation('next');
1588            e.preventDefault();
1589        });
1590    }
1591
1592    if ( config.button.prev ){
1593        config.button.prev.on('click', function(e){
1594            that.animation('prev');
1595            e.preventDefault();
1596        });
1597    }
1598
1599    // eğer başlangıç değişecek ise kontrol et
1600    if ( config.start > 0 ){
1601
1602        config.start = config.start - 1;
1603
1604        // eğer girilen başlangıç değeri toplam değerden büyük ise başlangıç değerini otomatik olarak toplam değer yap
1605        if ( config.start > this.total ) config.start = this.total;
1606
1607        // eğer başlangıç değerine animasyonlu şekilde geçiş yapacak ise burayı çalıştır
1608        if ( config.animation ){
1609            this.animation('next');
1610        }
1611        // görünmeden yapacak isede burayı çalıştır, dikey ve yataya göre hesapla
1612        else {
1613
1614            config.start = config.start + 1;
1615
1616            if ( config.direction === 'horizontal' )
1617                this.parent.css('margin-left', '-' + ( (config.start) * config.width ) + 'px');
1618            else if ( config.direction === 'vertical' )
1619                this.parent.css('margin-top', '-' + ( (config.start) * config.height ) + 'px');
1620
1621            // sayfalama aktif ise
1622            if ( config.pagination ){
1623                config.pagination.find('a').removeClass('active').eq(config.start).addClass('active');
1624            }
1625
1626            // liste aktif ise
1627            if ( config.list ){
1628                config.list.removeClass('active').eq(config.start).addClass('active');
1629            }
1630
1631        }
1632    }
1633
1634    // klavye kontrolü
1635    if ( config.keyboard ){
1636        this.keyboard = function(event){
1637            var key = event.which || event.keyCode;
1638            if ( config.direction === 'horizontal' ){
1639                if ( key === 37 ) that.animation('prev');
1640                else if ( key === 39 ) that.animation('next');
1641            } else if ( config.direction === 'vertical' ){
1642                if ( key === 40 ) that.animation('prev');
1643                else if ( key === 38 ) that.animation('next');
1644            }
1645            return false;
1646        };
1647        this.hover(function(){
1648            $(document).on('keydown', that.keyboard);
1649        }, function(){
1650            $(document).off('keydown', that.keyboard);
1651        });
1652    }
1653
1654    // eğer otomatik dönme var ise
1655    if ( config.auto ){
1656
1657        // otomatik döngüyü aktif et
1658        config.loop = true;
1659
1660        // otomatik döndürme işlemini başlat
1661        this.interval = setInterval(function(){
1662            that.animation('next');
1663        }, config.time);
1664
1665        this.hover(function(){
1666            clearInterval(that.interval);
1667            that.interval = null;
1668        }, function(){
1669            that.interval = setInterval(function(){
1670                that.animation('next');
1671            }, config.time);
1672        });
1673
1674    }
1675
1676    // yeniden boyutlandırma
1677    this.bind('resize', function(event, arg){
1678        that.animated = false;
1679        config.start = config.start + 1;
1680        arg = jQuery.extend(config, arg);
1681        $(this).pSlider(arg);
1682    });
1683
1684};
1685
1686
1687
1688/*!
1689 * fancyBox - jQuery Plugin
1690 * version: 2.1.5 (Fri, 14 Jun 2013)
1691 * @requires jQuery v1.6 or later
1692 *
1693 * Examples at http://fancyapps.com/fancybox/
1694 * License: www.fancyapps.com/fancybox/#license
1695 *
1696 * Copyright 2012 Janis Skarnelis - [email protected]
1697 *
1698 */
1699
1700(function (window, document, $, undefined) {
1701	"use strict";
1702
1703	var H = $("html"),
1704		W = $(window),
1705		D = $(document),
1706		F = $.fancybox = function () {
1707			F.open.apply( this, arguments );
1708		},
1709		IE =  navigator.userAgent.match(/msie/i),
1710		didUpdate	= null,
1711		isTouch		= document.createTouch !== undefined,
1712
1713		isQuery	= function(obj) {
1714			return obj && obj.hasOwnProperty && obj instanceof $;
1715		},
1716		isString = function(str) {
1717			return str && $.type(str) === "string";
1718		},
1719		isPercentage = function(str) {
1720			return isString(str) && str.indexOf('%') > 0;
vendor: 41,558 bytes, lines 1721-3376
1721		},
1722		isScrollable = function(el) {
1723			return (el && !(el.style.overflow && el.style.overflow === 'hidden') && ((el.clientWidth && el.scrollWidth > el.clientWidth) || (el.clientHeight && el.scrollHeight > el.clientHeight)));
1724		},
1725		getScalar = function(orig, dim) {
1726			var value = parseInt(orig, 10) || 0;
1727
1728			if (dim && isPercentage(orig)) {
1729				value = F.getViewport()[ dim ] / 100 * value;
1730			}
1731
1732			return Math.ceil(value);
1733		},
1734		getValue = function(value, dim) {
1735			return getScalar(value, dim) + 'px';
1736		};
1737
1738	$.extend(F, {
1739		// The current version of fancyBox
1740		version: '2.1.5',
1741
1742		defaults: {
1743			padding : 15,
1744			margin  : 20,
1745
1746			width     : 800,
1747			height    : 600,
1748			minWidth  : 100,
1749			minHeight : 100,
1750			maxWidth  : 9999,
1751			maxHeight : 9999,
1752			pixelRatio: 1, // Set to 2 for retina display support
1753
1754			autoSize   : true,
1755			autoHeight : false,
1756			autoWidth  : false,
1757
1758			autoResize  : true,
1759			autoCenter  : !isTouch,
1760			fitToView   : true,
1761			aspectRatio : false,
1762			topRatio    : 0.5,
1763			leftRatio   : 0.5,
1764
1765			scrolling : 'auto', // 'auto', 'yes' or 'no'
1766			wrapCSS   : '',
1767
1768			arrows     : true,
1769			closeBtn   : true,
1770			closeClick : false,
1771			nextClick  : false,
1772			mouseWheel : true,
1773			autoPlay   : false,
1774			playSpeed  : 3000,
1775			preload    : 3,
1776			modal      : false,
1777			loop       : true,
1778
1779			ajax  : {
1780				dataType : 'html',
1781				headers  : { 'X-fancyBox': true }
1782			},
1783			iframe : {
1784				scrolling : 'auto',
1785				preload   : true
1786			},
1787			swf : {
1788				wmode: 'transparent',
1789				allowfullscreen   : 'true',
1790				allowscriptaccess : 'always'
1791			},
1792
1793			keys  : {
1794				next : {
1795					13 : 'left', // enter
1796					34 : 'up',   // page down
1797					39 : 'left', // right arrow
1798					40 : 'up'    // down arrow
1799				},
1800				prev : {
1801					8  : 'right',  // backspace
1802					33 : 'down',   // page up
1803					37 : 'right',  // left arrow
1804					38 : 'down'    // up arrow
1805				},
1806				close  : [27], // escape key
1807				play   : [32], // space - start/stop slideshow
1808				toggle : [70]  // letter "f" - toggle fullscreen
1809			},
1810
1811			direction : {
1812				next : 'left',
1813				prev : 'right'
1814			},
1815
1816			scrollOutside  : true,
1817
1818			// Override some properties
1819			index   : 0,
1820			type    : null,
1821			href    : null,
1822			content : null,
1823			title   : null,
1824
1825			// HTML templates
1826			tpl: {
1827				wrap     : '<div class="fancybox-wrap" tabIndex="-1"><div class="fancybox-skin"><div class="fancybox-outer"><div class="fancybox-inner"></div></div></div></div>',
1828				image    : '<img class="fancybox-image" src="{href}" alt="" />',
1829				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>',
1830				error    : '<p class="fancybox-error">The requested content cannot be loaded.<br/>Please try again later.</p>',
1831				closeBtn : '<a title="Close" class="fancybox-item fancybox-close" href="javascript:;"></a>',
1832				next     : '<a title="Next" class="fancybox-nav fancybox-next" href="javascript:;"><span></span></a>',
1833				prev     : '<a title="Previous" class="fancybox-nav fancybox-prev" href="javascript:;"><span></span></a>'
1834			},
1835
1836			// Properties for each animation type
1837			// Opening fancyBox
1838			openEffect  : 'fade', // 'elastic', 'fade' or 'none'
1839			openSpeed   : 250,
1840			openEasing  : 'swing',
1841			openOpacity : true,
1842			openMethod  : 'zoomIn',
1843
1844			// Closing fancyBox
1845			closeEffect  : 'fade', // 'elastic', 'fade' or 'none'
1846			closeSpeed   : 250,
1847			closeEasing  : 'swing',
1848			closeOpacity : true,
1849			closeMethod  : 'zoomOut',
1850
1851			// Changing next gallery item
1852			nextEffect : 'elastic', // 'elastic', 'fade' or 'none'
1853			nextSpeed  : 250,
1854			nextEasing : 'swing',
1855			nextMethod : 'changeIn',
1856
1857			// Changing previous gallery item
1858			prevEffect : 'elastic', // 'elastic', 'fade' or 'none'
1859			prevSpeed  : 250,
1860			prevEasing : 'swing',
1861			prevMethod : 'changeOut',
1862
1863			// Enable default helpers
1864			helpers : {
1865				overlay : true,
1866				title   : true
1867			},
1868
1869			// Callbacks
1870			onCancel     : $.noop, // If canceling
1871			beforeLoad   : $.noop, // Before loading
1872			afterLoad    : $.noop, // After loading
1873			beforeShow   : $.noop, // Before changing in current item
1874			afterShow    : $.noop, // After opening
1875			beforeChange : $.noop, // Before changing gallery item
1876			beforeClose  : $.noop, // Before closing
1877			afterClose   : $.noop  // After closing
1878		},
1879
1880		//Current state
1881		group    : {}, // Selected group
1882		opts     : {}, // Group options
1883		previous : null,  // Previous element
1884		coming   : null,  // Element being loaded
1885		current  : null,  // Currently loaded element
1886		isActive : false, // Is activated
1887		isOpen   : false, // Is currently open
1888		isOpened : false, // Have been fully opened at least once
1889
1890		wrap  : null,
1891		skin  : null,
1892		outer : null,
1893		inner : null,
1894
1895		player : {
1896			timer    : null,
1897			isActive : false
1898		},
1899
1900		// Loaders
1901		ajaxLoad   : null,
1902		imgPreload : null,
1903
1904		// Some collections
1905		transitions : {},
1906		helpers     : {},
1907
1908		/*
1909		 *	Static methods
1910		 */
1911
1912		open: function (group, opts) {
1913			if (!group) {
1914				return;
1915			}
1916
1917			if (!$.isPlainObject(opts)) {
1918				opts = {};
1919			}
1920
1921			// Close if already active
1922			if (false === F.close(true)) {
1923				return;
1924			}
1925
1926			// Normalize group
1927			if (!$.isArray(group)) {
1928				group = isQuery(group) ? $(group).get() : [group];
1929			}
1930
1931			// Recheck if the type of each element is `object` and set content type (image, ajax, etc)
1932			$.each(group, function(i, element) {
1933				var obj = {},
1934					href,
1935					title,
1936					content,
1937					type,
1938					rez,
1939					hrefParts,
1940					selector;
1941
1942				if ($.type(element) === "object") {
1943					// Check if is DOM element
1944					if (element.nodeType) {
1945						element = $(element);
1946					}
1947
1948					if (isQuery(element)) {
1949						obj = {
1950							href    : element.data('fancybox-href') || element.attr('href'),
1951							title   : element.data('fancybox-title') || element.attr('title'),
1952							isDom   : true,
1953							element : element
1954						};
1955
1956						if ($.metadata) {
1957							$.extend(true, obj, element.metadata());
1958						}
1959
1960					} else {
1961						obj = element;
1962					}
1963				}
1964
1965				href  = opts.href  || obj.href || (isString(element) ? element : null);
1966				title = opts.title !== undefined ? opts.title : obj.title || '';
1967
1968				content = opts.content || obj.content;
1969				type    = content ? 'html' : (opts.type  || obj.type);
1970
1971				if (!type && obj.isDom) {
1972					type = element.data('fancybox-type');
1973
1974					if (!type) {
1975						rez  = element.prop('class').match(/fancybox\.(\w+)/);
1976						type = rez ? rez[1] : null;
1977					}
1978				}
1979
1980				if (isString(href)) {
1981					// Try to guess the content type
1982					if (!type) {
1983						if (F.isImage(href)) {
1984							type = 'image';
1985
1986						} else if (F.isSWF(href)) {
1987							type = 'swf';
1988
1989						} else if (href.charAt(0) === '#') {
1990							type = 'inline';
1991
1992						} else if (isString(element)) {
1993							type    = 'html';
1994							content = element;
1995						}
1996					}
1997
1998					// Split url into two pieces with source url and content selector, e.g,
1999					// "/mypage.html #my_id" will load "/mypage.html" and display element having id "my_id"
2000					if (type === 'ajax') {
2001						hrefParts = href.split(/\s+/, 2);
2002						href      = hrefParts.shift();
2003						selector  = hrefParts.shift();
2004					}
2005				}
2006
2007				if (!content) {
2008					if (type === 'inline') {
2009						if (href) {
2010							content = $( isString(href) ? href.replace(/.*(?=#[^\s]+$)/, '') : href ); //strip for ie7
2011
2012						} else if (obj.isDom) {
2013							content = element;
2014						}
2015
2016					} else if (type === 'html') {
2017						content = href;
2018
2019					} else if (!type && !href && obj.isDom) {
2020						type    = 'inline';
2021						content = element;
2022					}
2023				}
2024
2025				$.extend(obj, {
2026					href     : href,
2027					type     : type,
2028					content  : content,
2029					title    : title,
2030					selector : selector
2031				});
2032
2033				group[ i ] = obj;
2034			});
2035
2036			// Extend the defaults
2037			F.opts = $.extend(true, {}, F.defaults, opts);
2038
2039			// All options are merged recursive except keys
2040			if (opts.keys !== undefined) {
2041				F.opts.keys = opts.keys ? $.extend({}, F.defaults.keys, opts.keys) : false;
2042			}
2043
2044			F.group = group;
2045
2046			return F._start(F.opts.index);
2047		},
2048
2049		// Cancel image loading or abort ajax request
2050		cancel: function () {
2051			var coming = F.coming;
2052
2053			if (!coming || false === F.trigger('onCancel')) {
2054				return;
2055			}
2056
2057			F.hideLoading();
2058
2059			if (F.ajaxLoad) {
2060				F.ajaxLoad.abort();
2061			}
2062
2063			F.ajaxLoad = null;
2064
2065			if (F.imgPreload) {
2066				F.imgPreload.onload = F.imgPreload.onerror = null;
2067			}
2068
2069			if (coming.wrap) {
2070				coming.wrap.stop(true, true).trigger('onReset').remove();
2071			}
2072
2073			F.coming = null;
2074
2075			// If the first item has been canceled, then clear everything
2076			if (!F.current) {
2077				F._afterZoomOut( coming );
2078			}
2079		},
2080
2081		// Start closing animation if is open; remove immediately if opening/closing
2082		close: function (event) {
2083			F.cancel();
2084
2085			if (false === F.trigger('beforeClose')) {
2086				return;
2087			}
2088
2089			F.unbindEvents();
2090
2091			if (!F.isActive) {
2092				return;
2093			}
2094
2095			if (!F.isOpen || event === true) {
2096				$('.fancybox-wrap').stop(true).trigger('onReset').remove();
2097
2098				F._afterZoomOut();
2099
2100			} else {
2101				F.isOpen = F.isOpened = false;
2102				F.isClosing = true;
2103
2104				$('.fancybox-item, .fancybox-nav').remove();
2105
2106				F.wrap.stop(true, true).removeClass('fancybox-opened');
2107
2108				F.transitions[ F.current.closeMethod ]();
2109			}
2110		},
2111
2112		// Manage slideshow:
2113		//   $.fancybox.play(); - toggle slideshow
2114		//   $.fancybox.play( true ); - start
2115		//   $.fancybox.play( false ); - stop
2116		play: function ( action ) {
2117			var clear = function () {
2118					clearTimeout(F.player.timer);
2119				},
2120				set = function () {
2121					clear();
2122
2123					if (F.current && F.player.isActive) {
2124						F.player.timer = setTimeout(F.next, F.current.playSpeed);
2125					}
2126				},
2127				stop = function () {
2128					clear();
2129
2130					D.unbind('.player');
2131
2132					F.player.isActive = false;
2133
2134					F.trigger('onPlayEnd');
2135				},
2136				start = function () {
2137					if (F.current && (F.current.loop || F.current.index < F.group.length - 1)) {
2138						F.player.isActive = true;
2139
2140						D.bind({
2141							'onCancel.player beforeClose.player' : stop,
2142							'onUpdate.player'   : set,
2143							'beforeLoad.player' : clear
2144						});
2145
2146						set();
2147
2148						F.trigger('onPlayStart');
2149					}
2150				};
2151
2152			if (action === true || (!F.player.isActive && action !== false)) {
2153				start();
2154			} else {
2155				stop();
2156			}
2157		},
2158
2159		// Navigate to next gallery item
2160		next: function ( direction ) {
2161			var current = F.current;
2162
2163			if (current) {
2164				if (!isString(direction)) {
2165					direction = current.direction.next;
2166				}
2167
2168				F.jumpto(current.index + 1, direction, 'next');
2169			}
2170		},
2171
2172		// Navigate to previous gallery item
2173		prev: function ( direction ) {
2174			var current = F.current;
2175
2176			if (current) {
2177				if (!isString(direction)) {
2178					direction = current.direction.prev;
2179				}
2180
2181				F.jumpto(current.index - 1, direction, 'prev');
2182			}
2183		},
2184
2185		// Navigate to gallery item by index
2186		jumpto: function ( index, direction, router ) {
2187			var current = F.current;
2188
2189			if (!current) {
2190				return;
2191			}
2192
2193			index = getScalar(index);
2194
2195			F.direction = direction || current.direction[ (index >= current.index ? 'next' : 'prev') ];
2196			F.router    = router || 'jumpto';
2197
2198			if (current.loop) {
2199				if (index < 0) {
2200					index = current.group.length + (index % current.group.length);
2201				}
2202
2203				index = index % current.group.length;
2204			}
2205
2206			if (current.group[ index ] !== undefined) {
2207				F.cancel();
2208
2209				F._start(index);
2210			}
2211		},
2212
2213		// Center inside viewport and toggle position type to fixed or absolute if needed
2214		reposition: function (e, onlyAbsolute) {
2215			var current = F.current,
2216				wrap    = current ? current.wrap : null,
2217				pos;
2218
2219			if (wrap) {
2220				pos = F._getPosition(onlyAbsolute);
2221
2222				if (e && e.type === 'scroll') {
2223					delete pos.position;
2224
2225					wrap.stop(true, true).animate(pos, 200);
2226
2227				} else {
2228					wrap.css(pos);
2229
2230					current.pos = $.extend({}, current.dim, pos);
2231				}
2232			}
2233		},
2234
2235		update: function (e) {
2236			var type = (e && e.type),
2237				anyway = !type || type === 'orientationchange';
2238
2239			if (anyway) {
2240				clearTimeout(didUpdate);
2241
2242				didUpdate = null;
2243			}
2244
2245			if (!F.isOpen || didUpdate) {
2246				return;
2247			}
2248
2249			didUpdate = setTimeout(function() {
2250				var current = F.current;
2251
2252				if (!current || F.isClosing) {
2253					return;
2254				}
2255
2256				F.wrap.removeClass('fancybox-tmp');
2257
2258				if (anyway || type === 'load' || (type === 'resize' && current.autoResize)) {
2259					F._setDimension();
2260				}
2261
2262				if (!(type === 'scroll' && current.canShrink)) {
2263					F.reposition(e);
2264				}
2265
2266				F.trigger('onUpdate');
2267
2268				didUpdate = null;
2269
2270			}, (anyway && !isTouch ? 0 : 300));
2271		},
2272
2273		// Shrink content to fit inside viewport or restore if resized
2274		toggle: function ( action ) {
2275			if (F.isOpen) {
2276				F.current.fitToView = $.type(action) === "boolean" ? action : !F.current.fitToView;
2277
2278				// Help browser to restore document dimensions
2279				if (isTouch) {
2280					F.wrap.removeAttr('style').addClass('fancybox-tmp');
2281
2282					F.trigger('onUpdate');
2283				}
2284
2285				F.update();
2286			}
2287		},
2288
2289		hideLoading: function () {
2290			D.unbind('.loading');
2291
2292			$('#fancybox-loading').remove();
2293		},
2294
2295		showLoading: function () {
2296			var el, viewport;
2297
2298			F.hideLoading();
2299
2300			el = $('<div id="fancybox-loading"><div></div></div>').click(F.cancel).appendTo('body');
2301
2302			// If user will press the escape-button, the request will be canceled
2303			D.bind('keydown.loading', function(e) {
2304				if ((e.which || e.keyCode) === 27) {
2305					e.preventDefault();
2306
2307					F.cancel();
2308				}
2309			});
2310
2311			if (!F.defaults.fixed) {
2312				viewport = F.getViewport();
2313
2314				el.css({
2315					position : 'absolute',
2316					top  : (viewport.h * 0.5) + viewport.y,
2317					left : (viewport.w * 0.5) + viewport.x
2318				});
2319			}
2320		},
2321
2322		getViewport: function () {
2323			var locked = (F.current && F.current.locked) || false,
2324				rez    = {
2325					x: W.scrollLeft(),
2326					y: W.scrollTop()
2327				};
2328
2329			if (locked) {
2330				rez.w = locked[0].clientWidth;
2331				rez.h = locked[0].clientHeight;
2332
2333			} else {
2334				// See http://bugs.jquery.com/ticket/6724
2335				rez.w = isTouch && window.innerWidth  ? window.innerWidth  : W.width();
2336				rez.h = isTouch && window.innerHeight ? window.innerHeight : W.height();
2337			}
2338
2339			return rez;
2340		},
2341
2342		// Unbind the keyboard / clicking actions
2343		unbindEvents: function () {
2344			if (F.wrap && isQuery(F.wrap)) {
2345				F.wrap.unbind('.fb');
2346			}
2347
2348			D.unbind('.fb');
2349			W.unbind('.fb');
2350		},
2351
2352		bindEvents: function () {
2353			var current = F.current,
2354				keys;
2355
2356			if (!current) {
2357				return;
2358			}
2359
2360			// Changing document height on iOS devices triggers a 'resize' event,
2361			// that can change document height... repeating infinitely
2362			W.bind('orientationchange.fb' + (isTouch ? '' : ' resize.fb') + (current.autoCenter && !current.locked ? ' scroll.fb' : ''), F.update);
2363
2364			keys = current.keys;
2365
2366			if (keys) {
2367				D.bind('keydown.fb', function (e) {
2368					var code   = e.which || e.keyCode,
2369						target = e.target || e.srcElement;
2370
2371					// Skip esc key if loading, because showLoading will cancel preloading
2372					if (code === 27 && F.coming) {
2373						return false;
2374					}
2375
2376					// Ignore key combinations and key events within form elements
2377					if (!e.ctrlKey && !e.altKey && !e.shiftKey && !e.metaKey && !(target && (target.type || $(target).is('[contenteditable]')))) {
2378						$.each(keys, function(i, val) {
2379							if (current.group.length > 1 && val[ code ] !== undefined) {
2380								F[ i ]( val[ code ] );
2381
2382								e.preventDefault();
2383								return false;
2384							}
2385
2386							if ($.inArray(code, val) > -1) {
2387								F[ i ] ();
2388
2389								e.preventDefault();
2390								return false;
2391							}
2392						});
2393					}
2394				});
2395			}
2396
2397			if ($.fn.mousewheel && current.mouseWheel) {
2398				F.wrap.bind('mousewheel.fb', function (e, delta, deltaX, deltaY) {
2399					var target = e.target || null,
2400						parent = $(target),
2401						canScroll = false;
2402
2403					while (parent.length) {
2404						if (canScroll || parent.is('.fancybox-skin') || parent.is('.fancybox-wrap')) {
2405							break;
2406						}
2407
2408						canScroll = isScrollable( parent[0] );
2409						parent    = $(parent).parent();
2410					}
2411
2412					if (delta !== 0 && !canScroll) {
2413						if (F.group.length > 1 && !current.canShrink) {
2414							if (deltaY > 0 || deltaX > 0) {
2415								F.prev( deltaY > 0 ? 'down' : 'left' );
2416
2417							} else if (deltaY < 0 || deltaX < 0) {
2418								F.next( deltaY < 0 ? 'up' : 'right' );
2419							}
2420
2421							e.preventDefault();
2422						}
2423					}
2424				});
2425			}
2426		},
2427
2428		trigger: function (event, o) {
2429			var ret, obj = o || F.coming || F.current;
2430
2431			if (!obj) {
2432				return;
2433			}
2434
2435			if ($.isFunction( obj[event] )) {
2436				ret = obj[event].apply(obj, Array.prototype.slice.call(arguments, 1));
2437			}
2438
2439			if (ret === false) {
2440				return false;
2441			}
2442
2443			if (obj.helpers) {
2444				$.each(obj.helpers, function (helper, opts) {
2445					if (opts && F.helpers[helper] && $.isFunction(F.helpers[helper][event])) {
2446						F.helpers[helper][event]($.extend(true, {}, F.helpers[helper].defaults, opts), obj);
2447					}
2448				});
2449			}
2450
2451			D.trigger(event);
2452		},
2453
2454		isImage: function (str) {
2455			return isString(str) && str.match(/(^data:image\/.*,)|(\.(jp(e|g|eg)|gif|png|bmp|webp|svg)((\?|#).*)?$)/i);
2456		},
2457
2458		isSWF: function (str) {
2459			return isString(str) && str.match(/\.(swf)((\?|#).*)?$/i);
2460		},
2461
2462		_start: function (index) {
2463			var coming = {},
2464				obj,
2465				href,
2466				type,
2467				margin,
2468				padding;
2469
2470			index = getScalar( index );
2471			obj   = F.group[ index ] || null;
2472
2473			if (!obj) {
2474				return false;
2475			}
2476
2477			coming = $.extend(true, {}, F.opts, obj);
2478
2479			// Convert margin and padding properties to array - top, right, bottom, left
2480			margin  = coming.margin;
2481			padding = coming.padding;
2482
2483			if ($.type(margin) === 'number') {
2484				coming.margin = [margin, margin, margin, margin];
2485			}
2486
2487			if ($.type(padding) === 'number') {
2488				coming.padding = [padding, padding, padding, padding];
2489			}
2490
2491			// 'modal' propery is just a shortcut
2492			if (coming.modal) {
2493				$.extend(true, coming, {
2494					closeBtn   : false,
2495					closeClick : false,
2496					nextClick  : false,
2497					arrows     : false,
2498					mouseWheel : false,
2499					keys       : null,
2500					helpers: {
2501						overlay : {
2502							closeClick : false
2503						}
2504					}
2505				});
2506			}
2507
2508			// 'autoSize' property is a shortcut, too
2509			if (coming.autoSize) {
2510				coming.autoWidth = coming.autoHeight = true;
2511			}
2512
2513			if (coming.width === 'auto') {
2514				coming.autoWidth = true;
2515			}
2516
2517			if (coming.height === 'auto') {
2518				coming.autoHeight = true;
2519			}
2520
2521			/*
2522			 * Add reference to the group, so it`s possible to access from callbacks, example:
2523			 * afterLoad : function() {
2524			 *     this.title = 'Image ' + (this.index + 1) + ' of ' + this.group.length + (this.title ? ' - ' + this.title : '');
2525			 * }
2526			 */
2527
2528			coming.group  = F.group;
2529			coming.index  = index;
2530
2531			// Give a chance for callback or helpers to update coming item (type, title, etc)
2532			F.coming = coming;
2533
2534			if (false === F.trigger('beforeLoad')) {
2535				F.coming = null;
2536
2537				return;
2538			}
2539
2540			type = coming.type;
2541			href = coming.href;
2542
2543			if (!type) {
2544				F.coming = null;
2545
2546				//If we can not determine content type then drop silently or display next/prev item if looping through gallery
2547				if (F.current && F.router && F.router !== 'jumpto') {
2548					F.current.index = index;
2549
2550					return F[ F.router ]( F.direction );
2551				}
2552
2553				return false;
2554			}
2555
2556			F.isActive = true;
2557
2558			if (type === 'image' || type === 'swf') {
2559				coming.autoHeight = coming.autoWidth = false;
2560				coming.scrolling  = 'visible';
2561			}
2562
2563			if (type === 'image') {
2564				coming.aspectRatio = true;
2565			}
2566
2567			if (type === 'iframe' && isTouch) {
2568				coming.scrolling = 'scroll';
2569			}
2570
2571			// Build the neccessary markup
2572			coming.wrap = $(coming.tpl.wrap).addClass('fancybox-' + (isTouch ? 'mobile' : 'desktop') + ' fancybox-type-' + type + ' fancybox-tmp ' + coming.wrapCSS).appendTo( coming.parent || 'body' );
2573
2574			$.extend(coming, {
2575				skin  : $('.fancybox-skin',  coming.wrap),
2576				outer : $('.fancybox-outer', coming.wrap),
2577				inner : $('.fancybox-inner', coming.wrap)
2578			});
2579
2580			$.each(["Top", "Right", "Bottom", "Left"], function(i, v) {
2581				coming.skin.css('padding' + v, getValue(coming.padding[ i ]));
2582			});
2583
2584			F.trigger('onReady');
2585
2586			// Check before try to load; 'inline' and 'html' types need content, others - href
2587			if (type === 'inline' || type === 'html') {
2588				if (!coming.content || !coming.content.length) {
2589					return F._error( 'content' );
2590				}
2591
2592			} else if (!href) {
2593				return F._error( 'href' );
2594			}
2595
2596			if (type === 'image') {
2597				F._loadImage();
2598
2599			} else if (type === 'ajax') {
2600				F._loadAjax();
2601
2602			} else if (type === 'iframe') {
2603				F._loadIframe();
2604
2605			} else {
2606				F._afterLoad();
2607			}
2608		},
2609
2610		_error: function ( type ) {
2611			$.extend(F.coming, {
2612				type       : 'html',
2613				autoWidth  : true,
2614				autoHeight : true,
2615				minWidth   : 0,
2616				minHeight  : 0,
2617				scrolling  : 'no',
2618				hasError   : type,
2619				content    : F.coming.tpl.error
2620			});
2621
2622			F._afterLoad();
2623		},
2624
2625		_loadImage: function () {
2626			// Reset preload image so it is later possible to check "complete" property
2627			var img = F.imgPreload = new Image();
2628
2629			img.onload = function () {
2630				this.onload = this.onerror = null;
2631
2632				F.coming.width  = this.width / F.opts.pixelRatio;
2633				F.coming.height = this.height / F.opts.pixelRatio;
2634
2635				F._afterLoad();
2636			};
2637
2638			img.onerror = function () {
2639				this.onload = this.onerror = null;
2640
2641				F._error( 'image' );
2642			};
2643
2644			img.src = F.coming.href;
2645
2646			if (img.complete !== true) {
2647				F.showLoading();
2648			}
2649		},
2650
2651		_loadAjax: function () {
2652			var coming = F.coming;
2653
2654			F.showLoading();
2655
2656			F.ajaxLoad = $.ajax($.extend({}, coming.ajax, {
2657				url: coming.href,
2658				error: function (jqXHR, textStatus) {
2659					if (F.coming && textStatus !== 'abort') {
2660						F._error( 'ajax', jqXHR );
2661
2662					} else {
2663						F.hideLoading();
2664					}
2665				},
2666				success: function (data, textStatus) {
2667					if (textStatus === 'success') {
2668						coming.content = data;
2669
2670						F._afterLoad();
2671					}
2672				}
2673			}));
2674		},
2675
2676		_loadIframe: function() {
2677			var coming = F.coming,
2678				iframe = $(coming.tpl.iframe.replace(/\{rnd\}/g, new Date().getTime()))
2679					.attr('scrolling', isTouch ? 'auto' : coming.iframe.scrolling)
2680					.attr('src', coming.href);
2681
2682			// This helps IE
2683			$(coming.wrap).bind('onReset', function () {
2684				try {
2685					$(this).find('iframe').hide().attr('src', '//about:blank').end().empty();
2686				} catch (e) {}
2687			});
2688
2689			if (coming.iframe.preload) {
2690				F.showLoading();
2691
2692				iframe.one('load', function() {
2693					$(this).data('ready', 1);
2694
2695					// iOS will lose scrolling if we resize
2696					if (!isTouch) {
2697						$(this).bind('load.fb', F.update);
2698					}
2699
2700					// Without this trick:
2701					//   - iframe won't scroll on iOS devices
2702					//   - IE7 sometimes displays empty iframe
2703					$(this).parents('.fancybox-wrap').width('100%').removeClass('fancybox-tmp').show();
2704
2705					F._afterLoad();
2706				});
2707			}
2708
2709			coming.content = iframe.appendTo( coming.inner );
2710
2711			if (!coming.iframe.preload) {
2712				F._afterLoad();
2713			}
2714		},
2715
2716		_preloadImages: function() {
2717			var group   = F.group,
2718				current = F.current,
2719				len     = group.length,
2720				cnt     = current.preload ? Math.min(current.preload, len - 1) : 0,
2721				item,
2722				i;
2723
2724			for (i = 1; i <= cnt; i += 1) {
2725				item = group[ (current.index + i ) % len ];
2726
2727				if (item.type === 'image' && item.href) {
2728					new Image().src = item.href;
2729				}
2730			}
2731		},
2732
2733		_afterLoad: function () {
2734			var coming   = F.coming,
2735				previous = F.current,
2736				placeholder = 'fancybox-placeholder',
2737				current,
2738				content,
2739				type,
2740				scrolling,
2741				href,
2742				embed;
2743
2744			F.hideLoading();
2745
2746			if (!coming || F.isActive === false) {
2747				return;
2748			}
2749
2750			if (false === F.trigger('afterLoad', coming, previous)) {
2751				coming.wrap.stop(true).trigger('onReset').remove();
2752
2753				F.coming = null;
2754
2755				return;
2756			}
2757
2758			if (previous) {
2759				F.trigger('beforeChange', previous);
2760
2761				previous.wrap.stop(true).removeClass('fancybox-opened')
2762					.find('.fancybox-item, .fancybox-nav')
2763					.remove();
2764			}
2765
2766			F.unbindEvents();
2767
2768			current   = coming;
2769			content   = coming.content;
2770			type      = coming.type;
2771			scrolling = coming.scrolling;
2772
2773			$.extend(F, {
2774				wrap  : current.wrap,
2775				skin  : current.skin,
2776				outer : current.outer,
2777				inner : current.inner,
2778				current  : current,
2779				previous : previous
2780			});
2781
2782			href = current.href;
2783
2784			switch (type) {
2785				case 'inline':
2786				case 'ajax':
2787				case 'html':
2788					if (current.selector) {
2789						content = $('<div>').html(content).find(current.selector);
2790
2791					} else if (isQuery(content)) {
2792						if (!content.data(placeholder)) {
2793							content.data(placeholder, $('<div class="' + placeholder + '"></div>').insertAfter( content ).hide() );
2794						}
2795
2796						content = content.show().detach();
2797
2798						current.wrap.bind('onReset', function () {
2799							if ($(this).find(content).length) {
2800								content.hide().replaceAll( content.data(placeholder) ).data(placeholder, false);
2801							}
2802						});
2803					}
2804				break;
2805
2806				case 'image':
2807					content = current.tpl.image.replace('{href}', href);
2808				break;
2809
2810				case 'swf':
2811					content = '<object id="fancybox-swf" classid="clsid:D27CDB6E-AE6D-11cf-96B8-444553540000" width="100%" height="100%"><param name="movie" value="' + href + '"></param>';
2812					embed   = '';
2813
2814					$.each(current.swf, function(name, val) {
2815						content += '<param name="' + name + '" value="' + val + '"></param>';
2816						embed   += ' ' + name + '="' + val + '"';
2817					});
2818
2819					content += '<embed src="' + href + '" type="application/x-shockwave-flash" width="100%" height="100%"' + embed + '></embed></object>';
2820				break;
2821			}
2822
2823			if (!(isQuery(content) && content.parent().is(current.inner))) {
2824				current.inner.append( content );
2825			}
2826
2827			// Give a chance for helpers or callbacks to update elements
2828			F.trigger('beforeShow');
2829
2830			// Set scrolling before calculating dimensions
2831			current.inner.css('overflow', scrolling === 'yes' ? 'scroll' : (scrolling === 'no' ? 'hidden' : scrolling));
2832
2833			// Set initial dimensions and start position
2834			F._setDimension();
2835
2836			F.reposition();
2837
2838			F.isOpen = false;
2839			F.coming = null;
2840
2841			F.bindEvents();
2842
2843			if (!F.isOpened) {
2844				$('.fancybox-wrap').not( current.wrap ).stop(true).trigger('onReset').remove();
2845
2846			} else if (previous.prevMethod) {
2847				F.transitions[ previous.prevMethod ]();
2848			}
2849
2850			F.transitions[ F.isOpened ? current.nextMethod : current.openMethod ]();
2851
2852			F._preloadImages();
2853		},
2854
2855		_setDimension: function () {
2856			var viewport   = F.getViewport(),
2857				steps      = 0,
2858				canShrink  = false,
2859				canExpand  = false,
2860				wrap       = F.wrap,
2861				skin       = F.skin,
2862				inner      = F.inner,
2863				current    = F.current,
2864				width      = current.width,
2865				height     = current.height,
2866				minWidth   = current.minWidth,
2867				minHeight  = current.minHeight,
2868				maxWidth   = current.maxWidth,
2869				maxHeight  = current.maxHeight,
2870				scrolling  = current.scrolling,
2871				scrollOut  = current.scrollOutside ? current.scrollbarWidth : 0,
2872				margin     = current.margin,
2873				wMargin    = getScalar(margin[1] + margin[3]),
2874				hMargin    = getScalar(margin[0] + margin[2]),
2875				wPadding,
2876				hPadding,
2877				wSpace,
2878				hSpace,
2879				origWidth,
2880				origHeight,
2881				origMaxWidth,
2882				origMaxHeight,
2883				ratio,
2884				width_,
2885				height_,
2886				maxWidth_,
2887				maxHeight_,
2888				iframe,
2889				body;
2890
2891			// Reset dimensions so we could re-check actual size
2892			wrap.add(skin).add(inner).width('auto').height('auto').removeClass('fancybox-tmp');
2893
2894			wPadding = getScalar(skin.outerWidth(true)  - skin.width());
2895			hPadding = getScalar(skin.outerHeight(true) - skin.height());
2896
2897			// Any space between content and viewport (margin, padding, border, title)
2898			wSpace = wMargin + wPadding;
2899			hSpace = hMargin + hPadding;
2900
2901			origWidth  = isPercentage(width)  ? (viewport.w - wSpace) * getScalar(width)  / 100 : width;
2902			origHeight = isPercentage(height) ? (viewport.h - hSpace) * getScalar(height) / 100 : height;
2903
2904			if (current.type === 'iframe') {
2905				iframe = current.content;
2906
2907				if (current.autoHeight && iframe.data('ready') === 1) {
2908					try {
2909						if (iframe[0].contentWindow.document.location) {
2910							inner.width( origWidth ).height(9999);
2911
2912							body = iframe.contents().find('body');
2913
2914							if (scrollOut) {
2915								body.css('overflow-x', 'hidden');
2916							}
2917
2918							origHeight = body.outerHeight(true);
2919						}
2920
2921					} catch (e) {}
2922				}
2923
2924			} else if (current.autoWidth || current.autoHeight) {
2925				inner.addClass( 'fancybox-tmp' );
2926
2927				// Set width or height in case we need to calculate only one dimension
2928				if (!current.autoWidth) {
2929					inner.width( origWidth );
2930				}
2931
2932				if (!current.autoHeight) {
2933					inner.height( origHeight );
2934				}
2935
2936				if (current.autoWidth) {
2937					origWidth = inner.width();
2938				}
2939
2940				if (current.autoHeight) {
2941					origHeight = inner.height();
2942				}
2943
2944				inner.removeClass( 'fancybox-tmp' );
2945			}
2946
2947			width  = getScalar( origWidth );
2948			height = getScalar( origHeight );
2949
2950			ratio  = origWidth / origHeight;
2951
2952			// Calculations for the content
2953			minWidth  = getScalar(isPercentage(minWidth) ? getScalar(minWidth, 'w') - wSpace : minWidth);
2954			maxWidth  = getScalar(isPercentage(maxWidth) ? getScalar(maxWidth, 'w') - wSpace : maxWidth);
2955
2956			minHeight = getScalar(isPercentage(minHeight) ? getScalar(minHeight, 'h') - hSpace : minHeight);
2957			maxHeight = getScalar(isPercentage(maxHeight) ? getScalar(maxHeight, 'h') - hSpace : maxHeight);
2958
2959			// These will be used to determine if wrap can fit in the viewport
2960			origMaxWidth  = maxWidth;
2961			origMaxHeight = maxHeight;
2962
2963			if (current.fitToView) {
2964				maxWidth  = Math.min(viewport.w - wSpace, maxWidth);
2965				maxHeight = Math.min(viewport.h - hSpace, maxHeight);
2966			}
2967
2968			maxWidth_  = viewport.w - wMargin;
2969			maxHeight_ = viewport.h - hMargin;
2970
2971			if (current.aspectRatio) {
2972				if (width > maxWidth) {
2973					width  = maxWidth;
2974					height = getScalar(width / ratio);
2975				}
2976
2977				if (height > maxHeight) {
2978					height = maxHeight;
2979					width  = getScalar(height * ratio);
2980				}
2981
2982				if (width < minWidth) {
2983					width  = minWidth;
2984					height = getScalar(width / ratio);
2985				}
2986
2987				if (height < minHeight) {
2988					height = minHeight;
2989					width  = getScalar(height * ratio);
2990				}
2991
2992			} else {
2993				width = Math.max(minWidth, Math.min(width, maxWidth));
2994
2995				if (current.autoHeight && current.type !== 'iframe') {
2996					inner.width( width );
2997
2998					height = inner.height();
2999				}
3000
3001				height = Math.max(minHeight, Math.min(height, maxHeight));
3002			}
3003
3004			// Try to fit inside viewport (including the title)
3005			if (current.fitToView) {
3006				inner.width( width ).height( height );
3007
3008				wrap.width( width + wPadding );
3009
3010				// Real wrap dimensions
3011				width_  = wrap.width();
3012				height_ = wrap.height();
3013
3014				if (current.aspectRatio) {
3015					while ((width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight) {
3016						if (steps++ > 19) {
3017							break;
3018						}
3019
3020						height = Math.max(minHeight, Math.min(maxHeight, height - 10));
3021						width  = getScalar(height * ratio);
3022
3023						if (width < minWidth) {
3024							width  = minWidth;
3025							height = getScalar(width / ratio);
3026						}
3027
3028						if (width > maxWidth) {
3029							width  = maxWidth;
3030							height = getScalar(width / ratio);
3031						}
3032
3033						inner.width( width ).height( height );
3034
3035						wrap.width( width + wPadding );
3036
3037						width_  = wrap.width();
3038						height_ = wrap.height();
3039					}
3040
3041				} else {
3042					width  = Math.max(minWidth,  Math.min(width,  width  - (width_  - maxWidth_)));
3043					height = Math.max(minHeight, Math.min(height, height - (height_ - maxHeight_)));
3044				}
3045			}
3046
3047			if (scrollOut && scrolling === 'auto' && height < origHeight && (width + wPadding + scrollOut) < maxWidth_) {
3048				width += scrollOut;
3049			}
3050
3051			inner.width( width ).height( height );
3052
3053			wrap.width( width + wPadding );
3054
3055			width_  = wrap.width();
3056			height_ = wrap.height();
3057
3058			canShrink = (width_ > maxWidth_ || height_ > maxHeight_) && width > minWidth && height > minHeight;
3059			canExpand = current.aspectRatio ? (width < origMaxWidth && height < origMaxHeight && width < origWidth && height < origHeight) : ((width < origMaxWidth || height < origMaxHeight) && (width < origWidth || height < origHeight));
3060
3061			$.extend(current, {
3062				dim : {
3063					width	: getValue( width_ ),
3064					height	: getValue( height_ )
3065				},
3066				origWidth  : origWidth,
3067				origHeight : origHeight,
3068				canShrink  : canShrink,
3069				canExpand  : canExpand,
3070				wPadding   : wPadding,
3071				hPadding   : hPadding,
3072				wrapSpace  : height_ - skin.outerHeight(true),
3073				skinSpace  : skin.height() - height
3074			});
3075
3076			if (!iframe && current.autoHeight && height > minHeight && height < maxHeight && !canExpand) {
3077				inner.height('auto');
3078			}
3079		},
3080
3081		_getPosition: function (onlyAbsolute) {
3082			var current  = F.current,
3083				viewport = F.getViewport(),
3084				margin   = current.margin,
3085				width    = F.wrap.width()  + margin[1] + margin[3],
3086				height   = F.wrap.height() + margin[0] + margin[2],
3087				rez      = {
3088					position: 'absolute',
3089					top  : margin[0],
3090					left : margin[3]
3091				};
3092
3093			if (current.autoCenter && current.fixed && !onlyAbsolute && height <= viewport.h && width <= viewport.w) {
3094				rez.position = 'fixed';
3095
3096			} else if (!current.locked) {
3097				rez.top  += viewport.y;
3098				rez.left += viewport.x;
3099			}
3100
3101			rez.top  = getValue(Math.max(rez.top,  rez.top  + ((viewport.h - height) * current.topRatio)));
3102			rez.left = getValue(Math.max(rez.left, rez.left + ((viewport.w - width)  * current.leftRatio)));
3103
3104			return rez;
3105		},
3106
3107		_afterZoomIn: function () {
3108			var current = F.current;
3109
3110			if (!current) {
3111				return;
3112			}
3113
3114			F.isOpen = F.isOpened = true;
3115
3116			F.wrap.css('overflow', 'visible').addClass('fancybox-opened');
3117
3118			F.update();
3119
3120			// Assign a click event
3121			if ( current.closeClick || (current.nextClick && F.group.length > 1) ) {
3122				F.inner.css('cursor', 'pointer').bind('click.fb', function(e) {
3123					if (!$(e.target).is('a') && !$(e.target).parent().is('a')) {
3124						e.preventDefault();
3125
3126						F[ current.closeClick ? 'close' : 'next' ]();
3127					}
3128				});
3129			}
3130
3131			// Create a close button
3132			if (current.closeBtn) {
3133				$(current.tpl.closeBtn).appendTo(F.skin).bind('click.fb', function(e) {
3134					e.preventDefault();
3135
3136					F.close();
3137				});
3138			}
3139
3140			// Create navigation arrows
3141			if (current.arrows && F.group.length > 1) {
3142				if (current.loop || current.index > 0) {
3143					$(current.tpl.prev).appendTo(F.outer).bind('click.fb', F.prev);
3144				}
3145
3146				if (current.loop || current.index < F.group.length - 1) {
3147					$(current.tpl.next).appendTo(F.outer).bind('click.fb', F.next);
3148				}
3149			}
3150
3151			F.trigger('afterShow');
3152
3153			// Stop the slideshow if this is the last item
3154			if (!current.loop && current.index === current.group.length - 1) {
3155				F.play( false );
3156
3157			} else if (F.opts.autoPlay && !F.player.isActive) {
3158				F.opts.autoPlay = false;
3159
3160				F.play();
3161			}
3162		},
3163
3164		_afterZoomOut: function ( obj ) {
3165			obj = obj || F.current;
3166
3167			$('.fancybox-wrap').trigger('onReset').remove();
3168
3169			$.extend(F, {
3170				group  : {},
3171				opts   : {},
3172				router : false,
3173				current   : null,
3174				isActive  : false,
3175				isOpened  : false,
3176				isOpen    : false,
3177				isClosing : false,
3178				wrap   : null,
3179				skin   : null,
3180				outer  : null,
3181				inner  : null
3182			});
3183
3184			F.trigger('afterClose', obj);
3185		}
3186	});
3187
3188	/*
3189	 *	Default transitions
3190	 */
3191
3192	F.transitions = {
3193		getOrigPosition: function () {
3194			var current  = F.current,
3195				element  = current.element,
3196				orig     = current.orig,
3197				pos      = {},
3198				width    = 50,
3199				height   = 50,
3200				hPadding = current.hPadding,
3201				wPadding = current.wPadding,
3202				viewport = F.getViewport();
3203
3204			if (!orig && current.isDom && element.is(':visible')) {
3205				orig = element.find('img:first');
3206
3207				if (!orig.length) {
3208					orig = element;
3209				}
3210			}
3211
3212			if (isQuery(orig)) {
3213				pos = orig.offset();
3214
3215				if (orig.is('img')) {
3216					width  = orig.outerWidth();
3217					height = orig.outerHeight();
3218				}
3219
3220			} else {
3221				pos.top  = viewport.y + (viewport.h - height) * current.topRatio;
3222				pos.left = viewport.x + (viewport.w - width)  * current.leftRatio;
3223			}
3224
3225			if (F.wrap.css('position') === 'fixed' || current.locked) {
3226				pos.top  -= viewport.y;
3227				pos.left -= viewport.x;
3228			}
3229
3230			pos = {
3231				top     : getValue(pos.top  - hPadding * current.topRatio),
3232				left    : getValue(pos.left - wPadding * current.leftRatio),
3233				width   : getValue(width  + wPadding),
3234				height  : getValue(height + hPadding)
3235			};
3236
3237			return pos;
3238		},
3239
3240		step: function (now, fx) {
3241			var ratio,
3242				padding,
3243				value,
3244				prop       = fx.prop,
3245				current    = F.current,
3246				wrapSpace  = current.wrapSpace,
3247				skinSpace  = current.skinSpace;
3248
3249			if (prop === 'width' || prop === 'height') {
3250				ratio = fx.end === fx.start ? 1 : (now - fx.start) / (fx.end - fx.start);
3251
3252				if (F.isClosing) {
3253					ratio = 1 - ratio;
3254				}
3255
3256				padding = prop === 'width' ? current.wPadding : current.hPadding;
3257				value   = now - padding;
3258
3259				F.skin[ prop ](  getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) ) );
3260				F.inner[ prop ]( getScalar( prop === 'width' ?  value : value - (wrapSpace * ratio) - (skinSpace * ratio) ) );
3261			}
3262		},
3263
3264		zoomIn: function () {
3265			var current  = F.current,
3266				startPos = current.pos,
3267				effect   = current.openEffect,
3268				elastic  = effect === 'elastic',
3269				endPos   = $.extend({opacity : 1}, startPos);
3270
3271			// Remove "position" property that breaks older IE
3272			delete endPos.position;
3273
3274			if (elastic) {
3275				startPos = this.getOrigPosition();
3276
3277				if (current.openOpacity) {
3278					startPos.opacity = 0.1;
3279				}
3280
3281			} else if (effect === 'fade') {
3282				startPos.opacity = 0.1;
3283			}
3284
3285			F.wrap.css(startPos).animate(endPos, {
3286				duration : effect === 'none' ? 0 : current.openSpeed,
3287				easing   : current.openEasing,
3288				step     : elastic ? this.step : null,
3289				complete : F._afterZoomIn
3290			});
3291		},
3292
3293		zoomOut: function () {
3294			var current  = F.current,
3295				effect   = current.closeEffect,
3296				elastic  = effect === 'elastic',
3297				endPos   = {opacity : 0.1};
3298
3299			if (elastic) {
3300				endPos = this.getOrigPosition();
3301
3302				if (current.closeOpacity) {
3303					endPos.opacity = 0.1;
3304				}
3305			}
3306
3307			F.wrap.animate(endPos, {
3308				duration : effect === 'none' ? 0 : current.closeSpeed,
3309				easing   : current.closeEasing,
3310				step     : elastic ? this.step : null,
3311				complete : F._afterZoomOut
3312			});
3313		},
3314
3315		changeIn: function () {
3316			var current   = F.current,
3317				effect    = current.nextEffect,
3318				startPos  = current.pos,
3319				endPos    = { opacity : 1 },
3320				direction = F.direction,
3321				distance  = 200,
3322				field;
3323
3324			startPos.opacity = 0.1;
3325
3326			if (effect === 'elastic') {
3327				field = direction === 'down' || direction === 'up' ? 'top' : 'left';
3328
3329				if (direction === 'down' || direction === 'right') {
3330					startPos[ field ] = getValue(getScalar(startPos[ field ]) - distance);
3331					endPos[ field ]   = '+=' + distance + 'px';
3332
3333				} else {
3334					startPos[ field ] = getValue(getScalar(startPos[ field ]) + distance);
3335					endPos[ field ]   = '-=' + distance + 'px';
3336				}
3337			}
3338
3339			// Workaround for http://bugs.jquery.com/ticket/12273
3340			if (effect === 'none') {
3341				F._afterZoomIn();
3342
3343			} else {
3344				F.wrap.css(startPos).animate(endPos, {
3345					duration : current.nextSpeed,
3346					easing   : current.nextEasing,
3347					complete : F._afterZoomIn
3348				});
3349			}
3350		},
3351
3352		changeOut: function () {
3353			var previous  = F.previous,
3354				effect    = previous.prevEffect,
3355				endPos    = { opacity : 0.1 },
3356				direction = F.direction,
3357				distance  = 200;
3358
3359			if (effect === 'elastic') {
3360				endPos[ direction === 'down' || direction === 'up' ? 'top' : 'left' ] = ( direction === 'up' || direction === 'left' ? '-' : '+' ) + '=' + distance + 'px';
3361			}
3362
3363			previous.wrap.animate(endPos, {
3364				duration : effect === 'none' ? 0 : previous.prevSpeed,
3365				easing   : previous.prevEasing,
3366				complete : function () {
3367					$(this).trigger('onReset').remove();
3368				}
3369			});
3370		}
3371	};
3372
3373	/*
3374	 *	Overlay helper
3375	 */
3376
3377	F.helpers.overlay = {
3378		defaults : {
3379			closeClick : true,      // if true, fancyBox will be closed when user clicks on the overlay
3380			speedOut   : 200,       // duration of fadeOut animation
3381			showEarly  : true,      // indicates if should be opened immediately or wait until the content is ready
3382			css        : {},        // custom CSS properties
3383			locked     : !isTouch,  // if true, the content will be locked into overlay
3384			fixed      : true       // if false, the overlay CSS position property will not be set to "fixed"
3385		},
3386
3387		overlay : null,      // current handle
3388		fixed   : false,     // indicates if the overlay has position "fixed"
3389		el      : $('html'), // element that contains "the lock"
3390
3391		// Public methods
3392		create : function(opts) {
3393			opts = $.extend({}, this.defaults, opts);
3394
3395			if (this.overlay) {
3396				this.close();
3397			}
3398
3399			this.overlay = $('<div class="fancybox-overlay"></div>').appendTo( F.coming ? F.coming.parent : opts.parent );
3400			this.fixed   = false;
3401
3402			if (opts.fixed && F.defaults.fixed) {
3403				this.overlay.addClass('fancybox-overlay-fixed');
3404
3405				this.fixed = true;
3406			}
3407		},
3408
3409		open : function(opts) {
3410			var that = this;
3411
3412			opts = $.extend({}, this.defaults, opts);
3413
3414			if (this.overlay) {
3415				this.overlay.unbind('.overlay').width('auto').height('auto');
3416
3417			} else {
3418				this.create(opts);
3419			}
3420
3421			if (!this.fixed) {
3422				W.bind('resize.overlay', $.proxy( this.update, this) );
3423
3424				this.update();
3425			}
3426
3427			if (opts.closeClick) {
3428				this.overlay.bind('click.overlay', function(e) {
3429					if ($(e.target).hasClass('fancybox-overlay')) {
3430						if (F.isActive) {
3431							F.close();
3432						} else {
3433							that.close();
3434						}
3435
3436						return false;
3437					}
3438				});
3439			}
3440
3441			this.overlay.css( opts.css ).show();
3442		},
3443
3444		close : function() {
3445			var scrollV, scrollH;
3446
3447			W.unbind('resize.overlay');
3448
3449			if (this.el.hasClass('fancybox-lock')) {
3450				$('.fancybox-margin').removeClass('fancybox-margin');
3451
3452				scrollV = W.scrollTop();
3453				scrollH = W.scrollLeft();
3454
3455				this.el.removeClass('fancybox-lock');
3456
3457				W.scrollTop( scrollV ).scrollLeft( scrollH );
3458			}
3459
3460			$('.fancybox-overlay').remove().hide();
3461
3462			$.extend(this, {
3463				overlay : null,
3464				fixed   : false
3465			});
3466		},
3467
3468		// Private, callbacks
3469
3470		update : function () {
3471			var width = '100%', offsetWidth;
3472
3473			// Reset width/height so it will not mess
3474			this.overlay.width(width).height('100%');
3475
3476			// jQuery does not return reliable result for IE
3477			if (IE) {
3478				offsetWidth = Math.max(document.documentElement.offsetWidth, document.body.offsetWidth);
3479
3480				if (D.width() > offsetWidth) {
3481					width = D.width();
3482				}
3483
3484			} else if (D.width() > W.width()) {
3485				width = D.width();
3486			}
3487
3488			this.overlay.width(width).height(D.height());
3489		},
3490
3491		// This is where we can manipulate DOM, because later it would cause iframes to reload
3492		onReady : function (opts, obj) {
3493			var overlay = this.overlay;
3494
3495			$('.fancybox-overlay').stop(true, true);
3496
3497			if (!overlay) {
3498				this.create(opts);
3499			}
3500
3501			if (opts.locked && this.fixed && obj.fixed) {
3502				if (!overlay) {
3503					this.margin = D.height() > W.height() ? $('html').css('margin-right').replace("px", "") : false;
3504				}
3505
3506				obj.locked = this.overlay.append( obj.wrap );
3507				obj.fixed  = false;
3508			}
3509
3510			if (opts.showEarly === true) {
3511				this.beforeShow.apply(this, arguments);
3512			}
3513		},
3514
3515		beforeShow : function(opts, obj) {
3516			var scrollV, scrollH;
3517
3518			if (obj.locked) {
3519				if (this.margin !== false) {
3520					$('*').filter(function(){
3521						return ($(this).css('position') === 'fixed' && !$(this).hasClass("fancybox-overlay") && !$(this).hasClass("fancybox-wrap") );
3522					}).addClass('fancybox-margin');
3523
3524					this.el.addClass('fancybox-margin');
3525				}
3526
3527				scrollV = W.scrollTop();
3528				scrollH = W.scrollLeft();
3529
3530				this.el.addClass('fancybox-lock');
3531
3532				W.scrollTop( scrollV ).scrollLeft( scrollH );
3533			}
3534
3535			this.open(opts);
3536		},
3537
3538		onUpdate : function() {
3539			if (!this.fixed) {
3540				this.update();
3541			}
3542		},
3543
3544		afterClose: function (opts) {
3545			// Remove overlay if exists and fancyBox is not opening
3546			// (e.g., it is not being open using afterClose callback)
3547			//if (this.overlay && !F.isActive) {
3548			if (this.overlay && !F.coming) {
3549				this.overlay.fadeOut(opts.speedOut, $.proxy( this.close, this ));
3550			}
3551		}
3552	};
3553
3554	/*
3555	 *	Title helper
3556	 */
3557
3558	F.helpers.title = {
3559		defaults : {
3560			type     : 'float', // 'float', 'inside', 'outside' or 'over',
3561			position : 'bottom' // 'top' or 'bottom'
3562		},
3563
3564		beforeShow: function (opts) {
3565			var current = F.current,
3566				text    = current.title,
3567				type    = opts.type,
3568				title,
3569				target;
3570
3571			if ($.isFunction(text)) {
3572				text = text.call(current.element, current);
3573			}
3574
3575			if (!isString(text) || $.trim(text) === '') {
3576				return;
3577			}
3578
3579			title = $('<div class="fancybox-title fancybox-title-' + type + '-wrap">
3579' + text + '</div>');
3580
3581			switch (type) {
3582				case 'inside':
3583					target = F.skin;
3584				break;
3585
3586				case 'outside':
3587					target = F.wrap;
3588				break;
3589
3590				case 'over':
3591					target = F.inner;
3592				break;
3593
3594				default: // 'float'
3595					target = F.skin;
3596
3597					title.appendTo('body');
3598
3599					if (IE) {
3600						title.width( title.width() );
3601					}
3602
3603					title.wrapInner('<span class="child"></span>');
3604
3605					//Increase bottom margin so this title will also fit into viewport
3606					F.current.margin[2] += Math.abs( getScalar(title.css('margin-bottom')) );
3607				break;
3608			}
3609
3610			title[ (opts.position === 'top' ? 'prependTo'  : 'appendTo') ](target);
3611		}
3612	};
3613
3614	// jQuery plugin initialization
3615	$.fn.fancybox = function (options) {
3616		var index,
3617			that     = $(this),
3618			selector = this.selector || '',
3619			run      = function(e) {
3620				var what = $(this).blur(), idx = index, relType, relVal;
3621
3622				if (!(e.ctrlKey || e.altKey || e.shiftKey || e.metaKey) && !what.is('.fancybox-wrap')) {
3623					relType = options.groupAttr || 'data-fancybox-group';
3624					relVal  = what.attr(relType);
3625
3626					if (!relVal) {
3627						relType = 'rel';
3628						relVal  = what.get(0)[ relType ];
3629					}
3630
3631					if (relVal && relVal !== '' && relVal !== 'nofollow') {
3632						what = selector.length ? $(selector) : that;
3633						what = what.filter('[' + relType + '="' + relVal + '"]');
3634						idx  = what.index(this);
3635					}
3636
3637					options.index = idx;
3638
3639					// Stop an event from bubbling if everything is fine
3640					if (F.open(what, options) !== false) {
3641						e.preventDefault();
3642					}
3643				}
3644			};
3645
3646		options = options || {};
3647		index   = options.index || 0;
3648
3649		if (!selector || options.live === false) {
3650			that.unbind('click.fb-start').bind('click.fb-start', run);
3651
3652		} else {
3653			D.undelegate(selector, 'click.fb-start').delegate(selector + ":not('.fancybox-item, .fancybox-nav')", 'click.fb-start', run);
3654		}
3655
3656		this.filter('[data-fancybox-start=1]').trigger('click');
3657
3658		return this;
3659	};
3660
3661	// Tests that need a body at doc ready
3662	D.ready(function() {
3663		var w1, w2;
3664
3665		if ( $.scrollbarWidth === undefined ) {
3666			// http://benalman.com/projects/jquery-misc-plugins/#scrollbarwidth
3667			$.scrollbarWidth = function() {
3668				var parent = $('<div style="width:50px;height:50px;overflow:auto"><div/></div>').appendTo('body'),
3669					child  = parent.children(),
3670					width  = child.innerWidth() - child.height( 99 ).innerWidth();
3671
3672				parent.remove();
3673
3674				return width;
3675			};
3676		}
3677
3678		if ( $.support.fixedPosition === undefined ) {
3679			$.support.fixedPosition = (function() {
3680				var elem  = $('<div style="position:fixed;top:20px;"></div>').appendTo('body'),
3681					fixed = ( elem[0].offsetTop === 20 || elem[0].offsetTop === 15 );
3682
3683				elem.remove();
3684
3685				return fixed;
3686			}());
3687		}
3688
3689		$.extend(F.defaults, {
3690			scrollbarWidth : $.scrollbarWidth(),
3691			fixed  : $.support.fixedPosition,
3692			parent : $('body')
3693		});
3694
3695		//Get real width of page scroll-bar
3696		w1 = $(window).width();
3697
3698		H.addClass('fancybox-lock-test');
3699
3700		w2 = $(window).width();
3701
3702		H.removeClass('fancybox-lock-test');
3703
3704		$("<style type='text/css'>.fancybox-margin{margin-right:" + (w2 - w1) + "px;}</style>").appendTo("head");
3705	});
3706
3707}(window, document, jQuery));
3708
3709
3710
3711/*
3712* MIXITUP - A CSS3 and JQuery Filter & Sort Plugin
3713* Version: 1.5.5
3714* License: Creative Commons Attribution-NoDerivs 3.0 Unported - CC BY-ND 3.0
3715* http://creativecommons.org/licenses/by-nd/3.0/
3716* This software may be used freely on commercial and non-commercial projects with attribution to the author/copyright holder.
3717* Author: Patrick Kunka
3718* Copyright 2012-2013 Patrick Kunka, Barrel LLC, All Rights Reserved
3719* 
3720* http://mixitup.io
3721*/
3722
3723(function($){
3724	
3725	// DECLARE METHODS
3726 
3727	var methods = {
3728
3729		// "INIT" METHOD
3730	
3731	    init: function(settings){
3732
3733			return this.each(function(){
3734				
3735				var browser = window.navigator.appVersion.match(/Chrome\/(\d+)\./),
3736					ver = browser ? parseInt(browser[1], 10) : false,
3737					chromeFix = function(id){
3738						var grid = document.getElementById(id),
3739					        parent = grid.parentElement,
3740					        placeholder = document.createElement('div'),
3741					        frag = document.createDocumentFragment();
3742
3743					    parent.insertBefore(placeholder, grid);  
3744					    frag.appendChild(grid);
3745					    parent.replaceChild(grid, placeholder);
3746					    frag = null;
3747					    placeholder = null;
3748					};
3749				
3750				if(ver && ver == 31 || ver == 32){
3751					chromeFix(this.id);
3752				};
3753				
3754				// BUILD CONFIG OBJECT
3755
3756				var config = {
3757					
3758					// PUBLIC PROPERTIES
3759					
3760					targetSelector : '.mix',
3761					filterSelector : '.filter',
3762					sortSelector : '.sort',
3763					buttonEvent: 'click',
3764					effects : ['fade', 'scale'],
3765					listEffects : null,
3766					easing : 'smooth',
3767					layoutMode: 'grid',
3768					targetDisplayGrid : 'inline-block',
3769					targetDisplayList: 'block',
3770					listClass : '',
3771					gridClass : '',
3772					transitionSpeed : 600,
3773					showOnLoad : 'all',
3774					sortOnLoad : false,
3775					multiFilter : false,
3776					filterLogic : 'or',
3777					resizeContainer : true,
3778					minHeight : 0,
3779					failClass : 'fail',
3780					perspectiveDistance : '3000',
3781					perspectiveOrigin : '50% 50%',
3782					animateGridList : true,
3783					onMixLoad: null,
3784					onMixStart : null,
3785					onMixEnd : null,
3786
3787					// MISC
3788
3789					container : null,
3790					origOrder : [],
3791					startOrder : [],
3792					newOrder : [],
3793					origSort: [],
3794					checkSort: [],
3795					filter : '',
3796					mixing : false,
3797					origDisplay : '',
3798					origLayout: '',
3799					origHeight : 0, 
3800					newHeight : 0,
3801					isTouch : false,
3802					resetDelay : 0,
3803					failsafe : null,
3804
3805					// CSS
3806					
3807					prefix : '',
3808					easingFallback : 'ease-in-out',
3809					transition : {}, 
3810					perspective : {}, 
3811					clean : {},
3812					fade : '1',
3813					scale : '',
3814					rotateX : '',
3815					rotateY : '',
3816					rotateZ : '',
3817					blur : '',
3818					grayscale : ''
3819				};
3820				
3821				if(settings){
3822					$.extend(config, settings);
3823				};
3824
3825				// ADD CONFIG OBJECT TO CONTAINER OBJECT PER INSTANTIATION
3826				
3827				this.config = config;
3828				
3829				// DETECT TOUCH
3830				
3831				$.support.touch = 'ontouchend' in document;
3832
3833				if ($.support.touch) {
3834					config.isTouch = true;
3835					config.resetDelay = 350;
3836				};
3837				
3838				// LOCALIZE CONTAINER
3839	
3840				config.container = $(this);
3841				var $cont = config.container;
3842				
3843				// GET VENDOR PREFIX
3844				
3845				config.prefix = prefix($cont[0]);
3846				config.prefix = config.prefix ? '-'+config.prefix.toLowerCase()+'-' : '';
3847				
3848				// CACHE 'DEFAULT' SORTING ORDER
3849			
3850				$cont.find(config.targetSelector).each(function(){
3851					config.origOrder.push($(this));
3852				});
3853				
3854				// PERFORM SORT ON LOAD 
3855				
3856				if(config.sortOnLoad){
3857					var sortby, order;
3858					if($.isArray(config.sortOnLoad)){
3859						sortby = config.sortOnLoad[0], order = config.sortOnLoad[1];
3860						$(config.sortSelector+'[data-sort='+config.sortOnLoad[0]+'][data-order='+config.sortOnLoad[1]+']').addClass('active');
3861					} else {
3862						$(config.sortSelector+'[data-sort='+config.sortOnLoad+']').addClass('active');
3863						sortby = config.sortOnLoad, config.sortOnLoad = 'desc';
3864					};
3865					sort(sortby, order, $cont, config);
3866				};
3867				
3868				// BUILD TRANSITION AND PERSPECTIVE OBJECTS
3869				
3870				for(var i = 0; i<2; i++){
3871					var a = i==0 ? a = config.prefix : '';
3872					config.transition[a+'transition'] = 'all '+config.transitionSpeed+'ms ease-in-out';
3873					config.perspective[a+'perspective'] = config.perspectiveDistance+'px';
3874					config.perspective[a+'perspective-origin'] = config.perspectiveOrigin;
3875				};
3876				
3877				// BUILD TRANSITION CLEANER
3878				
3879				for(var i = 0; i<2; i++){
3880					var a = i==0 ? a = config.prefix : '';
3881					config.clean[a+'transition'] = 'none';
3882				};
3883	
3884				// CHOOSE GRID OR LIST
3885	
3886				if(config.layoutMode == 'list'){
3887					$cont.addClass(config.listClass);
3888					config.origDisplay = config.targetDisplayList;
3889				} else {
3890					$cont.addClass(config.gridClass);
3891					config.origDisplay = config.targetDisplayGrid;
3892				};
3893				config.origLayout = config.layoutMode;
3894				
3895				// PARSE 'SHOWONLOAD'
3896				
3897				var showOnLoadArray = config.showOnLoad.split(' ');
3898				
3899				// GIVE ACTIVE FILTER ACTIVE CLASS
3900				
3901				$.each(showOnLoadArray, function(){
3902					$(config.filterSelector+'[data-filter="'+this+'"]').addClass('active');
3903				});
3904				
3905				// RENAME "ALL" CATEGORY TO "MIX_ALL"
3906	
3907				$cont.find(config.targetSelector).addClass('mix_all');
3908				if(showOnLoadArray[0]  == 'all'){
3909					showOnLoadArray[0] = 'mix_all',
3910					config.showOnLoad = 'mix_all';
3911				};
3912				
3913				// FADE IN 'SHOWONLOAD'
3914				
3915				var $showOnLoad = $();
3916				$.each(showOnLoadArray, function(){
3917					$showOnLoad = $showOnLoad.add($('.'+this))
3918				});
3919				
3920				$showOnLoad.each(function(){
3921					var $t = $(this);
3922					if(config.layoutMode == 'list'){
3923						$t.css('display',config.targetDisplayList);
3924					} else {
3925						$t.css('display',config.targetDisplayGrid);
3926					};
3927					$t.css(config.transition);
3928				});
3929				
3930				// WRAP FADE-IN TO PREVENT RACE CONDITION
3931				
3932				var delay = setTimeout(function(){
3933					
3934					config.mixing = true;
3935					
3936					$showOnLoad.css('opacity','1');
3937					
3938					// CLEAN UP
3939					
3940					var reset = setTimeout(function(){
3941						if(config.layoutMode == 'list'){
3942							$showOnLoad.removeStyle(config.prefix+'transition, transition').css({
3943								display: config.targetDisplayList,
3944								opacity: 1
3945							});
3946						} else {
3947							$showOnLoad.removeStyle(config.prefix+'transition, transition').css({
3948								display: config.targetDisplayGrid,
3949								opacity: 1
3950							});
3951						};
3952						
3953						// FIRE "ONMIXLOAD" CALLBACK
3954						
3955						config.mixing = false;
3956
3957						if(typeof config.onMixLoad == 'function') {
3958							var output = config.onMixLoad.call(this, config);
3959
3960							// UPDATE CONFIG IF DATA RETURNED
3961
3962							config = output ? output : config;
3963						};
3964						
3965					},config.transitionSpeed);
3966				},10);
3967				
3968				// PRESET ACTIVE FILTER
3969				
3970				config.filter = config.showOnLoad;
3971			
3972				// BIND SORT CLICK HANDLERS
3973			
3974				$(config.sortSelector).bind(config.buttonEvent,function(){
3975					
3976					if(!config.mixing){
3977						
3978						// PARSE SORT ARGUMENTS FROM BUTTON CLASSES
3979						
3980						var $t = $(this),
3981						sortby = $t.attr('data-sort'),
3982						order = $t.attr('data-order');
3983						
3984						if(!$t.hasClass('active')){
3985							$(config.sortSelector).removeClass('active');
3986							$t.addClass('active');
3987						} else {
3988							if(sortby != 'random')return false;
3989						};
3990						
3991						$cont.find(config.targetSelector).each(function(){
3992							config.startOrder.push($(this));
3993						});
3994				
3995						goMix(config.filter,sortby,order,$cont, config);
3996				
3997					};
3998				
3999				});
4000
4001				// BIND FILTER CLICK HANDLERS
4002
4003				$(config.filterSelector).bind(config.buttonEvent,function(){
4004				
4005					if(!config.mixing){
4006						
4007						var $t = $(this);
4008						
4009						// PARSE FILTER ARGUMENTS FROM BUTTON CLASSES
4010		
4011						if(config.multiFilter == false){
4012							
4013							// SINGLE ACTIVE BUTTON
4014							
4015							$(config.filterSelector).removeClass('active');
4016							$t.addClass('active');
4017						
4018							config.filter = $t.attr('data-filter');
4019						
4020							$(config.filterSelector+'[data-filter="'+config.filter+'"]').addClass('active');
4021
4022						} else {
4023						
4024							// MULTIPLE ACTIVE BUTTONS
4025							
4026							var thisFilter = $t.attr('data-filter'); 
4027						
4028							if($t.hasClass('active')){
4029								$t.removeClass('active');
4030								
4031								// REMOVE FILTER FROM SPACE-SEPERATED STRING
4032								
4033								var re = new RegExp('(\\s|^)'+thisFilter);
4034								config.filter = config.filter.replace(re,'');
4035							} else {
4036								
4037								// ADD FILTER TO SPACE-SEPERATED STRING
4038								
4039								$t.addClass('active');
4040								config.filter = config.filter+' '+thisFilter;
4041								
4042							};
4043						};
4044						
4045						// GO MIX
4046						
4047						goMix(config.filter, null, null, $cont, config);
4048
4049					};
4050				
4051				});
4052					
4053			});
4054		},
4055	
4056		// "TOGRID" METHOD
4057	
4058		toGrid: function(){
4059			return this.each(function(){
4060				var config = this.config;
4061				if(config.layoutMode != 'grid'){
4062					config.layoutMode = 'grid';
4063					goMix(config.filter, null, null, $(this), config);
4064				};
4065			});
4066		},
4067	
4068		// "TOLIST" METHOD
4069	
4070		toList: function(){
4071			return this.each(function(){
4072				var config = this.config;
4073				if(config.layoutMode != 'list'){
4074					config.layoutMode = 'list';
4075					goMix(config.filter, null, null, $(this), config);
4076				};
4077			});
4078		},
4079	
4080		// "FILTER" METHOD
4081	
4082		filter: function(arg){
4083			return this.each(function(){
4084				var config = this.config;
4085				if(!config.mixing){	
4086					$(config.filterSelector).removeClass('active');
4087					$(config.filterSelector+'[data-filter="'+arg+'"]').addClass('active');
4088					goMix(arg, null, null, $(this), config);
4089				};
4090			});	
4091		},
4092	
4093		// "SORT" METHOD
4094	
4095		sort: function(args){
4096			return this.each(function(){
4097				var config = this.config,
4098					$t = $(this);
4099				if(!config.mixing){
4100					$(config.sortSelector).removeClass('active');
4101					if($.isArray(args)){
4102						var sortby = args[0], order = args[1];
4103						$(config.sortSelector+'[data-sort="'+args[0]+'"][data-order="'+args[1]+'"]').addClass('active');
4104					} else {
4105						$(config.sortSelector+'[data-sort="'+args+'"]').addClass('active');
4106						var sortby = args, order = 'desc';
4107					};
4108					$t.find(config.targetSelector).each(function(){
4109						config.startOrder.push($(this));
4110					});
4111					
4112					goMix(config.filter,sortby,order, $t, config);
4113				
4114				};
4115			});
4116		},
4117		
4118		// "MULTIMIX" METHOD
4119		
4120		multimix: function(args){
4121			return this.each(function(){
4122				var config = this.config,
4123					$t = $(this);
4124					multiOut = {
4125						filter: config.filter,
4126						sort: null,
4127						order: 'desc',
4128						layoutMode: config.layoutMode
4129					};
4130				$.extend(multiOut, args);
4131				if(!config.mixing){
4132					$(config.filterSelector).add(config.sortSelector).removeClass('active');
4133					$(config.filterSelector+'[data-filter="'+multiOut.filter+'"]').addClass('active');
4134					if(typeof multiOut.sort !== 'undefined'){
4135						$(config.sortSelector+'[data-sort="'+multiOut.sort+'"][data-order="'+multiOut.order+'"]').addClass('active');
4136						$t.find(config.targetSelector).each(function(){
4137							config.startOrder.push($(this));
4138						});
4139					};
4140					config.layoutMode = multiOut.layoutMode;
4141					goMix(multiOut.filter,multiOut.sort,multiOut.order, $t, config);
4142				};
4143			});
4144		},
4145		
4146		// "REMIX" METHOD
4147
4148		remix: function(arg){
4149			return this.each(function(){
4150				var config = this.config,
4151					$t = $(this);	
4152				config.origOrder = [];
4153				$t.find(config.targetSelector).each(function(){
4154					var $th = $(this);
4155					$th.addClass('mix_all'); 
4156				    config.origOrder.push($th);
4157				});
4158				if(!config.mixing && typeof arg !== 'undefined'){
4159					$(config.filterSelector).removeClass('active');
4160					$(config.filterSelector+'[data-filter="'+arg+'"]').addClass('active');
4161					goMix(arg, null, null, $t, config);
4162				};
4163			});
4164		}
4165	};
4166	
4167	// DECLARE PLUGIN
4168
4169	$.fn.mixitup = function(method, arg){
4170		if (methods[method]) {
4171			return methods[method].apply( this, Array.prototype.slice.call(arguments,1));
4172		} else if (typeof method === 'object' || ! method){
4173			return methods.init.apply( this, arguments );
4174		};
4175	};
4176	
4177	/* ==== THE MAGIC ==== */
4178	
4179	function goMix(filter, sortby, order, $cont, config){
4180		
4181		// WE ARE NOW MIXING
4182
4183		clearInterval(config.failsafe);
4184		config.mixing = true;	
4185		
4186		// APPLY ARGS TO CONFIG
4187		
4188		config.filter = filter;
4189		
4190		// FIRE "ONMIXSTART" CALLBACK
4191		
4192		if(typeof config.onMixStart == 'function') {
4193			var output = config.onMixStart.call(this, config);
4194			
4195			// UPDATE CONFIG IF DATA RETURNED
4196			
4197			config = output ? output : config;
4198		};
4199		
4200		// SHORT LOCAL VARS
4201		
4202		var speed = config.transitionSpeed;
4203		
4204		// REBUILD TRANSITION AND PERSPECTIVE OBJECTS
4205		
4206		for(var i = 0; i<2; i++){
4207			var a = i==0 ? a = config.prefix : '';
4208			config.transition[a+'transition'] = 'all '+speed+'ms linear';
4209			config.transition[a+'transform'] = a+'translate3d(0,0,0)';
4210			config.perspective[a+'perspective'] = config.perspectiveDistance+'px';
4211			config.perspective[a+'perspective-origin'] = config.perspectiveOrigin;
4212		};
4213		
4214		// CACHE TARGET ELEMENTS FOR QUICK ACCESS
4215		
4216		var mixSelector = config.targetSelector,
4217		$targets = $cont.find(mixSelector);
4218		
4219		// ADD DATA OBJECT TO EACH TARGET
4220		
4221		$targets.each(function(){
4222			this.data = {};
4223		});
4224		
4225		// RE-DEFINE CONTAINER INCASE NOT IMMEDIATE PARENT OF TARGET ELEMENTS 
4226		
4227		var $par = $targets.parent();
4228	
4229		// ADD PERSPECTIVE TO CONTAINER 
4230		
4231		$par.css(config.perspective);
4232		
4233		// SETUP EASING
4234
4235		config.easingFallback = 'ease-in-out';
4236		if(config.easing == 'smooth')config.easing = 'cubic-bezier(0.25, 0.46, 0.45, 0.94)';
4237		if(config.easing == 'snap')config.easing = 'cubic-bezier(0.77, 0, 0.175, 1)';
4238		if(config.easing == 'windback'){
4239			config.easing = 'cubic-bezier(0.175, 0.885, 0.320, 1.275)',
4240			config.easingFallback = 'cubic-bezier(0.175, 0.885, 0.320, 1)'; // Fall-back for old webkit, with no values > 1 or < 1
4241		};
4242		if(config.easing == 'windup'){
4243			config.easing = 'cubic-bezier(0.6, -0.28, 0.735, 0.045)',
4244			config.easingFallback = 'cubic-bezier(0.6, 0.28, 0.735, 0.045)';
4245		};
4246		
4247		// USE LIST SPECIFIC EFFECTS IF DECLARED
4248		
4249		var effectsOut = config.layoutMode == 'list' && config.listEffects != null ? config.listEffects : config.effects;
4250	
4251		// BUILD EFFECTS STRINGS & SKIP IF IE8
4252	
4253		if (Array.prototype.indexOf){
4254			config.fade = effectsOut.indexOf('fade') > -1 ? '0' : '';
4255			config.scale = effectsOut.indexOf('scale') > -1 ? 'scale(.01)' : '';
4256			config.rotateZ = effectsOut.indexOf('rotateZ') > -1 ? 'rotate(180deg)' : '';
4257			config.rotateY = effectsOut.indexOf('rotateY') > -1 ? 'rotateY(90deg)' : '';
4258			config.rotateX = effectsOut.indexOf('rotateX') > -1 ? 'rotateX(90deg)' : '';
4259			config.blur = effectsOut.indexOf('blur') > -1 ? 'blur(8px)' : '';
4260			config.grayscale = effectsOut.indexOf('grayscale') > -1 ? 'grayscale(100%)' : '';
4261		};
4262		
4263		// DECLARE NEW JQUERY OBJECTS FOR GROUPING
4264		
4265		var $show = $(), 
4266		$hide = $(),
4267		filterArray = [],
4268		multiDimensional = false;
4269		
4270		// BUILD FILTER ARRAY(S)
4271		
4272		if(typeof filter === 'string'){
4273			
4274			// SINGLE DIMENSIONAL FILTERING
4275			
4276			filterArray = buildFilterArray(filter);
4277			
4278		} else {
4279			
4280			// MULTI DIMENSIONAL FILTERING
4281			
4282			multiDimensional = true;
4283			
4284			$.each(filter,function(i){
4285				filterArray[i] = buildFilterArray(this);
4286			});
4287		};
4288
4289		// "OR" LOGIC (DEFAULT)
4290		
4291		if(config.filterLogic == 'or'){
4292			
4293			if(filterArray[0] == '') filterArray.shift(); // IF FIRST ITEM IN ARRAY IS AN EMPTY SPACE, DELETE
4294			
4295			// IF NO ELEMENTS ARE DESIRED THEN HIDE ALL VISIBLE ELEMENTS
4296		
4297			if(filterArray.length < 1){
4298				
4299				$hide = $hide.add($cont.find(mixSelector+':visible'));
4300				
4301			} else {
4302
4303			// ELSE CHECK EACH TARGET ELEMENT FOR ANY FILTER CATEGORY:
4304			
4305				$targets.each(function(){
4306					var $t = $(this);
4307					if(!multiDimensional){
4308						// IF HAS ANY FILTER, ADD TO "SHOW" OBJECT
4309						if($t.is('.'+filterArray.join(', .'))){
4310							$show = $show.add($t);
4311						// ELSE IF HAS NO FILTERS, ADD TO "HIDE" OBJECT
4312						} else {
4313							$hide = $hide.add($t);
4314						};
4315					} else {
4316						
4317						var pass = 0;
4318						// FOR EACH DIMENSION
4319						
4320						$.each(filterArray,function(i){
4321							if(this.length){
4322								if($t.is('.'+this.join(', .'))){
4323									pass++
4324								};
4325							} else if(pass > 0){
4326								pass++;
4327							};
4328						});
4329						// IF PASSES ALL DIMENSIONS, SHOW
4330						if(pass == filterArray.length){
4331							$show = $show.add($t);
4332						// ELSE HIDE
4333						} else {
4334							$hide = $hide.add($t);
4335						};
4336					};
4337				});
4338			
4339			};
4340	
4341		} else {
4342			
4343		// "AND" LOGIC
4344			
4345			// ADD "MIX_SHOW" CLASS TO ELEMENTS THAT HAVE ALL FILTERS
4346			
4347			$show = $show.add($par.find(mixSelector+'.'+filterArray.join('.')));
4348			
4349			// ADD "MIX_HIDE" CLASS TO EVERYTHING ELSE
4350			
4351			$hide = $hide.add($par.find(mixSelector+':not(.'+filterArray.join('.')+'):visible'));
4352		};
4353		
4354		// GET TOTAL NUMBER OF ELEMENTS TO SHOW
4355		
4356		var total = $show.length;
4357		
4358		// DECLARE NEW JQUERY OBJECTS
4359
4360		var $tohide = $(),
4361		$toshow = $(),
4362		$pre = $();
4363		
4364		// FOR ELEMENTS TO BE HIDDEN, IF NOT ALREADY HIDDEN THEN ADD TO OBJECTS "TOHIDE" AND "PRE" 
4365		// TO INDICATE PRE-EXISTING ELEMENTS TO BE HIDDEN
4366		
4367		$hide.each(function(){
4368			var $t = $(this);
4369			if($t.css('display') != 'none'){
4370				$tohide = $tohide.add($t);
4371				$pre = $pre.add($t);
4372			};
4373		});
4374		
4375		// IF ALL ELEMENTS ARE ALREADY SHOWN AND THERE IS NOTHING TO HIDE, AND NOT PERFORMING A LAYOUT CHANGE OR SORT:
4376		
4377		if($show.filter(':visible').length == total && !$tohide.length && !sortby){
4378			
4379			if(config.origLayout == config.layoutMode){
4380				
4381				// THEN CLEAN UP AND GO HOME
4382
4383				resetFilter();
4384				return false;
4385			} else {
4386				
4387				// IF ONLY ONE ITEM AND CHANGING FORM GRID TO LIST, MOST LIKELY POSITION WILL NOT CHANGE SO WE'RE DONE
4388			
4389				if($show.length == 1){ 
4390					
4391					if(config.layoutMode == 'list'){ 
4392						$cont.addClass(config.listClass);
4393						$cont.removeClass(config.gridClass);
4394						$pre.css('display',config.targetDisplayList);
4395					} else {
4396						$cont.addClass(config.gridClass);
4397						$cont.removeClass(config.listClass);
4398						$pre.css('display',config.targetDisplayGrid);
4399					};
4400					
4401					// THEN CLEAN UP AND GO HOME
4402
4403					resetFilter();
4404					return false;
4405				}
4406			};
4407		};
4408		
4409		// GET CONTAINER'S STARTING HEIGHT
4410
4411		config.origHeight = $par.height();
4412		
4413		// IF THERE IS SOMETHING TO BE SHOWN:
4414
4415		if($show.length){
4416			
4417			// REMOVE "FAIL CLASS" FROM CONTAINER IF EXISTS
4418			
4419			$cont.removeClass(config.failClass);
4420			
4421			
4422			// FOR ELEMENTS TO BE SHOWN, IF NOT ALREADY SHOWN THEN ADD TO OBJECTS "TOSHOW" ELSE ADD CLASS "MIX_PRE"
4423			// TO INDICATE PRE-EXISTING ELEMENT
4424
4425			$show.each(function(){ 
4426				var $t = $(this);
4427				if($t.css('display') == 'none'){
4428					$toshow = $toshow.add($t)
4429				} else {
4430					$pre = $pre.add($t);
4431				};
4432			});
4433	
4434			// IF NON-ANIMATED LAYOUT MODE TRANSITION:
4435		
4436			if((config.origLayout != config.layoutMode) && config.animateGridList == false){ 
4437			
4438				// ADD NEW DISPLAY TYPES, CLEAN UP AND GO HOME
4439				
4440				if(config.layoutMode == 'list'){ 
4441					$cont.addClass(config.listClass);
4442					$cont.removeClass(config.gridClass);
4443					$pre.css('display',config.targetDisplayList);
4444				} else {
4445					$cont.addClass(config.gridClass);
4446					$cont.removeClass(config.listClass);
4447					$pre.css('display',config.targetDisplayGrid);
4448				};
4449				
4450				resetFilter();
4451				return false;
4452			};
4453			
4454			// IF IE, FUCK OFF, AND THEN CLEAN UP AND GO HOME
4455		
4456			if(!window.atob){
4457				resetFilter();
4458				return false;
4459			};
4460			
4461			// OVERRIDE ANY EXISTING TRANSITION TIMING FOR CALCULATIONS
4462			
4463			$targets.css(config.clean);
4464			
4465			// FOR EACH PRE-EXISTING ELEMENT, ADD STARTING POSITION TO 'ORIGPOS' ARRAY
4466			
4467			$pre.each(function(){
4468				this.data.origPos = $(this).offset();
4469			});
4470	
4471			// TEMPORARILY SHOW ALL ELEMENTS TO SHOW (THAT ARE NOT ALREADY SHOWN), WITHOUT HIDING ELEMENTS TO HIDE
4472			// AND ADD/REMOVE GRID AND LIST CLASSES FROM CONTAINER
4473	
4474			if(config.layoutMode == 'list'){
4475				$cont.addClass(config.listClass);
4476				$cont.removeClass(config.gridClass);
4477				$toshow.css('display',config.targetDisplayList);
4478			} else {
4479				$cont.addClass(config.gridClass);
4480				$cont.removeClass(config.listClass);
4481				$toshow.css('display',config.targetDisplayGrid);
4482			};
4483			
4484			// FOR EACH ELEMENT NOW SHOWN, ADD ITS INTERMEDIATE POSITION TO 'SHOWINTERPOS' ARRAY
4485	
4486			$toshow.each(function(){
4487				this.data.showInterPos = $(this).offset();
4488			});
4489			
4490			// FOR EACH ELEMENT TO BE HIDDEN, BUT NOT YET HIDDEN, AND NOW MOVED DUE TO SHOWN ELEMENTS,
4491			// ADD ITS INTERMEDIATE POSITION TO 'HIDEINTERPOS' ARRAY
4492
4493			$tohide.each(function(){
4494				this.data.hideInterPos = $(this).offset();
4495			});
4496			
4497			// FOR EACH PRE-EXISTING ELEMENT, NOW MOVED DUE TO SHOWN ELEMENTS, ADD ITS POSITION TO 'PREINTERPOS' ARRAY
4498	
4499			$pre.each(function(){
4500				this.data.preInterPos = $(this).offset();
4501			});
4502			
4503			// SET DISPLAY PROPERTY OF PRE-EXISTING ELEMENTS INCASE WE ARE CHANGING LAYOUT MODE
4504	
4505			if(config.layoutMode == 'list'){
4506				$pre.css('display',config.targetDisplayList);
4507			} else {
4508				$pre.css('display',config.targetDisplayGrid);
4509			};
4510			
4511			// IF A SORT ARGUMENT HAS BEEN SENT, RUN SORT FUNCTION SO OBJECTS WILL MOVE TO THEIR FINAL ORDER
4512			
4513			if(sortby){
4514				sort(sortby, order, $cont, config);	
4515			};
4516			
4517			// IF VISIBLE SORT ORDER IS THE SAME (WHICH WOULD NOT TRIGGER A TRANSITION EVENT)
4518		
4519			if(sortby && compareArr(config.origSort, config.checkSort)){
4520				
4521				// THEN CLEAN UP AND GO HOME
4522				resetFilter();
4523				return false;
4524			};
4525			
4526			// TEMPORARILY HIDE ALL SHOWN ELEMENTS TO HIDE
4527
4528			$tohide.hide();
4529			
4530			// FOR EACH ELEMENT TO SHOW, AND NOW MOVED DUE TO HIDDEN ELEMENTS BEING REMOVED, 
4531			// ADD ITS POSITION TO 'FINALPOS' ARRAY
4532			
4533			$toshow.each(function(i){
4534				this.data.finalPos = $(this).offset();
4535			});
4536			
4537			// FOR EACH PRE-EXISTING ELEMENT NOW MOVED DUE TO HIDDEN ELEMENTS BEING REMOVED,
4538			// ADD ITS POSITION TO 'FINALPREPOS' ARRAY
4539	
4540			$pre.each(function(){
4541				this.data.finalPrePos = $(this).offset();
4542			});
4543			
4544			// SINCE WE ARE IN OUT FINAL STATE, GET NEW HEIGHT OF CONTAINER
4545	
4546			config.newHeight = $par.height();
4547			
4548			// IF A SORT ARGUMENT AS BEEN SENT, RUN SORT FUNCTION 'RESET' TO MOVE ELEMENTS BACK TO THEIR STARTING ORDER
4549			
4550			if(sortby){
4551				sort('reset', null, $cont, config);
4552			};
4553			
4554			// RE-HIDE ALL ELEMENTS TEMPORARILY SHOWN
4555			
4556			$toshow.hide();
4557			
4558			// SET DISPLAY PROPERTY OF PRE-EXISTING ELEMENTS BACK TO THEIR 
4559			// ORIGINAL PROPERTY, INCASE WE ARE CHANGING LAYOUT MODE
4560			
4561			$pre.css('display',config.origDisplay);
4562			
4563			// ADD/REMOVE GRID AND LIST CLASSES FROM CONTAINER
4564	
4565			if(config.origDisplay == 'block'){
4566				$cont.addClass(config.listClass);
4567				$toshow.css('display', config.targetDisplayList);
4568			} else {
4569				$cont.removeClass(config.listClass);
4570				$toshow.css('display', config.targetDisplayGrid);
4571			};
4572			
4573			// IF WE ARE ANIMATING CONTAINER, RESET IT TO ITS STARTING HEIGHT
4574		
4575			if(config.resizeContainer)$par.css('height', config.origHeight+'px');
4576	
4577			// ADD TRANSFORMS TO ALL ELEMENTS TO SHOW
4578			
4579			var toShowCSS = {};
4580			
4581			for(var i = 0; i<2; i++){
4582				var a = i==0 ? a = config.prefix : '';
4583				toShowCSS[a+'transform'] = config.scale+' '+config.rotateX+' '+config.rotateY+' '+config.rotateZ;
4584				toShowCSS[a+'filter'] = config.blur+' '+config.grayscale;
4585			};
4586			
4587			$toshow.css(toShowCSS);
4588	
4589			// FOR EACH PRE-EXISTING ELEMENT, SUBTRACT ITS INTERMEDIATE POSITION FROM ITS ORIGINAL POSITION 
4590			// TO GET ITS STARTING OFFSET
4591	
4592			$pre.each(function(){
4593				var data = this.data,
4594				$t = $(this);
4595				
4596				if ($t.hasClass('mix_tohide')){
4597					data.preTX = data.origPos.left - data.hideInterPos.left;
4598					data.preTY = data.origPos.top - data.hideInterPos.top;
4599				} else {
4600					data.preTX = data.origPos.left - data.preInterPos.left;
4601					data.preTY = data.origPos.top - data.preInterPos.top;
4602				};
4603				var preCSS = {};
4604				for(var i = 0; i<2; i++){
4605					var a = i==0 ? a = config.prefix : '';
4606					preCSS[a+'transform'] = 'translate('+data.preTX+'px,'+data.preTY+'px)';
4607				};
4608				
4609				$t.css(preCSS);	
4610			});
4611			
4612			// ADD/REMOVE GRID AND LIST CLASSES FROM CONTAINER
4613	
4614			if(config.layoutMode == 'list'){
4615				$cont.addClass(config.listClass);
4616				$cont.removeClass(config.gridClass);
4617			} else {
4618				$cont.addClass(config.gridClass);
4619				$cont.removeClass(config.listClass);
4620			};
4621			
4622			// WRAP ANIMATION FUNCTIONS IN 10ms TIMEOUT TO PREVENT RACE CONDITION
4623			
4624			var delay = setTimeout(function(){
4625		
4626				// APPLY TRANSITION TIMING TO CONTAINER, AND BEGIN ANIMATION TO NEW HEIGHT
4627				
4628				if(config.resizeContainer){
4629					var containerCSS = {};
4630					for(var i = 0; i<2; i++){
4631						var a = i==0 ? a = config.prefix : '';
4632						containerCSS[a+'transition'] = 'all '+speed+'ms ease-in-out';
4633						containerCSS['height'] = config.newHeight+'px';
4634					};
4635					$par.css(containerCSS);
4636				};
4637	
4638				// BEGIN FADING IN/OUT OF ALL ELEMENTS TO SHOW/HIDE
4639				$tohide.css('opacity',config.fade);
4640				$toshow.css('opacity',1);
4641	
4642				// FOR EACH ELEMENT BEING SHOWN, CALCULATE ITS TRAJECTORY BY SUBTRACTING
4643				// ITS INTERMEDIATE POSITION FROM ITS FINAL POSITION.
4644				// ALSO ADD SPEED AND EASING
4645				
4646				$toshow.each(function(){
4647					var data = this.data;
4648					data.tX = data.finalPos.left - data.showInterPos.left;
4649					data.tY = data.finalPos.top - data.showInterPos.top;
4650					
4651					var toShowCSS = {};
4652					for(var i = 0; i<2; i++){
4653						var a = i==0 ? a = config.prefix : '';
4654						toShowCSS[a+'transition-property'] = a+'transform, '+a+'filter, opacity';
4655						toShowCSS[a+'transition-timing-function'] = config.easing+', linear, linear';
4656						toShowCSS[a+'transition-duration'] = speed+'ms';
4657						toShowCSS[a+'transition-delay'] = '0';
4658						toShowCSS[a+'transform'] = 'translate('+data.tX+'px,'+data.tY+'px)';
4659						toShowCSS[a+'filter'] = 'none';
4660					};
4661					
4662					$(this).css('-webkit-transition', 'all '+speed+'ms '+config.easingFallback).css(toS
4662howCSS);
4663				});
4664				
4665				// FOR EACH PRE-EXISTING ELEMENT, IF IT HAS A FINAL POSITION, CALCULATE 
4666				// ITS TRAJETORY BY SUBTRACTING ITS INTERMEDIATE POSITION FROM ITS FINAL POSITION.
4667				// ALSO ADD SPEED AND EASING
4668				
4669				$pre.each(function(){
4670					var data = this.data
4671					data.tX = data.finalPrePos.left != 0 ? data.finalPrePos.left - data.preInterPos.left : 0;
4672					data.tY = data.finalPrePos.left != 0 ? data.finalPrePos.top - data.preInterPos.top : 0;
4673					
4674					var preCSS = {};
4675					for(var i = 0; i<2; i++){
4676						var a = i==0 ? a = config.prefix : '';
4677						preCSS[a+'transition'] = 'all '+speed+'ms '+config.easing;
4678						preCSS[a+'transform'] = 'translate('+data.tX+'px,'+data.tY+'px)';
4679					};
4680					
4681					$(this).css('-webkit-transition', 'all '+speed+'ms '+config.easingFallback).css(preCSS);
4682				});
4683		
4684				// BEGIN TRANSFORMS ON ALL ELEMENTS TO BE HIDDEN
4685				
4686				var toHideCSS = {};
4687				for(var i = 0; i<2; i++){
4688					var a = i==0 ? a = config.prefix : '';
4689					toHideCSS[a+'transition'] = 'all '+speed+'ms '+config.easing+', '+a+'filter '+speed+'ms linear, opacity '+speed+'ms linear';
4690					toHideCSS[a+'transform'] = config.scale+' '+config.rotateX+' '+config.rotateY+' '+config.rotateZ;
4691					toHideCSS[a+'filter'] = config.blur+' '+config.grayscale;
4692					toHideCSS['opacity'] = config.fade;
4693				};
4694				
4695				$tohide.css(toHideCSS);
4696				
4697				// ALL ANIMATIONS HAVE NOW BEEN STARTED, NOW LISTEN FOR TRANSITION END:
4698				
4699				$par.bind('webkitTransitionEnd transitionend otransitionend oTransitionEnd',function(e){
4700					
4701					if (e.originalEvent.propertyName.indexOf('transform') > -1 || e.originalEvent.propertyName.indexOf('opacity') > -1){
4702						
4703						if(mixSelector.indexOf('.') > -1){
4704						
4705						// IF MIXSELECTOR IS A CLASS NAME
4706						
4707							if($(e.target).hasClass(mixSelector.replace('.',''))){
4708								resetFilter();
4709							};
4710						
4711						} else {
4712							
4713						// IF MIXSELECTOR IS A TAG
4714						
4715							if($(e.target).is(mixSelector)){
4716								resetFilter();
4717							};
4718							
4719						};
4720						
4721					};
4722				});	
4723	
4724			},10);
4725			
4726			// LAST RESORT EMERGENCY FAILSAFE
4727			
4728			config.failsafe = setTimeout(function(){
4729				if(config.mixing){
4730					resetFilter();
4731				};
4732			}, speed + 400);
4733	
4734		} else {
4735			
4736		// ELSE IF NOTHING TO SHOW, AND EVERYTHING TO BE HIDDEN
4737		
4738			// IF WE ARE RESIZING CONTAINER, SET ITS STARTING HEIGHT
4739	
4740			if(config.resizeContainer)$par.css('height', config.origHeight+'px');
4741			
4742			// IF IE, FUCK OFF, AND THEN GO HOME
4743			
4744			if(!window.atob){
4745				resetFilter();
4746				return false;
4747			};
4748			
4749			// GROUP ALL ELEMENTS TO HIDE INTO JQUERY OBJECT
4750			
4751			$tohide = $hide;
4752			
4753			// WRAP ANIMATION FUNCTIONS IN A 10ms DELAY TO PREVENT RACE CONDITION
4754	
4755			var delay = setTimeout(function(){
4756				
4757				// APPLY PERSPECTIVE TO CONTAINER
4758	
4759				$par.css(config.perspective);
4760				
4761				// APPLY TRANSITION TIMING TO CONTAINER, AND BEGIN ANIMATION TO NEW HEIGHT
4762		
4763				if(config.resizeContainer){
4764					var containerCSS = {};
4765					for(var i = 0; i<2; i++){
4766						var a = i==0 ? a = config.prefix : '';
4767						containerCSS[a+'transition'] = 'height '+speed+'ms ease-in-out';
4768						containerCSS['height'] = config.minHeight+'px';
4769					};
4770					$par.css(containerCSS);
4771				};
4772	
4773				// APPLY TRANSITION TIMING TO ALL TARGET ELEMENTS
4774				
4775				$targets.css(config.transition);
4776				
4777				// GET TOTAL NUMBER OF ELEMENTS TO HIDE
4778	
4779				var totalHide = $hide.length;
4780				
4781				// IF SOMETHING TO HIDE:
4782	
4783				if(totalHide){
4784					
4785					// BEGIN TRANSFORMS ON ALL ELEMENTS TO BE HIDDEN
4786
4787					var toHideCSS = {};
4788					for(var i = 0; i<2; i++){
4789						var a = i==0 ? a = config.prefix : '';
4790						toHideCSS[a+'transform'] = config.scale+' '+config.rotateX+' '+config.rotateY+' '+config.rotateZ;
4791						toHideCSS[a+'filter'] = config.blur+' '+config.grayscale;
4792						toHideCSS['opacity'] = config.fade;
4793					};
4794
4795					$tohide.css(toHideCSS);
4796					
4797					// ALL ANIMATIONS HAVE NOW BEEN STARTED, NOW LISTEN FOR TRANSITION END:
4798
4799					$par.bind('webkitTransitionEnd transitionend otransitionend oTransitionEnd',function(e){
4800						if (e.originalEvent.propertyName.indexOf('transform') > -1 || e.originalEvent.propertyName.indexOf('opacity') > -1){
4801							$cont.addClass(config.failClass);
4802							resetFilter();
4803						};
4804					});
4805		
4806				} else {
4807					
4808				// ELSE, WE'RE DONE MIXING
4809				 	
4810					config.mixing = false;
4811				};
4812	
4813			}, 10);
4814		}; 
4815		
4816		// CLEAN UP AND RESET FUNCTION
4817
4818		function resetFilter(){
4819			
4820			// UNBIND TRANSITION END EVENTS FROM CONTAINER
4821			
4822			$par.unbind('webkitTransitionEnd transitionend otransitionend oTransitionEnd');
4823			
4824			// IF A SORT ARGUMENT HAS BEEN SENT, SORT ELEMENTS TO THEIR FINAL ORDER
4825			
4826			if(sortby){
4827				sort(sortby, order, $cont, config);
4828			};
4829			
4830			// EMPTY SORTING ARRAYS
4831		
4832			config.startOrder = [], config.newOrder = [], config.origSort = [], config.checkSort = [];
4833		
4834			// REMOVE INLINE STYLES FROM ALL TARGET ELEMENTS AND SLAM THE BRAKES ON
4835			
4836			$targets.removeStyle(
4837				config.prefix+'filter, filter, '+config.prefix+'transform, transform, opacity, display'
4838			).css(config.clean).removeAttr('data-checksum');
4839			
4840			// BECAUSE IE SUCKS
4841			
4842			if(!window.atob){
4843				$targets.css({
4844					display: 'none',
4845					opacity: '0'
4846				});
4847			};
4848			
4849			// REMOVE HEIGHT FROM CONTAINER ONLY IF RESIZING
4850			
4851			var remH = config.resizeContainer ? 'height' : '';
4852			
4853			// REMOVE INLINE STYLES FROM CONTAINER
4854		
4855			$par.removeStyle(
4856				config.prefix+'transition, transition, '+config.prefix+'perspective, perspective, '+config.prefix+'perspective-origin, perspective-origin, '+remH
4857			);
4858			
4859			// ADD FINAL DISPLAY PROPERTIES AND OPACITY TO ALL SHOWN ELEMENTS
4860			// CACHE CURRENT LAYOUT MODE & SORT FOR NEXT MIX
4861			
4862			if(config.layoutMode == 'list'){
4863				$show.css({display:config.targetDisplayList, opacity:'1'});
4864				config.origDisplay = config.targetDisplayList;
4865			} else {
4866				$show.css({display:config.targetDisplayGrid, opacity:'1'});
4867				config.origDisplay = config.targetDisplayGrid;
4868			};
4869			config.origLayout = config.layoutMode;
4870				
4871			var wait = setTimeout(function(){
4872				
4873				// LET GO OF THE BRAKES
4874				
4875				$targets.removeStyle(config.prefix+'transition, transition');
4876			
4877				// WE'RE DONE MIXING
4878			
4879				config.mixing = false;
4880			
4881				// FIRE "ONMIXEND" CALLBACK
4882			
4883				if(typeof config.onMixEnd == 'function') {
4884					var output = config.onMixEnd.call(this, config);
4885				
4886					// UPDATE CONFIG IF DATA RETURNED
4887				
4888					config = output ? output : config;
4889				};
4890			});
4891		};
4892	};
4893	
4894	// SORT FUNCTION
4895	
4896	function sort(sortby, order, $cont, config){
4897
4898		// COMPARE BY ATTRIBUTE
4899
4900		function compare(a,b) {
4901			var sortAttrA = isNaN(a.attr(sortby) * 1) ? a.attr(sortby).toLowerCase() : a.attr(sortby) * 1,
4902				sortAttrB = isNaN(b.attr(sortby) * 1) ? b.attr(sortby).toLowerCase() : b.attr(sortby) * 1;
4903		  	if (sortAttrA < sortAttrB)
4904		    	return -1;
4905		  	if (sortAttrA > sortAttrB)
4906		    	return 1;
4907		  	return 0;
4908		};
4909		
4910		// REBUILD DOM
4911
4912		function rebuild(element){
4913			if(order == 'asc'){
4914				$sortWrapper.prepend(element).prepend(' ');
4915			} else {
4916				$sortWrapper.append(element).append(' ');
4917			};
4918		};
4919		
4920		// RANDOMIZE ARRAY
4921
4922		function arrayShuffle(oldArray){
4923			var newArray = oldArray.slice();
4924		 	var len = newArray.length;
4925			var i = len;
4926			while (i--){
4927			 	var p = parseInt(Math.random()*len);
4928				var t = newArray[i];
4929		  		newArray[i] = newArray[p];
4930			  	newArray[p] = t;
4931		 	};
4932			return newArray; 
4933		};
4934		
4935		// SORT
4936		
4937		$cont.find(config.targetSelector).wrapAll('<div class="mix_sorter"/>');
4938		
4939		var $sortWrapper = $cont.find('.mix_sorter');
4940		
4941		if(!config.origSort.length){
4942			$sortWrapper.find(config.targetSelector+':visible').each(function(){
4943				$(this).wrap('<s/>');
4944				config.origSort.push($(this).parent().html().replace(/\s+/g, ''));
4945				$(this).unwrap();
4946			});
4947		};
4948		
4949		
4950		
4951		$sortWrapper.empty();
4952		
4953		if(sortby == 'reset'){
4954			$.each(config.startOrder,function(){
4955				$sortWrapper.append(this).append(' ');
4956			});
4957		} else if(sortby == 'default'){
4958			$.each(config.origOrder,function(){
4959				rebuild(this);
4960			});
4961		} else if(sortby == 'random'){
4962			if(!config.newOrder.length){
4963				config.newOrder = arrayShuffle(config.startOrder);
4964			};
4965			$.each(config.newOrder,function(){
4966				$sortWrapper.append(this).append(' ');
4967			});	
4968		} else if(sortby == 'custom'){
4969			$.each(order, function(){
4970				rebuild(this);
4971			});
4972		} else { 
4973			// SORT BY ATTRIBUTE
4974			
4975			if(typeof config.origOrder[0].attr(sortby) === 'undefined'){
4976				console.log('No such attribute found. Terminating');
4977				return false;
4978			};
4979			
4980			if(!config.newOrder.length){
4981				$.each(config.origOrder,function(){
4982					config.newOrder.push($(this));
4983				});
4984				config.newOrder.sort(compare);
4985			};
4986			$.each(config.newOrder,function(){
4987				rebuild(this);
4988			});
4989			
4990		};
4991		config.checkSort = [];
4992		$sortWrapper.find(config.targetSelector+':visible').each(function(i){
4993			var $t = $(this);
4994			if(i == 0){
4995				
4996				// PREVENT COMPARE RETURNING FALSE POSITIVES ON ELEMENTS WITH NO CLASS/ATTRIBUTES
4997				
4998				$t.attr('data-checksum','1');
4999			};
5000			$t.wrap('<s/>');
5001			config.checkSort.push($t.parent().html().replace(/\s+/g, ''));
5002			$t.unwrap();
5003		});
5004		
5005		$cont.find(config.targetSelector).unwrap();
5006	};
5007	
5008	// FIND VENDOR PREFIX
5009
5010	function prefix(el) {
5011	    var prefixes = ["Webkit", "Moz", "O", "ms"];
5012	    for (var i = 0; i < prefixes.length; i++){
5013	        if (prefixes[i] + "Transition" in el.style){
5014	            return prefixes[i];
5015	        };
5016	    };
5017	    return "transition" in el.style ? "" : false;
5018	};
5019	
5020	// REMOVE SPECIFIC STYLES
5021	
5022	$.fn.removeStyle = function(style){
5023		return this.each(function(){
5024			var obj = $(this);
5025			style = style.replace(/\s+/g, '');
5026			var styles = style.split(',');
5027			$.each(styles,function(){
5028				
5029				var search = new RegExp(this.toString() + '[^;]+;?', 'g');
5030				obj.attr('style', function(i, style){
5031					if(style) return style.replace(search, '');
5032			    });
5033			});
5034		});
5035    };
5036
5037	// COMPARE ARRAYS 
5038	
5039	function compareArr(a,b){
5040	    if (a.length != b.length) return false;
5041	    for (var i = 0; i < b.length; i++){
5042	        if (a[i].compare) { 
5043	            if (!a[i].compare(b[i])) return false;
5044	        };
5045	        if (a[i] !== b[i]) return false;
5046	    };
5047	    return true;
5048	};
5049	
5050	// BUILD FILTER ARRAY(S)
5051	
5052	function buildFilterArray(str){
5053		// CLEAN FILTER STRING
5054		str = str.replace(/\s{2,}/g, ' ');
5055		// FOR EACH PEROID SEPERATED CLASS NAME, ADD STRING TO FILTER ARRAY
5056		var arr = str.split(' ');
5057		// IF ALL, REPLACE WITH MIX_ALL
5058		$.each(arr,function(i){
5059			if(this == 'all')arr[i] = 'mix_all';
5060		});
5061		if(arr[0] == "")arr.shift(); 
5062		return arr;
5063	};
5064
5065	
5066})(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.