PageSourceSearch

https://www.alsuoposto.it/wp-content/themes/uncode/library/js/plugins.js?ver=395588513

js alsuoposto.it collected 2026-10-02 01:59:06 UTC 532,892 bytes, 15,941 lines download raw bytes

1/* ----------------------------------------------------------
2 * Plugins
3 * ---------------------------------------------------------- */
4
5(function(window, $) {
6  'use strict';
7  var counter = 0,
8    $headCache = $('head'),
9    oldBigText = window.BigText,
10    oldjQueryMethod = $.fn.bigtext,
11    BigText = {
12      DEBUG_MODE: false,
13      DEFAULT_MIN_FONT_SIZE_PX: null,
14      DEFAULT_MAX_FONT_SIZE_PX: 528,
15      GLOBAL_STYLE_ID: 'bigtext-style',
16      STYLE_ID: 'bigtext-id',
17      LINE_CLASS_PREFIX: 'bigtext-line',
18      EXEMPT_CLASS: 'bigtext-exempt',
19      noConflict: function(restore)
20      {
21        if(restore) {
22          $.fn.bigtext = oldjQueryMethod;
23          window.BigText = oldBigText;
24        }
25        return BigText;
26      },
27      supports: {
28        wholeNumberFontSizeOnly: (function() {
29          if( !( 'getComputedStyle' in window ) ) {
30            return true;
31          }
32          var test = $('<div/>').css({
33              position: 'absolute',
34              'font-size': '14.1px'
35            }).insertBefore( $('script').eq(0) ),
36            computedStyle = window.getComputedStyle( test[0], null );
37
38          var ret = computedStyle && computedStyle.getPropertyValue( 'font-size' ) === '14px';
39          test.remove();
40          return ret;
41        })()
42      },
43      init: function() {
44        if(!$('#'+BigText.GLOBAL_STYLE_ID).length) {
45          $headCache.append(BigText.generateStyleTag(BigText.GLOBAL_STYLE_ID, ['.bigtext * { white-space: nowrap; } .bigtext > * { display: block; }',
46                                          '.bigtext .' + BigText.EXEMPT_CLASS + ', .bigtext .' + BigText.EXEMPT_CLASS + ' * { white-space: normal; }']));
47        }
48      },
49      bindResize: function(eventName, resizeFunction) {
50        var timeoutId;
51        $(window).unbind(eventName).bind(eventName, function() {
52          if( timeoutId ) {
53            clearTimeout( timeoutId );
54          }
55          timeoutId = setTimeout( resizeFunction, 300 );
56        });
57      },
58      getStyleId: function(id)
59      {
60        return BigText.STYLE_ID + '-' + id;
61      },
62      generateStyleTag: function(id, css)
63      {
64        return $('<style>' + css.join('\n') + '</style>').attr('id', id);
65      },
66      clearCss: function(id)
67      {
68        var styleId = BigText.getStyleId(id);
69        $('#' + styleId).remove();
70      },
71      generateCss: function(id, linesFontSizes, lineWordSpacings, minFontSizes)
72      {
73        var css = [];
74
75        BigText.clearCss(id);
76
77        for(var j=0, k=linesFontSizes.length; j<k; j++) {
78          css.push('#' + id + ' .' + BigText.LINE_CLASS_PREFIX + j + ' {' +
79            (minFontSizes[j] ? ' white-space: normal;' : '') +
80            (linesFontSizes[j] ? ' font-size: ' + linesFontSizes[j] + 'px;' : '') +
81            (lineWordSpacings[j] ? ' word-spacing: ' + lineWordSpacings[j] + 'px;' : '') +
82            '}');
83        }
84
85        return BigText.generateStyleTag(BigText.getStyleId(id), css);
86      },
87      jQueryMethod: function(options)
88      {
89        BigText.init();
90
91        options = $.extend({
92          minfontsize: BigText.DEFAULT_MIN_FONT_SIZE_PX,
93          maxfontsize: BigText.DEFAULT_MAX_FONT_SIZE_PX,
94          childSelector: '',
95          resize: true
96        }, options || {});
97
98        this.each(function()
99        {
100          var $t = $(this).addClass('bigtext'),
101            maxWidth = $t.width(),
102            id = $t.attr('id'),
103            $children = options.childSelector ? $t.find( options.childSelector ) : $t.children();
104
105          if(!id) {
106            id = 'bigtext-id' + (counter++);
107            $t.attr('id', id);
108          }
109
110          if(options.resize) {
111            BigText.bindResize('resize.bigtext-event-' + id, function()
112            {
113              // TODO only call this if the width has changed.
114              BigText.jQueryMethod.call($('#' + id), options);
115            });
116          }
117
118          BigText.clearCss(id);
119
120          $children.addClass(function(lineNumber, className)
121          {
122            // remove existing line classes.
123            return [className.replace(new RegExp('\\b' + BigText.LINE_CLASS_PREFIX + '\\d+\\b'), ''),
124                BigText.LINE_CLASS_PREFIX + lineNumber].join(' ');
125          });
126
127          var sizes = calculateSizes($t, $children, maxWidth, options.maxfontsize, options.minfontsize);
128          $headCache.append(BigText.generateCss(id, sizes.fontSizes, sizes.wordSpacings, sizes.minFontSizes));
129        });
130
131        return this.trigger('bigtext:complete');
132      }
133    };
134
135  function testLineDimensions($line, maxWidth, property, size, interval, units, previousWidth)
136  {
137    var width;
138    previousWidth = typeof previousWidth === 'number' ? previousWidth : 0;
139    $line.css(property, size + units);
140
141    width = $line.width();
142
143    if(width >= maxWidth) {
144
145      $line.css(property, '');
146
147      if(width === maxWidth) {
148        return {
149          match: 'exact',
150          size: parseFloat((parseFloat(size) - 0.1).toFixed(3))
151        };
152      }
153
154      // Since this is an estimate, we calculate how far over the width we went with the new value.
155      // If this is word-spacing (our last resort guess) and the over is less than the under, we keep the higher value.
156      // Otherwise, we revert to the underestimate.
157      var under = maxWidth - previousWidth,
158        over = width - maxWidth;
159
160      return {
161        match: 'estimate',
162        size: parseFloat((parseFloat(size) - (property === 'word-spacing' && previousWidth && ( over < under ) ? 0 : interval)).toFixed(3))
163      };
164    }
165
166    return width;
167  }
168
169  function calculateSizes($t, $children, maxWidth, maxFontSize, minFontSize)
170  {
171    var $c = $t.clone(true)
172      .addClass('bigtext-cloned')
173      .css({
174        fontFamily: $t.css('font-family'),
175        textTransform: $t.css('text-transform'),
176        wordSpacing: $t.css('word-spacing'),
177        letterSpacing: $t.css('letter-spacing'),
178        position: 'absolute',
179        left: BigText.DEBUG_MODE ? 0 : -9999,
180        top: BigText.DEBUG_MODE ? 0 : -9999
181      })
182      .appendTo(document.body);
183
184    // font-size isn't the only thing we can modify, we can also mess with:
185    // word-spacing and letter-spacing. WebKit does not respect subpixel
186    // letter-spacing, word-spacing, or font-size.
187    // TODO try -webkit-transform: scale() as a workaround.
188    var fontSizes = [],
189      wordSpacings = [],
190      minFontSizes = [],
191      ratios = [];
192
193    $children.css('float', 'left').each(function() {
194      var $line = $(this),
195        // TODO replace 8, 4 with a proportional size to the calculated font-size.
196        intervals = BigText.supports.wholeNumberFontSizeOnly ? [8, 4, 1] : [8, 4, 1, 0.1],
197        lineMax,
198        newFontSize;
199
200      if($line.hasClass(BigText.EXEMPT_CLASS)) {
201        fontSizes.push(null);
202        ratios.push(null);
203        minFontSizes.push(false);
204        return;
205      }
206
207      // TODO we can cache this ratio?
208      var autoGuessSubtraction = 32, // font size in px
209        currentFontSize = parseFloat($line.css('font-size')),
210        ratio = ( $line.width() / currentFontSize ).toFixed(6);
211
212      newFontSize = parseInt( maxWidth / ratio, 10 ) - autoGuessSubtraction;
213
214      outer: for(var m=0, n=intervals.length; m<n; m++) {
215        inner: for(var j=1, k=10; j<=k; j++) {
216          if(newFontSize + j*intervals[m] > maxFontSize) {
217            newFontSize = maxFontSize;
218            break outer;
219          }
220
221          lineMax = testLineDimensions($line, maxWidth, 'font-size', newFontSize + j*intervals[m], intervals[m], 'px', lineMax);
222          if(typeof lineMax !== 'number') {
223            newFontSize = lineMax.size;
224
225            if(lineMax.match === 'exact') {
226              break outer;
227            }
228            break inner;
229          }
230        }
231      }
232
233      ratios.push(maxWidth / newFontSize);
234
235      if(newFontSize > maxFontSize) {
236        fontSizes.push(maxFontSize);
237        minFontSizes.push(false);
238      } else if(!!minFontSize && newFontSize < minFontSize) {
239        fontSizes.push(minFontSize);
240        minFontSizes.push(true);
241      } else {
242        fontSizes.push(newFontSize);
243        minFontSizes.push(false);
244      }
245    }).each(function(lineNumber) {
246      var $line = $(this),
247        wordSpacing = 0,
248        interval = 1,
249        maxWordSpacing;
250
251      if($line.hasClass(BigText.EXEMPT_CLASS)) {
252        wordSpacings.push(null);
253        return;
254      }
255
256      // must re-use font-size, even though it was removed above.
257      $line.css('font-size', fontSizes[lineNumber] + 'px');
258
259      for(var m=1, n=3; m<n; m+=interval) {
260        maxWordSpacing = testLineDimensions($line, maxWidth, 'word-spacing', m, interval, 'px', maxWordSpacing);
261        if(typeof maxWordSpacing !== 'number') {
262          wordSpacing = maxWordSpacing.size;
263          break;
264        }
265      }
266
267      $line.css('font-size', '');
268      wordSpacings.push(wordSpacing);
269    }).removeAttr('style');
270
271    if( !BigText.DEBUG_MODE ) {
272      $c.remove();
273    } else {
274      $c.css({
275        'background-color': 'rgba(255,255,255,.4)'
276      });
277    }
278
279    return {
280      fontSizes: fontSizes,
281      wordSpacings: wordSpacings,
282      ratios: ratios,
283      minFontSizes: minFontSizes
284    };
285  }
286
287  $.fn.bigtext = BigText.jQueryMethod;
288  window.BigText = BigText;
289
290})(this, jQuery);
291
292/*!
293 * Isotope PACKAGED v2.2.2
294 *
295 * Licensed GPLv3 for open source use
296 * or Isotope Commercial License for commercial use
297 *
298 * http://isotope.metafizzy.co
299 * Copyright 2015 Metafizzy
300 */
301
302/**
303 * Bridget makes jQuery widgets
304 * v1.1.0
305 * MIT license
306 */
307
308( function( window ) {
309
310
311
312// -------------------------- utils -------------------------- //
313
314var slice = Array.prototype.slice;
315
316function noop() {}
317
318// -------------------------- definition -------------------------- //
319
320function defineBridget( $ ) {
321
322// bail if no jQuery
323if ( !$ ) {
324  return;
325}
326
327// -------------------------- addOptionMethod -------------------------- //
328
329/**
330 * adds option method -> $().plugin('option', {...})
331 * @param {Function} PluginClass - constructor class
332 */
333function addOptionMethod( PluginClass ) {
334  // don't overwrite original option method
335  if ( PluginClass.prototype.option ) {
336    return;
337  }
338
339  // option setter
340  PluginClass.prototype.option = function( opts ) {
341    // bail out if not an object
342    if ( !$.isPlainObject( opts ) ){
343      return;
344    }
345    this.options = $.extend( true, this.options, opts );
346  };
347}
348
349// -------------------------- plugin bridge -------------------------- //
350
351// helper function for logging errors
352// $.error breaks jQuery chaining
353var logError = typeof console === 'undefined' ? noop :
354  function( message ) {
355    console.error( message );
356  };
357
358/**
359 * jQuery plugin bridge, access methods like $elem.plugin('method')
360 * @param {String} namespace - plugin name
361 * @param {Function} PluginClass - constructor class
362 */
363function bridge( namespace, PluginClass ) {
364  // add to jQuery fn namespace
365  $.fn[ namespace ] = function( options ) {
366    if ( typeof options === 'string' ) {
367      // call plugin method when first argument is a string
368      // get arguments for method
369      var args = slice.call( arguments, 1 );
370
371      for ( var i=0, len = this.length; i < len; i++ ) {
372        var elem = this[i];
373        var instance = $.data( elem, namespace );
374        if ( !instance ) {
375          logError( "cannot call methods on " + namespace + " prior to initialization; " +
376            "attempted to call '" + options + "'" );
377          continue;
378        }
379        if ( !$.isFunction( instance[options] ) || options.charAt(0) === '_' ) {
380          logError( "no such method '" + options + "' for " + namespace + " instance" );
381          continue;
382        }
383
384        // trigger method with arguments
385        var returnValue = instance[ options ].apply( instance, args );
386
387        // break look and return first value if provided
388        if ( returnValue !== undefined ) {
389          return returnValue;
390        }
391      }
392      // return this if no return value
393      return this;
394    } else {
395      return this.each( function() {
396        var instance = $.data( this, namespace );
397        if ( instance ) {
398          // apply options & init
399          instance.option( options );
400          instance._init();
401        } else {
402          // initialize new instance
403          instance = new PluginClass( this, options );
404          $.data( this, namespace, instance );
405        }
406      });
407    }
408  };
409
410}
411
412// -------------------------- bridget -------------------------- //
413
414/**
415 * converts a Prototypical class into a proper jQuery plugin
416 *   the class must have a ._init method
417 * @param {String} namespace - plugin name, used in $().pluginName
418 * @param {Function} PluginClass - constructor class
419 */
420$.bridget = function( namespace, PluginClass ) {
421  addOptionMethod( PluginClass );
422  bridge( namespace, PluginClass );
423};
424
425return $.bridget;
426
427}
428
429// transport
430if ( typeof define === 'function' && define.amd ) {
431  // AMD
432  define( 'jquery-bridget/jquery.bridget',[ 'jquery' ], defineBridget );
433} else if ( typeof exports === 'object' ) {
434  defineBridget( require('jquery') );
435} else {
436  // get jquery from browser global
437  defineBridget( window.jQuery );
438}
439
440})( window );
441
442/*!
443 * eventie v1.0.6
444 * event binding helper
445 *   eventie.bind( elem, 'click', myFn )
446 *   eventie.unbind( elem, 'click', myFn )
447 * MIT license
448 */
449
450/*jshint browser: true, undef: true, unused: true */
451/*global define: false, module: false */
452
453( function( window ) {
454
455
456
457var docElem = document.documentElement;
458
459var bind = function() {};
460
461function getIEEvent( obj ) {
462  var event = window.event;
463  // add event.target
464  event.target = event.target || event.srcElement || obj;
465  return event;
466}
467
468if ( docElem.addEventListener ) {
469  bind = function( obj, type, fn ) {
470    obj.addEventListener( type, fn, false );
471  };
472} else if ( docElem.attachEvent ) {
473  bind = function( obj, type, fn ) {
474    obj[ type + fn ] = fn.handleEvent ?
475      function() {
476        var event = getIEEvent( obj );
477        fn.handleEvent.call( fn, event );
478      } :
479      function() {
480        var event = getIEEvent( obj );
481        fn.call( obj, event );
482      };
483    obj.attachEvent( "on" + type, obj[ type + fn ] );
484  };
485}
486
487var unbind = function() {};
488
489if ( docElem.removeEventListener ) {
490  unbind = function( obj, type, fn ) {
491    obj.removeEventListener( type, fn, false );
492  };
493} else if ( docElem.detachEvent ) {
494  unbind = function( obj, type, fn ) {
495    obj.detachEvent( "on" + type, obj[ type + fn ] );
496    try {
497      delete obj[ type + fn ];
498    } catch ( err ) {
499      // can't delete window object properties
500      obj[ type + fn ] = undefined;
501    }
502  };
503}
504
505var eventie = {
506  bind: bind,
507  unbind: unbind
508};
509
510// ----- module definition ----- //
511
512if ( typeof define === 'function' && define.amd ) {
513  // AMD
514  define( 'eventie/eventie',eventie );
515} else if ( typeof exports === 'object' ) {
516  // CommonJS
517  module.exports = eventie;
518} else {
519  // browser global
520  window.eventie = eventie;
521}
522
523})( window );
524
525/*!
526 * EventEmitter v4.2.11 - git.io/ee
527 * Unlicense - http://unlicense.org/
528 * Oliver Caldwell - http://oli.me.uk/
529 * @preserve
530 */
531
532;(function () {
533    'use strict';
534
535    /**
536     * Class for managing events.
537     * Can be extended to provide event functionality in other classes.
538     *
539     * @class EventEmitter Manages event registering and emitting.
540     */
541    function EventEmitter() {}
542
543    // Shortcuts to improve speed and size
544    var proto = EventEmitter.prototype;
545    var exports = this;
546    var originalGlobalValue = exports.EventEmitter;
547
548    /**
549     * Finds the index of the listener for the event in its storage array.
550     *
551     * @param {Function[]} listeners Array of listeners to search through.
552     * @param {Function} listener Method to look for.
553     * @return {Number} Index of the specified listener, -1 if not found
554     * @api private
555     */
556    function indexOfListener(listeners, listener) {
557        var i = listeners.length;
558        while (i--) {
559            if (listeners[i].listener === listener) {
560                return i;
561            }
562        }
563
564        return -1;
565    }
566
567    /**
568     * Alias a method while keeping the context correct, to allow for over
vendor: 16,384 bytes, lines 568-971
568writing of target method.
569     *
570     * @param {String} name The name of the target method.
571     * @return {Function} The aliased method
572     * @api private
573     */
574    function alias(name) {
575        return function aliasClosure() {
576            return this[name].apply(this, arguments);
577        };
578    }
579
580    /**
581     * Returns the listener array for the specified event.
582     * Will initialise the event object and listener arrays if required.
583     * Will return an object if you use a regex search. The object contains keys for each matched event. So /ba[rz]/ might return an object containing bar and baz. But only if you have either defined them with defineEvent or added some listeners to them.
584     * Each property in the object response is an array of listener functions.
585     *
586     * @param {String|RegExp} evt Name of the event to return the listeners from.
587     * @return {Function[]|Object} All listener functions for the event.
588     */
589    proto.getListeners = function getListeners(evt) {
590        var events = this._getEvents();
591        var response;
592        var key;
593
594        // Return a concatenated array of all matching events if
595        // the selector is a regular expression.
596        if (evt instanceof RegExp) {
597            response = {};
598            for (key in events) {
599                if (events.hasOwnProperty(key) && evt.test(key)) {
600                    response[key] = events[key];
601                }
602            }
603        }
604        else {
605            response = events[evt] || (events[evt] = []);
606        }
607
608        return response;
609    };
610
611    /**
612     * Takes a list of listener objects and flattens it into a list of listener functions.
613     *
614     * @param {Object[]} listeners Raw listener objects.
615     * @return {Function[]} Just the listener functions.
616     */
617    proto.flattenListeners = function flattenListeners(listeners) {
618        var flatListeners = [];
619        var i;
620
621        for (i = 0; i < listeners.length; i += 1) {
622            flatListeners.push(listeners[i].listener);
623        }
624
625        return flatListeners;
626    };
627
628    /**
629     * Fetches the requested listeners via getListeners but will always return the results inside an object. This is mainly for internal use but others may find it useful.
630     *
631     * @param {String|RegExp} evt Name of the event to return the listeners from.
632     * @return {Object} All listener functions for an event in an object.
633     */
634    proto.getListenersAsObject = function getListenersAsObject(evt) {
635        var listeners = this.getListeners(evt);
636        var response;
637
638        if (listeners instanceof Array) {
639            response = {};
640            response[evt] = listeners;
641        }
642
643        return response || listeners;
644    };
645
646    /**
647     * Adds a listener function to the specified event.
648     * The listener will not be added if it is a duplicate.
649     * If the listener returns true then it will be removed after it is called.
650     * If you pass a regular expression as the event name then the listener will be added to all events that match it.
651     *
652     * @param {String|RegExp} evt Name of the event to attach the listener to.
653     * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
654     * @return {Object} Current instance of EventEmitter for chaining.
655     */
656    proto.addListener = function addListener(evt, listener) {
657        var listeners = this.getListenersAsObject(evt);
658        var listenerIsWrapped = typeof listener === 'object';
659        var key;
660
661        for (key in listeners) {
662            if (listeners.hasOwnProperty(key) && indexOfListener(listeners[key], listener) === -1) {
663                listeners[key].push(listenerIsWrapped ? listener : {
664                    listener: listener,
665                    once: false
666                });
667            }
668        }
669
670        return this;
671    };
672
673    /**
674     * Alias of addListener
675     */
676    proto.on = alias('addListener');
677
678    /**
679     * Semi-alias of addListener. It will add a listener that will be
680     * automatically removed after its first execution.
681     *
682     * @param {String|RegExp} evt Name of the event to attach the listener to.
683     * @param {Function} listener Method to be called when the event is emitted. If the function returns true then it will be removed after calling.
684     * @return {Object} Current instance of EventEmitter for chaining.
685     */
686    proto.addOnceListener = function addOnceListener(evt, listener) {
687        return this.addListener(evt, {
688            listener: listener,
689            once: true
690        });
691    };
692
693    /**
694     * Alias of addOnceListener.
695     */
696    proto.once = alias('addOnceListener');
697
698    /**
699     * Defines an event name. This is required if you want to use a regex to add a listener to multiple events at once. If you don't do this then how do you expect it to know what event to add to? Should it just add to every possible match for a regex? No. That is scary and bad.
700     * You need to tell it what event names should be matched by a regex.
701     *
702     * @param {String} evt Name of the event to create.
703     * @return {Object} Current instance of EventEmitter for chaining.
704     */
705    proto.defineEvent = function defineEvent(evt) {
706        this.getListeners(evt);
707        return this;
708    };
709
710    /**
711     * Uses defineEvent to define multiple events.
712     *
713     * @param {String[]} evts An array of event names to define.
714     * @return {Object} Current instance of EventEmitter for chaining.
715     */
716    proto.defineEvents = function defineEvents(evts) {
717        for (var i = 0; i < evts.length; i += 1) {
718            this.defineEvent(evts[i]);
719        }
720        return this;
721    };
722
723    /**
724     * Removes a listener function from the specified event.
725     * When passed a regular expression as the event name, it will remove the listener from all events that match it.
726     *
727     * @param {String|RegExp} evt Name of the event to remove the listener from.
728     * @param {Function} listener Method to remove from the event.
729     * @return {Object} Current instance of EventEmitter for chaining.
730     */
731    proto.removeListener = function removeListener(evt, listener) {
732        var listeners = this.getListenersAsObject(evt);
733        var index;
734        var key;
735
736        for (key in listeners) {
737            if (listeners.hasOwnProperty(key)) {
738                index = indexOfListener(listeners[key], listener);
739
740                if (index !== -1) {
741                    listeners[key].splice(index, 1);
742                }
743            }
744        }
745
746        return this;
747    };
748
749    /**
750     * Alias of removeListener
751     */
752    proto.off = alias('removeListener');
753
754    /**
755     * Adds listeners in bulk using the manipulateListeners method.
756     * If you pass an object as the second argument you can add to multiple events at once. The object should contain key value pairs of events and listeners or listener arrays. You can also pass it an event name and an array of listeners to be added.
757     * You can also pass it a regular expression to add the array of listeners to all events that match it.
758     * Yeah, this function does quite a bit. That's probably a bad thing.
759     *
760     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add to multiple events at once.
761     * @param {Function[]} [listeners] An optional array of listener functions to add.
762     * @return {Object} Current instance of EventEmitter for chaining.
763     */
764    proto.addListeners = function addListeners(evt, listeners) {
765        // Pass through to manipulateListeners
766        return this.manipulateListeners(false, evt, listeners);
767    };
768
769    /**
770     * Removes listeners in bulk using the manipulateListeners method.
771     * If you pass an object as the second argument you can remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
772     * You can also pass it an event name and an array of listeners to be removed.
773     * You can also pass it a regular expression to remove the listeners from all events that match it.
774     *
775     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to remove from multiple events at once.
776     * @param {Function[]} [listeners] An optional array of listener functions to remove.
777     * @return {Object} Current instance of EventEmitter for chaining.
778     */
779    proto.removeListeners = function removeListeners(evt, listeners) {
780        // Pass through to manipulateListeners
781        return this.manipulateListeners(true, evt, listeners);
782    };
783
784    /**
785     * Edits listeners in bulk. The addListeners and removeListeners methods both use this to do their job. You should really use those instead, this is a little lower level.
786     * The first argument will determine if the listeners are removed (true) or added (false).
787     * If you pass an object as the second argument you can add/remove from multiple events at once. The object should contain key value pairs of events and listeners or listener arrays.
788     * You can also pass it an event name and an array of listeners to be added/removed.
789     * You can also pass it a regular expression to manipulate the listeners of all events that match it.
790     *
791     * @param {Boolean} remove True if you want to remove listeners, false if you want to add.
792     * @param {String|Object|RegExp} evt An event name if you will pass an array of listeners next. An object if you wish to add/remove from multiple events at once.
793     * @param {Function[]} [listeners] An optional array of listener functions to add/remove.
794     * @return {Object} Current instance of EventEmitter for chaining.
795     */
796    proto.manipulateListeners = function manipulateListeners(remove, evt, listeners) {
797        var i;
798        var value;
799        var single = remove ? this.removeListener : this.addListener;
800        var multiple = remove ? this.removeListeners : this.addListeners;
801
802        // If evt is an object then pass each of its properties to this method
803        if (typeof evt === 'object' && !(evt instanceof RegExp)) {
804            for (i in evt) {
805                if (evt.hasOwnProperty(i) && (value = evt[i])) {
806                    // Pass the single listener straight through to the singular method
807                    if (typeof value === 'function') {
808                        single.call(this, i, value);
809                    }
810                    else {
811                        // Otherwise pass back to the multiple function
812                        multiple.call(this, i, value);
813                    }
814                }
815            }
816        }
817        else {
818            // So evt must be a string
819            // And listeners must be an array of listeners
820            // Loop over it and pass each one to the multiple method
821            i = listeners.length;
822            while (i--) {
823                single.call(this, evt, listeners[i]);
824            }
825        }
826
827        return this;
828    };
829
830    /**
831     * Removes all listeners from a specified event.
832     * If you do not specify an event then all listeners will be removed.
833     * That means every event will be emptied.
834     * You can also pass a regex to remove all events that match it.
835     *
836     * @param {String|RegExp} [evt] Optional name of the event to remove all listeners for. Will remove from every event if not passed.
837     * @return {Object} Current instance of EventEmitter for chaining.
838     */
839    proto.removeEvent = function removeEvent(evt) {
840        var type = typeof evt;
841        var events = this._getEvents();
842        var key;
843
844        // Remove different things depending on the state of evt
845        if (type === 'string') {
846            // Remove all listeners for the specified event
847            delete events[evt];
848        }
849        else if (evt instanceof RegExp) {
850            // Remove all events matching the regex.
851            for (key in events) {
852                if (events.hasOwnProperty(key) && evt.test(key)) {
853                    delete events[key];
854                }
855            }
856        }
857        else {
858            // Remove all listeners in all events
859            delete this._events;
860        }
861
862        return this;
863    };
864
865    /**
866     * Alias of removeEvent.
867     *
868     * Added to mirror the node API.
869     */
870    proto.removeAllListeners = alias('removeEvent');
871
872    /**
873     * Emits an event of your choice.
874     * When emitted, every listener attached to that event will be executed.
875     * If you pass the optional argument array then those arguments will be passed to every listener upon execution.
876     * Because it uses `apply`, your array of arguments will be passed as if you wrote them out separately.
877     * So they will not arrive within the array on the other side, they will be separate.
878     * You can also pass a regular expression to emit to all events that match it.
879     *
880     * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
881     * @param {Array} [args] Optional array of arguments to be passed to each listener.
882     * @return {Object} Current instance of EventEmitter for chaining.
883     */
884    proto.emitEvent = function emitEvent(evt, args) {
885        var listeners = this.getListenersAsObject(evt);
886        var listener;
887        var i;
888        var key;
889        var response;
890
891        for (key in listeners) {
892            if (listeners.hasOwnProperty(key)) {
893                i = listeners[key].length;
894
895                while (i--) {
896                    // If the listener returns true then it shall be removed from the event
897                    // The function is executed either with a basic call or an apply if there is an args array
898                    listener = listeners[key][i];
899
900                    if (listener.once === true) {
901                        this.removeListener(evt, listener.listener);
902                    }
903
904                    response = listener.listener.apply(this, args || []);
905
906                    if (response === this._getOnceReturnValue()) {
907                        this.removeListener(evt, listener.listener);
908                    }
909                }
910            }
911        }
912
913        return this;
914    };
915
916    /**
917     * Alias of emitEvent
918     */
919    proto.trigger = alias('emitEvent');
920
921    /**
922     * Subtly different from emitEvent in that it will pass its arguments on to the listeners, as opposed to taking a single array of arguments to pass on.
923     * As with emitEvent, you can pass a regex in place of the event name to emit to all events that match it.
924     *
925     * @param {String|RegExp} evt Name of the event to emit and execute listeners for.
926     * @param {...*} Optional additional arguments to be passed to each listener.
927     * @return {Object} Current instance of EventEmitter for chaining.
928     */
929    proto.emit = function emit(evt) {
930        var args = Array.prototype.slice.call(arguments, 1);
931        return this.emitEvent(evt, args);
932    };
933
934    /**
935     * Sets the current value to check against when executing listeners. If a
936     * listeners return value matches the one set here then it will be removed
937     * after execution. This value defaults to true.
938     *
939     * @param {*} value The new value to check for when executing listeners.
940     * @return {Object} Current instance of EventEmitter for chaining.
941     */
942    proto.setOnceReturnValue = function setOnceReturnValue(value) {
943        this._onceReturnValue = value;
944        return this;
945    };
946
947    /**
948     * Fetches the current value to check against when executing listeners. If
949     * the listeners return value matches this one then it should be removed
950     * automatically. It will return true by default.
951     *
952     * @return {*|Boolean} The current value to check for or the default, true.
953     * @api private
954     */
955    proto._getOnceReturnValue = function _getOnceReturnValue() {
956        if (this.hasOwnProperty('_onceReturnValue')) {
957            return this._onceReturnValue;
958        }
959        else {
960            return true;
961        }
962    };
963
964    /**
965     * Fetches the events object and creates one if required.
966     *
967     * @return {Object} The events storage object.
968     * @api private
969     */
970    proto._getEvents = function _getEvents() {
971        return this._events || (this
971._events = {});
972    };
973
974    /**
975     * Reverts the global {@link EventEmitter} to its previous value and returns a reference to this version.
976     *
977     * @return {Function} Non conflicting EventEmitter class.
978     */
979    EventEmitter.noConflict = function noConflict() {
980        exports.EventEmitter = originalGlobalValue;
981        return EventEmitter;
982    };
983
984    // Expose the class either via AMD, CommonJS or the global object
985    if (typeof define === 'function' && define.amd) {
986        define('eventEmitter/EventEmitter',[],function () {
987            return EventEmitter;
988        });
989    }
990    else if (typeof module === 'object' && module.exports){
991        module.exports = EventEmitter;
992    }
993    else {
994        exports.EventEmitter = EventEmitter;
995    }
996}.call(this));
997
998/*!
999 * getStyleProperty v1.0.4
1000 * original by kangax
1001 * http://perfectionkills.com/feature-testing-css-properties/
1002 * MIT license
1003 */
1004
1005/*jshint browser: true, strict: true, undef: true */
1006/*global define: false, exports: false, module: false */
1007
1008( function( window ) {
1009
1010
1011
1012var prefixes = 'Webkit Moz ms Ms O'.split(' ');
1013var docElemStyle = document.documentElement.style;
1014
1015function getStyleProperty( propName ) {
1016  if ( !propName ) {
1017    return;
1018  }
1019
1020  // test standard property first
1021  if ( typeof docElemStyle[ propName ] === 'string' ) {
1022    return propName;
1023  }
1024
1025  // capitalize
1026  propName = propName.charAt(0).toUpperCase() + propName.slice(1);
1027
1028  // test vendor specific properties
1029  var prefixed;
1030  for ( var i=0, len = prefixes.length; i < len; i++ ) {
1031    prefixed = prefixes[i] + propName;
1032    if ( typeof docElemStyle[ prefixed ] === 'string' ) {
1033      return prefixed;
1034    }
1035  }
1036}
1037
1038// transport
1039if ( typeof define === 'function' && define.amd ) {
1040  // AMD
1041  define( 'get-style-property/get-style-property',[],function() {
1042    return getStyleProperty;
1043  });
1044} else if ( typeof exports === 'object' ) {
1045  // CommonJS for Component
1046  module.exports = getStyleProperty;
1047} else {
1048  // browser global
1049  window.getStyleProperty = getStyleProperty;
1050}
1051
1052})( window );
1053
1054/*!
1055 * getSize v1.2.2
1056 * measure size of elements
1057 * MIT license
1058 */
1059
1060/*jshint browser: true, strict: true, undef: true, unused: true */
1061/*global define: false, exports: false, require: false, module: false, console: false */
1062
1063( function( window, undefined ) {
1064
1065
1066
1067// -------------------------- helpers -------------------------- //
1068
1069// get a number from a string, not a percentage
1070function getStyleSize( value ) {
1071  var num = parseFloat( value );
1072  // not a percent like '100%', and a number
1073  var isValid = value.indexOf('%') === -1 && !isNaN( num );
1074  return isValid && num;
1075}
1076
1077function noop() {}
1078
1079var logError = typeof console === 'undefined' ? noop :
1080  function( message ) {
1081    console.error( message );
1082  };
1083
1084// -------------------------- measurements -------------------------- //
1085
1086var measurements = [
1087  'paddingLeft',
1088  'paddingRight',
1089  'paddingTop',
1090  'paddingBottom',
1091  'marginLeft',
1092  'marginRight',
1093  'marginTop',
1094  'marginBottom',
1095  'borderLeftWidth',
1096  'borderRightWidth',
1097  'borderTopWidth',
1098  'borderBottomWidth'
1099];
1100
1101function getZeroSize() {
1102  var size = {
1103    width: 0,
1104    height: 0,
1105    innerWidth: 0,
1106    innerHeight: 0,
1107    outerWidth: 0,
1108    outerHeight: 0
1109  };
1110  for ( var i=0, len = measurements.length; i < len; i++ ) {
1111    var measurement = measurements[i];
1112    size[ measurement ] = 0;
1113  }
1114  return size;
1115}
1116
1117
1118
1119function defineGetSize( getStyleProperty ) {
1120
1121// -------------------------- setup -------------------------- //
1122
1123var isSetup = false;
1124
1125var getStyle, boxSizingProp, isBoxSizeOuter;
1126
1127/**
1128 * setup vars and functions
1129 * do it on initial getSize(), rather than on script load
1130 * For Firefox bug https://bugzilla.mozilla.org/show_bug.cgi?id=548397
1131 */
1132function setup() {
1133  // setup once
1134  if ( isSetup ) {
1135    return;
1136  }
1137  isSetup = true;
1138
1139  var getComputedStyle = window.getComputedStyle;
1140  getStyle = ( function() {
1141    var getStyleFn = getComputedStyle ?
1142      function( elem ) {
1143        return getComputedStyle( elem, null );
1144      } :
1145      function( elem ) {
1146        return elem.currentStyle;
1147      };
1148
1149      return function getStyle( elem ) {
1150        var style = getStyleFn( elem );
1151        if ( !style ) {
1152          logError( 'Style returned ' + style +
1153            '. Are you running this code in a hidden iframe on Firefox? ' +
1154            'See http://bit.ly/getsizebug1' );
1155        }
1156        return style;
1157      };
1158  })();
1159
1160  // -------------------------- box sizing -------------------------- //
1161
1162  boxSizingProp = getStyleProperty('boxSizing');
1163
1164  /**
1165   * WebKit measures the outer-width on style.width on border-box elems
1166   * IE & Firefox measures the inner-width
1167   */
1168  if ( boxSizingProp ) {
1169    var div = document.createElement('div');
1170    div.style.width = '200px';
1171    div.style.padding = '1px 2px 3px 4px';
1172    div.style.borderStyle = 'solid';
1173    div.style.borderWidth = '1px 2px 3px 4px';
1174    div.style[ boxSizingProp ] = 'border-box';
1175
1176    var body = document.body || document.documentElement;
1177    body.appendChild( div );
1178    var style = getStyle( div );
1179
1180    isBoxSizeOuter = getStyleSize( style.width ) === 200;
1181    body.removeChild( div );
1182  }
1183
1184}
1185
1186// -------------------------- getSize -------------------------- //
1187
1188function getSize( elem ) {
1189  setup();
1190
1191  // use querySeletor if elem is string
1192  if ( typeof elem === 'string' ) {
1193    elem = document.querySelector( elem );
1194  }
1195
1196  // do not proceed on non-objects
1197  if ( !elem || typeof elem !== 'object' || !elem.nodeType ) {
1198    return;
1199  }
1200
1201  var style = getStyle( elem );
1202
1203  // if hidden, everything is 0
1204  if ( style.display === 'none' ) {
1205    return getZeroSize();
1206  }
1207
1208  var size = {};
1209  size.width = elem.offsetWidth;
1210  size.height = elem.offsetHeight;
1211
1212  var isBorderBox = size.isBorderBox = !!( boxSizingProp &&
1213    style[ boxSizingProp ] && style[ boxSizingProp ] === 'border-box' );
1214
1215  // get all measurements
1216  for ( var i=0, len = measurements.length; i < len; i++ ) {
1217    var measurement = measurements[i];
1218    var value = style[ measurement ];
1219    value = mungeNonPixel( elem, value );
1220    var num = parseFloat( value );
1221    // any 'auto', 'medium' value will be 0
1222    size[ measurement ] = !isNaN( num ) ? num : 0;
1223  }
1224
1225  var paddingWidth = size.paddingLeft + size.paddingRight;
1226  var paddingHeight = size.paddingTop + size.paddingBottom;
1227  var marginWidth = size.marginLeft + size.marginRight;
1228  var marginHeight = size.marginTop + size.marginBottom;
1229  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
1230  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
1231
1232  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
1233
1234  // overwrite width and height if we can get it from style
1235  var styleWidth = getStyleSize( style.width );
1236  if ( styleWidth !== false ) {
1237    size.width = styleWidth +
1238      // add padding and border unless it's already including it
1239      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
1240  }
1241
1242  var styleHeight = getStyleSize( style.height );
1243  if ( styleHeight !== false ) {
1244    size.height = styleHeight +
1245      // add padding and border unless it's already including it
1246      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
1247  }
1248
1249  size.innerWidth = size.width - ( paddingWidth + borderWidth );
1250  size.innerHeight = size.height - ( paddingHeight + borderHeight );
1251
1252  size.outerWidth = size.width + marginWidth;
1253  size.outerHeight = size.height + marginHeight;
1254
1255  return size;
1256}
1257
1258// IE8 returns percent values, not pixels
1259// taken from jQuery's curCSS
1260function mungeNonPixel( elem, value ) {
1261  // IE8 and has percent value
1262  if ( window.getComputedStyle || value.indexOf('%') === -1 ) {
1263    return value;
1264  }
1265  var style = elem.style;
1266  // Remember the original values
1267  var left = style.left;
1268  var rs = elem.runtimeStyle;
1269  var rsLeft = rs && rs.left;
1270
1271  // Put in the new values to get a computed value out
1272  if ( rsLeft ) {
1273    rs.left = elem.currentStyle.left;
1274  }
1275  style.left = value;
1276  value = style.pixelLeft;
1277
1278  // Revert the changed values
1279  style.left = left;
1280  if ( rsLeft ) {
1281    rs.left = rsLeft;
1282  }
1283
1284  return value;
1285}
1286
1287return getSize;
1288
1289}
1290
1291// transport
1292if ( typeof define === 'function' && define.amd ) {
1293  // AMD for RequireJS
1294  define( 'get-size/get-size',[ 'get-style-property/get-style-property' ], defineGetSize );
1295} else if ( typeof exports === 'object' ) {
1296  // CommonJS for Component
1297  module.exports = defineGetSize( require('desandro-get-style-property') );
1298} else {
1299  // browser global
1300  window.getSize = defineGetSize( window.getStyleProperty );
1301}
1302
1303})( window );
1304
1305/*!
1306 * docReady v1.0.4
1307 * Cross browser DOMContentLoaded event emitter
1308 * MIT license
1309 */
1310
1311/*jshint browser: true, strict: true, undef: true, unused: true*/
1312/*global define: false, require: false, module: false */
1313
1314( function( window ) {
1315
1316
1317
1318var document = window.document;
1319// collection of functions to be triggered on ready
1320var queue = [];
1321
1322function docReady( fn ) {
1323  // throw out non-functions
1324  if ( typeof fn !== 'function' ) {
1325    return;
1326  }
1327
1328  if ( docReady.isReady ) {
1329    // ready now, hit it
1330    fn();
1331  } else {
1332    // queue function when ready
1333    queue.push( fn );
1334  }
1335}
1336
1337docReady.isReady = false;
1338
1339// triggered on various doc ready events
1340function onReady( event ) {
1341  // bail if already triggered or IE8 document is not ready just yet
1342  var isIE8NotReady = event.type === 'readystatechange' && document.readyState !== 'complete';
1343  if ( docReady.isReady || isIE8NotReady ) {
1344    return;
1345  }
1346
1347  trigger();
1348}
1349
1350function trigger() {
1351  docReady.isReady = true;
1352  // process queue
1353  for ( var i=0, len = queue.length; i < len; i++ ) {
1354    var fn = queue[i];
1355    fn();
1356  }
1357}
1358
1359function defineDocReady( eventie ) {
1360  // trigger ready if page is ready
1361  if ( document.readyState === 'complete' ) {
1362    trigger();
1363  } else {
1364    // listen for events
1365    eventie.bind( document, 'DOMContentLoaded', onReady );
1366    eventie.bind( document, 'readystatechange', onReady );
1367    eventie.bind( window, 'load', onReady );
1368  }
1369
1370  return docReady;
1371}
1372
1373// transport
1374if ( typeof define === 'function' && define.amd ) {
1375  // AMD
1376  define( 'doc-ready/doc-ready',[ 'eventie/eventie' ], defineDocReady );
1377} else if ( typeof exports === 'object' ) {
1378  module.exports = defineDocReady( require('eventie') );
1379} else {
1380  // browser global
1381  window.docReady = defineDocReady( window.eventie );
1382}
1383
1384})( window );
1385
1386/**
1387 * matchesSelector v1.0.3
1388 * matchesSelector( element, '.selector' )
1389 * MIT license
1390 */
1391
1392/*jshint browser: true, strict: true, undef: true, unused: true */
1393/*global define: false, module: false */
1394
1395( function( ElemProto ) {
1396
1397  'use strict';
1398
1399  var matchesMethod = ( function() {
1400    // check for the standard method name first
1401    if ( ElemProto.matches ) {
1402      return 'matches';
1403    }
1404    // check un-prefixed
1405    if ( ElemProto.matchesSelector ) {
1406      return 'matchesSelector';
1407    }
1408    // check vendor prefixes
1409    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
1410
1411    for ( var i=0, len = prefixes.length; i < len; i++ ) {
1412      var prefix = prefixes[i];
1413      var method = prefix + 'MatchesSelector';
1414      if ( ElemProto[ method ] ) {
1415        return method;
1416      }
1417    }
1418  })();
1419
1420  // ----- match ----- //
1421
1422  function match( elem, selector ) {
1423    return elem[ matchesMethod ]( selector );
1424  }
1425
1426  // ----- appendToFragment ----- //
1427
1428  function checkParent( elem ) {
1429    // not needed if already has parent
1430    if ( elem.parentNode ) {
1431      return;
1432    }
1433    var fragment = document.createDocumentFragment();
1434    fragment.appendChild( elem );
1435  }
1436
1437  // ----- query ----- //
1438
1439  // fall back to using QSA
1440  // thx @jonathantneal https://gist.github.com/3062955
1441  function query( elem, selector ) {
1442    // append to fragment if no parent
1443    checkParent( elem );
1444
1445    // match elem with all selected elems of parent
1446    var elems = elem.parentNode.querySelectorAll( selector );
1447    for ( var i=0, len = elems.length; i < len; i++ ) {
1448      // return true if match
1449      if ( elems[i] === elem ) {
1450        return true;
1451      }
1452    }
1453    // otherwise return false
1454    return false;
1455  }
1456
1457  // ----- matchChild ----- //
1458
1459  function matchChild( elem, selector ) {
1460    checkParent( elem );
1461    return match( elem, selector );
1462  }
1463
1464  // ----- matchesSelector ----- //
1465
1466  var matchesSelector;
1467
1468  if ( matchesMethod ) {
1469    // IE9 supports matchesSelector, but doesn't work on orphaned elems
1470    // check for that
1471    var div = document.createElement('div');
1472    var supportsOrphans = match( div, 'div' );
1473    matchesSelector = supportsOrphans ? match : matchChild;
1474  } else {
1475    matchesSelector = query;
1476  }
1477
1478  // transport
1479  if ( typeof define === 'function' && define.amd ) {
1480    // AMD
1481    define( 'matches-selector/matches-selector',[],function() {
1482      return matchesSelector;
1483    });
1484  } else if ( typeof exports === 'object' ) {
1485    module.exports = matchesSelector;
1486  }
1487  else {
1488    // browser global
1489    window.matchesSelector = matchesSelector;
1490  }
1491
1492})( Element.prototype );
1493
1494/**
1495 * Fizzy UI utils v1.0.1
1496 * MIT license
1497 */
1498
1499/*jshint browser: true, undef: true, unused: true, strict: true */
1500
1501( function( window, factory ) {
1502  /*global define: false, module: false, require: false */
1503  'use strict';
1504  // universal module definition
1505
1506  if ( typeof define == 'function' && define.amd ) {
1507    // AMD
1508    define( 'fizzy-ui-utils/utils',[
1509      'doc-ready/doc-ready',
1510      'matches-selector/matches-selector'
1511    ], function( docReady, matchesSelector ) {
1512      return factory( window, docReady, matchesSelector );
1513    });
1514  } else if ( typeof exports == 'object' ) {
1515    // CommonJS
1516    module.exports = factory(
1517      window,
1518      require('doc-ready'),
1519      require('desandro-matches-selector')
1520    );
1521  } else {
1522    // browser global
1523    window.fizzyUIUtils = factory(
1524      window,
1525      window.docReady,
1526      window.matchesSelector
1527    );
1528  }
1529
1530}( window, function factory( window, docReady, matchesSelector ) {
1531
1532
1533
1534var utils = {};
1535
1536// ----- extend ----- //
1537
1538// extends objects
1539utils.extend = function( a, b ) {
1540  for ( var prop in b ) {
1541    a[ prop ] = b[ prop ];
1542  }
1543  return a;
1544};
1545
1546// ----- modulo ----- //
1547
1548utils.modulo = function( num, div ) {
1549  return ( ( num % div ) + div ) % div;
1550};
1551
1552// ----- isArray ----- //
1553  
1554var objToString = Object.prototype.toString;
1555utils.isArray = function( obj ) {
1556  return objToString.call( obj ) == '[object Array]';
1557};
1558
1559// ----- makeArray ----- //
1560
1561// turn element or nodeList into an array
1562utils.makeArray = function( obj ) {
1563  var ary = [];
1564  if ( utils.isArray( obj ) ) {
1565    // use object if already an array
1566    ary = obj;
1567  } else if ( obj && typeof obj.length == 'number' ) {
1568    // convert nodeList to array
1569    for ( var i=0, len = obj.length; i < len; i++ ) {
1570      ary.push( obj[i] );
1571    }
1572  } else {
1573    // array of single index
1574    ary.push( obj );
1575  }
1576  return ary;
1577};
1578
1579// ----- indexOf ----- //
1580
1581// index of helper cause IE8
1582utils.indexOf = Array.prototype.indexOf ? function( ary, obj ) {
1583    return ary.indexOf( obj );
1584  } : function( ary, obj ) {
1585    for ( var i=0, len = ary.length; i < len; i++ ) {
1586      if ( ary[i] === obj ) {
1587        return i;
1588      }
1589    }
1590    return -1;
1591  };
1592
1593// ----- removeFrom ----- //
1594
1595utils.removeFrom = function( ary, obj ) {
1596  var index = utils.indexOf( ary, obj );
1597  if ( index != -1 ) {
1598    ary.splice( index, 1 );
1599  }
1600};
1601
1602// ----- isElement ----- //
1603
1604// http://stackoverflow.com/a/384380/182183
1605utils.isElement = ( typeof HTMLElement == 'function' || typeof HTMLElement == 'object' ) ?
1606  function isElementDOM2( obj ) {
1607    return obj instanceof HTMLElement;
1608  } :
1609  function isElementQuirky( obj ) {
1610    return obj && typeof obj == 'object' &&
1611      obj.nodeType == 1 && typeof obj.nodeName == 'string';
1612  };
1613
1614// ----- setText ----- //
1615
1616utils.setText = ( function() {
1617  var setTextProperty;
1618  function setText( elem, text ) {
1619    // only check setTextProperty once
1620    setTextProperty = setTextProperty || ( document.documentElement.textContent !== undefined ? 'textContent' : 'innerText' );
1621    elem[ setTextProperty ] = text;
1622  }
1623  return setText;
1624})();
1625
1626// ----- getParent ----- //
1627
1628utils.getParent = function( elem, selector ) {
1629  while ( elem != document.body ) {
1630    elem = elem.parentNode;
1631    if ( matchesSelector( elem, selector ) ) {
1632      return elem;
1633    }
1634  }
1635};
1636
1637// ----- getQueryElement ----- //
1638
1639// use element as selector string
1640utils.getQueryElement = function( elem ) {
1641  if ( typeof elem == 'string' ) {
1642    return document.querySelector( elem );
1643  }
1644  return elem;
1645};
1646
1647// ----- handleEvent ----- //
1648
1649// enable .ontype to trigger from .addEventListener( elem, 'type' )
1650utils.handleEvent = function( event ) {
1651  var method = 'on' + event.type;
1652  if ( this[ method ] ) {
1653    this[ method ]( event );
1654  }
1655};
1656
1657// ----- filterFindElements ----- //
1658
1659utils.filterFindElements = function( elems, selector ) {
1660  // make array of elems
1661  elems = utils.makeArray( elems );
1662  var ffElems = [];
1663
1664  for ( var i=0, len = elems.length; i < len; i++ ) {
1665    var elem = elems[i];
1666    // check that elem is an actual element
1667    if ( !utils.isElement( elem ) ) {
1668      continue;
1669    }
1670    // filter & find items if we have a selector
1671    if ( selector ) {
1672      // filter siblings
1673      if ( matchesSelector( elem, selector ) ) {
1674        ffElems.push( elem );
1675      }
1676      // find children
1677      var childElems = elem.querySelectorAll( selector );
1678      // concat childElems to filterFound array
1679      for ( var j=0, jLen = childElems.length; j < jLen; j++ ) {
1680        ffElems.push( childElems[j] );
1681      }
1682    } else {
1683      ffElems.push( elem );
1684    }
1685  }
1686
1687  return ffElems;
1688};
1689
1690// ----- debounceMethod ----- //
1691
1692utils.debounceMethod = function( _class, methodName, threshold ) {
1693  // original method
1694  var method = _class.prototype[ methodName ];
1695  var timeoutName = methodName + 'Timeout';
1696
1697  _class.prototype[ methodName ] = function() {
1698    var timeout = this[ timeoutName ];
1699    if ( timeout ) {
1700      clearTimeout( timeout );
1701    }
1702    var args = arguments;
1703
1704    var _this = this;
1705    this[ timeoutName ] = setTimeout( function() {
1706      method.apply( _this, args );
1707      delete _this[ timeoutName ];
1708    }, threshold || 100 );
1709  };
1710};
1711
1712// ----- htmlInit ----- //
1713
1714// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
1715utils.toDashed = function( str ) {
1716  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
1717    return $1 + '-' + $2;
1718  }).toLowerCase();
1719};
1720
1721var console = window.console;
1722/**
1723 * allow user to initialize classes via .js-namespace class
1724 * htmlInit( Widget, 'widgetName' )
1725 * options are parsed from data-namespace-option attribute
1726 */
1727utils.htmlInit = function( WidgetClass, namespace ) {
1728  docReady( function() {
1729    var dashedNamespace = utils.toDashed( namespace );
1730    var elems = document.querySelectorAll( '.js-' + dashedNamespace );
1731    var dataAttr = 'data-' + dashedNamespace + '-options';
1732
1733    for ( var i=0, len = elems.length; i < len; i++ ) {
1734      var elem = elems[i];
1735      var attr = elem.getAttribute( dataAttr );
1736      var options;
1737      try {
1738        options = attr && JSON.parse( attr );
1739      } catch ( error ) {
1740        // log error, do not initialize
1741        if ( console ) {
1742          console.error( 'Error parsing ' + dataAttr + ' on ' +
1743            elem.nodeName.toLowerCase() + ( elem.id ? '#' + elem.id : '' ) + ': ' +
1744            error );
1745        }
1746        continue;
1747      }
1748      // initialize
1749      var instance = new WidgetClass( elem, options );
1750      // make available via $().data('layoutname')
1751      var jQuery = window.jQuery;
1752      if ( jQuery ) {
1753        jQuery.data( elem, namespace, instance );
1754      }
1755    }
1756  });
1757};
1758
1759// -----  ----- //
1760
1761return utils;
1762
1763}));
1764
1765/**
1766 * Outlayer Item
1767 */
1768
1769( function( window, factory ) {
1770  'use strict';
1771  // universal module definition
1772  if ( typeof define === 'function' && define.amd ) {
1773    // AMD
1774    define( 'outlayer/item',[
1775        'eventEmitter/EventEmitter',
1776        'get-size/get-size',
1777        'get-style-property/get-style-property',
1778        'fizzy-ui-utils/utils'
1779      ],
1780      function( EventEmitter, getSize, getStyleProperty, utils ) {
1781        return factory( window, EventEmitter, getSize, getStyleProperty, utils );
1782      }
1783    );
1784  } else if (typeof exports === 'object') {
1785    // CommonJS
1786    module.exports = factory(
1787      window,
1788      require('wolfy87-eventemitter'),
1789      require('get-size'),
1790      require('desandro-get-style-property'),
1791      require('fizzy-ui-utils')
1792    );
1793  } else {
1794    // browser global
1795    window.Outlayer = {};
1796    window.Outlayer.Item = factory(
1797      window,
1798      window.EventEmitter,
1799      window.getSize,
1800      window.getStyleProperty,
1801      window.fizzyUIUtils
1802    );
1803  }
1804
1805}( window, function factory( window, EventEmitter, getSize, getStyleProperty, utils ) {
1806'use strict';
1807
1808// ----- helpers ----- //
1809
1810var getComputedStyle = window.getComputedStyle;
1811var getStyle = getComputedStyle ?
1812  function( elem ) {
1813    return getComputedStyle( elem, null );
1814  } :
1815  function( elem ) {
1816    return elem.currentStyle;
1817  };
1818
1819
1820function isEmptyObj( obj ) {
1821  for ( var prop in obj ) {
1822    return false;
1823  }
1824  prop = null;
1825  return true;
1826}
1827
1828// -------------------------- CSS3 support -------------------------- //
1829
1830var transitionProperty = getStyleProperty('transition');
1831var transformProperty = getStyleProperty('transform');
1832var supportsCSS3 = transitionProperty && transformProperty;
1833var is3d = !!getStyleProperty('perspective');
1834
1835var transitionEndEvent = {
1836  WebkitTransition: 'webkitTransitionEnd',
1837  MozTransition: 'transitionend',
1838  OTransition: 'otransitionend',
1839  transition: 'transitionend'
1840}[ transitionProperty ];
1841
1842// properties that could have vendor prefix
1843var prefixableProperties = [
1844  'transform',
1845  'transition',
1846  'transitionDuration',
1847  'transitionProperty'
1848];
1849
1850// cache all vendor properties
1851var vendorProperties = ( function() {
1852  var cache = {};
1853  for ( var i=0, len = prefixableProperties.length; i < len; i++ ) {
1854    var prop = prefixableProperties[i];
1855    var supportedProp = getStyleProperty( prop );
1856    if ( supportedProp && supportedProp !== prop ) {
1857      cache[ prop ] = supportedProp;
1858    }
1859  }
1860  return cache;
1861})();
1862
1863// -------------------------- Item -------------------------- //
1864
1865function Item( element, layout ) {
1866  if ( !element ) {
1867    return;
1868  }
1869
1870  this.element = element;
1871  // parent layout class, i.e. Masonry, Isotope, or Packery
1872  this.layout = layout;
1873  this.position = {
1874    x: 0,
1875    y: 0
1876  };
1877
1878  this._create();
1879}
1880
1881// inherit EventEmitter
1882utils.extend( Item.prototype, EventEmitter.prototype );
1883
1884Item.prototype._create = function() {
1885  // transition objects
1886  this._transn = {
1887    ingProperties: {},
1888    clean: {},
1889    onEnd: {}
1890  };
1891
1892  this.css({
1893    position: 'absolute'
1894  });
1895};
1896
1897// trigger specified handler for event type
1898Item.prototype.handleEvent = function( event ) {
1899  var method = 'on' + event.type;
1900  if ( this[ method ] ) {
1901    this[ method ]( event );
1902  }
1903};
1904
1905Item.prototype.getSize = function() {
1906  this.size = getSize( this.element );
1907};
1908
1909/**
1910 * apply CSS styles to element
1911 * @param {Object} style
1912 */
1913Item.prototype.css = function( style ) {
1914  var elemStyle = this.element.style;
1915
1916  for ( var prop in style ) {
1917    // use vendor property if available
1918    var supportedProp = vendorProperties[ prop ] || prop;
1919    elemStyle[ supportedProp ] = style[ prop ];
1920  }
1921};
1922
1923 // measure position, and sets it
1924Item.prototype.getPosition = function() {
1925  var style = getStyle( this.element );
1926  var layoutOptions = this.layout.options;
1927  var isOriginLeft = layoutOptions.isOriginLeft;
1928  var isOriginTop = layoutOptions.isOriginTop;
1929  var xValue = style[ isOriginLeft ? 'left' : 'right' ];
1930  var yValue = style[ isOriginTop ? 'top' : 'bottom' ];
1931  // convert percent to pixels
1932  var layoutSize = this.layout.size;
1933  var x = xValue.indexOf('%') != -1 ?
1934    ( parseFloat( xValue ) / 100 ) * layoutSize.width : parseInt( xValue, 10 );
1935  var y = yValue.indexOf('%') != -1 ?
1936    ( parseFloat( yValue ) / 100 ) * layoutSize.height : parseInt( yValue, 10 );
1937
1938  // clean up 'auto' or other non-integer values
1939  x = isNaN( x ) ? 0 : x;
1940  y = isNaN( y ) ? 0 : y;
1941  // remove padding from measurement
1942  x -= isOriginLeft ? layoutSize.paddingLeft : layoutSize.paddingRight;
1943  y -= isOriginTop ? layoutSize.paddingTop : layoutSize.paddingBottom;
1944
1945  this.position.x = x;
1946  this.position.y = y;
1947};
1948
1949// set settled position, apply padding
1950Item.prototype.layoutPosition = function() {
1951  var layoutSize = this.layout.size;
1952  var layoutOptions = this.layout.options;
1953  var style = {};
1954
1955  // x
1956  var xPadding = layoutOptions.isOriginLeft ? 'paddingLeft' : 'paddingRight';
1957  var xProperty = layoutOptions.isOriginLeft ? 'left' : 'right';
1958  var xResetProperty = layoutOptions.isOriginLeft ? 'right' : 'left';
1959
1960  var x = this.position.x + layoutSize[ xPadding ];
1961  // set in percentage or pixels
1962  style[ xProperty ] = this.getXValue( x );
1963  // reset other property
1964  style[ xResetProperty ] = '';
1965
1966  // y
1967  var yPadding = layoutOptions.isOriginTop ? 'paddingTop' : 'paddingBottom';
1968  var yProperty = layoutOptions.isOriginTop ? 'top' : 'bottom';
1969  var yResetProperty = layoutOptions.isOriginTop ? 'bottom' : 'top';
1970
1971  var y = this.position.y + layoutSize[ yPadding ];
1972  // set in percentage or pixels
1973  style[ yProperty ] = this.getYValue( y );
1974  // reset other property
1975  style[ yResetProperty ] = '';
1976
1977  this.css( style );
1978  this.emitEvent( 'layout', [ this ] );
1979};
1980
1981Item.prototype.getXValue = function( x ) {
1982  var layoutOptions = this.layout.options;
1983  return layoutOptions.percentPosition && !layoutOptions.isHorizontal ?
1984    ( ( x / this.layout.size.width ) * 100 ) + '%' : x + 'px';
1985};
1986
1987Item.prototype.getYValue = function( y ) {
1988  var layoutOptions = this.layout.options;
1989  return layoutOptions.percentPosition && layoutOptions.isHorizontal ?
1990    ( ( y / this.layout.size.height ) * 100 ) + '%' : y + 'px';
1991};
1992
1993
1994Item.prototype._transitionTo = function( x, y ) {
1995  this.getPosition();
1996  // get current x & y from top/left
1997  var curX = this.position.x;
1998  var curY = this.position.y;
1999
2000  var compareX = parseInt( x, 10 );
2001  var compareY = parseInt( y, 10 );
2002  var didNotMove = compareX === this.position.x && compareY === this.position.y;
2003
2004  // save end position
2005  this.setPosition( x, y );
2006
2007  // if did not move and not transitioning, just go to layout
2008  if ( didNotMove && !this.isTransitioning ) {
2009    this.layoutPosition();
2010    return;
2011  }
2012
2013  var transX = x - curX;
2014  var transY = y - curY;
2015  var transitionStyle = {};
2016  transitionStyle.transform = this.getTranslate( transX, transY );
2017
2018  this.transition({
2019    to: transitionStyle,
2020    onTransitionEnd: {
2021      transform: this.layoutPosition
2022    },
2023    isCleaning: true
2024  });
2025};
2026
2027Item.prototype.getTranslate = function( x, y ) {
2028  // flip cooridinates if origin on right or bottom
2029  var layoutOptions = this.layout.options;
2030  x = layoutOptions.isOriginLeft ? x : -x;
2031  y = layoutOptions.isOriginTop ? y : -y;
2032
2033  if ( is3d ) {
2034    return 'translate3d(' + x + 'px, ' + y + 'px, 0)';
2035  }
2036
2037  return 'translate(' + x + 'px, ' + y + 'px)';
2038};
2039
2040// non transition + transform support
2041Item.prototype.goTo = function( x, y ) {
2042  this.setPosition( x, y );
2043  this.layoutPosition();
2044};
2045
2046// use transition and transforms if supported
2047Item.prototype.moveTo = supportsCSS3 ?
2048  Item.prototype._transitionTo : Item.prototype.goTo;
2049
2050Item.prototype.setPosition = function( x, y ) {
2051  this.position.x = parseInt( x, 10 );
2052  this.position.y = parseInt( y, 10 );
2053};
2054
2055// ----- transition ----- //
2056
2057/**
2058 * @param {Object} style - CSS
2059 * @param {Function} onTransitionEnd
2060 */
2061
2062// non transition, just trigger callback
2063Item.prototype._nonTransition = function( args ) {
2064  this.css( args.to );
2065  if ( args.isCleaning ) {
2066    this._removeStyles( args.to );
2067  }
2068  for ( var prop in args.onTransitionEnd ) {
2069    args.onTransitionEnd[ prop ].call( this );
2070  }
2071};
2072
2073/**
2074 * proper transition
2075 * @param {Object} args - arguments
2076 *   @param {Object} to - style to transition to
2077 *   @param {Object} from - style to start transition from
2078 *   @param {Boolean} isCleaning - removes transition styles after transition
2079 *   @param {Function} onTransitionEnd - callback
2080 */
2081Item.prototype._transition = function( args ) {
2082  // redirect to nonTransition if no transition duration
2083  if ( !parseFloat( this.layout.options.transitionDuration ) ) {
2084    this._nonTransition( args );
2085    return;
2086  }
2087
2088  var _transition = this._transn;
2089  // keep track of onTransitionEnd callback by css property
2090  for ( var prop in args.onTransitionEnd ) {
2091    _transition.onEnd[ prop ] = args.onTransitionEnd[ prop ];
2092  }
2093  // keep track of properties that are transitioning
2094  for ( prop in args.to ) {
2095    _transition.ingProperties[ prop ] = true;
2096    // keep track of properties to clean up when transition is done
2097    if ( args.isCleaning ) {
2098      _transition.clean[ prop ] = true;
2099    }
2100  }
2101
2102  // set from styles
2103  if ( args.from ) {
2104    this.css( args.from );
2105    // force redraw. http://blog.alexmaccaw.com/css-transitions
2106    var h = this.element.offsetHeight;
2107    // hack for JSHint to hush about unused var
2108    h = null;
2109  }
2110  // enable transition
2111  this.enableTransition( args.to );
2112  // set styles that are transitioning
2113  this.css( args.to );
2114
2115  this.isTransitioning = true;
2116
2117};
2118
2119// dash before all cap letters, including first for
2120// WebkitTransform => -webkit-transform
2121function toDashedAll( str ) {
2122  return str.replace( /([A-Z])/g, function( $1 ) {
2123    return '-' + $1.toLowerCase();
2124  });
2125}
2126
2127var transitionProps = 'opacity,' +
vendor: 11,190 bytes, lines 2128-2574
2128  toDashedAll( vendorProperties.transform || 'transform' );
2129
2130Item.prototype.enableTransition = function(/* style */) {
2131  // HACK changing transitionProperty during a transition
2132  // will cause transition to jump
2133  if ( this.isTransitioning ) {
2134    return;
2135  }
2136
2137  // make `transition: foo, bar, baz` from style object
2138  // HACK un-comment this when enableTransition can work
2139  // while a transition is happening
2140  // var transitionValues = [];
2141  // for ( var prop in style ) {
2142  //   // dash-ify camelCased properties like WebkitTransition
2143  //   prop = vendorProperties[ prop ] || prop;
2144  //   transitionValues.push( toDashedAll( prop ) );
2145  // }
2146  // enable transition styles
2147  this.css({
2148    transitionProperty: transitionProps,
2149    transitionDuration: this.layout.options.transitionDuration
2150  });
2151  // listen for transition end event
2152  this.element.addEventListener( transitionEndEvent, this, false );
2153};
2154
2155Item.prototype.transition = Item.prototype[ transitionProperty ? '_transition' : '_nonTransition' ];
2156
2157// ----- events ----- //
2158
2159Item.prototype.onwebkitTransitionEnd = function( event ) {
2160  this.ontransitionend( event );
2161};
2162
2163Item.prototype.onotransitionend = function( event ) {
2164  this.ontransitionend( event );
2165};
2166
2167// properties that I munge to make my life easier
2168var dashedVendorProperties = {
2169  '-webkit-transform': 'transform',
2170  '-moz-transform': 'transform',
2171  '-o-transform': 'transform'
2172};
2173
2174Item.prototype.ontransitionend = function( event ) {
2175  // disregard bubbled events from children
2176  if ( event.target !== this.element ) {
2177    return;
2178  }
2179  var _transition = this._transn;
2180  // get property name of transitioned property, convert to prefix-free
2181  var propertyName = dashedVendorProperties[ event.propertyName ] || event.propertyName;
2182
2183  // remove property that has completed transitioning
2184  delete _transition.ingProperties[ propertyName ];
2185  // check if any properties are still transitioning
2186  if ( isEmptyObj( _transition.ingProperties ) ) {
2187    // all properties have completed transitioning
2188    this.disableTransition();
2189  }
2190  // clean style
2191  if ( propertyName in _transition.clean ) {
2192    // clean up style
2193    this.element.style[ event.propertyName ] = '';
2194    delete _transition.clean[ propertyName ];
2195  }
2196  // trigger onTransitionEnd callback
2197  if ( propertyName in _transition.onEnd ) {
2198    var onTransitionEnd = _transition.onEnd[ propertyName ];
2199    onTransitionEnd.call( this );
2200    delete _transition.onEnd[ propertyName ];
2201  }
2202
2203  this.emitEvent( 'transitionEnd', [ this ] );
2204};
2205
2206Item.prototype.disableTransition = function() {
2207  this.removeTransitionStyles();
2208  this.element.removeEventListener( transitionEndEvent, this, false );
2209  this.isTransitioning = false;
2210};
2211
2212/**
2213 * removes style property from element
2214 * @param {Object} style
2215**/
2216Item.prototype._removeStyles = function( style ) {
2217  // clean up transition styles
2218  var cleanStyle = {};
2219  for ( var prop in style ) {
2220    cleanStyle[ prop ] = '';
2221  }
2222  this.css( cleanStyle );
2223};
2224
2225var cleanTransitionStyle = {
2226  transitionProperty: '',
2227  transitionDuration: ''
2228};
2229
2230Item.prototype.removeTransitionStyles = function() {
2231  // remove transition
2232  this.css( cleanTransitionStyle );
2233};
2234
2235// ----- show/hide/remove ----- //
2236
2237// remove element from DOM
2238Item.prototype.removeElem = function() {
2239  this.element.parentNode.removeChild( this.element );
2240  // remove display: none
2241  this.css({ display: '' });
2242  this.emitEvent( 'remove', [ this ] );
2243};
2244
2245Item.prototype.remove = function() {
2246  // just remove element if no transition support or no transition
2247  if ( !transitionProperty || !parseFloat( this.layout.options.transitionDuration ) ) {
2248    this.removeElem();
2249    return;
2250  }
2251
2252  // start transition
2253  var _this = this;
2254  this.once( 'transitionEnd', function() {
2255    _this.removeElem();
2256  });
2257  this.hide();
2258};
2259
2260Item.prototype.reveal = function() {
2261  delete this.isHidden;
2262  // remove display: none
2263  this.css({ display: '' });
2264
2265  var options = this.layout.options;
2266
2267  var onTransitionEnd = {};
2268  var transitionEndProperty = this.getHideRevealTransitionEndProperty('visibleStyle');
2269  onTransitionEnd[ transitionEndProperty ] = this.onRevealTransitionEnd;
2270
2271  this.transition({
2272    from: options.hiddenStyle,
2273    to: options.visibleStyle,
2274    isCleaning: true,
2275    onTransitionEnd: onTransitionEnd
2276  });
2277};
2278
2279Item.prototype.onRevealTransitionEnd = function() {
2280  // check if still visible
2281  // during transition, item may have been hidden
2282  if ( !this.isHidden ) {
2283    this.emitEvent('reveal');
2284  }
2285};
2286
2287/**
2288 * get style property use for hide/reveal transition end
2289 * @param {String} styleProperty - hiddenStyle/visibleStyle
2290 * @returns {String}
2291 */
2292Item.prototype.getHideRevealTransitionEndProperty = function( styleProperty ) {
2293  var optionStyle = this.layout.options[ styleProperty ];
2294  // use opacity
2295  if ( optionStyle.opacity ) {
2296    return 'opacity';
2297  }
2298  // get first property
2299  for ( var prop in optionStyle ) {
2300    return prop;
2301  }
2302};
2303
2304Item.prototype.hide = function() {
2305  // set flag
2306  this.isHidden = true;
2307  // remove display: none
2308  this.css({ display: '' });
2309
2310  var options = this.layout.options;
2311
2312  var onTransitionEnd = {};
2313  var transitionEndProperty = this.getHideRevealTransitionEndProperty('hiddenStyle');
2314  onTransitionEnd[ transitionEndProperty ] = this.onHideTransitionEnd;
2315
2316  this.transition({
2317    from: options.visibleStyle,
2318    to: options.hiddenStyle,
2319    // keep hidden stuff hidden
2320    isCleaning: true,
2321    onTransitionEnd: onTransitionEnd
2322  });
2323};
2324
2325Item.prototype.onHideTransitionEnd = function() {
2326  // check if still hidden
2327  // during transition, item may have been un-hidden
2328  if ( this.isHidden ) {
2329    this.css({ display: 'none' });
2330    this.emitEvent('hide');
2331  }
2332};
2333
2334Item.prototype.destroy = function() {
2335  this.css({
2336    position: '',
2337    left: '',
2338    right: '',
2339    top: '',
2340    bottom: '',
2341    transition: '',
2342    transform: ''
2343  });
2344};
2345
2346return Item;
2347
2348}));
2349
2350/*!
2351 * Outlayer v1.4.2
2352 * the brains and guts of a layout library
2353 * MIT license
2354 */
2355
2356( function( window, factory ) {
2357  'use strict';
2358  // universal module definition
2359
2360  if ( typeof define == 'function' && define.amd ) {
2361    // AMD
2362    define( 'outlayer/outlayer',[
2363        'eventie/eventie',
2364        'eventEmitter/EventEmitter',
2365        'get-size/get-size',
2366        'fizzy-ui-utils/utils',
2367        './item'
2368      ],
2369      function( eventie, EventEmitter, getSize, utils, Item ) {
2370        return factory( window, eventie, EventEmitter, getSize, utils, Item);
2371      }
2372    );
2373  } else if ( typeof exports == 'object' ) {
2374    // CommonJS
2375    module.exports = factory(
2376      window,
2377      require('eventie'),
2378      require('wolfy87-eventemitter'),
2379      require('get-size'),
2380      require('fizzy-ui-utils'),
2381      require('./item')
2382    );
2383  } else {
2384    // browser global
2385    window.Outlayer = factory(
2386      window,
2387      window.eventie,
2388      window.EventEmitter,
2389      window.getSize,
2390      window.fizzyUIUtils,
2391      window.Outlayer.Item
2392    );
2393  }
2394
2395}( window, function factory( window, eventie, EventEmitter, getSize, utils, Item ) {
2396'use strict';
2397
2398// ----- vars ----- //
2399
2400var console = window.console;
2401var jQuery = window.jQuery;
2402var noop = function() {};
2403
2404// -------------------------- Outlayer -------------------------- //
2405
2406// globally unique identifiers
2407var GUID = 0;
2408// internal store of all Outlayer intances
2409var instances = {};
2410
2411
2412/**
2413 * @param {Element, String} element
2414 * @param {Object} options
2415 * @constructor
2416 */
2417function Outlayer( element, options ) {
2418  var queryElement = utils.getQueryElement( element );
2419  if ( !queryElement ) {
2420    if ( console ) {
2421      console.error( 'Bad element for ' + this.constructor.namespace +
2422        ': ' + ( queryElement || element ) );
2423    }
2424    return;
2425  }
2426  this.element = queryElement;
2427  // add jQuery
2428  if ( jQuery ) {
2429    this.$element = jQuery( this.element );
2430  }
2431
2432  // options
2433  this.options = utils.extend( {}, this.constructor.defaults );
2434  this.option( options );
2435
2436  // add id for Outlayer.getFromElement
2437  var id = ++GUID;
2438  this.element.outlayerGUID = id; // expando
2439  instances[ id ] = this; // associate via id
2440
2441  // kick it off
2442  this._create();
2443
2444  if ( this.options.isInitLayout ) {
2445    this.layout();
2446  }
2447}
2448
2449// settings are for internal use only
2450Outlayer.namespace = 'outlayer';
2451Outlayer.Item = Item;
2452
2453// default options
2454Outlayer.defaults = {
2455  containerStyle: {
2456    position: 'relative'
2457  },
2458  isInitLayout: true,
2459  isOriginLeft: true,
2460  isOriginTop: true,
2461  isResizeBound: true,
2462  isResizingContainer: true,
2463  // item options
2464  transitionDuration: '0.4s',
2465  hiddenStyle: {
2466    opacity: 0,
2467    transform: 'scale(0.001)'
2468  },
2469  visibleStyle: {
2470    opacity: 1,
2471    transform: 'scale(1)'
2472  }
2473};
2474
2475// inherit EventEmitter
2476utils.extend( Outlayer.prototype, EventEmitter.prototype );
2477
2478/**
2479 * set options
2480 * @param {Object} opts
2481 */
2482Outlayer.prototype.option = function( opts ) {
2483  utils.extend( this.options, opts );
2484};
2485
2486Outlayer.prototype._create = function() {
2487  // get items from children
2488  this.reloadItems();
2489  // elements that affect layout, but are not laid out
2490  this.stamps = [];
2491  this.stamp( this.options.stamp );
2492  // set container style
2493  utils.extend( this.element.style, this.options.containerStyle );
2494
2495  // bind resize method
2496  if ( this.options.isResizeBound ) {
2497    this.bindResize();
2498  }
2499};
2500
2501// goes through all children again and gets bricks in proper order
2502Outlayer.prototype.reloadItems = function() {
2503  // collection of item elements
2504  this.items = this._itemize( this.element.children );
2505};
2506
2507
2508/**
2509 * turn elements into Outlayer.Items to be used in layout
2510 * @param {Array or NodeList or HTMLElement} elems
2511 * @returns {Array} items - collection of new Outlayer Items
2512 */
2513Outlayer.prototype._itemize = function( elems ) {
2514
2515  var itemElems = this._filterFindItemElements( elems );
2516  var Item = this.constructor.Item;
2517
2518  // create new Outlayer Items for collection
2519  var items = [];
2520  for ( var i=0, len = itemElems.length; i < len; i++ ) {
2521    var elem = itemElems[i];
2522    var item = new Item( elem, this );
2523    items.push( item );
2524  }
2525
2526  return items;
2527};
2528
2529/**
2530 * get item elements to be used in layout
2531 * @param {Array or NodeList or HTMLElement} elems
2532 * @returns {Array} items - item elements
2533 */
2534Outlayer.prototype._filterFindItemElements = function( elems ) {
2535  return utils.filterFindElements( elems, this.options.itemSelector );
2536};
2537
2538/**
2539 * getter method for getting item elements
2540 * @returns {Array} elems - collection of item elements
2541 */
2542Outlayer.prototype.getItemElements = function() {
2543  var elems = [];
2544  for ( var i=0, len = this.items.length; i < len; i++ ) {
2545    elems.push( this.items[i].element );
2546  }
2547  return elems;
2548};
2549
2550// ----- init & layout ----- //
2551
2552/**
2553 * lays out all items
2554 */
2555Outlayer.prototype.layout = function() {
2556  this._resetLayout();
2557  this._manageStamps();
2558
2559  // don't animate first layout
2560  var isInstant = this.options.isLayoutInstant !== undefined ?
2561    this.options.isLayoutInstant : !this._isLayoutInited;
2562  this.layoutItems( this.items, isInstant );
2563
2564  // flag for initalized
2565  this._isLayoutInited = true;
2566};
2567
2568// _init is alias for layout
2569Outlayer.prototype._init = Outlayer.prototype.layout;
2570
2571/**
2572 * logic before any new layout
2573 */
2574Outlayer.prototype._resetLayout = function() {
2575  this.getSize();
2576};
2577
2578
2579Outlayer.prototype.getSize = function() {
2580  this.size = getSize( this.element );
2581};
2582
2583/**
2584 * get measurement from option, for columnWidth, rowHeight, gutter
2585 * if option is String -> get element from selector string, & get size of element
2586 * if option is Element -> get size of element
2587 * else use option as a number
2588 *
2589 * @param {String} measurement
2590 * @param {String} size - width or height
2591 * @private
2592 */
2593Outlayer.prototype._getMeasurement = function( measurement, size ) {
2594  var option = this.options[ measurement ];
2595  var elem;
2596  if ( !option ) {
2597    // default to 0
2598    this[ measurement ] = 0;
2599  } else {
2600    // use option as an element
2601    if ( typeof option === 'string' ) {
2602      elem = this.element.querySelector( option );
2603    } else if ( utils.isElement( option ) ) {
2604      elem = option;
2605    }
2606    // use size of element, if element
2607    this[ measurement ] = elem ? getSize( elem )[ size ] : option;
2608  }
2609};
2610
2611/**
2612 * layout a collection of item elements
2613 * @api public
2614 */
2615Outlayer.prototype.layoutItems = function( items, isInstant ) {
2616  items = this._getItemsForLayout( items );
2617
2618  this._layoutItems( items, isInstant );
2619
2620  this._postLayout();
2621};
2622
2623/**
2624 * get the items to be laid out
2625 * you may want to skip over some items
2626 * @param {Array} items
2627 * @returns {Array} items
2628 */
2629Outlayer.prototype._getItemsForLayout = function( items ) {
2630  var layoutItems = [];
2631  for ( var i=0, len = items.length; i < len; i++ ) {
2632    var item = items[i];
2633    if ( !item.isIgnored ) {
2634      layoutItems.push( item );
2635    }
2636  }
2637  return layoutItems;
2638};
2639
2640/**
2641 * layout items
2642 * @param {Array} items
2643 * @param {Boolean} isInstant
2644 */
2645Outlayer.prototype._layoutItems = function( items, isInstant ) {
2646  this._emitCompleteOnItems( 'layout', items );
2647
2648  if ( !items || !items.length ) {
2649    // no items, emit event with empty array
2650    return;
2651  }
2652
2653  var queue = [];
2654
2655  for ( var i=0, len = items.length; i < len; i++ ) {
2656    var item = items[i];
2657    // get x/y object from method
2658    var position = this._getItemLayoutPosition( item );
2659    // enqueue
2660    position.item = item;
2661    position.isInstant = isInstant || item.isLayoutInstant;
2662    queue.push( position );
2663  }
2664
2665  this._processLayoutQueue( queue );
2666};
2667
2668/**
2669 * get item layout position
2670 * @param {Outlayer.Item} item
2671 * @returns {Object} x and y position
2672 */
2673Outlayer.prototype._getItemLayoutPosition = function( /* item */ ) {
2674  return {
2675    x: 0,
2676    y: 0
2677  };
2678};
2679
2680/**
2681 * iterate over array and position each item
2682 * Reason being - separating this logic prevents 'layout invalidation'
2683 * thx @paul_irish
2684 * @param {Array} queue
2685 */
2686Outlayer.prototype._processLayoutQueue = function( queue ) {
2687  for ( var i=0, len = queue.length; i < len; i++ ) {
2688    var obj = queue[i];
2689    this._positionItem( obj.item, obj.x, obj.y, obj.isInstant );
2690  }
2691};
2692
2693/**
2694 * Sets position of item in DOM
2695 * @param {Outlayer.Item} item
2696 * @param {Number} x - horizontal position
2697 * @param {Number} y - vertical position
2698 * @param {Boolean} isInstant - disables transitions
2699 */
2700Outlayer.prototype._positionItem = function( item, x, y, isInstant ) {
2701  if ( isInstant ) {
2702    // if not transition, just set CSS
2703    item.goTo( x, y );
2704  } else {
2705    item.moveTo( x, y );
2706  }
2707};
2708
2709/**
2710 * Any logic you want to do after each layout,
2711 * i.e. size the container
2712 */
2713Outlayer.prototype._postLayout = function() {
2714  this.resizeContainer();
2715};
2716
2717Outlayer.prototype.resizeContainer = function() {
2718  if ( !this.options.isResizingContainer ) {
2719    return;
2720  }
2721  var size = this._getContainerSize();
2722  if ( size ) {
2723    this._setContainerMeasure( size.width, true );
2724    this._setContainerMeasure( size.height, false );
2725  }
2726};
2727
2728/**
2729 * Sets width or height of container if returned
2730 * @returns {Object} size
2731 *   @param {Number} width
2732 *   @param {Number} height
2733 */
2734Outlayer.prototype._getContainerSize = noop;
2735
2736/**
2737 * @param {Number} measure - size of width or height
2738 * @param {Boolean} isWidth
2739 */
2740Outlayer.prototype._setContainerMeasure = function( measure, isWidth ) {
2741  if ( measure === undefined ) {
2742    return;
2743  }
2744
2745  var elemSize = this.size;
2746  // add padding and border width if border box
2747  if ( elemSize.isBorderBox ) {
2748    measure += isWidth ? elemSize.paddingLeft + elemSize.paddingRight +
2749      elemSize.borderLeftWidth + elemSize.borderRightWidth :
2750      elemSize.paddingBottom + elemSize.paddingTop +
2751      elemSize.borderTopWidth + elemSize.borderBottomWidth;
2752  }
2753
2754  measure = Math.max( measure, 0 );
2755  this.element.style[ isWidth ? 'width' : 'height' ] = measure + 'px';
2756};
2757
2758/**
2759 * emit eventComplete on a collection of items events
2760 * @param {String} eventName
2761 * @param {Array} items - Outlayer.Items
2762 */
2763Outlayer.prototype._emitCompleteOnItems = function( eventName, items ) {
2764  var _this = this;
2765  function onComplete() {
2766    _this.dispatchEvent( eventName + 'Complete', null, [ items ] );
2767  }
2768
2769  var count = items.length;
2770  if ( !items || !count ) {
2771    onComplete();
2772    return;
2773  }
2774
2775  var doneCount = 0;
2776  function tick() {
2777    doneCount++;
2778    if ( doneCount === count ) {
2779      onComplete();
2780    }
2781  }
2782
2783  // bind callback
2784  for ( var i=0, len = items.length; i < len; i++ ) {
2785    var item = items[i];
2786    item.once( eventName, tick );
2787  }
2788};
2789
2790/**
2791 * emits events via eventEmitter and jQuery events
2792 * @param {String} type - name of event
2793 * @param {Event} event - original event
2794 * @param {Array} args - extra arguments
2795 */
2796Outlayer.prototype.dispatchEvent = function( type, event, args ) {
2797  // add original event to arguments
2798  var emitArgs = event ? [ event ].concat( args ) : args;
2799  this.emitEvent( type, emitArgs );
2800
2801  if ( jQuery ) {
2802    // set this.$element
2803    this.$element = this.$element || jQuery( this.element );
2804    if ( event ) {
2805      // create jQuery event
2806      var $event = jQuery.Event( event );
2807      $event.type = type;
2808      this.$element.trigger( $event, args );
2809    } else {
2810      // just trigger with type if no event available
2811      this.$element.trigger( type, args );
2812    }
2813  }
2814};
2815
2816// -------------------------- ignore & stamps -------------------------- //
2817
2818
2819/**
2820 * keep item in collection, but do not lay it out
2821 * ignored items do not get skipped in layout
2822 * @param {Element} elem
2823 */
2824Outlayer.prototype.ignore = function( elem ) {
2825  var item = this.getItem( elem );
2826  if ( item ) {
2827    item.isIgnored = true;
2828  }
2829};
2830
2831/**
2832 * return item to layout collection
2833 * @param {Element} elem
2834 */
2835Outlayer.prototype.unignore = function( elem ) {
2836  var item = this.getItem( elem );
2837  if ( item ) {
2838    delete item.isIgnored;
2839  }
2840};
2841
2842/**
2843 * adds elements to stamps
2844 * @param {NodeList, Array, Element, or String} elems
2845 */
2846Outlayer.prototype.stamp = function( elems ) {
2847  elems = this._find( elems );
2848  if ( !elems ) {
2849    return;
2850  }
2851
2852  this.stamps = this.stamps.concat( elems );
2853  // ignore
2854  for ( var i=0, len = elems.length; i < len; i++ ) {
2855    var elem = elems[i];
2856    this.ignore( elem );
2857  }
2858};
2859
2860/**
2861 * removes elements to stamps
2862 * @param {NodeList, Array, or Element} elems
2863 */
2864Outlayer.prototype.unstamp = function( elems ) {
2865  elems = this._find( elems );
2866  if ( !elems ){
2867    return;
2868  }
2869
2870  for ( var i=0, len = elems.length; i < len; i++ ) {
2871    var elem = elems[i];
2872    // filter out removed stamp elements
2873    utils.removeFrom( this.stamps, elem );
2874    this.unignore( elem );
2875  }
2876
2877};
2878
2879/**
2880 * finds child elements
2881 * @param {NodeList, Array, Element, or String} elems
2882 * @returns {Array} elems
2883 */
2884Outlayer.prototype._find = function( elems ) {
2885  if ( !elems ) {
2886    return;
2887  }
2888  // if string, use argument as selector string
2889  if ( typeof elems === 'string' ) {
2890    elems = this.element.querySelectorAll( elems );
2891  }
2892  elems = utils.makeArray( elems );
2893  return elems;
2894};
2895
2896Outlayer.prototype._manageStamps = function() {
2897  if ( !this.stamps || !this.stamps.length ) {
2898    return;
2899  }
2900
2901  this._getBoundingRect();
2902
2903  for ( var i=0, len = this.stamps.length; i < len; i++ ) {
2904    var stamp = this.stamps[i];
2905    this._manageStamp( stamp );
2906  }
2907};
2908
2909// update boundingLeft / Top
2910Outlayer.prototype._getBoundingRect = function() {
2911  // get bounding rect for container element
2912  var boundingRect = this.element.getBoundingClientRect();
2913  var size = this.size;
2914  this._boundingRect = {
2915    left: boundingRect.left + size.paddingLeft + size.borderLeftWidth,
2916    top: boundingRect.top + size.paddingTop + size.borderTopWidth,
2917    right: boundingRect.right - ( size.paddingRight + size.borderRightWidth ),
2918    bottom: boundingRect.bottom - ( size.paddingBottom + size.borderBottomWidth )
2919  };
2920};
2921
2922/**
2923 * @param {Element} stamp
2924**/
2925Outlayer.prototype._manageStamp = noop;
2926
2927/**
2928 * get x/y position of element relative to container element
2929 * @param {Element} elem
2930 * @returns {Object} offset - has left, top, right, bottom
2931 */
2932Outlayer.prototype._getElementOffset = function( elem ) {
2933  var boundingRect = elem.getBoundingClientRect();
2934  var thisRect = this._boundingRect;
2935  var size = getSize( elem );
2936  var offset = {
2937    left: boundingRect.left - thisRect.left - size.marginLeft,
2938    top: boundingRect.top - thisRect.top - size.marginTop,
2939    right: thisRect.right - boundingRect.right - size.marginRight,
2940    bottom: thisRect.bottom - boundingRect.bottom - size.marginBottom
2941  };
2942  return offset;
2943};
2944
2945// -------------------------- resize -------------------------- //
2946
2947// enable event handlers for listeners
2948// i.e. resize -> onresize
2949Outlayer.prototype.handleEvent = function( event ) {
2950  var method = 'on' + event.type;
2951  if ( this[ method ] ) {
2952    this[ method ]( event );
2953  }
2954};
2955
2956/**
2957 * Bind layout to window resizing
2958 */
2959Outlayer.prototype.bindResize = function() {
2960  // bind just one listener
2961  if ( this.isResizeBound ) {
2962    return;
2963  }
2964  eventie.bind( window, 'resize', this );
2965  this.isResizeBound = true;
2966};
2967
2968/**
2969 * Unbind layout to window resizing
2970 */
2971Outlayer.prototype.unbindResize = function() {
2972  if ( this.isResizeBound ) {
2973    eventie.unbind( window, 'resize', this );
2974  }
2975  this.isResizeBound = false;
2976};
2977
2978// original debounce by John Hann
2979// http://unscriptable.com/index.php/2009/03/20/debouncing-javascript-methods/
2980
2981// this fires every resize
2982Outlayer.prototype.onresize = function() {
2983  if ( this.resizeTimeout ) {
2984    clearTimeout( this.resizeTimeout );
2985  }
2986
2987  var _this = this;
2988  function delayed() {
2989    _this.resize();
2990    delete _this.resizeTimeout;
2991  }
2992
2993  this.resizeTimeout = setTimeout( delayed, 100 );
2994};
2995
2996// debounced, layout on resize
2997Outlayer.prototype.resize = function() {
2998  // don't trigger if size did not change
2999  // or if resize was unbound. See #9
3000  if ( !this.isResizeBound || !this.needsResizeLayout() ) {
3001    return;
3002  }
3003
3004  this.layout();
3005};
3006
3007/**
3008 * check if layout is needed post layout
3009 * @returns Boolean
3010 */
3011Outlayer.prototype.needsResizeLayout = function() {
3012  var size = getSize( this.element );
3013  // check that this.size and size are there
3014  // IE8 triggers resize on body size change, so they might not be
3015  var hasSizes = this.size && size;
3016  return hasSizes && size.innerWidth !== this.size.innerWidth;
3017};
3018
3019// -------------------------- methods -------------------------- //
3020
3021/**
3022 * add items to Outlayer instance
3023 * @param {Array or NodeList or Element} elems
3024 * @returns {Array} items - Outlayer.Items
3025**/
3026Outlayer.prototype.addItems = function( elems ) {
3027  var items = this._itemize( elems );
3028  // add items to collection
3029  if ( items.length ) {
3030    this.items = this.items.concat( items );
3031  }
3032  return items;
3033};
3034
3035/**
3036 * Layout newly-appended item elements
3037 * @param {Array or NodeList or Element} elems
3038 */
3039Outlayer.prototype.appended = function( elems ) {
3040  var items = this.addItems( elems );
3041  if ( !items.length ) {
3042    return;
3043  }
3044  // layout and reveal just the new items
3045  this.layoutItems( items, true );
3046  this.reveal( items );
3047};
3048
3049/**
3050 * Layout prepended elements
3051 * @param {Array or NodeList or Element} elems
3052 */
3053Outlayer.prototype.prepended = function( elems ) {
3054  var items = this._itemize( elems );
3055  if ( !items.length ) {
3056    return;
3057  }
3058  // add items to beginning of collection
3059  var previousItems = this.items.slice(0);
3060  this.items = items.concat( previousItems );
3061  // start new layout
3062  this._resetLayout();
3063  this._manageStamps();
3064  // layout new stuff without transition
3065  this.layoutItems( items, true );
3066  this.reveal( items );
3067  // layout previous items
3068  this.layoutItems( previousItems );
3069};
3070
3071/**
3072 * reveal a collection of items
3073 * @param {Array of Outlayer.Items} items
3074 */
3075Outlayer.prototype.reveal = function( items ) {
3076  this._emitCompleteOnItems( 'reveal', items );
3077
3078  var len = items && items.length;
3079  for ( var i=0; len && i < len; i++ ) {
3080    var item = items[i];
3081    item.reveal();
3082  }
3083};
3084
3085/**
3086 * hide a collection of items
3087 * @param {Array of Outlayer.Items} items
3088 */
3089Outlayer.prototype.hide = function( items ) {
3090  this._emitCompleteOnItems( 'hide', items );
3091
3092  var len = items && items.length;
3093  for ( var i=0; len && i < len; i++ ) {
3094    var item = items[i];
3095    item.hide();
3096  }
3097};
3098
3099/**
3100 * reveal item elements
3101 * @param {Array}, {Element}, {NodeList} items
3102 */
3103Outlayer.prototype.revealItemElements = function( elems ) {
3104  var items = this.getItems( elems );
3105  this.reveal( items );
3106};
3107
3108/**
3109 * hide item elements
3110 * @param {Array}, {Element}, {NodeList} items
3111 */
3112Outlayer.prototype.hideItemElements = function( elems ) {
3113  var items = this.getItems( elems );
3114  this.hide( items );
3115};
3116
3117/**
3118 * get Outlayer.Item, given an Element
3119 * @param {Element} elem
3120 * @param {Function} callback
3121 * @returns {Outlayer.Item} item
3122 */
3123Outlayer.prototype.getItem = function( elem ) {
3124  // loop through items to get the one that matches
3125  for ( var i=0, len = this.items.length; i < len; i++ ) {
3126    var item = this.items[i];
3127    if ( item.element === elem ) {
3128      // return item
3129      return item;
3130    }
3131  }
3132};
3133
3134/**
3135 * get collection of Outlayer.Items, given Elements
3136 * @param {Array} elems
3137 * @returns {Array} items - Outlayer.Items
3138 */
3139Outlayer.prototype.getItems = function( elems ) {
3140  elems = utils.makeArray( elems );
3141  var items = [];
3142  for ( var i=0, len = elems.length; i < len; i++ ) {
3143    var elem = elems[i];
3144    var item = this.getItem( elem );
3145    if ( item ) {
3146      items.push( item );
3147    }
3148  }
3149
3150  return items;
3151};
3152
3153/**
3154 * remove element(s) from instance and DOM
3155 * @param {Array or NodeList or Element} elems
3156 */
3157Outlayer.prototype.remove = function( elems ) {
3158  var removeItems = this.getItems( elems );
3159
3160  this._emitCompleteOnItems( 'remove', removeItems );
3161
3162  // bail if no items to remove
3163  if ( !removeItems || !removeItems.length ) {
3164    return;
3165  }
3166
3167  for ( var i=0, len = removeItems.length; i < len; i++ ) {
3168    var item = removeItems[i];
3169    item.remove();
3170    // remove item from collection
3171    utils.removeFrom( this.items, item );
3172  }
3173};
3174
3175// ----- destroy ----- //
3176
3177// remove and disable Outlayer instance
3178Outlayer.prototype.destroy = function() {
3179  // clean up dynamic styles
3180  var style = this.element.style;
3181  style.height = '';
3182  style.position = '';
3183  style.width = '';
3184  // destroy items
3185  for ( var i=0, len = this.items.length; i < len; i++ ) {
3186    var item = this.items[i];
3187    item.destroy();
3188  }
3189
3190  this.unbindResize();
3191
3192  var id = this.element.outlayerGUID;
3193  delete instances[ id ]; // remove reference to instance by id
3194  delete this.element.outlayerGUID;
3195  // remove data for jQuery
3196  if ( jQuery ) {
3197    jQuery.removeData( this.element, this.constructor.namespace );
3198  }
3199
3200};
3201
3202// -------------------------- data -------------------------- //
3203
3204/**
3205 * get Outlayer instance from element
3206 * @param {Element} elem
3207 * @returns {Outlayer}
3208 */
3209Outlayer.data = function( elem ) {
3210  elem = utils.getQueryElement( elem );
3211  var id = elem && elem.outlayerGUID;
3212  return id && instances[ id ];
3213};
3214
3215
3216// -------------------------- create Outlayer class -------------------------- //
3217
3218/**
3219 * create a layout class
3220 * @param {String} namespace
3221 */
3222Outlayer.create = function( namespace, options ) {
3223  // sub-class Outlayer
3224  function Layout() {
3225    Outlayer.apply( this, arguments );
3226  }
3227  // inherit Outlayer prototype, use Object.create if there
3228  if ( Object.create ) {
3229    Layout.prototype = Object.create( Outlayer.prototype );
3230  } else {
3231    utils.extend( Layout.prototype, Outlayer.prototype );
3232  }
3233  // set contructor, used for namespace and Item
3234  Layout.prototype.constructor = Layout;
3235
3236  Layout.defaults = utils.extend( {}, Outlayer.defaults );
3237  // apply new options
3238  utils.extend( Layout.defaults, options );
3239  // keep prototype.settings for backwards compatibility (Packery v1.2.0)
3240  Layout.prototype.settings = {};
3241
3242  Layout.namespace = namespace;
3243
3244  Layout.data = Outlayer.data;
3245
3246  // sub-class Item
3247  Layout.Item = function LayoutItem() {
3248    Item.apply( this, arguments );
3249  };
3250
3251  Layout.Item.prototype = new Item();
3252
3253  // -------------------------- declarative -------------------------- //
3254
3255  utils.htmlInit( Layout, namespace );
3256
3257  // -------------------------- jQuery bridge -------------------------- //
3258
3259  // make into jQuery plugin
3260  if ( jQuery && jQuery.bridget ) {
3261    jQuery.bridget( namespace, Layout );
3262  }
3263
3264  return Layout;
3265};
3266
3267// ----- fin ----- //
3268
3269// back in global
3270Outlayer.Item = Item;
3271
3272return Outlayer;
3273
3274}));
3275
3276
3277/**
3278 * Isotope Item
3279**/
3280
3281( function( window, factory ) {
3282'use strict';
3283  // universal module definition
3284  if ( typeof define == 'function' && define.amd ) {
3285    // AMD
3286    define( 'isotope/js/item',[
3287        'outlayer/outlayer'
3288      ],
3289      factory );
3290  } else if ( typeof exports == 'object' ) {
3291    // CommonJS
3292    module.exports = factory(
3293      require('outlayer')
3294    );
3295  } else {
3296    // browser global
3297    window.Isotope = window.Isotope || {};
3298    window.Isotope.Item = factory(
3299      window.Outlayer
3300    );
3301  }
3302
3303}( window, function factory( Outlayer ) {
3304'use strict';
3305
3306// -------------------------- Item -------------------------- //
3307
3308// sub-class Outlayer Item
3309function Item() {
3310  Outlayer.Item.apply( this, arguments );
3311}
3312
3313Item.prototype = new Outlayer.Item();
3314
3315Item.prototype._create = function() {
3316  // assign id, used for original-order sorting
3317  this.id = this.layout.itemGUID++;
3318  Outlayer.Item.prototype._create.call( this );
3319  this.sortData = {};
3320};
3321
3322Item.prototype.updateSortData = function() {
3323  if ( this.isIgnored ) {
3324    return;
3325  }
3326  // default sorters
3327  this.sortData.id = this.id;
3328  // for backward compatibility
3329  this.sortData['original-order'] = this.id;
3330  this.sortData.random = Math.random();
3331  // go thru getSortData obj and apply the sorters
3332  var getSortData = this.layout.options.getSortData;
3333  var sorters = this.layout._sorters;
3334  for ( var key in getSortData ) {
3335    var sorter = sorters[ key ];
3336    this.sortData[ key ] = sorter( this.element, this );
3337  }
3338};
3339
3340var _destroy = Item.prototype.destroy;
3341Item.prototype.destroy = function() {
3342  // call super
3343  _destroy.apply( this, arguments );
3344  // reset display, #741
3345  this.css({
3346    display: ''
3347  });
3348};
3349
3350return Item;
3351
3352}));
3353
3354/**
3355 * Isotope LayoutMode
3356 */
3357
3358( function( window, factory ) {
3359  'use strict';
3360  // universal module definition
3361
3362  if ( typeof define == 'function' && define.amd ) {
3363    // AMD
3364    define( 'isotope/js/layout-mode',[
3365        'get-size/get-size',
3366        'outlayer/outlayer'
3367      ],
3368      factory );
3369  } else if ( typeof exports == 'object' ) {
3370    // CommonJS
3371    module.exports = factory(
3372      require('get-size'),
3373      require('outlayer')
3374    );
3375  } else {
3376    // browser global
3377    window.Isotope = window.Isotope || {};
3378    window.Isotope.LayoutMode = factory(
3379      window.getSize,
3380      window.Outlayer
3381    );
3382  }
3383
3384}( window, function factory( getSize, Outlayer ) {
3385  'use strict';
3386
3387  // layout mode class
3388  function LayoutMode( isotope ) {
3389    this.isotope = isotope;
3390    // link properties
3391    if ( isotope ) {
3392      this.options = isotope.options[ this.namespace ];
3393      this.element = isotope.element;
3394      this.items = isotope.filteredItems;
3395      this.size = isotope.size;
3396    }
3397  }
3398
3399  /**
3400   * some methods should just defer to default Outlayer method
3401   * and reference the Isotope instance as `this`
3402  **/
3403  ( function() {
3404    var facadeMethods = [
3405      '_resetLayout',
3406      '_getItemLayoutPosition',
3407      '_manageStamp',
3408      '_getContainerSize',
3409      '_getElementOffset',
3410      'needsResizeLayout'
3411    ];
3412
3413    for ( var i=0, len = facadeMethods.length; i < len; i++ ) {
3414      var methodName = facadeMethods[i];
3415      LayoutMode.prototype[ methodName ] = getOutlayerMethod( methodName );
3416    }
3417
3418    function getOutlayerMethod( methodName ) {
3419      return function() {
3420        return Outlayer.prototype[ methodName ].apply( this.isotope, arguments );
3421      };
3422    }
3423  })();
3424
3425  // -----  ----- //
3426
3427  // for horizontal layout modes, check vertical size
3428  LayoutMode.prototype.needsVerticalResizeLayout = function() {
vendor: 20,029 bytes, lines 3429-4164
3429    // don't trigger if size did not change
3430    var size = getSize( this.isotope.element );
3431    // check that this.size and size are there
3432    // IE8 triggers resize on body size change, so they might not be
3433    var hasSizes = this.isotope.size && size;
3434    return hasSizes && size.innerHeight != this.isotope.size.innerHeight;
3435  };
3436
3437  // ----- measurements ----- //
3438
3439  LayoutMode.prototype._getMeasurement = function() {
3440    this.isotope._getMeasurement.apply( this, arguments );
3441  };
3442
3443  LayoutMode.prototype.getColumnWidth = function() {
3444    this.getSegmentSize( 'column', 'Width' );
3445  };
3446
3447  LayoutMode.prototype.getRowHeight = function() {
3448    this.getSegmentSize( 'row', 'Height' );
3449  };
3450
3451  /**
3452   * get columnWidth or rowHeight
3453   * segment: 'column' or 'row'
3454   * size 'Width' or 'Height'
3455  **/
3456  LayoutMode.prototype.getSegmentSize = function( segment, size ) {
3457    var segmentName = segment + size;
3458    var outerSize = 'outer' + size;
3459    // columnWidth / outerWidth // rowHeight / outerHeight
3460    this._getMeasurement( segmentName, outerSize );
3461    // got rowHeight or columnWidth, we can chill
3462    if ( this[ segmentName ] ) {
3463      return;
3464    }
3465    // fall back to item of first element
3466    var firstItemSize = this.getFirstItemSize();
3467    this[ segmentName ] = firstItemSize && firstItemSize[ outerSize ] ||
3468      // or size of container
3469      this.isotope.size[ 'inner' + size ];
3470  };
3471
3472  LayoutMode.prototype.getFirstItemSize = function() {
3473    var firstItem = this.isotope.filteredItems[0];
3474    return firstItem && firstItem.element && getSize( firstItem.element );
3475  };
3476
3477  // ----- methods that should reference isotope ----- //
3478
3479  LayoutMode.prototype.layout = function() {
3480    this.isotope.layout.apply( this.isotope, arguments );
3481  };
3482
3483  LayoutMode.prototype.getSize = function() {
3484    this.isotope.getSize();
3485    this.size = this.isotope.size;
3486  };
3487
3488  // -------------------------- create -------------------------- //
3489
3490  LayoutMode.modes = {};
3491
3492  LayoutMode.create = function( namespace, options ) {
3493
3494    function Mode() {
3495      LayoutMode.apply( this, arguments );
3496    }
3497
3498    Mode.prototype = new LayoutMode();
3499
3500    // default options
3501    if ( options ) {
3502      Mode.options = options;
3503    }
3504
3505    Mode.prototype.namespace = namespace;
3506    // register in Isotope
3507    LayoutMode.modes[ namespace ] = Mode;
3508
3509    return Mode;
3510  };
3511
3512  return LayoutMode;
3513
3514}));
3515
3516/*!
3517 * Masonry v3.3.1
3518 * Cascading grid layout library
3519 * http://masonry.desandro.com
3520 * MIT License
3521 * by David DeSandro
3522 */
3523
3524( function( window, factory ) {
3525  'use strict';
3526  // universal module definition
3527  if ( typeof define === 'function' && define.amd ) {
3528    // AMD
3529    define( 'masonry/masonry',[
3530        'outlayer/outlayer',
3531        'get-size/get-size',
3532        'fizzy-ui-utils/utils'
3533      ],
3534      factory );
3535  } else if ( typeof exports === 'object' ) {
3536    // CommonJS
3537    module.exports = factory(
3538      require('outlayer'),
3539      require('get-size'),
3540      require('fizzy-ui-utils')
3541    );
3542  } else {
3543    // browser global
3544    window.Masonry = factory(
3545      window.Outlayer,
3546      window.getSize,
3547      window.fizzyUIUtils
3548    );
3549  }
3550
3551}( window, function factory( Outlayer, getSize, utils ) {
3552
3553
3554
3555// -------------------------- masonryDefinition -------------------------- //
3556
3557  // create an Outlayer layout class
3558  var Masonry = Outlayer.create('masonry');
3559
3560  Masonry.prototype._resetLayout = function() {
3561    this.getSize();
3562    this._getMeasurement( 'columnWidth', 'outerWidth' );
3563    this._getMeasurement( 'gutter', 'outerWidth' );
3564    this.measureColumns();
3565
3566    // reset column Y
3567    var i = this.cols;
3568    this.colYs = [];
3569    while (i--) {
3570      this.colYs.push( 0 );
3571    }
3572
3573    this.maxY = 0;
3574  };
3575
3576  Masonry.prototype.measureColumns = function() {
3577    this.getContainerWidth();
3578    // if columnWidth is 0, default to outerWidth of first item
3579    if ( !this.columnWidth ) {
3580      var firstItem = this.items[0];
3581      var firstItemElem = firstItem && firstItem.element;
3582      // columnWidth fall back to item of first element
3583      this.columnWidth = firstItemElem && getSize( firstItemElem ).outerWidth ||
3584        // if first elem has no width, default to size of container
3585        this.containerWidth;
3586    }
3587
3588    var columnWidth = this.columnWidth += this.gutter;
3589
3590    // calculate columns
3591    var containerWidth = this.containerWidth + this.gutter;
3592    var cols = containerWidth / columnWidth;
3593    // fix rounding errors, typically with gutters
3594    var excess = columnWidth - containerWidth % columnWidth;
3595    // if overshoot is less than a pixel, round up, otherwise floor it
3596    var mathMethod = excess && excess < 1 ? 'round' : 'floor';
3597    cols = Math[ mathMethod ]( cols );
3598    this.cols = Math.max( cols, 1 );
3599  };
3600
3601  Masonry.prototype.getContainerWidth = function() {
3602    // container is parent if fit width
3603    var container = this.options.isFitWidth ? this.element.parentNode : this.element;
3604    // check that this.size and size are there
3605    // IE8 triggers resize on body size change, so they might not be
3606    var size = getSize( container );
3607    this.containerWidth = size && size.innerWidth;
3608  };
3609
3610  Masonry.prototype._getItemLayoutPosition = function( item ) {
3611    item.getSize();
3612    // how many columns does this brick span
3613    var remainder = item.size.outerWidth % this.columnWidth;
3614    var mathMethod = remainder && remainder < 1 ? 'round' : 'ceil';
3615    // round if off by 1 pixel, otherwise use ceil
3616    var colSpan = Math[ mathMethod ]( item.size.outerWidth / this.columnWidth );
3617    colSpan = Math.min( colSpan, this.cols );
3618
3619    var colGroup = this._getColGroup( colSpan );
3620    // get the minimum Y value from the columns
3621    var minimumY = Math.min.apply( Math, colGroup );
3622    var shortColIndex = utils.indexOf( colGroup, minimumY );
3623
3624    // position the brick
3625    var position = {
3626      x: this.columnWidth * shortColIndex,
3627      y: minimumY
3628    };
3629
3630    // apply setHeight to necessary columns
3631    var setHeight = minimumY + item.size.outerHeight;
3632    var setSpan = this.cols + 1 - colGroup.length;
3633    for ( var i = 0; i < setSpan; i++ ) {
3634      this.colYs[ shortColIndex + i ] = setHeight;
3635    }
3636
3637    return position;
3638  };
3639
3640  /**
3641   * @param {Number} colSpan - number of columns the element spans
3642   * @returns {Array} colGroup
3643   */
3644  Masonry.prototype._getColGroup = function( colSpan ) {
3645    if ( colSpan < 2 ) {
3646      // if brick spans only one column, use all the column Ys
3647      return this.colYs;
3648    }
3649
3650    var colGroup = [];
3651    // how many different places could this brick fit horizontally
3652    var groupCount = this.cols + 1 - colSpan;
3653    // for each group potential horizontal position
3654    for ( var i = 0; i < groupCount; i++ ) {
3655      // make an array of colY values for that one group
3656      var groupColYs = this.colYs.slice( i, i + colSpan );
3657      // and get the max value of the array
3658      colGroup[i] = Math.max.apply( Math, groupColYs );
3659    }
3660    return colGroup;
3661  };
3662
3663  Masonry.prototype._manageStamp = function( stamp ) {
3664    var stampSize = getSize( stamp );
3665    var offset = this._getElementOffset( stamp );
3666    // get the columns that this stamp affects
3667    var firstX = this.options.isOriginLeft ? offset.left : offset.right;
3668    var lastX = firstX + stampSize.outerWidth;
3669    var firstCol = Math.floor( firstX / this.columnWidth );
3670    firstCol = Math.max( 0, firstCol );
3671    var lastCol = Math.floor( lastX / this.columnWidth );
3672    // lastCol should not go over if multiple of columnWidth #425
3673    lastCol -= lastX % this.columnWidth ? 0 : 1;
3674    lastCol = Math.min( this.cols - 1, lastCol );
3675    // set colYs to bottom of the stamp
3676    var stampMaxY = ( this.options.isOriginTop ? offset.top : offset.bottom ) +
3677      stampSize.outerHeight;
3678    for ( var i = firstCol; i <= lastCol; i++ ) {
3679      this.colYs[i] = Math.max( stampMaxY, this.colYs[i] );
3680    }
3681  };
3682
3683  Masonry.prototype._getContainerSize = function() {
3684    this.maxY = Math.max.apply( Math, this.colYs );
3685    var size = {
3686      height: this.maxY
3687    };
3688
3689    if ( this.options.isFitWidth ) {
3690      size.width = this._getContainerFitWidth();
3691    }
3692
3693    return size;
3694  };
3695
3696  Masonry.prototype._getContainerFitWidth = function() {
3697    var unusedCols = 0;
3698    // count unused columns
3699    var i = this.cols;
3700    while ( --i ) {
3701      if ( this.colYs[i] !== 0 ) {
3702        break;
3703      }
3704      unusedCols++;
3705    }
3706    // fit container to columns that have been used
3707    return ( this.cols - unusedCols ) * this.columnWidth - this.gutter;
3708  };
3709
3710  Masonry.prototype.needsResizeLayout = function() {
3711    var previousWidth = this.containerWidth;
3712    this.getContainerWidth();
3713    return previousWidth !== this.containerWidth;
3714  };
3715
3716  return Masonry;
3717
3718}));
3719
3720/*!
3721 * Masonry layout mode
3722 * sub-classes Masonry
3723 * http://masonry.desandro.com
3724 */
3725
3726( function( window, factory ) {
3727  'use strict';
3728  // universal module definition
3729  if ( typeof define == 'function' && define.amd ) {
3730    // AMD
3731    define( 'isotope/js/layout-modes/masonry',[
3732        '../layout-mode',
3733        'masonry/masonry'
3734      ],
3735      factory );
3736  } else if ( typeof exports == 'object' ) {
3737    // CommonJS
3738    module.exports = factory(
3739      require('../layout-mode'),
3740      require('masonry-layout')
3741    );
3742  } else {
3743    // browser global
3744    factory(
3745      window.Isotope.LayoutMode,
3746      window.Masonry
3747    );
3748  }
3749
3750}( window, function factory( LayoutMode, Masonry ) {
3751'use strict';
3752
3753// -------------------------- helpers -------------------------- //
3754
3755// extend objects
3756function extend( a, b ) {
3757  for ( var prop in b ) {
3758    a[ prop ] = b[ prop ];
3759  }
3760  return a;
3761}
3762
3763// -------------------------- masonryDefinition -------------------------- //
3764
3765  // create an Outlayer layout class
3766  var MasonryMode = LayoutMode.create('masonry');
3767
3768  // save on to these methods
3769  var _getElementOffset = MasonryMode.prototype._getElementOffset;
3770  var layout = MasonryMode.prototype.layout;
3771  var _getMeasurement = MasonryMode.prototype._getMeasurement;
3772
3773  // sub-class Masonry
3774  extend( MasonryMode.prototype, Masonry.prototype );
3775
3776  // set back, as it was overwritten by Masonry
3777  MasonryMode.prototype._getElementOffset = _getElementOffset;
3778  MasonryMode.prototype.layout = layout;
3779  MasonryMode.prototype._getMeasurement = _getMeasurement;
3780
3781  var measureColumns = MasonryMode.prototype.measureColumns;
3782  MasonryMode.prototype.measureColumns = function() {
3783    // set items, used if measuring first item
3784    this.items = this.isotope.filteredItems;
3785    measureColumns.call( this );
3786  };
3787
3788  // HACK copy over isOriginLeft/Top options
3789  var _manageStamp = MasonryMode.prototype._manageStamp;
3790  MasonryMode.prototype._manageStamp = function() {
3791    this.options.isOriginLeft = this.isotope.options.isOriginLeft;
3792    this.options.isOriginTop = this.isotope.options.isOriginTop;
3793    _manageStamp.apply( this, arguments );
3794  };
3795
3796  return MasonryMode;
3797
3798}));
3799
3800/**
3801 * fitRows layout mode
3802 */
3803
3804( function( window, factory ) {
3805  'use strict';
3806  // universal module definition
3807  if ( typeof define == 'function' && define.amd ) {
3808    // AMD
3809    define( 'isotope/js/layout-modes/fit-rows',[
3810        '../layout-mode'
3811      ],
3812      factory );
3813  } else if ( typeof exports == 'object' ) {
3814    // CommonJS
3815    module.exports = factory(
3816      require('../layout-mode')
3817    );
3818  } else {
3819    // browser global
3820    factory(
3821      window.Isotope.LayoutMode
3822    );
3823  }
3824
3825}( window, function factory( LayoutMode ) {
3826'use strict';
3827
3828var FitRows = LayoutMode.create('fitRows');
3829
3830FitRows.prototype._resetLayout = function() {
3831  this.x = 0;
3832  this.y = 0;
3833  this.maxY = 0;
3834  this._getMeasurement( 'gutter', 'outerWidth' );
3835};
3836
3837FitRows.prototype._getItemLayoutPosition = function( item ) {
3838  item.getSize();
3839
3840  var itemWidth = item.size.outerWidth + this.gutter;
3841  // if this element cannot fit in the current row
3842  var containerWidth = this.isotope.size.innerWidth + this.gutter;
3843  if ( this.x !== 0 && itemWidth + this.x > containerWidth ) {
3844    this.x = 0;
3845    this.y = this.maxY;
3846  }
3847
3848  var position = {
3849    x: this.x,
3850    y: this.y
3851  };
3852
3853  this.maxY = Math.max( this.maxY, this.y + item.size.outerHeight );
3854  this.x += itemWidth;
3855
3856  return position;
3857};
3858
3859FitRows.prototype._getContainerSize = function() {
3860  return { height: this.maxY };
3861};
3862
3863return FitRows;
3864
3865}));
3866
3867/**
3868 * vertical layout mode
3869 */
3870
3871( function( window, factory ) {
3872  'use strict';
3873  // universal module definition
3874  if ( typeof define == 'function' && define.amd ) {
3875    // AMD
3876    define( 'isotope/js/layout-modes/vertical',[
3877        '../layout-mode'
3878      ],
3879      factory );
3880  } else if ( typeof exports == 'object' ) {
3881    // CommonJS
3882    module.exports = factory(
3883      require('../layout-mode')
3884    );
3885  } else {
3886    // browser global
3887    factory(
3888      window.Isotope.LayoutMode
3889    );
3890  }
3891
3892}( window, function factory( LayoutMode ) {
3893'use strict';
3894
3895var Vertical = LayoutMode.create( 'vertical', {
3896  horizontalAlignment: 0
3897});
3898
3899Vertical.prototype._resetLayout = function() {
3900  this.y = 0;
3901};
3902
3903Vertical.prototype._getItemLayoutPosition = function( item ) {
3904  item.getSize();
3905  var x = ( this.isotope.size.innerWidth - item.size.outerWidth ) *
3906    this.options.horizontalAlignment;
3907  var y = this.y;
3908  this.y += item.size.outerHeight;
3909  return { x: x, y: y };
3910};
3911
3912Vertical.prototype._getContainerSize = function() {
3913  return { height: this.y };
3914};
3915
3916return Vertical;
3917
3918}));
3919
3920/*!
3921 * Isotope v2.2.2
3922 *
3923 * Licensed GPLv3 for open source use
3924 * or Isotope Commercial License for commercial use
3925 *
3926 * http://isotope.metafizzy.co
3927 * Copyright 2015 Metafizzy
3928 */
3929
3930( function( window, factory ) {
3931  'use strict';
3932  // universal module definition
3933
3934  if ( typeof define == 'function' && define.amd ) {
3935    // AMD
3936    define( [
3937        'outlayer/outlayer',
3938        'get-size/get-size',
3939        'matches-selector/matches-selector',
3940        'fizzy-ui-utils/utils',
3941        'isotope/js/item',
3942        'isotope/js/layout-mode',
3943        // include default layout modes
3944        'isotope/js/layout-modes/masonry',
3945        'isotope/js/layout-modes/fit-rows',
3946        'isotope/js/layout-modes/vertical'
3947      ],
3948      function( Outlayer, getSize, matchesSelector, utils, Item, LayoutMode ) {
3949        return factory( window, Outlayer, getSize, matchesSelector, utils, Item, LayoutMode );
3950      });
3951  } else if ( typeof exports == 'object' ) {
3952    // CommonJS
3953    module.exports = factory(
3954      window,
3955      require('outlayer'),
3956      require('get-size'),
3957      require('desandro-matches-selector'),
3958      require('fizzy-ui-utils'),
3959      require('./item'),
3960      require('./layout-mode'),
3961      // include default layout modes
3962      require('./layout-modes/masonry'),
3963      require('./layout-modes/fit-rows'),
3964      require('./layout-modes/vertical')
3965    );
3966  } else {
3967    // browser global
3968    window.Isotope = factory(
3969      window,
3970      window.Outlayer,
3971      window.getSize,
3972      window.matchesSelector,
3973      window.fizzyUIUtils,
3974      window.Isotope.Item,
3975      window.Isotope.LayoutMode
3976    );
3977  }
3978
3979}( window, function factory( window, Outlayer, getSize, matchesSelector, utils,
3980  Item, LayoutMode ) {
3981
3982
3983
3984// -------------------------- vars -------------------------- //
3985
3986var jQuery = window.jQuery;
3987
3988// -------------------------- helpers -------------------------- //
3989
3990var trim = String.prototype.trim ?
3991  function( str ) {
3992    return str.trim();
3993  } :
3994  function( str ) {
3995    return str.replace( /^\s+|\s+$/g, '' );
3996  };
3997
3998var docElem = document.documentElement;
3999
4000var getText = docElem.textContent ?
4001  function( elem ) {
4002    return elem.textContent;
4003  } :
4004  function( elem ) {
4005    return elem.innerText;
4006  };
4007
4008// -------------------------- isotopeDefinition -------------------------- //
4009
4010  // create an Outlayer layout class
4011  var Isotope = Outlayer.create( 'isotope', {
4012    layoutMode: "masonry",
4013    isJQueryFiltering: true,
4014    sortAscending: true
4015  });
4016
4017  Isotope.Item = Item;
4018  Isotope.LayoutMode = LayoutMode;
4019
4020  Isotope.prototype._create = function() {
4021    this.itemGUID = 0;
4022    // functions that sort items
4023    this._sorters = {};
4024    this._getSorters();
4025    // call super
4026    Outlayer.prototype._create.call( this );
4027
4028    // create layout modes
4029    this.modes = {};
4030    // start filteredItems with all items
4031    this.filteredItems = this.items;
4032    // keep of track of sortBys
4033    this.sortHistory = [ 'original-order' ];
4034    // create from registered layout modes
4035    for ( var name in LayoutMode.modes ) {
4036      this._initLayoutMode( name );
4037    }
4038  };
4039
4040  Isotope.prototype.reloadItems = function() {
4041    // reset item ID counter
4042    this.itemGUID = 0;
4043    // call super
4044    Outlayer.prototype.reloadItems.call( this );
4045  };
4046
4047  Isotope.prototype._itemize = function() {
4048    var items = Outlayer.prototype._itemize.apply( this, arguments );
4049    // assign ID for original-order
4050    for ( var i=0, len = items.length; i < len; i++ ) {
4051      var item = items[i];
4052      item.id = this.itemGUID++;
4053    }
4054    this._updateItemsSortData( items );
4055    return items;
4056  };
4057
4058
4059  // -------------------------- layout -------------------------- //
4060
4061  Isotope.prototype._initLayoutMode = function( name ) {
4062    var Mode = LayoutMode.modes[ name ];
4063    // set mode options
4064    // HACK extend initial options, back-fill in default options
4065    var initialOpts = this.options[ name ] || {};
4066    this.options[ name ] = Mode.options ?
4067      utils.extend( Mode.options, initialOpts ) : initialOpts;
4068    // init layout mode instance
4069    this.modes[ name ] = new Mode( this );
4070  };
4071
4072
4073  Isotope.prototype.layout = function() {
4074    // if first time doing layout, do all magic
4075    if ( !this._isLayoutInited && this.options.isInitLayout ) {
4076      this.arrange();
4077      return;
4078    }
4079    this._layout();
4080  };
4081
4082  // private method to be used in layout() & magic()
4083  Isotope.prototype._layout = function() {
4084    // don't animate first layout
4085    var isInstant = this._getIsInstant();
4086    // layout flow
4087    this._resetLayout();
4088    this._manageStamps();
4089    this.layoutItems( this.filteredItems, isInstant );
4090
4091    // flag for initalized
4092    this._isLayoutInited = true;
4093  };
4094
4095  // filter + sort + layout
4096  Isotope.prototype.arrange = function( opts ) {
4097    // set any options pass
4098    this.option( opts );
4099    this._getIsInstant();
4100    // filter, sort, and layout
4101
4102    // filter
4103    var filtered = this._filter( this.items );
4104    this.filteredItems = filtered.matches;
4105
4106    var _this = this;
4107    function hideReveal() {
4108      _this.reveal( filtered.needReveal );
4109      _this.hide( filtered.needHide );
4110    }
4111
4112    this._bindArrangeComplete();
4113
4114    if ( this._isInstant ) {
4115      this._noTransition( hideReveal );
4116    } else {
4117      hideReveal();
4118    }
4119
4120    this._sort();
4121    this._layout();
4122  };
4123  // alias to _init for main plugin method
4124  Isotope.prototype._init = Isotope.prototype.arrange;
4125
4126  // HACK
4127  // Don't animate/transition first layout
4128  // Or don't animate/transition other layouts
4129  Isotope.prototype._getIsInstant = function() {
4130    var isInstant = this.options.isLayoutInstant !== undefined ?
4131      this.options.isLayoutInstant : !this._isLayoutInited;
4132    this._isInstant = isInstant;
4133    return isInstant;
4134  };
4135
4136  // listen for layoutComplete, hideComplete and revealComplete
4137  // to trigger arrangeComplete
4138  Isotope.prototype._bindArrangeComplete = function() {
4139    // listen for 3 events to trigger arrangeComplete
4140    var isLayoutComplete, isHideComplete, isRevealComplete;
4141    var _this = this;
4142    function arrangeParallelCallback() {
4143      if ( isLayoutComplete && isHideComplete && isRevealComplete ) {
4144        _this.dispatchEvent( 'arrangeComplete', null, [ _this.filteredItems ] );
4145      }
4146    }
4147    this.once( 'layoutComplete', function() {
4148      isLayoutComplete = true;
4149      arrangeParallelCallback();
4150    });
4151    this.once( 'hideComplete', function() {
4152      isHideComplete = true;
4153      arrangeParallelCallback();
4154    });
4155    this.once( 'revealComplete', function() {
4156      isRevealComplete = true;
4157      arrangeParallelCallback();
4158    });
4159  };
4160
4161  // -------------------------- filter -------------------------- //
4162
4163  Isotope.prototype._filter = function( items ) {
4164    var filter = this.options.filter;
4165    filter = filter || '*';
4166    var matches = [];
4167    var hiddenMatched = [];
4168    var visibleUnmatched = [];
4169
4170    var test = this._getFilterTest( filter );
4171
4172    // test each item
4173    for ( var i=0, len = items.length; i < len; i++ ) {
4174      var item = items[i];
4175      if ( item.isIgnored ) {
4176        continue;
4177      }
4178      // add item to either matched or unmatched group
4179      var isMatched = test( item );
4180      // item.isFilterMatched = isMatched;
4181      // add to matches if its a match
4182      if ( isMatched ) {
4183        matches.push( item );
4184      }
4185      // add to additional group if item needs to be hidden or revealed
4186      if ( isMatched && item.isHidden ) {
4187        hiddenMatched.push( item );
4188      } else if ( !isMatched && !item.isHidden ) {
4189        visibleUnmatched.push( item );
4190      }
4191    }
4192
4193    // return collections of items to be manipulated
4194    return {
4195      matches: matches,
4196      needReveal: hiddenMatched,
4197      needHide: visibleUnmatched
4198    };
4199  };
4200
4201  // get a jQuery, function, or a matchesSelector test given the filter
4202  Isotope.prototype._getFilterTest = function( filter ) {
4203    if ( jQuery && this.options.isJQueryFiltering ) {
4204      // use jQuery
4205      return function( item ) {
4206        return jQuery( item.element ).is( filter );
4207      };
4208    }
4209    if ( typeof filter == 'function' ) {
4210      // use filter as function
4211      return function( item ) {
4212        return filter( item.element );
4213      };
4214    }
4215    // default, use filter as selector string
4216    return function( item ) {
4217      return matchesSelector( item.element, filter );
4218    };
4219  };
4220
4221  // -------------------------- sorting -------------------------- //
4222
4223  /**
4224   * @params {Array} elems
4225   * @public
4226   */
4227  Isotope.prototype.updateSortData = function( elems ) {
4228    // get items
4229    var items;
4230    if ( elems ) {
4231      elems = utils.makeArray( elems );
4232      items = this.getItems( elems );
4233    } else {
4234      // update all items if no elems provided
4235      items = this.items;
4236    }
4237
4238    this._getSorters();
4239    this._updateItemsSortData( items );
4240  };
4241
4242  Isotope.prototype._getSorters = function() {
4243    var getSortData = this.options.getSortData;
4244    for ( var key in getSortData ) {
4245      var sorter = getSortData[ key ];
4246      this._sorters[ key ] = mungeSorter( sorter );
4247    }
4248  };
4249
4250  /**
4251   * @params {Array} items - of Isotope.Items
4252   * @private
4253   */
4254  Isotope.prototype._updateItemsSortData = function( items ) {
4255    // do not update if no items
4256    var len = items && items.length;
4257
4258    for ( var i=0; len && i < len; i++ ) {
4259      var item = items[i];
4260      item.updateSortData();
4261    }
4262  };
4263
4264  // ----- munge sorter ----- //
4265
4266  // encapsulate this, as we just need mungeSorter
4267  // other functions in here are just for munging
4268  var mungeSorter = ( function() {
4269    // add a magic layer to sorters for convienent shorthands
4270    // `.foo-bar` will use the text of .foo-bar querySelector
4271    // `[foo-bar]` will use attribute
4272    // you can also add parser
4273    // `.foo-bar parseInt` will parse that as a number
4274    function mungeSorter( sorter ) {
4275      // if not a string, return function or whatever it is
4276      if ( typeof sorter != 'string' ) {
4277        return sorter;
4278      }
4279      // parse the sorter string
4280      var args = trim( sorter ).split(' ');
4281      var query = args[0];
4282      // check if query looks like [an-attribute]
4283      var attrMatch = query.match( /^\[(.+)\]$/ );
4284      var attr = attrMatch && attrMatch[1];
4285      var getValue = getValueGetter( attr, query );
4286      // use second argument as a parser
4287      var parser = Isotope.sortDataParsers[ args[1] ];
4288      // parse the value, if there was a parser
4289      sorter = parser ? function( elem ) {
4290        return elem && parser( getValue( elem ) );
4291      } :
4292      // otherwise just return value
4293      function( elem ) {
4294        return elem && getValue( elem );
4295      };
4296
4297      return sorter;
4298    }
4299
4300    // get an attribute getter, or get text of the querySelector
4301    function getValueGetter( attr, query ) {
4302      var getValue;
4303      // if query looks like [foo-bar], get attribute
4304      if ( attr ) {
4305        getValue = function( elem ) {
4306          return elem.getAttribute( attr );
4307        };
4308      } else {
4309        // otherwise, assume its a querySelector, and get its text
4310        getValue = function( elem ) {
4311          var child = elem.querySelector( query );
4312          return child && getText( child );
4313        };
4314      }
4315      return getValue;
4316    }
4317
4318    return mungeSorter;
4319  })();
4320
4321  // parsers used in getSortData shortcut strings
4322  Isotope.sortDataParsers = {
4323    'parseInt': function( val ) {
4324      return parseInt( val, 10 );
4325    },
4326    'parseFloat': function( val ) {
4327      return parseFloat( val );
4328    }
4329  };
4330
4331  // ----- sort method ----- //
4332
4333  // sort filteredItem order
4334  Isotope.prototype._sort = function() {
4335    var sortByOpt = this.options.sortBy;
4336    if ( !sortByOpt ) {
4337      return;
4338    }
4339    // concat all sortBy and sortHistory
4340    var sortBys = [].concat.apply( sortByOpt, this.sortHistory );
4341    // sort magic
4342    var itemSorter = getItemSorter( sortBys, this.options.sortAscending );
4343    this.filteredItems.sort( itemSorter );
4344    // keep track of sortBy History
4345    if ( sortByOpt != this.sortHistory[0] ) {
4346      // add to front, oldest goes in last
4347      this.sortHistory.unshift( sortByOpt );
4348    }
4349  };
4350
4351  // returns a function used for sorting
4352  function getItemSorter( sortBys, sortAsc ) {
4353    return function sorter( itemA, itemB ) {
4354      // cycle through all sortKeys
4355      for ( var i = 0, len = sortBys.length; i < len; i++ ) {
4356        var sortBy = sortBys[i];
4357        var a = itemA.sortData[ sortBy ];
4358        var b = itemB.sortData[ sortBy ];
4359        if ( a > b || a < b ) {
4360          // if sortAsc is an object, use the value given the sortBy key
4361          var isAscending = sortAsc[ sortBy ] !== undefined ? sortAsc[ sortBy ] : sortAsc;
4362          var direction = isAscending ? 1 : -1;
4363          return ( a > b ? 1 : -1 ) * direction;
4364        }
4365      }
4366      return 0;
4367    };
4368  }
4369
4370  // -------------------------- methods -------------------------- //
4371
4372  // get layout mode
4373  Isotope.prototype._mode = function() {
4374    var layoutMode = this.options.layoutMode;
4375    var mode = this.modes[ layoutMode ];
4376    if ( !mode ) {
4377      // TODO console.error
4378      throw new Error( 'No layout mode: ' + layoutMode );
4379    }
4380    // HACK sync mode's options
4381    // any options set after init for layout mode need to be synced
4382    mode.options = this.options[ layoutMode ];
4383    return mode;
4384  };
4385
4386  Isotope.prototype._resetLayout = function() {
4387    // trigger original reset layout
4388    Outlayer.prototype._resetLayout.call( this );
4389    this._mode()._resetLayout();
4390  };
4391
4392  Isotope.prototype._getItemLayoutPosition = function( item  ) {
4393    return this._mode()._getItemLayoutPosition( item );
4394  };
4395
4396  Isotope.prototype._manageStamp = function( stamp ) {
4397    this._mode()._manageStamp( stamp );
4398  };
4399
4400  Isotope.prototype._getContainerSize = function() {
4401    return this._mode()._getContainerSize();
4402  };
4403
4404  Isotope.prototype.needsResizeLayout = function() {
4405    return this._mode().needsResizeLayout();
4406  };
4407
4408  // -------------------------- adding & removing -------------------------- //
4409
4410  // HEADS UP overwrites default Outlayer appended
4411  Isotope.prototype.appended = function( elems ) {
4412    var items = this.addItems( elems );
4413    if ( !items.length ) {
4414      return;
4415    }
4416    // filter, layout, reveal new items
4417    var filteredItems = this._filterRevealAdded( items );
4418    // add to filteredItems
4419    this.filteredItems = this.filteredItems.concat( filteredItems );
4420  };
4421
4422  // HEADS UP overwrites default Outlayer prepended
4423  Isotope.prototype.prepended = function( elems ) {
4424    var items = this._itemize( elems );
4425    if ( !items.length ) {
4426      return;
4427    }
4428    // start new layout
4429    this._resetLayout();
4430    this._manageStamps();
4431    // filter, layout, reveal new items
4432    var filteredItems = this._filterRevealAdded( items );
4433    // layout previous items
4434    this.layoutItems( this.filteredItems );
4435    // add to items and filteredItems
4436    this.filteredItems = filteredItems.concat( this.filteredItems );
4437    this.items = items.concat( this.items );
4438  };
4439
4440  Isotope.prototype._filterRevealAdded = function( items ) {
4441    var filtered = this._filter( items );
4442    this.hide( filtered.needHide );
4443    // reveal all new items
4444    this.reveal( filtered.matches );
4445    // layout new items, no transition
4446    this.layoutItems( filtered.matches, true );
4447    return filtered.matches;
4448  };
4449
4450  /**
4451   * Filter, sort, and layout newly-appended item elements
4452   * @param {Array or NodeList or Element} elems
4453   */
4454  Isotope.prototype.insert = function( elems ) {
4455    var items = this.addItems( elems );
4456    if ( !items.length ) {
4457      return;
4458    }
4459    // append item elements
4460    var i, item;
4461    var len = items.length;
4462    for ( i=0; i < len; i++ ) {
4463      item = items[i];
4464      this.element.appendChild( item.element );
4465    }
4466    // filter new stuff
4467    var filteredInsertItems = this._filter( items ).matches;
4468    // set flag
4469    for ( i=0; i < len; i++ ) {
4470      items[i].isLayoutInstant = true;
4471    }
4472    this.arrange();
4473    // reset flag
4474    for ( i=0; i < len; i++ ) {
4475      delete items[i].isLayoutInstant;
4476    }
4477    this.reveal( filteredInsertItems );
4478  };
4479
4480  var _remove = Isotope.prototype.remove;
4481  Isotope.prototype.remove = function( elems ) {
4482    elems = utils.makeArray( elems );
4483    var removeItems = this.getItems( elems );
4484    // do regular thing
4485    _remove.call( this, elems );
4486    // bail if no items to remove
4487    var len = removeItems && removeItems.length;
4488    if ( !len ) {
4489      return;
4490    }
4491    // remove elems from filteredItems
4492    for ( var i=0; i < len; i++ ) {
4493      var item = removeItems[i];
4494      // remove item from collection
4495      utils.removeFrom( this.filteredItems, item );
4496    }
4497  };
4498
4499  Isotope.prototype.shuffle = function() {
4500    // update random sortData
4501    for ( var i=0, len = this.items.length; i < len; i++ ) {
4502      var item = this.items[i];
4503      item.sortData.random = Math.random();
4504    }
4505    this.options.sortBy = 'random';
4506    this._sort();
4507    this._layout();
4508  };
4509
4510  /**
4511   * trigger fn without transition
4512   * kind of hacky to have this in the first place
4513   * @param {Function} fn
4514   * @returns ret
4515   * @private
4516   */
4517  Isotope.prototype._noTransition = function( fn ) {
4518    // save transitionDuration before disabling
4519    var transitionDuration = this.options.transitionDuration;
4520    // disable transition
4521    this.options.transitionDuration = 0;
4522    // do it
4523    var returnValue = fn.call( this );
4524    // re-enable transition for reveal
4525    this.options.transitionDuration = transitionDuration;
4526    return returnValue;
4527  };
4528
4529  // ----- helper methods ----- //
4530
4531  /**
4532   * getter method for getting filtered item elements
4533   * @returns {Array} elems - collection of item elements
4534   */
4535  Isotope.prototype.getFilteredItemElements = function() {
4536    var elems = [];
4537    for ( var i=0, len = this.filteredItems.length; i < len; i++ ) {
4538      elems.push( this.filteredItems[i].element );
4539    }
4540    return elems;
4541  };
4542
4543  // -----  ----- //
4544
4545  return Isotope;
4546
4547}));
4548
4549
4550/*!
4551 * Packery layout mode PACKAGED v1.1.1
4552 * sub-classes Packery
4553 * http://packery.metafizzy.co
4554 */
4555
4556!function(a){function b(a){return new RegExp("(^|\\s+)"+a+"(\\s+|$)")}function c(a,b){var c=d(a,b)?f:e;c(a,b)}var d,e,f;"classList"in document.documentElement?(d=function(a,b){return a.classList.contains(b)}
4556,e=function(a,b){a.classList.add(b)},f=function(a,b){a.classList.remove(b)}):(d=function(a,c){return b(c).test(a.className)},e=function(a,b){d(a,b)||(a.className=a.className+" "+b)},f=function(a,c){a.className=a.className.replace(b(c)," ")});var g={hasClass:d,addClass:e,removeClass:f,toggleClass:c,has:d,add:e,remove:f,toggle:c};"function"==typeof define&&define.amd?define("classie/classie",g):"object"==typeof exports?module.exports=g:a.classie=g}(window),function(a){function b(){function a(b){for(var c in a.defaults)this[c]=a.defaults[c];for(c in b)this[c]=b[c]}return c.Rect=a,a.defaults={x:0,y:0,width:0,height:0},a.prototype.contains=function(a){var b=a.width||0,c=a.height||0;return this.x<=a.x&&this.y<=a.y&&this.x+this.width>=a.x+b&&this.y+this.height>=a.y+c},a.prototype.overlaps=function(a){var b=this.x+this.width,c=this.y+this.height,d=a.x+a.width,e=a.y+a.height;return this.x<d&&b>a.x&&this.y<e&&c>a.y},a.prototype.getMaximalFreeRects=function(b){if(!this.overlaps(b))return!1;var c,d=[],e=this.x+this.width,f=this.y+this.height,g=b.x+b.width,h=b.y+b.height;return this.y<b.y&&(c=new a({x:this.x,y:this.y,width:this.width,height:b.y-this.y}),d.push(c)),e>g&&(c=new a({x:g,y:this.y,width:e-g,height:this.height}),d.push(c)),f>h&&(c=new a({x:this.x,y:h,width:this.width,height:f-h}),d.push(c)),this.x<b.x&&(c=new a({x:this.x,y:this.y,width:b.x-this.x,height:this.height}),d.push(c)),d},a.prototype.canFit=function(a){return this.width>=a.width&&this.height>=a.height},a}var c=a.Packery=function(){};"function"==typeof define&&define.amd?define("packery/js/rect",b):"object"==typeof exports?module.exports=b():(a.Packery=a.Packery||{},a.Packery.Rect=b())}(window),function(a){function b(a){function b(a,b,c){this.width=a||0,this.height=b||0,this.sortDirection=c||"downwardLeftToRight",this.reset()}b.prototype.reset=function(){this.spaces=[],this.newSpaces=[];var b=new a({x:0,y:0,width:this.width,height:this.height});this.spaces.push(b),this.sorter=c[this.sortDirection]||c.downwardLeftToRight},b.prototype.pack=function(a){for(var b=0,c=this.spaces.length;c>b;b++){var d=this.spaces[b];if(d.canFit(a)){this.placeInSpace(a,d);break}}},b.prototype.placeInSpace=function(a,b){a.x=b.x,a.y=b.y,this.placed(a)},b.prototype.placed=function(a){for(var b=[],c=0,d=this.spaces.length;d>c;c++){var e=this.spaces[c],f=e.getMaximalFreeRects(a);f?b.push.apply(b,f):b.push(e)}this.spaces=b,this.mergeSortSpaces()},b.prototype.mergeSortSpaces=function(){b.mergeRects(this.spaces),this.spaces.sort(this.sorter)},b.prototype.addSpace=function(a){this.spaces.push(a),this.mergeSortSpaces()},b.mergeRects=function(a){for(var b=0,c=a.length;c>b;b++){var d=a[b];if(d){var e=a.slice(0);e.splice(b,1);for(var f=0,g=0,h=e.length;h>g;g++){var i=e[g],j=b>g?0:1;d.contains(i)&&(a.splice(g+j-f,1),f++)}}}return a};var c={downwardLeftToRight:function(a,b){return a.y-b.y||a.x-b.x},rightwardTopToBottom:function(a,b){return a.x-b.x||a.y-b.y}};return b}if("function"==typeof define&&define.amd)define("packery/js/packer",["./rect"],b);else if("object"==typeof exports)module.exports=b(require("./rect"));else{var c=a.Packery=a.Packery||{};c.Packer=b(c.Rect)}}(window),function(a){function b(a,b,c){var d=a("transform"),e=function(){b.Item.apply(this,arguments)};e.prototype=new b.Item;var f=e.prototype._create;return e.prototype._create=function(){f.call(this),this.rect=new c,this.placeRect=new c},e.prototype.dragStart=function(){this.getPosition(),this.removeTransitionStyles(),this.isTransitioning&&d&&(this.element.style[d]="none"),this.getSize(),this.isPlacing=!0,this.needsPositioning=!1,this.positionPlaceRect(this.position.x,this.position.y),this.isTransitioning=!1,this.didDrag=!1},e.prototype.dragMove=function(a,b){this.didDrag=!0;var c=this.layout.size;a-=c.paddingLeft,b-=c.paddingTop,this.positionPlaceRect(a,b)},e.prototype.dragStop=function(){this.getPosition();var a=this.position.x!==this.placeRect.x,b=this.position.y!==this.placeRect.y;this.needsPositioning=a||b,this.didDrag=!1},e.prototype.positionPlaceRect=function(a,b,c){this.placeRect.x=this.getPlaceRectCoord(a,!0),this.placeRect.y=this.getPlaceRectCoord(b,!1,c)},e.prototype.getPlaceRectCoord=function(a,b,c){var d=b?"Width":"Height",e=this.size["outer"+d],f=this.layout[b?"columnWidth":"rowHeight"],g=this.layout.size["inner"+d];b||(g=Math.max(g,this.layout.maxY),this.layout.rowHeight||(g-=this.layout.gutter));var h;if(f){f+=this.layout.gutter,g+=b?this.layout.gutter:0,a=Math.round(a/f);var i;i=this.layout.options.isHorizontal?b?"ceil":"floor":b?"floor":"ceil";var j=Math[i](g/f);j-=Math.ceil(e/f),h=j}else h=g-e;return a=c?a:Math.min(a,h),a*=f||1,Math.max(0,a)},e.prototype.copyPlaceRectPosition=function(){this.rect.x=this.placeRect.x,this.rect.y=this.placeRect.y},e.prototype.removeElem=function(){this.element.parentNode.removeChild(this.element),this.layout.packer.addSpace(this.rect),this.emitEvent("remove",[this])},e}"function"==typeof define&&define.amd?define("packery/js/item",["get-style-property/get-style-property","outlayer/outlayer","./rect"],b):"object"==typeof exports?module.exports=b(require("desandro-get-style-property"),require("outlayer"),require("./rect")):a.Packery.Item=b(a.getStyleProperty,a.Outlayer,a.Packery.Rect)}(window),function(a){function b(a,b,c,d,e,f){function g(a,b){return a.position.y-b.position.y||a.position.x-b.position.x}function h(a,b){return a.position.x-b.position.x||a.position.y-b.position.y}d.prototype.canFit=function(a){return this.width>=a.width-1&&this.height>=a.height-1};var i=c.create("packery");return i.Item=f,i.prototype._create=function(){c.prototype._create.call(this),this.packer=new e,this.stamp(this.options.stamped);var a=this;this.handleDraggabilly={dragStart:function(b){a.itemDragStart(b.element)},dragMove:function(b){a.itemDragMove(b.element,b.position.x,b.position.y)},dragEnd:function(b){a.itemDragEnd(b.element)}},this.handleUIDraggable={start:function(b){a.itemDragStart(b.currentTarget)},drag:function(b,c){a.itemDragMove(b.currentTarget,c.position.left,c.position.top)},stop:function(b){a.itemDragEnd(b.currentTarget)}}}
4556,i.prototype._resetLayout=function(){this.getSize(),this._getMeasurements();var a=this.packer;this.options.isHorizontal?(a.width=Number.POSITIVE_INFINITY,a.height=this.size.innerHeight+this.gutter,a.sortDirection="rightwardTopToBottom"):(a.width=this.size.innerWidth+this.gutter,a.height=Number.POSITIVE_INFINITY,a.sortDirection="downwardLeftToRight"),a.reset(),this.maxY=0,this.maxX=0},i.prototype._getMeasurements=function(){this._getMeasurement("columnWidth","width"),this._getMeasurement("rowHeight","height"),this._getMeasurement("gutter","width")},i.prototype._getItemLayoutPosition=function(a){return this._packItem(a),a.rect},i.prototype._packItem=function(a){this._setRectSize(a.element,a.rect),this.packer.pack(a.rect),this._setMaxXY(a.rect)},i.prototype._setMaxXY=function(a){this.maxX=Math.max(a.x+a.width,this.maxX),this.maxY=Math.max(a.y+a.height,this.maxY)},i.prototype._setRectSize=function(a,c){var d=b(a),e=d.outerWidth,f=d.outerHeight;(e||f)&&(e=this._applyGridGutter(e,this.columnWidth),f=this._applyGridGutter(f,this.rowHeight)),c.width=Math.min(e,this.packer.width),c.height=Math.min(f,this.packer.height)},i.prototype._applyGridGutter=function(a,b){if(!b)return a+this.gutter;b+=this.gutter;var c=a%b,d=c&&1>c?"round":"ceil";return a=Math[d](a/b)*b},i.prototype._getContainerSize=function(){return this.options.isHorizontal?{width:this.maxX-this.gutter}:{height:this.maxY-this.gutter}},i.prototype._manageStamp=function(a){var b,c=this.getItem(a);if(c&&c.isPlacing)b=c.placeRect;else{var e=this._getElementOffset(a);b=new d({x:this.options.isOriginLeft?e.left:e.right,y:this.options.isOriginTop?e.top:e.bottom})}this._setRectSize(a,b),this.packer.placed(b),this._setMaxXY(b)},i.prototype.sortItemsByPosition=function(){var a=this.options.isHorizontal?h:g;this.items.sort(a)},i.prototype.fit=function(a,b,c){var d=this.getItem(a);d&&(this._getMeasurements(),this.stamp(d.element),d.getSize(),d.isPlacing=!0,b=void 0===b?d.rect.x:b,c=void 0===c?d.rect.y:c,d.positionPlaceRect(b,c,!0),this._bindFitEvents(d),d.moveTo(d.placeRect.x,d.placeRect.y),this.layout(),this.unstamp(d.element),this.sortItemsByPosition(),d.isPlacing=!1,d.copyPlaceRectPosition())},i.prototype._bindFitEvents=function(a){function b(){d++,2===d&&c.emitEvent("fitComplete",[c,a])}var c=this,d=0;a.on("layout",function(){return b(),!0}),this.on("layoutComplete",function(){return b(),!0})},i.prototype.resize=function(){var a=b(this.element),c=this.size&&a,d=this.options.isHorizontal?"innerHeight":"innerWidth";c&&a[d]===this.size[d]||this.layout()},i.prototype.itemDragStart=function(a){this.stamp(a);var b=this.getItem(a);b&&b.dragStart()},i.prototype.itemDragMove=function(a,b,c){function d(){f.layout(),delete f.dragTimeout}var e=this.getItem(a);e&&e.dragMove(b,c);var f=this;this.clearDragTimeout(),this.dragTimeout=setTimeout(d,40)},i.prototype.clearDragTimeout=function(){this.dragTimeout&&clearTimeout(this.dragTimeout)},i.prototype.itemDragEnd=function(b){var c,d=this.getItem(b);if(d&&(c=d.didDrag,d.dragStop()),!d||!c&&!d.needsPositioning)return void this.unstamp(b);a.add(d.element,"is-positioning-post-drag");var e=this._getDragEndLayoutComplete(b,d);d.needsPositioning?(d.on("layout",e),d.moveTo(d.placeRect.x,d.placeRect.y)):d&&d.copyPlaceRectPosition(),this.clearDragTimeout(),this.on("layoutComplete",e),this.layout()},i.prototype._getDragEndLayoutComplete=function(b,c){var d=c&&c.needsPositioning,e=0,f=d?2:1,g=this;return function(){return e++,e!==f?!0:(c&&(a.remove(c.element,"is-positioning-post-drag"),c.isPlacing=!1,
4556c.copyPlaceRectPosition()),g.unstamp(b),g.sortItemsByPosition(),d&&g.emitEvent("dragItemPositioned",[g,c]),!0)}},i.prototype.bindDraggabillyEvents=function(a){a.on("dragStart",this.handleDraggabilly.dragStart),a.on("dragMove",this.handleDraggabilly.dragMove),a.on("dragEnd",this.handleDraggabilly.dragEnd)},i.prototype.bindUIDraggableEvents=function(a){a.on("dragstart",this.handleUIDraggable.start).on("drag",this.handleUIDraggable.drag).on("dragstop",this.handleUIDraggable.stop)},i.Rect=d,i.Packer=e,i}"function"==typeof define&&define.amd?define("packery/js/packery",["classie/classie","get-size/get-size","outlayer/outlayer","./rect","./packer","./item"],b):"object"==typeof exports?module.exports=b(require("desandro-classie"),require("get-size"),require("outlayer"),require("./rect"),require("./packer"),require("./item")):a.Packery=b(a.classie,a.getSize,a.Outlayer,a.Packery.Rect,a.Packery.Packer,a.Packery.Item)}(window),function(a){function b(a,b){for(var c in b)a[c]=b[c];return a}function c(a,c,d){var e=a.create("packery"),f=e.prototype._getElementOffset,g=e.prototype._getMeasurement;b(e.prototype,c.prototype),e.prototype._getElementOffset=f,e.prototype._getMeasurement=g;var h=e.prototype._resetLayout;e.prototype._resetLayout=function(){this.packer=this.packer||new c.Packer,h.apply(this,arguments)};var i=e.prototype._getItemLayoutPosition;e.prototype._getItemLayoutPosition=function(a){return a.rect=a.rect||new c.Rect,i.call(this,a)};var j=e.prototype._manageStamp;return e.prototype._manageStamp=function(){this.options.isOriginLeft=this.isotope.options.isOriginLeft,this.options.isOriginTop=this.isotope.options.isOriginTop,j.apply(this,arguments)},e.prototype.needsResizeLayout=function(){var a=d(this.element),b=this.size&&a,c=this.options.isHorizontal?"innerHeight":"innerWidth";return b&&a[c]!==this.size[c]},e}"function"==typeof define&&define.amd?define(["isotope/js/layout-mode","packery/js/packery","get-size/get-size"],c):"object"==typeof exports?module.exports=c(require("isotope-layout/js/layout-mode"),require("packery"),require("get-size")):c(a.Isotope.LayoutMode,a.Packery,a.getSize)}(window);
4557
4558/*!
4559 * cellsByRows layout mode for Isotope
4560 * v1.1.2
4561 * http://isotope.metafizzy.co/layout-modes/cellsbyrow.html
4562 */
4563
4564/*jshint browser: true, devel: false, strict: true, undef: true, unused: true */
4565
4566( function( window ) {
4567
4568'use strict';
4569
4570function cellsByRowDefinition( LayoutMode ) {
4571
4572  var CellsByRow = LayoutMode.create( 'cellsByRow' );
4573
4574  CellsByRow.prototype._resetLayout = function() {
4575    // reset properties
4576    this.itemIndex = 0;
4577    // measurements
4578    this.getColumnWidth();
4579    this.getRowHeight();
4580    // set cols
4581    this.cols = Math.floor( this.isotope.size.innerWidth / this.columnWidth );
4582    this.cols = Math.max( this.cols, 1 );
4583  };
4584
4585  CellsByRow.prototype._getItemLayoutPosition = function( item ) {
4586    item.getSize();
4587    var col = this.itemIndex % this.cols;
4588    var row = Math.floor( this.itemIndex / this.cols );
4589    // center item within cell
4590    var x = ( col + 0.5 ) * this.columnWidth - item.size.outerWidth / 2;
4591    var y = ( row + 0.5 ) * this.rowHeight - item.size.outerHeight / 2;
4592    this.itemIndex++;
4593    return { x: x, y: y };
4594  };
4595
4596  CellsByRow.prototype._getContainerSize = function() {
4597    return {
4598      height: Math.ceil( this.itemIndex / this.cols ) * this.rowHeight
4599    };
4600  };
4601
4602  return CellsByRow;
4603
4604}
4605
4606if ( typeof define === 'function' && define.amd ) {
4607  // AMD
4608  define( [
4609      'isotope/js/layout-mode'
4610    ],
4611    cellsByRowDefinition );
4612} else if ( typeof exports === 'object' ) {
4613  // CommonJS
4614  module.exports = cellsByRowDefinition(
4615    require('isotope-layout/js/layout-mode')
4616  );
4617} else {
4618  // browser global
4619  cellsByRowDefinition(
4620    window.Isotope.LayoutMode
4621  );
4622}
4623
4624})( window );
4625
4626/*!
4627   --------------------------------
4628   Infinite Scroll
4629   --------------------------------
4630   + https://github.com/paulirish/infinite-scroll
4631   + version 2.1.0
4632   + Copyright 2011/12 Paul Irish & Luke Shumard
4633   + Licensed under the MIT license
4634
4635   + Documentation: http://infinite-scroll.com/
4636*/
4637;(function(e){if(typeof define==="function"&&define.amd){define(["jquery"],e)}else{e(jQuery)}})(function(e,t){"use strict";e.infinitescroll=function(n,r,i){this.element=e(i);if(!this._create(n,r)){this.failed=true}};e.infinitescroll.defaults={loading:{finished:t,finishedMsg:"<em>Congratulations, you've reached the end of the internet.</em>",img:"data:image/gif;
4637base64,R0lGODlh3AATAPQeAPDy+MnQ6LW/4N3h8MzT6rjC4sTM5r/I5NHX7N7j8c7U6tvg8OLl8uXo9Ojr9b3G5MfP6Ovu9tPZ7PT1+vX2+tbb7vf4+8/W69jd7rC73vn5/O/x+K243ai02////wAAACH/C05FVFNDQVBFMi4wAwEAAAAh+QQECgD/ACwAAAAA3AATAAAF/6AnjmRpnmiqrmzrvnAsz3Rt33iu73zv/8CgcEj0BAScpHLJbDqf0Kh0Sq1ar9isdioItAKGw+MAKYMFhbF63CW438f0mg1R2O8EuXj/aOPtaHx7fn96goR4hmuId4qDdX95c4+RBIGCB4yAjpmQhZN0YGYGXitdZBIVGAsLoq4BBKQDswm1CQRkcG6ytrYKubq8vbfAcMK9v7q7EMO1ycrHvsW6zcTKsczNz8HZw9vG3cjTsMIYqQkCLBwHCgsMDQ4RDAYIqfYSFxDxEfz88/X38Onr16+Bp4ADCco7eC8hQYMAEe57yNCew4IVBU7EGNDiRn8Z831cGLHhSIgdFf9chIeBg7oA7gjaWUWTVQAGE3LqBDCTlc9WOHfm7PkTqNCh54rePDqB6M+lR536hCpUqs2gVZM+xbrTqtGoWqdy1emValeXKzggYBBB5y1acFNZmEvXAoN2cGfJrTv3bl69Ffj2xZt3L1+/fw3XRVw4sGDGcR0fJhxZsF3KtBTThZxZ8mLMgC3fRatCbYMNFCzwLEqLgE4NsDWs/tvqdezZf13Hvk2A9Szdu2X3pg18N+68xXn7rh1c+PLksI/Dhe6cuO3ow3NfV92bdArTqC2Ebd3A8vjf5QWfH6Bg7Nz17c2fj69+fnq+8N2Lty+fuP78/eV2X13neIcCeBRwxorbZrA1ANoCDGrgoG8RTshahQ9iSKEEzUmYIYfNWViUhheCGJyIP5E4oom7WWjgCeBFAJNv1DVV01MAdJhhjdkplWNzO/5oXI846njjVEIqR2OS2B1pE5PVscajkxhMycqLJghQSwT40PgfAl4GqNSXYdZXJn5gSkmmmmJu1aZYb14V51do+pTOCmA40AqVCIhG5IJ9PvYnhIFOxmdqhpaI6GeHCtpooisuutmg+Eg62KOMKuqoTaXgicQWoIYq6qiklmoqFV0UoeqqrLbq6quwxirrrLTWauutJ4QAACH5BAUKABwALAcABADOAAsAAAX/IPd0D2dyRCoUp/k8gpHOKtseR9yiSmGbuBykler9XLAhkbDavXTL5k2oqFqNOxzUZPU5YYZd1XsD72rZpBjbeh52mSNnMSC8lwblKZGwi+0QfIJ8CncnCoCDgoVnBHmKfByGJimPkIwtiAeBkH6ZHJaKmCeVnKKTHIihg5KNq4uoqmEtcRUtEREMBggtEr4QDrjCuRC8h7/BwxENeicSF8DKy82pyNLMOxzWygzFmdvD2L3P0dze4+Xh1Arkyepi7dfFvvTtLQkZBC0T/FX3CRgCMOBHsJ+EHYQY7OinAGECgQsB+Lu3AOK+CewcWjwxQeJBihtNGHSoQOE+iQ3//4XkwBBhRZMcUS6YSXOAwIL8PGqEaSJCiYt9SNoCmnJPAgUVLChdaoFBURN8MAzl2PQphwQLfDFd6lTowglHve6rKpbjhK7/pG5VinZP1qkiz1rl4+tr2LRwWU64cFEihwEtZgbgR1UiHaMVvxpOSwBA37kzGz9e8G+B5MIEKLutOGEsAH2ATQwYfTmuX8aETWdGPZmiZcccNSzeTCA1Sw0bdiitC7LBWgu8jQr8HRzqgpK6gX88QbrB14z/kF+ELpwB8eVQj/JkqdylAudji/+ts3039vEEfK8Vz2dlvxZKG0CmbkKDBvllRd6fCzDvBLKBDSCeffhRJEFebFk1k/Mv9jVIoIJZSeBggwUaNeB+Qk34IE0cXlihcfRxkOAJFFhwGmKlmWDiakZhUJtnLBpnWWcnKaAZcxI0piFGGLBm1mc90kajSCveeBVWKeYEoU2wqeaQi0PetoE+rr14EpVC7oAbAUHqhYExbn2XHHsVqbcVew9tx8+XJKk5AZsqqdlddGpqAKdbAYBn1pcczmSTdWvdmZ17c1b3FZ99vnTdCRFM8OEcAhLwm1NdXnWcBBSMRWmfkWZqVlsmLIiAp/o1gGV2vpS4lalGYsUOqXrddcKCmK61aZ8SjEpUpVFVoCpTj4r661Km7kBHjrDyc1RAIQAAIfkEBQoAGwAsBwAEAM4ACwAABf/gtmUCd4goQQgFKj6PYKi0yrrbc8i4ohQt12EHcal+MNSQiCP8gigdz7iCioaCIvUmZLp8QBzW0EN2vSlCuDtFKaq4RyHzQLEKZNdiQDhRDVooCwkbfm59EAmKi4SGIm+AjIsKjhsqB4mSjT2IOIOUnICeCaB/mZKFNTSRmqVpmJqklSqskq6PfYYCDwYHDC4REQwGCBLGxxIQDsHMwhAIX8bKzcENgSLGF9PU1j3Sy9zX2NrgzQziChLk1BHWxcjf7N046tvN82715czn9Pryz6Ilc4ACj4EBOCZM8KEnAYYADBRKnACAYUMFv1wotIhCEcaJCisqwJFgAUSQGyX/kCSVUUTIdKMwJlyo0oXHlhskwrTJciZHEXsgaqS4s6PJiCAr1uzYU8kBBSgnWFqpoMJMUjGtDmUwkmfVmVypakWhEKvXsS4nhLW5wNjVroJIoc05wSzTr0PtiigpYe4EC2vj4iWrFu5euWIMRBhacaVJhYQBEFjA9jHjyQ0xEABwGceGAZYjY0YBOrRLCxUp29QM+bRkx5s7ZyYgVbTqwwti2ybJ+vLtDYpycyZbYOlptxdx0kV+V7lC5iJAyyRrwYKxAdiz82ng0/jnAdMJFz0cPi104Ec1Vj9/M6F173vKL/feXv156dw11tlqeMMnv4V5Ap53GmjQQH97nFfg+IFiucfgRX5Z8KAgbUlQ4IULIlghhhdOSB6AgX0IVn8eReghen3NRIBsRgnH4l4LuEidZBjwRpt6NM5WGwoW0KSjCwX6yJSMab2GwwAPDXfaBCtWpluRTQqC5JM5oUZAjUNS+VeOLWpJEQ7VYQANW0INJSZVDFSnZphjSikfmzE5N4EEbQI1QJmnWXCmHulRp2edwDXF43txukenJwvI9xyg9Q26Z3MzGUcBYFEChZh6DVTq34AU8Iflh51Sd+CnKFYQ6mmZkhqfBKfSxZWqA9DZanWjxmhrWwi0qtCrt/43K6WqVjjpmhIqgEGvculaGKklKstAACEAACH5BAUKABwALAcABADOAAsAAAX/ICdyQmaMYyAUqPgIBiHPxNpy79kqRXH8wAPsRmDdXpAWgWdEIYm2llCHqjVHU+jjJkwqBTecwItShMXkEfNWSh8e1NGAcLgpDGlRgk7EJ/6Ae3VKfoF/fDuFhohVeDeCfXkcCQqDVQcQhn+VNDOYmpSWaoqBlUSfmowjEA+iEAEGDRGztAwGCDcXEA60tXEiCrq8vREMEBLIyRLCxMWSH
4637MzExnbRvQ2Sy7vN0zvVtNfU2tLY3rPgLdnDvca4VQS/Cpk3ABwSLQkYAQwT/P309vcI7OvXr94jBQMJ/nskkGA/BQBRLNDncAIAiDcG6LsxAWOLiQzmeURBKWSLCQbv/1F0eDGinJUKR47YY1IEgQASKk7Yc7ACRwZm7mHweRJoz59BJUogisKCUaFMR0x4SlJBVBFTk8pZivTR0K73rN5wqlXEAq5Fy3IYgHbEzQ0nLy4QSoCjXLoom96VOJEeCosK5n4kkFfqXjl94wa+l1gvAcGICbewAOAxY8l/Ky/QhAGz4cUkGxu2HNozhwMGBnCUqUdBg9UuW9eUynqSwLHIBujePef1ZGQZXcM+OFuEBeBhi3OYgLyqcuaxbT9vLkf4SeqyWxSQpKGB2gQpm1KdWbu72rPRzR9Ne2Nu9Kzr/1Jqj0yD/fvqP4aXOt5sW/5qsXXVcv1Nsp8IBUAmgswGF3llGgeU1YVXXKTN1FlhWFXW3gIE+DVChApysACHHo7Q4A35lLichh+ROBmLKAzgYmYEYDAhCgxKGOOMn4WR4kkDaoBBOxJtdNKQxFmg5JIWIBnQc07GaORfUY4AEkdV6jHlCEISSZ5yTXpp1pbGZbkWmcuZmQCaE6iJ0FhjMaDjTMsgZaNEHFRAQVp3bqXnZED1qYcECOz5V6BhSWCoVJQIKuKQi2KFKEkEFAqoAo7uYSmO3jk61wUUMKmknJ4SGimBmAa0qVQBhAAAIfkEBQoAGwAsBwAEAM4ACwAABf/gJm5FmRlEqhJC+bywgK5pO4rHI0D3pii22+Mg6/0Ej96weCMAk7cDkXf7lZTTnrMl7eaYoy10JN0ZFdco0XAuvKI6qkgVFJXYNwjkIBcNBgR8TQoGfRsJCRuCYYQQiI+ICosiCoGOkIiKfSl8mJkHZ4U9kZMbKaI3pKGXmJKrngmug4WwkhA0lrCBWgYFCCMQFwoQDRHGxwwGCBLMzRLEx8iGzMMO0cYNeCMKzBDW19lnF9DXDIY/48Xg093f0Q3s1dcR8OLe8+Y91OTv5wrj7o7B+7VNQqABIoRVCMBggsOHE36kSoCBIcSH3EbFangxogJYFi8CkJhqQciLJEf/LDDJEeJIBT0GsOwYUYJGBS0fjpQAMidGmyVP6sx4Y6VQhzs9VUwkwqaCCh0tmKoFtSMDmBOf9phg4SrVrROuasRQAaxXpVUhdsU6IsECZlvX3kwLUWzRt0BHOLTbNlbZG3vZinArge5Dvn7wbqtQkSYAAgtKmnSsYKVKo2AfW048uaPmG386i4Q8EQMBAIAnfB7xBxBqvapJ9zX9WgRS2YMpnvYMGdPK3aMjt/3dUcNI4blpj7iwkMFWDXDvSmgAlijrt9RTR78+PS6z1uAJZIe93Q8g5zcsWCi/4Y+C8bah5zUv3vv89uft30QP23punGCx5954oBBwnwYaNCDY/wYrsYeggnM9B2Fpf8GG2CEUVWhbWAtGouEGDy7Y4IEJVrbSiXghqGKIo7z1IVcXIkKWWR361QOLWWnIhwERpLaaCCee5iMBGJQmJGyPFTnbkfHVZGRtIGrg5HALEJAZbu39BuUEUmq1JJQIPtZilY5hGeSWsSk52G9XqsmgljdIcABytq13HyIM6RcUA+r1qZ4EBF3WHWB29tBgAzRhEGhig8KmqKFv8SeCeo+mgsF7YFXa1qWSbkDpom/mqR1PmHCqJ3fwNRVXjC7S6CZhFVCQ2lWvZiirhQq42SACt25IK2hv8TprriUV1usGgeka7LFcNmCldMLi6qZMgFLgpw16Cipb7bC1knXsBiEAACH5BAUKABsALAcABADOAAsAAAX/4FZsJPkUmUGsLCEUTywXglFuSg7fW1xAvNWLF6sFFcPb42C8EZCj24EJdCp2yoegWsolS0Uu6fmamg8n8YYcLU2bXSiRaXMGvqV6/KAeJAh8VgZqCX+BexCFioWAYgqNi4qAR4ORhRuHY408jAeUhAmYYiuVlpiflqGZa5CWkzc5fKmbbhIpsAoQDRG8vQwQCBLCwxK6vb5qwhfGxxENahvCEA7NzskSy7vNzzzK09W/PNHF1NvX2dXcN8K55cfh69Luveol3vO8zwi4Yhj+AQwmCBw4IYclDAAJDlQggVOChAoLKkgFkSCAHDwWLKhIEOONARsDKryogFPIiAUb/95gJNIiw4wnI778GFPhzBKFOAq8qLJEhQpiNArjMcHCmlTCUDIouTKBhApELSxFWiGiVKY4E2CAekPgUphDu0742nRrVLJZnyrFSqKQ2ohoSYAMW6IoDpNJ4bLdILTnAj8KUF7UeENjAKuDyxIgOuGiOI0EBBMgLNew5AUrDTMGsFixwBIaNCQuAXJB57qNJ2OWm2Aj4skwCQCIyNkhhtMkdsIuodE0AN4LJDRgfLPtn5YDLdBlraAByuUbBgxQwICxMOnYpVOPej074OFdlfc0TqC62OIbcppHjV4o+LrieWhfT8JC/I/T6W8oCl29vQ0XjLdBaA3s1RcPBO7lFvpX8BVoG4O5jTXRQRDuJ6FDTzEWF1/BCZhgbyAKE9qICYLloQYOFtahVRsWYlZ4KQJHlwHS/IYaZ6sZd9tmu5HQm2xi1UaTbzxYwJk/wBF5g5EEYOBZeEfGZmNdFyFZmZIR4jikbLThlh5kUUVJGmRT7sekkziRWUIACABk3T4qCsedgO4xhgGcY7q5pHJ4klBBTQRJ0CeHcoYHHUh6wgfdn9uJdSdMiebGJ0zUPTcoS286FCkrZxnYoYYKWLkBowhQoBeaOlZAgVhLidrXqg2G
4637iqpQpZ4apwSwRtjqrB3muoF9BboaXKmshlqWqsWiGt2wphJkQbAU5hoCACH5BAUKABsALAcABADOAAsAAAX/oGFw2WZuT5oZROsSQnGaKjRvilI893MItlNOJ5v5gDcFrHhKIWcEYu/xFEqNv6B1N62aclysF7fsZYe5aOx2yL5aAUGSaT1oTYMBwQ5VGCAJgYIJCnx1gIOBhXdwiIl7d0p2iYGQUAQBjoOFSQR/lIQHnZ+Ue6OagqYzSqSJi5eTpTxGcjcSChANEbu8DBAIEsHBChe5vL13G7fFuscRDcnKuM3H0La3EA7Oz8kKEsXazr7Cw9/Gztar5uHHvte47MjktznZ2w0G1+D3BgirAqJmJMAQgMGEgwgn5Ei0gKDBhBMALGRYEOJBb5QcWlQo4cbAihZz3GgIMqFEBSM1/4ZEOWPAgpIIJXYU+PIhRG8ja1qU6VHlzZknJNQ6UanCjQkWCIGSUGEjAwVLjc44+DTqUQtPPS5gejUrTa5TJ3g9sWCr1BNUWZI161StiQUDmLYdGfesibQ3XMq1OPYthrwuA2yU2LBs2cBHIypYQPPlYAKFD5cVvNPtW8eVGbdcQADATsiNO4cFAPkvHpedPzc8kUcPgNGgZ5RNDZG05reoE9s2vSEP79MEGiQGy1qP8LA4ZcdtsJE48ONoLTBtTV0B9LsTnPceoIDBDQvS7W7vfjVY3q3eZ4A339J4eaAmKqU/sV58HvJh2RcnIBsDUw0ABqhBA5aV5V9XUFGiHfVeAiWwoFgJJrIXRH1tEMiDFV4oHoAEGlaWhgIGSGBO2nFomYY3mKjVglidaNYJGJDkWW2xxTfbjCbVaOGNqoX2GloR8ZeTaECS9pthRGJH2g0b3Agbk6hNANtteHD2GJUucfajCQBy5OOTQ25ZgUPvaVVQmbKh9510/qQpwXx3SQdfk8tZJOd5b6JJFplT3ZnmmX3qd5l1eg5q00HrtUkUn0AKaiGjClSAgKLYZcgWXwocGRcCFGCKwSB6ceqphwmYRUFYT/1WKlOdUpipmxW0mlCqHjYkAaeoZlqrqZ4qd+upQKaapn/AmgAegZ8KUtYtFAQQAgAh+QQFCgAbACwHAAQAzgALAAAF/+C2PUcmiCiZGUTrEkKBis8jQEquKwU5HyXIbEPgyX7BYa5wTNmEMwWsSXsqFbEh8DYs9mrgGjdK6GkPY5GOeU6ryz7UFopSQEzygOGhJBjoIgMDBAcBM0V/CYqLCQqFOwobiYyKjn2TlI6GKC2YjJZknouaZAcQlJUHl6eooJwKooobqoewrJSEmyKdt59NhRKFMxLEEA4RyMkMEAjDEhfGycqAG8TQx9IRDRDE3d3R2ctD1RLg0ttKEnbY5wZD3+zJ6M7X2RHi9Oby7u/r9g38UFjTh2xZJBEBMDAboogAgwkQI07IMUORwocSJwCgWDFBAIwZOaJIsOBjRogKJP8wTODw5ESVHVtm3AhzpEeQElOuNDlTZ0ycEUWKWFASqEahGwYUPbnxoAgEdlYSqDBkgoUNClAlIHbSAoOsqCRQnQHxq1axVb06FWFxLIqyaze0Tft1JVqyE+pWXMD1pF6bYl3+HTqAWNW8cRUFzmih0ZAAB2oGKukSAAGGRHWJgLiR6AylBLpuHKKUMlMCngMpDSAa9QIUggZVVvDaJobLeC3XZpvgNgCmtPcuwP3WgmXSq4do0DC6o2/guzcseECtUoO0hmcsGKDgOt7ssBd07wqesAIGZC1YIBa7PQHvb1+SFo+++HrJSQfB33xfav3i5eX3Hnb4CTJgegEq8tH/YQEOcIJzbm2G2EoYRLgBXFpVmFYDcREV4HIcnmUhiGBRouEMJGJGzHIspqgdXxK0yCKHRNXoIX4uorCdTyjkyNtdPWrA4Up82EbAbzMRxxZRR54WXVLDIRmRcag5d2R6ugl3ZXzNhTecchpMhIGVAKAYpgJjjsSklBEd99maZoo535ZvdamjBEpusJyctg3h4X8XqodBMx0tiNeg/oGJaKGABpogS40KSqiaEgBqlQWLUtqoVQnytekEjzo0hHqhRorppOZt2p923M2AAV+oBtpAnnPNoB6HaU6mAAIU+IXmi3j2mtFXuUoHKwXpzVrsjcgGOauKEjQrwq157hitGq2NoWmjh7z6Wmxb0m5w66+2VRAuXN/yFUAIACH5BAUKABsALAcABADOAAsAAAX/4CZuRiaM45MZqBgIRbs9AqTcuFLE7VHLOh7KB5ERdjJaEaU4ClO/lgKWjKKcMiJQ8KgumcieVdQMD8cbBeuAkkC6LYLhOxoQ2PF5Ys9PKPBMen17f0CCg4VSh32JV4t8jSNqEIOEgJKPlkYBlJWRInKdiJdkmQlvKAsLBxdABA4RsbIMBggtEhcQsLKxDBC2TAS6vLENdJLDxMZAubu8vjIbzcQRtMzJz79S08oQEt/guNiyy7fcvMbh4OezdAvGrakLAQwyABsELQkY9BP+//ckyPDD4J9BfAMh1GsBoImMeQUN+lMgUJ9CiRMa5msxoB9Gh/o8GmxYMZXIgxtR/yQ46S/gQAURR0pDwYDfywoyLPip5AdnCwsMFPBU4BPFhKBDi444quCmDKZOfwZ9KEGpCKgcN1jdALSpPqIYsabS+nSqvqplvYqQYAeDPgwKwjaMtiDl0oaqUAyo+3TuWwUAMPpVCfee0cEjVBGQq2ABx7oTWmQk4FglZMGN9fGVDMCuiH2AOVOu/PmyxM630gwM0CCn6q8LjVJ8GXvpa5Uwn95OTC/nNxkda1/dLSK475IjCD6dHbK1ZOa4hXP9DXs5chJ00UpVm5xo2qRpoxptwF2E4/IbJpB/SDz9+q9b1aNfQH08+p4a8uvX8B53fLP+ycAfemjsRUBgp1H20K+BghHgVgt1GXZXZpZ5lt4ECjxYR4ScUWiShEtZqBiIInRGWnERNnjiBglw+JyGnxUmGowsyiiZg189lNtPGACjV2+S9UjbU0JWF6SPvEk3QZEqsZYTk3UAaRSUnznJI5LmESCdBVSyaOWUWLK4I5gDUYVeV1T9l+FZClCAUVA09uSmRHBCKAECFEhW51ht6rnmWBXkaR+NjuHpJ40D3DmnQXt2F+ihZxlqVKOfQRACACH5BAUKABwALAcABADOAAsAAAX/ICdyUCkUo/g8mUG8MCGkKgspeC6j6XEIEBpBUeCNfECaglBcOVfJFK7YQwZHQ6JRZBUqTrSuVEuD3nI45pYjFuWKvjjSkCoRaBUMWxkwBGgJCXspQ36Bh4EEB0oKhoiBgyNLjo8Ki4QElIiWfJqHnISNEI+Ql5J9o6SgkqKkgqYihamPkW6oNBgSfiMMDQkGCBLCwxIQDhHIyQwQCGMKxsnKVyPCF9DREQ3MxMPX0cu4wt7J2uHWx9jlKd3o39MiuefYEcvNkuLt5O8c1ePI2tyELXGQwoGDAQf+iEC2xByDCRAjTlAgIUWCBRgCPJQ4AQBFXAs0coT40WLIjRxL/47AcHLkxIomRXL0CHPERZkpa4q4iVKiyp0tR/7kwHMkTUBBJR5dOCEBAVcKKtCAyOHpowXCpk7goABqBZdcvWploACpBKkpIJI1q5OD2rIWE0R1uTZu1LFwbWL9OlKuWb4c6+o9i3dEgw0RCGDUG9KlRw56gDY2qmCByZBaASi+TACA0TucAaTteCcy0ZuOK3N2vJlx58+LRQyY3Xm0ZsgjZg+oPQLi7dUcNXi0LOJw1pgNtB7XG6CBy+U75SYfPTSQAgZTNUDnQHt67wnbZyvwLgKiMN3oCZB3C76tdewpLFgIP2C88rbi4Y+QT3+8S5USMICZXWj1pkEDeUU3lOYGB3alSoEiMIjgX4WlgNF2EibIwQIXauWXSRg2SAOHIU5IIIMoZkhhWiJaiFVbKo6AQEgQXrTAazO1JhkBrBG3Y2Y6EsUhaGn95hprSN0oWpFE7rhkeaQBchGOEWnwEmc0uKWZj0LeuNV3W4Y2lZHFlQCSRjTIl8uZ+kG5HU/3sRlnTG2ytyadytnD3HrmuRcSn+0h1dycexIK1KCjYaCnjCCVqOFFJTZ5GkUUjESWaUIKU2lgCmAKKQIUjHapXRKE+t2og1VgankNYnohqKJ2CmKplso6GKz7WYCgqxeuyoF8u9IQAgA7",msg:null,msgText:"<em>Loading the next set of posts...</em>",selector:null,speed:"fast",start:t},state:{isDuringAjax:false,isInvalidPage:false,isDestroyed:false,isDone:false,isPaused:false,isBeyondMaxPage:false,currPage:1},debug:false,behavior:t,binder:e(window),nextSelector:"div.navigation a:first",navSelector:"div.navigation",contentSelector:null,extraScrollPx:150,itemSelector:"div.post",animate:false,pathParse:t,dataType:"html",appendCallback:true,bufferPx:40,errorCallback:function(){},infid:0,pixelsFromNavToBottom:t,path:t,prefill:false,maxPage:t};e.infinitescroll.prototype={_binding:function(n){var r=this,i=r.options;i.v="2.0b2.120520";if(!!i.behavior&&this["_binding_"+i.behavior]!==t){this["_binding_"+i.behavior].call(this);return}if(n!=="bind"&&n!=="unbind"){this._debug("Binding value  "+n+" not valid");return false}if(n==="unbind"){this.options.binder.unbind("smartscroll.infscr."+r.options.infid)}else{this.options.binder[n]("smartscroll.infscr."+r.options.infid,function(){r.scroll()})}this._debug("Binding",n)},_create:function(r,i){var s=e.extend(true,{},e.infinitescroll.defaults,r);this.options=s;var o=e(window);var u=this;if(!u._validate(r)){return false}var a=e(s.nextSelector).attr("href");if(!a){this._debug("Navigation selector not found");return false}s.path=s.path||this._determinepath(a);s.contentSelector=s.contentSelector||this.element;s.loading.selector=s.loading.selector||s.contentSelector;s.loading.msg=s.loading.msg||e('<div id="infscr-loading"><img alt="Loading..." src="'+s.loading.img+'" /><div>'+s.loading.msgText+"</div></div>");(new Image).src=s.loading.img;if(s.pixelsFromNavToBottom===t){s.pixelsFromNavToBottom=e(document).height()-e(s.navSelector).offset().top;this._debug("pixelsFromNavToBottom: "+s.pixelsFromNavToBottom)}var f=this;s.loading.start=s.loading.start||function(){e(s.navSelector).hide();s.loading.msg.appendTo(s.loading.selector).show(s.loading.speed,e.proxy(function(){this.beginAjax(s)},f))};s.loading.finished=s.loading.finished||function(){if(!s.state.isBeyondMaxPage)s.loading.msg.fadeOut(s.loading.speed)};s.callback=function(n,r,u){if(!!s.behavior&&n["_callback_"+s.behavior]!==t){n["_callback_"+s.behavior].call(e(s.contentSelector)[0],r,u)}if(i){i.call(e(s.contentSelector)[0],r,s,u)}if(s.prefill){o.bind("resize.infinite-scroll",n._prefill)}};if(r.debug){if(Function.prototype.bind&&(typeof console==="object"||typeof console==="function")&&typeof console.log==="object"){["log","info","warn","error","assert","dir","clear","profile","profileEnd"].forEach(function(e){console[e]=this.call(console[e],console)},Function.prototype.bind)}}this._setup();if(s.prefill){this._prefill()}return true},_prefill:function(){function i(){return e(n.options.contentSelector).height()<=r.height()}var n=this;var r=e(window);this._prefill=function(){if(i()){n.scroll()}r.bind("resize.infinite-scroll",function(){if(i()){r.unbind("resize.infinite-scroll");n.scroll()}})};this._prefill()},_debug:function(){if(true!==this.options.debug){return}if(typeof console!=="undefined"&&typeof console.log==="function"){if(Array.prototype.slice.call(arguments).length===1&&typeof Array.prototype.slice.call(arguments)[0]==="str
4637ing"){console.log(Array.prototype.slice.call(arguments).toString())}else{console.log(Array.prototype.slice.call(arguments))}}else if(!Function.prototype.bind&&typeof console!=="undefined"&&typeof console.log==="object"){Function.prototype.call.call(console.log,console,Array.prototype.slice.call(arguments))}},_determinepath:function(n){var r=this.options;if(!!r.behavior&&this["_determinepath_"+r.behavior]!==t){return this["_determinepath_"+r.behavior].call(this,n)}if(!!r.pathParse){this._debug("pathParse manual");return r.pathParse(n,this.options.state.currPage+1)}else if(n.match(/^(.*?)\b2\b(.*?$)/)){n=n.match(/^(.*?)\b2\b(.*?$)/).slice(1)}else if(n.match(/^(.*?)2(.*?$)/)){if(n.match(/^(.*?page=)2(\/.*|$)/)){n=n.match(/^(.*?page=)2(\/.*|$)/).slice(1);return n}n=n.match(/^(.*?)2(.*?$)/).slice(1)}else{if(n.match(/^(.*?page=)1(\/.*|$)/)){n=n.match(/^(.*?page=)1(\/.*|$)/).slice(1);return n}else{this._debug("Sorry, we couldn't parse your Next (Previous Posts) URL. Verify your the css selector points to the correct A tag. If you still get this error: yell, scream, and kindly ask for help at infinite-scroll.com.");r.state.isInvalidPage=true}}this._debug("determinePath",n);return n},_error:function(n){var r=this.options;if(!!r.behavior&&this["_error_"+r.behavior]!==t){this["_error_"+r.behavior].call(this,n);return}if(n!=="destroy"&&n!=="end"){n="unknown"}this._debug("Error",n);if(n==="end"||r.state.isBeyondMaxPage){this._showdonemsg()}r.state.isDone=true;r.state.currPage=1;
4637r.state.isPaused=false;r.state.isBeyondMaxPage=false;this._binding("unbind")},_loadcallback:function(r,i,s){var o=this.options,u=this.options.callback,a=o.state.isDone?"done":!o.appendCallback?"no-append":"append",f;if(!!o.behavior&&this["_loadcallback_"+o.behavior]!==t){this["_loadcallback_"+o.behavior].call(this,r,i);return}switch(a){case"done":this._showdonemsg();return false;case"no-append":if(o.dataType==="html"){i="<div>"+i+"</div>";i=e(i).find(o.itemSelector)}if(i.length===0){return this._error("end")}break;case"append":var l=r.children();if(l.length===0){return this._error("end")}f=document.createDocumentFragment();while(r[0].firstChild){f.appendChild(r[0].firstChild)}this._debug("contentSelector",e(o.contentSelector)[0]);e(o.contentSelector)[0].appendChild(f);i=l.get();break}o.loading.finished.call(e(o.contentSelector)[0],o);if(o.animate){var c=e(window).scrollTop()+e(o.loading.msg).height()+o.extraScrollPx+"px";e("html,body").animate({scrollTop:c},800,function(){o.state.isDuringAjax=false})}if(!o.animate){o.state.isDuringAjax=false}u(this,i,s);if(o.prefill){this._prefill()}},_nearbottom:function(){var r=this.options,i=0+e(document).height()-r.binder.scrollTop()-e(window).height();if(!!r.behavior&&this["_nearbottom_"+r.behavior]!==t){return this["_nearbottom_"+r.behavior].call(this)}this._debug("math:",i,r.pixelsFromNavToBottom);return i-r.bufferPx<r.pixelsFromNavToBottom},_pausing:function(n){var r=this.options;if(!!r.behavior&&this["_pausing_"+r.behavior]!==t){this["_pausing_"+r.behavior].call(this,n);return}if(n!=="pause"&&n!=="resume"&&n!==null){this._debug("Invalid argument. Toggling pause value instead")}n=n&&(n==="pause"||n==="resume")?n:"toggle";
4637switch(n){case"pause":r.state.isPaused=true;break;case"resume":r.state.isPaused=false;break;case"toggle":r.state.isPaused=!r.state.isPaused;break}this._debug("Paused",r.state.isPaused);return false},_setup:function(){var n=this.options;if(!!n.behavior&&this["_setup_"+n.behavior]!==t){this["_setup_"+n.behavior].call(this);return}this._binding("bind");return false},_showdonemsg:function(){var r=this.options;if(!!r.behavior&&this["_showdonemsg_"+r.behavior]!==t){this["_showdonemsg_"+r.behavior].call(this);return}r.loading.msg.find("img").hide().parent().find("div").html(r.loading.finishedMsg).animate({opacity:1},2e3,function(){e(this).parent().fadeOut(r.loading.speed)});r.errorCallback.call(e(r.contentSelector)[0],"done")},_validate:function(n){for(var r in n){if(r.indexOf&&r.indexOf("Selector")>-1&&e(n[r]).length===0){this._debug("Your "+r+" found no elements.");return false}}return true},bind:function(){this._binding("bind")},destroy:function(){this.options.state.isDestroyed=true;this.options.loading.finished();return this._error("destroy")},pause:function(){this._pausing("pause")},resume:function(){this._pausing("resume")},beginAjax:function(r){var i=this,s=r.path,o,u,a,f;r.state.currPage++;if(r.maxPage!==t&&r.state.currPage>r.maxPage){r.state.isBeyondMaxPage=true;this.destroy();return}o=e(r.contentSelector).is("table, tbody")?e("<tbody/>"):e("<div/>");u=typeof s==="function"?s(r.state.currPage):s.join(r.state.currPage);i._debug("heading into ajax",u);a=r.dataType==="html"||r.dataType==="json"?r.dataType:"html+callback";if(r.appendCallback&&r.dataType==="html"){a+="+callback"}switch(a){case"html+callback":i._debug("Using HTML via .load() method");o.load(u+" "+r.itemSelector,t,function(t){i._loadcallback(o,t,u)});break;case"html":i._debug("Using "+a.toUpperCase()+" via $.ajax() method");e.ajax({url:u,dataType:r.dataType,complete:function(t,n){f=typeof t.isResolved!=="undefined"?t.isResolved():n==="success"||n==="notmodified";if(f){i._loadcallback(o,t.responseText,u)}else{i._error("end")}}});break;case"json":i._debug("Using "+a.toUpperCase()+" via $.ajax() method");e.ajax({dataType:"json",type:"GET",url:u,success:function(e,n,s){f=typeof s.isResolved!=="undefined"?s.isResolved():n==="success"||n==="notmodified";if(r.appendCallback){if(r.template!==t){var a=r.template(e);o.append(a);if(f){i._loadcallback(o,a)}else{i._error("end")}}else{i._debug("template must be defined.");i._error("end")}}else{if(f){i._loadcallback(o,e,u)}else{i._error("end")}}},error:function(){i._debug("JSON ajax request failed.");i._error("end")}});break}},retrieve:function(r){r=r||null;var i=this,s=i.options;if(!!s.behavior&&this["retrieve_"+s.behavior]!==t){this["retrieve_"+s.behavior].call(this,r);return}if(s.state.isDestroyed){this._debug("Instance is destroyed");return false}s.state.isDuringAjax=true;s.loading.start.call(e(s.contentSelector)[0],s)},scroll:function(){var n=this.options,r=n.state;if(!!n.behavior&&this["scroll_"+n.behavior]!==t){this["scroll_"+n.behavior].call(this);return}if(r.isDuringAjax||r.isInvalidPage||r.isDone||r.isDestroyed||r.isPaused){return}if(!this._nearbottom()){return}this.retrieve()},toggle:function(){this._pausing()},unbind:function(){this._binding("unbind")},update:function(n){if(e.isPlainObject(n)){this.options=e.extend(true,this.options,n)}}};e.fn.infinitescroll=function(n,r){var i=typeof n;switch(i){case"string":var s=Array.prototype.slice.call(arguments,1);this.each(function(){var t=e.data(this,"infinitescroll");if(!t){return false}if(!e.isFunction(t[n])||n.charAt(0)==="_"){return false}t[n].apply(t,s)});break;case"object":this.each(function(){var t=e.data(this,"infinitescroll");if(t){t.update(n)}else{t=new e.infinitescroll(n,r,this);if(!t.failed){e.data(this,"infinitescroll",t)}}});break}return this};var n=e.event,r;n.special.smartscroll={setup:function(){e(this).bind("scroll",n.special.smartscroll.handler)},teardown:function(){e(this).unbind("scroll",n.special.smartscroll.handler)},handler:function(t,n){var i=this,s=arguments;t.type="smartscroll";if(r){clearTimeout(r)}r=setTimeout(function(){e(i).trigger("smartscroll",s)},n==="execAsap"?0:100)}};e.fn.smartscroll=function(e){return e?this.bind("smartscroll",e):this.trigger("smartscroll",["execAsap"])}});
4638
4639/*!
4640Waypoints - 4.0.0
4641Copyright © 2011-2015 Caleb Troughton
4642Licensed under the MIT license.
4643https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
4644*/
4645(function() {
4646  'use strict'
4647
4648  var keyCounter = 0
4649  var allWaypoints = {}
4650
4651  /* http://imakewebthings.com/waypoints/api/waypoint */
4652  function Waypoint(options) {
4653    if (!options) {
4654      throw new Error('No options passed to Waypoint constructor')
4655    }
4656    if (!options.element) {
4657      throw new Error('No element option passed to Waypoint constructor')
4658    }
4659    if (!options.handler) {
4660      throw new Error('No handler option passed to Waypoint constructor')
4661    }
4662
4663    this.key = 'waypoint-' + keyCounter
4664    this.options = Waypoint.Adapter.extend({}, Waypoint.defaults, options)
4665    this.element = this.options.element
4666    this.adapter = new Waypoint.Adapter(this.element)
4667    this.callback = options.handler
4668    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
4669    this.enabled = this.options.enabled
4670    this.triggerPoint = null
4671    this.group = Waypoint.Group.findOrCreate({
4672      name: this.options.group,
4673      axis: this.axis
4674    })
4675    this.context = Waypoint.Context.findOrCreateByElement(this.options.context)
4676
4677    if (Waypoint.offsetAliases[this.options.offset]) {
4678      this.options.offset = Waypoint.offsetAliases[this.options.offset]
4679    }
4680    this.group.add(this)
4681    this.context.add(this)
4682    allWaypoints[this.key] = this
4683    keyCounter += 1
4684  }
4685
4686  /* Private */
4687  Waypoint.prototype.queueTrigger = function(direction) {
4688    this.group.queueTrigger(this, direction)
4689  }
4690
4691  /* Private */
4692  Waypoint.prototype.trigger = function(args) {
4693    if (!this.enabled) {
4694      return
4695    }
4696    if (this.callback) {
4697      this.callback.apply(this, args)
4698    }
4699  }
4700
4701  /* Public */
4702  /* http://imakewebthings.com/waypoints/api/destroy */
4703  Waypoint.prototype.destroy = function() {
4704    this.context.remove(this)
4705    this.group.remove(this)
4706    delete allWaypoints[this.key]
4707  }
4708
4709  /* Public */
4710  /* http://imakewebthings.com/waypoints/api/disable */
4711  Waypoint.prototype.disable = function() {
4712    this.enabled = false
4713    return this
4714  }
4715
4716  /* Public */
4717  /* http://imakewebthings.com/waypoints/api/enable */
4718  Waypoint.prototype.enable = function() {
4719    this.context.refresh()
4720    this.enabled = true
4721    return this
4722  }
4723
4724  /* Public */
4725  /* http://imakewebthings.com/waypoints/api/next */
4726  Waypoint.prototype.next = function() {
4727    return this.group.next(this)
4728  }
4729
4730  /* Public */
4731  /* http://imakewebthings.com/waypoints/api/previous */
4732  Waypoint.prototype.previous = function() {
4733    return this.group.previous(this)
4734  }
4735
4736  /* Private */
4737  Waypoint.invokeAll = function(method) {
4738    var allWaypointsArray = []
4739    for (var waypointKey in allWaypoints) {
4740      allWaypointsArray.push(allWaypoints[waypointKey])
4741    }
4742    for (var i = 0, end = allWaypointsArray.length; i < end; i++) {
4743      allWaypointsArray[i][method]()
4744    }
4745  }
4746
4747  /* Public */
4748  /* http://imakewebthings.com/waypoints/api/destroy-all */
4749  Waypoint.destroyAll = function() {
4750    Waypoint.invokeAll('destroy')
4751  }
4752
4753  /* Public */
4754  /* http://imakewebthings.com/waypoints/api/disable-all */
4755  Waypoint.disableAll = function() {
4756    Waypoint.invokeAll('disable')
4757  }
4758
4759  /* Public */
4760  /* http://imakewebthings.com/waypoints/api/enable-all */
4761  Waypoint.enableAll = function() {
4762    Waypoint.invokeAll('enable')
4763  }
4764
4765  /* Public */
4766  /* http://imakewebthings.com/waypoints/api/refresh-all */
4767  Waypoint.refreshAll = function() {
4768    Waypoint.Context.refreshAll()
4769  }
4770
4771  /* Public */
4772  /* http://imakewebthings.com/waypoints/api/viewport-height */
4773  Waypoint.viewportHeight = function() {
4774    return window.innerHeight || document.documentElement.clientHeight
4775  }
4776
4777  /* Public */
4778  /* http://imakewebthings.com/waypoints/api/viewport-width */
4779  Waypoint.viewportWidth = function() {
4780    return document.documentElement.clientWidth
4781  }
4782
4783  Waypoint.adapters = []
4784
4785  Waypoint.defaults = {
4786    context: window,
4787    continuous: true,
4788    enabled: true,
4789    group: 'default',
4790    horizontal: false,
4791    offset: 0
4792  }
4793
4794  Waypoint.offsetAliases = {
4795    'bottom-in-view': function() {
4796      return this.context.innerHeight() - this.adapter.outerHeight()
4797    },
4798    'right-in-view': function() {
4799      return this.context.innerWidth() - this.adapter.outerWidth()
4800    }
4801  }
4802
4803  window.Waypoint = Waypoint
4804}())
4805;(function() {
4806  'use strict'
4807
4808  function requestAnimationFrameShim(callback) {
4809    window.setTimeout(callback, 1000 / 60)
4810  }
4811
4812  var keyCounter = 0
4813  var contexts = {}
4814  var Waypoint = window.Waypoint
4815  var oldWindowLoad = window.onload
4816
4817  /* http://imakewebthings.com/waypoints/api/context */
4818  function Context(element) {
4819    this.element = element
4820    this.Adapter = Waypoint.Adapter
4821    this.adapter = new this.Adapter(element)
4822    this.key = 'waypoint-context-' + keyCounter
4823    this.didScroll = false
4824    this.didResize = false
4825    this.oldScroll = {
4826      x: this.adapter.scrollLeft(),
4827      y: this.adapter.scrollTop()
4828    }
4829    this.waypoints = {
4830      vertical: {},
4831      horizontal: {}
4832    }
4833
4834    element.waypointContextKey = this.key
4835    contexts[element.waypointContextKey] = this
4836    keyCounter += 1
4837
4838    this.createThrottledScrollHandler()
4839    this.createThrottledResizeHandler()
4840  }
4841
4842  /* Private */
4843  Context.prototype.add = function(waypoint) {
4844    var axis = waypoint.options.horizontal ? 'horizontal' : 'vertical'
4845    this.waypoints[axis][waypoint.key] = waypoint
4846    this.refresh()
4847  }
4848
4849  /* Private */
4850  Context.prototype.checkEmpty = function() {
4851    var horizontalEmpty = this.Adapter.isEmptyObject(this.waypoints.horizontal)
4852    var verticalEmpty = this.Adapter.isEmptyObject(this.waypoints.vertical)
4853    if (horizontalEmpty && verticalEmpty) {
4854      this.adapter.off('.waypoints')
4855      delete contexts[this.key]
4856    }
4857  }
4858
4859  /* Private */
4860  Context.prototype.createThrottledResizeHandler = function() {
4861    var self = this
4862
4863    function resizeHandler() {
4864      self.handleResize()
4865      self.didResize = false
4866    }
4867
4868    this.adapter.on('resize.waypoints', function() {
4869      if (!self.didResize) {
4870        self.didResize = true
4871        Waypoint.requestAnimationFrame(resizeHandler)
4872      }
4873    })
4874  }
4875
4876  /* Private */
4877  Context.prototype.createThrottledScrollHandler = function() {
4878    var self = this
4879    function scrollHandler() {
4880      self.handleScroll()
4881      self.didScroll = false
4882    }
4883
4884    this.adapter.on('scroll.waypoints', function() {
4885      if (!self.didScroll || Waypoint.isTouch) {
4886        self.didScroll = true
4887        Waypoint.requestAnimationFrame(scrollHandler)
4888      }
4889    })
4890  }
4891
4892  /* Private */
4893  Context.prototype.handleResize = function() {
4894    Waypoint.Context.refreshAll()
4895  }
4896
4897  /* Private */
4898  Context.prototype.handleScroll = function() {
4899    var triggeredGroups = {}
4900    var axes = {
4901      horizontal: {
4902        newScroll: this.adapter.scrollLeft(),
4903        oldScroll: this.oldScroll.x,
4904        forward: 'right',
4905        backward: 'left'
4906      },
4907      vertical: {
4908        newScroll: this.adapter.scrollTop(),
4909        oldScroll: this.oldScroll.y,
4910        forward: 'down',
4911        backward: 'up'
4912      }
4913    }
4914
4915    for (var axisKey in axes) {
4916      var axis = axes[axisKey]
4917      var isForward = axis.newScroll > axis.oldScroll
4918      var direction = isForward ? axis.forward : axis.backward
4919
4920      for (var waypointKey in this.waypoints[axisKey]) {
4921        var waypoint = this.waypoints[axisKey][waypointKey]
4922        var wasBeforeTriggerPoint = axis.oldScroll < waypoint.triggerPoint
4923        var nowAfterTriggerPoint = axis.newScroll >= waypoint.triggerPoint
4924        var crossedForward = wasBeforeTriggerPoint && nowAfterTriggerPoint
4925        var crossedBackward = !wasBeforeTriggerPoint && !nowAfterTriggerPoint
4926        if (crossedForward || crossedBackward) {
4927          waypoint.queueTrigger(direction)
4928          triggeredGroups[waypoint.group.id] = waypoint.group
4929        }
4930      }
4931    }
4932
4933    for (var groupKey in triggeredGroups) {
4934      triggeredGroups[groupKey].flushTriggers()
4935    }
4936
4937    this.oldScroll = {
4938      x: axes.horizontal.newScroll,
4939      y: axes.vertical.newScroll
4940    }
4941  }
4942
4943  /* Private */
4944  Context.prototype.innerHeight = function() {
4945    /*eslint-disable eqeqeq */
4946    if (this.element == this.element.window) {
4947      return Waypoint.viewportHeight()
4948    }
4949    /*eslint-enable eqeqeq */
4950    return this.adapter.innerHeight()
4951  }
4952
4953  /* Private */
4954  Context.prototype.remove = function(waypoint) {
4955    delete this.waypoints[waypoint.axis][waypoint.key]
4956    this.checkEmpty()
4957  }
4958
4959  /* Private */
4960  Context.prototype.innerWidth = function() {
4961    /*eslint-disable eqeqeq */
4962    if (this.element == this.element.window) {
4963      return Waypoint.viewportWidth()
4964    }
4965    /*eslint-enable eqeqeq */
4966    return this.adapter.innerWidth()
4967  }
4968
4969  /* Public */
4970  /* http://imakewebthings.com/waypoints/api/context-destroy */
4971  Context.prototype.destroy = function() {
4972    var allWaypoints = []
4973    for (var axis in this.waypoints) {
4974      for (var waypointKey in this.waypoints[axis]) {
4975        allWaypoints.push(this.waypoints[axis][waypointKey])
4976      }
4977    }
4978    for (var i = 0, end = allWaypoints.length; i < end; i++) {
4979      allWaypoints[i].destroy()
4980    }
4981  }
4982
4983  /* Public */
4984  /* http://imakewebthings.com/waypoints/api/context-refresh */
4985  Context.prototype.refresh = function() {
4986    /*eslint-disable eqeqeq */
4987    var isWindow = this.element == this.element.window
4988    /*eslint-enable eqeqeq */
4989    var contextOffset = isWindow ? undefined : this.adapter.offset()
4990    var triggeredGroups = {}
4991    var axes
4992
4993    this.handleScroll()
4994    axes = {
4995      horizontal: {
4996        contextOffset: isWindow ? 0 : contextOffset.left,
4997        contextScroll: isWindow ? 0 : this.oldScroll.x,
4998        contextDimension: this.innerWidth(),
4999        oldScroll: this.oldScroll.x,
5000        forward: 'right',
5001        backward: 'left',
5002        offsetProp: 'left'
5003      },
5004      vertical: {
5005        contextOffset: isWindow ? 0 : contextOffset.top,
5006        contextScroll: isWindow ? 0 : this.oldScroll.y,
5007        contextDimension: this.innerHeight(),
5008        oldScroll: this.oldScroll.y,
5009        forward: 'down',
5010        backward: 'up',
5011        offsetProp: 'top'
5012      }
5013    }
5014
5015    for (var axisKey in axes) {
5016      var axis = axes[axisKey]
5017      for (var waypointKey in this.waypoints[axisKey]) {
5018        var waypoint = this.waypoints[axisKey][waypointKey]
5019        var adjustment = waypoint.options.offset
5020        var oldTriggerPoint = waypoint.triggerPoint
5021        var elementOffset = 0
5022        var freshWaypoint = oldTriggerPoint == null
5023        var contextModifier, wasBeforeScroll, nowAfterScroll
5024        var triggeredBackward, triggeredForward
5025
5026        if (waypoint.element !== waypoint.element.window) {
5027          elementOffset = waypoint.adapter.offset()[axis.offsetProp]
5028        }
5029
5030        if (typeof adjustment === 'function') {
5031          adjustment = adjustment.apply(waypoint)
5032        }
5033        else if (typeof adjustment === 'string') {
5034          adjustment = parseFloat(adjustment)
5035          if (waypoint.options.offset.indexOf('%') > - 1) {
5036            adjustment = Math.ceil(axis.contextDimension * adjustment / 100)
5037          }
5038        }
5039
5040        contextModifier = axis.contextScroll - axis.contextOffset
5041        waypoint.triggerPoint = elementOffset + contextModifier - adjustment
5042        wasBeforeScroll = oldTriggerPoint < axis.oldScroll
5043        nowAfterScroll = waypoint.triggerPoint >= axis.oldScroll
5044        triggeredBackward = wasBeforeScroll && nowAfterScroll
5045        triggeredForward = !wasBeforeScroll && !nowAfterScroll
5046
5047        if (!freshWaypoint && triggeredBackward) {
5048          waypoint.queueTrigger(axis.backward)
5049          triggeredGroups[waypoint.group.id] = waypoint.group
5050        }
5051        else if (!freshWaypoint && triggeredForward) {
5052          waypoint.queueTrigger(axis.forward)
5053          triggeredGroups[waypoint.group.id] = waypoint.group
5054        }
5055        else if (freshWaypoint && axis.oldScroll >= waypoint.triggerPoint) {
5056          waypoint.queueTrigger(axis.forward)
5057          triggeredGroups[waypoint.group.id] = waypoint.group
5058        }
5059      }
5060    }
5061
5062    Waypoint.requestAnimationFrame(function() {
5063      for (var groupKey in triggeredGroups) {
5064        triggeredGroups[groupKey].flushTriggers()
5065      }
5066    })
5067
5068    return this
5069  }
5070
5071  /* Private */
5072  Context.findOrCreateByElement = function(element) {
5073    return Context.findByElement(element) || new Context(element)
5074  }
5075
5076  /* Private */
5077  Context.refreshAll = function() {
5078    for (var contextId in contexts) {
5079      contexts[contextId].refresh()
5080    }
5081  }
5082
5083  /* Public */
5084  /* http://imakewebthings.com/waypoints/api/context-find-by-element */
5085  Context.findByElement = function(element) {
5086    return contexts[element.waypointContextKey]
5087  }
5088
5089  window.onload = function() {
5090    if (oldWindowLoad) {
5091      oldWindowLoad()
5092    }
5093    Context.refreshAll()
5094  }
5095
5096  Waypoint.requestAnimationFrame = function(callback) {
5097    var requestFn = window.requestAnimationFrame ||
5098      window.mozRequestAnimationFrame ||
5099      window.webkitRequestAnimationFrame ||
5100      requestAnimationFrameShim
5101    requestFn.call(window, callback)
5102  }
5103  Waypoint.Context = Context
5104}())
5105;(function() {
5106  'use strict'
5107
5108  function byTriggerPoint(a, b) {
5109    return a.triggerPoint - b.triggerPoint
5110  }
5111
5112  function byReverseTriggerPoint(a, b) {
5113    return b.triggerPoint - a.triggerPoint
5114  }
5115
5116  var groups = {
5117    vertical: {},
5118    horizontal: {}
5119  }
5120  var Waypoint = window.Waypoint
5121
5122  /* http://imakewebthings.com/waypoints/api/group */
5123  function Group(options) {
5124    this.name = options.name
5125    this.axis = options.axis
5126    this.id = this.name + '-' + this.axis
5127    this.waypoints = []
5128    this.clearTriggerQueues()
5129    groups[this.axis][this.name] = this
5130  }
5131
5132  /* Private */
5133  Group.prototype.add = function(waypoint) {
5134    this.waypoints.push(waypoint)
5135  }
5136
5137  /* Private */
5138  Group.prototype.clearTriggerQueues = function() {
5139    this.triggerQueues = {
5140      up: [],
5141      down: [],
5142      left: [],
5143      right: []
5144    }
5145  }
5146
5147  /* Private */
5148  Group.prototype.flushTriggers = function() {
5149    for (var direction in this.triggerQueues) {
5150      var waypoints = this.triggerQueues[direction]
5151      var reverse = direction === 'up' || direction === 'left'
5152      waypoints.sort(reverse ? byReverseTriggerPoint : byTriggerPoint)
5153      for (var i = 0, end = waypoints.length; i < end; i += 1) {
5154        var waypoint = waypoints[i]
5155        if (waypoint.options.continuous || i === waypoints.length - 1) {
5156          waypoint.trigger([direction])
5157        }
5158      }
5159    }
5160    this.clearTriggerQueues()
5161  }
5162
5163  /* Private */
5164  Group.prototype.next = function(waypoint) {
5165    this.waypoints.sort(byTriggerPoint)
5166    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
5167    var isLast = index === this.waypoints.length - 1
5168    return isLast ? null : this.waypoints[index + 1]
5169  }
5170
5171  /* Private */
5172  Group.prototype.previous = function(waypoint) {
5173    this.waypoints.sort(byTriggerPoint)
5174    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
5175    return index ? this.waypoints[index - 1] : null
5176  }
5177
5178  /* Private */
5179  Group.prototype.queueTrigger = function(waypoint, direction) {
5180    this.triggerQueues[direction].push(waypoint)
5181  }
5182
5183  /* Private */
5184  Group.prototype.remove = function(waypoint) {
5185    var index = Waypoint.Adapter.inArray(waypoint, this.waypoints)
5186    if (index > -1) {
5187      this.waypoints.splice(index, 1)
5188    }
5189  }
5190
5191  /* Public */
5192  /* http://imakewebthings.com/waypoints/api/first */
5193  Group.prototype.first = function() {
5194    return this.waypoints[0]
5195  }
5196
5197  /* Public */
5198  /* http://imakewebthings.com/waypoints/api/last */
5199  Group.prototype.last = function() {
5200    return this.waypoints[this.waypoints.length - 1]
5201  }
5202
5203  /* Private */
5204  Group.findOrCreate = function(options) {
5205    return groups[options.axis][options.name] || new Group(options)
5206  }
5207
5208  Waypoint.Group = Group
5209}())
5210;(function() {
5211  'use strict'
5212
5213  var $ = window.jQuery
5214  var Waypoint = window.Waypoint
5215
5216  function JQueryAdapter(element) {
5217    this.$element = $(element)
5218  }
5219
5220  $.each([
5221    'innerHeight',
5222    'innerWidth',
5223    'off',
5224    'offset',
5225    'on',
5226    'outerHeight',
5227    'outerWidth',
5228    'scrollLeft',
5229    'scrollTop'
5230  ], function(i, method) {
5231    JQueryAdapter.prototype[method] = function() {
5232      var args = Array.prototype.slice.call(arguments)
5233      return this.$element[method].apply(this.$element, args)
5234    }
5235  })
5236
5237  $.each([
5238    'extend',
5239    'inArray',
5240    'isEmptyObject'
5241  ], function(i, method) {
5242    JQueryAdapter[method] = $[method]
5243  })
5244
5245  Waypoint.adapters.push({
5246    name: 'jquery',
5247    Adapter: JQueryAdapter
5248  })
5249  Waypoint.Adapter = JQueryAdapter
5250}())
5251;(function() {
5252  'use strict'
5253
5254  var Waypoint = window.Waypoint
5255
5256  function createExtension(framework) {
5257    return function() {
5258      var waypoints = []
5259      var overrides = arguments[0]
5260
5261      if (framework.isFunction(arguments[0])) {
5262        overrides = framework.extend({}, arguments[1])
5263        overrides.handler = arguments[0]
5264      }
5265
5266      this.each(function() {
5267        var options = framework.extend({}, overrides, {
5268          element: this
5269        })
5270        if (typeof options.context === 'string') {
5271          options.context = framework(this).closest(options.context)[0]
5272        }
5273        waypoints.push(new Waypoint(options))
5274      })
5275
5276      return waypoints
5277    }
5278  }
5279
5280  if (window.jQuery) {
5281    window.jQuery.fn.waypoint = createExtension(window.jQuery)
5282  }
5283  if (window.Zepto) {
5284    window.Zepto.fn.waypoint = createExtension(window.Zepto)
5285  }
5286}())
5287;
5288
5289/*!
5290Waypoints Inview Shortcut - 4.0.0
5291Copyright © 2011-2015 Caleb Troughton
5292Licensed under the MIT license.
5293https://github.com/imakewebthings/waypoints/blob/master/licenses.txt
5294*/
5295(function() {
5296  'use strict'
5297
5298  function noop() {}
5299
5300  var Waypoint = window.Waypoint
5301
5302  /* http://imakewebthings.com/waypoints/shortcuts/inview */
5303  function Inview(options) {
5304    this.options = Waypoint.Adapter.extend({}, Inview.defaults, options)
5305    this.axis = this.options.horizontal ? 'horizontal' : 'vertical'
5306    this.waypoints = []
5307    this.element = this.options.element
5308    this.createWaypoints()
5309  }
5310
5311  /* Private */
5312  Inview.prototype.createWaypoints = function() {
5313    var configs = {
5314      vertical: [{
5315        down: 'enter',
5316        up: 'exited',
5317        offset: '100%'
5318      }, {
5319        down: 'entered',
5320        up: 'exit',
5321        offset: 'bottom-in-view'
5322      }, {
5323        down: 'exit',
5324        up: 'entered',
5325        offset: 0
5326      }, {
5327        down: 'exited',
5328        up: 'enter',
5329        offset: function() {
5330          return -this.adapter.outerHeight()
5331        }
5332      }],
5333      horizontal: [{
5334        right: 'enter',
5335        left: 'exited',
5336        offset: '100%'
5337      }, {
5338        right: 'entered',
5339        left: 'exit',
5340        offset: 'right-in-view'
5341      }, {
5342        right: 'exit',
5343        left: 'entered',
5344        offset: 0
5345      }, {
5346        right: 'exited',
5347        left: 'enter',
5348        offset: function() {
5349          return -this.adapter.outerWidth()
5350        }
5351      }]
5352    }
5353
5354    for (var i = 0, end = configs[this.axis].length; i < end; i++) {
5355      var config = configs[this.axis][i]
5356      this.createWaypoint(config)
5357    }
5358  }
5359
5360  /* Private */
5361  Inview.prototype.createWaypoint = function(config) {
5362    var self = this
5363    this.waypoints.push(new Waypoint({
5364      context: this.options.context,
5365      element: this.options.element,
5366      enabled: this.options.enabled,
5367      handler: (function(config) {
5368        return function(direction) {
5369          self.options[config[direction]].call(self, direction)
5370        }
5371      }(config)),
5372      offset: config.offset,
5373      horizontal: this.options.horizontal
5374    }))
5375  }
5376
5377  /* Public */
5378  Inview.prototype.destroy = function() {
5379    for (var i = 0, end = this.waypoints.length; i < end; i++) {
5380      this.waypoints[i].destroy()
5381    }
5382    this.waypoints = []
5383  }
5384
5385  Inview.prototype.disable = function() {
5386    for (var i = 0, end = this.waypoints.length; i < end; i++) {
5387      this.waypoints[i].disable()
5388    }
5389  }
5390
5391  Inview.prototype.enable = function() {
5392    for (var i = 0, end = this.waypoints.length; i < end; i++) {
5393      this.waypoints[i].enable()
5394    }
5395  }
5396
5397  Inview.defaults = {
5398    context: window,
5399    enabled: true,
5400    enter: noop,
5401    entered: noop,
5402    exit: noop,
5403    exited: noop
5404  }
5405
5406  Waypoint.Inview = Inview
5407}())
5408;
5409
5410/*
5411 * SmartMenus jQuery v0.9.6
5412 * http://www.smartmenus.org/
5413 *
5414 * Copyright 2014 Vasil Dinkov, Vadikom Web Ltd.
5415 * http://vadikom.com/
5416 *
5417 * Released under the MIT license:
5418 * http://www.opensource.org/licenses/MIT
5419 */
5420
5421(function($) {
5422
5423	var menuTrees = [],
5424		IE = !!window.createPopup, // we need to detect it, unfortunately
5425		IElt9 = IE && !document.defaultView,
5426		IElt8 = IE && !document.querySelector,
5427		IE6 = IE && typeof document.documentElement.currentStyle.minWidth == 'undefined',
5428		mouse = false, // optimize for touch by default - we will detect for mouse input
5429		mouseDetectionEnabled = false;
5430
5431	// Handle detection for mouse input (i.e. desktop browsers, tablets with a mouse, etc.)
5432	function initMouseDetection(disable) {
5433		if (!mouseDetectionEnabled && !disable) {
5434			// if we get two consecutive mousemoves within 2 pixels from each other and within 300ms, we assume a real mouse/cursor is present
5435			// in practice, this seems like impossible to trick unintentianally with a real mouse and a pretty safe detection on touch devices (even with older browsers that do not support touch events)
5436			var firstTime = true,
5437				lastMove = null;
5438			$(document).bind({
5439				'mousemove.smartmenus_mouse': function(e) {
5440					var thisMove = { x: e.pageX, y: e.pageY, timeStamp: new Date().getTime() };
5441					if (lastMove) {
5442						var deltaX = Math.abs(lastMove.x - thisMove.x),
5443							deltaY = Math.abs(lastMove.y - thisMove.y);
5444	 					if ((deltaX > 0 || deltaY > 0) && deltaX <= 2 && deltaY <= 2 && thisMove.timeStamp - lastMove.timeStamp <= 300) {
5445							mouse = true;
5446							// if this is the first check after page load, check if we are not over some item by chance and call the mouseenter handler if yes
5447							if (firstTime) {
5448								var $a = $(e.target).closest('a');
5449								if ($a.is('a')) {
5450									$.each(menuTrees, function() {
5451										if ($.contains(this.$root[0], $a[0])) {
5452											this.itemEnter({ currentTarget: $a[0] });
5453											return false;
5454										}
5455									});
5456								}
5457								firstTime = false;
5458							}
5459						}
5460					}
5461					lastMove = thisMove;
5462				},
5463				'touchstart.smartmenus_mouse pointerover.smartmenus_mouse MSPointerOver.smartmenus_mouse': function(e) {
5464					if (!/^(4|mouse)$/.test(e.originalEvent.pointerType)) {
5465						mouse = false;
5466					}
5467				}
5468			});
5469			mouseDetectionEnabled = true;
5470		} else if (mouseDetectionEnabled && disable) {
5471			$(document).unbind('.smartmenus_mouse');
5472			mouseDetectionEnabled = false;
5473		}
5474	};
5475
5476	$.SmartMenus = function(elm, options) {
5477		this.$root = $(elm);
5478		this.opts = options;
5479		this.rootId = ''; // internal
5480		this.$subArrow = null;
5481		this.subMenus = []; // all sub menus in the tree (UL elms) in no particular order (only real - e.g. UL's in mega sub menus won't be counted)
5482		this.activatedItems = []; // stores last activated A's for each level
5483		this.visibleSubMenus = []; // stores visible sub menus UL's
5484		this.showTimeout = 0;
5485		this.hideTimeout = 0;
5486		this.scrollTimeout = 0;
5487		this.clickActivated = false;
5488		this.zIndexInc = 0;
5489		this.$firstLink = null; // we'll use these for some tests
5490		this.$firstSub = null; // at runtime so we'll cache them
5491		this.disabled = false;
5492		this.$disableOverlay = null;
5493		this.init();
5494	};
5495
5496	$.extend($.SmartMenus, {
5497		hideAll: function() {
5498			$.each(menuTrees, function() {
5499				this.menuHideAll();
5500			});
5501		},
5502		destroy: function() {
5503			while (menuTrees.length) {
5504				menuTrees[0].destroy();
5505			}
5506			initMouseDetection(true);
5507		},
5508		prototype: {
5509			init: function(refresh) {
5510				var self = this;
5511
5512				if (!refresh) {
5513					menuTrees.push(this);
5514
5515					this.rootId = (new Date().getTime() + Math.random() + '').replace(/\D/g, '');
5516
5517					if (this.$root.hasClass('sm-rtl')) {
5518						this.opts.rightToLeftSubMenus = true;
5519					}
5520
5521					// init root (main menu)
5522					this.$root
5523						.data('smartmenus', this)
5524						.attr('data-smartmenus-id', this.rootId)
5525						.dataSM('level', 1)
5526						.bind({
5527							'mouseover.smartmenus focusin.smartmenus': $.proxy(this.rootOver, this),
5528							'mouseout.smartmenus focusout.smartmenus': $.proxy(this.rootOut, this)
5529						})
5530						.delegate('a', {
5531							'mouseenter.smartmenus': $.proxy(this.itemEnter, this),
5532							'mouseleave.smartmenus': $.proxy(this.itemLeave, this),
5533							'mousedown.smartmenus': $.proxy(this.itemDown, this),
5534							'focus.smartmenus': $.proxy(this.itemFocus, this),
5535							'blur.smartmenus': $.proxy(this.itemBlur, this),
5536							'click.smartmenus': $.proxy(this.itemClick, this),
5537							'touchend.smartmenus': $.proxy(this.itemTouchEnd, this)
5538						});
5539
5540					var eNamespace = '.smartmenus' + this.rootId;
5541					// hide menus on tap or click outside the root UL
5542					if (this.opts.hideOnClick) {
5543						$(document).bind('touchstart' + eNamespace, $.proxy(this.docTouchStart, this))
5544							.bind('touchmove' + eNamespace, $.proxy(this.docTouchMove, this))
5545							.bind('touchend' + eNamespace, $.proxy(this.docTouchEnd, this))
5546							// for Opera Mobile < 11.5, webOS browser, etc. we'll check click too
5547							.bind('click' + eNamespace, $.proxy(this.docClick, this));
5548					}
5549					// hide sub menus on resize
5550					$(window).bind('resize' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
5551					$(window).bind('scroll' + eNamespace + ' orientationchange' + eNamespace, $.proxy(this.winResize, this));
5552
5553					if (this.opts.subIndicators) {
5554						this.$subArrow = $('<span/>').addClass('sub-arrow');
5555						if (this.opts.subIndicatorsText) {
5556							this.$subArrow.html(this.opts.subIndicatorsText);
5557						}
5558					}
5559
5560					// make sure mouse detection is enabled
5561					initMouseDetection();
5562				}
5563
5564				// init sub menus
5565				this.$firstSub = this.$root.find('ul').each(function() { self.menuInit($(this)); }).eq(0);
5566
5567				this.$firstLink = this.$root.find('a').eq(0);
5568
5569				// find current item
5570				if (this.opts.markCurrentItem) {
5571					var reDefaultDoc = /(index|default)\.[^#\?\/]*/i,
5572						reHash = /#.*/,
5573						locHref = window.location.href.replace(reDefaultDoc, ''),
5574						locHrefNoHash = locHref.replace(reHash, '');
5575					this.$root.find('a').each(function() {
5576						var href = this.href.replace(reDefaultDoc, ''),
5577							$this = $(this);
5578						if (href == locHref || href == locHrefNoHash) {
5579							$this.addClass('current');
5580							if (self.opts.markCurrentTree) {
5581								$this.parents('li').each(function() {
5582									var $this = $(this);
5583									if ($this.dataSM('sub')) {
5584										$this.children('a').addClass('current');
5585									}
5586								});
5587							}
5588						}
5589					});
5590				}
5591			},
5592			destroy: function() {
5593				this.menuHideAll();
5594				this.$root
5595					.removeData('smartmenus')
5596					.removeAttr('data-smartmenus-id')
5597					.removeDataSM('level')
5598					.unbind('.smartmenus')
5599					.undelegate('.smartmenus');
5600				var eNamespace = '.smartmenus' + this.rootId;
5601				$(document).unbind(eNamespace);
5602				$(window).unbind(eNamespace);
5603				if (this.opts.subIndicators) {
5604					this.$subArrow = null;
5605				}
5606				var self = this;
5607				$.each(this.subMenus, function() {
5608					if (this.hasClass('mega-menu')) {
5609						this.find('ul').removeDataSM('in-mega');
5610					}
5611					if (this.dataSM('shown-before')) {
5612						if (IElt8) {
5613							this.children().css({ styleFloat: '', width: '' });
5614						}
5615						if (self.opts.subMenusMinWidth || self.opts.subMenusMaxWidth) {
5616							if (!IE6) {
5617								this.css({ width: '', minWidth: '', maxWidth: '' }).removeClass('sm-nowrap');
5618							} else {
5619								this.css({ width: '', overflowX: '', overflowY: '' }).children().children('a').css('white-space', '');
5620							}
5621						}
5622						if (this.dataSM('scroll-arrows')) {
5623							this.dataSM('scroll-arrows').remove();
5624						}
5625						this.css({ zIndex: '', top: '', left: '', marginLeft: '', marginTop: '', display: '' });
5626					}
5627					if (self.opts.subIndicators) {
5628						this.dataSM('parent-a').removeClass('has-submenu').children('span.sub-arrow').remove();
5629					}
5630					this.removeDataSM('shown-before')
5631						.removeDataSM('ie-shim')
5632						.removeDataSM('scroll-arrows')
5633						.removeDataSM('parent-a')
5634						.removeDataSM('level')
5635						.removeDataSM('beforefirstshowfired')
5636						.parent().removeDataSM('sub');
5637				});
5638				if (this.opts.markCurrentItem) {
5639					this.$root.find('a.current').removeClass('current');
5640				}
5641				this.$root = null;
5642				this.$firstLink = null;
5643				this.$firstSub = null;
5644				if (this.$disableOverlay) {
5645					this.$disableOverlay.remove();
5646					this.$disableOverlay = null;
5647				}
5648				menuTrees.splice($.inArray(this, menuTrees), 1);
5649			},
5650			disable: function(noOverlay) {
5651				if (!this.disabled) {
5652					this.menuHideAll();
5653					// display overlay over the menu to prevent interaction
5654					if (!noOverlay && !this.opts.isPopup && this.$root.is(':visible')) {
5655						var pos = this.$root.offset();
5656						this.$disableOverlay = $('<div class="sm-jquery-disable-overlay"/>').css({
5657							position: 'absolute',
5658							top: pos.top,
5659							left: pos.left,
5660							width: this.$root.outerWidth(),
5661							height: this.$root.outerHeight(),
5662							zIndex: this.getStartZIndex() + 1,
5663							opacity: 0
5664						}).appendTo(document.body);
5665					}
5666					this.disabled = true;
5667				}
5668			},
5669			docClick: function(e) {
5670				// hide on any click outside the menu or on a menu link
5671				if (this.visibleSubMenus.length && !$.contains(this.$root[0], e.target) || $(e.target).is('a')) {
5672					this.menuHideAll($(e.target));
5673				}
5674			},
5675			docTouchEnd: function(e) {
5676				if (!this.lastTouch) {
5677					return;
5678				}
5679				if (this.visibleSubMenus.length && (this.lastTouch.x2 === undefined || this.lastTouch.x1 == this.lastTouch.x2) && (this.lastTouch.y2 === undefined || this.lastTouch.y1 == this.lastTouch.y2) && (!this.lastTouch.target || !$.contains(this.$root[0], this.lastTouch.target))) {
5680					if (this.hideTimeout) {
5681						clearTimeout(this.hideTimeout);
5682						this.hideTimeout = 0;
5683					}
5684					// hide with a delay to prevent triggering accidental unwanted click on some page element
5685					var self = this;
5686					this.hideTimeout = setTimeout(function() { self.menuHideAll($(e.target)); }, 350);
5687				}
5688				this.lastTouch = null;
5689			},
5690			docTouchMove: function(e) {
5691				if (!this.lastTouch) {
5692					return;
5693				}
5694				var touchPoint = e.originalEvent.touches[0];
5695				this.lastTouch.x2 = touchPoint.pageX;
5696				this.lastTouch.y2 = touchPoint.pageY;
5697			},
5698			docTouchStart: function(e) {
5699				var touchPoint = e.originalEvent.touches[0];
5700				this.lastTouch = { x1: touchPoint.pageX, y1: touchPoint.pageY, target: touchPoint.target };
5701			},
5702			enable: function() {
5703				if (this.disabled) {
5704					if (this.$disableOverlay) {
5705						this.$disableOverlay.remove();
5706						this.$disableOverlay = null;
5707					}
5708					this.disabled = false;
5709				}
5710			},
5711			getHeight: function($elm) {
5712				return this.getOffset($elm, true);
5713			},
5714			// returns precise width/height float values in IE9+, FF4+, recent WebKit
5715			// http://vadikom.com/dailies/offsetwidth-offsetheight-useless-in-ie9-firefox4/
5716			getOffset: function($elm, height) {
5717				var old;
5718				if ($elm.css('display') == 'none') {
5719					old = { position: $elm[0].style.position, visibility: $elm[0].style.visibility };
5720					$elm.css({ position: 'absolute', visibility: 'hidden' }).show();
5721				}
5722				var defaultView = $elm[0].ownerDocument.defaultView,
5723					compStyle = defaultView && defaultView.getComputedStyle && defaultView.getComputedStyle($elm[0], null),
5724					val = compStyle && parseFloat(compStyle[height ? 'height' : 'width']);
5725				if (val) {
5726					val += parseFloat(compStyle[height ? 'paddingTop' : 'paddingLeft'])
5727	 					+ parseFloat(compStyle[height ? 'paddingBottom' : 'paddingRight'])
5728	 					+ parseInt(compStyle[height ? 'borderTopWidth' : 'borderLeftWidth'])
5729	 					+ parseInt(compStyle[height ? 'borderBottomWidth' : 'borderRightWidth']);
5730				} else {
5731					val = height ? $elm[0].offsetHeight : $elm[0].offsetWidth;
5732				}
5733				if (old) {
5734					$elm.hide().css(old);
5735				}
5736				return val;
5737			},
5738			getWidth: function($elm) {
5739				return this.getOffset($elm);
5740			},
5741			getStartZIndex: function() {
5742				var zIndex = parseInt(this.$root.css('z-index'));
5743				return !isNaN(zIndex) ? zIndex : 1;
5744			},
5745			handleEvents: function() {
5746				return !this.disabled && this.isCSSOn();
5747			},
5748			handleItemEvents: function($a) {
5749				return this.handleEvents() && !this.isLinkInMegaMenu($a);
5750			},
5751			isCollapsible: function() {
5752				return this.$firstSub.css('position') == 'static';
5753			},
5754			isCSSOn: function() {
5755				return this.$firstLink.css('display') == 'block' || this.$firstLink.css('display') == 'inline';
5756			},
5757			isFixed: function() {
5758				return this.$root.css('position') == 'fixed';
5759			},
5760			isLinkInMegaMenu: function($a) {
5761				return !$a.parent().parent().dataSM('level');
5762			},
5763			isTouchMode: function() {
5764				return !mouse || this.isCollapsible();
5765			},
5766			itemActivate: function($a) {
5767				var $li = $a.parent(),
5768					$ul = $li.parent(),
5769					level = $ul.dataSM('level');
5770				// if for some reason the parent item is not activated (e.g. this is an API call to activate the item), activate all parent items first
5771				if (level > 1 && (!this.activatedItems[level - 2] || this.activatedItems[level - 2][0] != $ul.dataSM('parent-a')[0])) {
5772					var self = this;
5773					$($ul.parentsUntil('[data-smartmenus-id]', 'ul').get().reverse()).add($ul).each(function() {
5774						self.itemActivate($(this).dataSM('parent-a'));
5775					});
5776				}
5777				// hide any visible deeper level sub menus
5778				if (this.visibleSubMenus.length > level) {
5779					for (var i = this.visibleSubMenus.length - 1, l = !this.activatedItems[level - 1] || this.activatedItems[level - 1][0] != $a[0] ? level - 1 : level; i > l; i--) {
5780						this.menuHide(this.visibleSubMenus[i]);
5781					}
5782				}
5783				// save new active item and sub menu for this level
5784				this.activatedItems[level - 1] = $a;
5785				this.visibleSubMenus[level - 1] = $ul;
5786				if (this.$root.triggerHandler('activate.smapi', $a[0]) === false) {
5787					return;
5788				}
5789				// show the sub menu if this item has one
5790				var $sub = $li.dataSM('sub');
5791				if ($sub && (this.isTouchMode() || (!this.opts.showOnClick || this.clickActivated))) {
5792					this.menuShow($sub);
5793				}
5794			},
5795			itemBlur: function(e) {
5796				var $a = $(e.currentTarget);
5797				if (!this.handleItemEvents($a)) {
5798					return;
5799				}
5800				this.$root.triggerHandler('blur.smapi', $a[0]);
5801			},
5802			itemClick: function(e) {
5803				var $a = $(e.currentTarget);
5804
5805				if (!this.handleItemEvents($a)) {
5806					return;
5807				}
5808				$a.removeDataSM('mousedown');
5809				if (this.$root.triggerHandler('click.smapi', $a[0]) === false) {
5810					return false;
5811				}
5812				var $sub = $a.parent().dataSM('sub');
5813				if (this.isTouchMode()) {
5814					// undo fix: prevent the address bar on iPhone from sliding down when expanding a sub menu
5815					if ($a.dataSM('href')) {
5816						$a.attr('href', $a.dataSM('href')).removeDataSM('href');
5817					}
5818					// if the sub is not visible
5819					if ($sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
5820						// try to activate the item and show the sub
5821						this.itemActivate($a);
5822						// if "itemActivate" showed the sub, prevent the click so that the link is not loaded
5823						// if it couldn't show it, then the sub menus are disabled with an !important declaration (e.g. via mobile styles) so let the link get loaded
5824						if ($sub.is(':visible')) {
5825							return false;
5826						}
5827					}
5828				} else if (this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 && $sub) {
5829					this.clickActivated = true;
5830					this.menuShow($sub);
5831					return false;
5832				}
5833				if ($a.hasClass('disabled')) {
5834					return false;
5835				}
5836				if (this.$root.triggerHandler('select.smapi', $a[0]) === false) {
5837					return false;
5838				}
5839			},
5840			itemDown: function(e) {
5841				var $a = $(e.currentTarget);
5842				if (!this.handleItemEvents($a)) {
5843					return;
5844				}
5845				$a.dataSM('mousedown', true);
5846			},
5847			itemEnter: function(e) {
5848				var $a = $(e.currentTarget);
5849				if (!this.handleItemEvents($a)) {
5850					return;
5851				}
5852				if (!this.isTouchMode()) {
5853					if (this.showTimeout) {
5854						clearTimeout(this.showTimeout);
5855						this.showTimeout = 0;
5856					}
5857					var self = this;
5858					this.showTimeout = setTimeout(function() { self.itemActivate($a); }, this.opts.showOnClick && $a.parent().parent().dataSM('level') == 1 ? 1 : this.opts.showTimeout);
5859				}
5860				this.$root.triggerHandler('mouseenter.smapi', $a[0]);
5861			},
5862			itemFocus: function(e) {
5863				var $a = $(e.currentTarget);
5864				if (!this.handleItemEvents($a)) {
5865					return;
5866				}
5867				// fix (the mousedown check): in some browsers a tap/click produces consecutive focus + click events so we don't need to activate the item on focus
5868				if ((!this.isTouchMode() || !$a.dataSM('mousedown')) && (!this.activatedItems.length || this.activatedItems[this.activatedItems.length - 1][0] != $a[0])) {
5869					this.itemActivate($a);
5870				}
5871				this.$root.triggerHandler('focus.smapi', $a[0]);
5872			},
5873			itemLeave: function(e) {
5874				var $a = $(e.currentTarget);
5875				if (!this.handleItemEvents($a)) {
5876					return;
5877				}
5878				if (!this.isTouchMode()) {
5879					if ($a[0].blur) {
5880						$a[0].blur();
5881					}
5882					if (this.showTimeout) {
5883						clearTimeout(this.showTimeout);
5884						this.showTimeout = 0;
5885					}
5886				}
5887				$a.removeDataSM('mousedown');
5888				this.$root.triggerHandler('mouseleave.smapi', $a[0]);
5889			},
5890			itemTouchEnd: function(e) {
5891				var $a = $(e.currentTarget);
5892				if (!this.handleItemEvents($a)) {
5893					return;
5894				}
5895				// prevent the address bar on iPhone from sliding down when expanding a sub menu
5896				var $sub = $a.parent().dataSM('sub');
5897				if ($a.attr('href').charAt(0) !== '#' && $sub && (!$sub.dataSM('shown-before') || !$sub.is(':visible'))) {
5898					$a.dataSM('href', $a.attr('href'));
5899					$a.attr('href', '#');
5900				}
5901			},
5902			menuFixLayout: function($ul) {
5903				// fixes a menu that is being shown for the first time
5904				if (!$ul.dataSM('shown-before')) {
5905					$ul.hide().dataSM('shown-before', true);
5906					// fix the layout of the items in IE<8
5907					if (IElt8) {
5908						$ul.children().css({ styleFloat: 'left', width: '100%' });
5909					}
5910				}
5911			},
5912			menuHide: function($sub) {
5913				if (this.$root.triggerHandler('beforehide.smapi', $sub[0]) === false) {
5914					return;
5915				}
5916				$sub.stop(true, true);
5917				if ($sub.is(':visible')) {
5918					var complete = function() {
5919						// unset z-index
5920						if (IElt9) {
5921							$sub.parent().css('z-index', '');
5922						} else {
5923							$sub.css('z-index', '');
5924						}
5925					};
5926					// if sub is collapsible (mobile view)
5927					if (this.isCollapsible()) {
5928						if (this.opts.collapsibleHideFunction) {
5929							this.opts.collapsibleHideFunction.call(this, $sub, complete);
5930						} else {
5931							$sub.hide(this.opts.collapsibleHideDuration, complete);
5932						}
5933					} else {
5934						if (this.opts.hideFunction) {
5935							this.opts.hideFunction.call(this, $sub, complete);
5936						} else {
5937							$sub.hide(this.opts.hideDuration, complete);
5938						}
5939					}
5940					// remove IE iframe shim
5941					if ($sub.dataSM('ie-shim')) {
5942						$sub.dataSM('ie-shim').remove();
5943					}
5944					// deactivate scrolling if it is activated for this sub
5945					if ($sub.dataSM('scroll')) {
5946						$sub.unbind('.smartmenus_scroll').removeDataSM('scroll').dataSM('scroll-arrows').hide();
5947					}
5948					// unhighlight parent item
5949					$sub.dataSM('parent-a').removeClass('highlighted');
5950					var level = $sub.dataSM('level');
5951					this.activatedItems.splice(level - 1, 1);
5952					this.visibleSubMenus.splice(level - 1, 1);
5953					this.$root.triggerHandler('hide.smapi', $sub[0]);
5954				}
5955			},
5956			menuHideAll: function($item) {
5957				if ($item != undefined && $item.parent().hasClass('menu-item') && !$item.parent().hasClass('menu-item-has-children')) return;
5958				if (this.showTimeout) {
5959					clearTimeout(this.showTimeout);
5960					this.showTimeout = 0;
5961				}
5962				// hide all subs
5963				for (var i = this.visibleSubMenus.length - 1; i > 0; i--) {
5964					this.menuHide(this.visibleSubMenus[i]);
5965				}
5966				// hide root if it's popup
5967				if (this.opts.isPopup) {
5968					this.$root.stop(true, true);
5969					if (this.$root.is(':visible')) {
5970						if (this.opts.hideFunction) {
5971							this.opts.hideFunction.call(this, this.$root);
5972						} else {
5973							this.$root.hide(this.opts.hideDuration);
5974						}
5975						// remove IE iframe shim
5976						if (this.$root.dataSM('ie-shim')) {
5977							this.$root.dataSM('ie-shim').remove();
5978						}
5979					}
5980				}
5981				this.activatedItems = [];
5982				this.visibleSubMenus = [];
5983				this.clickActivated = false;
5984				// reset z-index increment
5985				this.zIndexInc = 0;
5986			},
5987			menuIframeShim: function($ul) {
5988				// create iframe shim for the menu
5989				if (IE && this.opts.overlapControlsInIE && !$ul.dataSM('ie-shim')) {
5990					$ul.dataSM('ie-shim', $('<iframe/>').attr({ src: 'javascript:0', tabindex: -9 })
5991						.css({ position: 'absolute', top: 'auto', left: '0', opacity: 0, border: '0' })
5992					);
5993				}
5994			},
5995			menuInit: function($ul) {
5996				if (!$ul.dataSM('in-mega')) {
5997					this.subMenus.push($ul);
5998					// mark UL's in mega drop downs (if any) so we can neglect them
5999					if ($ul.hasClass('mega-menu')) {
6000						$ul.find('ul').dataSM('in-mega', true);
6001					}
6002					// get level (much faster than, for example, using parentsUntil)
6003					var level = 2,
6004						par = $ul[0];
6005					while ((par = par.parentNode.parentNode) != this.$root[0]) {
6006						level++;
6007					}
6008					// cache stuff
6009					$ul.dataSM('parent-a', $ul.prevAll('a').eq(-1))
6010						.dataSM('level', level)
6011						.parent().dataSM('sub', $ul);
6012					// add sub indicator to parent item
6013					if (this.opts.subIndicators) {
6014						$ul.dataSM('parent-a').addClass('has-submenu')[this.opts.subIndicatorsPos](this.$subArrow.clone());
6015					}
6016				}
6017			},
6018			menuPosition: function($sub) {
6019				var fixIE = $('html.ie').length;
6020				// if (fixIE) {
6021				// 	var $rowParent = $($sub).closest('.main-menu-container');
6022				// 	$rowParent.height($rowParent.height());
6023				// }
6024				var $a = $sub.dataSM('parent-a'),
6025					$li = $sub.parent(),
6026					$ul = $sub.parent().parent(),
6027					$container = $ul.closest('.row-menu-inner'),
6028					level = $sub.dataSM('level'),
6029					subW = this.getWidth($sub),
6030					subH = this.getHeight($sub),
6031					itemOffset = $a.offset(),
6032					itemX = itemOffset.left,
6033					itemY = itemOffset.top,
6034					itemW = this.getWidth($a),
6035					itemH = this.getHeight($a),
6036					$win = $(window),
6037					winX = $win.scrollLeft(),
6038					winY = $win.scrollTop(),
6039					winW = $win.width(),
6040					winH = $win.height(),
6041					containerW = $container.width(),
6042					containerOffsetX = containerW + ((winW - containerW) / 2),
6043					horizontalParent = $ul.hasClass('sm') && !$ul.hasClass('sm-vertical'),
6044					subOffsetX = level == 2 ? this.opts.mainMenuSubOffsetX : this.opts.subMenusSubOffsetX,
6045					subOffsetY = level == 2 ? this.opts.mainMenuSubOffsetY : this.opts.subMenusSubOffsetY,
6046					x, y, leftPos;
6047				if (horizontalParent) {
6048					x = this.opts.rightToLeftSubMenus ? itemW - subW - subOffsetX : subOffsetX;
6049					y = this.opts.bottomToTopSubMenus ? -subH - subOffsetY : itemH + subOffsetY;
6050				} else {
6051					x = this.opts.rightToLeftSubMenus ? subOffsetX - subW : itemW - subOffsetX;
6052					y = this.opts.bottomToTopSubMenus ? itemH - subOffsetY - subH : subOffsetY;
6053				}
6054				if (this.opts.keepInViewport && !this.isCollapsible()) {
6055					if (this.isFixed()) {
6056						itemX -= winX;
6057						itemY -= winY;
6058						winX = winY = 0;
6059					}
6060					var absX = itemX + x,
6061						absY = itemY + y;
6062					if (this.opts.rightToLeftSubMenus && absX < winX) {
6063						x = horizontalParent ? winX - absX + x : itemW - subOffsetX;
6064					} else if (!this.opts.rightToLeftSubMenus && absX + subW > winX + containerOffsetX ) {
6065						x = horizontalParent ? winX + containerOffsetX - subW - absX + x : subOffsetX - subW;
6066					}
6067					if (!horizontalParent) {
6068						if (subH < winH && absY + subH > winY + winH) {
6069							y += winY + winH - subH - absY;
6070						} else if (subH >= winH || absY < winY) {
6071							y += winY - absY;
6072						}
6073					}
6074					// do we need scrolling?
6075					// 0.49 added for the sake of IE9/FF4+ where we might be dealing with float numbers for "subH"
6076					if (mouse && (horizontalParent && (absY + subH > winY + winH + 0.49 || absY < winY) || !horizontalParent && subH > winH + 0.49)) {
6077						var self = this;
6078						if (!$sub.dataSM('scroll-arrows')) {
6079							$sub.dataSM('scroll-arrows', $([$('<span class="scroll-up"><span class="scroll-up-arrow"></span></span>')[0], $('<span class="scroll-down"><span class="scroll-down-arrow"></span></span>')[0]])
6080								.bind({
6081									mouseenter: function() { self.menuScroll($sub, $(this).hasClass('scroll-up')); },
6082									mouseleave: function(e) {
6083										self.menuScrollStop($sub);
6084										self.menuScrollOut($sub, e);
6085									},
6086									'mousewheel DOMMouseScroll': function(e) { e.preventDefault(); }
6087								})
6088								.insertAfter($sub)
6089							);
6090						}
6091						// bind events to show/hide arrows on hover and save scrolling data for this sub
6092						var vportY = winY - (itemY + itemH);
6093						$sub.dataSM('scroll', {
6094								vportY: vportY,
6095								subH: subH,
6096								winH: winH,
6097								step: 1
6098							})
6099							.bind({
6100								'mouseover.smartmenus_scroll': function(e) { self.menuScrollOver($sub, e); },
6101								'mouseout.smartmenus_scroll': function(e) { self.menuScrollOut($sub, e); },
6102								'mousewheel.smartmenus_scroll DOMMouseScroll.smartmenus_scroll': function(e) { self.menuScrollMousewheel($sub, e); }
6103							})
6104							.dataSM('scroll-arrows').css({ top: 'auto', left: '0', marginLeft: x + (parseInt($sub.css('border-left-width')) || 0), width: this.getWidth($sub) - (parseInt($sub.css('border-left-width')) || 0) - (parseInt($sub.css('border-right-width')) || 0), zIndex: this.get
6104StartZIndex() + this.zIndexInc })
6105							.eq(0).css('margin-top', vportY).end()
6106							.eq(1).css('margin-top', vportY + winH - this.getHeight($sub.dataSM('scroll-arrows').eq(1))).end()
6107							.eq(horizontalParent && this.opts.bottomToTopSubMenus ? 0 : 1).show();
6108					}
6109				}
6110				// if ($sub.hasClass('mega-menu-inner')) {
6111				// 	if ($('.menu-wrapper .megamenu-diff').length > 0) {
6112				// 		leftPos = parseFloat($('.menu-wrapper .megamenu-diff').outerWidth());
6113				// 		leftPos = -leftPos;
6114				// 	} else leftPos = parseFloat($('.menu-wrapper .main-menu-container').css('paddingLeft'));
6115
6116				// 	if ($('body.header-full-width').length > 0) {
6117				// 		$sub.css({ width: $('.box-container').width()});
6118				// 		leftPos = (leftPos - parseFloat($('.menu-wrapper .row-menu-inner').css('paddingLeft')));
6119				// 	} else $sub.css({ width: containerW});
6120				// 	leftPos = leftPos + 'px';
6121
6122				// } else {
6123				// 	leftPos = $li.position().left + 'px';
6124				// }
6125				if ($sub.hasClass('mega-menu-inner')) {
6126					$sub.css({ width: containerW});
6127					if ($('body.hmenu-center-split').length > 0) {
6128						leftPos = - ($sub.closest('#menu-main-menu')[0].offsetLeft) + 'px';
6129					} else {
6130						if ($sub.closest('.row-menu-inner').find('.logo-container').length > 0) {
6131							leftPos = - (parseFloat($sub.closest('.row-menu-inner').find('.logo-container').css('paddingRight')) + ($sub.closest('.row-menu-inner').find('.logo-container').width())) + 'px';
6132						} else {
6133							leftPos = '0px';
6134						}
6135					}
6136				} else {
6137					leftPos = (level > 2 ? $li.position().left - parseFloat($li.closest('ul').css('paddingLeft')) : $li.position().left ) + 'px';
6138					x = (level > 2 && x >= 0) ? x + (parseFloat($li.closest('ul').css('paddingLeft')) * 2) + 1 : x - 1;
6139				}
6140
6141				$sub.css({ top: (level > 2) ? $a[0].offsetTop : (fixIE ? itemH : '100%'), left: leftPos, marginLeft: x, marginTop: (level > 2) ? 0 : y - itemH + ($sub.closest('.menu-mini').length ? 0 : 1) });
6142				// IE iframe shim
6143				this.menuIframeShim($sub);
6144				if ($sub.dataSM('ie-shim')) {
6145					$sub.dataSM('ie-shim').css({ zIndex: $sub.css('z-index'), width: subW, height: subH, marginLeft: x, marginTop: y - itemH + ($sub.closest('.menu-mini').length ? 0 : 1) });
6146				}
6147			},
6148			menuScroll: function($sub, up, wheel) {
6149				var y = parseFloat($sub.css('margin-top')),
6150					scroll = $sub.dataSM('scroll'),
6151					end = scroll.vportY + (up ? 0 : scroll.winH - scroll.subH),
6152					step = wheel || !this.opts.scrollAccelerate ? this.opts.scrollStep : Math.floor($sub.dataSM('scroll').step);
6153				$sub.add($sub.dataSM('ie-shim')).css('margin-top', Math.abs(end - y) > step ? y + (up ? step : -step) : end);
6154				y = parseFloat($sub.css('margin-top'));
6155				// show opposite arrow if appropriate
6156				if (up && y + scroll.subH > scroll.vportY + scroll.winH || !up && y < scroll.vportY) {
6157					$sub.dataSM('scroll-arrows').eq(up ? 1 : 0).show();
6158				}
6159				// accelerate when not using mousewheel to scroll
6160				if (!wheel && this.opts.scrollAccelerate && $sub.dataSM('scroll').step < this.opts.scrollStep) {
6161					$sub.dataSM('scroll').step += 0.5;
6162				}
6163				// "y" and "end" might be float numbers in IE9/FF4+ so this weird way to check is used
6164				if (Math.abs(y - end) < 1) {
6165					$sub.dataSM('scroll-arrows').eq(up ? 0 : 1).hide();
6166					$sub.dataSM('scroll').step = 1;
6167				} else if (!wheel) {
6168					var self = this;
6169					this.scrollTimeout = setTimeout(function() { self.menuScroll($sub, up); }, this.opts.scrollInterval);
6170				}
6171			},
6172			menuScrollMousewheel: function($sub, e) {
6173				var $closestSub = $(e.target).closest('ul');
6174				while ($closestSub.dataSM('in-mega')) {
6175					$closestSub = $closestSub.parent().closest('ul');
6176				}
6177				if ($closestSub[0] == $sub[0]) {
6178					var up = (e.originalEvent.wheelDelta || -e.originalEvent.detail) > 0;
6179					if ($sub.dataSM('scroll-arrows').eq(up ? 0 : 1).is(':visible')) {
6180						this.menuScroll($sub, up, true);
6181					}
6182				}
6183				e.preventDefault();
6184			},
6185			menuScrollOut: function($sub, e) {
6186				var reClass = /^scroll-(up|down)/,
6187					$closestSub = $(e.relatedTarget).closest('ul');
6188				while ($closestSub.dataSM('in-mega')) {
6189					$closestSub = $closestSub.parent().closest('ul');
6190				}
6191				if (!reClass.test((e.relatedTarget || '').className) && ($sub[0] != e.relatedTarget && !$.contains($sub[0], e.relatedTarget) || $closestSub[0] != $sub[0])) {
6192					$sub.dataSM('scroll-arrows').css('visibility', 'hidden');
6193				}
6194			},
6195			menuScrollOver: function($sub, e) {
6196				var reClass = /^scroll-(up|down)/,
6197					$closestSub = $(e.target).closest('ul');
6198				while ($closestSub.dataSM('in-mega')) {
6199					$closestSub = $closestSub.parent().closest('ul');
6200				}
6201				if (!reClass.test(e.target.className) && $closestSub[0] == $sub[0]) {
6202					$sub.dataSM('scroll-arrows').css('visibility', 'visible');
6203				}
6204			},
6205			menuScrollStop: function($sub) {
6206				if (this.scrollTimeout) {
6207					clearTimeout(this.scrollTimeout);
6208					this.scrollTimeout = 0;
6209					$sub.dataSM('scroll').step = 1;
6210				}
6211			},
6212			menuShow: function($sub) {
6213				if (!$sub.dataSM('beforefirstshowfired')) {
6214					$sub.dataSM('beforefirstshowfired', true);
6215					if (this.$root.triggerHandler('beforefirstshow.smapi', $sub[0]) === false) {
6216						return;
6217					}
6218				}
6219				if (this.$root.triggerHandler('beforeshow.smapi', $sub[0]) === false) {
6220					return;
6221				}
6222				this.menuFixLayout($sub);
6223				$sub.stop(true, true);
6224				if (!$sub.is(':visible')) {
6225					// set z-index - for IE < 9 set it to the parent LI
6226					var zIndex = this.getStartZIndex() + (++this.zIndexInc);
6227					if (IElt9) {
6228						$sub.parent().css('z-index', zIndex);
6229					} else {
6230						$sub.css('z-index', zIndex);
6231					}
6232					// highlight parent item
6233					if (this.opts.keepHighlighted || this.isCollapsible()) {
6234						if ($sub.dataSM('parent-a').attr('data-type') != 'title')
6235							$sub.dataSM('parent-a').addClass('highlighted');
6236					}
6237					// min/max-width fix - no way to rely purely on CSS as all UL's are nested
6238					if (this.opts.subMenusMinWidth || this.opts.subMenusMaxWidth) {
6239						if (!IElt8) {
6240							$sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
6241							if (this.opts.subMenusMinWidth) {
6242							 	$sub.css('min-width', this.opts.subMenusMinWidth);
6243							}
6244							if (this.opts.subMenusMaxWidth) {
6245							 	var noMaxWidth = this.getWidth($sub);
6246							 	$sub.css('max-width', this.opts.subMenusMaxWidth);
6247								if (noMaxWidth > this.getWidth($sub)) {
6248									$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
6249								}
6250							}
6251						// IE6,7
6252 						} else {
6253							$sub.children().css('styleFloat', 'none');
6254							if (IE6) {
6255								$sub.width(this.opts.subMenusMinWidth ? this.opts.subMenusMinWidth : 1)
6256									.children().children('a').css('white-space', 'nowrap');
6257							} else { // IE7
6258								$sub.css({ width: ($sub.hasClass('mega-menu-inner')) ? $('.box-container').outerWidth() + 'px' : 'auto', minWidth: '', maxWidth: '' }).addClass('sm-nowrap');
6259								if (this.opts.subMenusMinWidth) {
6260							    $sub.css('min-width', this.opts.subMenusMinWidth);
6261								}
6262							}
6263							if (this.opts.subMenusMaxWidth) {
6264								var noMaxWidth = $sub.width();
6265								if (IE6) {
6266							 		var maxWidth = $sub.css({ width: this.opts.subMenusMaxWidth, overflowX: 'hidden', overflowY: 'hidden' }).width();
6267									if (noMaxWidth > maxWidth) {
6268										$sub.css({ width: maxWidth, overflowX: 'visible', overflowY: 'visible' }).children().children('a').css('white-space', '');
6269									} else {
6270										$sub.css({ width: noMaxWidth, overflowX: 'visible', overflowY: 'visible' });
6271									}
6272								} else { // IE7
6273									$sub.css('max-width', this.opts.subMenusMaxWidth);
6274									if (noMaxWidth > $sub.width()) {
6275										$sub.removeClass('sm-nowrap').css('width', this.opts.subMenusMaxWidth);
6276									} else {
6277										$sub.width(noMaxWidth);
6278									}
6279								}
6280							} else {
6281							 	$sub.width($sub.width());
6282							}
6283							$sub.children().css('styleFloat', 'left');
6284						}
6285					}
6286					this.menuPosition($sub);
6287					// insert IE iframe shim
6288					if ($sub.dataSM('ie-shim')) {
6289						$sub.dataSM('ie-shim').insertBefore($sub);
6290					}
6291					var complete = function() {
6292						// fix: "overflow: hidden;" is not reset on animation complete in jQuery < 1.9.0 in Chrome when global "box-sizing: border-box;" is used
6293						$sub.css('overflow', '');
6294					};
6295					// if sub is collapsible (mobile view)
6296					if (this.isCollapsible()) {
6297						if (this.opts.collapsibleShowFunction) {
6298							this.opts.collapsibleShowFunction.call(this, $sub, complete);
6299						} else {
6300							$sub.show(this.opts.collapsibleShowDuration, complete);
6301						}
6302					} else {
6303						if (this.opts.showFunction) {
6304							this.opts.showFunction.call(this, $sub, complete);
6305						} else {
6306							$sub.show(this.opts.showDuration, complete);
6307						}
6308					}
6309					// save new sub menu for this level
6310					this.visibleSubMenus[$sub.dataSM('level') - 1] = $sub;
6311					this.$root.triggerHandler('show.smapi', $sub[0]);
6312				}
6313			},
6314			popupHide: function(noHideTimeout) {
6315				if (this.hideTimeout) {
6316					clearTimeout(this.hideTimeout);
6317					this.hideTimeout = 0;
6318				}
6319				var self = this;
6320				this.hideTimeout = setTimeout(function() {
6321					self.menuHideAll();
6322				}, noHideTimeout ? 1 : this.opts.hideTimeout);
6323			},
6324			popupShow: function(left, top) {
6325				if (!this.opts.isPopup) {
6326					alert('SmartMenus jQuery Error:\n\nIf you want to show this menu via the "popupShow" method, set the isPopup:true option.');
6327					return;
6328				}
6329				if (this.hideTimeout) {
6330					clearTimeout(this.hideTimeout);
6331					this.hideTimeout = 0;
6332				}
6333				this.menuFixLayout(this.$root);
6334				this.$root.stop(true, true);
6335				if (!this.$root.is(':visible')) {
6336					this.$root.css({ left: left, top: top });
6337					// IE iframe shim
6338					this.menuIframeShim(this.$root);
6339					if (this.$root.dataSM('ie-shim')) {
6340						this.$root.dataSM('ie-shim').css({ zIndex: this.$root.css('z-index'), width: this.getWidth(this.$root), height: this.getHeight(this.$root), left
6340: left, top: top }).insertBefore(this.$root);
6341					}
6342					// show menu
6343					if (this.opts.showFunction) {
6344						this.opts.showFunction.call(this, this.$root);
6345					} else {
6346						this.$root.show(this.opts.showDuration);
6347					}
6348					this.visibleSubMenus[0] = this.$root;
6349				}
6350			},
6351			refresh: function() {
6352				this.menuHideAll();
6353				this.$root.find('ul').each(function() {
6354						var $this = $(this);
6355						if ($this.dataSM('scroll-arrows')) {
6356							$this.dataSM('scroll-arrows').remove();
6357						}
6358					})
6359					.removeDataSM('in-mega')
6360					.removeDataSM('shown-before')
6361					.removeDataSM('ie-shim')
6362					.removeDataSM('scroll-arrows')
6363					.removeDataSM('parent-a')
6364					.removeDataSM('level')
6365					.removeDataSM('beforefirstshowfired');
6366				this.$root.find('a.has-submenu').removeClass('has-submenu')
6367					.parent().removeDataSM('sub');
6368				if (this.opts.subIndicators) {
6369					this.$root.find('span.sub-arrow').remove();
6370				}
6371				if (this.opts.markCurrentItem) {
6372					this.$root.find('a.current').removeClass('current');
6373				}
6374				this.subMenus = [];
6375				this.init(true);
6376			},
6377			rootOut: function(e) {
6378				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
6379					return;
6380				}
6381				if (this.hideTimeout) {
6382					clearTimeout(this.hideTimeout);
6383					this.hideTimeout = 0;
6384				}
6385				if (!this.opts.showOnClick || !this.opts.hideOnClick) {
6386					var self = this;
6387					this.hideTimeout = setTimeout(function() { self.menuHideAll(); }, this.opts.hideTimeout);
6388				}
6389			},
6390			rootOver: function(e) {
6391				if (!this.handleEvents() || this.isTouchMode() || e.target == this.$root[0]) {
6392					return;
6393				}
6394				if (this.hideTimeout) {
6395					clearTimeout(this.hideTimeout);
6396					this.hideTimeout = 0;
6397				}
6398			},
6399			winResize: function(e) {
6400				if (!this.handleEvents()) {
6401					// we still need to resize the disable overlay if it's visible
6402					if (this.$disableOverlay) {
6403						var pos = this.$root.offset();
6404	 					this.$disableOverlay.css({
6405							top: pos.top,
6406							left: pos.left,
6407							width: this.$root.outerWidth(),
6408							height: this.$root.outerHeight()
6409						});
6410					}
6411					return;
6412				}
6413				// hide sub menus on resize - on mobile do it only on orientation change
6414				if (!this.isCollapsible() && (!('onorientationchange' in window) || e.type == 'orientationchange')) {
6415					if (this.activatedItems.length) {
6416						this.activatedItems[this.activatedItems.length - 1][0].blur();
6417					}
6418					this.menuHideAll();
6419				}
6420			}
6421		}
6422	});
6423
6424	$.fn.dataSM = function(key, val) {
6425		if (val) {
6426			return this.data(key + '_smartmenus', val);
6427		}
6428		return this.data(key + '_smartmenus');
6429	}
6430
6431	$.fn.removeDataSM = function(key) {
6432		return this.removeData(key + '_smartmenus');
6433	}
6434
6435	$.fn.smartmenus = function(options) {
6436		if (typeof options == 'string') {
6437			var args = arguments,
6438				method = options;
6439			Array.prototype.shift.call(args);
6440			return this.each(function() {
6441				var smartmenus = $(this).data('smartmenus');
6442				if (smartmenus && smartmenus[method]) {
6443					smartmenus[method].apply(smartmenus, args);
6444				}
6445			});
6446		}
6447		var opts = $.extend({}, $.fn.smartmenus.defaults, options);
6448		return this.each(function() {
6449			new $.SmartMenus(this, opts);
6450		});
6451	}
6452
6453	// default settings
6454	$.fn.smartmenus.defaults = {
6455		isPopup:		false,		// is this a popup menu (can be shown via the popupShow/popupHide methods) or a permanent menu bar
6456		mainMenuSubOffsetX:	0,		// pixels offset from default position
6457		mainMenuSubOffsetY:	0,		// pixels offset from default position
6458		subMenusSubOffsetX:	0,		// pixels offset from default position
6459		subMenusSubOffsetY:	0,		// pixels offset from default position
6460		subMenusMinWidth:	'10em',		// min-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
6461		subMenusMaxWidth:	'20em',		// max-width for the sub menus (any CSS unit) - if set, the fixed width set in CSS will be ignored
6462		subIndicators: 		true,		// create sub menu indicators - creates a SPAN and inserts it in the A
6463		subIndicatorsPos: 	'prepend',	// position of the SPAN relative to the menu item content ('prepend', 'append')
6464		subIndicatorsText:	'+',		// [optionally] add text in the SPAN (e.g. '+') (you may want to check the CSS for the sub indicators too)
6465		scrollStep: 		30,		// pixels step when scrolling long sub menus that do not fit in the viewport height
6466		scrollInterval:		30,		// interval between each scrolling step
6467		scrollAccelerate:	true,		// accelerate scrolling or use a fixed step
6468		showTimeout:		250,		// timeout before showing the sub menus
6469		hideTimeout:		500,		// timeout before hiding the sub menus
6470		showDuration:		0,		// duration for show animation - set to 0 for no animation - matters only if showFunction:null
6471		showFunction:		null,		// custom function to use when showing a sub menu (the default is the jQuery 'show')
6472							// don't forget to call complete() at the end of whatever you do
6473							// e.g.: function($ul, complete) { $ul.fadeIn(250, complete); }
6474		hideDuration:		0,		// duration for hide animation - set to 0 for no animation - matters only if hideFunction:null
6475		hideFunction:		function($ul, complete) { $ul.fadeOut(200, complete); },	// custom function to use when hiding a sub menu (the default is the jQuery 'hide')
6476							// don't forget to call complete() at the end of whatever you do
6477							// e.g.: function($ul, complete) { $ul.fadeOut(250, complete); }
6478		collapsibleShowDuration:0,		// duration for show animation for collapsible sub menus - matters only if collapsibleShowFunction:null
6479		collapsibleShowFunction:function($ul, complete) { $ul.slideDown(200, complete); },	// custom function to use when showing a collapsible sub menu
6480							// (i.e. when mobile styles are used to make the sub menus collapsible)
6481		collapsibleHideDuration:0,		// duration for hide animation for collapsible sub menus - matters only if collapsibleHideFunction:null
6482		collapsibleHideFunction:function($ul, complete) { $ul.slideUp(200, complete); },	// custom function to use when hiding a collapsible sub menu
6483							// (i.e. when mobile styles are used to make the sub menus collapsible)
6484		showOnClick:		false,		// show the first-level sub menus onclick instead of onmouseover (matters only for mouse input)
6485		hideOnClick:		true,		// hide the sub menus on click/tap anywhere on the page
6486		keepInViewport:		true,		// reposition the sub menus if needed to make sure they always appear inside the viewport
6487		keepHighlighted:	true,		// keep all ancestor items of the current sub menu highlighted (adds the 'highlighted' class to the A's)
6488		markCurrentItem:	false,		// automatically add the 'current' class to the A element of the item linking to the current URL
6489		markCurrentTree:	true,		// add the 'current' class also to the A elements of all ancestor items of the current item
6490		rightToLeftSubMenus:	false,		// right to left display of the sub menus (check the CSS for the sub indicators' position)
6491		bottomToTopSubMenus:	false,		// bottom to top display of the sub menus
6492		overlapControlsInIE:	true		// make sure sub menus appear on top of special OS controls in IE (i.e. SELECT, OBJECT, EMBED, etc.)
6493	};
6494
6495})(jQuery);
6496
6497/*
6498 * jQuery Easing v1.3 - http://gsgd.co.uk/sandbox/jquery/easing/
6499 *
6500 * Uses the built in easing capabilities added In jQuery 1.1
6501 * to offer multiple easing options
6502 *
6503 * TERMS OF USE - jQuery Easing
6504 * 
6505 * Open source under the BSD License. 
6506 * 
6507 * Copyright © 2008 George McGinley Smith
6508 * All rights reserved.
6509 * 
6510 * Redistribution and use in source and binary forms, with or without modification, 
6511 * are permitted provided that the following conditions are met:
6512 * 
6513 * Redistributions of source code must retain the above copyright notice, this list of 
6514 * conditions and the following disclaimer.
6515 * Redistributions in binary form must reproduce the above copyright notice, this list 
6516 * of conditions and the following disclaimer in the documentation and/or other materials 
6517 * provided with the distribution.
6518 * 
6519 * Neither the name of the author nor the names of contributors may be used to endorse 
6520 * or promote products derived from this software without specific prior written permission.
6521 * 
6522 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
6523 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
6524 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6525 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
vendor: 5,091 bytes, lines 6526-6671
6526 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6527 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
6528 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6529 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
6530 * OF THE POSSIBILITY OF SUCH DAMAGE. 
6531 *
6532*/
6533
6534// t: current time, b: begInnIng value, c: change In value, d: duration
6535jQuery.easing['jswing'] = jQuery.easing['swing'];
6536
6537jQuery.extend( jQuery.easing,
6538{
6539	def: 'easeOutQuad',
6540	swing: function (x, t, b, c, d) {
6541		//alert(jQuery.easing.default);
6542		return jQuery.easing[jQuery.easing.def](x, t, b, c, d);
6543	},
6544	easeInQuad: function (x, t, b, c, d) {
6545		return c*(t/=d)*t + b;
6546	},
6547	easeOutQuad: function (x, t, b, c, d) {
6548		return -c *(t/=d)*(t-2) + b;
6549	},
6550	easeInOutQuad: function (x, t, b, c, d) {
6551		if ((t/=d/2) < 1) return c/2*t*t + b;
6552		return -c/2 * ((--t)*(t-2) - 1) + b;
6553	},
6554	easeInCubic: function (x, t, b, c, d) {
6555		return c*(t/=d)*t*t + b;
6556	},
6557	easeOutCubic: function (x, t, b, c, d) {
6558		return c*((t=t/d-1)*t*t + 1) + b;
6559	},
6560	easeInOutCubic: function (x, t, b, c, d) {
6561		if ((t/=d/2) < 1) return c/2*t*t*t + b;
6562		return c/2*((t-=2)*t*t + 2) + b;
6563	},
6564	easeInQuart: function (x, t, b, c, d) {
6565		return c*(t/=d)*t*t*t + b;
6566	},
6567	easeOutQuart: function (x, t, b, c, d) {
6568		return -c * ((t=t/d-1)*t*t*t - 1) + b;
6569	},
6570	easeInOutQuart: function (x, t, b, c, d) {
6571		if ((t/=d/2) < 1) return c/2*t*t*t*t + b;
6572		return -c/2 * ((t-=2)*t*t*t - 2) + b;
6573	},
6574	easeInQuint: function (x, t, b, c, d) {
6575		return c*(t/=d)*t*t*t*t + b;
6576	},
6577	easeOutQuint: function (x, t, b, c, d) {
6578		return c*((t=t/d-1)*t*t*t*t + 1) + b;
6579	},
6580	easeInOutQuint: function (x, t, b, c, d) {
6581		if ((t/=d/2) < 1) return c/2*t*t*t*t*t + b;
6582		return c/2*((t-=2)*t*t*t*t + 2) + b;
6583	},
6584	easeInSine: function (x, t, b, c, d) {
6585		return -c * Math.cos(t/d * (Math.PI/2)) + c + b;
6586	},
6587	easeOutSine: function (x, t, b, c, d) {
6588		return c * Math.sin(t/d * (Math.PI/2)) + b;
6589	},
6590	easeInOutSine: function (x, t, b, c, d) {
6591		return -c/2 * (Math.cos(Math.PI*t/d) - 1) + b;
6592	},
6593	easeInExpo: function (x, t, b, c, d) {
6594		return (t==0) ? b : c * Math.pow(2, 10 * (t/d - 1)) + b;
6595	},
6596	easeOutExpo: function (x, t, b, c, d) {
6597		return (t==d) ? b+c : c * (-Math.pow(2, -10 * t/d) + 1) + b;
6598	},
6599	easeInOutExpo: function (x, t, b, c, d) {
6600		if (t==0) return b;
6601		if (t==d) return b+c;
6602		if ((t/=d/2) < 1) return c/2 * Math.pow(2, 10 * (t - 1)) + b;
6603		return c/2 * (-Math.pow(2, -10 * --t) + 2) + b;
6604	},
6605	easeInCirc: function (x, t, b, c, d) {
6606		return -c * (Math.sqrt(1 - (t/=d)*t) - 1) + b;
6607	},
6608	easeOutCirc: function (x, t, b, c, d) {
6609		return c * Math.sqrt(1 - (t=t/d-1)*t) + b;
6610	},
6611	easeInOutCirc: function (x, t, b, c, d) {
6612		if ((t/=d/2) < 1) return -c/2 * (Math.sqrt(1 - t*t) - 1) + b;
6613		return c/2 * (Math.sqrt(1 - (t-=2)*t) + 1) + b;
6614	},
6615	easeInElastic: function (x, t, b, c, d) {
6616		var s=1.70158;var p=0;var a=c;
6617		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
6618		if (a < Math.abs(c)) { a=c; var s=p/4; }
6619		else var s = p/(2*Math.PI) * Math.asin (c/a);
6620		return -(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
6621	},
6622	easeOutElastic: function (x, t, b, c, d) {
6623		var s=1.70158;var p=0;var a=c;
6624		if (t==0) return b;  if ((t/=d)==1) return b+c;  if (!p) p=d*.3;
6625		if (a < Math.abs(c)) { a=c; var s=p/4; }
6626		else var s = p/(2*Math.PI) * Math.asin (c/a);
6627		return a*Math.pow(2,-10*t) * Math.sin( (t*d-s)*(2*Math.PI)/p ) + c + b;
6628	},
6629	easeInOutElastic: function (x, t, b, c, d) {
6630		var s=1.70158;var p=0;var a=c;
6631		if (t==0) return b;  if ((t/=d/2)==2) return b+c;  if (!p) p=d*(.3*1.5);
6632		if (a < Math.abs(c)) { a=c; var s=p/4; }
6633		else var s = p/(2*Math.PI) * Math.asin (c/a);
6634		if (t < 1) return -.5*(a*Math.pow(2,10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )) + b;
6635		return a*Math.pow(2,-10*(t-=1)) * Math.sin( (t*d-s)*(2*Math.PI)/p )*.5 + c + b;
6636	},
6637	easeInBack: function (x, t, b, c, d, s) {
6638		if (s == undefined) s = 1.70158;
6639		return c*(t/=d)*t*((s+1)*t - s) + b;
6640	},
6641	easeOutBack: function (x, t, b, c, d, s) {
6642		if (s == undefined) s = 1.70158;
6643		return c*((t=t/d-1)*t*((s+1)*t + s) + 1) + b;
6644	},
6645	easeInOutBack: function (x, t, b, c, d, s) {
6646		if (s == undefined) s = 1.70158; 
6647		if ((t/=d/2) < 1) return c/2*(t*t*(((s*=(1.525))+1)*t - s)) + b;
6648		return c/2*((t-=2)*t*(((s*=(1.525))+1)*t + s) + 2) + b;
6649	},
6650	easeInBounce: function (x, t, b, c, d) {
6651		return c - jQuery.easing.easeOutBounce (x, d-t, 0, c, d) + b;
6652	},
6653	easeOutBounce: function (x, t, b, c, d) {
6654		if ((t/=d) < (1/2.75)) {
6655			return c*(7.5625*t*t) + b;
6656		} else if (t < (2/2.75)) {
6657			return c*(7.5625*(t-=(1.5/2.75))*t + .75) + b;
6658		} else if (t < (2.5/2.75)) {
6659			return c*(7.5625*(t-=(2.25/2.75))*t + .9375) + b;
6660		} else {
6661			return c*(7.5625*(t-=(2.625/2.75))*t + .984375) + b;
6662		}
6663	},
6664	easeInOutBounce: function (x, t, b, c, d) {
6665		if (t < d/2) return jQuery.easing.easeInBounce (x, t*2, 0, c, d) * .5 + b;
6666		return jQuery.easing.easeOutBounce (x, t*2-d, 0, c, d) * .5 + c*.5 + b;
6667	}
6668});
6669
6670/*
6671 *
6672 * TERMS OF USE - EASING EQUATIONS
6673 * 
6674 * Open source under the BSD License. 
6675 * 
6676 * Copyright © 2001 Robert Penner
6677 * All rights reserved.
6678 * 
6679 * Redistribution and use in source and binary forms, with or without modification, 
6680 * are permitted provided that the following conditions are met:
6681 * 
6682 * Redistributions of source code must retain the above copyright notice, this list of 
6683 * conditions and the following disclaimer.
6684 * Redistributions in binary form must reproduce the above copyright notice, this list 
6685 * of conditions and the following disclaimer in the documentation and/or other materials 
6686 * provided with the distribution.
6687 * 
6688 * Neither the name of the author nor the names of contributors may be used to endorse 
6689 * or promote products derived from this software without specific prior written permission.
6690 * 
6691 * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" AND ANY 
6692 * EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
6693 * MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
6694 *  COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
6695 *  EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE
6696 *  GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED 
6697 * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
6698 *  NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED 
6699 * OF THE POSSIBILITY OF SUCH DAMAGE. 
6700 *
6701 */
6702
6703(function($, window, undefined) {
6704    // http://paulirish.com/2011/requestanimationframe-for-smart-animating/
6705    // http://my.opera.com/emoller/blog/2011/12/20/requestanimationframe-for-smart-er-animating
6706 
6707    // requestAnimationFrame polyfill by Erik Möller
6708    // fixes from Paul Irish and Tino Zijdel
6709 
6710    var lastTime = 0,
6711        running,
6712        animate = function (elem) {
6713            if (running) {
6714                window.requestAnimationFrame(animate, elem);
6715                jQuery.fx.tick();
6716            }
6717        },
6718        vendors = ['ms', 'moz', 'webkit', 'o'];
6719 
6720    for(var x = 0; x < vendors.length && !window.requestAnimationFrame; ++x) {
6721        window.requestAnimationFrame = window[vendors[x]+'RequestAnimationFrame'];
6722        window.cancelAnimationFrame = window[vendors[x]+'CancelAnimationFrame']
6723            || window[vendors[x]+'CancelRequestAnimationFrame'];
6724    }
6725 
6726    if (!window.requestAnimationFrame)
6727        window.requestAnimationFrame = function(fn, element) {
6728            var currTime = new Date().getTime(),
6729                delta = currTime - lastTime,
6730                timeToCall = Math.max(0, 16 - delta);
6731 
6732            var id = window.setTimeout(function() {
6733                    fn(currTime + timeToCall);
6734                },
6735                timeToCall
6736            );
6737 
6738            lastTime = currTime + timeToCall;
6739 
6740            return id;
6741        };
6742 
6743    if (!window.cancelAnimationFrame) {
6744        window.cancelAnimationFrame = function(id) {
6745            clearTimeout(id);
6746        };
6747    }
6748 
6749    jQuery.fx.timer = function (timer) {
6750        if (timer() && jQuery.timers.push(timer) && !running) {
6751            running = true;
6752            animate(timer.elem);
6753        }
6754    };
6755 
6756    jQuery.fx.stop = function() {
6757        running = false;
6758    };
6759 
6760}(jQuery, this));
6761
6762/*! Copyright (c) 2011 Brandon Aaron (http://brandonaaron.net)
6763 * Licensed under the MIT License (LICENSE.txt).
6764 *
6765 * Thanks to: http://adomas.org/javascript-mouse-wheel/ for some pointers.
6766 * Thanks to: Mathias Bank(http://www.mathias-bank.de) for a scope bug fix.
6767 * Thanks to: Seamus Leahy for adding deltaX and deltaY
6768 *
6769 * Version: 3.0.6
6770 *
6771 * Requires: 1.2.2+
6772 */
6773(function($) {
6774    var types = ['DOMMouseScroll', 'mousewheel'];
6775    if ($.event.fixHooks) {
6776        for (var i = types.length; i;) {
6777            $.event.fixHooks[types[--i]] = $.event.mouseHooks;
6778        }
6779    }
6780    $.event.special.mousewheel = {
6781        setup: function() {
6782            if (this.addEventListener) {
6783                for (var i = types.length; i;) {
6784                    this.addEventListener(types[--i], handler, false);
6785                }
6786            } else {
6787                this.onmousewheel = handler;
6788            }
6789        },
6790        teardown: function() {
6791            if (this.removeEventListener) {
6792                for (var i = types.length; i;) {
6793                    this.removeEventListener(types[--i], handler, false);
6794                }
6795            } else {
6796                this.onmousewheel = null;
6797            }
6798        }
6799    };
6800    $.fn.extend({
6801        mousewheel: function(fn) {
6802            return fn ? this.bind("mousewheel", fn) : this.trigger("mousewheel");
6803        },
6804        unmousewheel: function(fn) {
6805            return this.unbind("mousewheel", fn);
6806        }
6807    });
6808
6809    function handler(event) {
6810        var orgEvent = event || window.event,
6811            args = [].slice.call(arguments, 1),
6812            delta = 0,
6813            returnValue = true,
6814            deltaX = 0,
6815            deltaY = 0;
6816        event = $.event.fix(orgEvent);
6817        event.type = "mousewheel";
6818        // Old school scrollwheel delta
6819        if (orgEvent.wheelDelta) {
6820            delta = orgEvent.wheelDelta / 120;
6821        }
6822        if (orgEvent.detail) {
6823            delta = -orgEvent.detail / 3;
6824        }
6825        // New school multidimensional scroll (touchpads) deltas
6826        deltaY = delta;
6827        // Gecko
6828        if (orgEvent.axis !== undefined && orgEvent.axis === orgEvent.HORIZONTAL_AXIS) {
6829            deltaY = 0;
6830            deltaX = -1 * delta;
6831        }
6832        // Webkit
6833        if (orgEvent.wheelDeltaY !== undefined) {
6834            deltaY = orgEvent.wheelDeltaY / 120;
6835        }
6836        if (orgEvent.wheelDeltaX !== undefined) {
6837            deltaX = -1 * orgEvent.wheelDeltaX / 120;
6838        }
6839        // Add event and delta to the front of the arguments
6840        args.unshift(event, delta, deltaX, deltaY);
6841        return ($.event.dispatch || $.event.handle).apply(this, args);
6842    }
6843})(jQuery);
6844
6845/**
6846 * jQuery iLightBox - Revolutionary Lightbox Plugin
6847 * http://www.ilightbox.net/
6848 *
6849 * @version: 2.2.0 - September 23, 2014
6850 *
6851 * @author: Hemn Chawroka
6852 *          http://www.iprodev.com/
6853 *
6854 */
6855(function($, window, undefined) {
6856
6857	var extensions = {
6858			flash: ['swf'],
6859			image: ['bmp', 'gif', 'jpeg', 'jpg', 'png', 'tiff', 'tif', 'jfif', 'jpe'],
6860			iframe: ['asp', 'aspx', 'cgi', 'cfm', 'htm', 'html', 'jsp', 'php', 'pl', 'php3', 'php4', 'php5', 'phtml', 'rb', 'rhtml', 'shtml', 'txt'],
6861			video: ['avi', 'mov', 'mpg', 'mpeg', 'movie', 'mp4', 'webm', 'ogv', 'ogg', '3gp', 'm4v']
6862		},
6863
6864		// Global DOM elements
6865		$win = $(window),
6866		$doc = $(document),
6867
6868		// Support indicators
6869		browser,
6870		transform,
6871		gpuAcceleration,
6872		fullScreenApi = '',
6873		supportTouch = !!('ontouchstart' in window) && (/Android|webOS|iPhone|iPad|iPod|BlackBerry|IEMobile|Opera Mini/i.test(navigator.userAgent)),
6874
6875		// Events
6876		clickEvent = supportTouch ? "itap.iLightBox" : "click.iLightBox",
6877		touchStartEvent = supportTouch ? "touchstart.iLightBox" : "mousedown.iLightBox",
6878		touchStopEvent = supportTouch ? "touchend.iLightBox" : "mouseup.iLightBox",
6879		touchMoveEvent = supportTouch ? "touchmove.iLightBox" : "mousemove.iLightBox",
6880
6881		// Math shorthands
6882		abs = Math.abs,
6883		sqrt = Math.sqrt,
6884		round = Math.round,
6885		max = Math.max,
6886		min = Math.min,
6887		floor = Math.floor,
6888		random = Math.random,
6889
6890		pluginspages = {
6891			quicktime: 'http://www.apple.com/quicktime/download',
6892			flash: 'http://www.adobe.com/go/getflash'
6893		},
6894
6895		iLightBox = function(el, options, items, instant) {
6896			var iL = this;
6897
6898			iL.options = options,
6899				iL.selector = el.selector || el,
6900				iL.context = el.context,
6901				iL.instant = instant;
6902
6903			if (items.length < 1) iL.attachItems();
6904			else iL.items = items;
6905
6906			iL.vars = {
6907				total: iL.items.length,
6908				start: 0,
6909				current: null,
6910				next: null,
6911				prev: null,
6912				BODY: $('body'),
6913				loadRequests: 0,
6914				overlay: $('<div class="ilightbox-overlay"></div>'),
6915				loader: $('<div class="ilightbox-loader"><div></div></div>'),
6916				toolbar: $('<div class="ilightbox-toolbar"></div>'),
6917				innerToolbar: $('<div class="ilightbox-inner-toolbar"></div>'),
6918				title: $('<div class="ilightbox-title"></div>'),
6919				closeButton: $('<a class="ilightbox-close" title="' + iL.options.text.close + '"></a>'),
6920				fullScreenButton: $('<a class="ilightbox-fullscreen" title="' + iL.options.text.enterFullscreen + '"></a>'),
6921				innerPlayButton: $('<a class="ilightbox-play" title="' + iL.options.text.slideShow + '"></a>'),
6922				innerNextButton: $('<a class="ilightbox-next-button" title="' + iL.options.text.next + '"></a>'),
6923				innerPrevButton: $('<a class="ilightbox-prev-button" title="' + iL.options.text.previous + '"></a>'),
6924				holder: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + '" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
6925				nextPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-next" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
6926				prevPhoto: $('<div class="ilightbox-holder' + (supportTouch ? ' supportTouch' : '') + ' ilightbox-prev" ondragstart="return false;"><div class="ilightbox-container"></div></div>'),
6927				nextButton: $('<a class="ilightbox-button ilightbox-next-button" ondragstart="return false;" title="' + iL.options.text.next + '"><span></span></a>'),
6928				prevButton: $('<a class="ilightbox-button ilightbox-prev-button" ondragstart="return false;" title="' + iL.options.text.previous + '"><span></span></a>'),
6929				thumbnails: $('<div class="ilightbox-thumbnails" ondragstart="return false;"><div class="ilightbox-thumbnails-container"><a class="ilightbox-thumbnails-dragger"></a><div class="ilightbox-thumbnails-grid"></div></div></div>'),
6930				thumbs: false,
6931				nextLock: false,
6932				prevLock: false,
6933				hashLock: false,
6934				isMobile: false,
6935				mobileMaxWidth: 980,
6936				isInFullScreen: false,
6937				isSwipe: false,
6938				mouseID: 0,
6939				cycleID: 0,
6940				isPaused: 0
6941			};
6942
6943			// Hideable elements with mousemove event
6944			iL.vars.hideableElements = iL.vars.nextButton.add(iL.vars.prevButton);
6945
6946			iL.normalizeItems();
6947
6948			//Check necessary plugins
6949			iL.availPlugins();
6950
6951			//Set startFrom
6952			iL.options.startFrom = (iL.options.startFrom > 0 && iL.options.startFrom >= iL.vars.total) ? iL.vars.total - 1 : iL.options.startFrom;
6953
6954			//If randomStart
6955			iL.options.startFrom = (iL.options.randomStart) ? floor(random() * iL.vars.total) : iL.options.startFrom;
6956			iL.vars.start = iL.options.startFrom;
6957
6958			if (instant) iL.instantCall();
6959			else iL.patchItemsEvents();
6960
6961			if (iL.options.linkId) {
6962				iL.hashChangeHandler();
6963				$win.iLightBoxHashChange(function() {
6964					iL.hashChangeHandler();
6965				});
6966			}
6967
6968			if (supportTouch) {
6969				var RegExp = /(click|mouseenter|mouseleave|mouseover|mouseout)/ig,
6970					replace = "itap";
6971				iL.options.caption.show = iL.options.caption.show.replace(RegExp, replace),
6972					iL.options.caption.hide = iL.options.caption.hide.replace(RegExp, replace),
6973					iL.options.social.show = iL.options.social.show.replace(RegExp, replace),
6974					iL.options.social.hide = iL.options.social.hide.replace(RegExp, replace);
6975			}
6976
6977			if (iL.options.controls.arrows) {
6978				$.extend(iL.options.styles, {
6979					nextOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4,
6980					prevOffsetX: ($(window).width() > UNCODE.mediaQuery) ? 36 : 4,
6981					nextOpacity: 0,
6982					prevOpacity: 0
6983				});
6984			}
6985		};
6986
6987	//iLightBox helpers
6988	iLightBox.prototype = {
6989		showLoader: function() {
6990			var iL = this;
6991			iL.vars.loadRequests += 1;
6992			if (iL.options.path.toLowerCase() == "horizontal") iL.vars.loader.stop().animate({
6993				//top: '2px'
6994				opacity: '1'
6995			}, iL.options.show.speed, 'easeOutCirc');
6996			else iL.vars.loader.stop().animate({
6997			//	left: '2px'
6998				opacity: '1'
6999			}, iL.options.show.speed, 'easeOutCirc');
7000		},
7001
7002		hideLoader: function() {
7003			var iL = this;
7004			iL.vars.loadRequests -= 1;
7005			iL.vars.loadRequests = (iL.vars.loadRequests < 0) ? 0 : iL.vars.loadRequests;
7006			if (iL.options.path.toLowerCase() == "horizontal") {
7007				if (iL.vars.loadRequests <= 0) iL.vars.loader.stop().animate({
7008					//top: '-20px'
7009					opacity: '0'
7010				}, iL.options.show.speed, 'easeInCirc');
7011			} else {
7012				if (iL.vars.loadRequests <= 0) iL.vars.loader.stop().animate({
7013					//left: '-20px'
7014					opacity: '0'
7015				}, iL.options.show.speed, 'easeInCirc');
7016			}
7017		},
7018
7019		createUI: function() {
7020			var iL = this;
7021
7022			iL.ui = {
7023				currentElement: iL.vars.holder,
7024				nextElement: iL.vars.nextPhoto,
7025				prevElement: iL.vars.prevPhoto,
7026				currentItem: iL.vars.current,
7027				nextItem: iL.vars.next,
7028				prevItem: iL.vars.prev,
7029				hide: function() {
7030					iL.closeAction();
7031				},
7032				refresh: function() {
7033					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
7034				},
7035				fullscreen: function() {
7036					iL.fullScreenAction();
7037				}
7038			};
7039		},
7040
7041		attachItems: function() {
7042			var iL = this,
7043				itemsObject = new Array(),
7044				items = new Array();
7045
7046			$(iL.selector, iL.context).each(function() {
7047				var t = $(this),
7048					URL = t.attr(iL.options.attr) || null,
7049					options = t.data("options") && eval("({" + t.data("options") + "})") || {},
7050					caption = t.data('caption'),
7051					title = t.data('title'),
7052					type = t.data('type') || getTypeByExtension(URL);
7053
7054				items.push({
7055					URL: URL,
7056					caption: caption,
7057					title: title,
7058					type: type,
7059					options: options
7060				});
7061
7062				if (!iL.instant) itemsObject.push(t);
7063			});
7064
7065			if (iL.vars != undefined) iL.vars.total = items.length;
7066
7067			iL.items = items,
7068				iL.itemsObject = itemsObject;
7069		},
7070
7071		normalizeItems: function() {
7072			var iL = this,
7073				newItems = new Array();
7074
7075			$.each(iL.items, function(key, val) {
7076
7077				if (typeof val == "string") val = {
7078					url: val
7079				};
7080
7081				var URL = val.url || val.URL || null,
7082					options = val.options || {},
7083					caption = val.caption || null,
7084					title = val.title || null,
7085					type = (val.type) ? val.type.toLowerCase() : getTypeByExtension(URL),
7086					ext = (typeof URL != 'object') ? getExtension(URL) : '';
7087
7088				options.thumbnail = options.thumbnail || ((type == "image") ? URL : null),
7089				options.videoType = options.videoType || null,
7090				options.skin = options.skin || iL.options.skin,
7091				options.width = options.width || null,
7092				options.height = options.height || null,
7093				options.mousewheel = (typeof options.mousewheel != 'undefined') ? options.mousewheel : true,
7094				options.swipe = (typeof options.swipe != 'undefined') ? options.swipe : true,
7095				options.social = (typeof options.social != 'undefined') ? options.social : iL.options.social.buttons && $.extend({}, {}, iL.options.social.buttons);
7096
7097				if (type == "video") {
7098					options.html5video = (typeof options.html5video != 'undefined') ? options.html5video : {};
7099
7100					options.html5video.webm = options.html5video.webm || options.html5video.WEBM || null;
7101					options.html5video.controls = (typeof options.html5video.controls != 'undefined') ? options.html5video.controls : "controls";
7102					options.html5video.preload = options.html5video.preload || "metadata";
7103					options.html5video.autoplay = (typeof options.html5video.autoplay != 'undefined') ? options.html5video.autoplay : false;
7104				}
7105
7106				if (!options.width || !options.height) {
7107					if (type == "video") options.width = 1280, options.height = 720;
7108					else if (type == "iframe") options.width = '100%', options.height = '90%';
7109					else if (type == "flash") options.width = 1280, options.height = 720;
7110				}
7111
7112				delete val.url;
7113				val.index = key;
7114				val.URL = URL;
7115				val.caption = caption;
7116				val.title = title;
7117				val.type = type;
7118				val.options = options;
7119				val.ext = ext;
7120
7121				newItems.push(val);
7122			});
7123
7124			iL.items = newItems;
7125		},
7126
7127		instantCall: function() {
7128			var iL = this,
7129				key = iL.vars.start;
7130
7131			iL.vars.current = key;
7132			iL.vars.next = (iL.items[key + 1]) ? key + 1 : null;
7133			iL.vars.prev = (iL.items[key - 1]) ? key - 1 : null;
7134
7135			iL.addContents();
7136			iL.patchEvents();
7137		},
7138
7139		addContents: function() {
7140			var iL = this,
7141				vars = iL.vars,
7142				opts = iL.options,
7143				viewport = getViewport(),
7144				path = opts.path.toLowerCase(),
7145				recognizingItems = vars.total > 0 && iL.items.filter(function(e, i, arr) {
7146					return ['image', 'flash', 'video'].indexOf(e.type) === -1 && typeof e.recognized === 'undefined' && (opts.smartRecognition || e.options.smartRecognition);
7147				}),
7148				needRecognition = recognizingItems.length > 0;
7149
7150			if (opts.mobileOptimizer && !opts.innerToolbar)
7151				vars.isMobile = viewport.width <= vars.mobileMaxWidth;
7152
7153			vars.overlay.addClass(opts.skin).hide().css('opacity', opts.overlay.opacity);
7154
7155			if (opts.linkId)
7156				vars.overlay[0].setAttribute('linkid', opts.linkId);
7157
7158			//Add Toolbar Buttons
7159			if (opts.controls.toolbar) {
7160				vars.toolbar.addClass(opts.skin).append(vars.closeButton);
7161				if (opts.controls.fullscreen)
7162					vars.toolbar.append(vars.fullScreenButton);
7163				if (opts.controls.slideshow)
7164					vars.toolbar.append(vars.innerPlayButton);
7165				if (vars.total > 1)
7166					vars.toolbar.append(vars.innerPrevButton).append(vars.innerNextButton);
7167			}
7168
7169			//Append elements to body
7170			vars.BODY.addClass('ilightbox-noscroll').append(vars.overlay).append(vars.loader).append(vars.holder).append(vars.nextPhoto).append(vars.prevPhoto);
7171
7172			if (!opts.innerToolbar)
7173				vars.BODY.append(vars.toolbar);
7174			if (opts.controls.arrows)
7175				vars.BODY.append(vars.nextButton).append(vars.prevButton);
7176
7177			if (opts.controls.thumbnail && vars.total > 1) {
7178				vars.BODY.append(vars.thumbnails);
7179				vars.thumbnails.addClass(opts.skin).addClass('ilightbox-' + path);
7180				$('div.ilightbox-thumbnails-grid', vars.thumbnails).empty();
7181				vars.thumbs = true;
7182			}
7183
7184			//Configure loader and arrows
7185			var loaderCss = (opts.path.toLowerCase() == "horizontal") ? {
7186				left: parseInt((viewport.width / 2) - (vars.loader.outerWidth() / 2))
7187			} : {
7188				top: parseInt((viewport.height / 2) - (vars.loader.outerHeight() / 2))
7189			};
7190			vars.loader.addClass(opts.skin).css(loaderCss);
7191			vars.nextButton.add(vars.prevButton).addClass(opts.skin);
7192			if (path == "horizontal")
7193				vars.loader.add(vars.nextButton).add(vars.prevButton).addClass('horizontal');
7194
7195			// Configure arrow buttons
7196			vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');
7197
7198			if (!opts.infinite) {
7199				vars.prevButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.nextButton).add(vars.innerNextButton).removeClass('disabled');
7200
7201				if (vars.current == 0)
7202					vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
7203
7204				if (vars.current >= vars.total - 1)
7205					vars.nextButton.add(vars.innerNextButton).addClass('disabled');
7206			}
7207
7208			if (opts.show.effect) {
7209				vars.overlay.stop().fadeIn(opts.show.speed);
7210				vars.toolbar.stop().fadeIn(opts.show.speed);
7211			} else {
7212				vars.overlay.show();
7213				vars.toolbar.show();
7214			}
7215
7216			var length = recognizingItems.length;
7217			if (needRecognition) {
7218				iL.showLoader();
7219
7220				$.each(recognizingItems, function(key, val) {
7221					var resultFnc = function(result) {
7222							var key = -1,
7223								filter = iL.items.filter(function(e, i, arr) {
7224									if (e.URL == result.url)
7225										key = i;
7226
7227									return e.URL == result.url;
7228								}),
7229								self = iL.items[key];
7230
7231							if (result)
7232								$.extend(true, self, {
7233									URL: result.source,
7234									type: result.type,
7235									recognized: true,
7236									options: {
7237										html5video: result.html5video,
7238										width: (result.type == "image") ? 0 : (result.width || self.width),
7239										height: (result.type == "image") ? 0 : (result.height || self.height),
7240										thumbnail: self.options.thumbnail || result.thumbnail
7241									}
7242								});
7243
7244							length--;
7245
7246							if (length == 0) {
7247								iL.hideLoader();
7248
7249								vars.dontGenerateThumbs = false;
7250								iL.generateThumbnails();
7251
7252								if (opts.show.effect)
7253									setTimeout(function() {
7254										iL.generateBoxes();
7255									}, opts.show.speed);
7256								else
7257									iL.generateBoxes();
7258							}
7259						};
7260
7261					iL.ogpRecognition(this, resultFnc);
7262				});
7263			}
7264			else {
7265				if (opts.show.effect)
7266					setTimeout(function() {
7267						iL.generateBoxes();
7268					}, opts.show.speed);
7269				else
7270					iL.generateBoxes();
7271			}
7272
7273			iL.createUI();
7274
7275			window.iLightBox = {
7276				close: function() {
7277					iL.closeAction();
7278				},
7279				fullscreen: function() {
7280					iL.fullScreenAction();
7281				},
7282				moveNext: function() {
7283					iL.moveTo('next');
7284				},
7285				movePrev: function() {
7286					iL.moveTo('prev');
7287				},
7288				goTo: function(index) {
7289					iL.goTo(index);
7290				},
7291				refresh: function() {
7292					iL.refresh();
7293				},
7294				reposition: function() {
7295					(arguments.length > 0) ? iL.repositionPhoto(true): iL.repositionPhoto();
7296				},
7297				setOption: function(options) {
7298					iL.setOption(options);
7299				},
7300				destroy: function() {
7301					iL.closeAction();
7302					iL.dispatchItemsEvents();
7303				}
7304			};
7305
7306			if (opts.linkId) {
7307				vars.hashLock = true;
7308				window.location.hash = opts.linkId + '/' + vars.current;
7309				setTimeout(function() {
7310					vars.hashLock = false;
7311				}, 55);
7312			}
7313
7314			if (!opts.slideshow.startPaused) {
7315				iL.resume();
7316				vars.innerPlayButton.removeClass('ilightbox-play').addClass('ilightbox-pause');
7317			}
7318
7319			//Trigger the onOpen callback
7320			if (typeof iL.options.callback.onOpen == 'function') iL.options.callback.onOpen.call(iL);
7321
7322		},
7323
7324		loadContent: function(obj, opt, speed) {
7325			var iL = this,
7326				holder, item;
7327
7328			iL.createUI();
7329
7330			obj.speed = speed || iL.options.effects.loadedFadeSpeed;
7331
7332			if (opt == 'current') {
7333				if (!obj.options.mousewheel) iL.vars.lockWheel = true;
7334				else iL.vars.lockWheel = false;
7335
7336				if (!obj.options.swipe) iL.vars.lockSwipe = true;
7337				else iL.vars.lockSwipe = false;
7338			}
7339
7340			switch (opt) {
7341				case 'current':
7342					holder = iL.vars.holder, item = iL.vars.current;
7343					break;
7344				case 'next':
7345					holder = iL.vars.nextPhoto, item = iL.vars.next;
7346					break;
7347				case 'prev':
7348					holder = iL.vars.prevPhoto, item = iL.vars.prev;
7349					break;
7350			}
7351
7352			holder.removeAttr('style class').addClass('ilightbox-holder' + (supportTouch ? ' supportTouch' : '')).addClass(obj.options.skin);
7353			$('div.ilightbox-inner-toolbar', holder).remove();
7354
7355			if (obj.title || iL.options.innerToolbar) {
7356				var innerToolbar = iL.vars.innerToolbar.clone();
7357				if (obj.title && iL.options.show.title) {
7358					var title = iL.vars.title.clone();
7359					title.empty().html(obj.title);
7360					innerToolbar.append(title);
7361				}
7362				if (iL.options.innerToolbar) {
7363					innerToolbar.append((iL.vars.total > 1) ? iL.vars.toolbar.clone() : iL.vars.toolbar);
7364				}
7365				holder.prepend(innerToolbar);
7366			}
7367
7368			iL.loadSwitcher(obj, holder, item, opt);
7369		},
7370
7371		loadSwitcher: function(obj, holder, item, opt) {
7372			var iL = this,
7373				opts = iL.options,
7374				api = {
7375					element: holder,
7376					position: item
7377				};
7378
7379			switch (obj.type) {
7380				case 'image':
7381					//Trigger the onBeforeLoad callback
7382					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
7383					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
7384
7385					iL.loadImage(obj.URL, function(img) {
7386						//Trigger the onAfterLoad callback
7387						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
7388						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
7389
7390						var width = (img) ? img.width : 400,
7391							height = (img) ? img.height : 200;
7392
7393						holder.data({
7394							naturalWidth: width,
7395							naturalHeight: height
7396						});
7397						$('div.ilightbox-container', holder).empty().append((img) ? '<img src="' + obj.URL + '" class="ilightbox-image" />' : '<span class="ilightbox-alert">' + opts.errors.loadImage + '</span>');
7398
7399						//Trigger the onRender callback
7400						if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7401						if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7402
7403						iL.configureHolder(obj, opt, holder);
7404					});
7405
7406					break;
7407
7408				case 'video':
7409					holder.data({
7410						naturalWidth: obj.options.width,
7411						naturalHeight: obj.options.height
7412					});
7413
7414					iL.addContent(holder, obj);
7415
7416					//Trigger the onRender callback
7417					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7418					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7419
7420					iL.configureHolder(obj, opt, holder);
7421
7422					break;
7423
7424				case 'iframe':
7425					iL.showLoader();
7426					holder.data({
7427						naturalWidth: obj.options.width,
7428						naturalHeight: obj.options.height
7429					});
7430					var el = iL.addContent(holder, obj);
7431
7432					//Trigger the onRender callback
7433					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7434					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7435
7436					//Trigger the onBeforeLoad callback
7437					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
7438					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
7439
7440					el.bind('load', function() {
7441						//Trigger the onAfterLoad callback
7442						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
7443						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
7444
7445						iL.hideLoader();
7446						iL.configureHolder(obj, opt, holder);
7447						el.unbind('load');
7448					});
7449
7450					break;
7451
7452				case 'inline':
7453					var el = $(obj.URL),
7454						content = iL.addContent(holder, obj),
7455						images = findImageInElement(holder);
7456
7457					holder.data({
7458						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
7459						naturalHeight: (iL.items[item].options.height || el.outerHeight())
7460					});
7461					content.children().eq(0).show();
7462
7463					//Trigger the onRender callback
7464					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7465					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7466
7467					//Trigger the onBeforeLoad callback
7468					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
7469					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
7470
7471					iL.loadImage(images, function() {
7472						//Trigger the onAfterLoad callback
7473						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
7474						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
7475
7476						iL.configureHolder(obj, opt, holder);
7477					});
7478
7479					break;
7480
7481				case 'flash':
7482					var el = iL.addContent(holder, obj);
7483
7484					holder.data({
7485						naturalWidth: (iL.items[item].options.width || el.outerWidth()),
7486						naturalHeight: (iL.items[item].options.height || el.outerHeight())
7487					});
7488
7489					//Trigger the onRender callback
7490					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7491					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7492
7493					iL.configureHolder(obj, opt, holder);
7494
7495					break;
7496
7497				case 'ajax':
7498					var ajax = obj.options.ajax || {};
7499					//Trigger the onBeforeLoad callback
7500					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
7501					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
7502
7503					iL.showLoader();
7504					$.ajax({
7505						url: obj.URL || opts.ajaxSetup.url,
7506						data: ajax.data || null,
7507						dataType: ajax.dataType || "html",
7508						type: ajax.type || opts.ajaxSetup.type,
7509						cache: ajax.cache || opts.ajaxSetup.cache,
7510						crossDomain: ajax.crossDomain || opts.ajaxSetup.crossDomain,
7511						global: ajax.global || opts.ajaxSetup.global,
7512						ifModified: ajax.ifModified || opts.ajaxSetup.ifModified,
7513						username: ajax.username || opts.ajaxSetup.username,
7514						password: ajax.password || opts.ajaxSetup.password,
7515						beforeSend: ajax.beforeSend || opts.ajaxSetup.beforeSend,
7516						complete: ajax.complete || opts.ajaxSetup.complete,
7517						success: function(data, textStatus, jqXHR) {
7518							iL.hideLoader();
7519
7520							var el = $(data),
7521								container = $('div.ilightbox-container', holder),
7522								elWidth = iL.items[item].options.width || parseInt(el[0].getAttribute('width')),
7523								elHeight = iL.items[item].options.height || parseInt(el[0].getAttribute('height')),
7524								css = (el[0].getAttribute('width') && el[0].getAttribute('height')) ? {
7525									'overflow': 'hidden'
7526								} : {};
7527
7528							container.empty().append($('<div class="ilightbox-wrapper"></div>').css(css).html(el));
7529							holder.show().data({
7530								naturalWidth: (elWidth || container.outerWidth()),
7531								naturalHeight: (elHeight || container.outerHeight())
7532							}).hide();
7533
7534							//Trigger the onRender callback
7535							if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7536							if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7537
7538							var images = findImageInElement(holder);
7539							iL.loadImage(images, function() {
7540								//Trigger the onAfterLoad callback
7541								if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
7542								if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
7543
7544								iL.configureHolder(obj, opt, holder);
7545							});
7546
7547							opts.ajaxSetup.success(data, textStatus, jqXHR);
7548							if (typeof ajax.success == 'function') ajax.success(data, textStatus, jqXHR);
7549						},
7550						error: function(jqXHR, textStatus, errorThrown) {
7551							//Trigger the onAfterLoad callback
7552							if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
7553							if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
7554
7555							iL.hideLoader();
7556							$('div.ilightbox-container', holder).empty().append('<span class="ilightbox-alert">' + opts.errors.loadContents + '</span>');
7557							iL.configureHolder(obj, opt, holder);
7558
7559							opts.ajaxSetup.error(jqXHR, textStatus, errorThrown);
7560							if (typeof ajax.error == 'function') ajax.error(jqXHR, textStatus, errorThrown);
7561						}
7562					});
7563
7564					break;
7565
7566				case 'html':
7567					var object = obj.URL,
7568						el
7569					container = $('div.ilightbox-container', holder);
7570
7571					if (object[0].nodeName) el = object.clone();
7572					else {
7573						var dom = $(object);
7574						if (dom.selector) el = $('<div>' + dom + '</div>');
7575						else el = dom;
7576					}
7577
7578					var elWidth = iL.items[item].options.width || parseInt(el.attr('width')),
7579						elHeight = iL.items[item].options.height || parseInt(el.attr('height'));
7580
7581					iL.addContent(holder, obj);
7582
7583					el.appendTo(document.documentElement).hide();
7584
7585					//Trigger the onRender callback
7586					if (typeof opts.callback.onRender == 'function') opts.callback.onRender.call(iL, iL.ui, item);
7587					if (typeof obj.options.onRender == 'function') obj.options.onRender.call(iL, api);
7588
7589					var images = findImageInElement(holder);
7590
7591					//Trigger the onBeforeLoad callback
7592					if (typeof opts.callback.onBeforeLoad == 'function') opts.callback.onBeforeLoad.call(iL, iL.ui, item);
7593					if (typeof obj.options.onBeforeLoad == 'function') obj.options.onBeforeLoad.call(iL, api);
7594
7595					iL.loadImage(images, function() {
7596						//Trigger the onAfterLoad callback
7597						if (typeof opts.callback.onAfterLoad == 'function') opts.callback.onAfterLoad.call(iL, iL.ui, item);
7598						if (typeof obj.options.onAfterLoad == 'function') obj.options.onAfterLoad.call(iL, api);
7599
7600						holder.show().data({
7601							naturalWidth: (elWidth || container.outerWidth()),
7602							naturalHeight: (elHeight || container.outerHeight())
7603						}).hide();
7604						el.remove();
7605
7606						iL.configureHolder(obj, opt, holder);
7607					});
7608
7609					break;
7610			}
7611		},
7612
7613		configureHolder: function(obj, opt, holder) {
7614			var iL = this,
7615				vars = iL.vars,
7616				opts = iL.options;
7617
7618			if (opt != "current")(opt == "next") ? holder.addClass('ilightbox-next') : holder.addClass('ilightbox-prev');
7619
7620			if (opt == "current")
7621				var item = vars.current;
7622			else if (opt == "next")
7623				var opacity = opts.styles.nextOpacity,
7624					item = vars.next;
7625			else
7626				var opacity = opts.styles.prevOpacity,
7627					item = vars.prev;
7628
7629			var api = {
7630				element: holder,
7631				position: item
7632			};
7633
7634			iL.items[item].options.width = iL.items[item].options.width || 0,
7635				iL.items[item].options.height = iL.items[item].options.height || 0;
7636
7637			if (opt == "current") {
7638				if (opts.show.effect) holder.css(transform, gpuAcceleration).fadeIn(obj.speed, function() {
7639					holder.css(transform, '');
7640					if (obj.caption) {
7641						iL.setCaption(obj, holder);
7642						var caption = $('div.ilightbox-caption', holder),
7643							percent = parseInt((caption.outerHeight() / holder.outerHeight()) * 100);
7644						if (opts.caption.start & percent <= 50) caption.fadeIn(opts.effects.fade
7644Speed);
7645					}
7646
7647					var social = obj.options.social;
7648					if (social) {
7649						iL.setSocial(social, obj.URL, holder);
7650						if (opts.social.start) $('div.ilightbox-social', holder).fadeIn(opts.effects.fadeSpeed);
7651					}
7652
7653					//Generate thumbnails
7654					iL.generateThumbnails();
7655
7656					//Trigger the onShow callback
7657					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
7658					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
7659				});
7660				else {
7661					holder.show();
7662
7663					//Generate thumbnails
7664					iL.generateThumbnails();
7665
7666					//Trigger the onShow callback
7667					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
7668					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
7669				}
7670			} else {
7671				if (opts.show.effect) holder.fadeTo(obj.speed, opacity, function() {
7672					if (opt == "next") vars.nextLock = false;
7673					else vars.prevLock = false;
7674
7675					//Generate thumbnails
7676					iL.generateThumbnails();
7677
7678					//Trigger the onShow callback
7679					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
7680					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
7681				});
7682				else {
7683					holder.css({
7684						opacity: opacity
7685					}).show();
7686					if (opt == "next") vars.nextLock = false;
7687					else vars.prevLock = false;
7688
7689					//Generate thumbnails
7690					iL.generateThumbnails();
7691
7692					//Trigger the onShow callback
7693					if (typeof opts.callback.onShow == 'function') opts.callback.onShow.call(iL, iL.ui, item);
7694					if (typeof obj.options.onShow == 'function') obj.options.onShow.call(iL, api);
7695				}
7696			}
7697
7698			setTimeout(function() {
7699				iL.repositionPhoto();
7700			}, 0);
7701		},
7702
7703		generateBoxes: function() {
7704			var iL = this,
7705				vars = iL.vars,
7706				opts = iL.options;
7707
7708			if (opts.infinite && vars.total >= 3) {
7709				if (vars.current == vars.total - 1) vars.next = 0;
7710				if (vars.current == 0) vars.prev = vars.total - 1;
7711			} else opts.infinite = false;
7712
7713			iL.loadContent(iL.items[vars.current], 'current', opts.show.speed);
7714
7715			if (iL.items[vars.next]) iL.loadContent(iL.items[vars.next], 'next', opts.show.speed);
7716			if (iL.items[vars.prev]) iL.loadContent(iL.items[vars.prev], 'prev', opts.show.speed);
7717		},
7718
7719		generateThumbnails: function() {
7720			var iL = this,
7721				vars = iL.vars,
7722				opts = iL.options,
7723				timeOut = null;
7724
7725			if (vars.thumbs && !iL.vars.dontGenerateThumbs) {
7726				var thumbnails = vars.thumbnails,
7727					container = $('div.ilightbox-thumbnails-container', thumbnails),
7728					grid = $('div.ilightbox-thumbnails-grid', container),
7729					i = 0;
7730
7731				grid.removeAttr('style').empty();
7732
7733				$.each(iL.items, function(key, val) {
7734					var isActive = (vars.current == key) ? 'ilightbox-active' : '',
7735						opacity = (vars.current == key) ? opts.thumbnails.activeOpacity : opts.thumbnails.normalOpacity,
7736						thumb = val.options.thumbnail,
7737						thumbnail = $('<div class="ilightbox-thumbnail"></div>'),
7738						icon = $('<div class="ilightbox-thumbnail-icon"></div>');
7739
7740					thumbnail.css({
7741						opacity: 0
7742					}).addClass(isActive);
7743
7744					if ((val.type == "video" || val.type == "flash") && typeof val.options.icon == 'undefined') {
7745						icon.addClass('ilightbox-thumbnail-video');
7746						thumbnail.append(icon);
7747					} else if (val.options.icon) {
7748						icon.addClass('ilightbox-thumbnail-' + val.options.icon);
7749						thumbnail.append(icon);
7750					}
7751
7752					if (thumb) iL.loadImage(thumb, function(img) {
7753						i++;
7754						if (img) thumbnail.data({
7755							naturalWidth: img.width,
7756							naturalHeight: img.height
7757						}).append('<img src="' + thumb + '" border="0" />');
7758						else thumbnail.data({
7759							naturalWidth: opts.thumbnails.maxWidth,
7760							naturalHeight: opts.thumbnails.maxHeight
7761						});
7762
7763						clearTimeout(timeOut);
7764						timeOut = setTimeout(function() {
7765							iL.positionThumbnails(thumbnails, container, grid);
7766						}, 20);
7767						setTimeout(function() {
7768							thumbnail.fadeTo(opts.effects.loadedFadeSpeed, opacity);
7769						}, i * 20);
7770					});
7771
7772					grid.append(thumbnail);
7773				});
7774				iL.vars.dontGenerateThumbs = true;
7775			}
7776		},
7777
7778		positionThumbnails: function(thumbnails, container, grid) {
7779			var iL = this,
7780				vars = iL.vars,
7781				opts = iL.options,
7782				viewport = getViewport(),
7783				path = opts.path.toLowerCase();
7784
7785			if (!thumbnails) thumbnails = vars.thumbnails;
7786			if (!container) container = $('div.ilightbox-thumbnails-container', thumbnails);
7787			if (!grid) grid = $('div.ilightbox-thumbnails-grid', container);
7788
7789			var thumbs = $('.ilightbox-thumbnail', grid),
7790				widthAvail = (path == 'horizontal') ? viewport.width - opts.styles.pageOffsetX : thumbs.eq(0).outerWidth() - opts.styles.pageOffsetX,
7791				heightAvail = (path == 'horizontal') ? thumbs.eq(0).outerHeight() - opts.styles.pageOffsetY : viewport.height - opts.styles.pageOffsetY,
7792				gridWidth = (path == 'horizontal') ? 0 : widthAvail,
7793				gridHeight = (path == 'horizontal') ? heightAvail : 0,
7794				active = $('.ilightbox-active', grid),
7795				gridCss = {},
7796				css = {};
7797
7798			if (arguments.length < 3) {
7799				thumbs.css({
7800					opacity: opts.thumbnails.normalOpacity
7801				});
7802				active.css({
7803					opacity: opts.thumbnails.activeOpacity
7804				});
7805			}
7806
7807			thumbs.each(function(i) {
7808				var t = $(this),
7809					data = t.data(),
7810					width = (path == 'horizontal') ? 0 : opts.thumbnails.maxWidth;
7811				height = (path == 'horizontal') ? opts.thumbnails.maxHeight : 0;
7812				dims = iL.getNewDimenstions(width, height, data.naturalWidth, data.naturalHeight, true);
7813
7814				t.css({
7815					width: dims.width,
7816					height: dims.height
7817				});
7818				if (path == 'horizontal') t.css({
7819					'float': 'left'
7820				});
7821
7822				(path == 'horizontal') ? (
7823					gridWidth += t.outerWidth()
7824				) : (
7825					gridHeight += t.outerHeight()
7826				);
7827			});
7828
7829			gridCss = {
7830				width: gridWidth,
7831				height: gridHeight
7832			};
7833
7834			grid.css(gridCss);
7835
7836			gridCss = {};
7837
7838			var gridOffset = grid.offset(),
7839				activeOffset = (active.length) ? active.offset() : {
7840					top: parseInt(heightAvail / 2),
7841					left: parseInt(widthAvail / 2)
7842				};
7843
7844			gridOffset.top = (gridOffset.top - $doc.scrollTop()),
7845				gridOffset.left = (gridOffset.left - $doc.scrollLeft()),
7846				activeOffset.top = (activeOffset.top - gridOffset.top - $doc.scrollTop()),
7847				activeOffset.left = (activeOffset.left - gridOffset.left - $doc.scrollLeft());
7848
7849			(path == 'horizontal') ? (
7850				gridCss.top = 0,
7851				gridCss.left = parseInt((widthAvail / 2) - activeOffset.left - (active.outerWidth() / 2))
7852			) : (
7853				gridCss.top = parseInt(((heightAvail / 2) - activeOffset.top - (active.outerHeight() / 2))),
7854				gridCss.left = 0
7855			);
7856
7857			if (arguments.length < 3) grid.stop().animate(gridCss, opts.effects.repositionSpeed, 'easeOutCirc');
7858			else grid.css(gridCss);
7859		},
7860
7861		loadImage: function(image, callback) {
7862			if (!$.isArray(image)) image = [image];
7863
7864			var iL = this,
7865				length = image.length;
7866
7867			if (length > 0) {
7868				iL.showLoader();
7869				$.each(image, function(index, value) {
7870					var img = new Image();
7871					img.onload = function() {
7872						length -= 1;
7873						if (length == 0) {
7874							iL.hideLoader();
7875							callback(img);
7876						}
7877					};
7878					img.onerror = img.onabort = function() {
7879						length -= 1;
7880						if (length == 0) {
7881							iL.hideLoader();
7882							callback(false);
7883						}
7884					};
7885					img.src = image[index];
7886				});
7887			} else callback(false);
7888		},
7889
7890		patchItemsEvents: function() {
7891			var iL = this,
7892				vars = iL.vars,
7893				clickEvent = supportTouch ? "itap.iL" : "click.iL",
7894				vEvent = supportTouch ? "click.iL" : "itap.iL";
7895
7896			if (iL.context && iL.selector) {
7897				var $items = $(iL.selector, iL.context);
7898				$(iL.context).on(clickEvent, iL.selector, function() {
7899
7900					var $this = $(this),
7901						key = $items.index($this);
7902					if (UNCODE.isMobile) {
7903						var isCarousel = $this.closest('.owl-carousel');
7904						if (isCarousel.length) {
7905							if (isCarousel.hasClass('owl-translating')) return false;
7906						}
7907					}
7908
7909					vars.current = key;
7910					vars.next = iL.items[key + 1] ? key + 1 : null;
7911					vars.prev = iL.items[key - 1] ? key - 1 : null;
7912
7913					iL.addContents();
7914					iL.patchEvents();
7915
7916					return false;
7917				}).on(vEvent, iL.selector, function() {
7918					return false;
7919				});
7920			} else
7921				$.each(iL.itemsObject, function(key, val) {
7922					val.on(clickEvent, function() {
7923						vars.current = key;
7924						vars.next = iL.items[key + 1] ? key + 1 : null;
7925						vars.prev = iL.items[key - 1] ? key - 1 : null;
7926
7927						iL.addContents();
7928						iL.patchEvents();
7929
7930						return false;
7931					}).on(vEvent, function() {
7932						return false;
7933					});
7934				});
7935		},
7936
7937		dispatchItemsEvents: function() {
7938			var iL = this,
7939				vars = iL.vars,
7940				opts = iL.options;
7941
7942			if (iL.context && iL.selector)
7943				$(iL.context).off('.iL', iL.selector);
7944			else
7945				$.each(iL.itemsObject, function(key, val) {
7946					val.off('.iL');
7947				});
7948		},
7949
7950		refresh: function() {
7951			var iL = this;
7952
7953			iL.dispatchItemsEvents();
7954			iL.attachItems();
7955			iL.normalizeItems();
7956			iL.patchItemsEvents();
7957		},
7958
7959		patchEvents: function() {
7960			var iL = this,
7961				vars = iL.vars,
7962				opts = iL.options,
7963				path = opts.path.toLowerCase(),
7964				holders = $('.ilightbox-holder'),
7965				fullscreenEvent = fullScreenApi.fullScreenEventName + '.iLightBox',
7966				durationThreshold = 1000,
7967				horizontalDistanceThreshold =
7968				verticalDistanceThreshold = 100,
7969				buttonsArray = [vars.nextButton[0], vars.prevButton[0], vars.nextButton[0].firstChild, vars.prevButton[0].firstChild];
7970
7971			$win.bind('resize.iLightBox', function() {
7972				var viewport = getViewport();
7973
7974				if (opts.mobileOptimizer && !opts.innerToolbar) vars.isMobile = viewport.width <= vars.mobileMaxWidth;
7975				vars.BODY[vars.isMobile ? 'addClass' : 'removeClass']('isMobile');
7976
7977				iL.repositionPhoto(null);
7978				if (supportTouch) {
7979					clearTimeout(vars.setTime);
7980					vars.setTime = setTimeout(function() {
7981						var scrollTop = getScrollXY().y;
7982						window.scrollTo(0, scrollTop - 30);
7983						window.scrollTo(0, scrollTop + 30);
7984						window.scrollTo(0, scrollTop);
7985					}, 2000);
7986				}
7987				if (vars.thumbs) iL.positionThumbnails();
7988			}).bind('keydown.iLightBox', function(event) {
7989				if (opts.controls.keyboard) {
7990					switch (event.keyCode) {
7991						case 13:
7992							if (event.shiftKey && opts.keyboard.shift_enter) iL.fullScreenAction();
7993							break;
7994						case 27:
7995							if (opts.keyboard.esc) iL.closeAction();
7996							break;
7997						case 37:
7998							if (opts.keyboard.left && !vars.lockKey) iL.moveTo('prev');
7999							break;
8000						case 38:
8001							if (opts.keyboard.up && !vars.lockKey) iL.moveTo('prev');
8002							break;
8003						case 39:
8004							if (opts.keyboard.right && !vars.lockKey) iL.moveTo('next');
8005							break;
8006						case 40:
8007							if (opts.keyboard.down && !vars.lockKey) iL.moveTo('next');
8008							break;
8009					}
8010				}
8011			});
8012
8013			if (fullScreenApi.supportsFullScreen) $win.bind(fullscreenEvent, function() {
8014				iL.doFullscreen();
8015			});
8016
8017			var holderEventsArr = [opts.caption.show + '.iLightBox', opts.caption.hide + '.iLightBox', opts.social.show + '.iLightBox', opts.social.hide + '.iLightBox'].filter(function(e, i, arr) {
8018					return arr.lastIndexOf(e) === i;
8019				}),
8020				holderEvents = "";
8021
8022			$.each(holderEventsArr, function(key, val) {
8023				if (key != 0) holderEvents += ' ';
8024				holderEvents += val;
8025			});
8026
8027			$doc.on(clickEvent, '.ilightbox-overlay', function() {
8028				if (opts.overlay.blur) iL.closeAction();
8029			}).on(clickEvent, '.ilightbox-next, .ilightbox-next-button', function() {
8030				iL.moveTo('next');
8031			}).on(clickEvent, '.ilightbox-prev, .ilightbox-prev-button', function() {
8032				iL.moveTo('prev');
8033			}).on(clickEvent, '.ilightbox-thumbnail', function() {
8034				var t = $(this),
8035					thumbs = $('.ilightbox-thumbnail', vars.thumbnails),
8036					index = thumbs.index(t);
8037
8038				if (index != vars.current) iL.goTo(index);
8039			}).on(holderEvents, '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
8040				var caption = $('div.ilightbox-caption', vars.holder),
8041					social = $('div.ilightbox-social', vars.holder),
8042					fadeSpeed = opts.effects.fadeSpeed;
8043
8044				if (vars.nextLock || vars.prevLock) {
8045					if (e.type == opts.caption.show && !caption.is(':visible')) caption.fadeIn(fadeSpeed);
8046					else if (e.type == opts.caption.hide && caption.is(':visible')) caption.fadeOut(fadeSpeed);
8047
8048					if (e.type == opts.social.show && !social.is(':visible')) social.fadeIn(fadeSpeed);
8049					else if (e.type == opts.social.hide && social.is(':visible')) social.fadeOut(fadeSpeed);
8050				} else {
8051					if (e.type == opts.caption.show && !caption.is(':visible')) caption.stop().fadeIn(fadeSpeed);
8052					else if (e.type == opts.caption.hide && caption.is(':visible')) caption.stop().fadeOut(fadeSpeed);
8053
8054					if (e.type == opts.social.show && !social.is(':visible')) social.stop().fadeIn(fadeSpeed);
8055					else if (e.type == opts.social.hide && social.is(':visible')) social.stop().fadeOut(fadeSpeed);
8056				}
8057			}).on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-wrapper', function(e) {
8058				if (e.type == 'mouseenter') vars.lockWheel = true;
8059				else vars.lockWheel = false;
8060			}).on(clickEvent, '.ilightbox-toolbar a.ilightbox-close, .ilightbox-toolbar a.ilightbox-fullscreen, .ilightbox-toolbar a.ilightbox-play, .ilightbox-toolbar a.ilightbox-pause', function() {
8061				var t = $(this);
8062
8063				if (t.hasClass('ilightbox-fullscreen')) iL.fullScreenAction();
8064				else if (t.hasClass('ilightbox-play')) {
8065					iL.resume();
8066					t.addClass('ilightbox-pause').removeClass('ilightbox-play');
8067				} else if (t.hasClass('ilightbox-pause')) {
8068					iL.pause();
8069					t.addClass('ilightbox-play').removeClass('ilightbox-pause');
8070				} else iL.closeAction();
8071			}).on(touchMoveEvent, '.ilightbox-overlay, .ilightbox-thumbnails-container', function(e) {
8072				// prevent scrolling
8073				e.preventDefault();
8074			});
8075
8076			function mouseMoveHandler(e) {
8077				if (!vars.isMobile) {
8078					if (!vars.mouseID) {
8079						vars.hideableElements.show();
8080					}
8081
8082					vars.mouseID = clearTimeout(vars.mouseID);
8083
8084					if (buttonsArray.indexOf(e.target) === -1)
8085						vars.mouseID = setTimeout(function() {
8086							vars.hideableElements.hide();
8087							vars.mouseID = clearTimeout(vars.mouseID);
8088						}, 3000);
8089				}
8090			}
8091
8092			if (opts.controls.arrows && !supportTouch) $doc.on('mousemove.iLightBox', mouseMoveHandler);
8093
8094			if (opts.controls.slideshow && opts.slideshow.pauseOnHover) $doc.on('mouseenter.iLightBox mouseleave.iLightBox', '.ilightbox-holder:not(.ilightbox-next, .ilightbox-prev)', function(e) {
8095				if (e.type == 'mouseenter' && vars.cycleID) iL.pause();
8096				else if (e.type == 'mouseleave' && vars.isPaused) iL.resume();
8097			});
8098
8099			var switchers = $('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails');
8100
8101			if (opts.controls.mousewheel) switchers.on('mousewheel.iLightBox', function(event, delta) {
8102				if (!vars.lockWheel) {
8103					event.preventDefault();
8104					if (delta < 0) iL.moveTo('next');
8105					else if (delta > 0) iL.moveTo('prev');
8106				}
8107			});
8108
8109			if (opts.controls.swipe) holders.on(touchStartEvent, function(event) {
8110				if (vars.nextLock || vars.prevLock || vars.total == 1 || vars.lockSwipe) return;
8111
8112				vars.BODY.addClass('ilightbox-closedhand');
8113
8114				var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event,
8115					scrollTop = $doc.scrollTop(),
8116					scrollLeft = $doc.scrollLeft(),
8117					offsets = [
8118						holders.eq(0).offset(),
8119						holders.eq(1).offset(),
8120						holders.eq(2).offset()
8121					],
8122					offSet = [{
8123						top: offsets[0].top - scrollTop,
8124						left: offsets[0].left - scrollLeft
8125					}, {
8126						top: offsets[1].top - scrollTop,
8127						left: offsets[1].left - scrollLeft
8128					}, {
8129						top: offsets[2].top - scrollTop,
8130						left: offsets[2].left - scrollLeft
8131					}],
8132					start = {
8133						time: (new Date()).getTime(),
8134						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
8135					},
8136					stop;
8137
8138				function moveEachHandler(i) {
8139					var t = $(this),
8140						offset = offSet[i],
8141						scroll = [(start.coords[0] - stop.coords[0]), (start.coords[1] - stop.coords[1])];
8142
8143					t[0].style[path == "horizontal" ? 'left' : 'top'] = (path == "horizontal" ? offset.left - scroll[0] : offset.top - scroll[1]) + 'px';
8144				}
8145
8146				function moveHandler(event) {
8147
8148					if (!start) return;
8149
8150					var data = event.originalEvent.touches ? event.originalEvent.touches[0] : event;
8151
8152					stop = {
8153						time: (new Date()).getTime(),
8154						coords: [data.pageX - scrollLeft, data.pageY - scrollTop]
8155					};
8156
8157					holders.each(moveEachHandler);
8158
8159					// prevent scrolling
8160					event.preventDefault();
8161				}
8162
8163				function repositionHolders() {
8164					holders.each(function() {
8165						var t = $(this),
8166							offset = t.data('offset') || {
8167								top: t.offset().top - scrollTop,
8168								left: t.offset().left - scrollLeft
8169							},
8170							top = offset.top,
8171							left = offset.left;
8172
8173						t.css(transform, gpuAcceleration).stop().animate({
8174							top: top,
8175							left: left
8176						}, 500, 'easeOutCirc', function() {
8177							t.css(transform, '');
8178						});
8179					});
8180				}
8181
8182				holders.bind(touchMoveEvent, moveHandler);
8183				$doc.one(touchStopEvent, function(event) {
8184					holders.unbind(touchMoveEvent, moveHandler);
8185
8186					vars.BODY.removeClass('ilightbox-closedhand');
8187
8188					if (start && stop) {
8189						if (path == "horizontal" && stop.time - start.time < durationThreshold && abs(start.coords[0] - stop.coords[0]) > horizontalDistanceThreshold && abs(start.coords[1] - stop.coords[1]) < verticalDistanceThreshold) {
8190							if (start.coords[0] > stop.coords[0]) {
8191								if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders();
8192								else {
8193									vars.isSwipe = true;
8194									iL.moveTo('next');
8195								}
8196							} else {
8197								if (vars.current == 0 && !opts.infinite) repositionHolders();
8198								else {
8199									vars.isSwipe = true;
8200									iL.moveTo('prev');
8201								}
8202							}
8203						} else if (path == "vertical" && stop.time - start.time < durationThreshold && abs(start.coords[1] - stop.coords[1]) > horizontalDistanceThreshold && abs(start.coords[0] - stop.coords[0]) < verticalDistanceThreshold) {
8204							if (start.coords[1] > stop.coords[1]) {
8205								if (vars.current == vars.total - 1 && !opts.infinite) repositionHolders();
8206								else {
8207									vars.isSwipe = true;
8208									iL.moveTo('next');
8209								}
8210							} else {
8211								if (vars.current == 0 && !opts.infinite) repositionHolders();
8212								else {
8213									vars.isSwipe = true;
8214									iL.moveTo('prev');
8215								}
8216							}
8217						} else repositionHolders();
8218					}
8219					start = stop = undefined;
8220				});
8221			});
8222
8223		},
8224
8225		goTo: function(index) {
8226			var iL = this,
8227				vars = iL.vars,
8228				opts = iL.options,
8229				diff = (index - vars.current);
8230
8231			if (opts.infinite) {
8232				if (index == vars.total - 1 && vars.current == 0) diff = -1;
8233				if (vars.current == vars.total - 1 && index == 0) diff = 1;
8234			}
8235
8236			if (diff == 1) iL.moveTo('next');
8237			else if (diff == -1) iL.moveTo('prev');
8238			else {
8239
8240				if (vars.nextLock || vars.prevLock) return false;
8241
8242				//Trigger the onBeforeChange callback
8243				if (typeof opts.callback.onBeforeChange == 'function') opts.callback.onBeforeChange.call(iL, iL.ui);
8244
8245				if (opts.linkId) {
8246					vars.hashLock = true;
8247					window.location.hash = opts.linkId + '/' + index;
8248				}
8249
8250				if (iL.items[index]) {
8251					if (!iL.items[index].options.mousewheel) vars.lockWheel = true;
8252					else iL.vars.lockWheel = false;
8253
8254					if (!iL.items[index].options.swipe) vars.lockSwipe = true;
8255					else vars.lockSwipe = false;
8256				}
8257
8258				$.each([vars.holder, vars.nextPhoto, vars.prevPhoto], function(key, val) {
8259					val.css(transform, gpuAcceleration).fadeOut(opts.effects.loadedFadeSpeed);
8260				});
8261
8262				vars.current = index;
8263				vars.next = index + 1;
8264				vars.prev = index - 1;
8265
8266				iL.createUI();
8267
8268				setTimeout(function() {
8269					iL.generateBoxes();
8270				}, opts.effects.loadedFadeSpeed + 50);
8271
8272				$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(index).addClass('ilightbox-active');
8273				iL.positionThumbnails();
8274
8275				if (opts.linkId) setTimeout(function() {
8276					vars.hashLock = false;
8277				}, 55);
8278
8279				// Configure arrow buttons
8280				if (!opts.infinite) {
8281					vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
8282
8283					if (vars.current == 0) {
8284						vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
8285					}
8286					if (vars.current >= vars.total - 1) {
8287						vars.nextButton.add(vars.innerNextButton).addClass('disabled');
8288					}
8289				}
8290
8291				// Reset next cycle timeout
8292				iL.resetCycle();
8293
8294				//Trigger the onAfterChange callback
8295				if (typeof opts.callback.onAfterChange == 'function') opts.callback.onAfterChange.call(iL, iL.ui);
8296			}
8297		},
8298
8299		moveTo: function(side) {
8300			var iL = this,
8301				vars = iL.vars,
8302				opts = iL.options,
8303				path = opts.path.toLowerCase(),
8304				viewport = getViewport(),
8305				switchSpeed = opts.effects.switchSpeed;
8306
8307			if (vars.nextLock || vars.prevLock) return false;
8308			else {
8309
8310				var item = (side == "next") ? vars.next : vars.prev;
8311
8312				if (opts.linkId) {
8313					vars.hashLock = true;
8314					window.location.hash = opts.linkId + '/' + item;
8315				}
8316
8317				if (side == "next") {
8318					if (!iL.items[item]) return false;
8319					var firstHolder = vars.nextPhoto,
8320						secondHolder = vars.holder,
8321						lastHolder = vars.prevPhoto,
8322						firstClass = 'ilightbox-prev',
8323						secondClass = 'ilightbox-next';
8324				} else if (side == "prev") {
8325					if (!iL.items[item]) return false;
8326					var firstHolder = vars.prevPhoto,
8327						secondHolder = vars.holder,
8328						lastHolder = vars.nextPhoto,
8329						firstClass = 'ilightbox-next',
8330						secondClass = 'ilightbox-prev';
8331				}
8332
8333				//Trigger the onBeforeChange callback
8334				if (typeof opts.callback.onBeforeChange == 'function')
8335					opts.callback.onBeforeChange.call(iL, iL.ui);
8336
8337				(side == "next") ? vars.nextLock = true: vars.prevLock = true;
8338
8339				var captionFirst = $('div.ilightbox-caption', secondHolder),
8340					socialFirst = $('div.ilightbox-social', secondHolder);
8341
8342				if (captionFirst.length)
8343					captionFirst.stop().fadeOut(switchSpeed, function() {
8344						$(this).remove();
8345					});
8346				if (socialFirst.length)
8347					socialFirst.stop().fadeOut(switchSpeed, function() {
8348						$(this).remove();
8349					});
8350
8351				if (iL.items[item].caption) {
8352					iL.setCaption(iL.items[item], firstHolder);
8353					var caption = $('div.ilightbox-caption', firstHolder),
8354						percent = parseInt((caption.outerHeight() / firstHolder.outerHeight()) * 100);
8355					if (opts.caption.start && percent <= 50) caption.fadeIn(switchSpeed);
8356				}
8357
8358				var social = iL.items[item].options.social;
8359				if (social) {
8360					iL.setSocial(social, iL.items[item].URL, firstHolder);
8361					if (opts.social.start) $('div.ilightbox-social', firstHolder).fadeIn(opts.effects.fadeSpeed);
8362				}
8363
8364				$.each([firstHolder, secondHolder, lastHolder], function(key, val) {
8365					val.removeClass('ilightbox-next ilightbox-prev');
8366				});
8367
8368				var firstOffset = firstHolder.data('offset'),
8369					winW = (viewport.width - (opts.styles.pageOffsetX)),
8370					winH = (viewport.height - (opts.styles.pageOffsetY)),
8371					width = firstOffset.newDims.width,
8372					height = firstOffset.newDims.height,
8373					thumbsOffset = firstOffset.thumbsOffset,
8374					diff = firstOffset.diff,
8375					top = parseInt((winH / 2) - (height / 2) - diff.H - (thumbsOffset.H / 2)),
8376					left = parseInt((winW / 2) - (width / 2) - diff.W - (thumbsOffset.W / 2));
8377
8378				firstHolder.css(transform, gpuAcceleration).animate({
8379					top: top,
8380					left: left,
8381					opacity: 1
8382				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
8383					firstHolder.css(transform, '');
8384				});
8385
8386				$('div.ilightbox-container', firstHolder).animate({
8387					width: width,
8388					height: height
8389				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');
8390
8391				var secondOffset = secondHolder.data('offset'),
8392					object = secondOffset.object;
8393
8394				diff = secondOffset.diff;
8395
8396				width = secondOffset.newDims.width,
8397					height = secondOffset.newDims.height;
8398
8399				width = parseInt(width * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
8400					height = parseInt(height * opts.styles[side == 'next' ? 'prevScale' : 'nextScale']),
8401					top = (path == 'horizontal') ? parseInt((winH / 2) - object.offsetY - (height / 2) - diff.H - (thumbsOffset.H / 2)) : parseInt(winH - object.offsetX - diff.H - (thumbsOffset.H / 2));
8402
8403				if (side == 'prev')
8404					left = (path == 'horizontal') ? parseInt(winW - object.offsetX - diff.W - (thumbsOffset.W / 2)) : parseInt((winW / 2) - (width / 2) - diff.W - object.offsetY - (thumbsOffset.W / 2));
8405				else {
8406					top = (path == 'horizontal') ? top : parseInt(object.offsetX - diff.H - height - (thumbsOffset.H / 2)),
8407						left = (path == 'horizontal') ? parseInt(object.offsetX - diff.W - width - (thumbsOffset.W / 2)) : parseInt((winW / 2) - object.offsetY - (width / 2) - diff.W - (thumbsOffset.W / 2));
8408				}
8409
8410				$('div.ilightbox-container', secondHolder).animate({
8411					width: width,
8412					height: height
8413				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc');
8414
8415				secondHolder.addClass(firstClass).css(transform, gpuAcceleration).animate({
8416					top: top,
8417					left: left,
8418					opacity: opts.styles.prevOpacity
8419				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
8420					secondHolder.css(transform, '');
8421
8422					$('.ilightbox-thumbnail', vars.thumbnails).removeClass('ilightbox-active').eq(item).addClass('ilightbox-active');
8423					iL.positionThumbnails();
8424
8425					if (iL.items[item]) {
8426						if (!iL.items[item].options.mousewheel) vars.lockWheel = true;
8427						else vars.lockWheel = false;
8428
8429						if (!iL.items[item].options.swipe) vars.lockSwipe = true;
8430						else vars.lockSwipe = false;
8431					}
8432
8433					vars.isSwipe = false;
8434
8435					if (side == "next") {
8436						vars.nextPhoto = lastHolder,
8437							vars.prevPhoto = secondHolder,
8438							vars.holder = firstHolder;
8439
8440						vars.nextPhoto.hide();
8441
8442						vars.next = vars.next + 1,
8443							vars.prev = vars.current,
8444							vars.current = vars.current + 1;
8445
8446						if (opts.infinite) {
8447							if (vars.current > vars.total - 1) vars.current = 0;
8448							if (vars.current == vars.total - 1) vars.next = 0;
8449							if (vars.current == 0) vars.prev = vars.total - 1;
8450						}
8451
8452						iL.createUI();
8453
8454						if (!iL.items[vars.next])
8455							vars.nextLock = false;
8456						else
8457							iL.loadContent(iL.items[vars.next], 'next');
8458					} else {
8459						vars.prevPhoto = lastHolder;
8460						vars.nextPhoto = secondHolder;
8461						vars.holder = firstHolder;
8462
8463						vars.prevPhoto.hide();
8464
8465						vars.next = vars.current;
8466						vars.current = vars.prev;
8467						vars.prev = vars.current - 1;
8468
8469						if (opts.infinite) {
8470							if (vars.current == vars.total - 1) vars.next = 0;
8471							if (vars.current == 0) vars.prev = vars.total - 1;
8472						}
8473
8474						iL.createUI();
8475
8476						if (!iL.items[vars.prev])
8477							vars.prevLock = false;
8478						else
8479							iL.loadContent(iL.items[vars.prev], 'prev');
8480					}
8481
8482					if (opts.linkId) setTimeout(function() {
8483						vars.hashLock = false;
8484					}, 55);
8485
8486					// Configure arrow buttons
8487					if (!opts.infinite) {
8488						vars.nextButton.add(vars.prevButton).add(vars.innerPrevButton).add(vars.innerNextButton).removeClass('disabled');
8489
8490						if (vars.current == 0)
8491							vars.prevButton.add(vars.innerPrevButton).addClass('disabled');
8492						if (vars.current >= vars.total - 1)
8493							vars.nextButton.add(vars.innerNextButton).addClass('disabled');
8494					}
8495
8496					iL.repositionPhoto();
8497
8498					// Reset next cycle timeout
8499					iL.resetCycle();
8500
8501					//Trigger the onAfterChange callback
8502					if (typeof opts.callback.onAfterChange == 'function')
8503						opts.callback.onAfterChange.call(iL, iL.ui);
8504				});
8505
8506				top = (path == 'horizontal') ? getPixel(lastHolder, 'top') : ((side == "next") ? parseInt(-(winH / 2) - lastHolder.outerHeight()) : parseInt(top * 2)),
8507					left = (path == 'horizontal') ? ((side == "next") ? parseInt(-(winW / 2) - lastHolder.outerWidth()) : parseInt(left * 2)) : getPixel(lastHolder, 'left');
8508
8509				lastHolder.css(transform, gpuAcceleration).animate({
8510					top: top,
8511					left: left,
8512					opacity: opts.styles.nextOpacity
8513				}, switchSpeed, (vars.isSwipe) ? 'easeOutCirc' : 'easeInOutCirc', function() {
8514					lastHolder.css(transform, '');
8515				}).addClass(secondClass);
8516
8517			}
8518		},
8519
8520		setCaption: function(obj, target) {
8521			var iL = this,
8522				caption = $('<div class="ilightbox-caption"></div>');
8523
8524			if (obj.caption) {
8525				caption.html(obj.caption);
8526				$('div.ilightbox-container', target).append(caption);
8527			}
8528		},
8529
8530		normalizeSocial: function(obj, url) {
8531			var iL = this,
8532				vars = iL.vars,
8533				opts = iL.options,
8534				baseURL = window.location.href;
8535
8536			$.each(obj, function(key, value) {
8537				if (!value)
8538					return true;
8539
8540				var item = key.toLowerCase(),
8541					source, text;
8542
8543				switch (item) {
8544					case 'facebook':
8545						source = "http://www.facebook.com/share.php?v=4&src=bm&u={URL}",
8546							text = "Share on Facebook";
8547						break;
8548					case 'twitter':
8549						source = "http://twitter.com/home?status={URL}",
8550							text = "Share on Twitter";
8551						break;
8552					case 'googleplus':
8553						source = "https://plus.google.com/share?url={URL}",
8554							text = "Share on Google+";
8555						break;
8556					case 'delicious':
8557						source = "http://delicious.com/post?url={URL}",
8558							text = "Share on Delicious";
8559						break;
8560					case 'digg':
8561						source = "http://digg.com/submit?phase=2&url={URL}",
8562							text = "Share on Digg";
8563						break;
8564					case 'reddit':
8565						source = "http://reddit.com/submit?url={URL}",
8566							text = "Share on reddit";
8567						break;
8568				}
8569
8570				obj[key] = {
8571					URL: value.URL && absolutizeURI(baseURL, value.URL) || opts.linkId && window.location.href || typeof url !== 'string' && baseURL || url && absolutizeURI(baseURL, url) || baseURL,
8572					source: value.source || source || value.URL && absolutizeURI(baseURL, value.URL) || url && absolutizeURI(baseURL, url),
8573					text: value.text || text || "Share on " + key,
8574					width: (typeof(value.width) != 'undefined' && !isNaN(value.width)) ? parseInt(value.width) : 640,
8575					height: value.height || 360
8576				};
8577
8578			});
8579
8580			return obj;
8581		},
8582
8583		setSocial: function(obj, url, target) {
8584			var iL = this,
8585				socialBar = $('<div class="ilightbox-social"></div>'),
8586				buttons = '<ul>';
8587
8588			obj = iL.normalizeSocial(obj, url);
8589
8590			$.each(obj, function(key, value) {
8591				var item = key.toLowerCase(),
8592					source = value.source.replace(/\{URL\}/g, encodeURIComponent(value.URL).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A').replace(/%20/g, '+'));
8593				buttons += '<li class="' + key + '"><a href="' + source + '" onclick="javascript:window.open(this.href' + ((value.width <= 0 || value.height <= 0) ? '' : ', \'\', \'menubar=no,toolbar=no,resizable=yes,scrollbars=yes,height=' + value.height + ',width=' + value.width + ',left=40,top=40\'') + ');return false;" title="' + value.text + '" target="_blank"></a></li>';
8594			});
8595
8596			buttons += '</ul>';
8597
8598			socialBar.html(buttons);
8599			$('div.ilightbox-container', target).append(socialBar);
8600		},
8601
8602		fullScreenAction: function() {
8603			var iL = this,
8604				vars = iL.vars;
8605
8606			if (fullScreenApi.supportsFullScreen) {
8607				if (fullScreenApi.isFullScreen()) fullScreenApi.cancelFullScreen(document.documentElement);
8608				else fullScreenApi.requestFullScreen(document.documentElement);
8609			} else {
8610				iL.doFullscreen();
8611			}
8612		},
8613
8614		doFullscreen: function() {
8615			var iL = this,
8616				vars = iL.vars,
8617				viewport = getViewport(),
8618				opts = iL.options;
8619
8620			if (opts.fullAlone) {
8621				var currentHolder = vars.holder,
8622					current = iL.items[vars.current],
8623					windowWidth = viewport.width,
8624					windowHeight = viewport.height,
8625					elements = [currentHolder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.overlay, vars.toolbar, vars.thumbnails, vars.loader],
8626					hideElements = [vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
8627
8628				if (!vars.isInFullScreen) {
8629					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = true;
8630					vars.overlay.css({
8631						opacity: 1
8632					});
8633
8634					$.each(hideElements, function(i, element) {
8635						element.hide();
8636					});
8637
8638					vars.fullScreenButton.attr('title', opts.text.exitFullscreen);
8639
8640					if (opts.fullStretchTypes.indexOf(current.type) != -1) currentHolder.data({
8641						naturalWidthOld: currentHolder.data('naturalWidth'),
8642						naturalHeightOld: currentHolder.data('naturalHeight'),
8643						naturalWidth: windowWidth,
8644						naturalHeight: windowHeight
8645					});
8646					else {
8647						var viewport = current.options.fullViewPort || opts.fullViewPort || '',
8648							newWidth = windowWidth,
8649							newHeight = windowHeight,
8650							width = currentHolder.data('naturalWidth'),
8651							height = currentHolder.data('naturalHeight');
8652
8653						if (viewport.toLowerCase() == 'fill') {
8654							newHeight = (newWidth / width) * height;
8655
8656							if (newHeight < windowHeight) {
8657								newWidth = (windowHeight / height) * width,
8658									newHeight = windowHeight;
8659							}
8660						} else if (viewport.toLowerCase() == 'fit') {
8661							var dims = iL.getNewDimenstions(newWidth, newHeight, width, height, true);
8662
8663							newWidth = dims.width,
8664								newHeight = dims.height;
8665						} else if (viewport.toLowerCase() == 'stretch') {
8666							newWidth = newWidth,
8667								newHeight = newHeight;
8668						} else {
8669							var scale = (width > newWidth || height > newHeight) ? true : false,
8670								dims = iL.getNewDimenstions(newWidth, newHeight, width, height, scale);
8671							newWidth = dims.width,
8672								newHeight = dims.height;
8673						}
8674
8675						currentHolder.data({
8676							naturalWidthOld: currentHolder.data('naturalWidth'),
8677							naturalHeightOld: currentHolder.data('naturalHeight'),
8678							naturalWidth: newWidth,
8679							naturalHeight: newHeight
8680						});
8681					}
8682
8683					$.each(elements, function(key, val) {
8684						val.addClass('ilightbox-fullscreen');
8685					});
8686
8687					//Trigger the onEnterFullScreen callback
8688					if (typeof opts.callback.onEnterFullScreen == 'function') opts.callback.onEnterFullScreen.call(iL, iL.ui);
8689				} else {
8690					vars.isInFullScreen = vars.lockKey = vars.lockWheel = vars.lockSwipe = false;
8691					vars.overlay.css({
8692						opacity: iL.options.overlay.opacity
8693					});
8694
8695					$.each(hideElements, function(i, element) {
8696						element.show();
8697					});
8698
8699					vars.fullScreenButton.attr('title', opts.text.enterFullscreen);
8700
8701					currentHolder.data({
8702						naturalWidth: currentHolder.data('naturalWidthOld'),
8703						naturalHeight: currentHolder.data('naturalHeightOld'),
8704						naturalWidthOld: null,
8705						naturalHeightOld: null
8706					});
8707
8708					$.each(elements, function(key, val) {
8709						val.removeClass('ilightbox-fullscreen');
8710					});
8711
8712					//Trigger the onExitFullScreen callback
8713					if (typeof opts.callback.onExitFullScreen == 'function') opts.callback.onExitFullScreen.call(iL, iL.ui);
8714				}
8715			} else {
8716				if (!vars.isInFullScreen) vars.isInFullScreen = true;
8717				else vars.isInFullScreen = false;
8718			}
8719			iL.repositionPhoto(true);
8720		},
8721
8722		closeAction: function() {
8723			var iL = this,
8724				vars = iL.vars,
8725				opts = iL.options;
8726
8727			$win.unbind('.iLightBox');
8728			$doc.off('.iLightBox');
8729
8730			if (vars.isInFullScreen) fullScreenApi.cancelFullScreen(document.documentElement);
8731
8732			$('.ilightbox-overlay, .ilightbox-holder, .ilightbox-thumbnails').off('.iLightBox');
8733
8734			if (opts.hide.effect) vars.overlay.stop().fadeOut(opts.hide.speed, function() {
8735				vars.overlay.remove();
8736				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
8737			});
8738			else {
8739				vars.overlay.remove();
8740				vars.BODY.removeClass('ilightbox-noscroll').off('.iLightBox');
8741			}
8742
8743			var fadeOuts = [vars.toolbar, vars.holder, vars.nextPhoto, vars.prevPhoto, vars.nextButton, vars.prevButton, vars.loader, vars.thumbnails];
8744
8745			$.each(fadeOuts, function(i, element) {
8746				element.removeAttr('style').remove();
8747			});
8748
8749			vars.dontGenerateThumbs = vars.isInFullScreen = false;
8750
8751			window.iLightBox = null;
8752
8753			if (opts.linkId) {
8754				vars.hashLock = true;
8755				removeHash();
8756				setTimeout(function() {
8757					vars.hashLock = false;
8758				}, 55);
8759			}
8760
8761			//Trigger the onHide callback
8762			if (typeof opts.callback.onHide == 'function') opts.callback.onHide.call(iL, iL.ui);
8763		},
8764
8765		repositionPhoto: function() {
8766			var iL = this,
8767				vars = iL.vars,
8768				opts = iL.options,
8769				path = opts.path.toLowerCase(),
8770				viewport = getViewport(),
8771				winWidth = viewport.width,
8772				winHeight = viewport.height;
8773
8774			if (viewport.width < UNCODE.mediaQuery) opts.styles.nextOffsetX = 0;
8775
8776			var thumbsOffsetW = (vars.isInFullScreen && opts.fullAlone || vars.isMobile) ? 0 : ((path == 'horizontal') ? 0 : vars.thumbnails.outerWidth()),
8777				thumbsOffsetH = vars.isMobile ? vars.toolbar.outerHeight() : ((vars.isInFullScreen && opts.fullAlone) ? 0 : ((path == 'horizontal') ? vars.thumbnails.outerHeight() : 0)),
8778				width = (vars.isInFullScreen && opts.fullAlone) ? winWidth : (winWidth - (opts.styles.pageOffsetX)),
8779				height = (vars.isInFullScreen && opts.fullAlone) ? winHeight : (winHeight - (opts.styles.pageOffsetY)),
8780				offsetW = (path == 'horizontal') ? parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((width / 10) <= 30) ? 30 : (width / 10))) : parseInt(((width / 10) <= 30) ? 30 : (width / 10)) + thumbsOffsetW,
8781				offsetH = (path == 'horizontal') ? parseInt(((height / 10) <= 30) ? 30 : (height / 10)) + thumbsOffsetH : parseInt((iL.items[vars.next] || iL.items[vars.prev]) ? ((opts.styles.nextOffsetX + opts.styles.prevOffsetX)) * 2 : (((height / 10) <= 30) ? 30 : (height / 10)));
8782
8783			var elObject = {
8784				type: 'current',
8785				width: width,
8786				height: height,
8787				item: iL.items[vars.current],
8788				offsetW: offsetW,
8789				offsetH: offsetH,
8790				thumbsOffsetW: thumbsOffsetW,
8791				thumbsOffsetH: thumbsOffsetH,
8792				animate: arguments.length,
8793				holder: vars.holder
8794			};
8795
8796			iL.repositionEl(elObject);
8797			if (iL.items[vars.next]) {
8798				elObject = $.extend(elObject, {
8799					type: 'next',
8800					item: iL.items[vars.next],
8801					offsetX: (viewport.width > UNCODE.mediaQuery) ? opts.styles.nextOffsetX : 0,
8802					offsetY: opts.styles.nextOffsetY,
8803					holder: vars.nextPhoto
8804				});
8805
8806				iL.repositionEl(elObject);
8807			}
8808
8809			if (iL.items[vars.prev]) {
8810				elObject = $.extend(elObject, {
8811					type: 'prev',
8812					item: iL.items[vars.prev],
8813					offsetX: (viewport.width > UNCODE.mediaQuery) ? opts.styles.prevOffsetX : 0,
8814					offsetY: opts.styles.prevOffsetY,
8815					holder: vars.prevPhoto
8816				});
8817
8818				iL.repositionEl(elObject);
8819			}
8820
8821			var loaderCss = (path == "horizontal") ? {
8822				left: parseInt((width / 2) - (vars.loader.outerWidth() / 2))
8823			} : {
8824				top: parseInt((height / 2) - (vars.loader.outerHeight() / 2))
8825			};
8826			vars.loader.css(loaderCss);
8827		},
8828
8829		repositionEl: function(obj) {
8830			var iL = this,
8831				vars = iL.vars,
8832				opts = iL.options,
8833				path = opts.path.toLowerCase(),
8834				widthAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.width : (obj.width - obj.offsetW)) : (obj.width - obj.offsetW),
8835				heightAvail = (obj.type == 'current') ? ((vars.isInFullScreen && opts.fullAlone) ? obj.height : (obj.height - obj.offsetH)) : (obj.height - obj.offsetH),
8836				itemParent = obj.item,
8837				item = obj.item.options,
8838				holder = obj.holder,
8839				offsetX = obj.offsetX || 0,
8840				offsetY = obj.offsetY || 0,
8841				thumbsOffsetW = obj.thumbsOffsetW,
8842				thumbsOffsetH = obj.thumbsOffsetH;
8843
8844			if (obj.type == 'current') {
8845				if (typeof item.width == 'number' && item.width) widthAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? widthAvail : ((item.width > widthAvail) ? widthAvail : item.width);
8846				if (typeof item.height == 'number' && item.height) heightAvail = ((vars.isInFullScreen && opts.fullAlone) && (opts.fullStretchTypes.indexOf(itemParent.type) != -1 || item.fullViewPort || opts.fullViewPort)) ? heightAvail : ((item.height > heightAvail) ? heightAvail : item.height);
8847			} else {
8848				if (typeof item.width == 'number' && item.width) widthAvail = (item.width > widthAvail) ? widthAvail : item.width;
8849				if (typeof item.height == 'number' && item.height) heightAvail = (item.height > heightAvail) ? heightAvail : item.height;
8850			}
8851
8852			heightAvail = parseInt(heightAvail - $('.ilightbox-inner-toolbar', holder).outerHeight());
8853
8854			var width = (typeof item.width == 'string' && item.width.indexOf('%') != -1) ? percentToValue(parseInt(item.width.replace('%', '')), obj.width) : holder.data('naturalWidth'),
8855				height = (typeof item.height == 'string' && item.height.indexOf('%') != -1) ? percentToValue(parseInt(item.height.replace('%', '')), obj.height) : holder.data('naturalHeight');
8856
8857			var dims = ((typeof item.width == 'string' && item.width.indexOf('%') != -1 || typeof item.height == 'string' && item.height.indexOf('%') != -1) ? {
8858					width: width,
8859					height: height
8860				} : iL.getNewDimenstions(widthAvail, heightAvail, width, height)),
8861				newDims = $.extend({}, dims, {});
8862
8863			if (obj.type == 'prev' || obj.type == 'next')
8864				width = parseInt(dims.width * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale)),
8865				height = parseInt(dims.height * ((obj.type == 'next') ? opts.styles.nextScale : opts.styles.prevScale));
8866			else
8867				width = dims.width,
8868				height = dims.height;
8869
8870			var widthDiff = parseInt((getPixel(holder, 'padding-left') + getPixel(holder, 'padding-right') + getPixel(holder, 'border-left-width') + getPixel(holder, 'border-right-width')) / 2),
8871				heightDiff = parseInt((getPixel(holder, 'padding-top') + getPixel(holder, 'padding-bottom') + getPixel(holder, 'border-top-width') + getPixel(holder, 'border-bottom-width') + $('.ilightbox-inner-toolbar', holder).outerHeight()) / 2);
8872
8873			switch (obj.type) {
8874				case 'current':
8875					var top = parseInt((obj.height / 2) - (height / 2) - heightDiff - (thumbsOffsetH / 2)),
8876						left = parseInt((obj.width / 2) - (width / 2) - widthDiff - (thumbsOffsetW / 2));
8877					break;
8878
8879				case 'next':
8880					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(obj.height - offsetX - heightDiff - (thumbsOffsetH / 2)),
8881						left = (path == 'horizontal') ? parseInt(obj.width - offsetX - widthDiff - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - (width / 2) - widthDiff - offsetY - (thumbsOffsetW / 2));
8882					break;
8883
8884				case 'prev':
8885					var top = (path == 'horizontal') ? parseInt((obj.height / 2) - offsetY - (height / 2) - heightDiff - (thumbsOffsetH / 2)) : parseInt(offsetX - heightDiff - height - (thumbsOffsetH / 2)),
8886						left = (path == 'horizontal') ? parseInt(offsetX - widthDiff - width - (thumbsOffsetW / 2)) : parseInt((obj.width / 2) - offsetY - (width / 2) - widthDiff - (thumbsOffsetW / 2));
8887					break;
8888			}
8889
8890			holder.data('offset', {
8891				top: top,
8892				left: left,
8893				newDims: newDims,
8894				diff: {
8895					W: widthDiff,
8896					H: heightDiff
8897				},
8898				thumbsOffset: {
8899					W: thumbsOffsetW,
8900					H: thumbsOffsetH
8901				},
8902				object: obj
8903			});
8904
8905			if (obj.animate > 0 && opts.effects.reposition) {
8906				holder.css(transform, gpuAcceleration).stop().animate({
8907					top: top,
8908					left: left
8909				}, opts.effects.repositionSpeed, 'easeOutCirc', function() {
8910					holder.css(transform, '');
8911				});
8912				$('div.ilightbox-container', holder).stop().animate({
8913					width: width,
8914					height: height
8915				}, opts.effects.repositionSpeed, 'easeOutCirc');
8916				$('div.ilightbox-inner-toolbar', holder).stop().animate({
8917					width: width
8918				}, opts.effects.repositionSpeed, 'easeOutCirc', function() {
8919					$(this).css('overflow', 'visible');
8920				});
8921			} else {
8922				holder.css({
8923					top: top,
8924					left: left
8925				});
8926				$('div.ilightbox-container', holder).css({
8927					width: width,
8928					height: height
8929				});
8930				$('div.ilightbox-inner-toolbar', holder).css({
8931					width: width
8932				});
8933			}
8934		},
8935
8936		resume: function(priority) {
8937			var iL = this,
8938				vars = iL.vars,
8939				opts = iL.options;
8940
8941			if (!opts.slideshow.pauseTime || opts.controls.slideshow && vars.total <= 1 || priority < vars.isPaused) {
8942				return;
8943			}
8944
8945			vars.isPaused = 0;
8946
8947			if (vars.cycleID) {
8948				vars.cycleID = clearTimeout(vars.cycleID);
8949			}
8950
8951			vars.cycleID = setTimeout(function() {
8952				if (vars.current == vars.total - 1) iL.goTo(0);
8953				else iL.moveTo('next');
8954			}, opts.slideshow.pauseTime);
8955		},
8956
8957		pause: function(priority) {
8958			var iL = this,
8959				vars = iL.vars,
8960				opts = iL.options;
8961
8962			if (priority < vars.isPaused) {
8963				return;
8964			}
8965
8966			vars.isPaused = priority || 100;
8967
8968			if (vars.cycleID) {
8969				vars.cycleID = clearTimeout(vars.cycleID);
8970			}
8971		},
8972
8973		resetCycle: function() {
8974			var iL = this,
8975				vars = iL.vars,
8976				opts = iL.options;
8977
8978			if (opts.controls.slideshow && vars.cycleID && !vars.isPaused) {
8979				iL.resume();
8980			}
8981		},
8982
8983		getNewDimenstions: function(width, height, width_old, height_old, thumb) {
8984			var iL = this;
8985
8986			if (!width) factor = height / height_old;
8987			else if (!height) factor = width / width_old;
8988			else factor = min(width / width_old, height / height_old);
8989
8990			if (!thumb) {
8991				if (factor > iL.options.maxScale) factor = iL.options.maxScale;
8992				else if (factor < iL.options.minScale) factor = iL.options.minScale;
8993			}
8994
8995			var final_width = (iL.options.keepAspectRatio) ? round(width_old * factor) : width,
8996				final_height = (iL.options.keepAspectRatio) ? round(height_old * factor) : height;
8997
8998			return {
8999				width: final_width,
9000				height: final_height,
9001				ratio: factor
9002			};
9003		},
9004
9005		setOption: function(options) {
9006			var iL = this;
9007
9008			iL.options = $.extend(true, iL.options, options || {});
9009			iL.refresh();
9010		},
9011
9012		availPlugins: function() {
9013			var iL = this,
9014				testEl = document.createElement("video");
9015
9016			iL.plugins = {
9017				flash: false,
9018				quicktime: (parseInt(PluginDetect.getVersion("QuickTime")) >= 0) ? true : false,
9019				html5H264: !!(testEl.canPlayType && testEl.canPlayType('video/mp4').replace(/no/, '')),
9020				html5WebM: !!(testEl.canPlayType && testEl.canPlayType('video/webm').replace(/no/, '')),
9021				html5Vorbis: !!(testEl.canPlayType && testEl.canPlayType('video/ogg').replace(/no/, '')),
9022				html5QuickTime: !!(testEl.canPlayType && testEl.canPlayType('video/quicktime').replace(/no/, ''))
9023			};
9024		},
9025
9026		addContent: function(element, obj) {
9027			var iL = this,
9028				el;
9029
9030			switch (obj.type) {
9031				case 'video':
9032					var HTML5 = false,
9033						videoType = obj.videoType,
9034						html5video = obj.options.html5video;
9035
9036					if (((videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v') || html5video.h264) && iL.plugins.html5H264)
9037						obj.ext = 'mp4',
9038						obj.URL = html5video.h264 || obj.URL;
9039					else if (html5video.webm && iL.plugins.html5WebM)
9040						obj.ext = 'webm',
9041						obj.URL = html5video.webm || obj.URL;
9042					else if (html5video.ogg && iL.plugins.html5Vorbis)
9043						obj.ext = 'ogv',
9044						obj.URL = html5video.ogg || obj.URL;
9045
9046					if (iL.plugins.html5H264 && (videoType == 'video/mp4' || obj.ext == 'mp4' || obj.ext == 'm4v')) HTML5 = true, videoType = "video/mp4";
9047					else if (iL.plugins.html5WebM && (videoType == 'video/webm' || obj.ext == 'webm')) HTML5 = true, videoType = "video/webm";
9048					else if (iL.plugins.html5Vorbis && (videoType == 'video/ogg' || obj.ext == 'ogv')) HTML5 = true, videoType = "video/ogg";
9049					else if (iL.plugins.html5QuickTime && (videoType == 'video/quicktime' || obj.ext == 'mov' || obj.ext == 'qt')) HTML5 = true, videoType = "video/quicktime";
9050
9051					if (HTML5) {
9052						el = $('<video />
9052', {
9053							"width": "100%",
9054							"height": "100%",
9055							"preload": html5video.preload,
9056							"autoplay": html5video.autoplay,
9057							"poster": html5video.poster,
9058							"controls": html5video.controls
9059						}).append($('<source />', {
9060							"src": obj.URL,
9061							"type": videoType
9062						}));
9063					} else {
9064						if (!iL.plugins.quicktime) el = $('<span />', {
9065							"class": "ilightbox-alert",
9066							html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.quicktime).replace('{type}', 'QuickTime')
9067						});
9068						else {
9069
9070							el = $('<object />', {
9071								"type": "video/quicktime",
9072								"pluginspage": pluginspages.quicktime
9073							}).attr({
9074								"data": obj.URL,
9075								"width": "100%",
9076								"height": "100%"
9077							}).append($('<param />', {
9078								"name": "src",
9079								"value": obj.URL
9080							})).append($('<param />', {
9081								"name": "autoplay",
9082								"value": "false"
9083							})).append($('<param />', {
9084								"name": "loop",
9085								"value": "false"
9086							})).append($('<param />', {
9087								"name": "scale",
9088								"value": "tofit"
9089							}));
9090
9091							if (browser.msie) el = QT_GenerateOBJECTText(obj.URL, '100%', '100%', '', 'SCALE', 'tofit', 'AUTOPLAY', 'false', 'LOOP', 'false');
9092						}
9093					}
9094
9095					break;
9096
9097				case 'flash':
9098					if (!iL.plugins.flash) el = $('<span />', {
9099						"class": "ilightbox-alert",
9100						html: iL.options.errors.missingPlugin.replace('{pluginspage}', pluginspages.flash).replace('{type}', 'Adobe Flash player')
9101					});
9102					else {
9103						var flashvars = "",
9104							i = 0;
9105
9106						if (obj.options.flashvars) $.each(obj.options.flashvars, function(k, v) {
9107							if (i != 0) flashvars += "&";
9108							flashvars += k + "=" + encodeURIComponent(v);
9109							i++;
9110						});
9111						else flashvars = null;
9112
9113						el = $('<embed />').attr({
9114							"type": "application/x-shockwave-flash",
9115							"src": obj.URL,
9116							"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
9117							"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
9118							"quality": "high",
9119							"bgcolor": "#000000",
9120							"play": "true",
9121							"loop": "true",
9122							"menu": "true",
9123							"wmode": "transparent",
9124							"scale": "showall",
9125							"allowScriptAccess": "always",
9126							"allowFullScreen": "true",
9127							"flashvars": flashvars,
9128							"fullscreen": "yes"
9129						});
9130					}
9131
9132					break;
9133
9134				case 'iframe':
9135					el = $('<iframe />').attr({
9136						"width": (typeof obj.options.width == 'number' && obj.options.width && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.width : "100%",
9137						"height": (typeof obj.options.height == 'number' && obj.options.height && iL.options.minScale == '1' && iL.options.maxScale == '1') ? obj.options.height : "100%",
9138						src: obj.URL,
9139						frameborder: 0,
9140						'hspace': 0,
9141						'vspace': 0,
9142						'scrolling': supportTouch ? 'auto' : 'scroll',
9143						'webkitAllowFullScreen': '',
9144						'mozallowfullscreen': '',
9145						'allowFullScreen': ''
9146					});
9147
9148					break;
9149
9150				case 'inline':
9151					el = $('<div class="ilightbox-wrapper"></div>').html($(obj.URL).clone(true));
9152
9153					break;
9154
9155				case 'html':
9156					var object = obj.URL,
9157						el;
9158
9159					if (object[0].nodeName) {
9160						el = $('<div class="ilightbox-wrapper"></div>').html(object);
9161					} else {
9162						var dom = $(obj.URL),
9163							html = (dom.selector) ? $('<div>' + dom + '</div>') : dom;
9164						el = $('<div class="ilightbox-wrapper"></div>').html(html);
9165					}
9166
9167					break;
9168			}
9169
9170			$('div.ilightbox-container', element).empty().html(el);
9171
9172			// For fixing Chrome about just playing the video for first time
9173			if (el[0].tagName.toLowerCase() === 'video' && browser.webkit) setTimeout(function() {
9174				var src = el[0].currentSrc + '?' + floor(random() * 30000);
9175				el[0].currentSrc = src;
9176				el[0].src = src;
9177			});
9178
9179			return el;
9180		},
9181
9182		ogpRecognition: function(obj, callback) {
9183			var iL = this,
9184				url = obj.URL;
9185
9186			iL.showLoader();
9187			doAjax(url, function(data) {
9188				iL.hideLoader();
9189
9190				if (data) {
9191					var object = new Object();
9192
9193					object.length = false,
9194					object.url = data.url;
9195
9196					if (data.status == 200) {
9197						var result = data.results,
9198							type = result.type,
9199							source = result.source;
9200
9201						object.source = source.src,
9202						object.width = source.width && parseInt(source.width) || 0,
9203						object.height = source.height && parseInt(source.height) || 0,
9204						object.type = type,
9205						object.thumbnail = source.thumbnail || result.images[0],
9206						object.html5video = result.html5video || {},
9207						object.length = true;
9208
9209						if (source.type == 'application/x-shockwave-flash') object.type = "flash";
9210						else if (source.type.indexOf("video/") != -1) object.type = "video";
9211						else if (source.type.indexOf("/html") != -1) object.type = "iframe";
9212						else if (source.type.indexOf("image/") != -1) object.type = "image";
9213
9214					} else if (typeof data.response != 'undefined')
9215						throw data.response;
9216
9217					callback.call(this, object.length ? object : false);
9218				}
9219			});
9220		},
9221
9222		hashChangeHandler: function(url) {
9223			var iL = this,
9224				vars = iL.vars,
9225				opts = iL.options,
9226				URL = url || window.location.href,
9227				hash = parseURI(URL).hash,
9228				split = hash.split('/'),
9229				index = split[1];
9230
9231			if (vars.hashLock || ('#' + opts.linkId != split[0] && hash.length > 1)) return;
9232
9233			if (index) {
9234				var target = split[1] || 0;
9235				if (iL.items[target]) {
9236					var overlay = $('.ilightbox-overlay');
9237					if (overlay.length && overlay.attr('linkid') == opts.linkId) {
9238						iL.goTo(target);
9239					} else {
9240						iL.itemsObject[target].trigger(supportTouch ? 'itap' : 'click');
9241					}
9242				} else {
9243					var overlay = $('.ilightbox-overlay');
9244					if (overlay.length) iL.closeAction();
9245				}
9246			} else {
9247				var overlay = $('.ilightbox-overlay');
9248				if (overlay.length) iL.closeAction();
9249			}
9250		}
9251	};
9252
9253	/**
9254	 * Parse style to pixels.
9255	 *
9256	 * @param {Object}   $element   jQuery object with element.
9257	 * @param {Property} property   CSS property to get the pixels from.
9258	 *
9259	 * @return {Int}
9260	 */
9261	function getPixel($element, property) {
9262		return parseInt($element.css(property), 10) || 0;
9263	}
9264
9265	/**
9266	 * Make sure that number is within the limits.
9267	 *
9268	 * @param {Number} number
9269	 * @param {Number} min
9270	 * @param {Number} max
9271	 *
9272	 * @return {Number}
9273	 */
9274	function within(number, min, max) {
9275		return number < min ? min : number > max ? max : number;
9276	}
9277
9278	/**
9279	 * Get viewport/window size (width and height).
9280	 *
9281	 * @return {Object}
9282	 */
9283	function getViewport() {
9284		var e = window,
9285			a = 'inner';
9286		if (!('innerWidth' in window)) {
9287			a = 'client';
9288			e = document.documentElement || document.body;
9289		}
9290		return {
9291			width: e[a + 'Width'],
9292			height: e[a + 'Height']
9293		}
9294	}
9295
9296	/**
9297	 * Remove hash tag from the URL
9298	 *
9299	 * @return {Void}
9300	 */
9301	function removeHash() {
9302		var scroll = getScrollXY();
9303
9304		window.location.hash = "";
9305
9306		// Restore the scroll offset, should be flicker free
9307		window.scrollTo(scroll.x, scroll.y);
9308	}
9309
9310	/**
9311	 * Do the ajax requests with callback.
9312	 *
9313	 * @param {String}   url
9314	 * @param {Function} callback
9315	 *
9316	 * @return {Void}
9317	 */
9318	function doAjax(url, callback) {
9319		var url = "http://ilightbox.net/getSource/jsonp.php?url=" + encodeURIComponent(url).replace(/!/g, '%21').replace(/'/g, '%27').replace(/\(/g, '%28').replace(/\)/g, '%29').replace(/\*/g, '%2A');
9320		$.ajax({
9321			url: url,
9322			dataType: 'jsonp'
9323		});
9324
9325		iLCallback = function(data) {
9326			callback.call(this, data);
9327		};
9328	}
9329
9330	/**
9331	 * Find image from DOM elements
9332	 *
9333	 * @param {Element} element
9334	 *
9335	 * @return {Void}
9336	 */
9337	function findImageInElement(element) {
9338		var elements = $('*', element),
9339			imagesArr = new Array();
9340
9341		elements.each(function() {
9342			var url = "",
9343				element = this;
9344
9345			if ($(element).css("background-image") != "none") {
9346				url = $(element).css("background-image");
9347			} else if (typeof($(element).attr("src")) != "undefined" && element.nodeName.toLowerCase() == "img") {
9348				url = $(element).attr("src");
9349			}
9350
9351			if (url.indexOf("gradient") == -1) {
9352				url = url.replace(/url\(\"/g, "");
9353				url = url.replace(/url\(/g, "");
9354				url = url.replace(/\"\)/g, "");
9355				url = url.replace(/\)/g, "");
9356
9357				var urls = url.split(",");
9358
9359				for (var i = 0; i < urls.length; i++) {
9360					if (urls[i].length > 0 && $.inArray(urls[i], imagesArr) == -1) {
9361						var extra = "";
9362						if (browser.msie && browser.version < 9) {
9363							extra = "?" + floor(random() * 3000);
9364						}
9365						imagesArr.push(urls[i] + extra);
9366					}
9367				}
9368			}
9369		});
9370
9371		return imagesArr;
9372	}
9373
9374	/**
9375	 * Get file extension.
9376	 *
9377	 * @param {String} URL
9378	 *
9379	 * @return {String}
9380	 */
9381	function getExtension(URL) {
9382		if (URL !== null) {
9383			var ext = URL.split('.').pop().toLowerCase(),
9384				extra = ext.indexOf('?') !== -1 ? ext.split('?').pop() : '';
9385
9386			return ext.replace(extra, '');
9387		}
9388	}
9389
9390	/**
9391	 * Get type via extension.
9392	 *
9393	 * @param {String} URL
9394	 *
9395	 * @return {String}
9396	 */
9397	function getTypeByExtension(URL) {
9398		var type,
9399			ext = getExtension(URL);
9400
9401		if (extensions.image.indexOf(ext) !== -1) type = 'image';
9402		else if (extensions.flash.indexOf(ext) !== -1) type = 'flash';
9403		else if (extensions.video.indexOf(ext) !== -1) type = 'video';
9404		else type = 'iframe';
9405
9406		return type;
9407	}
9408
9409	/**
9410	 * Return value from percent of a number.
9411	 *
9412	 * @param {Number} percent
9413	 * @param {Number} total
9414	 *
9415	 * @return {Number}
9416	 */
9417	function percentToValue(percent, total) {
9418		return parseInt((total / 100) * percent);
9419	}
9420
9421	/**
9422	 * A JavaScript equivalent of PHP’s parse_url.
9423	 *
9424	 * @param {String} url           The URL to parse.
9425	 *
9426	 * @return {Mixed}
9427	 */
9428	function parseURI(url) {
9429		var m = String(url).replace(/^\s+|\s+$/g, '').match(/^([^:\/?#]+:)?(\/\/(?:[^:@]*(?::[^:@]*)?@)?(([^:\/?#]*)(?::(\d*))?))?([^?#]*)(\?[^#]*)?(#[\s\S]*)?/);
9430		// authority = '//' + user + ':' + pass '@' + hostname + ':' port
9431		return (m ? {
9432			href: m[0] || '',
9433			protocol: m[1] || '',
9434			authority: m[2] || '',
9435			host: m[3] || '',
9436			hostname: m[4] || '',
9437			port: m[5] || '',
9438			pathname: m[6] || '',
9439			search: m[7] || '',
9440			hash: m[8] || ''
9441		} : null);
9442	}
9443
9444	/**
9445	 * Gets the absolute URI.
9446	 *
9447	 * @param {String} href     The relative URL.
9448	 * @param {String} base     The base URL.
9449	 *
9450	 * @return {String}         The absolute URL.
9451	 */
9452	function absolutizeURI(base, href) { // RFC 3986
9453		var iL = this;
9454
9455		function removeDotSegments(input) {
9456			var output = [];
9457			input.replace(/^(\.\.?(\/|$))+/, '')
9458				.replace(/\/(\.(\/|$))+/g, '/')
9459				.replace(/\/\.\.$/, '/../')
9460				.replace(/\/?[^\/]*/g, function(p) {
9461					if (p === '/..') {
9462						output.pop();
9463					} else {
9464						output.push(p);
9465					}
9466				});
9467			return output.join('').replace(/^\//, input.charAt(0) === '/' ? '/' : '');
9468		}
9469
9470		href = parseURI(href || '');
9471		base = parseURI(base || '');
9472
9473		return !href || !base ? null : (href.protocol || base.protocol) +
9474			(href.protocol || href.authority ? href.authority : base.authority) +
9475			removeDotSegments(href.protocol || href.authority || href.pathname.charAt(0) === '/' ? href.pathname : (href.pathname ? ((base.authority && !base.pathname ? '/' : '') + base.pathname.slice(0, base.pathname.lastIndexOf('/') + 1) + href.pathname) : base.pathname)) +
9476			(href.protocol || href.authority || href.pathname ? href.search : (href.search || base.search)) +
9477			href.hash;
9478	}
9479
9480	/**
9481	 * A JavaScript equivalent of PHP’s version_compare.
9482	 *
9483	 * @param {String} v1
9484	 * @param {String} v2
9485	 * @param {String} operator
9486	 *
9487	 * @return {Boolean}
9488	 */
9489	function version_compare(v1, v2, operator) {
9490		this.php_js = this.php_js || {};
9491		this.php_js.ENV = this.php_js.ENV || {};
9492		var i = 0,
9493			x = 0,
9494			compare = 0,
9495			vm = {
9496				'dev': -6,
9497				'alpha': -5,
9498				'a': -5,
9499				'beta': -4,
9500				'b': -4,
9501				'RC': -3,
9502				'rc': -3,
9503				'#': -2,
9504				'p': 1,
9505				'pl': 1
9506			},
9507			prepVersion = function(v) {
9508				v = ('' + v).replace(/[_\-+]/g, '.');
9509				v = v.replace(/([^.\d]+)/g, '.$1.').replace(/\.{2,}/g, '.');
9510				return (!v.length ? [-8] : v.split('.'));
9511			},
9512			numVersion = function(v) {
9513				return !v ? 0 : (isNaN(v) ? vm[v] || -7 : parseInt(v, 10));
9514			};
9515		v1 = prepVersion(v1);
9516		v2 = prepVersion(v2);
9517		x = max(v1.length, v2.length);
9518		for (i = 0; i < x; i++) {
9519			if (v1[i] == v2[i]) {
9520				continue;
9521			}
9522			v1[i] = numVersion(v1[i]);
9523			v2[i] = numVersion(v2[i]);
9524			if (v1[i] < v2[i]) {
9525				compare = -1;
9526				break;
9527			} else if (v1[i] > v2[i]) {
9528				compare = 1;
9529				break;
9530			}
9531		}
9532		if (!operator) {
9533			return compare;
9534		}
9535
9536		switch (operator) {
9537			case '>':
9538			case 'gt':
9539				return (compare > 0);
9540			case '>=':
9541			case 'ge':
9542				return (compare >= 0);
9543			case '<=':
9544			case 'le':
9545				return (compare <= 0);
9546			case '==':
9547			case '=':
9548			case 'eq':
9549				return (compare === 0);
9550			case '<>':
9551			case '!=':
9552			case 'ne':
9553				return (compare !== 0);
9554			case '':
9555			case '<':
9556			case 'lt':
9557				return (compare < 0);
9558			default:
9559				return null;
9560		}
9561	}
9562
9563
9564	// Begin the iLightBox plugin
9565	$.fn.iLightBox = function() {
9566
9567		var args = arguments,
9568			opt = ($.isPlainObject(args[0])) ? args[0] : args[1],
9569			items = ($.isArray(args[0]) || typeof args[0] == 'string') ? args[0] : args[1];
9570
9571		if (!opt) opt = {};
9572
9573		// Default options. Play carefully.
9574		var options = $.extend(true, {
9575			attr: 'href',
9576			path: 'vertical',
9577			skin: 'dark',
9578			linkId: false,
9579			infinite: false,
9580			startFrom: 0,
9581			randomStart: false,
9582			keepAspectRatio: true,
9583			maxScale: 1,
9584			minScale: .2,
9585			innerToolbar: false,
9586			smartRecognition: false,
9587			mobileOptimizer: true,
9588			fullAlone: true,
9589			fullViewPort: null,
9590			fullStretchTypes: 'flash, video',
9591			overlay: {
9592				blur: true,
9593				opacity: .85
9594			},
9595			controls: {
9596				arrows: false,
9597				slideshow: false,
9598				toolbar: true,
9599				fullscreen: true,
9600				thumbnail: true,
9601				keyboard: true,
9602				mousewheel: true,
9603				swipe: true
9604			},
9605			keyboard: {
9606				left: true, // previous
9607				right: true, // next
9608				up: true, // previous
9609				down: true, // next
9610				esc: true, // close
9611				shift_enter: true // fullscreen
9612			},
9613			show: {
9614				effect: true,
9615				speed: 300,
9616				title: true
9617			},
9618			hide: {
9619				effect: true,
9620				speed: 300
9621			},
9622			caption: {
9623				start: true,
9624				show: 'mouseenter',
9625				hide: 'mouseleave'
9626			},
9627			social: {
9628				start: true,
9629				show: 'mouseenter',
9630				hide: 'mouseleave',
9631				buttons: false
9632			},
9633			styles: {
9634				pageOffsetX: 0,
9635				pageOffsetY: 0,
9636				nextOffsetX: 45,
9637				nextOffsetY: 0,
9638				nextOpacity: 1,
9639				nextScale: 1,
9640				prevOffsetX: 45,
9641				prevOffsetY: 0,
9642				prevOpacity: 1,
9643				prevScale: 1
9644			},
9645			thumbnails: {
9646				maxWidth: 120,
9647				maxHeight: 80,
9648				normalOpacity: 1,
9649				activeOpacity: .6
9650			},
9651			effects: {
9652				reposition: true,
9653				repositionSpeed: 200,
9654				switchSpeed: 500,
9655				loadedFadeSpeed: 180,
9656				fadeSpeed: 200
9657			},
9658			slideshow: {
9659				pauseTime: 5000,
9660				pauseOnHover: false,
9661				startPaused: true
9662			},
9663			text: {
9664				close: "Press Esc to close",
9665				enterFullscreen: "Enter Fullscreen (Shift+Enter)",
9666				exitFullscreen: "Exit Fullscreen (Shift+Enter)",
9667				slideShow: "Slideshow",
9668				next: "Next",
9669				previous: "Previous"
9670			},
9671			errors: {
9672				loadImage: "An error occurred when trying to load photo.",
9673				loadContents: "An error occurred when trying to load contents.",
9674				missingPlugin: "The content your are attempting to view requires the <a href='{pluginspage}' target='_blank'>{type} plugin<\/a>."
9675			},
9676			ajaxSetup: {
9677				url: '',
9678				beforeSend: function(jqXHR, settings) {},
9679				cache: false,
9680				complete: function(jqXHR, textStatus) {},
9681				crossDomain: false,
9682				error: function(jqXHR, textStatus, errorThrown) {},
9683				success: function(data, textStatus, jqXHR) {},
9684				global: true,
9685				ifModified: false,
9686				username: null,
9687				password: null,
9688				type: 'GET'
9689			},
9690			callback: {}
9691		}, opt);
9692
9693		var instant = ($.isArray(items) || typeof items == 'string') ? true : false;
9694
9695		items = $.isArray(items) ? items : new Array();
9696
9697		if (typeof args[0] == 'string') items[0] = args[0];
9698
9699		if (version_compare($.fn.jquery, '1.8', '>=')) {
9700			var iLB = new iLightBox($(this), options, items, instant);
9701			return {
9702				close: function() {
9703					iLB.closeAction();
9704				},
9705				fullscreen: function() {
9706					iLB.fullScreenAction();
9707				},
9708				moveNext: function() {
9709					iLB.moveTo('next');
9710				},
9711				movePrev: function() {
9712					iLB.moveTo('prev');
9713				},
9714				goTo: function(index) {
9715					iLB.goTo(index);
9716				},
9717				refresh: function() {
9718					iLB.refresh();
9719				},
9720				reposition: function() {
9721					(arguments.length > 0) ? iLB.repositionPhoto(true): iLB.repositionPhoto();
9722				},
9723				setOption: function(options) {
9724					iLB.setOption(options);
9725				},
9726				destroy: function() {
9727					iLB.closeAction();
9728					iLB.dispatchItemsEvents();
9729				}
9730			};
9731		} else {
9732			throw "The jQuery version that was loaded is too old. iLightBox requires jQuery 1.8+";
9733		}
9734
9735	};
9736
9737
9738	$.iLightBox = function() {
9739		return $.fn.iLightBox(arguments[0], arguments[1]);
9740	};
9741
9742
9743	$.extend($.easing, {
9744		easeInCirc: function(x, t, b, c, d) {
9745			return -c * (sqrt(1 - (t /= d) * t) - 1) + b;
9746		},
9747		easeOutCirc: function(x, t, b, c, d) {
9748			return c * sqrt(1 - (t = t / d - 1) * t) + b;
9749		},
9750		easeInOutCirc: function(x, t, b, c, d) {
9751			if ((t /= d / 2) < 1) return -c / 2 * (sqrt(1 - t * t) - 1) + b;
9752			return c / 2 * (sqrt(1 - (t -= 2) * t) + 1) + b;
9753		}
9754	});
9755
9756	function getScrollXY() {
9757		var scrOfX = 0,
9758			scrOfY = 0;
9759		if (typeof(window.pageYOffset) == 'number') {
9760			//Netscape compliant
9761			scrOfY = window.pageYOffset;
9762			scrOfX = window.pageXOffset;
9763		} else if (document.body && (document.body.scrollLeft || document.body.scrollTop)) {
9764			//DOM compliant
9765			scrOfY = document.body.scrollTop;
9766			scrOfX = document.body.scrollLeft;
9767		} else if (document.documentElement && (document.documentElement.scrollLeft || document.documentElement.scrollTop)) {
9768			//IE6 standards compliant mode
9769			scrOfY = document.documentElement.scrollTop;
9770			scrOfX = document.documentElement.scrollLeft;
9771		}
9772		return {
9773			x: scrOfX,
9774			y: scrOfY
9775		};
9776	}
9777
9778	(function() {
9779		// add new event shortcuts
9780		$.each(("touchstart touchmove touchend " +
9781			"tap taphold " +
9782			"swipe swipeleft swiperight " +
9783			"scrollstart scrollstop").split(" "), function(i, name) {
9784
9785			$.fn[name] = function(fn) {
9786				return fn ? this.bind(name, fn) : this.trigger(name);
9787			};
9788
9789			// jQuery < 1.8
9790			// if ($.attrFn) {
9791			// 	$.attrFn[name] = true;
9792			// }
9793		});
9794
9795		var tapSettings = {
9796			startEvent: 'touchstart.iTap',
9797			endEvent: 'touchend.iTap'
9798		};
9799
9800		// tap Event:
9801		$.event.special.itap = {
9802			setup: function() {
9803
9804				var self = this,
9805					$self = $(this),
9806					start, stop;
9807
9808				$self.bind(tapSettings.startEvent, function(event) {
9809					start = getScrollXY();
9810
9811					$self.one(tapSettings.endEvent, function(event) {
9812						stop = getScrollXY();
9813
9814						var orgEvent = event || window.event;
9815						event = $.event.fix(orgEvent);
9816						event.type = "itap";
9817
9818						if ((start && stop) && (start.x == stop.x && start.y == stop.y))($.event.dispatch || $.event.handle).call(self, event);
9819
9820						start = stop = undefined;
9821					});
9822				});
9823			},
9824
9825			teardown: function() {
9826				$(this).unbind(tapSettings.startEvent);
9827			}
9828		};
9829	}());
9830
9831
9832	//Fullscreen API
9833	(function() {
9834		fullScreenApi = {
9835				supportsFullScreen: false,
9836				isFullScreen: function() {
9837					return false;
9838				},
9839				requestFullScreen: function() {},
9840				cancelFullScreen: function() {},
9841				fullScreenEventName: '',
9842				prefix: ''
9843			},
9844			browserPrefixes = 'webkit moz o ms khtml'.split(' ');
9845
9846		// check for native support
9847		if (typeof document.cancelFullScreen != 'undefined') {
9848			fullScreenApi.supportsFullScreen = true;
9849		} else {
9850			// check for fullscreen support by vendor prefix
9851			for (var i = 0, il = browserPrefixes.length; i < il; i++) {
9852				fullScreenApi.prefix = browserPrefixes[i];
9853
9854				if (typeof document[fullScreenApi.prefix + 'CancelFullScreen'] != 'undefined') {
9855					fullScreenApi.supportsFullScreen = true;
9856
9857					break;
9858				}
9859			}
9860		}
9861
9862		// update methods to do something useful
9863		if (fullScreenApi.supportsFullScreen) {
9864			fullScreenApi.fullScreenEventName = fullScreenApi.prefix + 'fullscreenchange';
9865
9866			fullScreenApi.isFullScreen = function() {
9867				switch (this.prefix) {
9868					case '':
9869						return document.fullScreen;
9870					case 'webkit':
9871						return document.webkitIsFullScreen;
9872					default:
9873						return document[this.prefix + 'FullScreen'];
9874				}
9875			}
9876			fullScreenApi.requestFullScreen = function(el) {
9877				return (this.prefix === '') ? el.requestFullScreen() : el[this.prefix + 'RequestFullScreen']();
9878			}
9879			fullScreenApi.cancelFullScreen = function(el) {
9880				return (this.prefix === '') ? document.cancelFullScreen() : document[this.prefix + 'CancelFullScreen']();
9881			}
9882		}
9883	}());
9884
9885	// Browser detect
9886	(function() {
9887		function uaMatch(ua) {
9888			ua = ua.toLowerCase();
9889
9890			var match = /(chrome)[ \/]([\w.]+)/.exec(ua) ||
9891				/(webkit)[ \/]([\w.]+)/.exec(ua) ||
9892				/(opera)(?:.*version|)[ \/]([\w.]+)/.exec(ua) ||
9893				/(msie) ([\w.]+)/.exec(ua) ||
9894				ua.indexOf("compatible") < 0 && /(mozilla)(?:.*? rv:([\w.]+)|)/.exec(ua) || [];
9895
9896			return {
9897				browser: match[1] || "",
9898				version: match[2] || "0"
9899			};
9900		}
9901
9902		var matched = uaMatch(navigator.userAgent);
9903		browser = {};
9904
9905		if (matched.browser) {
9906			browser[matched.browser] = true;
9907			browser.version = matched.version;
9908		}
9909
9910		// Chrome is Webkit, but Webkit is also Safari.
9911		if (browser.chrome) {
9912			browser.webkit = true;
9913		} else if (browser.webkit) {
9914			browser.safari = true;
9915		}
9916	}());
9917
9918	// Feature detects
9919	(function() {
9920		var prefixes = ['', 'webkit', 'moz', 'ms', 'o'];
9921		var el = document.createElement('div');
9922
9923		function testProp(prop) {
9924			for (var p = 0, pl = prefixes.length; p < pl; p++) {
9925				var prefixedProp = prefixes[p] ? prefixes[p] + prop.charAt(0).toUpperCase() + prop.slice(1) : prop;
9926				if (el.style[prefixedProp] !== undefined) {
9927					return prefixedProp;
9928				}
9929			}
9930		}
9931
9932		// Global support indicators
9933		transform = testProp('transform') || '';
9934		gpuAcceleration = testProp('perspective') ? 'translateZ(0) ' : '';
9935	}());
9936
9937
9938	/*
9939		PluginDetect v0.7.9
9940		www.pinlady.net/PluginDetect/license/
9941		[ getVersion onWindowLoaded BetterIE ]
9942		[ Flash QuickTime Shockwave ]
9943	*/
9944	var PluginDetect={version:"0.7.9",name:"PluginDetect",handler:function(c,b,a){return function(){c(b,a)}},openTag:"<",isDefined:function(b){return typeof b!="undefined"},isArray:function(b){return(/array/i).test(Object.prototype.toString.call(b))},isFunc:function(b){return typeof b=="function"},isString:function(b){return typeof b=="string"},isNum:function(b){return typeof b=="number"},isStrNum:function(b){return(typeof b=="string"&&(/\d/).test(b))},getNumRegx:/[\d][\d\.\_,-]*/,splitNumRegx:/[\.\_,-]/g,getNum:function(b,c){var d=this,a=d.isStrNum(b)?(d.isDefined(c)?new RegExp(c):d.getNumRegx).exec(b):null;return a?a[0]:null},compareNums:function(h,f,d){var e=this,c,b,a,g=parseInt;if(e.isStrNum(h)&&e.isStrNum(f)){if(e.isDefined(d)&&d.compareNums){return d.compareNums(h,f)}c=h.split(e.splitNumRegx);b=f.split(e.splitNumRegx);for(a=0;a<min(c.length,b.length);a++){if(g(c[a],10)>g(b[a],10)){return 1}if(g(c[a],10)<g(b[a],10)){return -1}}}return 0},formatNum:function(b,c){var d=this,a,e;if(!d.isStrNum(b)){return null}if(!d.isNum(c)){c=4}c--;e=b.replace(/\s/g,"").split(d.splitNumRegx).concat(["0","0","0","0"]);for(a=0;a<4;a++){if(/^(0+)(.+)$/.test(e[a])){e[a]=RegExp.$2}if(a>c||!(/\d/).test(e[a])){e[a]="0"}}return e.slice(0,4).join(",")},$$hasMimeType:function(a){return function(c){if(!a.isIE&&c){var f,e,b,d=a.isArray(c)?c:(a.isString(c)?[c]:[]);for(b=0;b<d.length;b++){if(a.isString(d[b])&&/[^\s]/.test(d[b])){f=navigator.mimeTypes[d[b]];e=f?f.enabledPlugin:0;if(e&&(e.name||e.description)){return f}}}}return null}},findNavPlugin:function(l,e,c){var j=this,h=new RegExp(l,"i"),d=(!j.isDefined(e)||e)?/\d/:0,k=c?new RegExp(c,"i"):0,a=navigator.plugins,g="",f,b,m;for(f=0;f<a.length;f++){m=a[f].description||g;b=a[f].name||g;if((h.test(m)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))||(h.test(b)&&(!d||d.test(RegExp.leftContext+RegExp.rightContext)))){if(!k||!(k.test(m)||k.test(b))){return a[f]}}}return null},getMimeEnabledPlugin:function(k,m,c){var e=this,f,b=new RegExp(m,"i"),h="",g=c?new RegExp(c,"i"):0,a,l,d,j=e.isString(k)?[k]:k;for(d=0;d<j.length;
9944d++){if((f=e.hasMimeType(j[d]))&&(f=f.enabledPlugin)){l=f.description||h;a=f.name||h;if(b.test(l)||b.test(a)){if(!g||!(g.test(l)||g.test(a))){return f}}}}return 0},getPluginFileVersion:function(f,b){var h=this,e,d,g,a,c=-1;if(h.OS>2||!f||!f.version||!(e=h.getNum(f.version))){return b}if(!b){return e}e=h.formatNum(e);b=h.formatNum(b);d=b.split(h.splitNumRegx);g=e.split(h.splitNumRegx);for(a=0;a<d.length;a++){if(c>-1&&a>c&&d[a]!="0"){return b}if(g[a]!=d[a]){if(c==-1){c=a}if(d[a]!="0"){return b}}}return e},AXO:window.ActiveXObject,getAXO:function(a){var f=null,d,b=this,c={};try{f=new b.AXO(a)}catch(d){}return f},convertFuncs:function(f){var a,g,d,b=/^[\$][\$]/,c=this;for(a in f){if(b.test(a)){try{g=a.slice(2);if(g.length>0&&!f[g]){f[g]=f[a](f);delete f[a]}}catch(d){}}}},initObj:function(e,b,d){var a,c;if(e){if(e[b[0]]==1||d){for(a=0;a<b.length;a=a+2){e[b[a]]=b[a+1]}}for(a in e){c=e[a];if(c&&c[b[0]]==1){this.initObj(c,b)}}}},initScript:function(){var d=this,a=navigator,h,i=document,l=a.userAgent||"",j=a.vendor||"",b=a.platform||"",k=a.product||"";d.initObj(d,["$",d]);for(h in d.Plugins){if(d.Plugins[h]){d.initObj(d.Plugins[h],["$",d,"$$",d.Plugins[h]],1)}}d.convertFuncs(d);d.OS=100;if(b){var g=["Win",1,"Mac",2,"Linux",3,"FreeBSD",4,"iPhone",21.1,"iPod",21.2,"iPad",21.3,"Win.*CE",22.1,"Win.*Mobile",22.2,"Pocket\\s*PC",22.3,"",100];for(h=g.length-2;h>=0;h=h-2){if(g[h]&&new RegExp(g[h],"i").test(b)){d.OS=g[h+1];break}}};d.head=i.getElementsByTagName("head")[0]||i.getElementsByTagName("body")[0]||i.body||null;d.isIE=new Function("return/*@cc_on!@*/!1")();d.verIE=d.isIE&&(/MSIE\s*(\d+\.?\d*)/i).test(l)?parseFloat(RegExp.$1,10):null;d.verIEfull=null;d.docModeIE=null;if(d.isIE){var f,n,c=document.createElement("div");try{c.style.behavior="url(#default#clientcaps)";d.verIEfull=(c.getComponentVersion("{89820200-ECBD-11CF-8B85-00AA005B4383}","componentid")).replace(/,/g,".")}catch(f){}n=parseFloat(d.verIEfull||"0",10);d.docModeIE=i.documentMode||((/back/i).test(i.compatMode||"")?5:n)||d.verIE;d.verIE=n||d.docModeIE};d.ActiveXEnabled=false;if(d.isIE){var h,m=["Msxml2.XMLHTTP","Msxml2.DOMDocument","Microsoft.XMLDOM","ShockwaveFlash.ShockwaveFlash","TDCCtl.TDCCtl","Shell.UIHelper","Scripting.Dictionary","wmplayer.ocx"];for(h=0;h<m.length;h++){if(d.getAXO(m[h])){d.ActiveXEnabled=true;break}}};d.isGecko=(/Gecko/i).test(k)&&(/Gecko\s*\/\s*\d/i).test(l);
9944d.verGecko=d.isGecko?d.formatNum((/rv\s*\:\s*([\.\,\d]+)/i).test(l)?RegExp.$1:"0.9"):null;d.isChrome=(/Chrome\s*\/\s*(\d[\d\.]*)/i).test(l);d.verChrome=d.isChrome?d.formatNum(RegExp.$1):null;d.isSafari=((/Apple/i).test(j)||(!j&&!d.isChrome))&&(/Safari\s*\/\s*(\d[\d\.]*)/i).test(l);d.verSafari=d.isSafari&&(/Version\s*\/\s*(\d[\d\.]*)/i).test(l)?d.formatNum(RegExp.$1):null;d.isOpera=(/Opera\s*[\/]?\s*(\d+\.?\d*)/i).test(l);d.verOpera=d.isOpera&&((/Version\s*\/\s*(\d+\.?\d*)/i).test(l)||1)?parseFloat(RegExp.$1,10):null;d.addWinEvent("load",d.handler(d.runWLfuncs,d))},init:function(d){var c=this,b,d,a={status:-3,plugin:0};if(!c.isString(d)){return a}if(d.length==1){c.getVersionDelimiter=d;return a}d=d.toLowerCase().replace(/\s/g,"");b=c.Plugins[d];if(!b||!b.getVersion){return a}a.plugin=b;if(!c.isDefined(b.installed)){b.installed=null;b.version=null;b.version0=null;b.getVersionDone=null;b.pluginName=d}c.garbage=false;if(c.isIE&&!c.ActiveXEnabled&&d!=="java"){a.status=-2;return a}a.status=1;return a},fPush:function(b,a){var c=this;if(c.isArray(a)&&(c.isFunc(b)||(c.isArray(b)&&b.length>0&&c.isFunc(b[0])))){a.push(b)}},callArray:function(b){var c=this,a;if(c.isArray(b)){for(a=0;a<b.length;a++){if(b[a]===null){return}c.call(b[a]);b[a]=null}}},call:function(c){var b=this,a=b.isArray(c)?c.length:-1;if(a>0&&b.isFunc(c[0])){c[0](b,a>1?c[1]:0,a>2?c[2]:0,a>3?c[3]:0)}else{if(b.isFunc(c)){c(b)}}},getVersionDelimiter:",",$$getVersion:function(a){return function(g,d,c){var e=a.init(g),f,b,h={};if(e.status<0){return null};f=e.plugin;if(f.getVersionDone!=1){f.getVersion(null,d,c);if(f.getVersionDone===null){f.getVersionDone=1}}a.cleanup();b=(f.version||f.version0);b=b?b.replace(a.splitNumRegx,a.getVersionDelimiter):b;return b}},cleanup:function(){var a=this;if(a.garbage&&a.isDefined(window.CollectGarbage)){window.CollectGarbage()}},isActiveXObject:function(d,b){var f=this,a=false,g,c='<object width="1" height="1" style="display:none" '+d.getCodeBaseVersion(b)+">"+d.HTML+f.openTag+"/object>";if(!f.head){return a}f.head.insertBefore(document.createElement("object"),f.head.firstChild);f.head.firstChild.outerHTML=c;try{f.head.firstChild.classid=d.classID}catch(g){}try{if(f.head.firstChild.object){a=true}}catch(g){}try{if(a&&f.head.firstChild.readyState<4){f.garbage=true}}catch(g){}f.head.removeChild(f.head.firstChild);return a},codebaseSearch:function(f,b){var c=this;if(!c.ActiveXEnabled||!f){return null}if(f.BIfuncs&&f.BIfuncs.length&&f.BIfuncs[f.BIfuncs.length-1]!==null){c.callArray(f.BIfuncs)}var d,o=f.SEARCH,k={};if(c.isStrNum(b)){if(o.match&&o.min&&c.compareNums(b,o.min)<=0){return true}if(o.match&&o.max&&c.compareNums(b,o.max)>=0){return false}d=c.isActiveXObject(f,b);if(d&&(!o.min||c.compareNums(b,o.min)>0)){o.min=b}if(!d&&(!o.max||c.compareNums(b,o.max)<0)){o.max=b}return d};var e=[0,0,0,0],l=[].concat(o.digits),a=o.min?1:0,j,i,h,g,m,n=function(p,r){var q=[].concat(e);q[p]=r;return c.isActiveXObject(f,q.join(","))};if(o.max){g=o.max.split(c.splitNumRegx);for(j=0;j<g.length;j++){g[j]=parseInt(g[j],10)}if(g[0]<l[0]){l[0]=g[0]}}if(o.min){m=o.min.split(c.splitNumRegx);for(j=0;j<m.length;j++){m[j]=parseInt(m[j],10)}if(m[0]>e[0]){e[0]=m[0]}}if(m&&g){for(j=1;j<m.length;j++){if(m[j-1]!=g[j-1]){break}if(g[j]<l[j]){l[j]=g[j]}if(m[j]>e[j]){e[j]=m[j]}}}if(o.max){for(j=1;j<l.length;j++){if(g[j]>0&&l[j]==0&&l[j-1]<o.digits[j-1]){l[j-1]+=1;break}}};for(j=0;j<l.length;j++){h={};for(i=0;i<20;i++){if(l[j]-e[j]<1){break}d=round((l[j]+e[j])/2);if(h["a"+d]){break}h["a"+d]=1;if(n(j,d)){e[j]=d;a=1}else{l[j]=d}}l[j]=e[j];if(!a&&n(j,e[j])){a=1};if(!a){break}};return a?e.join(","):null},addWinEvent:function(d,c){var e=this,a=window,b;if(e.isFunc(c)){if(a.addEventListener){a.addEventListener(d,c,false)}else{if(a.attachEvent){a.attachEvent("on"+d,c)}else{b=a["on"+d];a["on"+d]=e.winHandler(c,b)}}}},winHandler:function(d,c){return function(){d();if(typeof c=="function"){c()}}},WLfuncs0:[],WLfuncs:[],runWLfuncs:function(a){var b={};a.winLoaded=true;a.callArray(a.WLfuncs0);a.callArray(a.WLfuncs);if(a.onDoneEmptyDiv){a.onDoneEmptyDiv()}},winLoaded:false,$$onWindowLoaded:function(a){return function(b){if(a.winLoaded){a.call(b)}else{a.fPush(b,a.WLfuncs)}}},div:null,divID:"plugindetect",divWidth:50,pluginSize:1,emptyDiv:function(){var d=this,b,h,c,a,f,g;if(d.div&&d.div.childNodes){for(b=d.div.childNodes.length-1;b>=0;b--){c=d.div.childNodes[b];if(c&&c.childNodes){for(h=c.childNodes.length-1;h>=0;h--){g=c.childNodes[h];try{c.removeChild(g)}catch(f){}}}if(c){try{d.div.removeChild(c)}catch(f){}}}}if(!d.div){a=document.getElementById(d.divID);if(a){d.div=a}}if(d.div&&d.div.parentNode){try{d.div.parentNode.removeChild(d.div)}catch(f){}d.div=null}},DONEfuncs:[],onDoneEmptyDiv:function(){var c=this,a,b;if(!c.winLoaded){return}if(c.WLfuncs&&c.WLfuncs.length&&c.WLfuncs[c.WLfuncs.length-1]!==null){return}for(a in c){b=c[a];if(b&&b.funcs){if(b.OTF==3){return}if(b.funcs.length&&b.funcs[b.funcs.length-1]!==null){return}}}for(a=0;a<c.DONEfuncs.length;a++){c.callArray(c.DONEfuncs)}
9944c.emptyDiv()},getWidth:function(c){if(c){var a=c.scrollWidth||c.offsetWidth,b=this;if(b.isNum(a)){return a}}return -1},getTagStatus:function(m,g,a,b){var c=this,f,k=m.span,l=c.getWidth(k),h=a.span,j=c.getWidth(h),d=g.span,i=c.getWidth(d);if(!k||!h||!d||!c.getDOMobj(m)){return -2}if(j<i||l<0||j<0||i<0||i<=c.pluginSize||c.pluginSize<1){return 0}if(l>=i){return -1}try{if(l==c.pluginSize&&(!c.isIE||c.getDOMobj(m).readyState==4)){if(!m.winLoaded&&c.winLoaded){return 1}if(m.winLoaded&&c.isNum(b)){if(!c.isNum(m.count)){m.count=b}if(b-m.count>=10){return 1}}}}catch(f){}return 0},getDOMobj:function(g,a){var f,d=this,c=g?g.span:0,b=c&&c.firstChild?1:0;try{if(b&&a){d.div.focus()}}catch(f){}return b?c.firstChild:null},setStyle:function(b,g){var f=b.style,a,d,c=this;if(f&&g){for(a=0;a<g.length;a=a+2){try{f[g[a]]=g[a+1]}catch(d){}}}},insertDivInBody:function(i,g){var f,c=this,h="pd33993399",b=null,d=g?window.top.document:window.document,a=d.getElementsByTagName("body")[0]||d.body;if(!a){try{d.write('<div id="'+h+'">.'+c.openTag+"/div>");b=d.getElementById(h)}catch(f){}}a=d.getElementsByTagName("body")[0]||d.body;if(a){a.insertBefore(i,a.firstChild);if(b){a.removeChild(b)}}},insertHTML:function(f,b,g,a,k){var l,m=document,j=this,p,o=m.createElement("span"),n,i;var c=["outlineStyle","none","borderStyle","none","padding","0px","margin","0px","visibility","visible"];var h="outline-style:none;border-style:none;padding:0px;margin:0px;visibility:visible;";if(!j.isDefined(a)){a=""}if(j.isString(f)&&(/[^\s]/).test(f)){f=f.toLowerCase().replace(/\s/g,"");p=j.openTag+f+' width="'+j.pluginSize+'" height="'+j.pluginSize+'" ';p+='style="'+h+'display:inline;" ';for(n=0;n<b.length;n=n+2){if(/[^\s]/.test(b[n+1])){p+=b[n]+'="'+b[n+1]+'" '}}p+=">";for(n=0;n<g.length;n=n+2){if(/[^\s]/.test(g[n+1])){p+=j.openTag+'param name="'+g[n]+'" value="'+g[n+1]+'" />'}}p+=a+j.openTag+"/"+f+">"}else{p=a}if(!j.div){i=m.getElementById(j.divID);if(i){j.div=i}else{j.div=m.createElement("div");j.div.id=j.divID}j.setStyle(j.div,c.concat(["width",j.divWidth+"px","height",(j.pluginSize+3)+"px","fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","block"]));if(!i){j.setStyle(j.div,["position","absolute","right","0px","top","0px"]);j.insertDivInBody(j.div)}}if(j.div&&j.div.parentNode){j.setStyle(o,c.concat(["fontSize",(j.pluginSize+3)+"px","lineHeight",(j.pluginSize+3)+"px","verticalAlign","baseline","display","inline"]));try{o.innerHTML=p}catch(l){};try{j.div.appendChild(o)}catch(l){};return{span:o,winLoaded:j.winLoaded,tagName:f,outerHTML:p}}return{span:null,winLoaded:j.winLoaded,tagName:"",outerHTML:p}},Plugins:{quicktime:{mimeType:["video/quicktime","application/x-quicktimeplayer","image/x-macpaint","image/x-quicktime"],progID:"QuickTimeCheckObject.QuickTimeCheck.1",progID0:"QuickTime.QuickTime",classID:"clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B",minIEver:7,HTML:'<param name="src" value="" /><param name="controller" value="false" />',getCodeBaseVersion:function(a){return'codebase="#version='+a+'"'},SEARCH:{min:0,max:0,match:0,digits:[16,128,128,0]},getVersion:function(c){var f=this,d=f.$,a=null,e=null,b;if(!d.isIE){if(d.hasMimeType(f.mimeType)){e=d.OS!=3?d.findNavPlugin("QuickTime.*Plug-?in",0):null;if(e&&e.name){a=d.getNum(e.name)}}}else{if(d.isStrNum(c)){b=c.split(d.splitNumRegx);if(b.length>3&&parseInt(b[3],10)>0){b[3]="9999"}c=b.join(",")}if(d.isStrNum(c)&&d.verIE>=f.minIEver&&f.canUseIsMin()>0){f.installed=f.isMin(c);f.getVersionDone=0;return}f.getVersionDone=1;if(!a&&d.verIE>=f.minIEver){a=f.CDBASE2VER(d.codebaseSearch(f))}if(!a){e=d.getAXO(f.progID);if(e&&e.QuickTimeVersion){a=e.QuickTimeVersion.toString(16);a=parseInt(a.charAt(0),16)+"."+parseInt(a.charAt(1),16)+"."+parseInt(a.charAt(2),16)}}}f.installed=a?1:(e?0:-1);f.version=d.formatNum(a,3)},cdbaseUpper:["7,60,0,0","0,0,0,0"],cdbaseLower:["7,50,0,0",null],cdbase2ver:[function(c,b){var a=b.split(c.$.splitNumRegx);return[a[0],a[1].charAt(0),a[1].charAt(1),a[2]].join(",")},null],CDBASE2VER:function(f){var e=this,c=e.$,b,a=e.cdbaseUpper,d=e.cdbaseLower;
9944if(f){f=c.formatNum(f);for(b=0;b<a.length;b++){if(a[b]&&c.compareNums(f,a[b])<0&&d[b]&&c.compareNums(f,d[b])>=0&&e.cdbase2ver[b]){return e.cdbase2ver[b](e,f)}}}return f},canUseIsMin:function(){var f=this,d=f.$,b,c=f.canUseIsMin,a=f.cdbaseUpper,e=f.cdbaseLower;if(!c.value){c.value=-1;for(b=0;b<a.length;b++){if(a[b]&&d.codebaseSearch(f,a[b])){c.value=1;break}if(e[b]&&d.codebaseSearch(f,e[b])){c.value=-1;break}}}f.SEARCH.match=c.value==1?1:0;return c.value},isMin:function(c){var b=this,a=b.$;return a.codebaseSearch(b,c)?0.7:-1}},flash:{mimeType:"application/x-shockwave-flash",progID:"ShockwaveFlash.ShockwaveFlash",classID:"clsid:D27CDB6E-AE6D-11CF-96B8-444553540000",getVersion:function(){var b=function(i){if(!i){return null}var e=/[\d][\d\,\.\s]*[rRdD]{0,1}[\d\,]*/.exec(i);return e?e[0].replace(/[rRdD\.]/g,",").replace(/\s/g,""):null};var j=this,g=j.$,k,h,l=null,c=null,a=null,f,m,d;if(!g.isIE){m=g.hasMimeType(j.mimeType);if(m){f=g.getDOMobj(g.insertHTML("object",["type",j.mimeType],[],"",j));try{l=g.getNum(f.GetVariable("$version"))}catch(k){}}if(!l){d=m?m.enabledPlugin:null;if(d&&d.description){l=b(d.description)}if(l){l=g.getPluginFileVersion(d,l)}}}else{for(h=15;h>2;h--){c=g.getAXO(j.progID+"."+h);if(c){a=h.toString();break}}if(!c){c=g.getAXO(j.progID)}if(a=="6"){try{c.AllowScriptAccess="always"}catch(k){return"6,0,21,0"}}try{l=b(c.GetVariable("$version"))}catch(k){}if(!l&&a){l=a}}j.installed=l?1:-1;j.version=g.formatNum(l);return true}},shockwave:{mimeType:"application/x-director",progID:"SWCtl.SWCtl",classID:"clsid:166B1BCA-3F9C-11CF-8075-444553540000",getVersion:function(){var a=null,b=null,g,f,d=this,c=d.$;if(!c.isIE){f=c.findNavPlugin("Shockwave\\s*for\\s*Director");if(f&&f.description&&c.hasMimeType(d.mimeType)){a=c.getNum(f.description)}if(a){a=c.getPluginFileVersion(f,a)}}else{try{b=c.getAXO(d.progID).ShockwaveVersion("")}catch(g){}if(c.isString(b)&&b.length>0){a=c.getNum(b)}else{if(c.getAXO(d.progID+".8")){a="8"}else{if(c.getAXO(d.progID+".7")){a="7"}else{if(c.getAXO(d.progID+".1")){a="6"}}}}}d.installed=a?1:-1;d.version=c.formatNum(a)}},zz:0}};PluginDetect.initScript();
9945
9946	var gArgCountErr='The "%%" function requires an even number of arguments.\nArguments should be in the form "atttributeName", "attributeValue", ...',gTagAttrs=null,gQTGeneratorVersion=1;function AC_QuickTimeVersion(){return gQTGeneratorVersion}function _QTComplain(a,b){b=b.replace("%%",a);alert(b)}function _QTAddAttribute(a,b,c){var d;d=gTagAttrs[a+b];null==d&&(d=gTagAttrs[b]);return null!=d?(0==b.indexOf(a)&&null==c&&(c=b.substring(a.length)),null==c&&(c=b),c+'="'+d+'" '):""}function _QTAddObjectAttr(a,b){if(0==a.indexOf("emb#"))return"";0==a.indexOf("obj#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("obj#",a,b)}function _QTAddEmbedAttr(a,b){if(0==a.indexOf("obj#"))return"";0==a.indexOf("emb#")&&null==b&&(b=a.substring(4));return _QTAddAttribute("emb#",a,b)}function _QTAddObjectParam(a,b){var c,d="",e=b?" />":">";-1==a.indexOf("emb#")&&(c=gTagAttrs["obj#"+a],null==c&&(c=gTagAttrs[a]),0==a.indexOf("obj#")&&(a=a.substring(4)),null!=c&&(d='  <param name="'+a+'" value="'+c+'"'+e+"\n"));return d}function _QTDeleteTagAttrs(){for(var a=0;a<arguments.length;a++){var b=arguments[a];delete gTagAttrs[b];delete gTagAttrs["emb#"+b];delete gTagAttrs["obj#"+b]}}function _QTGenerate(a,b,c){if(4>c.length||0!=c.length%2)return _QTComplain(a,gArgCountErr),"";gTagAttrs=[];gTagAttrs.src=c[0];gTagAttrs.width=c[1];gTagAttrs.height=c[2];gTagAttrs.classid="clsid:02BF25D5-8C17-4B23-BC80-D3488ABDDC6B";gTagAttrs.pluginspage="http://www.apple.com/quicktime/download/";a=c[3];if(null==a||""==a)a="6,0,2,0";gTagAttrs.codebase="http://www.apple.com/qtactivex/qtplugin.cab#version="+a;for(var d,e=4;e<c.length;e+=2)d=c[e].toLowerCase(),a=c[e+1],"name"==d||"id"==d?gTagAttrs.name=a:gTagAttrs[d]=a;c="<object "+_QTAddObjectAttr("classid")+_QTAddObjectAttr("width")+_QTAddObjectAttr("height")+_QTAddObjectAttr("codebase")+_QTAddObjectAttr("name","id")+_QTAddObjectAttr("tabindex")+_QTAddObjectAttr("hspace")+_QTAddObjectAttr("vspace")+_QTAddObjectAttr("border")+_QTAddObjectAttr("align")+_QTAddObjectAttr("class")+_QTAddObjectAttr("title")+_QTAddObjectAttr("accesskey")+_QTAddObjectAttr("noexternaldata")+">\n"+_QTAddObjectParam("src",b);e="  <embed "+_QTAddEmbedAttr("src")+_QTAddEmbedAttr("width")+_QTAddEmbedAttr("height")+_QTAddEmbedAttr("pluginspage")+_QTAddEmbedAttr("name")+_QTAddEmbedAttr("align")+_QTAddEmbedAttr("tabindex");_QTDeleteTagAttrs("src","width","height","pluginspage","classid","codebase","name","tabindex","hspace","vspace","border","align","noexternaldata","class","title","accesskey");for(d in gTagAttrs)a=gTagAttrs[d],null!=a&&(e+=_QTAddEmbedAttr(d),c+=_QTAddObjectParam(d,b));return c+e+"> </embed>\n</object>"}function QT_GenerateOBJECTText(){return _QTGenerate("QT_GenerateOBJECTText",!1,arguments)};
9947
9948
9949	/*
9950		jQuery hashchange event v1.3
9951		https://github.com/cowboy/jquery-hashchange
9952		Copyright (c) 2010 "Cowboy" Ben Alman
9953		Dual licensed under the MIT and GPL licenses.
9954	*/
9955	(function(){function e(a){a=a||location.href;return"#"+a.replace(/^[^#]*#?(.*)$/,"$1")}var k=document,b,f=$.event.special,p=k.documentMode,m="oniLightBoxHashChange"in window&&(void 0===p||7<p);$.fn.iLightBoxHashChange=function(a){return a?this.bind("iLightBoxHashChange",a):this.trigger("iLightBoxHashChange")};$.fn.iLightBoxHashChange.delay=50;f.iLightBoxHashChange=$.extend(f.iLightBoxHashChange,{setup:function(){if(m)return!1;$(b.start)},teardown:function(){if(m)return!1;$(b.stop)}});b=function(){function a(){var c=
9956	e(),d=f(l);c!==l?(n(l=c,d),$(window).trigger("iLightBoxHashChange")):d!==l&&(location.href=location.href.replace(/#.*/,"")+d);g=setTimeout(a,$.fn.iLightBoxHashChange.delay)}var h={},g,l=e(),b=function(c){return c},n=b,f=b;h.start=function(){g||a()};h.stop=function(){g&&clearTimeout(g);g=void 0};browser.msie&&!m&&function(){var c,d;h.start=function(){c||(d=(d=$.fn.iLightBoxHashChange.src)&&d+e(),c=$('<iframe tabindex="-1" title="empty"/>').hide().one("load",function(){d||n(e());a()}).attr("src",d||
9957	"javascript:0").insertAfter("body")[0].contentWindow,k.onpropertychange=function(){try{"title"===event.propertyName&&(c.document.title=k.title)}catch(a){}})};h.stop=b;f=function(){return e(c.location.href)};n=function(a,d){var b=c.document,e=$.fn.iLightBoxHashChange.domain;
9957a!==d&&(b.title=k.title,b.open(),e&&b.write('<script>document.domain="'+e+'"\x3c/script>'),b.close(),c.location.hash=a)}}();return h}()})();
9958
9959	if (!Array.prototype.filter) {
9960		Array.prototype.filter = function(fun /*, thisp */ ) {
9961			"use strict";
9962
9963			if (this == null)
9964				throw new TypeError();
9965
9966			var t = Object(this);
9967			var len = t.length >>> 0;
9968			if (typeof fun != "function")
9969				throw new TypeError();
9970
9971			var res = [];
9972			var thisp = arguments[1];
9973			for (var i = 0; i < len; i++) {
9974				if (i in t) {
9975					var val = t[i]; // in case fun mutates this
9976					if (fun.call(thisp, val, i, t))
9977						res.push(val);
9978				}
9979			}
9980
9981			return res;
9982		};
9983	}
9984
9985	if (!Array.prototype.indexOf) {
9986		Array.prototype.indexOf = function(searchElement, fromIndex) {
9987			var k;
9988
9989			if (this == null) {
9990				throw new TypeError('"this" is null or not defined');
9991			}
9992
9993			var O = Object(this);
9994
9995			var len = O.length >>> 0;
9996
9997			if (len === 0) {
9998				return -1;
9999			}
10000
10001			var n = +fromIndex || 0;
10002
10003			if (abs(n) === Infinity) {
10004				n = 0;
10005			}
10006
10007			if (n >= len) {
10008				return -1;
10009			}
10010
10011			k = max(n >= 0 ? n : len - abs(n), 0);
10012
10013			while (k < len) {
10014				var kValue;
10015				if (k in O && O[k] === searchElement) {
10016					return k;
10017				}
10018				k++;
10019			}
10020			return -1;
10021		};
10022	}
10023
10024	if (!Array.prototype.lastIndexOf) {
10025		Array.prototype.lastIndexOf = function(searchElement /*, fromIndex*/ ) {
10026			"use strict";
10027
10028			if (this == null)
10029				throw new TypeError();
10030
10031			var t = Object(this);
10032			var len = t.length >>> 0;
10033			if (len === 0)
10034				return -1;
10035
10036			var n = len;
10037			if (arguments.length > 1) {
10038				n = Number(arguments[1]);
10039				if (n != n)
10040					n = 0;
10041				else if (n != 0 && n != (1 / 0) && n != -(1 / 0))
10042					n = (n > 0 || -1) * floor(abs(n));
10043			}
10044
10045			var k = n >= 0 ? min(n, len - 1) : len - abs(n);
10046
10047			for (; k >= 0; k--) {
10048				if (k in t && t[k] === searchElement)
10049					return k;
10050			}
10051			return -1;
10052		};
10053	}
10054})(jQuery, this);
10055
10056
10057/**
10058 * Owl carousel
vendor: 25,822 bytes, lines 10059-11083
10059 * @version 2.0.0-beta.3
10060 * @author Bartosz Wojciechowski
10061 * @license The MIT License (MIT)
10062 * @todo Lazy Load Icon
10063 * @todo prevent animationend bubling
10064 * @todo itemsScaleUp
10065 * @todo Test Zepto
10066 * @todo stagePadding calculate wrong active classes
10067 */
10068;(function($, window, document, undefined) {
10069
10070	/**
10071	 * Creates a carousel.
10072	 * @class The Owl Carousel.
10073	 * @public
10074	 * @param {HTMLElement|jQuery} element - The element to create the carousel for.
10075	 * @param {Object} [options] - The options
10076	 */
10077	function Owl(element, options) {
10078
10079		/**
10080		 * Current settings for the carousel.
10081		 * @public
10082		 */
10083		this.settings = null;
10084
10085		/**
10086		 * Current options set by the caller including defaults.
10087		 * @public
10088		 */
10089		this.options = $.extend({}, Owl.Defaults, options);
10090
10091		/**
10092		 * Plugin element.
10093		 * @public
10094		 */
10095		this.$element = $(element);
10096
10097		/**
10098		 * Proxied event handlers.
10099		 * @protected
10100		 */
10101		this._handlers = {};
10102
10103		/**
10104		 * References to the running plugins of this carousel.
10105		 * @protected
10106		 */
10107		this._plugins = {};
10108
10109		/**
10110		 * Currently suppressed events to prevent them from beeing retriggered.
10111		 * @protected
10112		 */
10113		this._supress = {};
10114
10115		/**
10116		 * Absolute current position.
10117		 * @protected
10118		 */
10119		this._current = null;
10120
10121		/**
10122		 * Animation speed in milliseconds.
10123		 * @protected
10124		 */
10125		this._speed = null;
10126
10127		/**
10128		 * Coordinates of all items in pixel.
10129		 * @todo The name of this member is missleading.
10130		 * @protected
10131		 */
10132		this._coordinates = [];
10133
10134		/**
10135		 * Current breakpoint.
10136		 * @todo Real media queries would be nice.
10137		 * @protected
10138		 */
10139		this._breakpoint = null;
10140
10141		/**
10142		 * Current width of the plugin element.
10143		 */
10144		this._width = null;
10145
10146		/**
10147		 * All real items.
10148		 * @protected
10149		 */
10150		this._items = [];
10151
10152		/**
10153		 * All cloned items.
10154		 * @protected
10155		 */
10156		this._clones = [];
10157
10158		/**
10159		 * Merge values of all items.
10160		 * @todo Maybe this could be part of a plugin.
10161		 * @protected
10162		 */
10163		this._mergers = [];
10164
10165		/**
10166		 * Widths of all items.
10167		 */
10168		this._widths = [];
10169
10170		/**
10171		 * Invalidated parts within the update process.
10172		 * @protected
10173		 */
10174		this._invalidated = {};
10175
10176		/**
10177		 * Ordered list of workers for the update process.
10178		 * @protected
10179		 */
10180		this._pipe = [];
10181
10182		/**
10183		 * Current state information for the drag operation.
10184		 * @todo #261
10185		 * @protected
10186		 */
10187		this._drag = {
10188			time: null,
10189			target: null,
10190			pointer: null,
10191			stage: {
10192				start: null,
10193				current: null
10194			},
10195			direction: null
10196		};
10197
10198		/**
10199		 * Current state information and their tags.
10200		 * @type {Object}
10201		 * @protected
10202		 */
10203		this._states = {
10204			current: {},
10205			tags: {
10206				'initializing': [ 'busy' ],
10207				'animating': [ 'busy' ],
10208				'dragging': [ 'interacting' ]
10209			}
10210		};
10211
10212		$.each([ 'onResize', 'onThrottledResize' ], $.proxy(function(i, handler) {
10213			this._handlers[handler] = $.proxy(this[handler], this);
10214		}, this));
10215
10216		$.each(Owl.Plugins, $.proxy(function(key, plugin) {
10217			this._plugins[key.charAt(0).toLowerCase() + key.slice(1)]
10218				= new plugin(this);
10219		}, this));
10220
10221		$.each(Owl.Workers, $.proxy(function(priority, worker) {
10222			this._pipe.push({
10223				'filter': worker.filter,
10224				'run': $.proxy(worker.run, this)
10225			});
10226		}, this));
10227
10228		this.setup();
10229		this.initialize();
10230	}
10231
10232	/**
10233	 * Default options for the carousel.
10234	 * @public
10235	 */
10236	Owl.Defaults = {
10237		items: 3,
10238		loop: false,
10239		center: false,
10240		rewind: false,
10241
10242		mouseDrag: true,
10243		touchDrag: true,
10244		pullDrag: true,
10245		freeDrag: false,
10246
10247		margin: 0,
10248		stagePadding: 0,
10249
10250		merge: false,
10251		mergeFit: true,
10252		autoWidth: false,
10253
10254		startPosition: 0,
10255		rtl: false,
10256
10257		smartSpeed: 250,
10258		fluidSpeed: false,
10259		dragEndSpeed: false,
10260
10261		responsive: {},
10262		responsiveRefreshRate: 200,
10263		responsiveBaseElement: window,
10264
10265		fallbackEasing: 'swing',
10266
10267		info: false,
10268
10269		nestedItemSelector: false,
10270		itemElement: 'div',
10271		stageElement: 'div',
10272
10273		refreshClass: 'owl-refresh',
10274		loadedClass: 'owl-loaded',
10275		loadingClass: 'owl-loading',
10276		rtlClass: 'owl-rtl',
10277		responsiveClass: 'owl-responsive',
10278		dragClass: 'owl-drag',
10279		itemClass: 'owl-item',
10280		stageClass: 'owl-stage',
10281		stageOuterClass: 'owl-stage-outer',
10282		grabClass: 'owl-grab'
10283	};
10284
10285	/**
10286	 * Enumeration for width.
10287	 * @public
10288	 * @readonly
10289	 * @enum {String}
10290	 */
10291	Owl.Width = {
10292		Default: 'default',
10293		Inner: 'inner',
10294		Outer: 'outer'
10295	};
10296
10297	/**
10298	 * Enumeration for types.
10299	 * @public
10300	 * @readonly
10301	 * @enum {String}
10302	 */
10303	Owl.Type = {
10304		Event: 'event',
10305		State: 'state'
10306	};
10307
10308	/**
10309	 * Contains all registered plugins.
10310	 * @public
10311	 */
10312	Owl.Plugins = {};
10313
10314	/**
10315	 * List of workers involved in the update process.
10316	 */
10317	Owl.Workers = [ {
10318		filter: [ 'width', 'settings' ],
10319		run: function() {
10320			this._width = (this.$element.closest('.px-gutter').length) ? 12 * Math.ceil(this.$element.width() / 12) : this.$element.width();
10321			//this._width = (UNCODE.isMobile) ? this.$element.width() : 12 * Math.ceil(this.$element.width() / 12);
10322		}
10323	}, {
10324		filter: [ 'width', 'items', 'settings' ],
10325		run: function(cache) {
10326			cache.current = this._items && this._items[this.relative(this._current)];
10327		}
10328	}, {
10329		filter: [ 'items', 'settings' ],
10330		run: function() {
10331			this.$stage.children('.cloned').remove();
10332		}
10333	}, {
10334		filter: [ 'width', 'items', 'settings' ],
10335		run: function(cache) {
10336			var margin = this.settings.margin || '',
10337				grid = !this.settings.autoWidth,
10338				rtl = this.settings.rtl,
10339				css = {
10340					'width': 'auto',
10341					'margin-left': rtl ? margin : '',
10342					'margin-right': rtl ? '' : margin
10343				};
10344
10345			!grid && this.$stage.children().css(css);
10346
10347			cache.css = css;
10348		}
10349	}, {
10350		filter: [ 'width', 'items', 'settings' ],
10351		run: function(cache) {
10352			var width = (this.width() / this.settings.items).toFixed(3) - this.settings.margin,
10353				merge = null,
10354				iterator = this._items.length,
10355				grid = !this.settings.autoWidth,
10356				widths = [];
10357
10358			cache.items = {
10359				merge: false,
10360				width: width
10361			};
10362
10363			while (iterator--) {
10364				merge = this._mergers[iterator];
10365				merge = this.settings.mergeFit && Math.min(merge, this.settings.items) || merge;
10366
10367				cache.items.merge = merge > 1 || cache.items.merge;
10368
10369				widths[iterator] = !grid ? this._items[iterator].width() : width * merge;
10370			}
10371
10372			this._widths = widths;
10373		}
10374	}, {
10375		filter: [ 'items', 'settings' ],
10376		run: function() {
10377			var clones = [],
10378				items = this._items,
10379				settings = this.settings,
10380				view = Math.max(settings.items * 2, 4),
10381				size = Math.ceil(items.length / 2) * 2,
10382				repeat = settings.loop && items.length ? settings.rewind ? view : Math.max(view, size) : 0,
10383				append = '',
10384				prepend = '';
10385
10386			repeat /= 2;
10387
10388			while (repeat--) {
10389				clones.push(this.normalize(clones.length / 2, true));
10390				append = append + items[clones[clones.length - 1]][0].outerHTML;
10391				clones.push(this.normalize(items.length - 1 - (clones.length - 1) / 2, true));
10392				prepend = items[clones[clones.length - 1]][0].outerHTML + prepend;
10393			}
10394
10395			this._clones = clones;
10396
10397			// var appendVideo = $(append).find('.uncode-video-container');
10398			// if (appendVideo.length) {
10399			// 	appendVideo.attr('data-id', Math.round(Math.random() * 100000));
10400			// }
10401			// var prependVideo = $(prepend).find('.uncode-video-container');
10402			// if (prependVideo.length) {
10403			// 	prependVideo.attr('data-id', Math.round(Math.random() * 100000));
10404			// }
10405			$(append).addClass('cloned').appendTo(this.$stage);
10406			$(prepend).addClass('cloned').prependTo(this.$stage);
10407		}
10408	}, {
10409		filter: [ 'width', 'items', 'settings' ],
10410		run: function() {
10411			var rtl = this.settings.rtl ? 1 : -1,
10412				size = this._clones.length + this._items.length,
10413				iterator = -1,
10414				previous = 0,
10415				current = 0,
10416				coordinates = [];
10417
10418			while (++iterator < size) {
10419				previous = coordinates[iterator - 1] || 0;
10420				current = this._widths[this.relative(iterator)] + this.settings.margin;
10421				coordinates.push(previous + current * rtl);
10422			}
10423
10424			this._coordinates = coordinates;
10425		}
10426	}, {
10427		filter: [ 'width', 'items', 'settings' ],
10428		run: function() {
10429			var padding = this.settings.stagePadding,
10430				coordinates = this._coordinates,
10431				css = {
10432					'width': Math.ceil(Math.abs(coordinates[coordinates.length - 1])) + padding * 2,
10433					'padding-left': padding || '',
10434					'padding-right': padding || ''
10435				};
10436
10437			this.$stage.css(css);
10438		}
10439	}, {
10440		filter: [ 'width', 'items', 'settings' ],
10441		run: function(cache) {
10442			var iterator = this._coordinates.length,
10443				grid = !this.settings.autoWidth,
10444				items = this.$stage.children();
10445
10446			if (grid && cache.items.merge) {
10447				while (iterator--) {
10448					cache.css.width = this._widths[this.relative(iterator)];
10449					items.eq(iterator).css(cache.css);
10450				}
10451			} else if (grid) {
10452				cache.css.width = cache.items.width;
10453				items.css(cache.css);
10454			}
10455		}
10456	}, {
10457		filter: [ 'items' ],
10458		run: function() {
10459			this._coordinates.length < 1 && this.$stage.removeAttr('style');
10460		}
10461	}, {
10462		filter: [ 'width', 'items', 'settings' ],
10463		run: function(cache) {
10464			cache.current = cache.current ? this.$stage.children().index(cache.current) : 0;
10465			cache.current = Math.max(this.minimum(), Math.min(this.maximum(), cache.current));
10466			this.reset(cache.current);
10467		}
10468	}, {
10469		filter: [ 'position' ],
10470		run: function() {
10471			this.animate(this.coordinates(this._current));
10472		}
10473	}, {
10474		filter: [ 'width', 'position', 'items', 'settings' ],
10475		run: function() {
10476			var rtl = this.settings.rtl ? 1 : -1,
10477				padding = this.settings.stagePadding * 2,
10478				begin = this.coordinates(this.current()) + padding,
10479				end = begin + this.width() * rtl,
10480				inner, outer, matches = [], i, n;
10481
10482			for (i = 0, n = this._coordinates.length; i < n; i++) {
10483				inner = this._coordinates[i - 1] || 0;
10484				outer = Math.abs(this._coordinates[i]) + padding * rtl;
10485
10486				if ((this.op(inner, '<=', begin) && (this.op(inner, '>', end)))
10487					|| (this.op(outer, '<', begin) && this.op(outer, '>', end))) {
10488					matches.push(i);
10489				}
10490			}
10491
10492			this.$stage.children('.active').removeClass('active');
10493			this.$stage.children(':eq(' + matches.join('), :eq(') + ')').addClass('active');
10494
10495			if (this.settings.center) {
10496				this.$stage.children('.center').removeClass('center');
10497				this.$stage.children().eq(this.current()).addClass('center');
10498			}
10499		}
10500	} ];
10501
10502	/**
10503	 * Initializes the carousel.
10504	 * @protected
10505	 */
10506	Owl.prototype.initialize = function() {
10507		this.enter('initializing');
10508		this.trigger('initialize');
10509
10510		this.$element.toggleClass(this.settings.rtlClass, this.settings.rtl);
10511
10512		if (this.settings.autoWidth && !this.is('pre-loading')) {
10513			var imgs, nestedSelector, width;
10514			imgs = this.$element.find('img');
10515			nestedSelector = this.settings.nestedItemSelector ? '.' + this.settings.nestedItemSelector : undefined;
10516			width = this.$element.children(nestedSelector).width();
10517
10518			if (imgs.length && width <= 0) {
10519				this.preloadAutoWidthImages(imgs);
10520			}
10521		}
10522
10523		this.$element.addClass(this.options.loadingClass);
10524
10525		// create stage
10526		this.$stage = $('<' + this.settings.stageElement + ' class="' + this.settings.stageClass + '"/>')
10527			.wrap('<div class="' + this.settings.stageOuterClass + '"/>');
10528
10529		// append stage
10530		this.$element.append(this.$stage.parent());
10531
10532		// append content
10533		this.replace(this.$element.children().not(this.$stage.parent()));
10534
10535		// check visibility
10536		if (this.$element.is(':visible')) {
10537			// update view
10538			this.refresh();
10539		} else {
10540			// invalidate width
10541			this.invalidate('width');
10542		}
10543
10544		this.$element
10545			.removeClass(this.options.loadingClass)
10546			.addClass(this.options.loadedClass);
10547
10548		// register event handlers
10549		this.registerEventHandlers();
10550
10551		this.leave('initializing');
10552		this.trigger('initialized');
10553	};
10554
10555	/**
10556	 * Setups the current settings.
10557	 * @todo Remove responsive classes. Why should adaptive designs be brought into IE8?
10558	 * @todo Support for media queries by using `matchMedia` would be nice.
10559	 * @public
10560	 */
10561	Owl.prototype.setup = function() {
10562		var viewport = this.viewport(),
10563			overwrites = this.options.responsive,
10564			match = -1,
10565			settings = null;
10566
10567		if (!overwrites) {
10568			settings = $.extend({}, this.options);
10569		} else {
10570			$.each(overwrites, function(breakpoint) {
10571				if (breakpoint <= viewport && breakpoint > match) {
10572					match = Number(breakpoint);
10573				}
10574			});
10575
10576			settings = $.extend({}, this.options, overwrites[match]);
10577			delete settings.responsive;
10578
10579			// responsive class
10580			if (settings.responsiveClass) {
10581				this.$element.attr('class',
10582					this.$element.attr('class').replace(new RegExp('(' + this.options.responsiveClass + '-)\\S+\\s', 'g'), '$1' + match)
10583				);
10584			}
10585		}
10586
10587		if (this.settings === null || this._breakpoint !== match) {
10588			this.trigger('change', { property: { name: 'settings', value: settings } });
10589			this._breakpoint = match;
10590			this.settings = settings;
10591			this.invalidate('settings');
10592			this.trigger('changed', { property: { name: 'settings', value: this.settings } });
10593		}
10594	};
10595
10596	/**
10597	 * Updates option logic if necessery.
10598	 * @protected
10599	 */
10600	Owl.prototype.optionsLogic = function() {
10601		if (this.settings.autoWidth) {
10602			this.settings.stagePadding = false;
10603			this.settings.merge = false;
10604		}
10605	};
10606
10607	/**
10608	 * Prepares an item before add.
10609	 * @todo Rename event parameter `content` to `item`.
10610	 * @protected
10611	 * @returns {jQuery|HTMLElement} - The item container.
10612	 */
10613	Owl.prototype.prepare = function(item, index) {
10614		var event = this.trigger('prepare', { content: item });
10615		if (!event.data) {
10616			event.data = $('<' + this.settings.itemElement + '/>')
10617				.addClass(this.options.itemClass).attr('data-index', index + 1).append(item)
10618		}
10619
10620		this.trigger('prepared', { content: event.data });
10621
10622		return event.data;
10623	};
10624
10625	/**
10626	 * Updates the view.
10627	 * @public
10628	 */
10629	Owl.prototype.update = function() {
10630		var i = 0,
10631			n = this._pipe.length,
10632			filter = $.proxy(function(p) { return this[p] }, this._invalidated),
10633			cache = {};
10634
10635		while (i < n) {
10636			if (this._invalidated.all || $.grep(this._pipe[i].filter, filter).length > 0) {
10637				this._pipe[i].run(cache);
10638			}
10639			i++;
10640		}
10641
10642		this._invalidated = {};
10643
10644		!this.is('valid') && this.enter('valid');
10645	};
10646
10647	/**
10648	 * Gets the width of the view.
10649	 * @public
10650	 * @param {Owl.Width} [dimension=Owl.Width.Default] - The dimension to return.
10651	 * @returns {Number} - The width of the view in pixel.
10652	 */
10653	Owl.prototype.width = function(dimension) {
10654		dimension = dimension || Owl.Width.Default;
10655		switch (dimension) {
10656			case Owl.Width.Inner:
10657			case Owl.Width.Outer:
10658				return this._width;
10659			default:
10660				return this._width - this.settings.stagePadding * 2 + this.settings.margin;
10661		}
10662	};
10663
10664	/**
10665	 * Refreshes the carousel primarily for adaptive purposes.
10666	 * @public
10667	 */
10668	Owl.prototype.refresh = function() {
10669		this.enter('refreshing');
10670		this.trigger('refresh');
10671
10672		this.setup();
10673
10674		this.optionsLogic();
10675
10676		this.$element.addClass(this.options.refreshClass);
10677
10678		this.update();
10679
10680		this.$element.removeClass(this.options.refreshClass);
10681
10682		this.leave('refreshing');
10683		this.trigger('refreshed');
10684	};
10685
10686	/**
10687	 * Checks window `resize` event.
10688	 * @protected
10689	 */
10690	Owl.prototype.onThrottledResize = function() {
10691		window.clearTimeout(this.resizeTimer);
10692		this.resizeTimer = window.setTimeout(this._handlers.onResize, this.settings.responsiveRefreshRate);
10693	};
10694
10695	/**
10696	 * Checks window `resize` event.
10697	 * @protected
10698	 */
10699	Owl.prototype.onResize = function() {
10700		if (!this._items.length) {
10701			return false;
10702		}
10703
10704		if (this._width === this.$element.width()) {
10705			return false;
10706		}
10707
10708		if (!this.$element.is(':visible')) {
10709			return false;
10710		}
10711
10712		this.enter('resizing');
10713
10714		if (this.trigger('resize').isDefaultPrevented()) {
10715			this.leave('resizing');
10716			return false;
10717		}
10718
10719		this.invalidate('width');
10720
10721		this.refresh();
10722
10723		this.leave('resizing');
10724		this.trigger('resized');
10725	};
10726
10727	/**
10728	 * Registers event handlers.
10729	 * @todo Check `msPointerEnabled`
10730	 * @todo #261
10731	 * @protected
10732	 */
10733	Owl.prototype.registerEventHandlers = function() {
10734		if ($.support.transition) {
10735			this.$stage.on($.support.transition.end + '.owl.core', $.proxy(this.onTransitionEnd, this));
10736		}
10737
10738		if (this.settings.responsive !== false) {
10739			this.on(window, 'resize', this._handlers.onThrottledResize);
10740		}
10741
10742		if (this.settings.mouseDrag) {
10743			this.$element.addClass(this.options.dragClass);
10744			this.$stage.on('mousedown.owl.core', $.proxy(this.onDragStart, this));
10745			this.$stage.on('dragstart.owl.core selectstart.owl.core', function() { return false });
10746		}
10747
10748		if (this.settings.touchDrag){
10749			this.$stage.on('touchstart.owl.core', $.proxy(this.onDragStart, this));
10750			this.$stage.on('touchcancel.owl.core', $.proxy(this.onDragEnd, this));
10751		}
10752	};
10753
10754	/**
10755	 * Handles `touchstart` and `mousedown` events.
10756	 * @todo Horizontal swipe threshold as option
10757	 * @todo #261
10758	 * @protected
10759	 * @param {Event} event - The event arguments.
10760	 */
10761	Owl.prototype.onDragStart = function(event) {
10762		var stage = null;
10763
10764		if (event.which === 3) {
10765			return;
10766		}
10767
10768		if ($.support.transform) {
10769			stage = this.$stage.css('transform').replace(/.*\(|\)| /g, '').split(',');
10770			stage = {
10771				x: stage[stage.length === 16 ? 12 : 4],
10772				y: stage[stage.length === 16 ? 13 : 5]
10773			};
10774		} else {
10775			stage = this.$stage.position();
10776			stage = {
10777				x: this.settings.rtl ?
10778					stage.left + this.$stage.width() - this.width() + this.settings.margin :
10779					stage.left,
10780				y: stage.top
10781			};
10782		}
10783
10784		if (this.is('animating')) {
10785			$.support.transform ? this.animate(stage.x) : this.$stage.stop()
10786			this.invalidate('position');
10787		}
10788
10789		this.$element.toggleClass(this.options.grabClass, event.type === 'mousedown');
10790
10791		this.speed(0);
10792
10793		this._drag.time = new Date().getTime();
10794		this._drag.target = $(event.target);
10795		this._drag.stage.start = stage;
10796		this._drag.stage.current = stage;
10797		this._drag.pointer = this.pointer(event);
10798
10799		$(document).on('mouseup.owl.core touchend.owl.core', $.proxy(this.onDragEnd, this));
10800
10801		$(document).one('mousemove.owl.core touchmove.owl.core', $.proxy(function(event) {
10802			var delta = this.difference(this._drag.pointer, this.pointer(event));
10803
10804			$(document).on('mousemove.owl.core touchmove.owl.core', $.proxy(this.onDragMove, this));
10805
10806			if (Math.abs(delta.x) < Math.abs(delta.y) && this.is('valid')) {
10807				return;
10808			}
10809
10810			event.preventDefault();
10811
10812			this.enter('dragging');
10813			this.trigger('drag');
10814		}, this));
10815	};
10816
10817	/**
10818	 * Handles the `touchmove` and `mousemove` events.
10819	 * @todo #261
10820	 * @protected
10821	 * @param {Event} event - The event arguments.
10822	 */
10823	Owl.prototype.onDragMove = function(event) {
10824		var minimum = null,
10825			maximum = null,
10826			pull = null,
10827			delta = this.difference(this._drag.pointer, this.pointer(event)),
10828			stage = this.difference(this._drag.stage.start, delta);
10829
10830		if (!this.is('dragging')) {
10831			return;
10832		}
10833
10834		event.preventDefault();
10835
10836		if (this.settings.loop) {
10837			minimum = this.coordinates(this.minimum());
10838			maximum = this.coordinates(this.maximum() + 1) - minimum;
10839			stage.x = (((stage.x - minimum) % maximum + maximum) % maximum) + minimum;
10840		} else {
10841			minimum = this.settings.rtl ? this.coordinates(this.maximum()) : this.coordinates(this.minimum());
10842			maximum = this.settings.rtl ? this.coordinates(this.minimum()) : this.coordinates(this.maximum());
10843			pull = this.settings.pullDrag ? -1 * delta.x / 5 : 0;
10844			stage.x = Math.max(Math.min(stage.x, minimum + pull), maximum + pull);
10845		}
10846
10847		this._drag.stage.current = stage;
10848
10849		this.animate(stage.x);
10850	};
10851
10852	/**
10853	 * Handles the `touchend` and `mouseup` events.
10854	 * @todo #261
10855	 * @todo Threshold for click event
10856	 * @protected
10857	 * @param {Event} event - The event arguments.
10858	 */
10859	Owl.prototype.onDragEnd = function(event) {
10860		var delta = this.difference(this._drag.pointer, this.pointer(event)),
10861			stage = this._drag.stage.current,
10862			direction = delta.x > 0 ^ this.settings.rtl ? 'left' : 'right';
10863
10864		$(document).off('.owl.core');
10865
10866		this.$element.removeClass(this.options.grabClass);
10867
10868		if (delta.x !== 0 && this.is('dragging') || !this.is('valid')) {
10869			this.speed(this.settings.dragEndSpeed || this.settings.smartSpeed);
10870			this.current(this.closest(stage.x, delta.x !== 0 ? direction : this._drag.direction));
10871			this.invalidate('position');
10872			this.update();
10873
10874			this._drag.direction = direction;
10875
10876			if (Math.abs(delta.x) > 3 || new Date().getTime() - this._drag.time > 300) {
10877				this._drag.target.one('click.owl.core', function() { return false; });
10878			}
10879		}
10880
10881		if (!this.is('dragging')) {
10882			return;
10883		}
10884
10885		this.leave('dragging');
10886		this.trigger('dragged');
10887	};
10888
10889	/**
10890	 * Gets absolute position of the closest item for a coordinate.
10891	 * @todo Setting `freeDrag` makes `closest` not reusable. See #165.
10892	 * @protected
10893	 * @param {Number} coordinate - The coordinate in pixel.
10894	 * @param {String} direction - The direction to check for the closest item. Ether `left` or `right`.
10895	 * @return {Number} - The absolute position of the closest item.
10896	 */
10897	Owl.prototype.closest = function(coordinate, direction) {
10898		var position = -1,
10899			pull = 30,
10900			width = this.width(),
10901			coordinates = this.coordinates();
10902
10903		if (!this.settings.freeDrag) {
10904			// check closest item
10905			$.each(coordinates, $.proxy(function(index, value) {
10906				if (coordinate > value - pull && coordinate < value + pull) {
10907					position = index;
10908				} else if (this.op(coordinate, '<', value)
10909					&& this.op(coordinate, '>', coordinates[index + 1] || value - width)) {
10910					position = direction === 'left' ? index + 1 : index;
10911				}
10912				return position === -1;
10913			}, this));
10914		}
10915
10916		if (!this.settings.loop) {
10917			// non loop boundries
10918			if (this.op(coordinate, '>', coordinates[this.minimum()])) {
10919				position = coordinate = this.minimum();
10920			} else if (this.op(coordinate, '<', coordinates[this.maximum()])) {
10921				position = coordinate = this.maximum();
10922			}
10923		}
10924
10925		return position;
10926	};
10927
10928	/**
10929	 * Animates the stage.
10930	 * @todo #270
10931	 * @public
10932	 * @param {Number} coordinate - The coordinate in pixels.
10933	 */
10934	Owl.prototype.animate = function(coordinate) {
10935		var animate = this.speed() > 0;
10936
10937		this.is('animating') && this.onTransitionEnd();
10938
10939		if (animate) {
10940			this.enter('animating');
10941			this.trigger('translate');
10942		}
10943
10944		if ($.support.transform3d && $.support.transition) {
10945			this.$stage.css({
10946				transform: 'translate3d(' + coordinate + 'px,0px,0px)',
10947				transition: (this.speed() / 1000) + 's'
10948			});
10949		} else if (animate) {
10950			this.$stage.animate({
10951				left: coordinate + 'px'
10952			}, this.speed(), this.settings.fallbackEasing, $.proxy(this.onTransitionEnd, this));
10953		} else {
10954			this.$stage.css({
10955				left: coordinate + 'px'
10956			});
10957		}
10958	};
10959
10960	/**
10961	 * Checks whether the carousel is in a specific state or not.
10962	 * @param {String} state - The state to check.
10963	 * @returns {Boolean} - The flag which indicates if the carousel is busy.
10964	 */
10965	Owl.prototype.is = function(state) {
10966		return this._states.current[state] && this._states.current[state] > 0;
10967	};
10968
10969	/**
10970	 * Sets the absolute position of the current item.
10971	 * @public
10972	 * @param {Number} [position] - The new absolute position or nothing to leave it unchanged.
10973	 * @returns {Number} - The absolute position of the current item.
10974	 */
10975	Owl.prototype.current = function(position) {
10976		if (position === undefined) {
10977			return this._current;
10978		}
10979
10980		if (this._items.length === 0) {
10981			return undefined;
10982		}
10983
10984		position = this.normalize(position);
10985
10986		if (this._current !== position) {
10987			var event = this.trigger('change', { property: { name: 'position', value: position } });
10988
10989			if (event.data !== undefined) {
10990				position = this.normalize(event.data);
10991			}
10992
10993			this._current = position;
10994
10995			this.invalidate('position');
10996
10997			this.trigger('changed', { property: { name: 'position', value: this._current } });
10998		}
10999
11000		return this._current;
11001	};
11002
11003	/**
11004	 * Invalidates the given part of the update routine.
11005	 * @param {String} [part] - The part to invalidate.
11006	 * @returns {Array.<String>} - The invalidated parts.
11007	 */
11008	Owl.prototype.invalidate = function(part) {
11009		if ($.type(part) === 'string') {
11010			this._invalidated[part] = true;
11011			this.is('valid') && this.leave('valid');
11012		}
11013		return $.map(this._invalidated, function(v, i) { return i });
11014	};
11015
11016	/**
11017	 * Resets the absolute position of the current item.
11018	 * @public
11019	 * @param {Number} position - The absolute position of the new item.
11020	 */
11021	Owl.prototype.reset = function(position) {
11022		position = this.normalize(position);
11023
11024		if (position === undefined) {
11025			return;
11026		}
11027
11028		this._speed = 0;
11029		this._current = position;
11030
11031		this.suppress([ 'translate', 'translated' ]);
11032
11033		this.animate(this.coordinates(position));
11034
11035		this.release([ 'translate', 'translated' ]);
11036	};
11037
11038	/**
11039	 * Normalizes an absolute or a relative position of an item.
11040	 * @public
11041	 * @param {Number} position - The absolute or relative position to normalize.
11042	 * @param {Boolean} [relative=false] - Whether the given position is relative or not.
11043	 * @returns {Number} - The normalized position.
11044	 */
11045	Owl.prototype.normalize = function(position, relative) {
11046		var n = this._items.length,
11047			m = relative ? 0 : this._clones.length;
11048
11049		if (!$.isNumeric(position) || n < 1) {
11050			position = undefined;
11051		} else if (position < 0 || position >= n + m) {
11052			position = ((position - m / 2) % n + n) % n + m / 2;
11053		}
11054
11055		return position;
11056	};
11057
11058	/**
11059	 * Converts an absolute position of an item into a relative one.
11060	 * @public
11061	 * @param {Number} position - The absolute position to convert.
11062	 * @returns {Number} - The converted position.
11063	 */
11064	Owl.prototype.relative = function(position) {
11065		position -= this._clones.length / 2;
11066		return this.normalize(position, true);
11067	};
11068
11069	/**
11070	 * Gets the maximum position for the current item.
11071	 * @public
11072	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
11073	 * @returns {Number}
11074	 */
11075	Owl.prototype.maximum = function(relative) {
11076		var settings = this.settings,
11077			maximum = this._coordinates.length,
11078			boundary = Math.abs(this._coordinates[maximum - 1]) - this._width,
11079			i = -1, j;
11080
11081		if (settings.loop) {
11082			maximum = this._clones.length / 2 + this._items.length - 1;
11083		} else if (settings.autoWidth || settings.merge) {
11084			// binary search
11085			while (maximum - i > 1) {
11086				Math.abs(this._coordinates[j = maximum + i >> 1]) < boundary
11087					? i = j : maximum = j;
11088			}
11089		} else if (settings.center) {
11090			maximum = this._items.length - 1;
11091		} else {
11092			maximum = this._items.length - settings.items;
11093		}
11094
11095		if (relative) {
11096			maximum -= this._clones.length / 2;
11097		}
11098
11099		return Math.max(maximum, 0);
11100	};
11101
11102	/**
11103	 * Gets the minimum position for the current item.
11104	 * @public
11105	 * @param {Boolean} [relative=false] - Whether to return an absolute position or a relative position.
11106	 * @returns {Number}
11107	 */
11108	Owl.prototype.minimum = function(relative) {
11109		return relative ? 0 : this._clones.length / 2;
11110	};
11111
11112	/**
11113	 * Gets an item at the specified relative position.
11114	 * @public
11115	 * @param {Number} [position] - The relative position of the item.
11116	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
11117	 */
11118	Owl.prototype.items = function(position) {
11119		if (position === undefined) {
11120			return this._items.slice();
11121		}
11122
11123		position = this.normalize(position, true);
11124		return this._items[position];
11125	};
11126
11127	/**
11128	 * Gets an item at the specified relative position.
11129	 * @public
11130	 * @param {Number} [position] - The relative position of the item.
11131	 * @return {jQuery|Array.<jQuery>} - The item at the given position or all items if no position was given.
11132	 */
11133	Owl.prototype.mergers = function(position) {
11134		if (position === undefined) {
11135			return this._mergers.slice();
11136		}
11137
11138		position = this.normalize(position, true);
11139		return this._mergers[position];
11140	};
11141
11142	/**
11143	 * Gets the absolute positions of clones for an item.
11144	 * @public
11145	 * @param {Number} [position] - The relative position of the item.
11146	 * @returns {Array.<Number>} - The absolute positions of clones for the item or all if no position was given.
11147	 */
11148	Owl.prototype.clones = function(position) {
11149		var odd = this._clones.length / 2,
11150			even = odd + this._items.length,
11151			map = function(index) { return index % 2 === 0 ? even + index / 2 : odd - (index + 1) / 2 };
11152
11153		if (position === undefined) {
11154			return $.map(this._clones, function(v, i) { return map(i) });
11155		}
11156
11157		return $.map(this._clones, function(v, i) { return v === position ? map(i) : null });
11158	};
11159
11160	/**
11161	 * Sets the current animation speed.
11162	 * @public
11163	 * @param {Number} [speed] - The animation speed in milliseconds or nothing to leave it unchanged.
11164	 * @returns {Number} - The current animation speed in milliseconds.
11165	 */
11166	Owl.prototype.speed = function(speed) {
11167		if (speed !== undefined) {
11168			this._speed = speed;
11169		}
11170
11171		return this._speed;
11172	};
11173
11174	/**
11175	 * Gets the coordinate of an item.
11176	 * @todo The name of this method is missleanding.
11177	 * @public
11178	 * @param {Number} position - The absolute position of the item within `minimum()` and `maximum()`.
11179	 * @returns {Number|Array.<Number>} - The coordinate of the item in pixel or all coordinates.
11180	 */
11181	Owl.prototype.coordinates = function(position) {
11182		var coordinate = null;
11183
11184		if (position === undefined) {
11185			return $.map(this._coordinates, $.proxy(function(coordinate, index) {
11186				return this.coordinates(index);
11187			}, this));
11188		}
11189
11190		if (this.settings.center) {
11191			coordinate = this._coordinates[position];
11192			coordinate += (this.width() - coordinate + (this._coordinates[position - 1] || 0)) / 2 * (this.settings.rtl ? -1 : 1);
11193		} else {
11194			coordinate = this._coordinates[position - 1] || 0;
11195		}
11196
11197		return coordinate;
11198	};
11199
11200	/**
11201	 * Calculates the speed for a translation.
11202	 * @protected
11203	 * @param {Number} from - The absolute position of the start item.
11204	 * @param {Number} to - The absolute position of the target item.
11205	 * @param {Number} [factor=undefined] - The time factor in milliseconds.
11206	 * @returns {Number} - The time in milliseconds for the translation.
11207	 */
11208	Owl.prototype.duration = function(from, to, factor) {
11209		return Math.min(Math.max(Math.abs(to - from), 1), 6) * Math.abs((factor || this.settings.smartSpeed));
11210	};
11211
11212	/**
11213	 * Slides to the specified item.
11214	 * @public
11215	 * @param {Number} position - The position of the item.
11216	 * @param {Number} [speed] - The time in milliseconds for the transition.
11217	 */
11218	Owl.prototype.to = function(position, speed) {
11219		var current = this.current(),
11220			revert = null,
11221			distance = position - this.relative(current),
11222			direction = (distance > 0) - (distance < 0),
11223			items = this._items.length,
11224			minimum = this.minimum(),
11225			maximum = this.maximum();
11226
11227		if (this.settings.loop) {
11228			if (!this.settings.rewind && Math.abs(distance) > items / 2) {
11229				distance += direction * -1 * items;
11230			}
11231
11232			position = current + distance;
11233			revert = ((position - minimum) % items + items) % items + minimum;
11234
11235			if (revert !== position && revert - distance <= maximum && revert - distance > 0) {
11236				current = revert - distance;
11237				position = revert;
11238				this.reset(current);
11239			}
11240		} else if (this.settings.rewind) {
11241			maximum += 1;
11242			position = (position % maximum + maximum) % maximum;
11243		} else {
11244			position = Math.max(minimum, Math.min(maximum, position));
11245		}
11246
11247		this.speed(this.duration(current, position, speed));
11248		this.current(position);
11249
11250		if (this.$element.is(':visible')) {
11251			this.update();
11252		}
11253	};
11254
11255	/**
11256	 * Slides to the next item.
11257	 * @public
11258	 * @param {Number}
vendor: 12,284 bytes, lines 11258-11678
11258 [speed] - The time in milliseconds for the transition.
11259	 */
11260	Owl.prototype.next = function(speed) {
11261		speed = speed || false;
11262		this.to(this.relative(this.current()) + 1, speed);
11263	};
11264
11265	/**
11266	 * Slides to the previous item.
11267	 * @public
11268	 * @param {Number} [speed] - The time in milliseconds for the transition.
11269	 */
11270	Owl.prototype.prev = function(speed) {
11271		speed = speed || false;
11272		this.to(this.relative(this.current()) - 1, speed);
11273	};
11274
11275	/**
11276	 * Handles the end of an animation.
11277	 * @protected
11278	 * @param {Event} event - The event arguments.
11279	 */
11280	Owl.prototype.onTransitionEnd = function(event) {
11281
11282		// if css2 animation then event object is undefined
11283		if (event !== undefined) {
11284			event.stopPropagation();
11285
11286			// Catch only owl-stage transitionEnd event
11287			if ((event.target || event.srcElement || event.originalTarget) !== this.$stage.get(0)) {
11288				return false;
11289			}
11290		}
11291
11292		this.leave('animating');
11293		this.trigger('translated');
11294	};
11295
11296	/**
11297	 * Gets viewport width.
11298	 * @protected
11299	 * @return {Number} - The width in pixel.
11300	 */
11301	Owl.prototype.viewport = function() {
11302		var width;
11303		if (this.options.responsiveBaseElement !== window) {
11304			width = $(this.options.responsiveBaseElement).width();
11305		} else if (window.innerWidth) {
11306			width = window.innerWidth;
11307		} else if (document.documentElement && document.documentElement.clientWidth) {
11308			width = document.documentElement.clientWidth;
11309		} else {
11310			throw 'Can not detect viewport width.';
11311		}
11312
11313		return width;
11314	};
11315
11316	/**
11317	 * Replaces the current content.
11318	 * @public
11319	 * @param {HTMLElement|jQuery|String} content - The new content.
11320	 */
11321	Owl.prototype.replace = function(content) {
11322		this.$stage.empty();
11323		this._items = [];
11324
11325		if (content) {
11326			content = (content instanceof jQuery) ? content : $(content);
11327		}
11328
11329		if (this.settings.nestedItemSelector) {
11330			content = content.find('.' + this.settings.nestedItemSelector);
11331		}
11332
11333		content.filter(function() {
11334			return this.nodeType === 1;
11335		}).each($.proxy(function(index, item) {
11336			item = this.prepare(item, index);
11337			this.$stage.append(item);
11338			this._items.push(item);
11339			this._mergers.push(item.find('[data-merge]').addBack('[data-merge]').attr('data-merge') * 1 || 1);
11340		}, this));
11341
11342		this.reset($.isNumeric(this.settings.startPosition) ? this.settings.startPosition : 0);
11343
11344		this.invalidate('items');
11345	};
11346
11347	/**
11348	 * Adds an item.
11349	 * @todo Use `item` instead of `content` for the event arguments.
11350	 * @public
11351	 * @param {HTMLElement|jQuery|String} content - The item content to add.
11352	 * @param {Number} [position] - The relative position at which to insert the item otherwise the item will be added to the end.
11353	 */
11354	Owl.prototype.add = function(content, position) {
11355		var current = this.relative(this._current);
11356
11357		position = position === undefined ? this._items.length : this.normalize(position, true);
11358		content = content instanceof jQuery ? content : $(content);
11359
11360		this.trigger('add', { content: content, position: position });
11361
11362		content = this.prepare(content, this._items[current].index());
11363
11364		if (this._items.length === 0 || position === this._items.length) {
11365			this._items.length === 0 && this.$stage.append(content);
11366			this._items.length !== 0 && this._items[position - 1].after(content);
11367			this._items.push(content);
11368			this._mergers.push(content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
11369		} else {
11370			this._items[position].before(content);
11371			this._items.splice(position, 0, content);
11372			this._mergers.splice(position, 0, content.find('[data-merge]').andSelf('[data-merge]').attr('data-merge') * 1 || 1);
11373		}
11374
11375		this._items[current] && this.reset(this._items[current].index());
11376
11377		this.invalidate('items');
11378
11379		this.trigger('added', { content: content, position: position });
11380	};
11381
11382	/**
11383	 * Removes an item by its position.
11384	 * @todo Use `item` instead of `content` for the event arguments.
11385	 * @public
11386	 * @param {Number} position - The relative position of the item to remove.
11387	 */
11388	Owl.prototype.remove = function(position) {
11389		position = this.normalize(position, true);
11390
11391		if (position === undefined) {
11392			return;
11393		}
11394
11395		this.trigger('remove', { content: this._items[position], position: position });
11396
11397		this._items[position].remove();
11398		this._items.splice(position, 1);
11399		this._mergers.splice(position, 1);
11400
11401		this.invalidate('items');
11402
11403		this.trigger('removed', { content: null, position: position });
11404	};
11405
11406	/**
11407	 * Preloads images with auto width.
11408	 * @todo Replace by a more generic approach
11409	 * @protected
11410	 */
11411	Owl.prototype.preloadAutoWidthImages = function(images) {
11412		images.each($.proxy(function(i, element) {
11413			this.enter('pre-loading');
11414			element = $(element);
11415			$(new Image()).one('load', $.proxy(function(e) {
11416				element.attr('src', e.target.src);
11417				element.css('opacity', 1);
11418				this.leave('pre-loading');
11419				!this.is('pre-loading') && !this.is('initializing') && this.refresh();
11420			}, this)).attr('src', element.attr('src') || element.attr('data-src') || element.attr('data-src-retina'));
11421		}, this));
11422	};
11423
11424	/**
11425	 * Destroys the carousel.
11426	 * @public
11427	 */
11428	Owl.prototype.destroy = function() {
11429
11430		this.$element.off('.owl.core');
11431		this.$stage.off('.owl.core');
11432		$(document).off('.owl.core');
11433
11434		if (this.settings.responsive !== false) {
11435			window.clearTimeout(this.resizeTimer);
11436			this.off(window, 'resize', this._handlers.onThrottledResize);
11437		}
11438
11439		for (var i in this._plugins) {
11440			this._plugins[i].destroy();
11441		}
11442
11443		this.$stage.children('.cloned').remove();
11444
11445		this.$stage.unwrap();
11446		this.$stage.children().contents().unwrap();
11447		this.$stage.children().unwrap();
11448
11449		this.$element
11450			.removeClass(this.options.refreshClass)
11451			.removeClass(this.options.loadingClass)
11452			.removeClass(this.options.loadedClass)
11453			.removeClass(this.options.rtlClass)
11454			.removeClass(this.options.dragClass)
11455			.removeClass(this.options.grabClass)
11456			.attr('class', this.$element.attr('class').replace(new RegExp(this.options.responsiveClass + '-\\S+\\s', 'g'), ''))
11457			.removeData('owl.carousel');
11458	};
11459
11460	/**
11461	 * Operators to calculate right-to-left and left-to-right.
11462	 * @protected
11463	 * @param {Number} [a] - The left side operand.
11464	 * @param {String} [o] - The operator.
11465	 * @param {Number} [b] - The right side operand.
11466	 */
11467	Owl.prototype.op = function(a, o, b) {
11468		var rtl = this.settings.rtl;
11469		switch (o) {
11470			case '<':
11471				return rtl ? a > b : a < b;
11472			case '>':
11473				return rtl ? a < b : a > b;
11474			case '>=':
11475				return rtl ? a <= b : a >= b;
11476			case '<=':
11477				return rtl ? a >= b : a <= b;
11478			default:
11479				break;
11480		}
11481	};
11482
11483	/**
11484	 * Attaches to an internal event.
11485	 * @protected
11486	 * @param {HTMLElement} element - The event source.
11487	 * @param {String} event - The event name.
11488	 * @param {Function} listener - The event handler to attach.
11489	 * @param {Boolean} capture - Wether the event should be handled at the capturing phase or not.
11490	 */
11491	Owl.prototype.on = function(element, event, listener, capture) {
11492		if (element.addEventListener) {
11493			element.addEventListener(event, listener, capture);
11494		} else if (element.attachEvent) {
11495			element.attachEvent('on' + event, listener);
11496		}
11497	};
11498
11499	/**
11500	 * Detaches from an internal event.
11501	 * @protected
11502	 * @param {HTMLElement} element - The event source.
11503	 * @param {String} event - The event name.
11504	 * @param {Function} listener - The attached event handler to detach.
11505	 * @param {Boolean} capture - Wether the attached event handler was registered as a capturing listener or not.
11506	 */
11507	Owl.prototype.off = function(element, event, listener, capture) {
11508		if (element.removeEventListener) {
11509			element.removeEventListener(event, listener, capture);
11510		} else if (element.detachEvent) {
11511			element.detachEvent('on' + event, listener);
11512		}
11513	};
11514
11515	/**
11516	 * Triggers a public event.
11517	 * @todo Remove `status`, `relatedTarget` should be used instead.
11518	 * @protected
11519	 * @param {String} name - The event name.
11520	 * @param {*} [data=null] - The event data.
11521	 * @param {String} [namespace=carousel] - The event namespace.
11522	 * @param {String} [state] - The state which is associated with the event.
11523	 * @param {Boolean} [enter=false] - Indicates if the call enters the specified state or not.
11524	 * @returns {Event} - The event arguments.
11525	 */
11526	Owl.prototype.trigger = function(name, data, namespace, state, enter) {
11527		var status = {
11528			item: { count: this._items.length, index: this.current() }
11529		}, handler = $.camelCase(
11530			$.grep([ 'on', name, namespace ], function(v) { return v })
11531				.join('-').toLowerCase()
11532		), event = $.Event(
11533			[ name, 'owl', namespace || 'carousel' ].join('.').toLowerCase(),
11534			$.extend({ relatedTarget: this }, status, data)
11535		);
11536
11537		if (!this._supress[name]) {
11538			$.each(this._plugins, function(name, plugin) {
11539				if (plugin.onTrigger) {
11540					plugin.onTrigger(event);
11541				}
11542			});
11543
11544			this.register({ type: Owl.Type.Event, name: name });
11545			this.$element.trigger(event);
11546
11547			if (this.settings && typeof this.settings[handler] === 'function') {
11548				this.settings[handler].call(this, event);
11549			}
11550		}
11551
11552		return event;
11553	};
11554
11555	/**
11556	 * Enters a state.
11557	 * @param name - The state name.
11558	 */
11559	Owl.prototype.enter = function(name) {
11560		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
11561			if (this._states.current[name] === undefined) {
11562				this._states.current[name] = 0;
11563			}
11564
11565			this._states.current[name]++;
11566		}, this));
11567	};
11568
11569	/**
11570	 * Leaves a state.
11571	 * @param name - The state name.
11572	 */
11573	Owl.prototype.leave = function(name) {
11574		$.each([ name ].concat(this._states.tags[name] || []), $.proxy(function(i, name) {
11575			this._states.current[name]--;
11576		}, this));
11577	};
11578
11579	/**
11580	 * Registers an event or state.
11581	 * @public
11582	 * @param {Object} object - The event or state to register.
11583	 */
11584	Owl.prototype.register = function(object) {
11585		if (object.type === Owl.Type.Event) {
11586			if (!$.event.special[object.name]) {
11587				$.event.special[object.name] = {};
11588			}
11589
11590			if (!$.event.special[object.name].owl) {
11591				var _default = $.event.special[object.name]._default;
11592				$.event.special[object.name]._default = function(e) {
11593					if (_default && _default.apply && (!e.namespace || e.namespace.indexOf('owl') === -1)) {
11594						return _default.apply(this, arguments);
11595					}
11596					return e.namespace && e.namespace.indexOf('owl') > -1;
11597				};
11598				$.event.special[object.name].owl = true;
11599			}
11600		} else if (object.type === Owl.Type.State) {
11601			if (!this._states.tags[object.name]) {
11602				this._states.tags[object.name] = object.tags;
11603			} else {
11604				this._states.tags[object.name] = this._states.tags[object.name].concat(object.tags);
11605			}
11606
11607			this._states.tags[object.name] = $.grep(this._states.tags[object.name], $.proxy(function(tag, i) {
11608				return $.inArray(tag, this._states.tags[object.name]) === i;
11609			}, this));
11610		}
11611	};
11612
11613	/**
11614	 * Suppresses events.
11615	 * @protected
11616	 * @param {Array.<String>} events - The events to suppress.
11617	 */
11618	Owl.prototype.suppress = function(events) {
11619		$.each(events, $.proxy(function(index, event) {
11620			this._supress[event] = true;
11621		}, this));
11622	};
11623
11624	/**
11625	 * Releases suppressed events.
11626	 * @protected
11627	 * @param {Array.<String>} events - The events to release.
11628	 */
11629	Owl.prototype.release = function(events) {
11630		$.each(events, $.proxy(function(index, event) {
11631			delete this._supress[event];
11632		}, this));
11633	};
11634
11635	/**
11636	 * Gets unified pointer coordinates from event.
11637	 * @todo #261
11638	 * @protected
11639	 * @param {Event} - The `mousedown` or `touchstart` event.
11640	 * @returns {Object} - Contains `x` and `y` coordinates of current pointer position.
11641	 */
11642	Owl.prototype.pointer = function(event) {
11643		var result = { x: null, y: null };
11644
11645		event = event.originalEvent || event || window.event;
11646
11647		event = event.touches && event.touches.length ?
11648			event.touches[0] : event.changedTouches && event.changedTouches.length ?
11649				event.changedTouches[0] : event;
11650
11651		if (event.pageX) {
11652			result.x = event.pageX;
11653			result.y = event.pageY;
11654		} else {
11655			result.x = event.clientX;
11656			result.y = event.clientY;
11657		}
11658
11659		return result;
11660	};
11661
11662	/**
11663	 * Gets the difference of two vectors.
11664	 * @todo #261
11665	 * @protected
11666	 * @param {Object} - The first vector.
11667	 * @param {Object} - The second vector.
11668	 * @returns {Object} - The difference.
11669	 */
11670	Owl.prototype.difference = function(first, second) {
11671		return {
11672			x: first.x - second.x,
11673			y: first.y - second.y
11674		};
11675	};
11676
11677	/**
11678	 * The jQuery Plugin for the Owl Carousel
vendor: 32,236 bytes, lines 11679-12961
11679	 * @todo Navigation plugin `next` and `prev`
11680	 * @public
11681	 */
11682	$.fn.owlCarousel = function(option) {
11683		var args = Array.prototype.slice.call(arguments, 1);
11684
11685		return this.each(function() {
11686			var $this = $(this),
11687				data = $this.data('owl.carousel');
11688
11689			if (!data) {
11690				data = new Owl(this, typeof option == 'object' && option);
11691				$this.data('owl.carousel', data);
11692
11693				$.each([
11694					'next', 'prev', 'to', 'destroy', 'refresh', 'replace', 'add', 'remove'
11695				], function(i, event) {
11696					data.register({ type: Owl.Type.Event, name: event });
11697					data.$element.on(event + '.owl.carousel.core', $.proxy(function(e) {
11698						if (e.namespace && e.relatedTarget !== this) {
11699							this.suppress([ event ]);
11700							data[event].apply(this, [].slice.call(arguments, 1));
11701							this.release([ event ]);
11702						}
11703					}, data));
11704				});
11705			}
11706
11707			if (typeof option == 'string' && option.charAt(0) !== '_') {
11708				data[option].apply(data, args);
11709			}
11710		});
11711	};
11712
11713	/**
11714	 * The constructor for the jQuery Plugin
11715	 * @public
11716	 */
11717	$.fn.owlCarousel.Constructor = Owl;
11718
11719})(window.Zepto || window.jQuery, window, document);
11720
11721/**
11722 * AutoRefresh Plugin
11723 * @version 2.0.0-beta.3
11724 * @author Artus Kolanowski
11725 * @license The MIT License (MIT)
11726 */
11727;(function($, window, document, undefined) {
11728
11729	/**
11730	 * Creates the auto refresh plugin.
11731	 * @class The Auto Refresh Plugin
11732	 * @param {Owl} carousel - The Owl Carousel
11733	 */
11734	var AutoRefresh = function(carousel) {
11735		/**
11736		 * Reference to the core.
11737		 * @protected
11738		 * @type {Owl}
11739		 */
11740		this._core = carousel;
11741
11742		/**
11743		 * Refresh interval.
11744		 * @protected
11745		 * @type {number}
11746		 */
11747		this._interval = null;
11748
11749		/**
11750		 * Whether the element is currently visible or not.
11751		 * @protected
11752		 * @type {Boolean}
11753		 */
11754		this._visible = null;
11755
11756		/**
11757		 * All event handlers.
11758		 * @protected
11759		 * @type {Object}
11760		 */
11761		this._handlers = {
11762			'initialized.owl.carousel': $.proxy(function(e) {
11763				if (e.namespace && this._core.settings.autoRefresh) {
11764					this.watch();
11765				}
11766			}, this)
11767		};
11768
11769		// set default options
11770		this._core.options = $.extend({}, AutoRefresh.Defaults, this._core.options);
11771
11772		// register event handlers
11773		this._core.$element.on(this._handlers);
11774	};
11775
11776	/**
11777	 * Default options.
11778	 * @public
11779	 */
11780	AutoRefresh.Defaults = {
11781		autoRefresh: true,
11782		autoRefreshInterval: 500
11783	};
11784
11785	/**
11786	 * Watches the element.
11787	 */
11788	AutoRefresh.prototype.watch = function() {
11789		if (this._interval) {
11790			return;
11791		}
11792
11793		this._visible = this._core.$element.is(':visible');
11794		this._interval = window.setInterval($.proxy(this.refresh, this), this._core.settings.autoRefreshInterval);
11795	};
11796
11797	/**
11798	 * Refreshes the element.
11799	 */
11800	AutoRefresh.prototype.refresh = function() {
11801		if (this._core.$element.is(':visible') === this._visible) {
11802			return;
11803		}
11804
11805		this._visible = !this._visible;
11806
11807		this._core.$element.toggleClass('owl-hidden', !this._visible);
11808
11809		this._visible && (this._core.invalidate('width') && this._core.refresh());
11810	};
11811
11812	/**
11813	 * Destroys the plugin.
11814	 */
11815	AutoRefresh.prototype.destroy = function() {
11816		var handler, property;
11817
11818		window.clearInterval(this._interval);
11819
11820		for (handler in this._handlers) {
11821			this._core.$element.off(handler, this._handlers[handler]);
11822		}
11823		for (property in Object.getOwnPropertyNames(this)) {
11824			typeof this[property] != 'function' && (this[property] = null);
11825		}
11826	};
11827
11828	$.fn.owlCarousel.Constructor.Plugins.AutoRefresh = AutoRefresh;
11829
11830})(window.Zepto || window.jQuery, window, document);
11831
11832/**
11833 * Lazy Plugin
11834 * @version 2.0.0-beta.3
11835 * @author Bartosz Wojciechowski
11836 * @license The MIT License (MIT)
11837 */
11838;(function($, window, document, undefined) {
11839
11840	/**
11841	 * Creates the lazy plugin.
11842	 * @class The Lazy Plugin
11843	 * @param {Owl} carousel - The Owl Carousel
11844	 */
11845	var Lazy = function(carousel) {
11846
11847		/**
11848		 * Reference to the core.
11849		 * @protected
11850		 * @type {Owl}
11851		 */
11852		this._core = carousel;
11853
11854		/**
11855		 * Already loaded items.
11856		 * @protected
11857		 * @type {Array.<jQuery>}
11858		 */
11859		this._loaded = [];
11860
11861		/**
11862		 * Event handlers.
11863		 * @protected
11864		 * @type {Object}
11865		 */
11866		this._handlers = {
11867			'initialized.owl.carousel change.owl.carousel': $.proxy(function(e) {
11868				if (!e.namespace) {
11869					return;
11870				}
11871
11872				if (!this._core.settings || !this._core.settings.lazyLoad) {
11873					return;
11874				}
11875
11876				if ((e.property && e.property.name == 'position') || e.type == 'initialized') {
11877					var settings = this._core.settings,
11878						n = (settings.center && Math.ceil(settings.items / 2) || settings.items),
11879						i = ((settings.center && n * -1) || 0),
11880						position = ((e.property && e.property.value) || this._core.current()) + i,
11881						clones = this._core.clones().length,
11882						load = $.proxy(function(i, v) { this.load(v) }, this);
11883
11884					while (i++ < n) {
11885						this.load(clones / 2 + this._core.relative(position));
11886						clones && $.each(this._core.clones(this._core.relative(position)), load);
11887						position++;
11888					}
11889				}
11890			}, this)
11891		};
11892
11893		// set the default options
11894		this._core.options = $.extend({}, Lazy.Defaults, this._core.options);
11895
11896		// register event handler
11897		this._core.$element.on(this._handlers);
11898	}
11899
11900	/**
11901	 * Default options.
11902	 * @public
11903	 */
11904	Lazy.Defaults = {
11905		lazyLoad: false
11906	}
11907
11908	/**
11909	 * Loads all resources of an item at the specified position.
11910	 * @param {Number} position - The absolute position of the item.
11911	 * @protected
11912	 */
11913	Lazy.prototype.load = function(position) {
11914		var $item = this._core.$stage.children().eq(position),
11915			$elements = $item && $item.find('.owl-lazy');
11916
11917		if (!$elements || $.inArray($item.get(0), this._loaded) > -1) {
11918			return;
11919		}
11920
11921		$elements.each($.proxy(function(index, element) {
11922			var $element = $(element), image,
11923				url = (window.devicePixelRatio > 1 && $element.attr('data-src-retina')) || $element.attr('data-src');
11924
11925			this._core.trigger('load', { element: $element, url: url }, 'lazy');
11926
11927			if ($element.is('img')) {
11928				$element.one('load.owl.lazy', $.proxy(function() {
11929					$element.css('opacity', 1);
11930					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
11931				}, this)).attr('src', url);
11932			} else {
11933				image = new Image();
11934				image.onload = $.proxy(function() {
11935					$element.css({
11936						'background-image': 'url(' + url + ')',
11937						'opacity': '1'
11938					});
11939					this._core.trigger('loaded', { element: $element, url: url }, 'lazy');
11940				}, this);
11941				image.src = url;
11942			}
11943		}, this));
11944
11945		this._loaded.push($item.get(0));
11946	}
11947
11948	/**
11949	 * Destroys the plugin.
11950	 * @public
11951	 */
11952	Lazy.prototype.destroy = function() {
11953		var handler, property;
11954
11955		for (handler in this.handlers) {
11956			this._core.$element.off(handler, this.handlers[handler]);
11957		}
11958		for (property in Object.getOwnPropertyNames(this)) {
11959			typeof this[property] != 'function' && (this[property] = null);
11960		}
11961	};
11962
11963	$.fn.owlCarousel.Constructor.Plugins.Lazy = Lazy;
11964
11965})(window.Zepto || window.jQuery, window, document);
11966
11967/**
11968 * AutoHeight Plugin
11969 * @version 2.0.0-beta.3
11970 * @author Bartosz Wojciechowski
11971 * @license The MIT License (MIT)
11972 */
11973;(function($, window, document, undefined) {
11974
11975	/**
11976	 * Creates the auto height plugin.
11977	 * @class The Auto Height Plugin
11978	 * @param {Owl} carousel - The Owl Carousel
11979	 */
11980	var AutoHeight = function(carousel) {
11981		/**
11982		 * Reference to the core.
11983		 * @protected
11984		 * @type {Owl}
11985		 */
11986		this._core = carousel;
11987
11988		/**
11989		 * All event handlers.
11990		 * @protected
11991		 * @type {Object}
11992		 */
11993		this._handlers = {
11994			'initialized.owl.carousel refreshed.owl.carousel': $.proxy(function(e) {
11995				if (e.namespace && this._core.settings.autoHeight) {
11996					this.update();
11997				}
11998			}, this),
11999			'changed.owl.carousel': $.proxy(function(e) {
12000				if (e.namespace && this._core.settings.autoHeight && e.property.name == 'position'){
12001					this.update();
12002				}
12003			}, this),
12004			'loaded.owl.lazy': $.proxy(function(e) {
12005				if (e.namespace && this._core.settings.autoHeight
12006					&& e.element.closest('.' + this._core.settings.itemClass).index() === this._core.current()) {
12007					this.update();
12008				}
12009			}, this)
12010		};
12011
12012		// set default options
12013		this._core.options = $.extend({}, AutoHeight.Defaults, this._core.options);
12014
12015		// register event handlers
12016		this._core.$element.on(this._handlers);
12017	};
12018
12019	/**
12020	 * Default options.
12021	 * @public
12022	 */
12023	AutoHeight.Defaults = {
12024		autoHeight: false,
12025		autoHeightClass: 'owl-height'
12026	};
12027
12028	/**
12029	 * Updates the view.
12030	 */
12031	AutoHeight.prototype.update = function() {
12032		var start = this._core._current,
12033			end = start + this._core.settings.items,
12034			visible = this._core.$stage.children().toArray().slice(start, end);
12035			heights = [],
12036			maxheight = 0;
12037
12038		$.each(visible, function(index, item) {
12039			heights.push($(item).height());
12040		});
12041
12042		maxheight = Math.max.apply(null, heights);
12043
12044		this._core.$stage.parent()
12045			.height(maxheight)
12046			.addClass(this._core.settings.autoHeightClass);
12047	};
12048
12049	AutoHeight.prototype.destroy = function() {
12050		var handler, property;
12051
12052		for (handler in this._handlers) {
12053			this._core.$element.off(handler, this._handlers[handler]);
12054		}
12055		for (property in Object.getOwnPropertyNames(this)) {
12056			typeof this[property] != 'function' && (this[property] = null);
12057		}
12058	};
12059
12060	$.fn.owlCarousel.Constructor.Plugins.AutoHeight = AutoHeight;
12061
12062})(window.Zepto || window.jQuery, window, document);
12063
12064/**
12065 * Video Plugin
12066 * @version 2.0.0-beta.3
12067 * @author Bartosz Wojciechowski
12068 * @license The MIT License (MIT)
12069 */
12070;(function($, window, document, undefined) {
12071
12072	/**
12073	 * Creates the video plugin.
12074	 * @class The Video Plugin
12075	 * @param {Owl} carousel - The Owl Carousel
12076	 */
12077	var Video = function(carousel) {
12078		/**
12079		 * Reference to the core.
12080		 * @protected
12081		 * @type {Owl}
12082		 */
12083		this._core = carousel;
12084
12085		/**
12086		 * Cache all video URLs.
12087		 * @protected
12088		 * @type {Object}
12089		 */
12090		this._videos = {};
12091
12092		/**
12093		 * Current playing item.
12094		 * @protected
12095		 * @type {jQuery}
12096		 */
12097		this._playing = null;
12098
12099		/**
12100		 * All event handlers.
12101		 * @todo The cloned content removale is too late
12102		 * @protected
12103		 * @type {Object}
12104		 */
12105		this._handlers = {
12106			'initialized.owl.carousel': $.proxy(function(e) {
12107				if (e.namespace) {
12108					this._core.register({ type: 'state', name: 'playing', tags: [ 'interacting' ] });
12109				}
12110			}, this),
12111			'resize.owl.carousel': $.proxy(function(e) {
12112				if (e.namespace && this._core.settings.video && this.isInFullScreen()) {
12113					e.preventDefault();
12114				}
12115			}, this),
12116			'refreshed.owl.carousel': $.proxy(function(e) {
12117				if (e.namespace && this._core.is('resizing')) {
12118					this._core.$stage.find('.cloned .owl-video-frame').remove();
12119				}
12120			}, this),
12121			'changed.owl.carousel': $.proxy(function(e) {
12122				if (e.namespace && e.property.name === 'position' && this._playing) {
12123					this.stop();
12124				}
12125			}, this),
12126			'prepared.owl.carousel': $.proxy(function(e) {
12127				if (!e.namespace) {
12128					return;
12129				}
12130
12131				var $element = $(e.content).find('.owl-video');
12132
12133				if ($element.length) {
12134					$element.css('display', 'none');
12135					this.fetch($element, $(e.content));
12136				}
12137			}, this)
12138		};
12139
12140		// set default options
12141		this._core.options = $.extend({}, Video.Defaults, this._core.options);
12142
12143		// register event handlers
12144		this._core.$element.on(this._handlers);
12145
12146		this._core.$element.on('click.owl.video', '.owl-video-play-icon', $.proxy(function(e) {
12147			this.play(e);
12148		}, this));
12149	};
12150
12151	/**
12152	 * Default options.
12153	 * @public
12154	 */
12155	Video.Defaults = {
12156		video: false,
12157		videoHeight: false,
12158		videoWidth: false
12159	};
12160
12161	/**
12162	 * Gets the video ID and the type (YouTube/Vimeo only).
12163	 * @protected
12164	 * @param {jQuery} target - The target containing the video data.
12165	 * @param {jQuery} item - The item containing the video.
12166	 */
12167	Video.prototype.fetch = function(target, item) {
12168		var type = target.attr('data-vimeo-id') ? 'vimeo' : 'youtube',
12169			id = target.attr('data-vimeo-id') || target.attr('data-youtube-id'),
12170			width = target.attr('data-width') || this._core.settings.videoWidth,
12171			height = target.attr('data-height') || this._core.settings.videoHeight,
12172			url = target.attr('href');
12173
12174		if (url) {
12175			id = url.match(/(http:|https:|)\/\/(player.|www.)?(vimeo\.com|youtu(be\.com|\.be|be\.googleapis\.com))\/(video\/|embed\/|watch\?v=|v\/)?([A-Za-z0-9._%-]*)(\&\S+)?/);
12176
12177			if (id[3].indexOf('youtu') > -1) {
12178				type = 'youtube';
12179			} else if (id[3].indexOf('vimeo') > -1) {
12180				type = 'vimeo';
12181			} else {
12182				throw new Error('Video URL not supported.');
12183			}
12184			id = id[6];
12185		} else {
12186			throw new Error('Missing video URL.');
12187		}
12188
12189		this._videos[url] = {
12190			type: type,
12191			id: id,
12192			width: width,
12193			height: height
12194		};
12195
12196		item.attr('data-video', url);
12197
12198		this.thumbnail(target, this._videos[url]);
12199	};
12200
12201	/**
12202	 * Creates video thumbnail.
12203	 * @protected
12204	 * @param {jQuery} target - The target containing the video data.
12205	 * @param {Object} info - The video info object.
12206	 * @see `fetch`
12207	 */
12208	Video.prototype.thumbnail = function(target, video) {
12209		var tnLink,
12210			icon,
12211			path,
12212			dimensions = video.width && video.height ? 'style="width:' + video.width + 'px;height:' + video.height + 'px;"' : '',
12213			customTn = target.find('img'),
12214			srcType = 'src',
12215			lazyClass = '',
12216			settings = this._core.settings,
12217			create = function(path) {
12218				icon = '<div class="owl-video-play-icon"></div>';
12219
12220				if (settings.lazyLoad) {
12221					tnLink = '<div class="owl-video-tn ' + lazyClass + '" ' + srcType + '="' + path + '"></div>';
12222				} else {
12223					tnLink = '<div class="owl-video-tn" style="opacity:1;background-image:url(' + path + ')"></div>';
12224				}
12225				target.after(tnLink);
12226				target.after(icon);
12227			};
12228
12229		// wrap video content into owl-video-wrapper div
12230		target.wrap('<div class="owl-video-wrapper"' + dimensions + '></div>');
12231
12232		if (this._core.settings.lazyLoad) {
12233			srcType = 'data-src';
12234			lazyClass = 'owl-lazy';
12235		}
12236
12237		// custom thumbnail
12238		if (customTn.length) {
12239			create(customTn.attr(srcType));
12240			customTn.remove();
12241			return false;
12242		}
12243
12244		if (video.type === 'youtube') {
12245			path = "http://img.youtube.com/vi/" + video.id + "/hqdefault.jpg";
12246			create(path);
12247		} else if (video.type === 'vimeo') {
12248			$.ajax({
12249				type: 'GET',
12250				url: 'http://vimeo.com/api/v2/video/' + video.id + '.json',
12251				jsonp: 'callback',
12252				dataType: 'jsonp',
12253				success: function(data) {
12254					path = data[0].thumbnail_large;
12255					create(path);
12256				}
12257			});
12258		}
12259	};
12260
12261	/**
12262	 * Stops the current video.
12263	 * @public
12264	 */
12265	Video.prototype.stop = function() {
12266		this._core.trigger('stop', null, 'video');
12267		this._playing.find('.owl-video-frame').remove();
12268		this._playing.removeClass('owl-video-playing');
12269		this._playing = null;
12270		this._core.leave('playing');
12271		this._core.trigger('stopped', null, 'video');
12272	};
12273
12274	/**
12275	 * Starts the current video.
12276	 * @public
12277	 * @param {Event} event - The event arguments.
12278	 */
12279	Video.prototype.play = function(event) {
12280		var target = $(event.target),
12281			item = target.closest('.' + this._core.settings.itemClass),
12282			video = this._videos[item.attr('data-video')],
12283			width = video.width || '100%',
12284			height = video.height || this._core.$stage.height(),
12285			html;
12286
12287		if (this._playing) {
12288			return;
12289		}
12290
12291		this._core.enter('playing');
12292		this._core.trigger('play', null, 'video');
12293
12294		item = this._core.items(this._core.relative(item.index()));
12295
12296		this._core.reset(item.index());
12297
12298		if (video.type === 'youtube') {
12299			html = '<iframe width="' + width + '" height="' + height + '" src="http://www.youtube.com/embed/' +
12300				video.id + '?autoplay=1&v=' + video.id + '" frameborder="0" allowfullscreen></iframe>';
12301		} else if (video.type === 'vimeo') {
12302			html = '<iframe src="http://player.vimeo.com/video/' + video.id +
12303				'?autoplay=1" width="' + width + '" height="' + height +
12304				'" frameborder="0" webkitallowfullscreen mozallowfullscreen allowfullscreen></iframe>';
12305		}
12306
12307		$('<div class="owl-video-frame">' + html + '</div>').insertAfter(item.find('.owl-video'));
12308
12309		this._playing = item.addClass('owl-video-playing');
12310	};
12311
12312	/**
12313	 * Checks whether an video is currently in full screen mode or not.
12314	 * @todo Bad style because looks like a readonly method but changes members.
12315	 * @protected
12316	 * @returns {Boolean}
12317	 */
12318	Video.prototype.isInFullScreen = function() {
12319		var element = document.fullscreenElement || document.mozFullScreenElement ||
12320				document.webkitFullscreenElement;
12321
12322		return element && $(element).parent().hasClass('owl-video-frame');
12323	};
12324
12325	/**
12326	 * Destroys the plugin.
12327	 */
12328	Video.prototype.destroy = function() {
12329		var handler, property;
12330
12331		this._core.$element.off('click.owl.video');
12332
12333		for (handler in this._handlers) {
12334			this._core.$element.off(handler, this._handlers[handler]);
12335		}
12336		for (property in Object.getOwnPropertyNames(this)) {
12337			typeof this[property] != 'function' && (this[property] = null);
12338		}
12339	};
12340
12341	$.fn.owlCarousel.Constructor.Plugins.Video = Video;
12342
12343})(window.Zepto || window.jQuery, window, document);
12344
12345/**
12346 * Animate Plugin
12347 * @version 2.0.0-beta.3
12348 * @author Bartosz Wojciechowski
12349 * @license The MIT License (MIT)
12350 */
12351;(function($, window, document, undefined) {
12352
12353	/**
12354	 * Creates the animate plugin.
12355	 * @class The Navigation Plugin
12356	 * @param {Owl} scope - The Owl Carousel
12357	 */
12358	var Animate = function(scope) {
12359		this.core = scope;
12360		this.core.options = $.extend({}, Animate.Defaults, this.core.options);
12361		this.swapping = true;
12362		this.previous = undefined;
12363		this.next = undefined;
12364
12365		this.handlers = {
12366			'change.owl.carousel': $.proxy(function(e) {
12367				if (e.namespace && e.property.name == 'position') {
12368					this.previous = this.core.current();
12369					this.next = e.property.value;
12370				}
12371			}, this),
12372			'drag.owl.carousel dragged.owl.carousel translated.owl.carousel': $.proxy(function(e) {
12373				if (e.namespace) {
12374					this.swapping = e.type == 'translated';
12375				}
12376			}, this),
12377			'translate.owl.carousel': $.proxy(function(e) {
12378				if (e.namespace && this.swapping && (this.core.options.animateOut || this.core.options.animateIn)) {
12379					this.swap();
12380				}
12381			}, this)
12382		};
12383
12384		this.core.$element.on(this.handlers);
12385	};
12386
12387	/**
12388	 * Default options.
12389	 * @public
12390	 */
12391	Animate.Defaults = {
12392		animateOut: false,
12393		animateIn: false
12394	};
12395
12396	/**
12397	 * Toggles the animation classes whenever an translations starts.
12398	 * @protected
12399	 * @returns {Boolean|undefined}
12400	 */
12401	Animate.prototype.swap = function() {
12402
12403		if (this.core.settings.items !== 1) {
12404			return;
12405		}
12406
12407		if (!$.support.animation || !$.support.transition) {
12408			return;
12409		}
12410
12411		this.core.speed(0);
12412
12413		var left,
12414			clear = $.proxy(this.clear, this),
12415			previous = this.core.$stage.children().eq(this.previous),
12416			next = this.core.$stage.children().eq(this.next),
12417			incoming = this.core.settings.animateIn,
12418			outgoing = this.core.settings.animateOut;
12419
12420		if (this.core.current() === this.previous) {
12421			return;
12422		}
12423
12424		if (outgoing) {
12425			left = this.core.coordinates(this.previous) - this.core.coordinates(this.next);
12426			previous.css( { 'left': left + 'px' } )
12427				.addClass('animated owl-animated-out')
12428				.addClass(outgoing)
12429				.on($.support.animation.end, clear);
12430		}
12431
12432		if (incoming) {
12433			next.addClass('animated owl-animated-in')
12434				.addClass(incoming)
12435				.on($.support.animation.end, clear);
12436		}
12437	};
12438
12439	Animate.prototype.clear = function(e) {
12440		if ($(e.target).hasClass('animated')) {
12441			$(e.target).css( { 'left': '' } )
12442				.removeClass('animated owl-animated-out owl-animated-in')
12443				.removeClass(this.core.settings.animateIn)
12444				.removeClass(this.core.settings.animateOut);
12445			this.core.onTransitionEnd();
12446		}
12447	};
12448
12449	/**
12450	 * Destroys the plugin.
12451	 * @public
12452	 */
12453	Animate.prototype.destroy = function() {
12454		var handler, property;
12455
12456		for (handler in this.handlers) {
12457			this.core.$element.off(handler, this.handlers[handler]);
12458		}
12459		for (property in Object.getOwnPropertyNames(this)) {
12460			typeof this[property] != 'function' && (this[property] = null);
12461		}
12462	};
12463
12464	$.fn.owlCarousel.Constructor.Plugins.Animate = Animate;
12465
12466})(window.Zepto || window.jQuery, window, document);
12467
12468/**
12469 * Autoplay Plugin
12470 * @version 2.0.0-beta.3
12471 * @author Bartosz Wojciechowski
12472 * @author Artus Kolanowski
12473 * @license The MIT License (MIT)
12474 */
12475;(function($, window, document, undefined) {
12476
12477	/**
12478	 * Creates the autoplay plugin.
12479	 * @class The Autoplay Plugin
12480	 * @param {Owl} scope - The Owl Carousel
12481	 */
12482	var Autoplay = function(carousel) {
12483		/**
12484		 * Reference to the core.
12485		 * @protected
12486		 * @type {Owl}
12487		 */
12488		this._core = carousel;
12489
12490		/**
12491		 * The autoplay interval.
12492		 * @type {Number}
12493		 */
12494		this._interval = null;
12495
12496		/**
12497		 * Indicates whenever the autoplay is paused.
12498		 * @type {Boolean}
12499		 */
12500		this._paused = false;
12501
12502		/**
12503		 * All event handlers.
12504		 * @protected
12505		 * @type {Object}
12506		 */
12507		this._handlers = {
12508			'changed.owl.carousel': $.proxy(function(e) {
12509				if (e.namespace && e.property.name === 'settings') {
12510					if (this._core.settings.autoplay) {
12511						this.play();
12512					} else {
12513						this.stop();
12514					}
12515				}
12516			}, this),
12517			'initialized.owl.carousel': $.proxy(function(e) {
12518				if (e.namespace && this._core.settings.autoplay) {
12519					this.play();
12520				}
12521			}, this),
12522			'play.owl.autoplay': $.proxy(function(e, t, s) {
12523				if (e.namespace) {
12524					this.play(t, s);
12525				}
12526			}, this),
12527			'stop.owl.autoplay': $.proxy(function(e) {
12528				if (e.namespace) {
12529					this.stop();
12530				}
12531			}, this),
12532			'mouseover.owl.autoplay': $.proxy(function() {
12533				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
12534					this.pause();
12535				}
12536			}, this),
12537			'mouseleave.owl.autoplay': $.proxy(function() {
12538				if (this._core.settings.autoplayHoverPause && this._core.is('rotating')) {
12539					this.play();
12540				}
12541			}, this)
12542		};
12543
12544		// register event handlers
12545		this._core.$element.on(this._handlers);
12546
12547		// set default options
12548		this._core.options = $.extend({}, Autoplay.Defaults, this._core.options);
12549	};
12550
12551	/**
12552	 * Default options.
12553	 * @public
12554	 */
12555	Autoplay.Defaults = {
12556		autoplay: false,
12557		autoplayTimeout: 5000,
12558		autoplayHoverPause: false,
12559		autoplaySpeed: false
12560	};
12561
12562	/**
12563	 * Starts the autoplay.
12564	 * @public
12565	 * @param {Number} [timeout] - The interval before the next animation starts.
12566	 * @param {Number} [speed] - The animation speed for the animations.
12567	 */
12568	Autoplay.prototype.play = function(timeout, speed) {
12569		this._paused = false;
12570
12571		if (this._core.is('rotating')) {
12572			return;
12573		}
12574
12575		this._core.enter('rotating');
12576
12577		this._interval = window.setInterval($.proxy(function() {
12578			if (this._paused || this._core.is('busy') || this._core.is('interacting') || document.hidden) {
12579				return;
12580			}
12581			this._core.next(speed || this._core.settings.autoplaySpeed);
12582		}, this), timeout || this._core.settings.autoplayTimeout);
12583	};
12584
12585	/**
12586	 * Stops the autoplay.
12587	 * @public
12588	 */
12589	Autoplay.prototype.stop = function() {
12590		if (!this._core.is('rotating')) {
12591			return;
12592		}
12593
12594		window.clearInterval(this._interval);
12595		this._core.leave('rotating');
12596	};
12597
12598	/**
12599	 * Stops the autoplay.
12600	 * @public
12601	 */
12602	Autoplay.prototype.pause = function() {
12603		if (!this._core.is('rotating')) {
12604			return;
12605		}
12606
12607		this._paused = true;
12608	};
12609
12610	/**
12611	 * Destroys the plugin.
12612	 */
12613	Autoplay.prototype.destroy = function() {
12614		var handler, property;
12615
12616		this.stop();
12617
12618		for (handler in this._handlers) {
12619			this._core.$element.off(handler, this._handlers[handler]);
12620		}
12621		for (property in Object.getOwnPropertyNames(this)) {
12622			typeof this[property] != 'function' && (this[property] = null);
12623		}
12624	};
12625
12626	$.fn.owlCarousel.Constructor.Plugins.autoplay = Autoplay;
12627
12628})(window.Zepto || window.jQuery, window, document);
12629
12630/**
12631 * Navigation Plugin
12632 * @version 2.0.0-beta.3
12633 * @author Artus Kolanowski
12634 * @license The MIT License (MIT)
12635 */
12636;(function($, window, document, undefined) {
12637	'use strict';
12638
12639	/**
12640	 * Creates the navigation plugin.
12641	 * @class The Navigation Plugin
12642	 * @param {Owl} carousel - The Owl Carousel.
12643	 */
12644	var Navigation = function(carousel) {
12645		/**
12646		 * Reference to the core.
12647		 * @protected
12648		 * @type {Owl}
12649		 */
12650		this._core = carousel;
12651
12652		/**
12653		 * Indicates whether the plugin is initialized or not.
12654		 * @protected
12655		 * @type {Boolean}
12656		 */
12657		this._initialized = false;
12658
12659		/**
12660		 * The current paging indexes.
12661		 * @protected
12662		 * @type {Array}
12663		 */
12664		this._pages = [];
12665
12666		/**
12667		 * All DOM elements of the user interface.
12668		 * @protected
12669		 * @type {Object}
12670		 */
12671		this._controls = {};
12672
12673		/**
12674		 * Markup for an indicator.
12675		 * @protected
12676		 * @type {Array.<String>}
12677		 */
12678		this._templates = [];
12679
12680		/**
12681		 * The carousel element.
12682		 * @type {jQuery}
12683		 */
12684		this.$element = this._core.$element;
12685
12686		/**
12687		 * Overridden methods of the carousel.
12688		 * @protected
12689		 * @type {Object}
12690		 */
12691		this._overrides = {
12692			next: this._core.next,
12693			prev: this._core.prev,
12694			to: this._core.to
12695		};
12696
12697		/**
12698		 * All event handlers.
12699		 * @protected
12700		 * @type {Object}
12701		 */
12702		this._handlers = {
12703			'prepared.owl.carousel': $.proxy(function(e) {
12704				if (e.namespace && this._core.settings.dotsData) {
12705					this._templates.push('<div class="' + this._core.settings.dotClass + '">' +
12706						$(e.content).find('[data-dot]').andSelf('[data-dot]').attr('data-dot') + '</div>');
12707				}
12708			}, this),
12709			'added.owl.carousel': $.proxy(function(e) {
12710				if (e.namespace && this._core.settings.dotsData) {
12711					this._templates.splice(e.position, 0, this._templates.pop());
12712				}
12713			}, this),
12714			'remove.owl.carousel': $.proxy(function(e) {
12715				if (e.namespace && this._core.settings.dotsData) {
12716					this._templates.splice(e.position, 1);
12717				}
12718			}, this),
12719			'changed.owl.carousel': $.proxy(function(e) {
12720				if (e.namespace && e.property.name == 'position') {
12721					this.draw();
12722				}
12723			}, this),
12724			'initialized.owl.carousel': $.proxy(function(e) {
12725				if (e.namespace && !this._initialized) {
12726					this._core.trigger('initialize', null, 'navigation');
12727					this.initialize();
12728					this.update();
12729					this.draw();
12730					this._initialized = true;
12731					this._core.trigger('initialized', null, 'navigation');
12732				}
12733			}, this),
12734			'refreshed.owl.carousel': $.proxy(function(e) {
12735				if (e.namespace && this._initialized) {
12736					this._core.trigger('refresh', null, 'navigation');
12737					this.update();
12738					this.draw();
12739					this._core.trigger('refreshed', null, 'navigation');
12740				}
12741			}, this)
12742		};
12743
12744		// set default options
12745		this._core.options = $.extend({}, Navigation.Defaults, this._core.options);
12746
12747		// register event handlers
12748		this.$element.on(this._handlers);
12749	};
12750
12751	/**
12752	 * Default options.
12753	 * @public
12754	 * @todo Rename `slideBy` to `navBy`
12755	 */
12756	Navigation.Defaults = {
12757		nav: false,
12758		navText: [ 'prev', 'next' ],
12759		navSpeed: false,
12760		navElement: 'div',
12761		navContainer: false,
12762		navContainerClass: 'owl-nav',
12763		navClass: [ 'owl-prev', 'owl-next' ],
12764		slideBy: 1,
12765		dotClass: 'owl-dot',
12766		dotsClass: 'owl-dots',
12767		dots: true,
12768		dotsEach: false,
12769		dotsData: false,
12770		dotsSpeed: false,
12771		dotsContainer: false
12772	};
12773
12774	/**
12775	 * Initializes the layout of the plugin and extends the carousel.
12776	 * @protected
12777	 */
12778	Navigation.prototype.initialize = function() {
12779		var override,
12780			settings = this._core.settings;
12781
12782		// create DOM structure for relative navigation
12783		this._controls.$relative = (settings.navContainer ? $(settings.navContainer)
12784			: $('<div>').addClass(settings.navContainerClass).appendTo(this.$element)).addClass('disabled');
12785
12786		this._controls.$previous = $('<' + settings.navElement + '>')
12787			.addClass(settings.navClass[0])
12788			.html(settings.navText[0])
12789			.prependTo(this._controls.$relative)
12790			.on('click', $.proxy(function(e) {
12791				this.prev(settings.navSpeed);
12792			}, this));
12793		this._controls.$next = $('<' + settings.navElement + '>')
12794			.addClass(settings.navClass[1])
12795			.html(settings.navText[1])
12796			.appendTo(this._controls.$relative)
12797			.on('click', $.proxy(function(e) {
12798				this.next(settings.navSpeed);
12799			}, this));
12800
12801		// create DOM structure for absolute navigation
12802		if (!settings.dotsData) {
12803			this._templates = [ $('<div>')
12804				.addClass(settings.dotClass)
12805				.append($('<span>'))
12806				.prop('outerHTML') ];
12807		}
12808
12809		this._controls.$absolute = (settings.dotsContainer ? $(settings.dotsContainer)
12810			: $('<div>').addClass(settings.dotsClass).appendTo(this.$element)).addClass('disabled');
12811
12812		this._controls.$absolute.on('click', 'div', $.proxy(function(e) {
12813			var index = $(e.target).parent().is(this._controls.$absolute)
12814				? $(e.target).index() : $(e.target).parent().index();
12815
12816			e.preventDefault();
12817
12818			this.to(index, settings.dotsSpeed);
12819		}, this));
12820
12821		// override public methods of the carousel
12822		for (override in this._overrides) {
12823			this._core[override] = $.proxy(this[override], this);
12824		}
12825	};
12826
12827	/**
12828	 * Destroys the plugin.
12829	 * @protected
12830	 */
12831	Navigation.prototype.destroy = function() {
12832		var handler, control, property, override;
12833
12834		for (handler in this._handlers) {
12835			this.$element.off(handler, this._handlers[handler]);
12836		}
12837		for (control in this._controls) {
12838			this._controls[control].remove();
12839		}
12840		for (override in this.overides) {
12841			this._core[override] = this._overrides[override];
12842		}
12843		for (property in Object.getOwnPropertyNames(this)) {
12844			typeof this[property] != 'function' && (this[property] = null);
12845		}
12846	};
12847
12848	/**
12849	 * Updates the internal state.
12850	 * @protected
12851	 */
12852	Navigation.prototype.update = function() {
12853		var i, j, k,
12854			lower = this._core.clones().length / 2,
12855			upper = lower + this._core.items().length,
12856			maximum = this._core.maximum(true),
12857			settings = this._core.settings,
12858			size = settings.center || settings.autoWidth || settings.dotsData
12859				? 1 : settings.dotsEach || settings.items;
12860
12861		if (settings.slideBy !== 'page') {
12862			settings.slideBy = Math.min(settings.slideBy, settings.items);
12863		}
12864
12865		if (settings.dots || settings.slideBy == 'page') {
12866			this._pages = [];
12867
12868			for (i = lower, j = 0, k = 0; i < upper; i++) {
12869				if (j >= size || j === 0) {
12870					this._pages.push({
12871						start: Math.min(maximum, i - lower),
12872						end: i - lower + size - 1
12873					});
12874					if (Math.min(maximum, i - lower) === maximum) {
12875						break;
12876					}
12877					j = 0, ++k;
12878				}
12879				j += this._core.mergers(this._core.relative(i));
12880			}
12881		}
12882	};
12883
12884	/**
12885	 * Draws the user interface.
12886	 * @todo The option `dotsData` wont work.
12887	 * @protected
12888	 */
12889	Navigation.prototype.draw = function() {
12890		var difference,
12891			settings = this._core.settings,
12892			disabled = this._core.items().length <= settings.items,
12893			index = this._core.relative(this._core.current()),
12894			loop = settings.loop || settings.rewind;
12895
12896		this._controls.$relative.toggleClass('disabled', !settings.nav || disabled);
12897
12898		if (settings.nav) {
12899			this._controls.$previous.toggleClass('disabled', !loop && index <= this._core.minimum(true));
12900			this._controls.$next.toggleClass('disabled', !loop && index >= this._core.maximum(true));
12901		}
12902
12903		this._controls.$absolute.toggleClass('disabled', !settings.dots || disabled);
12904
12905		if (settings.dots) {
12906			difference = this._pages.length - this._controls.$absolute.children().length;
12907
12908			if (settings.dotsData && difference !== 0) {
12909				this._controls.$absolute.html(this._templates.join(''));
12910			} else if (difference > 0) {
12911				this._controls.$absolute.append(new Array(difference + 1).join(this._templates[0]));
12912			} else if (difference < 0) {
12913				this._controls.$absolute.children().slice(difference).remove();
12914			}
12915
12916			this._controls.$absolute.find('.active').removeClass('active');
12917			this._controls.$absolute.children().eq($.inArray(this.current(), this._pages)).addClass('active');
12918		}
12919	};
12920
12921	/**
12922	 * Extends event data.
12923	 * @protected
12924	 * @param {Event} event - The event object which gets thrown.
12925	 */
12926	Navigation.prototype.onTrigger = function(event) {
12927		var settings = this._core.settings;
12928
12929		event.page = {
12930			index: $.inArray(this.current(), this._pages),
12931			count: this._pages.length,
12932			size: settings && (settings.center || settings.autoWidth || settings.dotsData
12933				? 1 : settings.dotsEach || settings.items)
12934		};
12935	};
12936
12937	/**
12938	 * Gets the current page position of the carousel.
12939	 * @protected
12940	 * @returns {Number}
12941	 */
12942	Navigation.prototype.current = function() {
12943		var current = this._core.relative(this._core.current());
12944		return $.grep(this._pages, $.proxy(function(page, index) {
12945			return page.start <= current && page.end >= current;
12946		}, this)).pop();
12947	};
12948
12949	/**
12950	 * Gets the current succesor/predecessor position.
12951	 * @protected
12952	 * @returns {Number}
12953	 */
12954	Navigation.prototype.getPosition = function(successor) {
12955		var position, length,
12956			settings = this._core.settings;
12957
12958		if (settings.slideBy == 'page') {
12959			position = $.inArray(this.current(), this._pages);
12960			length = this._pages.length;
12961			successor ? ++position : --position;
vendor: 5,670 bytes, lines 12962-13186
12962			position = this._pages[((position % length) + length) % length].start;
12963		} else {
12964			position = this._core.relative(this._core.current());
12965			length = this._core.items().length;
12966			successor ? position += settings.slideBy : position -= settings.slideBy;
12967		}
12968
12969		return position;
12970	};
12971
12972	/**
12973	 * Slides to the next item or page.
12974	 * @public
12975	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
12976	 */
12977	Navigation.prototype.next = function(speed) {
12978		$.proxy(this._overrides.to, this._core)(this.getPosition(true), speed);
12979	};
12980
12981	/**
12982	 * Slides to the previous item or page.
12983	 * @public
12984	 * @param {Number} [speed=false] - The time in milliseconds for the transition.
12985	 */
12986	Navigation.prototype.prev = function(speed) {
12987		$.proxy(this._overrides.to, this._core)(this.getPosition(false), speed);
12988	};
12989
12990	/**
12991	 * Slides to the specified item or page.
12992	 * @public
12993	 * @param {Number} position - The position of the item or page.
12994	 * @param {Number} [speed] - The time in milliseconds for the transition.
12995	 * @param {Boolean} [standard=false] - Whether to use the standard behaviour or not.
12996	 */
12997	Navigation.prototype.to = function(position, speed, standard) {
12998		var length;
12999
13000		if (!standard) {
13001			length = this._pages.length;
13002			$.proxy(this._overrides.to, this._core)(this._pages[((position % length) + length) % length].start, speed);
13003		} else {
13004			$.proxy(this._overrides.to, this._core)(position, speed);
13005		}
13006	};
13007
13008	$.fn.owlCarousel.Constructor.Plugins.Navigation = Navigation;
13009
13010})(window.Zepto || window.jQuery, window, document);
13011
13012/**
13013 * Hash Plugin
13014 * @version 2.0.0-beta.3
13015 * @author Artus Kolanowski
13016 * @license The MIT License (MIT)
13017 */
13018;(function($, window, document, undefined) {
13019	'use strict';
13020
13021	/**
13022	 * Creates the hash plugin.
13023	 * @class The Hash Plugin
13024	 * @param {Owl} carousel - The Owl Carousel
13025	 */
13026	var Hash = function(carousel) {
13027		/**
13028		 * Reference to the core.
13029		 * @protected
13030		 * @type {Owl}
13031		 */
13032		this._core = carousel;
13033
13034		/**
13035		 * Hash index for the items.
13036		 * @protected
13037		 * @type {Object}
13038		 */
13039		this._hashes = {};
13040
13041		/**
13042		 * The carousel element.
13043		 * @type {jQuery}
13044		 */
13045		this.$element = this._core.$element;
13046
13047		/**
13048		 * All event handlers.
13049		 * @protected
13050		 * @type {Object}
13051		 */
13052		this._handlers = {
13053			'initialized.owl.carousel': $.proxy(function(e) {
13054				if (e.namespace && this._core.settings.startPosition === 'URLHash') {
13055					$(window).trigger('hashchange.owl.navigation');
13056				}
13057			}, this),
13058			'prepared.owl.carousel': $.proxy(function(e) {
13059				if (e.namespace) {
13060					var hash = $(e.content).find('[data-hash]').addBack('[data-hash]').attr('data-hash');
13061
13062					if (!hash) {
13063						return;
13064					}
13065
13066					this._hashes[hash] = e.content;
13067				}
13068			}, this),
13069			'changed.owl.carousel': $.proxy(function(e) {
13070				if (e.namespace && e.property.name === 'position') {
13071					var current = this._core.items(this._core.relative(this._core.current())),
13072						hash = $.map(this._hashes, function(item, hash) {
13073							return item === current ? hash : null;
13074						}).join();
13075
13076					if (!hash || window.location.hash.slice(1) === hash) {
13077						return;
13078					}
13079
13080					window.location.hash = hash;
13081				}
13082			}, this)
13083		};
13084
13085		// set default options
13086		this._core.options = $.extend({}, Hash.Defaults, this._core.options);
13087
13088		// register the event handlers
13089		this.$element.on(this._handlers);
13090
13091		// register event listener for hash navigation
13092		$(window).on('hashchange.owl.navigation', $.proxy(function(e) {
13093			var hash = window.location.hash.substring(1),
13094				items = this._core.$stage.children(),
13095				position = this._hashes[hash] && items.index(this._hashes[hash]);
13096
13097			if (position === undefined || position === this._core.current()) {
13098				return;
13099			}
13100
13101			this._core.to(this._core.relative(position), false, true);
13102		}, this));
13103	};
13104
13105	/**
13106	 * Default options.
13107	 * @public
13108	 */
13109	Hash.Defaults = {
13110		URLhashListener: false
13111	};
13112
13113	/**
13114	 * Destroys the plugin.
13115	 * @public
13116	 */
13117	Hash.prototype.destroy = function() {
13118		var handler, property;
13119
13120		$(window).off('hashchange.owl.navigation');
13121
13122		for (handler in this._handlers) {
13123			this._core.$element.off(handler, this._handlers[handler]);
13124		}
13125		for (property in Object.getOwnPropertyNames(this)) {
13126			typeof this[property] != 'function' && (this[property] = null);
13127		}
13128	};
13129
13130	$.fn.owlCarousel.Constructor.Plugins.Hash = Hash;
13131
13132})(window.Zepto || window.jQuery, window, document);
13133
13134/**
13135 * Support Plugin
13136 *
13137 * @version 2.0.0-beta.3
13138 * @author Vivid Planet Software GmbH
13139 * @author Artus Kolanowski
13140 * @license The MIT License (MIT)
13141 */
13142;(function($, window, document, undefined) {
13143
13144	var style = $('<support>').get(0).style,
13145		prefixes = 'Webkit Moz O ms'.split(' '),
13146		events = {
13147			transition: {
13148				end: {
13149					WebkitTransition: 'webkitTransitionEnd',
13150					MozTransition: 'transitionend',
13151					OTransition: 'oTransitionEnd',
13152					transition: 'transitionend'
13153				}
13154			},
13155			animation: {
13156				end: {
13157					WebkitAnimation: 'webkitAnimationEnd',
13158					MozAnimation: 'animationend',
13159					OAnimation: 'oAnimationEnd',
13160					animation: 'animationend'
13161				}
13162			}
13163		},
13164		tests = {
13165			csstransforms: function() {
13166				return !!test('transform');
13167			},
13168			csstransforms3d: function() {
13169				return !!test('perspective');
13170			},
13171			csstransitions: function() {
13172				return !!test('transition');
13173			},
13174			cssanimations: function() {
13175				return !!test('animation');
13176			}
13177		};
13178
13179	function test(property, prefixed) {
13180		var result = false,
13181			upper = property.charAt(0).toUpperCase() + property.slice(1);
13182
13183		$.each((property + ' ' + prefixes.join(upper + ' ') + upper).split(' '), function(i, property) {
13184			if (style[property] !== undefined) {
13185				result = prefixed ? property : true;
13186				return false;
13187			}
13188		});
13189
13190		return result;
13191	}
13192
13193	function prefixed(property) {
13194		return test(property, true);
13195	}
13196
13197	if (tests.csstransitions()) {
13198		/* jshint -W053 */
13199		$.support.transition = new String(prefixed('transition'))
13200		$.support.transition.end = events.transition.end[ $.support.transition ];
13201	}
13202
13203	if (tests.cssanimations()) {
13204		/* jshint -W053 */
13205		$.support.animation = new String(prefixed('animation'))
13206		$.support.animation.end = events.animation.end[ $.support.animation ];
13207	}
13208
13209	if (tests.csstransforms()) {
13210		/* jshint -W053 */
13211		$.support.transform = new String(prefixed('transform'));
13212		$.support.transform3d = tests.csstransforms3d();
13213	}
13214
13215})(window.Zepto || window.jQuery, window, document);
13216
13217(function(window, document, undefined) {
13218
13219    /**
13220     * Find the absolute position of an element
13221     */
13222    var absPos = function(element) {
13223        var offsetLeft, offsetTop;
13224        offsetLeft = offsetTop = 0;
13225        if (element.offsetParent) {
13226            do {
13227                offsetLeft += element.offsetLeft;
13228                offsetTop += element.offsetTop;
13229            } while (element = element.offsetParent);
13230        }
13231        return [offsetLeft, offsetTop];
13232    };
13233
13234    /**
13235     * @constructor Progress Circle class
13236     * @param params.canvas Canvas on which the circles will be drawn.
13237     * @param params.minRadius Inner radius of the innermost circle, in px.
13238     * @param params.arcWidth Width of each circle(to be more accurate, ring).
13239     * @param params.gapWidth Space between each circle.
13240     * @param params.centerX X coordinate of the center of circles.
13241     * @param params.centerY Y coordinate of the center of circles.
13242     * @param params.infoLineBaseAngle Base angle of the info line.
13243     * @param params.infoLineAngleInterval Angles between the info lines.
13244     */
13245    var ProgressCircle = function(params) {
13246        this.canvas = params.canvas;
13247        this.minRadius = params.minRadius || 15;
13248        this.arcWidth = params.arcWidth || 5;
13249        this.gapWidth = params.gapWidth || 3;
13250        this.centerX = params.centerX || this.canvas.width / 2;
13251        this.centerY = params.centerY || this.canvas.height / 2;
13252        this.infoLineLength = params.infoLineLength || 60;
13253        this.horizLineLength = params.horizLineLength || 10;
13254        this.infoLineAngleInterval = params.infoLineAngleInterval || Math.PI / 8;
13255        this.infoLineBaseAngle = params.infoLineBaseAngle || Math.PI / 6;
13256
13257        this.context = this.canvas.getContext('2d');
13258
13259        this.width = this.canvas.width;
13260        this.height = this.canvas.height;
13261
13262        this.circles = [];
13263        this.runningCount = 0;
13264    };
13265
13266    ProgressCircle.prototype = {
13267        constructor: ProgressCircle,
13268
13269        /**
13270         * @method Adds an progress monitor entry.
13271         * @param params.fillColor Color to fill in the circle.
13272         * @param params.outlineColor Color to outline the circle.
13273         * @param params.progressListener Callback function to fetch the progress.
13274         * @param params.infoListener Callback function to fetch the info.
13275         * @returns this
13276         */
13277        addEntry: function(params) {
13278            this.circles.push(new Circle({
13279                canvas: this.canvas,
13280                context: this.context,
13281                centerX: this.centerX,
13282                centerY: this.centerY,
13283                innerRadius: this.minRadius + this.circles.length *
13284                    (this.gapWidth + this.arcWidth),
13285                arcWidth: this.arcWidth,
13286                infoLineLength: this.infoLineLength,
13287                horizLineLength: this.horizLineLength,
13288
13289                id: this.circles.length,
13290                fillColor: params.fillColor,
13291                outlineColor: params.outlineColor,
13292                progressListener: params.progressListener,
13293                infoListener: params.infoListener,
13294                infoLineAngle: this.infoLineBaseAngle +
13295                    this.circles.length * this.infoLineAngleInterval,
13296            }));
13297
13298            return this;
13299        },
13300
13301        /**
13302         * @method Starts the monitor and updates with the given interval.
13303         * @param interval Interval between updates, in millisecond.
13304         * @returns this
13305         */
13306        start: function(interval) {
13307            var self = this;
13308            this.timer = setInterval(function() {
13309                self._update();
13310            }, interval || 33);
13311
13312            return this;
13313        },
13314
13315        /**
13316         * @method Stop the animation.
13317         */
13318        stop: function() {
13319            clearTimeout(this.timer);
13320        },
13321
13322        /**
13323         * @private
13324         * @method Call update on each circle and redraw them.
13325         * @returns this
13326         */
13327        _update: function() {
13328            this._clear();
13329            this.circles.forEach(function(circle, idx, array) {
13330                circle.update();
13331            });
13332
13333            return this;
13334        },
13335
13336        /**
13337         * @private
13338         * @method Clear the canvas.
13339         * @returns this
13340         */
13341        _clear: function() {
13342            this.context.clearRect(0, 0, this.canvas.width, this.canvas.height);
13343
13344            return this;
13345        },
13346
13347    };
13348
13349    /**
13350     * @private
13351     * @class Individual progress circle.
13352     * @param params.canvas Canvas on which the circle will be drawn.
13353     * @param params.context Context of the canvas.
13354     * @param params.innerRadius Inner radius of the circle, in px.
13355     * @param params.arcWidth Width of each arc(circle).
13356     * @param params.gapWidth Distance between each arc.
13357     * @param params.centerX X coordinate of the center of circles.
13358     * @param params.centerY Y coordinate of the center of circles.
13359     * @param params.fillColor Color to fill in the circle.
13360     * @param params.outlineColor Color to outline the circle.
13361     * @param params.progressListener Callback function to fetch the progress.
13362     * @param params.infoListener Callback function to fetch the info.
13363     * @param params.infoLineAngle Angle of info line.
13364     */
13365    var Circle = function(params) {
13366        this.id = params.id;
13367        this.canvas = params.canvas;
13368        this.context = params.context;
13369        this.centerX = params.centerX;
13370        this.centerY = params.centerY;
13371        this.arcWidth = params.arcWidth;
13372        this.innerRadius = params.innerRadius || 0;
13373        this.fillColor = params.fillColor || '#fff';
13374        this.outlineColor = params.outlineColor || this.fillColor;
13375        this.progressListener = params.progressListener;
13376        this.infoLineLength = params.infoLineLength || 250;
13377        this.horizLineLength = params.horizLineLength || 50;
13378        this.infoListener = params.infoListener;
13379        this.infoLineAngle = params.infoLineAngle;
13380
13381        this.outerRadius = this.innerRadius + this.arcWidth;
13382
13383        // If the info listener is not registered, then don't calculate
13384        // the related coordinates
13385        if (!this.infoListener) return;
13386
13387        // calculate the info-line turning points
13388        var angle = this.infoLineAngle,
13389            arcDistance = (this.innerRadius + this.outerRadius) / 2,
13390
13391            sinA = Math.sin(angle),
13392            cosA = Math.cos(angle);
13393
13394        this.infoLineStartX = this.centerX + sinA * arcDistance;
13395        this.infoLineStartY = this.centerY - cosA * arcDistance;
13396
13397        this.infoLineMidX = this.centerX + sinA * this.infoLineLength;
13398        this.infoLineMidY = this.centerY - cosA * this.infoLineLength;
13399
13400        this.infoLineEndX = this.infoLineMidX +
13401             (sinA < 0 ? -this.horizLineLength : this.horizLineLength);
13402        this.infoLineEndY = this.infoLineMidY;
13403
13404        var infoText = document.createElement('div'),
13405            style = infoText.style;
13406
13407        style.color = this.fillColor;
13408        style.position = 'absolute';
13409        style.left = this.infoLineEndX + absPos(this.canvas)[0] + 'px';
13410        // style.top will be calculated in the `drawInfo` method. Since
13411        // user may want to change the size of the font, so the top offset
13412        // must be updated in each loop.
13413        infoText.className = 'ProgressCircleInfo'; // For css styling
13414        infoText.id = 'progress_circle_info_' + this.id;
13415        document.body.appendChild(infoText);
13416        this.infoText = infoText;
13417    };
13418
13419    Circle.prototype = {
13420        constructor: Circle,
13421
13422        update: function() {
13423            this.progress = this.progressListener();
13424            this._draw();
13425
13426            if (this.infoListener) {
13427                this.info = this.infoListener();
13428                this._drawInfo();
13429            }
13430        },
13431
13432        /**
13433         * @private
13434         * @method Draw the circle on the canvas.
13435         * @returns this
13436         */
13437        _draw: function() {
13438            var ctx = this.context,
13439
13440                ANGLE_OFFSET = -Math.PI / 2,
13441
13442                startAngle = 0 + ANGLE_OFFSET,
13443                endAngle= startAngle + this.progress * Math.PI * 2,
13444
13445                x = this.centerX,
13446                y = this.centerY,
13447
13448                innerRadius = this.innerRadius - this.arcWidth - 1,
13449                outerRadius = this.outerRadius - this.arcWidth - 1;
13450
13451            ctx.fillStyle = this.fillColor;
13452            ctx.strokeStyle = this.outlineColor;
13453
13454            ctx.beginPath();
13455            ctx.arc(x, y, innerRadius, startAngle, endAngle, false);
13456            ctx.arc(x, y, outerRadius, endAngle, startAngle, true);
13457            ctx.closePath();
13458            ctx.stroke();
13459            ctx.fill();
13460
13461            return this;
13462        },
13463
13464        /**
13465         * @private
13466         * @method Draw the info lines and info text.
13467         * @returns this
13468         */
13469        _drawInfo: function() {
13470
13471            var pointList, lineHeight;
13472
13473            pointList = [
13474                [this.infoLineStartX, this.infoLineStartY],
13475                [this.infoLineMidX, this.infoLineMidY],
13476                [this.infoLineEndX, this.infoLineEndY],
13477            ];
13478            this._drawSegments(pointList, false);
13479
13480            this.infoText.innerHTML = this.info;
13481
13482            lineHeight = this.infoText.offsetHeight;
13483            this.infoText.style.top = this.infoLineEndY +
13484                absPos(this.canvas)[1] - lineHeight / 2 + 'px';
13485
13486            return this;
13487        },
13488
13489        /**
13490         * @private
13491         * @method Helper function to draw the segments
13492         * @param pointList An array of points in the form of [x, y].
13493         * @param close Whether to connect the first and last point.
13494         */
13495        _drawSegments: function(pointList, close) {
13496            var ctx = this.context;
13497
13498            ctx.beginPath();
13499            ctx.moveTo(pointList[0][0], pointList[0][1]);
13500            for (var i = 1; i < pointList.length; ++i) {
13501                ctx.lineTo(pointList[i][0], pointList[i][1]);
13502            }
13503
13504            if (close) {
13505                ctx.closePath();
13506            }
13507            ctx.stroke();
13508        },
13509    };
13510
13511    window.ProgressCircle = ProgressCircle;
13512
13513})(window, document);
13514
13515
13516
13517
13518/* =========================================================
13519 * jquery.vc_chart.js v1.0
13520 * =========================================================
13521 * Copyright 2013 Wpbakery
13522 *
13523 * Jquery chart plugin for the Visual Composer.
13524 * ========================================================= */
13525(function($){
13526    /**
13527     * Pie chart animated.
13528     * @param element - DOM element
13529     * @param options - settings object.
13530     * @constructor
13531     */
13532    var VcChart = function(element, options) {
13533        this.el = element;
13534        this.$el = $(this.el);
13535        this.options = $.extend({
13536            color: 'wpb_button',
13537            units: '',
13538            width: '',
13539            label_selector: '.vc_pie_chart_value',
13540            back_selector: '.vc_pie_chart_back',
13541            responsive: true
13542        }, options);
13543        this.init();
13544    };
13545    VcChart.prototype = {
13546        constructor: VcChart,
13547        _progress_v: 0,
13548        animated: false,
13549        colors: {
13550            'wpb_button': 'rgba(247, 247, 247, 1)',
13551            'btn-primary': 'rgba(0, 136, 204, 1)',
13552            'btn-info': 'rgba(88, 185, 218, 1)',
13553            'btn-success': 'rgba(106, 177, 101, 1)',
13554            'btn-warning': 'rgba(255, 153, 0, 1)',
13555            'btn-danger': 'rgba(255, 103, 91, 1)',
13556            'btn-inverse': 'rgba(85, 85, 85, 1)'
13557        },
13558        init: function() {
13559            this.setupColor();
13560            this.value = this.$el.data('pie-value')/100;
13561            this.label_value = this.$el.data('pie-label-value') || this.$el.data('pie-value');
13562            this.$wrapper = $('.vc_pie_wrapper', this.$el);
13563            this.$label = $(this.options.label_selector, this.$el);
13564            this.$back = $(this.options.back_selector, this.$el);
13565            this.$canvas = this.$el.find('canvas');
13566            this.arcWidth = this.$el.data('pie-width') * 2;
13567            this.draw();
13568            this.setWayPoint();
13569            if(this.options.responsive === true) this.setResponsive();
13570            if (UNCODE.isMobile) this._progress_v = this.value;
13571        },
13572        setupColor: function() {
13573            // if(typeof this.colors[this.options.color] !== 'undefined') {
13574            //     this.color = this.colors[this.options.color];
13575            // } else if(typeof this.options.color === 'string' && this.options.color.match(/^rgba?\([^\)]+\)/)) {
13576            //     this.color = this.options.color;
13577            // } else {
13578            //     this.color = 'rgba(247, 247, 247, 0.2)';
13579            // }
13580            if(typeof this.options.color !== 'undefined') {
13581                this.color = this.options.color;
13582            } else this.color = 'rgba(247, 247, 247, 0.2)';
13583
13584        },
13585        setResponsive: function() {
13586            var that = this;
13587            if (!UNCODE.isMobile) {
13588                $(window).resize(function(){
13589                    if(that.animated === true) that.circle.stop();
13590                    that.draw(true);
13591                });
13592            }
13593        },
13594          draw: function(redraw) {
13595            var w = this.$el.addClass('vc_ready').width() * 2,
13596                border_w = this.arcWidth,
13597                radius;
13598            if(!w) w = this.$el.parents(':visible').first().width()-2;
13599            //w = Math.round(w/100*80);
13600            //if (w < 250) w = 250;
13601            radius = w/2;
13602            this.$wrapper.css({"width" : (w / 2) + "px"});
13603            this.$label.css({"width" : (w / 2), "height" : (w / 2), "line-height" : (w / 2)+"px"});
13604            this.$back.css({"width" : (w / 2), "height" : (w / 2)});
13605            this.$canvas.attr({"width" : w + "px", "height" : w + "px"});
13606            this.$el.addClass('vc_ready');
13607            this.circle = new ProgressCircle({
13608                canvas: this.$canvas.get(0),
13609                minRadius: radius,
13610                arcWidth: border_w
13611            });
13612            if(redraw === true && this.animated === true) {
13613                this._progress_v = this.value;
13614                this.circle.addEntry({
13615                    fillColor: this.color,
13616                    progressListener: $.proxy(this.setProgress, this)
13617                }).start();
13618            }
13619        },
13620        setProgress: function() {
13621            if (this._progress_v >= this.value) {
13622                this.circle.stop();
13623                this.$label.html(this.label_value + this.options.units);
13624                return this._progress_v;
13625            }
13626            this._progress_v += 0.01;
13627            if (!isNaN(this.label_value)) {
13628                var label_value = this._progress_v/this.value*this.label_value;
13629                var val = Math.round(label_value) + this.options.units;
13630                this.$label.html(val);
13631            } else this.$label.html(this.label_value + this.options.units);
13632            return this._progress_v;
13633        },
13634        animate: function() {
13635            if(this.animated !== true) {
13636                this.animated = true;
13637                this.circle.addEntry({
13638                    fillColor: this.color,
13639                    progressListener: $.proxy(this.setProgress, this)
13640                }).start(5);
13641            }
13642        },
13643        setWayPoint: function() {
13644            if (typeof $.fn.waypoint !== 'undefined' && !UNCODE.isMobile) {
13645                this.$el.waypoint($.proxy(this.animate, this), { offset: '85%' });
13646            } else {
13647                this.animate();
13648            }
13649        }
13650    };
13651    /**
13652     * jQuery plugin
13653     * @param option - object with settings
13654     * @return {*}
13655     */
13656    $.fn.vcChat = function(option, value) {
13657        return this.each(function () {
13658            var $this = $(this),
13659                data = $this.data('vc_chart'),
13660                options = typeof option === 'object' ? option : {
13661                    color: $this.data('pie-color'),
13662                    units: $this.data('pie-units')
13663                };
13664            if (typeof option == 'undefined') $this.data('vc_chart', (data = new VcChart(this, options)));
13665            if (typeof option == 'string') data[option](value);
13666        });
13667    };
13668    /**
13669     * Allows users to rewrite function inside theme.
13670     */
13671    if ( typeof window['vc_pieChart'] !== 'function' ) {
13672        window.vc_pieChart = function() {
13673            $('.vc_pie_chart:visible').vcChat();
13674        }
13675    }
13676    $(document).ready(function(){
13677        !window.vc_iframe && vc_pieChart();
13678    });
13679
13680})(window.jQuery);
13681
13682
13683/* Progress bar
13684 ---------------------------------------------------------- */
13685function uncode_progress_bar() {    
13686	jQuery.each(jQuery('.vc_progress_bar'), function(index, val) {
13687		if (!UNCODE.isMobile) {
13688			new Waypoint({
13689				element: val,
13690				handler: function() {
13691					var element = jQuery(this.element);
13692					element.find('.vc_single_bar').each(function(index) {          
13693						var $this = jQuery(this),
13694							            bar = $this.find('.vc_bar'),
13695							            val = bar.data('percentage-value');          
13696						setTimeout(function() {            
13697							bar.css({
13698								"width": val + '%'
13699							});          
13700						}, index * 200);        
13701					});
13702				},
13703				offset: '80%'
13704			});
13705		} else {
13706			var element = jQuery(val);
13707			element.find('.vc_single_bar').each(function(index) {          
13708				var $this = jQuery(this),
13709					            bar = $this.find('.vc_bar'),
13710					            val = bar.data('percentage-value');          
13711				setTimeout(function() {            
13712					bar.css({
13713						"width": val + '%'
13714					});          
13715				}, index * 200);        
13716			});
13717		}
13718	});
13719};
13720uncode_progress_bar();
13721
13722/*!
13723 * jquery.counterup.js 1.0
13724 *
13725 * Copyright 2013, Benjamin Intal http://gambit.ph @bfintal
13726 * Released under the GPL v2 License
13727 *
13728 * Date: Nov 26, 2013
13729 */
13730(function($) {
13731	"use strict";
13732	$.fn.counterUp = function(options) {
13733		// Defaults
13734		var settings = $.extend({
13735			'time': 400,
13736			'delay': 10
13737		}, options);
13738		return this.each(function() {
13739			// Store the object
13740			var $this = $(this);
13741			var $settings = settings;
13742			var counterUpper = function() {
13743				var nums = [];
13744				var divisions = $settings.time / $settings.delay;
13745				var numReal = $this.text(),
13746				num = numReal;
13747				var isComma = /[0-9]+,[0-9]+/.test(num);
13748				num = num.replace(/,/g, '');
13749				var isInt = /^[0-9]+$/.test(num);
13750				var isFloat = /^[0-9]+\.[0-9]+$/.test(num);
13751				var decimalPlaces = isFloat ? (num.split('.')[1] || []).length : 0;
13752				// Generate list of incremental numbers to display
13753				for (var i = divisions; i >= 1; i--) {
13754					// Preserve as int if input was int
13755					var newNum = parseInt(num / divisions * i);
13756					// Preserve float if input was float
13757					if (isFloat) {
13758						newNum = parseFloat(num / divisions * i).toFixed(decimalPlaces);
13759					}
13760					// Preserve commas if input had commas
13761					if (isComma) {
13762						while (/(\d+)(\d{3})/.test(newNum.toString())) {
13763							newNum = newNum.toString().replace(/(\d+)(\d{3})/, '$1' + ',' + '$2');
13764						}
13765					}
13766					nums.unshift(newNum);
13767				}
13768				nums.push(numReal);
13769				$this.data('counterup-nums', nums);
13770				$this.text('0');
13771				// Updates the number until we're done
13772				var f = function() {
13773					if ($this.data('counterup-nums') != null) {
13774						$this.text($this.data('counterup-nums').shift());
13775						if ($this.data('counterup-nums').length) {
13776							setTimeout($this.data('counterup-func'), $settings.delay);
13777						} else {
13778							delete $this.data('counterup-nums');
13779							$this.data('counterup-nums', null);
13780							$this.data('counterup-func', null);
13781						}
13782					}
13783				};
13784				$this.data('counterup-func', f);
13785				// Start the count up
13786				setTimeout($this.data('counterup-func'), $settings.delay);
13787			};
13788			// Perform counts when the element gets into view
13789			if (!UNCODE.isMobile) {
13790				new Waypoint({
13791					element: this,
13792					handler: function() {
13793						counterUpper();
13794						this.destroy();
13795					},
13796					offset: '80%'
13797				});
13798			}
13799		});
13800	};
13801})(jQuery);
13802
13803/*!
13804 * The Final Countdown for jQuery v2.0.4 (http://hilios.github.io/jQuery.countdown/)
13805 * Copyright (c) 2014 Edson Hilios
13806 * 
13807 * Permission is hereby granted, free of charge, to any person obtaining a copy of
13808 * this software and associated documentation files (the "Software"), to deal in
13809 * the Software without restriction, including without limitation the rights to
13810 * use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of
13811 * the Software, and to permit persons to whom the Software is furnished to do so,
13812 * subject to the following conditions:
13813 * 
13814 * The above copyright notice and this permission notice shall be included in all
13815 * copies or substantial portions of the Software.
13816 * 
13817 * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
13818 * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS
13819 * FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR
13820 * COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER
13821 * IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN
13822 * CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
13823 */
13824!function(a){"use strict";"function"==typeof define&&define.amd?define(["jquery"],a):a(jQuery)}(function(a){"use strict";function b(a){if(a instanceof Date)return a;
13824if(String(a).match(h))return String(a).match(/^[0-9]*$/)&&(a=Number(a)),String(a).match(/\-/)&&(a=String(a).replace(/\-/g,"/")),new Date(a);throw new Error("Couldn't cast `"+a+"` to a date object.")}function c(a){var b=a.toString().replace(/([.?*+^$[\]\\(){}|-])/g,"\\$1");return new RegExp(b)}function d(a){return function(b){var d=b.match(/%(-|!)?[A-Z]{1}(:[^;]+;)?/gi);if(d)for(var f=0,g=d.length;g>f;++f){var h=d[f].match(/%(-|!)?([a-zA-Z]{1})(:[^;]+;)?/),j=c(h[0]),k=h[1]||"",l=h[3]||"",m=null;h=h[2],i.hasOwnProperty(h)&&(m=i[h],m=Number(a[m])),null!==m&&("!"===k&&(m=e(l,m)),""===k&&10>m&&(m="0"+m.toString()),b=b.replace(j,m.toString()))}return b=b.replace(/%%/,"%")}}function e(a,b){var c="s",d="";return a&&(a=a.replace(/(:|;|\s)/gi,"").split(/\,/),1===a.length?c=a[0]:(d=a[0],c=a[1])),1===Math.abs(b)?d:c}var f=100,g=[],h=[];h.push(/^[0-9]*$/.source),h.push(/([0-9]{1,2}\/){2}[0-9]{4}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),h.push(/[0-9]{4}([\/\-][0-9]{1,2}){2}( [0-9]{1,2}(:[0-9]{2}){2})?/.source),h=new RegExp(h.join("|"));var i={Y:"years",m:"months",w:"weeks",d:"days",D:"totalDays",H:"hours",M:"minutes",S:"seconds"},j=function(b,c,d){this.el=b,this.$el=a(b),this.interval=null,this.offset={},this.instanceNumber=g.length,g.push(this),this.$el.data("countdown-instance",this.instanceNumber),d&&(this.$el.on("update.countdown",d),this.$el.on("stoped.countdown",d),this.$el.on("finish.countdown",d)),this.setFinalDate(c),this.start()};a.extend(j.prototype,{start:function(){null!==this.interval&&clearInterval(this.interval);var a=this;this.update(),this.interval=setInterval(function(){a.update.call(a)},f)},stop:function(){clearInterval(this.interval),this.interval=null,this.dispatchEvent("stoped")},toggle:function(){this.interval?this.stop():this.start()},pause:function(){this.stop()},resume:function(){this.start()},remove:function(){this.stop.call(this),g[this.instanceNumber]=null,delete this.$el.data().countdownInstance},setFinalDate:function(a){this.finalDate=b(a)},update:function(){return 0===this.$el.closest("html").length?void this.remove():(this.totalSecsLeft=this.finalDate.getTime()-(new Date).getTime(),this.totalSecsLeft=Math.ceil(this.totalSecsLeft/1e3),this.totalSecsLeft=this.totalSecsLeft<0?0:this.totalSecsLeft,this.offset={seconds:this.totalSecsLeft%60,minutes:Math.floor(this.totalSecsLeft/60)%60,hours:Math.floor(this.totalSecsLeft/60/60)%24,days:Math.floor(this.totalSecsLeft/60/60/24)%7,totalDays:Math.floor(this.totalSecsLeft/60/60/24),weeks:Math.floor(this.totalSecsLeft/60/60/24/7),months:Math.floor(this.totalSecsLeft/60/60/24/30),years:Math.floor(this.totalSecsLeft/60/60/24/365)},void(0===this.totalSecsLeft?(this.stop(),this.dispatchEvent("finish")):this.dispatchEvent("update")))},dispatchEvent:function(b){var c=a.Event(b+".countdown");c.finalDate=this.finalDate,c.offset=a.extend({},this.offset),c.strftime=d(this.offset),this.$el.trigger(c)}}),a.fn.countdown=function(){var b=Array.prototype.slice.call(arguments,0);return this.each(function(){var c=a(this).data("countdown-instance");if(void 0!==c){var d=g[c],e=b[0];j.prototype.hasOwnProperty(e)?d[e].apply(d,b.slice(1)):null===String(e).match(/^[$A-Z_][0-9A-Z_$]*$/i)?(d.setFinalDate.call(d,e),d.start()):a.error("Method %s does not exist on jQuery.countdown".replace(/\%s/gi,e))}else new j(this,b[0],b[1])})}});
13825
13826/*! waitForImages jQuery Plugin - v2.0.2 - 2015-05-05
13827* https://github.com/alexanderdickson/waitForImages
13828* Copyright (c) 2015 Alex Dickson; Licensed MIT */
13829;(function (factory) {
13830    if (typeof define === 'function' && define.amd) {
13831        // AMD. Register as an anonymous module.
13832        define(['jquery'], factory);
13833    } else if (typeof exports === 'object') {
13834        // CommonJS / nodejs module
13835        module.exports = factory(require('jquery'));
13836    } else {
13837        // Browser globals
13838        factory(jQuery);
13839    }
13840}(function ($) {
13841    // Namespace all events.
13842    var eventNamespace = 'waitForImages';
13843
13844    // CSS properties which contain references to images.
13845    $.waitForImages = {
13846        hasImageProperties: [
13847            'backgroundImage',
13848            'listStyleImage',
13849            'borderImage',
13850            'borderCornerImage',
13851            'cursor'
13852        ],
13853        hasImageAttributes: ['srcset']
13854    };
13855
13856    // Custom selector to find `img` elements that have a valid `src`
13857    // attribute and have not already loaded.
13858    $.expr[':'].uncached = function (obj) {
13859        // Ensure we are dealing with an `img` element with a valid
13860        // `src` attribute.
13861        if (!$(obj).is('img[src][src!=""]')) {
13862            return false;
13863        }
13864
13865        return !obj.complete;
13866    };
13867
13868    $.fn.waitForImages = function () {
13869
13870        var allImgsLength = 0;
13871        var allImgsLoaded = 0;
13872        var deferred = $.Deferred();
13873
13874        var finishedCallback;
13875        var eachCallback;
13876        var waitForAll;
13877
13878        // Handle options object (if passed).
13879        if ($.isPlainObject(arguments[0])) {
13880
13881            waitForAll = arguments[0].waitForAll;
13882            eachCallback = arguments[0].each;
13883            finishedCallback = arguments[0].finished;
13884
13885        } else {
13886
13887            // Handle if using deferred object and only one param was passed in.
13888            if (arguments.length === 1 && $.type(arguments[0]) === 'boolean') {
13889                waitForAll = arguments[0];
13890            } else {
13891                finishedCallback = arguments[0];
13892                eachCallback = arguments[1];
13893                waitForAll = arguments[2];
13894            }
13895
13896        }
13897
13898        // Handle missing callbacks.
13899        finishedCallback = finishedCallback || $.noop;
13900        eachCallback = eachCallback || $.noop;
13901
13902        // Convert waitForAll to Boolean
13903        waitForAll = !! waitForAll;
13904
13905        // Ensure callbacks are functions.
13906        if (!$.isFunction(finishedCallback) || !$.isFunction(eachCallback)) {
13907            throw new TypeError('An invalid callback was supplied.');
13908        }
13909
13910        this.each(function () {
13911            // Build a list of all imgs, dependent on what images will
13912            // be considered.
13913            var obj = $(this);
13914            var allImgs = [];
13915            // CSS properties which may contain an image.
13916            var hasImgProperties = $.waitForImages.hasImageProperties || [];
13917            // Element attributes which may contain an image.
13918            var hasImageAttributes = $.waitForImages.hasImageAttributes || [];
13919            // To match `url()` references.
13920            // Spec: http://www.w3.org/TR/CSS2/syndata.html#value-def-uri
13921            var matchUrl = /url\(\s*(['"]?)(.*?)\1\s*\)/g;
13922
13923            if (waitForAll) {
13924
13925                // Get all elements (including the original), as any one of
13926                // them could have a background image.
13927                obj.find('*').addBack().each(function () {
13928                    var element = $(this);
13929
13930                    // If an `img` element, add it. But keep iterating in
13931                    // case it has a background image too.
13932                    if (element.is('img:uncached')) {
13933                        allImgs.push({
13934                            src: element.attr('src'),
13935                            element: element[0]
13936                        });
13937                    }
13938
13939                    $.each(hasImgProperties, function (i, property) {
13940                        var propertyValue = element.css(property);
13941                        var match;
13942
13943                        // If it doesn't contain this property, skip.
13944                        if (!propertyValue) {
13945                            return true;
13946                        }
13947
13948                        // Get all url() of this element.
13949                        while (match = matchUrl.exec(propertyValue)) {
13950                            allImgs.push({
13951                                src: match[2],
13952                                element: element[0]
13953                            });
13954                        }
13955                    });
13956
13957                    $.each(hasImageAttributes, function (i, attribute) {
13958                        var attributeValue = element.attr(attribute);
13959                        var attributeValues;
13960
13961                        // If it doesn't contain this property, skip.
13962                        if (!attributeValue) {
13963                            return true;
13964                        }
13965
13966                        // Check for multiple comma separated images
13967                        attributeValues = attributeValue.split(',');
13968
13969                        $.each(attributeValues, function(i, value) {
13970                            // Trim value and get string before first
13971                            // whitespace (for use with srcset).
13972                            value = $.trim(value).split(' ')[0];
13973                            allImgs.push({
13974                                src: value,
13975                                element: element[0]
13976                            });
13977                        });
13978                    });
13979                });
13980            } else {
13981                // For images only, the task is simpler.
13982                obj.find('img:uncached')
13983                    .each(function () {
13984                    allImgs.push({
13985                        src: this.src,
13986                        element: this
13987                    });
13988                });
13989            }
13990
13991            allImgsLength = allImgs.length;
13992            allImgsLoaded = 0;
13993
13994            // If no images found, don't bother.
13995            if (allImgsLength === 0) {
13996                finishedCallback.call(obj[0]);
13997                deferred.resolveWith(obj[0]);
13998            }
13999
14000            $.each(allImgs, function (i, img) {
14001
14002                var image = new Image();
14003                var events =
14004                  'load.' + eventNamespace + ' error.' + eventNamespace;
14005
14006                // Handle the image loading and error with the same callback.
14007                $(image).one(events, function me (event) {
14008                    // If an error occurred with loading the image, set the
14009                    // third argument accordingly.
14010                    var eachArguments = [
14011                        allImgsLoaded,
14012                        allImgsLength,
14013                        event.type == 'load'
14014                    ];
14015                    allImgsLoaded++;
14016
14017                    eachCallback.apply(img.element, eachArguments);
14018                    deferred.notifyWith(img.element, eachArguments);
14019
14020                    // Unbind the event listeners. I use this in addition to
14021                    // `one` as one of those events won't be called (either
14022                    // 'load' or 'error' will be called).
14023                    $(this).off(events, me);
14024
14025                    if (allImgsLoaded == allImgsLength) {
14026                        finishedCallback.call(obj[0]);
14027                        deferred.resolveWith(obj[0]);
14028                        return false;
14029                    }
14030
14031                });
14032
14033                image.src = img.src;
14034            });
14035        });
14036
14037        return deferred.promise();
14038
14039    };
14040}));
14041
14042/**
14043 * @preserve  textfill
14044 * @name      jquery.textfill.js
14045 * @author    Russ Painter
14046 * @author    Yu-Jie Lin
14047 * @author    Alexandre Dantas
14048 * @version   0.6.0
14049 * @date      2014-08-19
14050 * @copyright (c) 2014 Alexandre Dantas
14051 * @copyright (c) 2012-2013 Yu-Jie Lin
14052 * @copyright (c) 2009 Russ Painter
14053 * @license   MIT License
14054 * @homepage  https://github.com/jquery-textfill/jquery-textfill
14055 * @example   http://jquery-textfill.github.io/jquery-textfill/index.html
14056 */
14057; (function($) {
14058
14059	/**
14060	 * Resizes an inner element's font so that the
14061	 * inner element completely fills the outer element.
14062	 *
14063	 * @param {Object} options User options that take
14064	 *                         higher precedence when
14065	 *                         merging with the default ones.
14066	 *
14067	 * @return All outer elements processed
14068	 */
14069	$.fn.textfill = function(options) {
14070
14071		// ______  _______ _______ _______ _     _        _______ _______
14072		// |     \ |______ |______ |_____| |     | |         |    |______
14073		// |_____/ |______ |       |     | |_____| |_____    |    ______|
14074        //
14075		// Merging user options with the default values
14076
14077		var defaults = {
14078			debug            : false,
14079			maxFontPixels    : 40,
14080			minFontPixels    : 4,
14081			innerTag         : 'span',
14082			widthOnly        : false,
14083			success          : null, // callback when a resizing is done
14084			callback         : null, // callback when a resizing is done (deprecated, use success)
14085			fail             : null, // callback when a resizing is failed
14086			complete         : null, // callback when all is done
14087			explicitWidth    : null,
14088			explicitHeight   : null,
14089			changeLineHeight : false
14090		};
14091
14092		var Opts = $.extend(defaults, options);
14093
14094		// _______ _     _ __   _ _______ _______ _____  _____  __   _ _______
14095		// |______ |     | | \  | |          |      |   |     | | \  | |______
14096		// |       |_____| |  \_| |_____     |    __|__ |_____| |  \_| ______|
14097		//
14098		// Predefining the awesomeness
14099
14100		// Output arguments to the Debug console
14101		// if "Debug Mode" is enabled
14102		function _debug() {
14103			if (!Opts.debug
14104				||  typeof console       == 'undefined'
14105				||  typeof console.debug == 'undefined') {
14106				return;
14107			}
14108			console.debug.apply(console, arguments);
14109		}
14110
14111		// Output arguments to the Warning console
14112		function _warn() {
14113			if (typeof console      == 'undefined' ||
14114				typeof console.warn == 'undefined') {
14115				return;
14116			}
14117			console.warn.apply(console, arguments);
14118		}
14119
14120		// Outputs all information on the current sizing
14121		// of the font.
14122		function _debug_sizing(prefix, ourText, maxHeight, maxWidth, minFontPixels, maxFontPixels) {
14123
14124			function _m(v1, v2) {
14125
14126				var marker = ' / ';
14127
14128				if (v1 > v2)
14129					marker = ' > ';
14130
14131				else if (v1 == v2)
14132					marker = ' = ';
14133
14134				return marker;
14135			}
14136
14137			_debug(
14138				'[TextFill] '  + prefix + ' { ' +
14139				'font-size: ' + ourText.css('font-size') + ',' +
14140				'Height: '    + ourText.height() + 'px ' + _m(ourText.height(), maxHeight) + maxHeight + 'px,' +
14141				'Width: '     + ourText.width()  + _m(ourText.width() , maxWidth)  + maxWidth + ',' +
14142				'minFontPixels: ' + minFontPixels + 'px, ' +
14143				'maxFontPixels: ' + maxFontPixels + 'px }'
14144			);
14145		}
14146
14147		/**
14148		 * Calculates which size the font can get resized,
14149		 * according to constrains.
14150		 *
14151		 * @param {String} prefix Gets shown on the console before
14152		 *                        all the arguments, if debug mode is on.
14153		 * @param {Object} ourText The DOM element to resize,
14154		 *                         that contains the text.
14155		 * @param {function} func Function called on `ourText` that's
14156		 *                        used to compare with `max`.
14157		 * @param {number} max Maximum value, that gets compared with
14158		 *                     `func` called on `ourText`.
14159		 * @param {number} minFontPixels Minimum value the font can
14160		 *                               get resized to (in pixels).
14161		 * @param {number} maxFontPixels Maximum value the font can
14162		 *                               get resized to (in pixels).
14163		 *
14164		 * @return Size (in pixels) that the font can be resized.
14165		 */
14166		function _sizing(prefix, ourText, func, max, maxHeight, maxWidth, minFontPixels, maxFontPixels) {
14167
14168			_debug_sizing(
14169				prefix, ourText,
14170				maxHeight, maxWidth,
14171				minFontPixels, maxFontPixels
14172			);
14173
14174			// The kernel of the whole plugin, take most attention
14175			// on this part.
14176			//
14177			// This is a loop that keeps increasing the `font-size`
14178			// until it fits the parent element.
14179			//
14180			// - Start from the minimal allowed value (`minFontPixels`)
14181			// - Guesses an average font size (in pixels) for the font,
14182			// - Resizes the text and sees if its size is within the
14183			//   boundaries (`minFontPixels` and `maxFontPixels`).
14184			//   - If so, keep guessing until we break.
14185			//   - If not, return the last calculated size.
14186			//
14187			// I understand this is not optimized and we should
14188			// consider implementing something akin to
14189			// Daniel Hoffmann's answer here:
14190			//
14191			//     http://stackoverflow.com/a/17433451/1094964
14192			//
14193
14194			while (minFontPixels < (maxFontPixels - 1)) {
14195
14196				var fontSize = Math.floor((minFontPixels + maxFontPixels) / 2);
14197				ourText.css('font-size', fontSize);
14198
14199				if (func.call(ourText) <= max) {
14200					minFontPixels = fontSize;
14201
14202					if (func.call(ourText) == max)
14203						break;
14204				}
14205				else
14206					maxFontPixels = fontSize;
14207
14208				_debug_sizing(
14209					prefix, ourText,
14210					maxHeight, maxWidth,
14211					minFontPixels, maxFontPixels
14212				);
14213			}
14214
14215			ourText.css('font-size', maxFontPixels);
14216
14217			if (func.call(ourText) <= max) {
14218				minFontPixels = maxFontPixels;
14219
14220				_debug_sizing(
14221					prefix + '* ', ourText,
14222					maxHeight, maxWidth,
14223					minFontPixels, maxFontPixels
14224				);
14225			}
14226			return minFontPixels;
14227		}
14228
14229		// _______ _______ _______  ______ _______
14230		// |______    |    |_____| |_____/    |
14231		// ______|    |    |     | |    \_    |
14232        //
14233		// Let's get it started (yeah)!
14234
14235		_debug('[TextFill] Start Debug');
14236
14237		this.each(function() {
14238
14239			// Contains the child element we will resize.
14240			// $(this) means the parent container
14241			var ourText = $(Opts.innerTag + ':visible:first', this);
14242
14243			// Will resize to this dimensions.
14244			// Use explicit dimensions when specified
14245			var maxHeight = Opts.explicitHeight || $(this).height();
14246			var maxWidth  = Opts.explicitWidth  || $(this).width();
14247
14248			var oldFontSize = ourText.css('font-size');
14249
14250			var lineHeight  = parseFloat(ourText.css('line-height')) / parseFloat(oldFontSize);
14251
14252			_debug('[TextFill] Inner text: ' + ourText.text());
14253			_debug('[TextFill] All options: ', Opts);
14254			_debug('[TextFill] Maximum sizes: { ' +
14255				   'Height: ' + maxHeight + 'px, ' +
14256				   'Width: '  + maxWidth  + 'px' + ' }'
14257				  );
14258
14259			var minFontPixels = Opts.minFontPixels;
14260
14261			// Remember, if this `maxFontPixels` is negative,
14262			// the text will resize to as long as the container
14263			// can accomodate
14264			var maxFontPixels = (Opts.maxFontPixels <= 0 ?
14265								 maxHeight :
14266								 Opts.maxFontPixels);
14267
14268
14269			// Let's start it all!
14270
14271			// 1. Calculate which `font-size` would
14272			//    be best for the Height
14273			var fontSizeHeight = undefined;
14274
14275			if (! Opts.widthOnly)
14276				fontSizeHeight = _sizing(
14277					'Height', ourText,
14278					$.fn.height, maxHeight,
14279					maxHeight, maxWidth,
14280					minFontPixels, maxFontPixels
14281				);
14282
14283			// 2. Calculate which `font-size` would
14284			//    be best for the Width
14285			var fontSizeWidth = undefined;
14286
14287			fontSizeWidth = _sizing(
14288				'Width', ourText,
14289				$.fn.width, maxWidth,
14290				maxHeight, maxWidth,
14291				minFontPixels, maxFontPixels
14292			);
14293
14294			// 3. Actually resize the text!
14295
14296			if (Opts.widthOnly) {
14297				ourText.css({
14298					'font-size'  : fontSizeWidth,
14299					'white-space': 'nowrap'
14300				});
14301
14302				if (Opts.changeLineHeight)
14303					ourText.parent().css(
14304						'line-height',
14305						(lineHeight * fontSizeWidth + 'px')
14306					);
14307			}
14308			else {
14309				var fontSizeFinal = Math.min(fontSizeHeight, fontSizeWidth);
14310
14311				ourText.css('font-size', fontSizeFinal);
14312
14313				if (Opts.changeLineHeight)
14314					ourText.parent().css(
14315						'line-height',
14316						(lineHeight * fontSizeFinal) + 'px'
14317					);
14318			}
14319
14320			_debug(
14321				'[TextFill] Finished { ' +
14322				'Old font-size: ' + oldFontSize              + ', ' +
14323				'New font-size: ' + ourText.css('font-size') + ' }'
14324			);
14325
14326			// Oops, something wrong happened!
14327			// We weren't supposed to exceed the original size
14328			if ((ourText.width()  > maxWidth) ||
14329				(ourText.height() > maxHeight && !Opts.widthOnly)) {
14330
14331				ourText.css('font-size', oldFontSize);
14332
14333				// Failure callback
14334				if (Opts.fail)
14335					Opts.fail(this);
14336
14337				_debug(
14338					'[TextFill] Failure { ' +
14339					'Current Width: '  + ourText.width()  + ', ' +
14340					'Maximum Width: '  + maxWidth         + ', ' +
14341					'Current Height: ' + ourText.height() + ', ' +
14342					'Maximum Height: ' + maxHeight        + ' }'
14343				);
14344			}
14345			else if (Opts.success) {
14346				Opts.success(this);
14347			}
14348			else if (Opts.callback) {
14349				_warn('callback is deprecated, use success, instead');
14350
14351				// Success callback
14352				Opts.callback(this);
14353			}
14354		});
14355
14356		// Complete callback
14357		if (Opts.complete)
14358			Opts.complete(this);
14359
14360		_debug('[TextFill] End Debug');
14361		return this;
14362	};
14363
14364})(window.jQuery);
14365
14366
14367!function(e){if("object"==typeof exports&&"undefined"!=typeof module)module.exports=e();else if("function"==typeof define&&define.amd)define([],e);else{var f;"undefined"!=typeof window?f=window:"undefined"!=typeof global?f=global:"undefined"!=typeof self&&(f=self),f.Share=e()}}(function(){var define,module,exports;
14368function getStyles(config){
14369  // return ""+config.selector+"{width:92px;height:20px;-webkit-touch-callout:none;-khtml-user-select:none;-webkit-user-select:none;-moz-user-select:none;-ms-user-select:none;user-select:none}"+config.selector+" [class*=social-]:before{font-family:'uncodeicon'}"+config.selector+" label{font-size:16px;cursor:pointer;margin:0;padding:5px 10px;border-radius:5px;background:#a29baa;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}"+config.selector+" label:hover{opacity:.8}"+config.selector+" label span{text-transform:uppercase;font-size:.9em;font-family:Lato,sans-serif;font-weight:700;-webkit-font-smoothing:antialiased;padding-left:6px}"+config.selector+" .social{opacity:0;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;margin-left:-15px;visibility:hidden}"+config.selector+" .social.top{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;margin-top:-80px}"+config.selector+" .social.bottom{-webkit-transform-origin:0 0;-ms-transform-origin:0 0;transform-origin:0 0;margin-top:5px}"+config.selector+" .social.middle{margin-top:-34px}"+config.selector+" .social.middle.right{-webkit-transform-origin:5% 50%;-ms-transform-origin:5% 50%;transform-origin:5% 50%;margin-left:105px}"+config.selector+" .social.middle.left{-webkit-transform-origin:5% 50%;-ms-transform-origin:5% 50%;transform-origin:5% 50%}"+config.selector+" .social.right{margin-left:14px}"+config.selector+" .social.load{-webkit-transition:none!important;transition:none!important}"+config.selector+" .social.networks-1{width:60px}"+config.selector+" .social.networks-1.center,"+config.selector+" .social.networks-1.left{margin-left:14px}"+config.selector+" .social.networks-1.middle.left{margin-left:-70px}"+config.selector+" .social.networks-1 ul{width:60px}"+config.selector+" .social.networks-2{width:120px}"+config.selector+" .social.networks-2.center{margin-left:-13px}"+config.selector+" .social.networks-2.left{margin-left:-44px}"+config.selector+" .social.networks-2.middle.left{margin-left:-130px}"+config.selector+" .social.networks-2 ul{width:120px}"+config.selector+" .social.networks-3{width:180px}"+config.selector+" .social.networks-3.center{margin-left:-45px}"+config.selector+" .social.networks-3.left{margin-left:-102px}"+config.selector+" .social.networks-3.middle.left{margin-left:-190px}"+config.selector+" .social.networks-3 ul{width:180px}"+config.selector+" .social.networks-4{width:240px}"+config.selector+" .social.networks-4.center{margin-left:-75px}"+config.selector+" .social.networks-4.left{margin-left:162px}"+config.selector+" .social.networks-4.middle.left{margin-left:-250px}"+config.selector+" .social.networks-4 ul{width:240px}"+config.selector+" .social.networks-5{width:300px}"+config.selector+" .social.networks-5.center{margin-left:-105px}"+config.selector+" .social.networks-5.left{margin-left:-225px}"+config.selector+" .social.networks-5.middle.left{margin-left:-320px}"+config.selector+" .social.networks-5 ul{width:300px}"+config.selector+" .social.active{opacity:1;-webkit-transition:all .2s ease-in-out;transition:all .2s ease-in-out;visibility:visible}"+config.selector+" .social.active.top{-webkit-transform:scale(1) translateY(-20px);-ms-transform:scale(1) translateY(-20px);transform:scale(1) translateY(-20px)}"+config.selector+" .social.active.bottom{-webkit-transform:scale(1) translateY(15px);-ms-transform:scale(1) translateY(15px);transform:scale(1) translateY(15px)}"+config.selector+" .social.active.middle.right{-webkit-transform:scale(1) translateX(10px);-ms-transform:scale(1) translateX(10px);transform:scale(1) translateX(10px)}"+config.selector+" .social.active.middle.left{-webkit-transform:scale(1) translateX(-20px);-ms-transform:scale(1) translateX(-20px);transform:scale(1) translateX(-20px)}"+config.selector+" .social ul{position:relative;
14369left:0;right:0;height:46px;color:#fff;margin:auto;padding:0;list-style:none}"+config.selector+" .social ul li{font-size:20px;cursor:pointer;width:60px;margin:0;padding:12px 0;text-align:center;float:left;display:none;height:22px;position:relative;z-index:2;-webkit-box-sizing:content-box;-moz-box-sizing:content-box;box-sizing:content-box;-webkit-transition:all .3s ease-in-out;transition:all .3s ease-in-out}"+config.selector+" .social ul li:hover{}"+config.selector+" .social li[class*=facebook]{display:"+config.networks.facebook.display+"}"+config.selector+" .social li[class*=twitter]{display:"+config.networks.twitter.display+"}"+config.selector+" .social li[class*=gplus]{display:"+config.networks.google_plus.display+"}"+config.selector+" .social li[class*=pinterest]{display:"+config.networks.pinterest.display+"}"+config.selector+" .social li[class*=paper-plane]{display:"+config.networks.email.display+"}"
14370};
14371  var ShareUtils;
14372
14373if ((!("classList" in document.documentElement)) && Object.defineProperty && typeof HTMLElement !== "undefined") {
14374  Object.defineProperty(HTMLElement.prototype, "classList", {
14375    get: function() {
14376      var ret, self, update;
14377      update = function(fn) {
14378        return function(value) {
14379          var classes, index;
14380          classes = self.className.split(/\s+/);
14381          index = classes.indexOf(value);
14382          fn(classes, index, value);
14383          self.className = classes.join(" ");
14384        };
14385      };
14386      self = this;
14387      ret = {
14388        add: update(function(classes, index, value) {
14389          ~index || classes.push(value);
14390        }),
14391        remove: update(function(classes, index) {
14392          ~index && classes.splice(index, 1);
14393        }),
14394        toggle: update(function(classes, index, value) {
14395          if (~index) {
14396            classes.splice(index, 1);
14397          } else {
14398            classes.push(value);
14399          }
14400        }),
14401        contains: function(value) {
14402          return !!~self.className.split(/\s+/).indexOf(value);
14403        },
14404        item: function(i) {
14405          return self.className.split(/\s+/)[i] || null;
14406        }
14407      };
14408      Object.defineProperty(ret, "length", {
14409        get: function() {
14410          return self.className.split(/\s+/).length;
14411        }
14412      });
14413      return ret;
14414    }
14415  });
14416}
14417
14418String.prototype.to_rfc3986 = function() {
14419  var tmp;
14420  tmp = encodeURIComponent(this);
14421  return tmp.replace(/[!'()*]/g, function(c) {
14422    return "%" + c.charCodeAt(0).toString(16);
14423  });
14424};
14425
14426ShareUtils = (function() {
14427  function ShareUtils() {}
14428
14429  ShareUtils.prototype.extend = function(to, from, overwrite) {
14430    var hasProp, prop;
14431    for (prop in from) {
14432      hasProp = to[prop] !== undefined;
14433      if (hasProp && typeof from[prop] === "object") {
14434        this.extend(to[prop], from[prop], overwrite);
14435      } else {
14436        if (overwrite || !hasProp) {
14437          to[prop] = from[prop];
14438        }
14439      }
14440    }
14441  };
14442
14443  ShareUtils.prototype.hide = function(el) {
14444    return el.style.display = "none";
14445  };
14446
14447  ShareUtils.prototype.show = function(el) {
14448    return el.style.display = "block";
14449  };
14450
14451  ShareUtils.prototype.has_class = function(el, class_name) {
14452    return el.classList.contains(class_name);
14453  };
14454
14455  ShareUtils.prototype.add_class = function(el, class_name) {
14456    return el.classList.add(class_name);
14457  };
14458
14459  ShareUtils.prototype.remove_class = function(el, class_name) {
14460    return el.classList.remove(class_name);
14461  };
14462
14463  ShareUtils.prototype.is_encoded = function(str) {
14464    str = str.to_rfc3986();
14465    return decodeURIComponent(str) !== str;
14466  };
14467
14468  ShareUtils.prototype.encode = function(str) {
14469    if (typeof str === "undefined" || this.is_encoded(str)) {
14470      return str;
14471    } else {
14472      return str.to_rfc3986();
14473    }
14474  };
14475
14476  ShareUtils.prototype.popup = function(url, params) {
14477    var k, popup, qs, v;
14478    if (params == null) {
14479      params = {};
14480    }
14481    popup = {
14482      width: 500,
14483      height: 350
14484    };
14485    popup.top = (screen.height / 2) - (popup.height / 2);
14486    popup.left = (screen.width / 2) - (popup.width / 2);
14487    qs = ((function() {
14488      var _results;
14489      _results = [];
14490      for (k in params) {
14491        v = params[k];
14492        _results.push("" + k + "=" + (this.encode(v)));
14493      }
14494      return _results;
14495    }).call(this)).join('&');
14496    if (qs) {
14497      qs = "?" + qs;
14498    }
14499    return window.open(url + qs, 'targetWindow', "toolbar=no,location=no,status=no,menubar=no,scrollbars=yes,resizable=yes,left=" + popup.left + ",top=" + popup.top + ",width=" 
14499+ popup.width + ",height=" + popup.height);
14500  };
14501
14502  return ShareUtils;
14503
14504})();
14505var Share,
14506  __hasProp = {}.hasOwnProperty,
14507  __extends = function(child, parent) { for (var key in parent) { if (__hasProp.call(parent, key)) child[key] = parent[key]; } function ctor() { this.constructor = child; } ctor.prototype = parent.prototype; child.prototype = new ctor(); child.__super__ = parent.prototype; return child; };
14508
14509Share = (function(_super) {
14510  __extends(Share, _super);
14511
14512  function Share(element, options) {
14513    this.element = element;
14514    this.el = {
14515      head: document.getElementsByTagName('head')[0],
14516      body: document.getElementsByTagName('body')[0]
14517    };
14518    this.config = {
14519      enabled_networks: 0,
14520      protocol: ['http', 'https'].indexOf(window.location.href.split(':')[0]) === -1 ? 'https://' : '//',
14521      url: window.location.href,
14522      caption: null,
14523      title: this.default_title(),
14524      image: this.default_image(),
14525      description: this.default_description(),
14526      ui: {
14527        flyout: 'top center',
14528        button_text: 'Share',
14529        button_font: true,
14530        icon_font: true
14531      },
14532      networks: {
14533        google_plus: {
14534          enabled: true,
14535          url: null
14536        },
14537        twitter: {
14538          enabled: true,
14539          url: null,
14540          title: null,
14541          description: null
14542        },
14543        facebook: {
14544          enabled: true,
14545          load_sdk: true,
14546          url: null,
14547          app_id: null,
14548          title: null,
14549          caption: null,
14550          description: null,
14551          image: null
14552        },
14553        pinterest: {
14554          enabled: true,
14555          url: null,
14556          image: null,
14557          description: null
14558        },
14559        reddit: {
14560          enabled: true,
14561          url: null,
14562          title: null
14563        },
14564        linkedin: {
14565          enabled: true,
14566          url: null,
14567          title: null,
14568          description: null
14569        },
14570        xing: {
14571          enabled: true,
14572          url: null,
14573          title: null,
14574          image: null,
14575          description: null
14576        },
14577        whatsapp: {
14578          enabled: true,
14579          description: null,
14580          url: null
14581        },
14582        email: {
14583          enabled: true,
14584          title: null,
14585          description: null,
14586          url: null
14587        }
14588      }
14589    };
14590    this.setup(element, options);
14591    return this;
14592  }
14593
14594  Share.prototype.setup = function(element, opts) {
14595    var index, instance, instances, _i, _len;
14596    instances = document.querySelectorAll(element);
14597    this.extend(this.config, opts, true);
14598    this.set_global_configuration();
14599    this.normalize_network_configuration();
14600    if (this.config.ui.icon_font) {
14601      this.inject_icons();
14602    }
14603    if (this.config.ui.button_font) {
14604      this.inject_fonts();
14605    }
14606    if (this.config.networks.facebook.enabled && this.config.networks.facebook.load_sdk) {
14607      this.inject_facebook_sdk();
14608    }
14609    for (index = _i = 0, _len = instances.length; _i < _len; index = ++_i) {
14610      instance = instances[index];
14611      this.setup_instance(element, index);
14612    }
14613  };
14614
14615  Share.prototype.setup_instance = function(element, index) {
14616    var button, instance, label, network, networks, _i, _len, _results,
14617      _this = this;
14618    instance = document.querySelectorAll(element)[index];
14619    this.hide(instance);
14620    this.add_class(instance, "sharer-" + index);
14621    instance = document.querySelectorAll(element)[index];
14622    this.inject_css(instance);
14623    this.inject_html(instance);
14624    this.show(instance);
14625    label = instance.getElementsByTagName("label")[0];
14626    button = instance.getElementsByClassName("social")[0];
14627    networks = instance.getElementsByTagName('li');
14628    this.add_class(button, "networks-" + this.config.enabled_networks);
14629    label.addEventListener("click", function() {
14630      return _this.event_toggle(button);
14631    });
14632    _this = this;
14633    _results = [];
14634    for (index = _i = 0, _len = networks.length; _i < _len; index = ++_i) {
14635      network = networks[index];
14636      _results.push(network.addEventListener("click", function() {
14637        _this.event_network(instance, this);
14638        return _this.event_close(button);
14639      }));
14640    }
14641    return _results;
14642  };
14643
14644  Share.prototype.event_toggle = function(button) {
14645    if (this.has_class(button, "active")) {
14646      return this.event_close(button);
14647    } else {
14648      return this.event_open(button);
14649    }
14650  };
14651
14652  Share.prototype.event_open = function(button) {
14653    if (this.has_class(button, "load")) {
14654      this.remove_class(button, "load");
14655    }
14656    return this.add_class(button, "active");
14657  };
14658
14659  Share.prototype.event_close = function(button) {
14660    return this.remove_class(button, "active");
14661  };
14662
14663  Share.prototype.event_network = function(instance, network) {
14664    var name;
14665    name = network.getAttribute("data-network");
14666    this.hook("before", name, instance);
14667    this["network_" + name]();
14668    return this.hook("after", name, instance);
14669  };
14670
14671  Share.prototype.open = function() {
14672    return this["public"]("open");
14673  };
14674
14675  Share.prototype.close = function() {
14676    return this["public"]("close");
14677  };
14678
14679  Share.prototype.toggle = function() {
14680    return this["public"]("toggle");
14681  };
14682
14683  Share.prototype["public"] = function(action) {
14684    var button, index, instance, _i, _len, _ref, _results;
14685    _ref = document.querySelectorAll(this.element);
14686    _results = [];
14687    for (index = _i = 0, _len = _ref.length; _i < _len; index = ++_i) {
14688      instance = _ref[index];
14689      button = instance.getElementsByClassName("social")[0];
14690      _results.push(this["event_" + action](button));
14691    }
14692    return _results;
14693  };
14694
14695  Share.prototype.network_facebook = function() {
14696    if (this.config.networks.facebook.load_sdk) {
14697      if (!window.FB) {
14698        return console.error("The Facebook JS SDK hasn't loaded yet.");
14699      }
14700      return FB.ui({
14701        method: 'feed',
14702        name: this.config.networks.facebook.title,
14703        link: this.config.networks.facebook.url,
14704        picture: this.config.networks.facebook.image,
14705        caption: this.config.networks.facebook.caption,
14706        description: this.config.networks.facebook.description
14707      });
14708    } else {
14709      return this.popup('https://www.facebook.com/sharer/sharer.php', {
14710        u: this.config.networks.facebook.url
14711      });
14712    }
14713  };
14714
14715  Share.prototype.network_twitter = function() {
14716    return this.popup('https://twitter.com/intent/tweet', {
14717      text: this.config.networks.twitter.title,
14718      url: this.config.networks.twitter.url
14719    });
14720  };
14721
14722  Share.prototype.network_google_plus = function() {
14723    return this.popup('https://plus.google.com/share', {
14724      url: this.config.networks.google_plus.url
14725    });
14726  };
14727
14728  Share.prototype.network_pinterest = function() {
14729    return this.popup('https://www.pinterest.com/pin/create/button', {
14730      url: this.config.networks.pinterest.url,
14731      media: this.config.networks.pinterest.image,
14732      description: this.config.networks.pinterest.description
14733    });
14734  };
14735
14736  Share.prototype.network_linkedin = function() {
14737    return this.popup('https://www.linkedin.com/shareArticle', {
14738      url: this.config.networks.linkedin.url,
14739      title: this.config.networks.linkedin.title,
14740      summary: this.config.networks.linkedin.description
14741    });
14742  }
14743
14744  Share.prototype.network_xing = function() {
14745    return this.popup('https://www.xing.com/spi/shares/new', {
14746      url: this.config.networks.xing.url,
14747      image: this.config.networks.xing.image,
14748      title: this.config.networks.xing.title,
14749      summary: this.config.networks.xing.description
14750    });
14751  }
14752
14753  Share.prototype.network_email = function() {
14754    return this.popup('mailto:', {
14755      subject: this.config.networks.email.title,
14756      body: this.config.networks.email.url + '%0A%0A' + this.config.networks.email.description,
14757    });
14758  };
14759
14760  Share.prototype.inject_icons = function() {
14761  //  return this.inject_stylesheet("https://www.sharebutton.co/fonts/v2/entypo.min.css");
14762  };
14763
14764  Share.prototype.inject_fonts = function() {
14765   // return this.inject_stylesheet("http://fonts.googleapis.com/css?family=Lato:900&text=" + this.config.ui.button_text);
14766  };
14767
14768  Share.prototype.inject_stylesheet = function(url) {
14769    var link;
14770    if (!this.el.head.querySelector("link[href=\"" + url + "\"]")) {
14771      link = document.createElement("link");
14772      link.setAttribute("rel", "stylesheet");
14773      link.setAttribute("href", url);
14774      return this.el.head.appendChild(link);
14775    }
14776  };
14777
14778  Share.prototype.inject_css = function(instance) {
14779    var css, meta, selector, style;
14780    selector = "." + (instance.getAttribute('class').split(" ").join("."));
14781    if (!this.el.head.querySelector("meta[name='sharer" + selector + "']")) {
14782      this.config.selector = selector;
14783      css = getStyles(this.config);
14784      style = document.createElement("style");
14785      style.type = "text/css";
14786      if (style.styleSheet) {
14787        style.styleSheet.cssText = css;
14788      } else {
14789        style.appendChild(document.createTextNode(css));
14790      }
14791      this.el.head.appendChild(style);
14792      delete this.config.selector;
14793      meta = document.createElement("meta");
14794      meta.setAttribute("name", "sharer" + selector);
14795      return this.el.head.appendChild(meta);
14796    }
14797  };
14798
14799  Share.prototype.inject_html = function(instance) {
14800    return instance.innerHTML = "<label class='social-export'><span>" + this.config.ui.button_text + "</span></label><div class='social load " + this.config.ui.flyout + "'><ul><li class='social-facebook' data-network='facebook' tabindex='0'></li><li class='social-twitter' data-network='twitter' tabindex='0'></li><li class='social-gplus' data-network='google_plus' tabindex='0'></li><li class='social-pinterest' data-network='pinterest' tabindex='0'></li><li class='social-linkedin' data-network='linkedin' tabindex='0'></li><li class='social-xing' data-network='xing' tabindex='0'></li><li class='social-paper-plane' data-network='email' tabindex='0'></li></ul></div>";
14801  };
14802
14803  Share.prototype.inject_facebook_sdk = function() {
14804    var fb_root, script;
14805    if (!window.FB && this.config.networks.facebook.app_id && !this.el.body.querySelector('#fb-root')) {
14806      script = document.createElement("script");
14807      script.text = "window.fbAsyncInit=function(){FB.init({appId:'" + this.config.networks.facebook.app_id + "',status:true,xfbml:true})};(function(e,t,n){var r,i=e.getElementsByTagName(t)[0];if(e.getElementById(n)){return}r=e.createElement(t);r.id=n;r.src='" + this.config.protocol + "connect.facebook.net/en_US/all.js';i.parentNode.insertBefore(r,i)})(document,'script','facebook-jssdk')";
14808      fb_root = document.createElement("div");
14809      fb_root.id = "fb-root";
14810      this.el.body.appendChild(fb_root);
14811      return this.el.body.appendChild(script);
14812    }
14813  };
14814
14815  Share.prototype.hook = function(type, network, instance) {
14816    var fn, opts;
14817    fn = this.config.networks[network][type];
14818    if (typeof fn === "function") {
14819      opts = fn.call(this.config.networks[network], instance);
14820      if (opts !== void 0) {
14821        opts = this.normalize_filter_config_updates(opts);
14822        this.extend(this.config.networks[network], opts, true);
14823        this.normalize_network_configuration();
14824      }
14825    }
14826  };
14827
14828  Share.prototype.default_title = function() {
14829    var content;
14830    if (content = document.querySelector('meta[property="og:title"]') || document.querySelector('meta[name="twitter:title"]')) {
14831      return encodeURIComponent(content.getAttribute('content'));
14832    } else if (content = document.querySelector('title')) {
14833      return encodeURIComponent(content.innerText);
14834    }
14835  };
14836
14837  Share.prototype.default_image = function() {
14838    var content;
14839    if (content = document.querySelector('meta[property="og:image"]') || document.querySelector('meta[name="twitter:image"]')) {
14840      return content.getAttribute('content');
14841    }
14842  };
14843
14844  Share.prototype.default_description = function() {
14845    var content;
14846    if (content = document.querySelector('meta[property="og:description"]') || document.querySelector('meta[name="twitter:description"]') || document.querySelector('meta[name="description"]')) {
14847      return content.getAttribute('content');
14848    } else {
14849      return '';
14850    }
14851  };
14852
14853  Share.prototype.set_global_configuration = function() {
14854    var display, network, option, options, _ref, _results;
14855    _ref = this.config.networks;
14856    _results = [];
14857    for (network in _ref) {
14858      options = _ref[network];
14859      for (option in options) {
14860        if (this.config.networks[network][option] == null) {
14861          this.config.networks[network][option] = this.config[option];
14862        }
14863      }
14864      if (this.config.networks[network].enabled) {
14865        display = 'block';
14866        this.config.enabled_networks += 1;
14867      } else {
14868        display = 'none';
14869      }
14870      _results.push(this.config.networks[network].display = display);
14871    }
14872    return _results;
14873  };
14874
14875  Share.prototype.normalize_network_configuration = function() {
14876    if (!this.config.networks.facebook.app_id) {
14877      this.config.networks.facebook.load_sdk = false;
14878    }
14879    if (!this.is_encoded(this.config.networks.twitter.description)) {
14880      this.config.networks.twitter.description = encodeURIComponent(this.config.networks.twitter.description);
14881    }
14882    if (typeof this.config.networks.facebook.app_id === 'number') {
14883      return this.config.networks.facebook.app_id = this.config.networks.facebook.app_id.toString();
14884    }
14885  };
14886
14887  Share.prototype.normalize_filter_config_updates = function(opts) {
14888    if (this.config.networks.facebook.app_id !== opts.app_id) {
14889      console.warn("You are unable to change the Facebook app_id after the button has been initialized. Please-in-out update your Facebook filters accordingly.");
14890      delete opts.app_id;
14891    }
14892    if (this.config.networks.facebook.load_sdk !== opts.load_sdk) {
14893      console.warn("You are unable to change the Facebook load_sdk option after the button has been initialized. Please-in-out update your Facebook filters accordingly.");
14894      delete opts.app_id;
14895    }
14896    return opts;
14897  };
14898
14899  return Share;
14900
14901})(ShareUtils);
14902 return Share;
14903});
14904
14905
14906// Generated by CoffeeScript 1.9.2
14907
14908// @license Sticky-kit v1.1.2 | WTFPL | Leaf Corcoran 2015 | http://leafo.net
14909
14910(function() {
14911  var $, win;
14912
14913  $ = this.jQuery || window.jQuery;
14914
14915  win = $(window);
14916
14917  $.fn.stick_in_parent = function(opts) {
14918    var doc, elm, enable_bottoming, fn, i, inner_scrolling, len, manual_spacer, offset_top, outer_width, parent_selector, recalc_every, sticky_class;
14919    if (opts == null) {
14920      opts = {};
14921    }
14922    sticky_class = opts.sticky_class, inner_scrolling = opts.inner_scrolling, recalc_every = opts.recalc_every, parent_selector = opts.parent, offset_top = opts.offset_top, manual_spacer = opts.spacer, enable_bottoming = opts.bottoming;
14923    if (offset_top == null) {
14924      offset_top = 0;
14925    }
14926    if (parent_selector == null) {
14927      parent_selector = void 0;
14928    }
14929    if (inner_scrolling == null) {
14930      inner_scrolling = true;
14931    }
14932    if (sticky_class == null) {
14933      sticky_class = "is_stuck";
14934    }
14935    doc = $(document);
14936    if (enable_bottoming == null) {
14937      enable_bottoming = true;
14938    }
14939    outer_width = function(el) {
14940      var _el, computed, w;
14941      if (window.getComputedStyle) {
14942        _el = el[0];
14943        computed = window.getComputedStyle(el[0]);
14944        w = parseFloat(computed.getPropertyValue("width")) + parseFloat(computed.getPropertyValue("margin-left")) + parseFloat(computed.getPropertyValue("margin-right"));
14945        if (computed.getPropertyValue("box-sizing") !== "border-box") {
14946          w += parseFloat(computed.getPropertyValue("border-left-width")) + parseFloat(computed.getPropertyValue("border-right-width")) + parseFloat(computed.getPropertyValue("padding-left")) + parseFloat(computed.getPropertyValue("padding-right"));
14947        }
14948        return w;
14949      } else {
14950        return el.outerWidth(true);
14951      }
14952    };
14953    fn = function(elm, padding_bottom, parent_top, parent_height, top, height, el_float, detached) {
14954      var bottomed, detach, fixed, last_pos, last_scroll_height, offset, parent, recalc, recalc_and_tick, recalc_counter, spacer, tick;
14955      if (elm.data("sticky_kit")) {
14956        return;
14957      }
14958      elm.data("sticky_kit", true);
14959      last_scroll_height = doc.height();
14960      parent = elm.parent();
14961      if (parent_selector != null) {
14962        parent = parent.closest(parent_selector);
14963      }
14964      if (!parent.length) {
14965        throw "failed to find stick parent";
14966      }
14967      fixed = false;
14968      bottomed = false;
14969      spacer = manual_spacer != null ? manual_spacer && elm.closest(manual_spacer) : $("<div />");
14970      if (spacer) {
14971        spacer.css('position', elm.css('position'));
14972      }
14973      recalc = function() {
14974        var border_top, padding_top, restore;
14975        if (detached) {
14976          return;
14977        }
14978        last_scroll_height = doc.height();
14979        border_top = parseInt(parent.css("border-top-width"), 10);
14980        padding_top = parseInt(parent.css("padding-top"), 10);
14981        padding_bottom = parseInt(parent.css("padding-bottom"), 10);
14982        parent_top = parent.offset().top + border_top + padding_top;
14983        parent_height = parent.height();
14984        if (fixed) {
14985          fixed = false;
14986          bottomed = false;
14987          if (manual_spacer == null) {
14988            elm.insertAfter(spacer);
14989            spacer.detach();
14990          }
14991          elm.css({
14992            position: "",
14993            top: "",
14994            width: "",
14995            bottom: ""
14996          }).removeClass(sticky_class);
14997          restore = true;
14998        }
14999        top = elm.offset().top - (parseInt(elm.css("margin-top"), 10) || 0) - offset_top;
15000        height = elm.outerHeight(true);
15001        el_float = elm.css("float");
15002        if (spacer) {
15003          spacer.css({
15004            width: outer_width(elm),
15005            height: height,
15006            display: elm.css("display"),
15007            "vertical-align": elm.css("vertical-align"),
15008            "float": el_float
15009          });
15010        }
15011        if (restore) {
15012          return tick();
15013        }
15014      };
15015      recalc();
15016      if (height === parent_height) {
15017        return;
15018      }
15019      last_pos = void 0;
15020      offset = offset_top;
15021      recalc_counter = recalc_every;
15022      tick = function() {
15023        var css, delta, recalced, scroll, will_bottom, win_height;
15024        if (detached) {
15025          return;
15026        }
15027        recalced = false;
15028        if (recalc_counter != null) {
15029          recalc_counter -= 1;
15030          if (recalc_counter <= 0) {
15031            recalc_counter = recalc_every;
15032            recalc();
15033            recalced = true;
15034          }
15035        }
15036        if (!recalced && doc.height() !== last_scroll_height) {
15037          recalc();
15038          recalced = true;
15039        }
15040        scroll = win.scrollTop();
15041        if (last_pos != null) {
15042          delta = scroll - last_pos;
15043        }
15044        last_pos = scroll;
15045        if (fixed) {
15046          if (enable_bottoming) {
15047            will_bottom = scroll + height + offset > parent_height + parent_top;
15048            if (bottomed && !will_bottom) {
15049              bottomed = false;
15050              elm.css({
15051                position: "fixed",
15052                bottom: "",
15053                top: offset
15054              }).trigger("sticky_kit:unbottom");
15055            }
15056          }
15057          if (scroll < top) {
15058            fixed = false;
15059            offset = offset_top;
15060            if (manual_spacer == null) {
15061              if (el_float === "left" || el_float === "right") {
15062                elm.insertAfter(spacer);
15063              }
15064              spacer.detach();
15065            }
15066            css = {
15067              position: "",
15068              width: "",
15069              top: ""
15070            };
15071            elm.css(css).removeClass(sticky_class).trigger("sticky_kit:unstick");
15072          }
15073          if (inner_scrolling) {
15074            win_height = win.height();
15075            if (height + offset_top > win_height) {
15076              if (!bottomed) {
15077                offset -= delta;
15078                offset = Math.max(win_height - height, offset);
15079                offset = Math.min(offset_top, offset);
15080                if (fixed) {
15081                  elm.css({
15082                    top: offset + "px"
15083                  });
15084                }
15085              }
15086            }
15087          }
15088        } else {
15089          if (scroll > top) {
15090            fixed = true;
15091            css = {
15092              position: "fixed",
15093              top: offset
15094            };
15095            css.width = elm.css("box-sizing") === "border-box" ? elm.outerWidth() + "px" : elm.width() + "px";
15096            elm.css(css).addClass(sticky_class);
15097            if (manual_spacer == null) {
15098              elm.after(spacer);
15099              if (el_float === "left" || el_float === "right") {
15100                spacer.append(elm);
15101              }
15102            }
15103            elm.trigger("sticky_kit:stick");
15104          }
15105        }
15106        if (fixed && enable_bottoming) {
15107          if (will_bottom == null) {
15108            will_bottom = scroll + height + offset > parent_height + parent_top;
15109          }
15110          if (!bottomed && will_bottom) {
15111            bottomed = true;
15112            if (parent.css("position") === "static") {
15113              parent.css({
15114                position: "relative"
15115              });
15116            }
15117            return elm.css({
15118              position: "absolute",
15119              bottom: padding_bottom,
15120              top: "auto"
15121            }).trigger("sticky_kit:bottom");
15122          }
15123        }
15124      };
15125      recalc_and_tick = function() {
15126        recalc();
15127        return tick();
15128      };
15129      detach = function() {
15130        detached = true;
15131        win.off("touchmove", tick);
15132        win.off("scroll", tick);
15133        win.off("resize", recalc_and_tick);
15134        $(document.body).off("sticky_kit:recalc", recalc_and_tick);
15135        elm.off("sticky_kit:detach", detach);
15136        elm.removeData("sticky_kit");
15137        elm.css({
15138          position: "",
15139          bottom: "",
15140          top: "",
15141          width: ""
15142        });
15143        parent.position("position", "");
15144        if (fixed) {
15145          if (manual_spacer == null) {
15146            if (el_float === "left" || el_float === "right") {
15147              elm.insertAfter(spacer);
15148            }
15149            spacer.remove();
15150          }
15151          return elm.removeClass(sticky_class);
15152        }
15153      };
15154      win.on("touchmove", tick);
15155      win.on("scroll", tick);
15156      win.on("resize", recalc_and_tick);
15157      $(document.body).on("sticky_kit:recalc", recalc_and_tick);
15158      elm.on("sticky_kit:detach", detach);
15159      return setTimeout(tick, 0);
15160    };
15161    for (i = 0, len = this.length; i < len; i++) {
15162      elm = this[i];
15163      fn($(elm));
15164    }
15165    return this;
15166  };
15167
15168}).call(this);
15169
15170
15171
15172/* ========================================================================
15173 * Bootstrap: collapse.js v3.1.1
15174 * http://getbootstrap.com/javascript/#collapse
15175 * ========================================================================
15176 * Copyright 2011-2014 Twitter, Inc.
15177 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15178 * ======================================================================== */
15179
15180
15181+function ($) {
15182  'use strict';
15183
15184  // COLLAPSE PUBLIC CLASS DEFINITION
15185  // ================================
15186
15187  var Collapse = function (element, options) {
15188    this.$element      = $(element)
15189    this.options       = $.extend({}, Collapse.DEFAULTS, options)
15190    this.transitioning = null
15191
15192    if (this.options.parent) this.$parent = $(this.options.parent)
15193    if (this.options.toggle) this.toggle()
15194  }
15195
15196  Collapse.DEFAULTS = {
15197    toggle: true
15198  }
15199
15200  Collapse.prototype.dimension = function () {
15201    var hasWidth = this.$element.hasClass('width')
15202    return hasWidth ? 'width' : 'height'
15203  }
15204
15205  Collapse.prototype.show = function () {
15206    if (this.transitioning || this.$element.hasClass('in')) return
15207
15208    var startEvent = $.Event('show.bs.collapse')
15209    this.$element.trigger(startEvent)
15210    if (startEvent.isDefaultPrevented()) return
15211
15212    var actives = this.$parent && this.$parent.find('> .panel > .in')
15213
15214    if (actives && actives.length) {
15215      var hasData = actives.data('bs.collapse')
15216      if (hasData && hasData.transitioning) return
15217      actives.collapse('hide')
15218      hasData || actives.data('bs.collapse', null)
15219    }
15220
15221    var dimension = this.dimension()
15222
15223    this.$element
15224      .removeClass('collapse')
15225      .addClass('collapsing')[dimension](0)
15226
15227    this.transitioning = 1
15228
15229    var complete = function (e) {
15230      if (e && e.target != this.$element[0]) return
15231      this.$element
15232        .removeClass('collapsing')
15233        .addClass('collapse in')[dimension]('auto')
15234      this.transitioning = 0
15235      this.$element.trigger('shown.bs.collapse')
15236    }
15237
15238    if (!$.support.transition) return complete.call(this)
15239
15240    var scrollSize = $.camelCase(['scroll', dimension].join('-'))
15241
15242    this.$element
15243      .one($.support.transition.end, $.proxy(complete, this))
15244      .emulateTransitionEnd(350)[dimension](this.$element[0][scrollSize])
15245  }
15246
15247  Collapse.prototype.hide = function () {
15248    if (this.transitioning || !this.$element.hasClass('in')) return
15249
15250    var startEvent = $.Event('hide.bs.collapse')
15251    this.$element.trigger(startEvent)
15252    if (startEvent.isDefaultPrevented()) return
15253
15254    var dimension = this.dimension()
15255
15256    this.$element[dimension](this.$element[dimension]())[0].offsetHeight
15257
15258    this.$element
15259      .addClass('collapsing')
15260      .removeClass('collapse')
15261      .removeClass('in')
15262
15263    this.transitioning = 1
15264
15265    var complete = function (e) {
15266      if (e && e.target != this.$element[0]) return
15267      this.transitioning = 0
15268      this.$element
15269        .trigger('hidden.bs.collapse')
15270        .removeClass('collapsing')
15271        .addClass('collapse')
15272    }
15273
15274    if (!$.support.transition) return complete.call(this)
15275
15276    this.$element
15277      [dimension](0)
15278      .one($.support.transition.end, $.proxy(complete, this))
15279      .emulateTransitionEnd(350)
15280  }
15281
15282  Collapse.prototype.toggle = function () {
15283    this[this.$element.hasClass('in') ? 'hide' : 'show']()
15284  }
15285
15286
15287  // COLLAPSE PLUGIN DEFINITION
15288  // ==========================
15289
15290  var old = $.fn.collapse
15291
15292  $.fn.collapse = function (option) {
15293    return this.each(function () {
15294      var $this   = $(this)
15295      var data    = $this.data('bs.collapse')
15296      var options = $.extend({}, Collapse.DEFAULTS, $this.data(), typeof option == 'object' && option)
15297
15298      if (!data && options.toggle && option == 'show') option = !option
15299      if (!data) $this.data('bs.collapse', (data = new Collapse(this, options)))
15300      if (typeof option == 'string') data[option]()
15301    })
15302  }
15303
15304  $.fn.collapse.Constructor = Collapse
15305
15306
15307  // COLLAPSE NO CONFLICT
15308  // ====================
15309
15310  $.fn.collapse.noConflict = function () {
15311    $.fn.collapse = old
15312    return this
15313  }
15314
15315
15316  // COLLAPSE DATA-API
15317  // =================
15318
15319  $(document).on('click.bs.collapse.data-api', '[data-toggle="collapse"]', function (e) {
15320    var $this   = $(this), href
15321    var target  = $this.attr('data-target')
15322        || e.preventDefault()
15323        || (href = $this.attr('href')) && href.replace(/.*(?=#[^\s]+$)/, '') //strip for ie7
15324    var $target = $(target)
15325    var data    = $target.data('bs.collapse')
15326    var option  = data ? 'toggle' : $this.data()
15327    var parent  = $this.attr('data-parent')
15328    var $parent = parent && $(parent)
15329
15330    if (!data || !data.transitioning) {
15331      if ($parent) $parent.find('[data-toggle="collapse"][data-parent="' + parent + '"]').not($this).addClass('collapsed')
15332      $this[$target.hasClass('in') ? 'addClass' : 'removeClass']('collapsed')
15333    }
15334
15335    $target.collapse(option)
15336  })
15337
15338}(jQuery);
15339
15340
15341/* ========================================================================
15342 * Bootstrap: tab.js v3.1.1
15343 * http://getbootstrap.com/javascript/#tabs
15344 * ========================================================================
15345 * Copyright 2011-2014 Twitter, Inc.
15346 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15347 * ======================================================================== */
15348
15349
15350+function ($) {
15351  'use strict';
15352
15353  // TAB CLASS DEFINITION
15354  // ====================
15355
15356  var Tab = function (element) {
15357    this.element = $(element)
15358  }
15359
15360  Tab.prototype.show = function () {
15361    var $this    = this.element
15362    var $ul      = $this.closest('ul:not(.dropdown-menu)')
15363    var selector = $this.data('target')
15364
15365    if (!selector) {
15366      selector = $this.attr('href')
15367      selector = selector && selector.replace(/.*(?=#[^\s]*$)/, '') //strip for ie7
15368    }
15369
15370    if ($this.parent('li').hasClass('active')) return
15371
15372    var previous = $ul.find('.active:last a')[0]
15373    var e        = $.Event('show.bs.tab', {
15374      relatedTarget: previous
15375    })
15376
15377    $this.trigger(e)
15378
15379    if (e.isDefaultPrevented()) return
15380
15381    var $target = $(selector)
15382
15383    this.activate($this.parent('li'), $ul)
15384    this.activate($target, $target.parent(), function () {
15385      $this.trigger({
15386        type: 'shown.bs.tab',
15387        relatedTarget: previous
15388      })
15389    })
15390  }
15391
15392  Tab.prototype.activate = function (element, container, callback) {
15393    var $active    = container.find('> .active')
15394    var transition = callback
15395      && $.support.transition
15396      && $active.hasClass('fade')
15397
15398    function next() {
15399      $active
15400        .removeClass('active')
15401        .find('> .dropdown-menu > .active')
15402        .removeClass('active')
15403
15404      element.addClass('active')
15405
15406      if (transition) {
15407        element[0].offsetWidth // reflow for transition
15408        element.addClass('in')
15409      } else {
15410        element.removeClass('fade')
15411      }
15412
15413      if (element.parent('.dropdown-menu')) {
15414        element.closest('li.dropdown').addClass('active')
15415      }
15416
15417      callback && callback()
15418    }
15419
15420    transition ?
15421      $active
15422        .one($.support.transition.end, next)
15423        .emulateTransitionEnd(150) :
15424      next()
15425
15426    $active.removeClass('in')
15427  }
15428
15429
15430  // TAB PLUGIN DEFINITION
15431  // =====================
15432
15433  var old = $.fn.tab
15434
15435  $.fn.tab = function ( option ) {
15436    return this.each(function () {
15437      var $this = $(this)
15438      var data  = $this.data('bs.tab')
15439
15440      if (!data) $this.data('bs.tab', (data = new Tab(this)))
15441      if (typeof option == 'string') data[option]()
15442    })
15443  }
15444
15445  $.fn.tab.Constructor = Tab
15446
15447
15448  // TAB NO CONFLICT
15449  // ===============
15450
15451  $.fn.tab.noConflict = function () {
15452    $.fn.tab = old
15453    return this
15454  }
15455
15456
15457  // TAB DATA-API
15458  // ============
15459
15460  $(document).on('click.bs.tab.data-api', '[data-toggle="tab"], [data-toggle="pill"]', function (e) {
15461    e.preventDefault()
15462    $(this).tab('show')
15463  })
15464
15465}(jQuery);
15466
15467
15468/* ========================================================================
15469 * Bootstrap: tooltip.js v3.1.1
15470 * http://getbootstrap.com/javascript/#tooltip
15471 * Inspired by the original jQuery.tipsy by Jason Frame
15472 * ========================================================================
15473 * Copyright 2011-2014 Twitter, Inc.
15474 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15475 * ======================================================================== */
15476
15477
15478+function ($) {
15479  'use strict';
15480
15481  // TOOLTIP PUBLIC CLASS DEFINITION
15482  // ===============================
15483
15484  var Tooltip = function (element, options) {
15485    this.type       =
15486    this.options    =
15487    this.enabled    =
15488    this.timeout    =
15489    this.hoverState =
15490    this.$element   = null
15491
15492    this.init('tooltip', element, options)
15493  }
15494
15495  Tooltip.DEFAULTS = {
15496    animation: true,
15497    placement: 'top',
15498    selector: false,
15499    template: '<div class="tooltip" role="tooltip"><div class="tooltip-arrow"></div><div class="tooltip-inner"></div></div>',
15500    trigger: 'hover focus',
15501    title: '',
15502    delay: 0,
15503    html: false,
15504    container: false,
15505    viewport: {
15506      selector: 'body',
15507      padding: 0
15508    }
15509  }
15510
15511  Tooltip.prototype.init = function (type, element, options) {
15512    this.enabled   = true
15513    this.type      = type
15514    this.$element  = $(element)
15515    this.options   = this.getOptions(options)
15516    this.$viewport = this.options.viewport && $(this.options.viewport.selector || this.options.viewport)
15517
15518    var triggers = this.options.trigger.split(' ')
15519
15520    for (var i = triggers.length; i--;) {
15521      var trigger = triggers[i]
15522
15523      if (trigger == 'click') {
15524        this.$element.on('click.' + this.type, this.options.selector, $.proxy(this.toggle, this))
15525      } else if (trigger != 'manual') {
15526        var eventIn  = trigger == 'hover' ? 'mouseenter' : 'focusin'
15527        var eventOut = trigger == 'hover' ? 'mouseleave' : 'focusout'
15528
15529        this.$element.on(eventIn  + '.' + this.type, this.options.selector, $.proxy(this.enter, this))
15530        this.$element.on(eventOut + '.' + this.type, this.options.selector, $.proxy(this.leave, this))
15531      }
15532    }
15533
15534    this.options.selector ?
15535      (this._options = $.extend({}, this.options, { trigger: 'manual', selector: '' })) :
15536      this.fixTitle()
15537  }
15538
15539  Tooltip.prototype.getDefaults = function () {
15540    return Tooltip.DEFAULTS
15541  }
15542
15543  Tooltip.prototype.getOptions = function (options) {
15544    options = $.extend({}, this.getDefaults(), this.$element.data(), options)
15545
15546    if (options.delay && typeof options.delay == 'number') {
15547      options.delay = {
15548        show: options.delay,
15549        hide: options.delay
15550      }
15551    }
15552
15553    return options
15554  }
15555
15556  Tooltip.prototype.getDelegateOptions = function () {
15557    var options  = {}
15558    var defaults = this.getDefaults()
15559
15560    this._options && $.each(this._options, function (key, value) {
15561      if (defaults[key] != value) options[key] = value
15562    })
15563
15564    return options
15565  }
15566
15567  Tooltip.prototype.enter = function (obj) {
15568    var self = obj instanceof this.con
15568structor ?
15569      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
15570
15571    clearTimeout(self.timeout)
15572
15573    self.hoverState = 'in'
15574
15575    if (!self.options.delay || !self.options.delay.show) return self.show()
15576
15577    self.timeout = setTimeout(function () {
15578      if (self.hoverState == 'in') self.show()
15579    }, self.options.delay.show)
15580  }
15581
15582  Tooltip.prototype.leave = function (obj) {
15583    var self = obj instanceof this.constructor ?
15584      obj : $(obj.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type)
15585
15586    clearTimeout(self.timeout)
15587
15588    self.hoverState = 'out'
15589
15590    if (!self.options.delay || !self.options.delay.hide) return self.hide()
15591
15592    self.timeout = setTimeout(function () {
15593      if (self.hoverState == 'out') self.hide()
15594    }, self.options.delay.hide)
15595  }
15596
15597  Tooltip.prototype.show = function () {
15598    var e = $.Event('show.bs.' + this.type)
15599
15600    if (this.hasContent() && this.enabled) {
15601      this.$element.trigger(e)
15602
15603      if (e.isDefaultPrevented()) return
15604      var that = this;
15605
15606      var $tip = this.tip()
15607
15608      this.setContent()
15609
15610      if (this.options.animation) $tip.addClass('fade')
15611
15612      var placement = typeof this.options.placement == 'function' ?
15613        this.options.placement.call(this, $tip[0], this.$element[0]) :
15614        this.options.placement
15615
15616      var autoToken = /\s?auto?\s?/i
15617      var autoPlace = autoToken.test(placement)
15618      if (autoPlace) placement = placement.replace(autoToken, '') || 'top'
15619
15620      $tip
15621        .detach()
15622        .css({ top: 0, left: 0, display: 'block' })
15623        .addClass(placement)
15624
15625      this.options.container ? $tip.appendTo(this.options.container) : $tip.insertAfter(this.$element)
15626
15627      var pos          = this.getPosition()
15628      var actualWidth  = $tip[0].offsetWidth
15629      var actualHeight = $tip[0].offsetHeight
15630
15631      if (autoPlace) {
15632        var orgPlacement = placement
15633        var $parent      = this.$element.parent()
15634        var parentDim    = this.getPosition($parent)
15635
15636        placement = placement == 'bottom' && pos.top   + pos.height       + actualHeight - parentDim.scroll > parentDim.height ? 'top'    :
15637                    placement == 'top'    && pos.top   - parentDim.scroll - actualHeight < 0                                   ? 'bottom' :
15638                    placement == 'right'  && pos.right + actualWidth      > parentDim.width                                    ? 'left'   :
15639                    placement == 'left'   && pos.left  - actualWidth      < parentDim.left                                     ? 'right'  :
15640                    placement
15641
15642        $tip
15643          .removeClass(orgPlacement)
15644          .addClass(placement)
15645      }
15646
15647      var calculatedOffset = this.getCalculatedOffset(placement, pos, actualWidth, actualHeight)
15648
15649      this.applyPlacement(calculatedOffset, placement)
15650      this.hoverState = null
15651
15652      var complete = function() {
15653        that.$element.trigger('shown.bs.' + that.type)
15654      }
15655
15656      $.support.transition && this.$tip.hasClass('fade') ?
15657        $tip
15658          .one($.support.transition.end, complete)
15659          .emulateTransitionEnd(150) :
15660        complete()
15661    }
15662  }
15663
15664  Tooltip.prototype.applyPlacement = function (offset, placement) {
15665    var $tip   = this.tip()
15666    var width  = $tip[0].offsetWidth
15667    var height = $tip[0].offsetHeight
15668
15669    // manually read margins because getBoundingClientRect includes difference
15670    var marginTop = parseInt($tip.css('margin-top'), 10)
15671    var marginLeft = parseInt($tip.css('margin-left'), 10)
15672
15673    // we must check for NaN for ie 8/9
15674    if (isNaN(marginTop))  marginTop  = 0
15675    if (isNaN(marginLeft)) marginLeft = 0
15676
15677    offset.top  = offset.top  + marginTop
15678    offset.left = offset.left + marginLeft
15679
15680    // $.fn.offset doesn't round pixel values
15681    // so we use setOffset directly with our own function B-0
15682    $.offset.setOffset($tip[0], $.extend({
15683      using: function (props) {
15684        $tip.css({
15685          top: Math.round(props.top),
15686          left: Math.round(props.left)
15687        })
15688      }
15689    }, offset), 0)
15690
15691    $tip.addClass('in')
15692
15693    // check to see if placing tip in new offset caused the tip to resize itself
15694    var actualWidth  = $tip[0].offsetWidth
15695    var actualHeight = $tip[0].offsetHeight
15696
15697    if (placement == 'top' && actualHeight != height) {
15698      offset.top = offset.top + height - actualHeight
15699    }
15700
15701    var delta = this.getViewportAdjustedDelta(placement, offset, actualWidth, actualHeight)
15702
15703    if (delta.left) offset.left += delta.left
15704    else offset.top += delta.top
15705
15706    var arrowDelta          = delta.left ? delta.left * 2 - width + actualWidth : delta.top * 2 - height + actualHeight
15707    var arrowPosition       = delta.left ? 'left'        : 'top'
15708    var arrowOffsetPosition = delta.left ? 'offsetWidth' : 'offsetHeight'
15709
15710    $tip.offset(offset)
15711    this.replaceArrow(arrowDelta, $tip[0][arrowOffsetPosition], arrowPosition)
15712  }
15713
15714  Tooltip.prototype.replaceArrow = function (delta, dimension, position) {
15715    this.arrow().css(position, delta ? (50 * (1 - delta / dimension) + '%') : '')
15716  }
15717
15718  Tooltip.prototype.setContent = function () {
15719    var $tip  = this.tip()
15720    var title = this.getTitle()
15721
15722    $tip.find('.tooltip-inner')[this.options.html ? 'html' : 'text'](title)
15723    $tip.removeClass('fade in top bottom left right')
15724  }
15725
15726  Tooltip.prototype.hide = function () {
15727    var that = this
15728    var $tip = this.tip()
15729    var e    = $.Event('hide.bs.' + this.type)
15730
15731    function complete() {
15732      if (that.hoverState != 'in') $tip.detach()
15733      that.$element.trigger('hidden.bs.' + that.type)
15734    }
15735
15736    this.$element.trigger(e)
15737
15738    if (e.isDefaultPrevented()) return
15739
15740    $tip.removeClass('in')
15741
15742    $.support.transition && this.$tip.hasClass('fade') ?
15743      $tip
15744        .one($.support.transition.end, complete)
15745        .emulateTransitionEnd(150) :
15746      complete()
15747
15748    this.hoverState = null
15749
15750    return this
15751  }
15752
15753  Tooltip.prototype.fixTitle = function () {
15754    var $e = this.$element
15755    if ($e.attr('title') || typeof($e.attr('data-original-title')) != 'string') {
15756      $e.attr('data-original-title', $e.attr('title') || '').attr('title', '')
15757    }
15758  }
15759
15760  Tooltip.prototype.hasContent = function () {
15761    return this.getTitle()
15762  }
15763
15764  Tooltip.prototype.getPosition = function ($element) {
15765    $element   = $element || this.$element
15766    var el     = $element[0]
15767    var isBody = el.tagName == 'BODY'
15768    return $.extend({}, (typeof el.getBoundingClientRect == 'function') ? el.getBoundingClientRect() : null, {
15769      scroll: isBody ? document.documentElement.scrollTop || document.body.scrollTop : $element.scrollTop(),
15770      width:  isBody ? $(window).width()  : $element.outerWidth(),
15771      height: isBody ? $(window).height() : $element.outerHeight()
15772    }, isBody ? {top: 0, left: 0} : $element.offset())
15773  }
15774
15775  Tooltip.prototype.getCalculatedOffset = function (placement, pos, actualWidth, actualHeight) {
15776    return placement == 'bottom' ? { top: pos.top + pos.height,   left: pos.left + pos.width / 2 - actualWidth / 2  } :
15777           placement == 'top'    ? { top: pos.top - actualHeight, left: pos.left + pos.width / 2 - actualWidth / 2  } :
15778           placement == 'left'   ? { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left - actualWidth } :
15779        /* placement == 'right' */ { top: pos.top + pos.height / 2 - actualHeight / 2, left: pos.left + pos.width   }
15780
15781  }
15782
15783  Tooltip.prototype.getViewportAdjustedDelta = function (placement, pos, actualWidth, actualHeight) {
15784    var delta = { top: 0, left: 0 }
15785    if (!this.$viewport) return delta
15786
15787    var viewportPadding = this.options.viewport && this.options.viewport.padding || 0
15788    var viewportDimensions = this.getPosition(this.$viewport)
15789
15790    if (/right|left/.test(placement)) {
15791      var topEdgeOffset    = pos.top - viewportPadding - viewportDimensions.scroll
15792      var bottomEdgeOffset = pos.top + viewportPadding - viewportDimensions.scroll + actualHeight
15793      if (topEdgeOffset < viewportDimensions.top) { // top overflow
15794        delta.top = viewportDimensions.top - topEdgeOffset
15795      } else if (bottomEdgeOffset > viewportDimensions.top + viewportDimensions.height) { // bottom overflow
15796        delta.top = viewportDimensions.top + viewportDimensions.height - bottom
15796EdgeOffset
15797      }
15798    } else {
15799      var leftEdgeOffset  = pos.left - viewportPadding
15800      var rightEdgeOffset = pos.left + viewportPadding + actualWidth
15801      if (leftEdgeOffset < viewportDimensions.left) { // left overflow
15802        delta.left = viewportDimensions.left - leftEdgeOffset
15803      } else if (rightEdgeOffset > viewportDimensions.width) { // right overflow
15804        delta.left = viewportDimensions.left + viewportDimensions.width - rightEdgeOffset
15805      }
15806    }
15807
15808    return delta
15809  }
15810
15811  Tooltip.prototype.getTitle = function () {
15812    var title
15813    var $e = this.$element
15814    var o  = this.options
15815
15816    title = $e.attr('data-original-title')
15817      || (typeof o.title == 'function' ? o.title.call($e[0]) :  o.title)
15818
15819    return title
15820  }
15821
15822  Tooltip.prototype.tip = function () {
15823    return this.$tip = this.$tip || $(this.options.template)
15824  }
15825
15826  Tooltip.prototype.arrow = function () {
15827    return this.$arrow = this.$arrow || this.tip().find('.tooltip-arrow')
15828  }
15829
15830  Tooltip.prototype.validate = function () {
15831    if (!this.$element[0].parentNode) {
15832      this.hide()
15833      this.$element = null
15834      this.options  = null
15835    }
15836  }
15837
15838  Tooltip.prototype.enable = function () {
15839    this.enabled = true
15840  }
15841
15842  Tooltip.prototype.disable = function () {
15843    this.enabled = false
15844  }
15845
15846  Tooltip.prototype.toggleEnabled = function () {
15847    this.enabled = !this.enabled
15848  }
15849
15850  Tooltip.prototype.toggle = function (e) {
15851    var self = e ? $(e.currentTarget)[this.type](this.getDelegateOptions()).data('bs.' + this.type) : this
15852    self.tip().hasClass('in') ? self.leave(self) : self.enter(self)
15853  }
15854
15855  Tooltip.prototype.destroy = function () {
15856    clearTimeout(this.timeout)
15857    this.hide().$element.off('.' + this.type).removeData('bs.' + this.type)
15858  }
15859
15860
15861  // TOOLTIP PLUGIN DEFINITION
15862  // =========================
15863
15864  var old = $.fn.tooltip
15865
15866  $.fn.tooltip = function (option) {
15867    return this.each(function () {
15868      var $this   = $(this)
15869      var data    = $this.data('bs.tooltip')
15870      var options = typeof option == 'object' && option
15871
15872      if (!data && option == 'destroy') return
15873      if (!data) $this.data('bs.tooltip', (data = new Tooltip(this, options)))
15874      if (typeof option == 'string') data[option]()
15875    })
15876  }
15877
15878  $.fn.tooltip.Constructor = Tooltip
15879
15880
15881  // TOOLTIP NO CONFLICT
15882  // ===================
15883
15884  $.fn.tooltip.noConflict = function () {
15885    $.fn.tooltip = old
15886    return this
15887  }
15888
15889}(jQuery);
15890
15891
15892/* ========================================================================
15893 * Bootstrap: transition.js v3.1.1
15894 * http://getbootstrap.com/javascript/#transitions
15895 * ========================================================================
15896 * Copyright 2011-2014 Twitter, Inc.
15897 * Licensed under MIT (https://github.com/twbs/bootstrap/blob/master/LICENSE)
15898 * ======================================================================== */
15899
15900
15901+function ($) {
15902  'use strict';
15903
15904  // CSS TRANSITION SUPPORT (Shoutout: http://www.modernizr.com/)
15905  // ============================================================
15906
15907  function transitionEnd() {
15908    var el = document.createElement('bootstrap')
15909
15910    var transEndEventNames = {
15911      WebkitTransition : 'webkitTransitionEnd',
15912      MozTransition    : 'transitionend',
15913      OTransition      : 'oTransitionEnd otransitionend',
15914      transition       : 'transitionend'
15915    }
15916
15917    for (var name in transEndEventNames) {
15918      if (el.style[name] !== undefined) {
15919        return { end: transEndEventNames[name] }
15920      }
15921    }
15922
15923    return false // explicit for ie8 (  ._.)
15924  }
15925
15926  // http://blog.alexmaccaw.com/css-transitions
15927  $.fn.emulateTransitionEnd = function (duration) {
15928    var called = false, $el = this
15929    $(this).one($.support.transition.end, function () { called = true })
15930    var callback = function () { if (!called) $($el).trigger($.support.transition.end) }
15931    setTimeout(callback, duration)
15932    return this
15933  }
15934
15935  $(function () {
15936    $.support.transition = transitionEnd()
15937  })
15938
15939}(jQuery);
15940
15941

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.