PageSourceSearch

https://rectorarosadeves.cl/wp-content/themes/salient/js/build/third-party/flickity.min.js?ver=2.2.2

js rectorarosadeves.cl collected 2026-10-06 11:21:59 UTC 123,348 bytes, 4,769 lines download raw bytes

1/*!
2 * Flickity PACKAGED v2.1.2
3 * Touch, responsive, flickable carousels
4 *
5 * Licensed GPLv3 for open source use
6 * or Flickity Commercial License for commercial use
7 *
8 * https://flickity.metafizzy.co
9 * Copyright 2015-2018 Metafizzy
vendor: 15,950 bytes, lines 9-660
9
10 */
11
12/**
13 * Bridget makes jQuery widgets
14 * v2.0.1
15 * MIT license
16 */
17
18/* jshint browser: true, strict: true, undef: true, unused: true */
19
20( function( window, factory ) {
21  // universal module definition
22  /*jshint strict: false */ /* globals define, module, require */
23  if ( typeof define == 'function' && define.amd ) {
24    // AMD
25    define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) {
26      return factory( window, jQuery );
27    });
28  } else if ( typeof module == 'object' && module.exports ) {
29    // CommonJS
30    module.exports = factory(
31      window,
32      require('jquery')
33    );
34  } else {
35    // browser global
36    window.jQueryBridget = factory(
37      window,
38      window.jQuery
39    );
40  }
41
42}( window, function factory( window, jQuery ) {
43'use strict';
44
45// ----- utils ----- //
46
47var arraySlice = Array.prototype.slice;
48
49// helper function for logging errors
50// $.error breaks jQuery chaining
51var console = window.console;
52var logError = typeof console == 'undefined' ? function() {} :
53  function( message ) {
54    console.error( message );
55  };
56
57// ----- jQueryBridget ----- //
58
59function jQueryBridget( namespace, PluginClass, $ ) {
60  $ = $ || jQuery || window.jQuery;
61  if ( !$ ) {
62    return;
63  }
64
65  // add option method -> $().plugin('option', {...})
66  if ( !PluginClass.prototype.option ) {
67    // option setter
68    PluginClass.prototype.option = function( opts ) {
69      // bail out if not an object
70      if ( !$.isPlainObject( opts ) ){
71        return;
72      }
73      this.options = $.extend( true, this.options, opts );
74    };
75  }
76
77  // make jQuery plugin
78  $.fn[ namespace ] = function( arg0 /*, arg1 */ ) {
79    if ( typeof arg0 == 'string' ) {
80      // method call $().plugin( 'methodName', { options } )
81      // shift arguments by 1
82      var args = arraySlice.call( arguments, 1 );
83      return methodCall( this, arg0, args );
84    }
85    // just $().plugin({ options })
86    plainCall( this, arg0 );
87    return this;
88  };
89
90  // $().plugin('methodName')
91  function methodCall( $elems, methodName, args ) {
92    var returnValue;
93    var pluginMethodStr = '$().' + namespace + '("' + methodName + '")';
94
95    $elems.each( function( i, elem ) {
96      // get instance
97      var instance = $.data( elem, namespace );
98      if ( !instance ) {
99        logError( namespace + ' not initialized. Cannot call methods, i.e. ' +
100          pluginMethodStr );
101        return;
102      }
103
104      var method = instance[ methodName ];
105      if ( !method || methodName.charAt(0) == '_' ) {
106        logError( pluginMethodStr + ' is not a valid method' );
107        return;
108      }
109
110      // apply method, get return value
111      var value = method.apply( instance, args );
112      // set return value if value is returned, use only first value
113      returnValue = returnValue === undefined ? value : returnValue;
114    });
115
116    return returnValue !== undefined ? returnValue : $elems;
117  }
118
119  function plainCall( $elems, options ) {
120    $elems.each( function( i, elem ) {
121      var instance = $.data( elem, namespace );
122      if ( instance ) {
123        // set options & init
124        instance.option( options );
125        instance._init();
126      } else {
127        // initialize new instance
128        instance = new PluginClass( elem, options );
129        $.data( elem, namespace, instance );
130      }
131    });
132  }
133
134  updateJQuery( $ );
135
136}
137
138// ----- updateJQuery ----- //
139
140// set $.bridget for v1 backwards compatibility
141function updateJQuery( $ ) {
142  if ( !$ || ( $ && $.bridget ) ) {
143    return;
144  }
145  $.bridget = jQueryBridget;
146}
147
148updateJQuery( jQuery || window.jQuery );
149
150// -----  ----- //
151
152return jQueryBridget;
153
154}));
155
156/**
157 * EvEmitter v1.1.0
158 * Lil' event emitter
159 * MIT License
160 */
161
162/* jshint unused: true, undef: true, strict: true */
163
164( function( global, factory ) {
165  // universal module definition
166  /* jshint strict: false */ /* globals define, module, window */
167  if ( typeof define == 'function' && define.amd ) {
168    // AMD - RequireJS
169    define( 'ev-emitter/ev-emitter',factory );
170  } else if ( typeof module == 'object' && module.exports ) {
171    // CommonJS - Browserify, Webpack
172    module.exports = factory();
173  } else {
174    // Browser globals
175    global.EvEmitter = factory();
176  }
177
178}( typeof window != 'undefined' ? window : this, function() {
179
180
181
182function EvEmitter() {}
183
184var proto = EvEmitter.prototype;
185
186proto.on = function( eventName, listener ) {
187  if ( !eventName || !listener ) {
188    return;
189  }
190  // set events hash
191  var events = this._events = this._events || {};
192  // set listeners array
193  var listeners = events[ eventName ] = events[ eventName ] || [];
194  // only add once
195  if ( listeners.indexOf( listener ) == -1 ) {
196    listeners.push( listener );
197  }
198
199  return this;
200};
201
202proto.once = function( eventName, listener ) {
203  if ( !eventName || !listener ) {
204    return;
205  }
206  // add event
207  this.on( eventName, listener );
208  // set once flag
209  // set onceEvents hash
210  var onceEvents = this._onceEvents = this._onceEvents || {};
211  // set onceListeners object
212  var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {};
213  // set flag
214  onceListeners[ listener ] = true;
215
216  return this;
217};
218
219proto.off = function( eventName, listener ) {
220  var listeners = this._events && this._events[ eventName ];
221  if ( !listeners || !listeners.length ) {
222    return;
223  }
224  var index = listeners.indexOf( listener );
225  if ( index != -1 ) {
226    listeners.splice( index, 1 );
227  }
228
229  return this;
230};
231
232proto.emitEvent = function( eventName, args ) {
233  var listeners = this._events && this._events[ eventName ];
234  if ( !listeners || !listeners.length ) {
235    return;
236  }
237  // copy over to avoid interference if .off() in listener
238  listeners = listeners.slice(0);
239  args = args || [];
240  // once stuff
241  var onceListeners = this._onceEvents && this._onceEvents[ eventName ];
242
243  for ( var i=0; i < listeners.length; i++ ) {
244    var listener = listeners[i]
245    var isOnce = onceListeners && onceListeners[ listener ];
246    if ( isOnce ) {
247      // remove listener
248      // remove before trigger to prevent recursion
249      this.off( eventName, listener );
250      // unset once flag
251      delete onceListeners[ listener ];
252    }
253    // trigger listener
254    listener.apply( this, args );
255  }
256
257  return this;
258};
259
260proto.allOff = function() {
261  delete this._events;
262  delete this._onceEvents;
263};
264
265return EvEmitter;
266
267}));
268
269/*!
270 * getSize v2.0.3
271 * measure size of elements
272 * MIT license
273 */
274
275/* jshint browser: true, strict: true, undef: true, unused: true */
276/* globals console: false */
277
278( function( window, factory ) {
279  /* jshint strict: false */ /* globals define, module */
280  if ( typeof define == 'function' && define.amd ) {
281    // AMD
282    define( 'get-size/get-size',factory );
283  } else if ( typeof module == 'object' && module.exports ) {
284    // CommonJS
285    module.exports = factory();
286  } else {
287    // browser global
288    window.getSize = factory();
289  }
290
291})( window, function factory() {
292'use strict';
293
294// -------------------------- helpers -------------------------- //
295
296// get a number from a string, not a percentage
297function getStyleSize( value ) {
298  var num = parseFloat( value );
299  // not a percent like '100%', and a number
300  var isValid = value.indexOf('%') == -1 && !isNaN( num );
301  return isValid && num;
302}
303
304function noop() {}
305
306var logError = typeof console == 'undefined' ? noop :
307  function( message ) {
308    console.error( message );
309  };
310
311// -------------------------- measurements -------------------------- //
312
313var measurements = [
314  'paddingLeft',
315  'paddingRight',
316  'paddingTop',
317  'paddingBottom',
318  'marginLeft',
319  'marginRight',
320  'marginTop',
321  'marginBottom',
322  'borderLeftWidth',
323  'borderRightWidth',
324  'borderTopWidth',
325  'borderBottomWidth'
326];
327
328var measurementsLength = measurements.length;
329
330function getZeroSize() {
331  var size = {
332    width: 0,
333    height: 0,
334    innerWidth: 0,
335    innerHeight: 0,
336    outerWidth: 0,
337    outerHeight: 0
338  };
339  for ( var i=0; i < measurementsLength; i++ ) {
340    var measurement = measurements[i];
341    size[ measurement ] = 0;
342  }
343  return size;
344}
345
346// -------------------------- getStyle -------------------------- //
347
348/**
349 * getStyle, get style of element, check for Firefox bug
350 * https://bugzilla.mozilla.org/show_bug.cgi?id=548397
351 */
352function getStyle( elem ) {
353  var style = getComputedStyle( elem );
354  if ( !style ) {
355    logError( 'Style returned ' + style +
356      '. Are you running this code in a hidden iframe on Firefox? ' +
357      'See https://bit.ly/getsizebug1' );
358  }
359  return style;
360}
361
362// -------------------------- setup -------------------------- //
363
364var isSetup = false;
365
366var isBoxSizeOuter;
367
368/**
369 * setup
370 * check isBoxSizerOuter
371 * do on first getSize() rather than on page load for Firefox bug
372 */
373function setup() {
374  // setup once
375  if ( isSetup ) {
376    return;
377  }
378  isSetup = true;
379
380  // -------------------------- box sizing -------------------------- //
381
382  /**
383   * Chrome & Safari measure the outer-width on style.width on border-box elems
384   * IE11 & Firefox<29 measures the inner-width
385   */
386  var div = document.createElement('div');
387  div.style.width = '200px';
388  div.style.padding = '1px 2px 3px 4px';
389  div.style.borderStyle = 'solid';
390  div.style.borderWidth = '1px 2px 3px 4px';
391  div.style.boxSizing = 'border-box';
392
393  var body = document.body || document.documentElement;
394  body.appendChild( div );
395  var style = getStyle( div );
396  // round value for browser zoom. desandro/masonry#928
397  isBoxSizeOuter = Math.round( getStyleSize( style.width ) ) == 200;
398  getSize.isBoxSizeOuter = isBoxSizeOuter;
399
400  body.removeChild( div );
401}
402
403// -------------------------- getSize -------------------------- //
404
405function getSize( elem ) {
406  setup();
407
408  // use querySeletor if elem is string
409  if ( typeof elem == 'string' ) {
410    elem = document.querySelector( elem );
411  }
412
413  // do not proceed on non-objects
414  if ( !elem || typeof elem != 'object' || !elem.nodeType ) {
415    return;
416  }
417
418  var style = getStyle( elem );
419
420  // if hidden, everything is 0
421  if ( style.display == 'none' ) {
422    return getZeroSize();
423  }
424
425  var size = {};
426  size.width = elem.offsetWidth;
427  size.height = elem.offsetHeight;
428
429  var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box';
430
431  // get all measurements
432  for ( var i=0; i < measurementsLength; i++ ) {
433    var measurement = measurements[i];
434    var value = style[ measurement ];
435    var num = parseFloat( value );
436    // any 'auto', 'medium' value will be 0
437    size[ measurement ] = !isNaN( num ) ? num : 0;
438  }
439
440  var paddingWidth = size.paddingLeft + size.paddingRight;
441  var paddingHeight = size.paddingTop + size.paddingBottom;
442  var marginWidth = size.marginLeft + size.marginRight;
443  var marginHeight = size.marginTop + size.marginBottom;
444  var borderWidth = size.borderLeftWidth + size.borderRightWidth;
445  var borderHeight = size.borderTopWidth + size.borderBottomWidth;
446
447  var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter;
448
449  // overwrite width and height if we can get it from style
450  var styleWidth = getStyleSize( style.width );
451  if ( styleWidth !== false ) {
452    size.width = styleWidth +
453      // add padding and border unless it's already including it
454      ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth );
455  }
456
457  var styleHeight = getStyleSize( style.height );
458  if ( styleHeight !== false ) {
459    size.height = styleHeight +
460      // add padding and border unless it's already including it
461      ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight );
462  }
463
464  size.innerWidth = size.width - ( paddingWidth + borderWidth );
465  size.innerHeight = size.height - ( paddingHeight + borderHeight );
466
467  size.outerWidth = size.width + marginWidth;
468  size.outerHeight = size.height + marginHeight;
469
470  return size;
471}
472
473return getSize;
474
475});
476
477/**
478 * matchesSelector v2.0.2
479 * matchesSelector( element, '.selector' )
480 * MIT license
481 */
482
483/*jshint browser: true, strict: true, undef: true, unused: true */
484
485( function( window, factory ) {
486  /*global define: false, module: false */
487  'use strict';
488  // universal module definition
489  if ( typeof define == 'function' && define.amd ) {
490    // AMD
491    define( 'desandro-matches-selector/matches-selector',factory );
492  } else if ( typeof module == 'object' && module.exports ) {
493    // CommonJS
494    module.exports = factory();
495  } else {
496    // browser global
497    window.matchesSelector = factory();
498  }
499
500}( window, function factory() {
501  'use strict';
502
503  var matchesMethod = ( function() {
504    var ElemProto = window.Element.prototype;
505    // check for the standard method name first
506    if ( ElemProto.matches ) {
507      return 'matches';
508    }
509    // check un-prefixed
510    if ( ElemProto.matchesSelector ) {
511      return 'matchesSelector';
512    }
513    // check vendor prefixes
514    var prefixes = [ 'webkit', 'moz', 'ms', 'o' ];
515
516    for ( var i=0; i < prefixes.length; i++ ) {
517      var prefix = prefixes[i];
518      var method = prefix + 'MatchesSelector';
519      if ( ElemProto[ method ] ) {
520        return method;
521      }
522    }
523  })();
524
525  return function matchesSelector( elem, selector ) {
526    return elem[ matchesMethod ]( selector );
527  };
528
529}));
530
531/**
532 * Fizzy UI utils v2.0.7
533 * MIT license
534 */
535
536/*jshint browser: true, undef: true, unused: true, strict: true */
537
538( function( window, factory ) {
539  // universal module definition
540  /*jshint strict: false */ /*globals define, module, require */
541
542  if ( typeof define == 'function' && define.amd ) {
543    // AMD
544    define( 'fizzy-ui-utils/utils',[
545      'desandro-matches-selector/matches-selector'
546    ], function( matchesSelector ) {
547      return factory( window, matchesSelector );
548    });
549  } else if ( typeof module == 'object' && module.exports ) {
550    // CommonJS
551    module.exports = factory(
552      window,
553      require('desandro-matches-selector')
554    );
555  } else {
556    // browser global
557    window.fizzyUIUtils = factory(
558      window,
559      window.matchesSelector
560    );
561  }
562
563}( window, function factory( window, matchesSelector ) {
564
565
566
567var utils = {};
568
569// ----- extend ----- //
570
571// extends objects
572utils.extend = function( a, b ) {
573  for ( var prop in b ) {
574    a[ prop ] = b[ prop ];
575  }
576  return a;
577};
578
579// ----- modulo ----- //
580
581utils.modulo = function( num, div ) {
582  return ( ( num % div ) + div ) % div;
583};
584
585// ----- makeArray ----- //
586
587var arraySlice = Array.prototype.slice;
588
589// turn element or nodeList into an array
590utils.makeArray = function( obj ) {
591  if ( Array.isArray( obj ) ) {
592    // use object if already an array
593    return obj;
594  }
595  // return empty array if undefined or null. #6
596  if ( obj === null || obj === undefined ) {
597    return [];
598  }
599
600  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
601  if ( isArrayLike ) {
602    // convert nodeList to array
603    return arraySlice.call( obj );
604  }
605
606  // array of single index
607  return [ obj ];
608};
609
610// ----- removeFrom ----- //
611
612utils.removeFrom = function( ary, obj ) {
613  var index = ary.indexOf( obj );
614  if ( index != -1 ) {
615    ary.splice( index, 1 );
616  }
617};
618
619// ----- getParent ----- //
620
621utils.getParent = function( elem, selector ) {
622  while ( elem.parentNode && elem != document.body ) {
623    elem = elem.parentNode;
624    if ( matchesSelector( elem, selector ) ) {
625      return elem;
626    }
627  }
628};
629
630// ----- getQueryElement ----- //
631
632// use element as selector string
633utils.getQueryElement = function( elem ) {
634  if ( typeof elem == 'string' ) {
635    return document.querySelector( elem );
636  }
637  return elem;
638};
639
640// ----- handleEvent ----- //
641
642// enable .ontype to trigger from .addEventListener( elem, 'type' )
643utils.handleEvent = function( event ) {
644  var method = 'on' + event.type;
645  if ( this[ method ] ) {
646    this[ method ]( event );
647  }
648};
649
650// ----- filterFindElements ----- //
651
652utils.filterFindElements = function( elems, selector ) {
653  // make array of elems
654  elems = utils.makeArray( elems );
655  var ffElems = [];
656
657  elems.forEach( function( elem ) {
658    // check that elem is an actual element
659    if ( !( elem instanceof HTMLElement ) ) {
660      
660/*nectar addition*/
661      if(jQuery('body.compose-mode').length == 0) {
662        return;
663      }
664      /*nectar addition end*/
665    }
666    // add elem if no selector
667    if ( !selector ) {
668      ffElems.push( elem );
669      return;
670    }
671    // filter & find items if we have a selector
672    // filter
673    if ( matchesSelector( elem, selector ) ) {
674      ffElems.push( elem );
675    }
676    // find children
677    var childElems = elem.querySelectorAll( selector );
678    // concat childElems to filterFound array
679    for ( var i=0; i < childElems.length; i++ ) {
680      ffElems.push( childElems[i] );
681    }
682  });
683
684  return ffElems;
685};
686
687// ----- debounceMethod ----- //
688
689utils.debounceMethod = function( _class, methodName, threshold ) {
690  threshold = threshold || 100;
691  // original method
692  var method = _class.prototype[ methodName ];
693  var timeoutName = methodName + 'Timeout';
694
695  _class.prototype[ methodName ] = function() {
696    var timeout = this[ timeoutName ];
697    clearTimeout( timeout );
698
699    var args = arguments;
700    var _this = this;
701    this[ timeoutName ] = setTimeout( function() {
702      method.apply( _this, args );
703      delete _this[ timeoutName ];
704    }, threshold );
705  };
706};
707
708// ----- docReady ----- //
709
710utils.docReady = function( callback ) {
711  var readyState = document.readyState;
712  if ( readyState == 'complete' || readyState == 'interactive' ) {
713    // do async to allow for other scripts to run. metafizzy/flickity#441
714    setTimeout( callback );
715  } else {
716    document.addEventListener( 'DOMContentLoaded', callback );
717  }
718};
719
720// ----- htmlInit ----- //
721
722// http://jamesroberts.name/blog/2010/02/22/string-functions-for-javascript-trim-to-camel-case-to-dashed-and-to-underscore/
723utils.toDashed = function( str ) {
724  return str.replace( /(.)([A-Z])/g, function( match, $1, $2 ) {
725    return $1 + '-' + $2;
726  }).toLowerCase();
727};
728
729var console = window.console;
730/**
731 * allow user to initialize classes via [data-namespace] or .js-namespace class
732 * htmlInit( Widget, 'widgetName' )
733 * options are parsed from data-namespace-options
734 */
735utils.htmlInit = function( WidgetClass, namespace ) {
736  utils.docReady( function() {
737    var dashedNamespace = utils.toDashed( namespace );
738    var dataAttr = 'data-' + dashedNamespace;
739    var dataAttrElems = document.querySelectorAll( '[' + dataAttr + ']' );
740    var jsDashElems = document.querySelectorAll( '.js-' + dashedNamespace );
741    var elems = utils.makeArray( dataAttrElems )
742      .concat( utils.makeArray( jsDashElems ) );
743    var dataOptionsAttr = dataAttr + '-options';
744    var jQuery = window.jQuery;
745
746    elems.forEach( function( elem ) {
747      var attr = elem.getAttribute( dataAttr ) ||
748        elem.getAttribute( dataOptionsAttr );
749      var options;
750      try {
751        options = attr && JSON.parse( attr );
752      } catch ( error ) {
753        // log error, do not initialize
754        if ( console ) {
755          console.error( 'Error parsing ' + dataAttr + ' on ' + elem.className +
756          ': ' + error );
757        }
758        return;
759      }
760      // initialize
761      var instance = new WidgetClass( elem, options );
762      // make available via $().data('namespace')
763      if ( jQuery ) {
764        jQuery.data( elem, namespace, instance );
765      }
766    });
767
768  });
769};
770
771// -----  ----- //
772
773return utils;
774
775}));
776
777// Flickity.Cell
778( function( window, factory ) {
779  // universal module definition
780  /* jshint strict: false */
781  if ( typeof define == 'function' && define.amd ) {
782    // AMD
783    define( 'flickity/js/cell',[
784      'get-size/get-size'
785    ], function( getSize ) {
786      return factory( window, getSize );
787    });
788  } else if ( typeof module == 'object' && module.exports ) {
789    // CommonJS
790    module.exports = factory(
791      window,
792      require('get-size')
793    );
794  } else {
795    // browser global
796    window.Flickity = window.Flickity || {};
797    window.Flickity.Cell = factory(
798      window,
799      window.getSize
800    );
801  }
802
803}( window, function factory( window, getSize ) {
804
805
806
807function Cell( elem, parent ) {
808  this.element = elem;
809  this.parent = parent;
810
811  this.create();
812}
813
814var proto = Cell.prototype;
815
816proto.create = function() {
817  this.element.style.position = 'absolute';
818  this.element.setAttribute( 'aria-selected', 'false' );
819  this.x = 0;
820  this.shift = 0;
821};
822
823proto.destroy = function() {
824  // reset style
825  this.element.style.position = '';
826  var side = this.parent.originSide;
827  this.element.removeAttribute('aria-selected');
828  this.element.style[ side ] = '';
829};
830
831proto.getSize = function() {
832  this.size = getSize( this.element );
833};
834
835proto.setPosition = function( x ) {
836  this.x = x;
837  this.updateTarget();
838  this.renderPosition( x );
839};
840
841// setDefaultTarget v1 method, backwards compatibility, remove in v3
842proto.updateTarget = proto.setDefaultTarget = function() {
843  var marginProperty = this.parent.originSide == 'left' ? 'marginLeft' : 'marginRight';
844  this.target = this.x + this.size[ marginProperty ] +
845    this.size.width * this.parent.cellAlign;
846};
847
848proto.renderPosition = function( x ) {
849  // render position of cell with in slider
850  var side = this.parent.originSide;
851  this.element.style[ side ] = this.parent.getPositionValue( x );
852};
853
854/**
855 * @param {Integer} factor - 0, 1, or -1
856**/
857proto.wrapShift = function( shift ) {
858  this.shift = shift;
859  this.renderPosition( this.x + this.parent.slideableWidth * shift );
860};
861
862proto.remove = function() {
863  this.element.parentNode.removeChild( this.element );
864};
865
866return Cell;
867
868}));
869
870// slide
871( function( window, factory ) {
872  // universal module definition
873  /* jshint strict: false */
874  if ( typeof define == 'function' && define.amd ) {
875    // AMD
876    define( 'flickity/js/slide',factory );
877  } else if ( typeof module == 'object' && module.exports ) {
878    // CommonJS
879    module.exports = factory();
880  } else {
881    // browser global
882    window.Flickity = window.Flickity || {};
883    window.Flickity.Slide = factory();
884  }
885
886}( window, function factory() {
887'use strict';
888
889function Slide( parent ) {
890  this.parent = parent;
891  this.isOriginLeft = parent.originSide == 'left';
892  this.cells = [];
893  this.outerWidth = 0;
894  this.height = 0;
895}
896
897var proto = Slide.prototype;
898
899proto.addCell = function( cell ) {
900  this.cells.push( cell );
901  this.outerWidth += cell.size.outerWidth;
902  this.height = Math.max( cell.size.outerHeight, this.height );
903  // first cell stuff
904  if ( this.cells.length == 1 ) {
905    this.x = cell.x; // x comes from first cell
906    var beginMargin = this.isOriginLeft ? 'marginLeft' : 'marginRight';
907    this.firstMargin = cell.size[ beginMargin ];
908  }
909};
910
911proto.updateTarget = function() {
912  var endMargin = this.isOriginLeft ? 'marginRight' : 'marginLeft';
913  var lastCell = this.getLastCell();
914  var lastMargin = lastCell ? lastCell.size[ endMargin ] : 0;
915  var slideWidth = this.outerWidth - ( this.firstMargin + lastMargin );
916  this.target = this.x + this.firstMargin + slideWidth * this.parent.cellAlign;
917};
918
919proto.getLastCell = function() {
920  return this.cells[ this.cells.length - 1 ];
921};
922
923proto.select = function() {
924  this.changeSelected( true );
925};
926
927proto.unselect = function() {
928  this.changeSelected( false );
929};
930
931proto.changeSelected = function( isSelected ) {
932  var classMethod = isSelected ? 'add' : 'remove';
933  this.cells.forEach( function( cell ) {
934    cell.element.classList[ classMethod ]('is-selected');
935    cell.element.setAttribute( 'aria-selected', isSelected.toString() );
936  });
937};
938
939proto.getCellElements = function() {
940  return this.cells.map( function( cell ) {
941    return cell.element;
942  });
943};
944
945return Slide;
946
947}));
948
949// animate
950( function( window, factory ) {
951  // universal module definition
952  /* jshint strict: false */
953  if ( typeof define == 'function' && define.amd ) {
954    // AMD
955    define( 'flickity/js/animate',[
956      'fizzy-ui-utils/utils'
957    ], function( utils ) {
958      return factory( window, utils );
959    });
960  } else if ( typeof module == 'object' && module.exports ) {
961    // CommonJS
962    module.exports = factory(
963      window,
964      require('fizzy-ui-utils')
965    );
966  } else {
967    // browser global
968    window.Flickity = window.Flickity || {};
969    window.Flickity.animatePrototype = factory(
970      window,
971      window.fizzyUIUtils
972    );
973  }
974
975}( window, function factory( window, utils ) {
976
977
978
979// -------------------------- animate -------------------------- //
980
981var proto = {};
982
983proto.startAnimation = function() {
984  if ( this.isAnimating ) {
985    return;
986  }
987
988  this.isAnimating = true;
989  this.restingFrames = 0;
990  this.animate();
991};
992
993proto.animate = function() {
994  this.applyDragForce();
995  this.applySelectedAttraction();
996
997  var previousX = this.x;
998
999  this.integratePhysics();
1000  this.positionSlider();
1001  this.settle( previousX );
1002  // animate next frame
1003  if ( this.isAnimating ) {
1004    var _this = this;
1005    requestAnimationFrame( function animateFrame() {
1006      _this.animate();
1007    });
1008  }
1009};
1010
1011proto.positionSlider = function() {
1012  var x = this.x;
1013  // wrap position around
1014  if ( this.options.wrapAround && this.cells.length > 1 ) {
1015    x = utils.modulo( x, this.slideableWidth );
1016    x = x - this.slideableWidth;
1017    this.shiftWrapCells( x );
1018  }
1019
1020  x = x + this.cursorPosition;
1021  // reverse if right-to-left and using transform
1022  x = this.options.rightToLeft ? -x : x;
1023  var value = this.getPositionValue( x );
1024  // use 3D tranforms for hardware acceleration on iOS
1025  // but use 2D when settled, for better font-rendering
1026  this.slider.style.transform = this.isAnimating ?
1027    'translate3d(' + value + ',0,0)' : 'translateX(' + value + ')';
1028
1029  // scroll event
1030  var firstSlide = this.slides[0];
1031  if ( firstSlide ) {
1032    var positionX = -this.x - firstSlide.target;
1033    var progress = positionX / this.slidesWidth;
1034    this.dispatchEvent( 'scroll', null, [ progress, positionX ] );
1035  }
1036};
1037
1038proto.setTranslateX = function( x, is3d ) {
1039  x += this.cursorPosition;
1040  // reverse if right-to-left and using transform
1041  x = this.options.rightToLeft ? -x : x;
1042  var translateX = this.getPositionValue( x );
1043  // use 3D transforms for hardware acceleration on iOS
1044  // but use 2D when settled, for better font-rendering
1045  this.slider.style.transform = is3d ?
1046    'translate3d(' + translateX + ',0,0)' : 'translateX(' + translateX + ')';
1047};
1048
1049proto.dispatchScrollEvent = function() {
1050  var firstSlide = this.slides[0];
1051  if ( !firstSlide ) {
1052    return;
1053  }
1054  var positionX = -this.x - firstSlide.target;
1055  var progress = positionX / this.slidesWidth;
1056  this.dispatchEvent( 'scroll', null, [ progress, positionX ] );
1057};
1058
1059
1060proto.positionSliderAtSelected = function() {
1061  if ( !this.cells.length ) {
1062    return;
1063  }
1064  this.x = -this.selectedSlide.target;
1065  this.velocity = 0; // stop wobble
1066  this.positionSlider();
1067};
1068
1069proto.getPositionValue = function( position ) {
1070  if ( this.options.percentPosition ) {
1071    // percent position, round to 2 digits, like 12.34%
1072    return ( Math.round( ( position / this.size.innerWidth ) * 10000 ) * 0.01 )+ '%';
1073  } else {
1074    // pixel positioning
1075    return Math.round( position ) + 'px';
1076  }
1077};
1078
1079proto.settle = function( previousX ) {
1080  // keep track of frames where x hasn't moved
1081  if ( !this.isPointerDown && Math.round( this.x * 100 ) == Math.round( previousX * 100 ) ) {
1082    this.restingFrames++;
1083  }
1084  // stop animating if resting for 3 or more frames
1085  if ( this.restingFrames > 2 ) {
1086    this.isAnimating = false;
1087    delete this.isFreeScrolling;
1088    // render position with translateX when settled
1089    this.positionSlider();
1090    this.dispatchEvent( 'settle', null, [ this.selectedIndex ] );
1091  }
1092};
1093
1094proto.shiftWrapCells = function( x ) {
1095  // shift before cells
1096  var beforeGap = this.cursorPosition + x;
1097  this._shiftCells( this.beforeShiftCells, beforeGap, -1 );
1098  // shift after cells
1099  var afterGap = this.size.innerWidth - ( x + this.slideableWidth + this.cursorPosition );
1100  this._shiftCells( this.afterShiftCells, afterGap, 1 );
1101};
1102
1103proto._shiftCells = function( cells, gap, shift ) {
1104  for ( var i=0; i < cells.length; i++ ) {
1105    var cell = cells[i];
1106    var cellShift = gap > 0 ? shift : 0;
1107    cell.wrapShift( cellShift );
1108    gap -= cell.size.outerWidth;
1109  }
1110};
1111
1112proto._unshiftCells = function( cells ) {
1113  if ( !cells || !cells.length ) {
1114    return;
1115  }
1116  for ( var i=0; i < cells.length; i++ ) {
1117    cells[i].wrapShift( 0 );
1118  }
1119};
1120
1121// -------------------------- physics -------------------------- //
1122
1123proto.integratePhysics = function() {
1124  this.x += this.velocity;
1125  this.velocity *= this.getFrictionFactor();
1126};
1127
1128proto.applyForce = function( force ) {
1129  this.velocity += force;
1130};
1131
1132proto.getFrictionFactor = function() {
1133  return 1 - this.options[ this.isFreeScrolling ? 'freeScrollFriction' : 'friction' ];
1134};
1135
1136proto.getRestingPosition = function() {
1137  // my thanks to Steven Wittens, who simplified this math greatly
1138  return this.x + this.velocity / ( 1 - this.getFrictionFactor() );
1139};
1140
1141proto.applyDragForce = function() {
1142  if ( !this.isDraggable || !this.isPointerDown ) {
1143    return;
1144  }
1145  // change the position to drag position by applying force
1146  var dragVelocity = this.dragX - this.x;
1147  var dragForce = dragVelocity - this.velocity;
1148  this.applyForce( dragForce );
1149};
1150
1151proto.applySelectedAttraction = function() {
1152  // do not attract if pointer down or no slides
1153  var dragDown = this.isDraggable && this.isPointerDown;
1154  if ( dragDown || this.isFreeScrolling || !this.slides.length ) {
1155    return;
1156  }
1157  var distance = this.selectedSlide.target * -1 - this.x;
1158  var force = distance * this.options.selectedAttraction;
1159  this.applyForce( force );
1160};
1161
1162return proto;
1163
1164}));
1165
1166// Flickity main
1167( function( window, factory ) {
1168  // universal module definition
1169  /* jshint strict: false */
1170  if ( typeof define == 'function' && define.amd ) {
1171    // AMD
1172    define( 'flickity/js/flickity',[
1173      'ev-emitter/ev-emitter',
1174      'get-size/get-size',
1175      'fizzy-ui-utils/utils',
1176      './cell',
1177      './slide',
1178      './animate'
1179    ], function( EvEmitter, getSize, utils, Cell, Slide, animatePrototype ) {
1180      return factory( window, EvEmitter, getSize, utils, Cell, Slide, animatePrototype );
1181    });
1182  } else if ( typeof module == 'object' && module.exports ) {
1183    // CommonJS
1184    module.exports = factory(
1185      window,
1186      require('ev-emitter'),
1187      require('get-size'),
1188      require('fizzy-ui-utils'),
1189      require('./cell'),
1190      require('./slide'),
1191      require('./animate')
1192    );
1193  } else {
1194    // browser global
1195    var _Flickity = window.Flickity;
1196
1197    window.Flickity = factory(
1198      window,
1199      window.EvEmitter,
1200      window.getSize,
1201      window.fizzyUIUtils,
1202      _Flickity.Cell,
1203      _Flickity.Slide,
1204      _Flickity.animatePrototype
1205    );
1206  }
1207
1208}( window, function factory( window, EvEmitter, getSize,
1209  utils, Cell, Slide, animatePrototype ) {
1210
1211
1212
1213// vars
1214var jQuery = window.jQuery;
1215var getComputedStyle = window.getComputedStyle;
1216var console = window.console;
1217
1218function moveElements( elems, toElem ) {
1219  elems = utils.makeArray( elems );
1220  while ( elems.length ) {
1221    toElem.appendChild( elems.shift() );
1222  }
1223}
1224
1225// -------------------------- Flickity -------------------------- //
1226
1227// globally unique identifiers
1228var GUID = 0;
1229// internal store of all Flickity intances
1230var instances = {};
1231
1232function Flickity( element, options ) {
1233  var queryElement = utils.getQueryElement( element );
1234  if ( !queryElement ) {
1235    if ( console ) {
1236      console.error( 'Bad element for Flickity: ' + ( queryElement || element ) );
1237    }
1238    return;
1239  }
1240  this.element = queryElement;
1241  // do not initialize twice on same element
1242  if ( this.element.flickityGUID ) {
1243    var instance = instances[ this.element.flickityGUID ];
1244    instance.option( options );
1245    return instance;
1246  }
1247
1248  // add jQuery
1249  if ( jQuery ) {
1250    this.$element = jQuery( this.element );
1251  }
1252  // options
1253  this.options = utils.extend( {}, this.constructor.defaults );
1254  this.option( options );
1255
1256  // kick things off
1257  this._create();
1258}
1259
1260Flickity.defaults = {
1261  accessibility: true,
1262  // adaptiveHeight: false,
1263  cellAlign: 'center',
1264  // cellSelector: undefined,
1265  // contain: false,
1266  freeScrollFriction: 0.075, // friction when free-scrolling
1267  friction: 0.28, // friction when selecting
1268  namespaceJQueryEvents: true,
1269  // initialIndex: 0,
1270  percentPosition: true,
1271  resize: true,
1272  selectedAttraction: 0.025,
1273  setGallerySize: true
1274  // watchCSS: false,
1275  // wrapAround: false
1276};
1277
1278// hash of methods triggered on _create()
1279Flickity.createMethods = [];
1280
1281var proto = Flickity.prototype;
1282// inherit EventEmitter
1283utils.extend( proto, EvEmitter.prototype );
1284
1285proto._create = function() {
1286  // add id for Flickity.data
1287  var id = this.guid = ++GUID;
1288  this.element.flickityGUID = id; // expando
1289  instances[ id ] = this; // associate via id
1290  // initial properties
1291  this.selectedIndex = 0;
1292  // how many frames slider has been in same position
1293  this.restingFrames = 0;
1294  // initial physics properties
1295  this.x = 0;
1296  this.velocity = 0;
1297  this.originSide = this.options.rightToLeft ? 'right' : 'left';
1298  // create viewport & slider
1299  /*nectar addition*/
1300
1301  if(this.$element.hasClass('generate-markup')) {
1302    this.viewport = document.createElement('div');
1303    this.viewport.className = 'flickity-viewport';
1304  } else {
1305    this.viewport = this.$element.find('.flickity-viewport')[0];
1306    this.slider = this.$element.find('.flickity-slider')[0];
1307    this.viewport.className = 'flickity-viewport';
1308  }
1309
1310  this._createSlider();
1311
1312
1313  /*nectar addition end*/
1314
1315  if ( this.options.resize || this.options.watchCSS ) {
1316    window.addEventListener( 'resize', this );
1317  }
1318
1319  // add listeners from on option
1320  for ( var eventName in this.options.on ) {
1321    var listener = this.options.on[ eventName ];
1322    this.on( eventName, listener );
1323  }
1324
1325  Flickity.createMethods.forEach( function( method ) {
1326    this[ method ]();
1327  }, this );
1328
1329  if ( this.options.watchCSS ) {
1330    this.watchCSS();
1331  } else {
1332    this.activate();
1333  }
1334
1335};
1336
1337/**
1338 * set options
1339 * @param {Object} opts
1340 */
1341proto.option = function( opts ) {
1342  utils.extend( this.options, opts );
1343};
1344
1345proto.activate = function() {
1346  if ( this.isActive ) {
1347    return;
1348  }
1349  this.isActive = true;
1350  this.element.classList.add('flickity-enabled');
1351  if ( this.options.rightToLeft ) {
1352    this.element.classList.add('flickity-rtl');
1353  }
1354
1355  this.getSize();
1356  // move initial cell elements so they can be loaded as cells
1357  var cellElems = this._filterFindCellElements( this.element.children );
1358
1359  /* nectar addition */
1360  if(this.$element.hasClass('generate-markup')) {
1361    moveElements( cellElems, this.slider );
1362    this.viewport.appendChild( this.slider );
1363    this.element.appendChild( this.viewport );
1364  } else {
1365    //do nothing
1366  }
1367  /* nectar addition  end */
1368
1369  // get cells from children
1370  this.reloadCells();
1371
1372  if ( this.options.accessibility ) {
1373    // allow element to focusable
1374    this.element.tabIndex = 0;
1375    // listen for key presses
1376    this.element.addEventListener( 'keydown', this );
1377  }
1378
1379  this.emitEvent('activate');
1380
1381  var index;
1382  var initialIndex = this.options.initialIndex;
1383  if ( this.isInitActivated ) {
1384    index = this.selectedIndex;
1385  } else if ( initialIndex !== undefined ) {
1386    index = this.cells[ initialIndex ] ? initialIndex : 0;
1387  } else {
1388    index = 0;
1389  }
1390  // select instantly
1391  this.select( index, false, true );
1392  // flag for initial activation, for using initialIndex
1393  this.isInitActivated = true;
1394  // ready event. #493
1395  this.dispatchEvent('ready');
1396};
1397
1398// slider positions the cells
1399/* nectar addition */
1400proto._createSlider = function() {
1401  if(this.$element.hasClass('generate-markup')) {
1402    var slider = document.createElement('div');
1403    slider.className = 'flickity-slider';
1404    slider.style[ this.originSide ] = 0;
1405    this.slider = slider;
1406  } else {
1407    // slider element does all the positioning
1408    //var slider = document.createElement('div');
1409    //slider.className = 'flickity-slider';
1410    this.slider.style[ this.originSide ] = 0;
1411    //this.slider = slider;
1412  }
1413
1414};
1415/* nectar addition end */
1416
1417proto._filterFindCellElements = function( elems ) {
1418  return utils.filterFindElements( elems, this.options.cellSelector );
1419};
1420
1421// goes through all children
1422proto.reloadCells = function() {
1423  /* nectar addition */
1424
1425  if(jQuery(this.slider).parent().parent().find('.flickity-page-dots').length > 0) {
1426    var $that = this;
1427    setTimeout(function(){
1428      $that.pageDots.setDots();
1429    },100);
1430  }
1431  var slidesArr = [];
1432  jQuery(this.slider).find('> *').each(function(i){
1433    slidesArr[i] = jQuery(this)[0];
1434  });
1435
1436
1437  // collection of item elements
1438    this.cells = this._makeCells(slidesArr);
1439    /* nectar addition end */
1440  this.positionCells();
1441  this._getWrapShiftCells();
1442  this.setGallerySize();
1443};
1444
1445/**
1446 * turn elements into Flickity.Cells
1447 * @param {Array or NodeList or HTMLElement} elems
1448 * @returns {Array} items - collection of new Flickity Cells
1449 */
1450proto._makeCells = function( elems ) {
1451  var cellElems = this._filterFindCellElements( elems );
1452
1453  // create new Flickity for collection
1454  var cells = cellElems.map( function( cellElem ) {
1455    return new Cell( cellElem, this );
1456  }, this );
1457
1458  return cells;
1459};
1460
1461proto.getLastCell = function() {
1462  return this.cells[ this.cells.length - 1 ];
1463};
1464
1465proto.getLastSlide = function() {
1466  return this.slides[ this.slides.length - 1 ];
1467};
1468
1469// positions all cells
1470proto.positionCells = function() {
1471  // size all cells
1472  this._sizeCells( this.cells );
1473  // position all cells
1474  this._positionCells( 0 );
1475};
1476
1477/**
1478 * position certain cells
1479 * @param {Integer} index - which cell to start with
1480 */
1481proto._positionCells = function( index ) {
1482  index = index || 0;
1483  // also measure maxCellHeight
1484  // start 0 if positioning all cells
1485  this.maxCellHeight = index ? this.maxCellHeight || 0 : 0;
1486  var cellX = 0;
1487  // get cellX
1488  if ( index > 0 ) {
1489    var startCell = this.cells[ index - 1 ];
1490    cellX = startCell.x + startCell.size.outerWidth;
1491  }
1492  var len = this.cells.length;
1493  for ( var i=index; i < len; i++ ) {
1494    var cell = this.cells[i];
1495    cell.setPosition( cellX );
1496    cellX += cell.size.outerWidth;
1497    this.maxCellHeight = Math.max( cell.size.outerHeight, this.maxCellHeight );
1498  }
1499  // keep track of cellX for wrap-around
1500  this.slideableWidth = cellX;
1501  // slides
1502  this.updateSlides();
1503  // contain slides target
1504  this._containSlides();
1505  // update slidesWidth
1506  this.slidesWidth = len ? this.getLastSlide().target - this.slides[0].target : 0;
1507};
1508
1509/**
1510 * cell.getSize() on multiple cells
1511 * @param {Array} cells
1512 */
1513proto._sizeCells = function( cells ) {
1514  cells.forEach( function( cell ) {
1515    cell.getSize();
1516  });
1517};
1518
1519// --------------------------  -------------------------- //
1520
1521proto.updateSlides = function() {
1522  this.slides = [];
1523  if ( !this.cells.length ) {
1524    return;
1525  }
1526
1527  var slide = new Slide( this );
1528  this.slides.push( slide );
1529  var isOriginLeft = this.originSide == 'left';
1530  var nextMargin = isOriginLeft ? 'marginRight' : 'marginLeft';
1531
1532  var canCellFit = this._getCanCellFit();
1533
1534  this.cells.forEach( function( cell, i ) {
1535    // just add cell if first cell in slide
1536    if ( !slide.cells.length ) {
1537      slide.addCell( cell );
1538      return;
1539    }
1540
1541    var slideWidth = ( slide.outerWidth - slide.firstMargin ) +
1542      ( cell.size.outerWidth - cell.size[ nextMargin ] );
1543
1544    if ( canCellFit.call( this, i, slideWidth ) ) {
1545      slide.addCell( cell );
1546    } else {
1547      // doesn't fit, new slide
1548      slide.updateTarget();
1549
1550      slide = new Slide( this );
1551      this.slides.push( slide );
1552      slide.addCell( cell );
1553    }
1554  }, this );
1555  // last slide
1556  slide.updateTarget();
1557  // update .selectedSlide
1558  this.updateSelectedSlide();
1559};
1560
1561proto._getCanCellFit = function() {
1562  var groupCells = this.options.groupCells;
1563  if ( !groupCells ) {
1564    return function() {
1565      return false;
1566    };
1567  } else if ( typeof groupCells == 'number' ) {
1568    // group by number. 3 -> [0,1,2], [3,4,5], ...
1569    var number = parseInt( groupCells, 10 );
1570    return function( i ) {
1571      return ( i % number ) !== 0;
1572    };
1573  }
1574  // default, group by width of slide
1575  // parse '75%
1576  var percentMatch = typeof groupCells == 'string' &&
1577    groupCells.match(/^(\d+)%$/);
1578  var percent = percentMatch ? parseInt( percentMatch[1], 10 ) / 100 : 1;
1579  return function( i, slideWidth ) {
1580    return slideWidth <= ( this.size.innerWidth + 1 ) * percent;
1581  };
1582};
1583
1584// alias _init for jQuery plugin .flickity()
1585proto._init =
1586proto.reposition = function() {
1587  this.positionCells();
1588  this.positionSliderAtSelected();
1589};
1590
1591proto.getSize = function() {
1592  this.size = getSize( this.element );
1593  this.setCellAlign();
1594  this.cursorPosition = this.size.innerWidth * this.cellAlign;
1595};
1596
1597var cellAlignShorthands = {
1598  // cell align, then based on origin side
1599  center: {
1600    left: 0.5,
1601    right: 0.5
1602  },
1603  left: {
1604    left: 0,
1605    right: 1
1606  },
1607  right: {
1608    right: 0,
1609    left: 1
1610  }
1611};
1612
1613proto.setCellAlign = function() {
1614  var shorthand = cellAlignShorthands[ this.options.cellAlign ];
1615  this.cellAlign = shorthand ? shorthand[ this.originSide ] : this.options.cellAlign;
1616};
1617
1618proto.setGallerySize = function() {
1619  if ( this.options.setGallerySize ) {
1620    var height = this.options.adaptiveHeight && this.selectedSlide ?
1621      this.selectedSlide.height : this.maxCellHeight;
1622    this.viewport.style.height = height + 'px';
1623  }
1624};
1625
1626proto._getWrapShiftCells = function() {
1627  // only for wrap-around
1628  if ( !this.options.wrapAround ) {
1629    return;
1630  }
1631  // unshift previous cells
1632  this._unshiftCells( this.beforeShiftCells );
1633  this._unshiftCells( this.afterShiftCells );
1634  // get before cells
1635  // initial gap
1636  var gapX = this.cursorPosition;
1637  var cellIndex = this.cells.length - 1;
1638  this.beforeShiftCells = this._getGapCells( gapX, cellIndex, -1 );
1639  // get after cells
1640  // ending gap between last cell and end of gallery viewport
1641  gapX = this.size.innerWidth - this.cursorPosition;
1642  // start cloning at first cell, working forwards
1643  this.afterShiftCells = this._getGapCells( gapX, 0, 1 );
1644};
1645
1646proto._getGapCells = function( gapX, cellIndex, increment ) {
1647  // keep adding cells until the cover the initial gap
1648  var cells = [];
1649  while ( gapX > 0 ) {
1650    var cell = this.cells[ cellIndex ];
1651    if ( !cell ) {
1652      break;
1653    }
1654    cells.push( cell );
1655    cellIndex += increment;
1656    gapX -= cell.size.outerWidth;
1657  }
1658  return cells;
1659};
1660
1661// ----- contain ----- //
1662
1663// contain cell targets so no excess sliding
1664proto._containSlides = function() {
1665  if ( !this.options.contain || this.options.wrapAround || !this.cells.length ) {
1666    return;
1667  }
1668  var isRightToLeft = this.options.rightToLeft;
1669  var beginMargin = isRightToLeft ? 'marginRight' : 'marginLeft';
1670  var endMargin = isRightToLeft ? 'marginLeft' : 'marginRight';
1671  var contentWidth = this.slideableWidth - this.getLastCell().size[ endMargin ];
1672  // content is less than gallery size
1673  var isContentSmaller = contentWidth < this.size.innerWidth;
1674  // bounds
1675  var beginBound = this.cursorPosition + this.cells[0].size[ beginMargin ];
1676  var endBound = contentWidth - this.size.innerWidth * ( 1 - this.cellAlign );
1677  // contain each cell target
1678  this.slides.forEach( function( slide ) {
1679    if ( isContentSmaller ) {
1680      // all cells fit inside gallery
1681      slide.target = contentWidth * this.cellAlign;
1682    } else {
1683      // contain to bounds
1684      slide.target = Math.max( slide.target, beginBound );
1685      slide.target = Math.min( slide.target, endBound );
1686    }
1687  }, this );
1688};
1689
1690// -----  ----- //
1691
1692/**
1693 * emits events via eventEmitter and jQuery events
1694 * @param {String} type - name of event
1695 * @param {Event} event - original event
1696 * @param {Array} args - extra arguments
1697 */
1698proto.dispatchEvent = function( type, event, args ) {
1699  var emitArgs = event ? [ event ].concat( args ) : args;
1700  this.emitEvent( type, emitArgs );
1701
1702  if ( jQuery && this.$element ) {
1703    // default trigger with type if no event
1704    type += this.options.namespaceJQueryEvents ? '.flickity' : '';
1705    var $event = type;
1706    if ( event ) {
1707      // create jQuery event
1708      var jQEvent = new jQuery.Event( event );
1709      jQEvent.type = type;
1710      $event = jQEvent;
1711    }
1712    this.$element.trigger( $event, args );
1713  }
1714};
1715
1716// -------------------------- select -------------------------- //
1717
1718/**
1719 * @param {Integer} index - index of the slide
1720 * @param {Boolean} isWrap - will wrap-around to last/first if at the end
1721 * @param {Boolean} isInstant - will immediately set position at selected cell
1722 */
1723proto.select = function( index, isWrap, isInstant ) {
1724  if ( !this.isActive ) {
1725    return;
1726  }
1727  index = parseInt( index, 10 );
1728  this._wrapSelect( index );
1729
1730  if ( this.options.wrapAround || isWrap ) {
1731    index = utils.modulo( index, this.slides.length );
1732  }
1733  // bail if invalid index
1734  if ( !this.slides[ index ] ) {
1735    return;
1736  }
1737  var prevIndex = this.selectedIndex;
1738  this.selectedIndex = index;
1739  this.updateSelectedSlide();
1740  if ( isInstant ) {
1741    this.positionSliderAtSelected();
1742  } else {
1743    this.startAnimation();
1744  }
1745  if ( this.options.adaptiveHeight ) {
1746    this.setGallerySize();
1747  }
1748  // events
1749  this.dispatchEvent( 'select', null, [ index ] );
1750  // change event if new index
1751  if ( index != prevIndex ) {
1752    this.dispatchEvent( 'change', null, [ index ] );
1753  }
1754  // old v1 event name, remove in v3
1755  this.dispatchEvent('cellSelect');
1756};
1757
1758// wraps position for wrapAround, to move to closest slide. #113
1759proto._wrapSelect = function( index ) {
1760  var len = this.slides.length;
1761  var isWrapping = this.options.wrapAround && len > 1;
1762  if ( !isWrapping ) {
1763    return index;
1764  }
1765  var wrapIndex = utils.modulo( index, len );
1766  // go to shortest
1767  var delta = Math.abs( wrapIndex - this.selectedIndex );
1768  var backWrapDelta = Math.abs( ( wrapIndex + len ) - this.selectedIndex );
1769  var forewardWrapDelta = Math.abs( ( wrapIndex - len ) - this.selectedIndex );
1770  if ( !this.isDragSelect && backWrapDelta < delta ) {
1771    index += len;
1772  } else if ( !this.isDragSelect && forewardWrapDelta < delta ) {
1773    index -= len;
1774  }
1775  // wrap position so slider is within normal area
1776  if ( index < 0 ) {
1777    this.x -= this.slideableWidth;
1778  } else if ( index >= len ) {
1779    this.x += this.slideableWidth;
1780  }
1781};
1782
1783proto.previous = function( isWrap, isInstant ) {
1784  this.select( this.selectedIndex - 1, isWrap, isInstant );
1785};
1786
1787proto.next = function( isWrap, isInstant ) {
1788  this.select( this.selectedIndex + 1, isWrap, isInstant );
1789};
1790
1791proto.updateSelectedSlide = function() {
1792  var slide = this.slides[ this.selectedIndex ];
1793  // selectedIndex could be outside of slides, if triggered before resize()
1794  if ( !slide ) {
1795    return;
1796  }
1797  // unselect previous selected slide
1798  this.unselectSelectedSlide();
1799  // update new selected slide
1800  this.selectedSlide = slide;
1801  slide.select();
1802  this.selectedCells = slide.cells;
1803  this.selectedElements = slide.getCellElements();
1804  // HACK: selectedCell & selectedElement is first cell in slide, backwards compatibility
1805  // Remove in v3?
1806  this.selectedCell = slide.cells[0];
1807  this.selectedElement = this.selectedElements[0];
1808};
1809
1810proto.unselectSelectedSlide = function() {
1811  if ( this.selectedSlide ) {
1812    this.selectedSlide.unselect();
1813  }
1814};
1815
1816/**
1817 * select slide from number or cell element
1818 * @param {Element or Number} elem
1819 */
1820proto.selectCell = function( value, isWrap, isInstant ) {
1821  // get cell
1822  var cell = this.queryCell( value );
1823  if ( !cell ) {
1824    return;
1825  }
1826
1827  var index = this.getCellSlideIndex( cell );
1828  this.select( index, isWrap, isInstant );
1829};
1830
1831proto.getCellSlideIndex = function( cell ) {
1832  // get index of slides that has cell
1833  for ( var i=0; i < this.slides.length; i++ ) {
1834    var slide = this.slides[i];
1835    var index = slide.cells.indexOf( cell );
1836    if ( index != -1 ) {
1837      return i;
1838    }
1839  }
1840};
1841
1842// -------------------------- get cells -------------------------- //
1843
1844/**
1845 * get Flickity.Cell, given an Element
1846 * @param {Element} elem
1847 * @returns {Flickity.Cell} item
1848 */
1849proto.getCell = function( elem ) {
1850  // loop through cells to get the one that matches
1851  for ( var i=0; i < this.cells.length; i++ ) {
1852    var cell = this.cells[i];
1853    if ( cell.element == elem ) {
1854      return cell;
1855    }
1856  }
1857};
1858
1859/**
1860 * get collection of Flickity.Cells, given Elements
1861 * @param {Element, Array, NodeList} elems
1862 * @returns {Array} cells - Flickity.Cells
1863 */
1864proto.getCells = function( elems ) {
1865  elems = utils.makeArray( elems );
1866  var cells = [];
1867  elems.forEach( function( elem ) {
1868    var cell = this.getCell( elem );
1869    if ( cell ) {
1870      cells.push( cell );
1871    }
1872  }, this );
1873  return cells;
1874};
1875
1876/**
1877 * get cell elements
1878 * @returns {Array} cellElems
1879 */
1880proto.getCellElements = function() {
1881  return this.cells.map( function( cell ) {
1882    return cell.element;
1883  });
1884};
1885
1886/**
1887 * get parent cell from an element
1888 * @param {Element} elem
1889 * @returns {Flickit.Cell} cell
1890 */
1891proto.getParentCell = function( elem ) {
1892  // first check if elem is cell
1893  var cell = this.getCell( elem );
1894  if ( cell ) {
1895    return cell;
1896  }
1897  // try to get parent cell elem
1898  elem = utils.getParent( elem, '.flickity-slider > *' );
1899  return this.getCell( elem );
1900};
1901
1902/**
1903 * get cells adjacent to a slide
1904 * @param {Integer} adjCount - number of adjacent slides
1905 * @param {Integer} index - index of slide to start
1906 * @returns {Array} cells - array of Flickity.Cells
1907 */
1908proto.getAdjacentCellElements = function( adjCount, index ) {
1909  if ( !adjCount ) {
1910    return this.selectedSlide.getCellElements();
1911  }
1912  index = index === undefined ? this.selectedIndex : index;
1913
1914  var len = this.slides.length;
1915  if ( 1 + ( adjCount * 2 ) >= len ) {
1916    return this.getCellElements();
1917  }
1918
1919  var cellElems = [];
1920  for ( var i = index - adjCount; i <= index + adjCount ; i++ ) {
1921    var slideIndex = this.options.wrapAround ? utils.modulo( i, len ) : i;
1922    var slide = this.slides[ slideIndex ];
1923    if ( slide ) {
1924      cellElems = cellElems.concat( slide.getCellElements() );
1925    }
1926  }
1927  return cellElems;
1928};
1929
1930/**
1931 * select slide from number or cell element
1932 * @param {Element, Selector String, or Number} selector
1933 */
1934proto.queryCell = function( selector ) {
1935  if ( typeof selector == 'number' ) {
1936    // use number as index
1937    return this.cells[ selector ];
1938  }
1939  if ( typeof selector == 'string' ) {
1940    // use string as selector, get element
1941    selector = this.element.querySelector( selector );
1942  }
1943  // get cell from element
1944  return this.getCell( selector );
1945};
1946
1947// -------------------------- events -------------------------- //
1948
1949proto.uiChange = function() {
1950  this.emitEvent('uiChange');
1951};
1952
1953proto.childUIPointerDown = function( event ) {
1954  this.emitEvent( 'childUIPointerDown', [ event ] );
1955};
1956
1957// ----- resize ----- //
1958
1959proto.onresize = function() {
1960  this.watchCSS();
1961  this.resize();
1962};
1963
1964utils.debounceMethod( Flickity, 'onresize', 150 );
1965
1966proto.resize = function() {
1967  /* nectar addition to check for this.isAnimating for iOS15 fix  */
1968
1969  if ( !this.isActive || this.isAnimating ) {
1970    return;
1971  }
1972  this.getSize();
1973  // wrap values
1974  if ( this.options.wrapAround ) {
1975    this.x = utils.modulo( this.x, this.slideableWidth );
1976  }
1977  this.positionCells();
1978  this._getWrapShiftCells();
1979  this.setGallerySize();
1980  this.emitEvent('resize');
1981  // update selected index for group slides, instant
1982  // TODO: position can be lost between groups of various numbers
1983  var selectedElement = this.selectedElements && this.selectedElements[0];
1984  this.selectCell( selectedElement, false, true );
1985};
1986
1987// watches the :after property, activates/deactivates
1988proto.watchCSS = function() {
1989  var watchOption = this.options.watchCSS;
1990  if ( !watchOption ) {
1991    return;
1992  }
1993
1994  var afterContent = getComputedStyle( this.element, ':after' ).content;
1995  // activate if :after { content: 'flickity' }
1996  if ( afterContent.indexOf('flickity') != -1 ) {
1997    this.activate();
1998  } else {
1999    this.deactivate();
2000  }
2001};
2002
2003// ----- keydown ----- //
2004
2005// go previous/next if left/right keys pressed
2006proto.onkeydown = function( event ) {
2007  // only work if element is in focus
2008  var isNotFocused = document.activeElement && document.activeElement != this.element;
2009  if ( !this.options.accessibility ||isNotFocused ) {
2010    return;
2011  }
2012
2013  var handler = Flickity.keyboardHandlers[ event.keyCode ];
2014  if ( handler ) {
2015    handler.call( this );
2016  }
2017};
2018
2019Flickity.keyboardHandlers = {
2020  // left arrow
2021  37: function() {
2022    var leftMethod = this.options.rightToLeft ? 'next' : 'previous';
2023    this.uiChange();
2024    this[ leftMethod ]();
2025  },
2026  // right arrow
2027  39: function() {
2028    var rightMethod = this.options.rightToLeft ? 'previous' : 'next';
2029    this.uiChange();
2030    this[ rightMethod ]();
2031  },
2032};
2033
2034// ----- focus ----- //
2035
2036proto.focus = function() {
2037  // TODO remove scrollTo once focus options gets more support
2038  // https://developer.mozilla.org/en-US/docs/Web/API/HTMLElement/focus#Browser_compatibility
2039  var prevScrollY = window.pageYOffset;
2040  this.element.focus({ preventScroll: true });
2041  // hack to fix scroll jump after focus, #76
2042  if ( window.pageYOffset != prevScrollY && prevScrollY > 10 ) { // nectar addition - iframe fix
2043    window.scrollTo( window.pageXOffset, prevScrollY );
2044  }
2045};
2046
2047// -------------------------- destroy -------------------------- //
2048
2049// deactivate all Flickity functionality, but keep stuff available
2050proto.deactivate = function() {
2051  if ( !this.isActive ) {
2052    return;
2053  }
2054  this.element.classList.remove('flickity-enabled');
2055  this.element.classList.remove('flickity-rtl');
2056  this.unselectSelectedSlide();
2057  // destroy cells
vendor: 10,270 bytes, lines 2058-2495
2058  this.cells.forEach( function( cell ) {
2059    cell.destroy();
2060  });
2061  this.element.removeChild( this.viewport );
2062  // move child elements back into element
2063  moveElements( this.slider.children, this.element );
2064  if ( this.options.accessibility ) {
2065    this.element.removeAttribute('tabIndex');
2066    this.element.removeEventListener( 'keydown', this );
2067  }
2068  // set flags
2069  this.isActive = false;
2070  this.emitEvent('deactivate');
2071};
2072
2073proto.destroy = function() {
2074  this.deactivate();
2075  window.removeEventListener( 'resize', this );
2076  this.emitEvent('destroy');
2077  if ( jQuery && this.$element ) {
2078    jQuery.removeData( this.element, 'flickity' );
2079  }
2080  delete this.element.flickityGUID;
2081  delete instances[ this.guid ];
2082};
2083
2084// -------------------------- prototype -------------------------- //
2085
2086utils.extend( proto, animatePrototype );
2087
2088// -------------------------- extras -------------------------- //
2089
2090/**
2091 * get Flickity instance from element
2092 * @param {Element} elem
2093 * @returns {Flickity}
2094 */
2095Flickity.data = function( elem ) {
2096  elem = utils.getQueryElement( elem );
2097  var id = elem && elem.flickityGUID;
2098  return id && instances[ id ];
2099};
2100
2101utils.htmlInit( Flickity, 'flickity' );
2102
2103if ( jQuery && jQuery.bridget ) {
2104  jQuery.bridget( 'flickity', Flickity );
2105}
2106
2107// set internal jQuery, for Webpack + jQuery v3, #478
2108Flickity.setJQuery = function( jq ) {
2109  jQuery = jq;
2110};
2111
2112Flickity.Cell = Cell;
2113Flickity.Slide = Slide;
2114
2115return Flickity;
2116
2117}));
2118
2119/*!
2120 * Unipointer v2.3.0
2121 * base class for doing one thing with pointer event
2122 * MIT license
2123 */
2124
2125/*jshint browser: true, undef: true, unused: true, strict: true */
2126
2127( function( window, factory ) {
2128  // universal module definition
2129  /* jshint strict: false */ /*global define, module, require */
2130  if ( typeof define == 'function' && define.amd ) {
2131    // AMD
2132    define( 'unipointer/unipointer',[
2133      'ev-emitter/ev-emitter'
2134    ], function( EvEmitter ) {
2135      return factory( window, EvEmitter );
2136    });
2137  } else if ( typeof module == 'object' && module.exports ) {
2138    // CommonJS
2139    module.exports = factory(
2140      window,
2141      require('ev-emitter')
2142    );
2143  } else {
2144    // browser global
2145    window.Unipointer = factory(
2146      window,
2147      window.EvEmitter
2148    );
2149  }
2150
2151}( window, function factory( window, EvEmitter ) {
2152
2153
2154
2155function noop() {}
2156
2157function Unipointer() {}
2158
2159// inherit EvEmitter
2160var proto = Unipointer.prototype = Object.create( EvEmitter.prototype );
2161
2162proto.bindStartEvent = function( elem ) {
2163  this._bindStartEvent( elem, true );
2164};
2165
2166proto.unbindStartEvent = function( elem ) {
2167  this._bindStartEvent( elem, false );
2168};
2169
2170/**
2171 * Add or remove start event
2172 * @param {Boolean} isAdd - remove if falsey
2173 */
2174proto._bindStartEvent = function( elem, isAdd ) {
2175  // munge isAdd, default to true
2176  isAdd = isAdd === undefined ? true : isAdd;
2177  var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
2178
2179  // default to mouse events
2180  var startEvent = 'mousedown';
2181  if ( window.PointerEvent ) {
2182    // Pointer Events
2183    startEvent = 'pointerdown';
2184  } else if ( 'ontouchstart' in window ) {
2185    // Touch Events. iOS Safari
2186    startEvent = 'touchstart';
2187  }
2188  elem[ bindMethod ]( startEvent, this );
2189};
2190
2191// trigger handler methods for events
2192proto.handleEvent = function( event ) {
2193  var method = 'on' + event.type;
2194  if ( this[ method ] ) {
2195    this[ method ]( event );
2196  }
2197};
2198
2199// returns the touch that we're keeping track of
2200proto.getTouch = function( touches ) {
2201  for ( var i=0; i < touches.length; i++ ) {
2202    var touch = touches[i];
2203    if ( touch.identifier == this.pointerIdentifier ) {
2204      return touch;
2205    }
2206  }
2207};
2208
2209// ----- start event ----- //
2210
2211proto.onmousedown = function( event ) {
2212  // dismiss clicks from right or middle buttons
2213  var button = event.button;
2214  if ( button && ( button !== 0 && button !== 1 ) ) {
2215    return;
2216  }
2217  this._pointerDown( event, event );
2218};
2219
2220proto.ontouchstart = function( event ) {
2221  this._pointerDown( event, event.changedTouches[0] );
2222};
2223
2224proto.onpointerdown = function( event ) {
2225  this._pointerDown( event, event );
2226};
2227
2228/**
2229 * pointer start
2230 * @param {Event} event
2231 * @param {Event or Touch} pointer
2232 */
2233proto._pointerDown = function( event, pointer ) {
2234  // dismiss right click and other pointers
2235  // button = 0 is okay, 1-4 not
2236  if ( event.button || this.isPointerDown ) {
2237    return;
2238  }
2239
2240  this.isPointerDown = true;
2241  // save pointer identifier to match up touch events
2242  this.pointerIdentifier = pointer.pointerId !== undefined ?
2243    // pointerId for pointer events, touch.indentifier for touch events
2244    pointer.pointerId : pointer.identifier;
2245
2246  this.pointerDown( event, pointer );
2247};
2248
2249proto.pointerDown = function( event, pointer ) {
2250  this._bindPostStartEvents( event );
2251  this.emitEvent( 'pointerDown', [ event, pointer ] );
2252};
2253
2254// hash of events to be bound after start event
2255var postStartEvents = {
2256  mousedown: [ 'mousemove', 'mouseup' ],
2257  touchstart: [ 'touchmove', 'touchend', 'touchcancel' ],
2258  pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ],
2259};
2260
2261proto._bindPostStartEvents = function( event ) {
2262  if ( !event ) {
2263    return;
2264  }
2265  // get proper events to match start event
2266  var events = postStartEvents[ event.type ];
2267  // bind events to node
2268  events.forEach( function( eventName ) {
2269    window.addEventListener( eventName, this );
2270  }, this );
2271  // save these arguments
2272  this._boundPointerEvents = events;
2273};
2274
2275proto._unbindPostStartEvents = function() {
2276  // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug)
2277  if ( !this._boundPointerEvents ) {
2278    return;
2279  }
2280  this._boundPointerEvents.forEach( function( eventName ) {
2281    window.removeEventListener( eventName, this );
2282  }, this );
2283
2284  delete this._boundPointerEvents;
2285};
2286
2287// ----- move event ----- //
2288
2289proto.onmousemove = function( event ) {
2290  this._pointerMove( event, event );
2291};
2292
2293proto.onpointermove = function( event ) {
2294  if ( event.pointerId == this.pointerIdentifier ) {
2295    this._pointerMove( event, event );
2296  }
2297};
2298
2299proto.ontouchmove = function( event ) {
2300  var touch = this.getTouch( event.changedTouches );
2301  if ( touch ) {
2302    this._pointerMove( event, touch );
2303  }
2304};
2305
2306/**
2307 * pointer move
2308 * @param {Event} event
2309 * @param {Event or Touch} pointer
2310 * @private
2311 */
2312proto._pointerMove = function( event, pointer ) {
2313  this.pointerMove( event, pointer );
2314};
2315
2316// public
2317proto.pointerMove = function( event, pointer ) {
2318  this.emitEvent( 'pointerMove', [ event, pointer ] );
2319};
2320
2321// ----- end event ----- //
2322
2323
2324proto.onmouseup = function( event ) {
2325  this._pointerUp( event, event );
2326};
2327
2328proto.onpointerup = function( event ) {
2329  if ( event.pointerId == this.pointerIdentifier ) {
2330    this._pointerUp( event, event );
2331  }
2332};
2333
2334proto.ontouchend = function( event ) {
2335  var touch = this.getTouch( event.changedTouches );
2336  if ( touch ) {
2337    this._pointerUp( event, touch );
2338  }
2339};
2340
2341/**
2342 * pointer up
2343 * @param {Event} event
2344 * @param {Event or Touch} pointer
2345 * @private
2346 */
2347proto._pointerUp = function( event, pointer ) {
2348  this._pointerDone();
2349  this.pointerUp( event, pointer );
2350};
2351
2352// public
2353proto.pointerUp = function( event, pointer ) {
2354  this.emitEvent( 'pointerUp', [ event, pointer ] );
2355};
2356
2357// ----- pointer done ----- //
2358
2359// triggered on pointer up & pointer cancel
2360proto._pointerDone = function() {
2361  this._pointerReset();
2362  this._unbindPostStartEvents();
2363  this.pointerDone();
2364};
2365
2366proto._pointerReset = function() {
2367  // reset properties
2368  this.isPointerDown = false;
2369  delete this.pointerIdentifier;
2370};
2371
2372proto.pointerDone = noop;
2373
2374// ----- pointer cancel ----- //
2375
2376proto.onpointercancel = function( event ) {
2377  if ( event.pointerId == this.pointerIdentifier ) {
2378    this._pointerCancel( event, event );
2379  }
2380};
2381
2382proto.ontouchcancel = function( event ) {
2383  var touch = this.getTouch( event.changedTouches );
2384  if ( touch ) {
2385    this._pointerCancel( event, touch );
2386  }
2387};
2388
2389/**
2390 * pointer cancel
2391 * @param {Event} event
2392 * @param {Event or Touch} pointer
2393 * @private
2394 */
2395proto._pointerCancel = function( event, pointer ) {
2396  this._pointerDone();
2397  this.pointerCancel( event, pointer );
2398};
2399
2400// public
2401proto.pointerCancel = function( event, pointer ) {
2402  this.emitEvent( 'pointerCancel', [ event, pointer ] );
2403};
2404
2405// -----  ----- //
2406
2407// utility function for getting x/y coords from event
2408Unipointer.getPointerPoint = function( pointer ) {
2409  return {
2410    x: pointer.pageX,
2411    y: pointer.pageY
2412  };
2413};
2414
2415// -----  ----- //
2416
2417return Unipointer;
2418
2419}));
2420
2421/*!
2422 * Unidragger v2.3.0
2423 * Draggable base class
2424 * MIT license
2425 */
2426
2427/*jshint browser: true, unused: true, undef: true, strict: true */
2428
2429( function( window, factory ) {
2430  // universal module definition
2431  /*jshint strict: false */ /*globals define, module, require */
2432
2433  if ( typeof define == 'function' && define.amd ) {
2434    // AMD
2435    define( 'unidragger/unidragger',[
2436      'unipointer/unipointer'
2437    ], function( Unipointer ) {
2438      return factory( window, Unipointer );
2439    });
2440  } else if ( typeof module == 'object' && module.exports ) {
2441    // CommonJS
2442    module.exports = factory(
2443      window,
2444      require('unipointer')
2445    );
2446  } else {
2447    // browser global
2448    window.Unidragger = factory(
2449      window,
2450      window.Unipointer
2451    );
2452  }
2453
2454}( window, function factory( window, Unipointer ) {
2455
2456
2457
2458// -------------------------- Unidragger -------------------------- //
2459
2460function Unidragger() {}
2461
2462// inherit Unipointer & EvEmitter
2463var proto = Unidragger.prototype = Object.create( Unipointer.prototype );
2464
2465// ----- bind start ----- //
2466
2467proto.bindHandles = function() {
2468  this._bindHandles( true );
2469};
2470
2471proto.unbindHandles = function() {
2472  this._bindHandles( false );
2473};
2474
2475/**
2476 * Add or remove start event
2477 * @param {Boolean} isAdd
2478 */
2479proto._bindHandles = function( isAdd ) {
2480  // munge isAdd, default to true
2481  isAdd = isAdd === undefined ? true : isAdd;
2482  // bind each handle
2483  var bindMethod = isAdd ? 'addEventListener' : 'removeEventListener';
2484  var touchAction = isAdd ? this._touchActionValue : '';
2485  for ( var i=0; i < this.handles.length; i++ ) {
2486    var handle = this.handles[i];
2487    this._bindStartEvent( handle, isAdd );
2488    handle[ bindMethod ]( 'click', this );
2489    // touch-action: none to override browser touch gestures. metafizzy/flickity#540
2490    if ( window.PointerEvent ) {
2491      handle.style.touchAction = touchAction;
2492    }
2493  }
2494};
2495
vendor: 3,343 bytes, lines 2496-2627
2496// prototype so it can be overwriteable by Flickity
2497proto._touchActionValue = 'none';
2498
2499// ----- start event ----- //
2500
2501/**
2502 * pointer start
2503 * @param {Event} event
2504 * @param {Event or Touch} pointer
2505 */
2506proto.pointerDown = function( event, pointer ) {
2507  var isOkay = this.okayPointerDown( event );
2508  if ( !isOkay ) {
2509    return;
2510  }
2511  // track start event position
2512  // Safari 9 overrides pageX and pageY. These values needs to be copied. flickity#842
2513  this.pointerDownPointer = {
2514    pageX: pointer.pageX,
2515    pageY: pointer.pageY,
2516  };
2517
2518  event.preventDefault();
2519  this.pointerDownBlur();
2520  // bind move and end events
2521  this._bindPostStartEvents( event );
2522  this.emitEvent( 'pointerDown', [ event, pointer ] );
2523};
2524
2525// nodes that have text fields
2526var cursorNodes = {
2527  TEXTAREA: true,
2528  INPUT: true,
2529  SELECT: true,
2530  OPTION: true,
2531};
2532
2533// input types that do not have text fields
2534var clickTypes = {
2535  radio: true,
2536  checkbox: true,
2537  button: true,
2538  submit: true,
2539  image: true,
2540  file: true,
2541};
2542
2543// dismiss inputs with text fields. flickity#403, flickity#404
2544proto.okayPointerDown = function( event ) {
2545  var isCursorNode = cursorNodes[ event.target.nodeName ];
2546  var isClickType = clickTypes[ event.target.type ];
2547  var isOkay = !isCursorNode || isClickType;
2548  if ( !isOkay ) {
2549    this._pointerReset();
2550  }
2551  return isOkay;
2552};
2553
2554// kludge to blur previously focused input
2555proto.pointerDownBlur = function() {
2556  var focused = document.activeElement;
2557  // do not blur body for IE10, metafizzy/flickity#117
2558  var canBlur = focused && focused.blur && focused != document.body;
2559  if ( canBlur ) {
2560    focused.blur();
2561  }
2562};
2563
2564// ----- move event ----- //
2565
2566/**
2567 * drag move
2568 * @param {Event} event
2569 * @param {Event or Touch} pointer
2570 */
2571proto.pointerMove = function( event, pointer ) {
2572  var moveVector = this._dragPointerMove( event, pointer );
2573  this.emitEvent( 'pointerMove', [ event, pointer, moveVector ] );
2574  this._dragMove( event, pointer, moveVector );
2575};
2576
2577// base pointer move logic
2578proto._dragPointerMove = function( event, pointer ) {
2579  var moveVector = {
2580    x: pointer.pageX - this.pointerDownPointer.pageX,
2581    y: pointer.pageY - this.pointerDownPointer.pageY
2582  };
2583  // start drag if pointer has moved far enough to start drag
2584  if ( !this.isDragging && this.hasDragStarted( moveVector ) ) {
2585    this._dragStart( event, pointer );
2586  }
2587  return moveVector;
2588};
2589
2590// condition if pointer has moved far enough to start drag
2591proto.hasDragStarted = function( moveVector ) {
2592  return Math.abs( moveVector.x ) > 3 || Math.abs( moveVector.y ) > 3;
2593};
2594
2595// ----- end event ----- //
2596
2597/**
2598 * pointer up
2599 * @param {Event} event
2600 * @param {Event or Touch} pointer
2601 */
2602proto.pointerUp = function( event, pointer ) {
2603  this.emitEvent( 'pointerUp', [ event, pointer ] );
2604  this._dragPointerUp( event, pointer );
2605};
2606
2607proto._dragPointerUp = function( event, pointer ) {
2608  if ( this.isDragging ) {
2609    this._dragEnd( event, pointer );
2610  } else {
2611    // pointer didn't move enough for drag to start
2612    this._staticClick( event, pointer );
2613  }
2614};
2615
2616// -------------------------- drag -------------------------- //
2617
2618// dragStart
2619proto._dragStart = function( event, pointer ) {
2620  this.isDragging = true;
2621  /* nectar addition iOS15 fix */
2622  document.ontouchmove = function() {
2623    return false;
2624  };
2625  /* nectar addition iOS15 fix end */
2626
2627  // prevent clicks
2628  this.isPreventingClicks = true;
2629  this.dragStart( event, pointer );
2630};
2631
2632proto.dragStart = function( event, pointer ) {
2633  this.emitEvent( 'dragStart', [ event, pointer ] );
2634};
2635
2636// dragMove
2637proto._dragMove = function( event, pointer, moveVector ) {
2638  // do not drag if not dragging yet
2639  if ( !this.isDragging ) {
2640    return;
2641  }
2642
2643  this.dragMove( event, pointer, moveVector );
2644};
2645
2646proto.dragMove = function( event, pointer, moveVector ) {
2647  event.preventDefault();
2648  this.emitEvent( 'dragMove', [ event, pointer, moveVector ] );
2649};
2650
2651// dragEnd
2652proto._dragEnd = function( event, pointer ) {
2653  // set flags
2654  this.isDragging = false;
2655
2656  /* nectar addition iOS15 fix */
2657  document.ontouchmove = function() {
2658    return true;
2659  };
2660  /* nectar addition iOS15 fix end */
2661
2662  // re-enable clicking async
2663  setTimeout( function() {
2664    delete this.isPreventingClicks;
2665  }.bind( this ) );
2666
2667  this.dragEnd( event, pointer );
2668};
2669
2670proto.dragEnd = function( event, pointer ) {
2671  this.emitEvent( 'dragEnd', [ event, pointer ] );
2672};
2673
2674// ----- onclick ----- //
2675
2676// handle all clicks and prevent clicks when dragging
2677proto.onclick = function( event ) {
vendor: 9,088 bytes, lines 2678-3006
2678  if ( this.isPreventingClicks ) {
2679    event.preventDefault();
2680  }
2681};
2682
2683// ----- staticClick ----- //
2684
2685// triggered after pointer down & up with no/tiny movement
2686proto._staticClick = function( event, pointer ) {
2687  // ignore emulated mouse up clicks
2688  if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) {
2689    return;
2690  }
2691
2692  this.staticClick( event, pointer );
2693
2694  // set flag for emulated clicks 300ms after touchend
2695  if ( event.type != 'mouseup' ) {
2696    this.isIgnoringMouseUp = true;
2697    // reset flag after 300ms
2698    setTimeout( function() {
2699      delete this.isIgnoringMouseUp;
2700    }.bind( this ), 400 );
2701  }
2702};
2703
2704proto.staticClick = function( event, pointer ) {
2705  this.emitEvent( 'staticClick', [ event, pointer ] );
2706};
2707
2708// ----- utils ----- //
2709
2710Unidragger.getPointerPoint = Unipointer.getPointerPoint;
2711
2712// -----  ----- //
2713
2714return Unidragger;
2715
2716}));
2717
2718// drag
2719( function( window, factory ) {
2720  // universal module definition
2721  /* jshint strict: false */
2722  if ( typeof define == 'function' && define.amd ) {
2723    // AMD
2724    define( 'flickity/js/drag',[
2725      './flickity',
2726      'unidragger/unidragger',
2727      'fizzy-ui-utils/utils'
2728    ], function( Flickity, Unidragger, utils ) {
2729      return factory( window, Flickity, Unidragger, utils );
2730    });
2731  } else if ( typeof module == 'object' && module.exports ) {
2732    // CommonJS
2733    module.exports = factory(
2734      window,
2735      require('./flickity'),
2736      require('unidragger'),
2737      require('fizzy-ui-utils')
2738    );
2739  } else {
2740    // browser global
2741    window.Flickity = factory(
2742      window,
2743      window.Flickity,
2744      window.Unidragger,
2745      window.fizzyUIUtils
2746    );
2747  }
2748
2749}( window, function factory( window, Flickity, Unidragger, utils ) {
2750
2751
2752
2753// ----- defaults ----- //
2754
2755utils.extend( Flickity.defaults, {
2756  draggable: '>1',
2757  dragThreshold: 3,
2758});
2759
2760// ----- create ----- //
2761
2762Flickity.createMethods.push('_createDrag');
2763
2764// -------------------------- drag prototype -------------------------- //
2765
2766var proto = Flickity.prototype;
2767utils.extend( proto, Unidragger.prototype );
2768proto._touchActionValue = 'pan-y';
2769
2770// --------------------------  -------------------------- //
2771
2772var isTouch = 'createTouch' in document;
2773var isTouchmoveScrollCanceled = false;
2774
2775proto._createDrag = function() {
2776  this.on( 'activate', this.onActivateDrag );
2777  this.on( 'uiChange', this._uiChangeDrag );
2778  this.on( 'childUIPointerDown', this._childUIPointerDownDrag );
2779  this.on( 'deactivate', this.onDeactivateDrag );
2780  this.on( 'cellChange', this.updateDraggable );
2781  // TODO updateDraggable on resize? if groupCells & slides change
2782  // HACK - add seemingly innocuous handler to fix iOS 10 scroll behavior
2783  // #457, RubaXa/Sortable#973
2784  if ( isTouch && !isTouchmoveScrollCanceled ) {
2785    window.addEventListener( 'touchmove', function() {});
2786    isTouchmoveScrollCanceled = true;
2787  }
2788};
2789
2790proto.onActivateDrag = function() {
2791  this.handles = [ this.viewport ];
2792  this.bindHandles();
2793  this.updateDraggable();
2794};
2795
2796proto.onDeactivateDrag = function() {
2797  this.unbindHandles();
2798  this.element.classList.remove('is-draggable');
2799};
2800
2801proto.updateDraggable = function() {
2802  // disable dragging if less than 2 slides. #278
2803  if ( this.options.draggable == '>1' ) {
2804    this.isDraggable = this.slides.length > 1;
2805  } else {
2806    this.isDraggable = this.options.draggable;
2807  }
2808  if ( this.isDraggable ) {
2809    this.element.classList.add('is-draggable');
2810  } else {
2811    this.element.classList.remove('is-draggable');
2812  }
2813};
2814
2815// backwards compatibility
2816proto.bindDrag = function() {
2817  this.options.draggable = true;
2818  this.updateDraggable();
2819};
2820
2821proto.unbindDrag = function() {
2822  this.options.draggable = false;
2823  this.updateDraggable();
2824};
2825
2826proto._uiChangeDrag = function() {
2827  delete this.isFreeScrolling;
2828};
2829
2830proto._childUIPointerDownDrag = function( event ) {
2831  // allow focus & preventDefault even when not draggable
2832  // so child UI elements keep focus on carousel. #721
2833  event.preventDefault();
2834  this.pointerDownFocus( event );
2835};
2836
2837// -------------------------- pointer events -------------------------- //
2838
2839proto.pointerDown = function( event, pointer ) {
2840  if ( !this.isDraggable ) {
2841    this._pointerDownDefault( event, pointer );
2842    return;
2843  }
2844  var isOkay = this.okayPointerDown( event );
2845  if ( !isOkay ) {
2846    return;
2847  }
2848
2849  this._pointerDownPreventDefault( event );
2850  this.pointerDownFocus( event );
2851  // blur
2852  if ( document.activeElement != this.element ) {
2853    // do not blur if already focused
2854    this.pointerDownBlur();
2855  }
2856
2857  // stop if it was moving
2858  this.dragX = this.x;
2859  this.viewport.classList.add('is-pointer-down');
2860  // track scrolling
2861  this.pointerDownScroll = getScrollPosition();
2862  window.addEventListener( 'scroll', this );
2863
2864  this._pointerDownDefault( event, pointer );
2865};
2866
2867// default pointerDown logic, used for staticClick
2868proto._pointerDownDefault = function( event, pointer ) {
2869  // track start event position
2870  // Safari 9 overrides pageX and pageY. These values needs to be copied. #779
2871  this.pointerDownPointer = {
2872    pageX: pointer.pageX,
2873    pageY: pointer.pageY,
2874  };
2875  // bind move and end events
2876  this._bindPostStartEvents( event );
2877  this.dispatchEvent( 'pointerDown', event, [ pointer ] );
2878};
2879
2880var focusNodes = {
2881  INPUT: true,
2882  TEXTAREA: true,
2883  SELECT: true,
2884};
2885
2886proto.pointerDownFocus = function( event ) {
2887  var isFocusNode = focusNodes[ event.target.nodeName ];
2888  if ( !isFocusNode ) {
2889    this.focus();
2890  }
2891};
2892
2893proto._pointerDownPreventDefault = function( event ) {
2894  var isTouchStart = event.type == 'touchstart';
2895  var isTouchPointer = event.pointerType == 'touch';
2896  var isFocusNode = focusNodes[ event.target.nodeName ];
2897  if ( !isTouchStart && !isTouchPointer && !isFocusNode ) {
2898    event.preventDefault();
2899  }
2900};
2901
2902// ----- move ----- //
2903
2904proto.hasDragStarted = function( moveVector ) {
2905  return Math.abs( moveVector.x ) > this.options.dragThreshold;
2906};
2907
2908// ----- up ----- //
2909
2910proto.pointerUp = function( event, pointer ) {
2911  delete this.isTouchScrolling;
2912  this.viewport.classList.remove('is-pointer-down');
2913  this.dispatchEvent( 'pointerUp', event, [ pointer ] );
2914  this._dragPointerUp( event, pointer );
2915};
2916
2917proto.pointerDone = function() {
2918  window.removeEventListener( 'scroll', this );
2919  delete this.pointerDownScroll;
2920};
2921
2922// -------------------------- dragging -------------------------- //
2923
2924proto.dragStart = function( event, pointer ) {
2925  if ( !this.isDraggable ) {
2926    return;
2927  }
2928  this.dragStartPosition = this.x;
2929  this.startAnimation();
2930  window.removeEventListener( 'scroll', this );
2931  this.dispatchEvent( 'dragStart', event, [ pointer ] );
2932};
2933
2934proto.pointerMove = function( event, pointer ) {
2935  var moveVector = this._dragPointerMove( event, pointer );
2936  this.dispatchEvent( 'pointerMove', event, [ pointer, moveVector ] );
2937  this._dragMove( event, pointer, moveVector );
2938};
2939
2940proto.dragMove = function( event, pointer, moveVector ) {
2941  if ( !this.isDraggable ) {
2942    return;
2943  }
2944  event.preventDefault();
2945
2946  // reverse if right-to-left
2947  var direction = this.options.rightToLeft ? -1 : 1;
2948  if ( this.options.wrapAround ) {
2949    // wrap around move. #589
2950    moveVector.x = moveVector.x % this.slideableWidth;
2951  }
2952  var dragX = this.dragStartPosition + moveVector.x * direction;
2953
2954  if ( !this.options.wrapAround && this.slides.length ) {
2955    // slow drag
2956    var originBound = Math.max( -this.slides[0].target, this.dragStartPosition );
2957    dragX = dragX > originBound ? ( dragX + originBound ) * 0.5 : dragX;
2958    var endBound = Math.min( -this.getLastSlide().target, this.dragStartPosition );
2959    dragX = dragX < endBound ? ( dragX + endBound ) * 0.5 : dragX;
2960  }
2961
2962  // nectar addition ios13 bugfix
2963  if ( this.dragX !== dragX ) {
2964    this.previousDragX = this.dragX;
2965  }
2966
2967  this.dragX = dragX;
2968
2969  this.dragMoveTime = new Date();
2970  this.dispatchEvent( 'dragMove', event, [ pointer, moveVector ] );
2971};
2972
2973proto.dragEnd = function( event, pointer ) {
2974  if ( !this.isDraggable ) {
2975    return;
2976  }
2977  if ( this.options.freeScroll ) {
2978    this.isFreeScrolling = true;
2979  }
2980  // set selectedIndex based on where flick will end up
2981  var index = this.dragEndRestingSelect();
2982
2983  if ( this.options.freeScroll && !this.options.wrapAround ) {
2984    // if free-scroll & not wrap around
2985    // do not free-scroll if going outside of bounding slides
2986    // so bounding slides can attract slider, and keep it in bounds
2987    var restingX = this.getRestingPosition();
2988    this.isFreeScrolling = -restingX > this.slides[0].target &&
2989      -restingX < this.getLastSlide().target;
2990  } else if ( !this.options.freeScroll && index == this.selectedIndex ) {
2991    // boost selection if selected index has not changed
2992    index += this.dragEndBoostSelect();
2993  }
2994  delete this.previousDragX;
2995  // apply selection
2996  // TODO refactor this, selecting here feels weird
2997  // HACK, set flag so dragging stays in correct direction
2998  this.isDragSelect = this.options.wrapAround;
2999  this.select( index );
3000  delete this.isDragSelect;
3001  this.dispatchEvent( 'dragEnd', event, [ pointer ] );
3002};
3003
3004proto.dragEndRestingSelect = function() {
3005  var restingX = this.getRestingPosition();
3006  // how far away from selected slide
3007  var distance = Math.abs( this.getSlideDistance( -restingX, this.selectedIndex ) );
3008  // get closet resting going up and going down
3009  var positiveResting = this._getClosestResting( restingX, distance, 1 );
3010  var negativeResting = this._getClosestResting( restingX, distance, -1 );
3011  // use closer resting for wrap-around
3012  var index = positiveResting.distance < negativeResting.distance ?
3013    positiveResting.index : negativeResting.index;
3014  return index;
3015};
3016
3017/**
3018 * given resting X and distance to selected cell
3019 * get the distance and index of the closest cell
3020 * @param {Number} restingX - estimated post-flick resting position
3021 * @param {Number} distance - distance to selected cell
3022 * @param {Integer} increment - +1 or -1, going up or down
3023 * @returns {Object} - { distance: {Number}, index: {Integer} }
3024 */
3025proto._getClosestResting = function( restingX, distance, increment ) {
3026  var index = this.selectedIndex;
3027  var minDistance = Infinity;
3028  var condition = this.options.contain && !this.options.wrapAround ?
3029    // if contain, keep going if distance is equal to minDistance
3030    function( d, md ) { return d <= md; } : function( d, md ) { return d < md; };
3031  while ( condition( distance, minDistance ) ) {
3032    // measure distance to next cell
3033    index += increment;
3034    minDistance = distance;
3035    distance = this.getSlideDistance( -restingX, index );
3036    if ( distance === null ) {
3037      break;
3038    }
3039    distance = Math.abs( distance );
3040  }
3041  return {
3042    distance: minDistance,
3043    // selected was previous index
3044    index: index - increment
3045  };
3046};
3047
3048/**
3049 * measure distance between x and a slide target
3050 * @param {Number} x
3051 * @param {Integer} index - slide index
3052 */
3053proto.getSlideDistance = function( x, index ) {
3054  var len = this.slides.length;
3055  // wrap around if at least 2 slides
3056  var isWrapAround = this.options.wrapAround && len > 1;
3057  var slideIndex = isWrapAround ? utils.modulo( index, len ) : index;
3058  var slide = this.slides[ slideIndex ];
3059  if ( !slide ) {
3060    return null;
3061  }
3062  // add distance for wrap-around slides
3063  var wrap = isWrapAround ? this.slideableWidth * Math.floor( index / len ) : 0;
3064  return x - ( slide.target + wrap );
3065};
3066
3067proto.dragEndBoostSelect = function() {
3068  // do not boost if no previousDragX or dragMoveTime
3069  if ( this.previousDragX === undefined || !this.dragMoveTime ||
3070    // or if drag was held for 100 ms
3071    new Date() - this.dragMoveTime > 100 ) {
3072    return 0;
3073  }
3074
3075  var distance = this.getSlideDistance( -this.dragX, this.selectedIndex );
3076  var delta = this.previousDragX - this.dragX;
3077  if ( distance > 0 && delta > 0 ) {
3078    // boost to next if moving towards the right, and positive velocity
3079    return 1;
3080  } else if ( distance < 0 && delta < 0 ) {
3081    // boost to previous if moving towards the left, and negative velocity
3082    return -1;
3083  }
3084  return 0;
3085};
3086
3087// ----- staticClick ----- //
3088
3089proto.staticClick = function( event, pointer ) {
3090  // get clickedCell, if cell was clicked
3091  var clickedCell = this.getParentCell( event.target );
3092  var cellElem = clickedCell && clickedCell.element;
3093  var cellIndex = clickedCell && this.cells.indexOf( clickedCell );
3094  this.dispatchEvent( 'staticClick', event, [ pointer, cellElem, cellIndex ] );
3095};
3096
3097// ----- scroll ----- //
3098
3099proto.onscroll = function() {
3100  var scroll = getScrollPosition();
3101  var scrollMoveX = this.pointerDownScroll.x - scroll.x;
3102  var scrollMoveY = this.pointerDownScroll.y - scroll.y;
3103  // cancel click/tap if scroll is too much
3104  if ( Math.abs( scrollMoveX ) > 3 || Math.abs( scrollMoveY ) > 3 ) {
3105    this._pointerDone();
3106  }
3107};
3108
3109// ----- utils ----- //
3110
3111function getScrollPosition() {
3112  return {
3113    x: window.pageXOffset,
3114    y: window.pageYOffset
3115  };
3116}
3117
3118// -----  ----- //
3119
3120return Flickity;
3121
3122}));
3123
3124/*!
3125 * Tap listener v2.0.0
3126 * listens to taps
3127 * MIT license
3128 */
3129
3130/*jshint browser: true, unused: true, undef: true, strict: true */
3131
3132( function( window, factory ) {
3133  // universal module definition
3134  /*jshint strict: false*/ /*globals define, module, require */
3135
3136  if ( typeof define == 'function' && define.amd ) {
3137    // AMD
3138    define( 'tap-listener/tap-listener',[
3139      'unipointer/unipointer'
3140    ], function( Unipointer ) {
3141      return factory( window, Unipointer );
3142    });
3143  } else if ( typeof module == 'object' && module.exports ) {
3144    // CommonJS
3145    module.exports = factory(
3146      window,
3147      require('unipointer')
3148    );
3149  } else {
3150    // browser global
3151    window.TapListener = factory(
3152      window,
3153      window.Unipointer
3154    );
3155  }
3156
3157}( window, function factory( window, Unipointer ) {
3158
3159
3160
3161// --------------------------  TapListener -------------------------- //
3162
3163function TapListener( elem ) {
3164  this.bindTap( elem );
3165}
3166
3167// inherit Unipointer & EventEmitter
3168var proto = TapListener.prototype = Object.create( Unipointer.prototype );
3169
3170/**
3171 * bind tap event to element
3172 * @param {Element} elem
3173 */
3174proto.bindTap = function( elem ) {
3175  if ( !elem ) {
3176    return;
3177  }
3178  this.unbindTap();
3179  this.tapElement = elem;
3180  this._bindStartEvent( elem, true );
3181};
3182
3183proto.unbindTap = function() {
3184  if ( !this.tapElement ) {
3185    return;
3186  }
3187  this._bindStartEvent( this.tapElement, true );
3188  delete this.tapElement;
3189};
3190
3191/**
3192 * pointer up
3193 * @param {Event} event
3194 * @param {Event or Touch} pointer
3195 */
3196proto.pointerUp = function( event, pointer ) {
3197  // ignore emulated mouse up clicks
3198  if ( this.isIgnoringMouseUp && event.type == 'mouseup' ) {
3199    return;
3200  }
3201
3202  var pointerPoint = Unipointer.getPointerPoint( pointer );
3203  var boundingRect = this.tapElement.getBoundingClientRect();
3204  var scrollX = window.pageXOffset;
3205  var scrollY = window.pageYOffset;
3206  // calculate if pointer is inside tapElement
3207  var isInside = pointerPoint.x >
3207= boundingRect.left + scrollX &&
3208    pointerPoint.x <= boundingRect.right + scrollX &&
3209    pointerPoint.y >= boundingRect.top + scrollY &&
3210    pointerPoint.y <= boundingRect.bottom + scrollY;
3211  // trigger callback if pointer is inside element
3212  if ( isInside ) {
3213    this.emitEvent( 'tap', [ event, pointer ] );
3214  }
3215
3216  // set flag for emulated clicks 300ms after touchend
3217  if ( event.type != 'mouseup' ) {
3218    this.isIgnoringMouseUp = true;
3219    // reset flag after 300ms
3220    var _this = this;
3221    setTimeout( function() {
3222      delete _this.isIgnoringMouseUp;
3223    }, 400 );
3224  }
3225};
3226
3227proto.destroy = function() {
3228  this.pointerDone();
3229  this.unbindTap();
3230};
3231
3232// -----  ----- //
3233
3234return TapListener;
3235
3236}));
3237
3238// prev/next buttons
3239( function( window, factory ) {
3240  // universal module definition
3241  /* jshint strict: false */
3242  if ( typeof define == 'function' && define.amd ) {
3243    // AMD
3244    define( 'flickity/js/prev-next-button',[
3245      './flickity',
3246      'tap-listener/tap-listener',
3247      'fizzy-ui-utils/utils'
3248    ], function( Flickity, TapListener, utils ) {
3249      return factory( window, Flickity, TapListener, utils );
3250    });
3251  } else if ( typeof module == 'object' && module.exports ) {
3252    // CommonJS
3253    module.exports = factory(
3254      window,
3255      require('./flickity'),
3256      require('tap-listener'),
3257      require('fizzy-ui-utils')
3258    );
3259  } else {
3260    // browser global
3261    factory(
3262      window,
3263      window.Flickity,
3264      window.TapListener,
3265      window.fizzyUIUtils
3266    );
3267  }
3268
3269}( window, function factory( window, Flickity, TapListener, utils ) {
3270'use strict';
3271
3272var svgURI = 'http://www.w3.org/2000/svg';
3273
3274// -------------------------- PrevNextButton -------------------------- //
3275
3276function PrevNextButton( direction, parent ) {
3277  this.direction = direction;
3278  this.parent = parent;
3279  this._create();
3280}
3281
3282PrevNextButton.prototype = Object.create( TapListener.prototype );
3283
3284PrevNextButton.prototype._create = function() {
3285  // properties
3286  this.isEnabled = true;
3287  this.isPrevious = this.direction == -1;
3288  var leftDirection = this.parent.options.rightToLeft ? 1 : -1;
3289  this.isLeft = this.direction == leftDirection;
3290
3291  var element = this.element = document.createElement('button');
3292  element.className = 'flickity-button flickity-prev-next-button';
3293  element.className += this.isPrevious ? ' previous' : ' next';
3294  // prevent button from submitting form http://stackoverflow.com/a/10836076/182183
3295  element.setAttribute( 'type', 'button' );
3296  // init as disabled
3297  this.disable();
3298
3299  element.setAttribute( 'aria-label', this.isPrevious ? 'Previous' : 'Next' );
3300
3301  // create arrow
3302  var svg = this.createSVG();
3303  element.appendChild( svg );
3304  // events
3305  this.on( 'tap', this.onTap );
3306  this.parent.on( 'select', this.update.bind( this ) );
3307  this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
3308};
3309
3310PrevNextButton.prototype.activate = function() {
3311  this.bindTap( this.element );
3312  // click events from keyboard
3313  this.element.addEventListener( 'click', this );
3314  // add to DOM
3315  this.parent.element.appendChild( this.element );
3316};
3317
3318PrevNextButton.prototype.deactivate = function() {
3319  // remove from DOM
3320  this.parent.element.removeChild( this.element );
3321  // do regular TapListener destroy
3322  TapListener.prototype.destroy.call( this );
3323  // click events from keyboard
3324  this.element.removeEventListener( 'click', this );
3325};
3326
3327PrevNextButton.prototype.createSVG = function() {
3328  var svg = document.createElementNS( svgURI, 'svg');
3329  svg.setAttribute( 'class', 'flickity-button-icon' );
3330  svg.setAttribute( 'viewBox', '0 0 100 100' );
3331  var path = document.createElementNS( svgURI, 'path');
3332  var pathMovements = getArrowMovements( this.parent.options.arrowShape );
3333  path.setAttribute( 'd', pathMovements );
3334  path.setAttribute( 'class', 'arrow' );
3335  // rotate arrow
3336  if ( !this.isLeft ) {
3337    path.setAttribute( 'transform', 'translate(100, 100) rotate(180) ' );
3338  }
3339  svg.appendChild( path );
3340  return svg;
3341};
3342
3343// get SVG path movmement
3344function getArrowMovements( shape ) {
3345  // use shape as movement if string
3346  if ( typeof shape == 'string' ) {
3347    return shape;
3348  }
3349  // create movement string
3350  return 'M ' + shape.x0 + ',50' +
3351    ' L ' + shape.x1 + ',' + ( shape.y1 + 50 ) +
3352    ' L ' + shape.x2 + ',' + ( shape.y2 + 50 ) +
3353    ' L ' + shape.x3 + ',50 ' +
3354    ' L ' + shape.x2 + ',' + ( 50 - shape.y2 ) +
3355    ' L ' + shape.x1 + ',' + ( 50 - shape.y1 ) +
3356    ' Z';
3357}
3358
3359PrevNextButton.prototype.onTap = function() {
3360  if ( !this.isEnabled ) {
3361    return;
3362  }
3363  this.parent.uiChange();
3364  var method = this.isPrevious ? 'previous' : 'next';
3365  this.parent[ method ]();
3366};
3367
3368PrevNextButton.prototype.handleEvent = utils.handleEvent;
3369
3370PrevNextButton.prototype.onclick = function( event ) {
3371  // only allow clicks from keyboard
3372  var focused = document.activeElement;
3373  if ( focused && focused == this.element ) {
3374    this.onTap( event, event );
3375  }
3376};
3377
3378// -----  ----- //
3379
3380PrevNextButton.prototype.enable = function() {
3381  if ( this.isEnabled ) {
3382    return;
3383  }
3384  this.element.disabled = false;
3385  this.isEnabled = true;
3386};
3387
3388PrevNextButton.prototype.disable = function() {
3389  if ( !this.isEnabled ) {
3390    return;
3391  }
3392  this.element.disabled = true;
3393  this.isEnabled = false;
3394};
3395
3396PrevNextButton.prototype.update = function() {
3397  // index of first or last slide, if previous or next
3398  var slides = this.parent.slides;
3399  // enable is wrapAround and at least 2 slides
3400  if ( this.parent.options.wrapAround && slides.length > 1 ) {
3401    this.enable();
3402    return;
3403  }
3404  var lastIndex = slides.length ? slides.length - 1 : 0;
3405  var boundIndex = this.isPrevious ? 0 : lastIndex;
3406  var method = this.parent.selectedIndex == boundIndex ? 'disable' : 'enable';
3407  this[ method ]();
3408};
3409
3410PrevNextButton.prototype.destroy = function() {
3411  this.deactivate();
3412};
3413
3414// -------------------------- Flickity prototype -------------------------- //
3415
3416utils.extend( Flickity.defaults, {
3417  prevNextButtons: true,
3418  arrowShape: {
3419    x0: 10,
3420    x1: 60, y1: 50,
3421    x2: 70, y2: 40,
3422    x3: 30
3423  }
3424});
3425
3426Flickity.createMethods.push('_createPrevNextButtons');
3427var proto = Flickity.prototype;
3428
3429proto._createPrevNextButtons = function() {
3430  if ( !this.options.prevNextButtons ) {
3431    return;
3432  }
3433
3434  this.prevButton = new PrevNextButton( -1, this );
3435  this.nextButton = new PrevNextButton( 1, this );
3436
3437  this.on( 'activate', this.activatePrevNextButtons );
3438};
3439
3440proto.activatePrevNextButtons = function() {
3441  this.prevButton.activate();
3442  this.nextButton.activate();
3443  this.on( 'deactivate', this.deactivatePrevNextButtons );
3444};
3445
3446proto.deactivatePrevNextButtons = function() {
3447  this.prevButton.deactivate();
3448  this.nextButton.deactivate();
3449  this.off( 'deactivate', this.deactivatePrevNextButtons );
3450};
3451
3452// --------------------------  -------------------------- //
3453
3454Flickity.PrevNextButton = PrevNextButton;
3455
3456return Flickity;
3457
3458}));
3459
3460// page dots
3461( function( window, factory ) {
3462  // universal module definition
3463  /* jshint strict: false */
3464  if ( typeof define == 'function' && define.amd ) {
3465    // AMD
3466    define( 'flickity/js/page-dots',[
3467      './flickity',
3468      'tap-listener/tap-listener',
3469      'fizzy-ui-utils/utils'
3470    ], function( Flickity, TapListener, utils ) {
3471      return factory( window, Flickity, TapListener, utils );
3472    });
3473  } else if ( typeof module == 'object' && module.exports ) {
3474    // CommonJS
3475    module.exports = factory(
3476      window,
3477      require('./flickity'),
3478      require('tap-listener'),
3479      require('fizzy-ui-utils')
3480    );
3481  } else {
3482    // browser global
3483    factory(
3484      window,
3485      window.Flickity,
3486      window.TapListener,
3487      window.fizzyUIUtils
3488    );
3489  }
3490
3491}( window, function factory( window, Flickity, TapListener, utils ) {
3492
3493// -------------------------- PageDots -------------------------- //
3494
3495
3496
3497function PageDots( parent ) {
3498  this.parent = parent;
3499  this._create();
3500}
3501
3502PageDots.prototype = new TapListener();
3503
3504PageDots.prototype._create = function() {
3505  // create holder element
3506  this.holder = document.createElement('ol');
3507  this.holder.className = 'flickity-page-dots';
3508  // create dots, array of elements
3509  this.dots = [];
3510  // events
3511  this.on( 'tap', this.onTap );
3512  this.on( 'pointerDown', this.parent.childUIPointerDown.bind( this.parent ) );
3513};
3514
3515PageDots.prototype.activate = function() {
3516  this.setDots();
3517  this.bindTap( this.holder );
3518  // add to DOM
3519  this.parent.element.appendChild( this.holder );
3520};
3521
3522PageDots.prototype.deactivate = function() {
3523  // remove from DOM
3524  this.parent.element.removeChild( this.holder );
3525  TapListener.prototype.destroy.call( this );
3526};
3527
3528PageDots.prototype.setDots = function() {
3529  // get difference between number of slides and number of dots
3530  var delta = this.parent.slides.length - this.dots.length;
3531  if ( delta > 0 ) {
3532    this.addDots( delta );
3533  } else if ( delta < 0 ) {
3534    this.removeDots( -delta );
3535  }
3536};
3537
3538PageDots.prototype.addDots = function( count ) {
3539  var fragment = document.createDocumentFragment();
3540  var newDots = [];
3541  var length = this.dots.length;
3542  var max = length + count;
3543
3544  for ( var i = length; i < max; i++ ) {
3545    var dot = document.createElement('li');
3546    dot.className = 'dot';
3547    dot.setAttribute( 'aria-label', 'Page dot ' + ( i + 1 ) );
3548    fragment.appendChild( dot );
3549    newDots.push( dot );
3550  }
3551
3552  this.holder.appendChild( fragment );
3553  this.dots = this.dots.concat( newDots );
3554};
3555
3556PageDots.prototype.removeDots = function( count ) {
3557  // remove from this.dots collection
3558  var removeDots = this.dots.splice( this.dots.length - count, count );
3559  // remove from DOM
3560  removeDots.forEach( function( dot ) {
3561    this.holder.removeChild( dot );
3562  }, this );
3563};
3564
3565PageDots.prototype.updateSelected = function() {
3566  // remove selected class on previous
3567  if ( this.selectedDot ) {
3568    this.selectedDot.className = 'dot';
3569    this.selectedDot.removeAttribute('aria-current');
3570  }
3571  // don't proceed if no dots
3572  if ( !this.dots.length ) {
3573    return;
3574  }
3575  this.selectedDot = this.dots[ this.parent.selectedIndex ];
3576  this.selectedDot.className = 'dot is-selected';
3577  this.selectedDot.setAttribute( 'aria-current', 'step' );
3578};
3579
3580PageDots.prototype.onTap = function( event ) {
3581  var target = event.target;
3582  // only care about dot clicks
3583  if ( target.nodeName != 'LI' ) {
3584    return;
3585  }
3586
3587  this.parent.uiChange();
3588  var index = this.dots.indexOf( target );
3589  this.parent.select( index );
3590};
3591
3592PageDots.prototype.destroy = function() {
3593  this.deactivate();
3594};
3595
3596Flickity.PageDots = PageDots;
3597
3598// -------------------------- Flickity -------------------------- //
3599
3600utils.extend( Flickity.defaults, {
3601  pageDots: true
3602});
3603
3604Flickity.createMethods.push('_createPageDots');
3605
3606var proto = Flickity.prototype;
3607
3608proto._createPageDots = function() {
3609  if ( !this.options.pageDots ) {
3610    return;
3611  }
3612  this.pageDots = new PageDots( this );
3613  // events
3614  this.on( 'activate', this.activatePageDots );
3615  this.on( 'select', this.updateSelectedPageDots );
3616  this.on( 'cellChange', this.updatePageDots );
3617  this.on( 'resize', this.updatePageDots );
3618  this.on( 'deactivate', this.deactivatePageDots );
3619};
3620
3621proto.activatePageDots = function() {
3622  this.pageDots.activate();
3623};
3624
3625proto.updateSelectedPageDots = function() {
3626  this.pageDots.updateSelected();
3627};
3628
3629proto.updatePageDots = function() {
3630  this.pageDots.setDots();
3631};
3632
3633proto.deactivatePageDots = function() {
3634  this.pageDots.deactivate();
3635};
3636
3637// -----  ----- //
3638
3639Flickity.PageDots = PageDots;
3640
3641return Flickity;
3642
3643}));
3644
3645// player & autoPlay
3646( function( window, factory ) {
3647  // universal module definition
3648  /* jshint strict: false */
3649  if ( typeof define == 'function' && define.amd ) {
3650    // AMD
3651    define( 'flickity/js/player',[
3652      'ev-emitter/ev-emitter',
3653      'fizzy-ui-utils/utils',
3654      './flickity'
3655    ], function( EvEmitter, utils, Flickity ) {
3656      return factory( EvEmitter, utils, Flickity );
3657    });
3658  } else if ( typeof module == 'object' && module.exports ) {
3659    // CommonJS
3660    module.exports = factory(
3661      require('ev-emitter'),
3662      require('fizzy-ui-utils'),
3663      require('./flickity')
3664    );
3665  } else {
3666    // browser global
3667    factory(
3668      window.EvEmitter,
3669      window.fizzyUIUtils,
3670      window.Flickity
3671    );
3672  }
3673
3674}( window, function factory( EvEmitter, utils, Flickity ) {
3675
3676
3677
3678// -------------------------- Player -------------------------- //
3679
3680function Player( parent ) {
3681  this.parent = parent;
3682  this.state = 'stopped';
3683  // visibility change event handler
3684  this.onVisibilityChange = this.visibilityChange.bind( this );
3685  this.onVisibilityPlay = this.visibilityPlay.bind( this );
3686}
3687
3688Player.prototype = Object.create( EvEmitter.prototype );
3689
3690// start play
3691Player.prototype.play = function() {
3692  if ( this.state == 'playing' ) {
3693    return;
3694  }
3695  // do not play if page is hidden, start playing when page is visible
3696  var isPageHidden = document.hidden;
3697  if ( isPageHidden ) {
3698    document.addEventListener( 'visibilitychange', this.onVisibilityPlay );
3699    return;
3700  }
3701
3702  this.state = 'playing';
3703  // listen to visibility change
3704  document.addEventListener( 'visibilitychange', this.onVisibilityChange );
3705  // start ticking
3706  this.tick();
3707};
3708
3709Player.prototype.tick = function() {
3710  // do not tick if not playing
3711  if ( this.state != 'playing' ) {
3712    return;
3713  }
3714
3715  var time = this.parent.options.autoPlay;
3716  // default to 3 seconds
3717  time = typeof time == 'number' ? time : 3000;
3718  var _this = this;
3719  // HACK: reset ticks if stopped and started within interval
3720  this.clear();
3721  this.timeout = setTimeout( function() {
3722    _this.parent.next( true );
3723    _this.tick();
3724  }, time );
3725};
3726
3727Player.prototype.stop = function() {
3728  this.state = 'stopped';
3729  this.clear();
3730  // remove visibility change event
3731  document.removeEventListener( 'visibilitychange', this.onVisibilityChange );
3732};
3733
3734Player.prototype.clear = function() {
3735  clearTimeout( this.timeout );
3736};
3737
3738Player.prototype.pause = function() {
3739  if ( this.state == 'playing' ) {
3740    this.state = 'paused';
3741    this.clear();
3742  }
3743};
3744
3745Player.prototype.unpause = function() {
3746  // re-start play if paused
3747  if ( this.state == 'paused' ) {
3748    this.play();
3749  }
3750};
3751
3752// pause if page visibility is hidden, unpause if visible
3753Player.prototype.visibilityChange = function() {
3754  var isPageHidden = document.hidden;
3755  this[ isPageHidden ? 'pause' : 'unpause' ]();
3756};
3757
3758Player.prototype.visibilityPlay = function() {
3759  this.play();
3760  document.removeEventListener( 'visibilitychange', this.onVisibilityPlay );
3761};
3762
3763// -------------------------- Flickity -------------------------- //
3764
3765utils.extend( Flickity.defaults, {
3766  pauseAutoPlayOnHover: true
3767});
3768
3769Flickity.createMethods.push('_createPlayer');
3770var proto = Flickity.prototype;
3771
3772proto._createPlayer = function() {
3773  this.player = new Player( this );
3774
3775  this.on( 'activate', this.activatePlayer );
3776  this.on( 'uiChange', this.stopPlayer );
3777  this.on( 'pointerDown', this.stopPlayer );
3778  this.on( 'deactivate', this.deactivatePlayer );
3779};
3780
3781proto.activatePlayer = function() {
3782  if ( !this.options.autoPlay ) {
3783    return;
3784  }
3785  this.player.play();
3786  this.element.addEventListener( 'mouseenter', this );
3787};
3788
3789// Player API, don't hate the ... thanks I know where the door is
3790
3791proto.playPlayer = function() {
3792  this.player.play();
3793};
3794
3795proto.stopPlayer = function() {
3796  this.player.stop();
3797};
3798
3799proto.pausePlayer = function() {
3800  this.player.pause();
3801};
3802
3803proto.unpausePlayer = function() {
3804  this.player.unpause();
3805};
3806
3807proto.deactivatePlayer = function() {
3808  this.player.stop();
3809  this.element.removeEventListener( 'mouseenter', this );
3810};
3811
3812// ----- mouseenter/leave ----- //
3813
3814// pause auto-play on hover
3815proto.onmouseenter = function() {
3816  if ( !this.options.pauseAutoPlayOnHover ) {
3817    return;
3818  }
3819  this.player.pause();
3820  this.element.addEventListener( 'mouseleave', this );
3821};
3822
3823// resume auto-play on hover off
3824proto.onmouseleave = function() {
3825  this.player.unpause();
3826  this.element.removeEventListener( 'mouseleave', this );
3827};
3828
3829// -----  ----- //
3830
3831Flickity.Player = Player;
3832
3833return Flickity;
3834
3835}));
3836
3837// add, remove cell
3838( function( window, factory ) {
3839  // universal module definition
3840  /* jshint strict: false */
3841  if ( typeof define == 'function' && define.amd ) {
3842    // AMD
3843    define( 'flickity/js/add-remove-cell',[
3844      './flickity',
3845      'fizzy-ui-utils/utils'
3846    ], function( Flickity, utils ) {
3847      return factory( window, Flickity, utils );
3848    });
3849  } else if ( typeof module == 'object' && module.exports ) {
3850    // CommonJS
3851    module.exports = factory(
3852      window,
3853      require('./flickity'),
3854      require('fizzy-ui-utils')
3855    );
3856  } else {
3857    // browser global
3858    factory(
3859      window,
3860      window.Flickity,
3861      window.fizzyUIUtils
3862    );
3863  }
3864
3865}( window, function factory( window, Flickity, utils ) {
3866
3867
3868
3869// append cells to a document fragment
3870function getCellsFragment( cells ) {
3871  var fragment = document.createDocumentFragment();
3872  cells.forEach( function( cell ) {
3873    fragment.appendChild( cell.element );
3874  });
3875  return fragment;
3876}
3877
3878// -------------------------- add/remove cell prototype -------------------------- //
3879
3880var proto = Flickity.prototype;
3881
3882/**
3883 * Insert, prepend, or append cells
3884 * @param {Element, Array, NodeList} elems
3885 * @param {Integer} index
3886 */
3887proto.insert = function( elems, index ) {
3888  var cells = this._makeCells( elems );
3889  if ( !cells || !cells.length ) {
3890    return;
3891  }
3892  var len = this.cells.length;
3893  // default to append
3894  index = index === undefined ? len : index;
3895  // add cells with document fragment
3896  var fragment = getCellsFragment( cells );
3897  // append to slider
3898  var isAppend = index == len;
3899  if ( isAppend ) {
3900    this.slider.appendChild( fragment );
3901  } else {
3902    var insertCellElement = this.cells[ index ].element;
3903    this.slider.insertBefore( fragment, insertCellElement );
3904  }
3905  // add to this.cells
3906  if ( index === 0 ) {
3907    // prepend, add to start
3908    this.cells = cells.concat( this.cells );
3909  } else if ( isAppend ) {
3910    // append, add to end
3911    this.cells = this.cells.concat( cells );
3912  } else {
3913    // insert in this.cells
3914    var endCells = this.cells.splice( index, len - index );
3915    this.cells = this.cells.concat( cells ).concat( endCells );
3916  }
3917
3918  this._sizeCells( cells );
3919  this.cellChange( index, true );
3920};
3921
3922proto.append = function( elems ) {
3923  this.insert( elems, this.cells.length );
3924};
3925
3926proto.prepend = function( elems ) {
3927  this.insert( elems, 0 );
3928};
3929
3930/**
3931 * Remove cells
3932 * @param {Element, Array, NodeList} elems
3933 */
3934proto.remove = function( elems ) {
3935  var cells = this.getCells( elems );
3936  if ( !cells || !cells.length ) {
3937    return;
3938  }
3939
3940  var minCellIndex = this.cells.length - 1;
3941  // remove cells from collection & DOM
3942  cells.forEach( function( cell ) {
3943    cell.remove();
3944    var index = this.cells.indexOf( cell );
3945    minCellIndex = Math.min( index, minCellIndex );
3946    utils.removeFrom( this.cells, cell );
3947  }, this );
3948
3949  this.cellChange( minCellIndex, true );
3950};
3951
3952/**
3953 * logic to be run after a cell's size changes
3954 * @param {Element} elem - cell's element
3955 */
3956proto.cellSizeChange = function( elem ) {
3957  var cell = this.getCell( elem );
3958  if ( !cell ) {
3959    return;
3960  }
3961  cell.getSize();
3962
3963  var index = this.cells.indexOf( cell );
3964  this.cellChange( index );
3965};
3966
3967/**
3968 * logic any time a cell is changed: added, removed, or size changed
3969 * @param {Integer} changedCellIndex - index of the changed cell, optional
3970 */
3971proto.cellChange = function( changedCellIndex, isPositioningSlider ) {
3972  var prevSelectedElem = this.selectedElement;
3973  this._positionCells( changedCellIndex );
3974  this._getWrapShiftCells();
3975  this.setGallerySize();
3976  // update selectedIndex
3977  // try to maintain position & select previous selected element
3978  var cell = this.getCell( prevSelectedElem );
3979  if ( cell ) {
3980    this.selectedIndex = this.getCellSlideIndex( cell );
3981  }
3982  this.selectedIndex = Math.min( this.slides.length - 1, this.selectedIndex );
3983
3984  this.emitEvent( 'cellChange', [ changedCellIndex ] );
3985  // position slider
3986  this.select( this.selectedIndex );
3987  // do not position slider after lazy load
3988  if ( isPositioningSlider ) {
3989    this.positionSliderAtSelected();
3990  }
3991};
3992
3993// -----  ----- //
3994
3995return Flickity;
3996
3997}));
3998
3999// lazyload
4000( function( window, factory ) {
4001  // universal module definition
4002  /* jshint strict: false */
4003  if ( typeof define == 'function' && define.amd ) {
4004    // AMD
4005    define( 'flickity/js/lazyload',[
4006      './flickity',
4007      'fizzy-ui-utils/utils'
4008    ], function( Flickity, utils ) {
4009      return factory( window, Flickity, utils );
4010    });
4011  } else if ( typeof module == 'object' && module.exports ) {
4012    // CommonJS
4013    module.exports = factory(
4014      window,
4015      require('./flickity'),
4016      require('fizzy-ui-utils')
4017    );
4018  } else {
4019    // browser global
4020    factory(
4021      window,
4022      window.Flickity,
4023      window.fizzyUIUtils
4024    );
4025  }
4026
4027}( window, function factory( window, Flickity, utils ) {
4028'use strict';
4029
4030Flickity.createMethods.push('_createLazyload');
4031var proto = Flickity.prototype;
4032
4033proto._createLazyload = function() {
4034  this.on( 'select', this.lazyLoad );
4035};
4036
4037proto.lazyLoad = function() {
4038  var lazyLoad = this.options.lazyLoad;
4039  if ( !lazyLoad ) {
4040    return;
4041  }
4042  // get adjacent cells, use lazyLoad option for adjacent count
4043  var adjCount = typeof lazyLoad == 'number' ? lazyLoad : 0;
4044  var cellElems = this.getAdjacentCellElements( adjCount );
4045  // get lazy images in those cells
4046  var lazyImages = [];
4047  cellElems.forEach( function( cellElem ) {
4048    var lazyCellImages = getCellLazyImages( cellElem );
4049    lazyImages = lazyImages.concat( lazyCellImages );
4050  });
4051  // load lazy images
4052  lazyImages.forEach( function( img ) {
4053    new LazyLoader( img, this );
4054  }, this );
4055};
4056
4057function getCellLazyImages( cellElem ) {
4058  // check if cell element is lazy image
4059  if ( cellElem.nodeName == 'IMG' ) {
4060    var lazyloadAttr = cellElem.getAttribute('data-flickity-lazyload');
4061    var srcAttr = cellElem.getAttribute('data-flickity-lazyload-src');
4062    var srcsetAttr = cellElem.getAttribute('data-flickity-lazyload-srcset');
4063    if ( lazyloadAttr || srcAttr || srcsetAttr ) {
4064      return [ cellElem ];
4065    }
4066  }
4067  // select lazy images in cell
4068  var lazySelector = 'img[data-flickity-lazyload], ' +
4069    'img[data-flickity-lazyload-src], img[data-flickity-lazyload-srcset]';
4070  var imgs = cellElem.querySelectorAll( lazySelector );
4071  return utils.makeArray( imgs );
4072}
4073
4074// -------------------------- LazyLoader -------------------------- //
4075
4076/**
4077 * class to handle loading images
4078 */
4079function LazyLoader( img, flickity ) {
4080  this.img = img;
4081  this.flickity = flickity;
4082  this.load();
4083}
4084
4085LazyLoader.prototype.handleEvent = utils.handleEvent;
4086
4087LazyLoader.prototype.load = function() {
4088  this.img.addEventListener( 'load', this );
4089  this.img.addEventListener( 'error', this );
4090  // get src & srcset
4091  var src = this.img.getAttribute('data-flickity-lazyload') ||
4092    this.img.getAttribute('data-flickity-lazyload-src');
4093  var srcset = this.img.getAttribute('data-flickity-lazyload-srcset');
4094  // set src & serset
4095  this.img.src = src;
4096  if ( srcset ) {
4097    this.img.setAttribute( 'srcset', srcset );
4098  }
4099  // remove attr
4100  this.img.removeAttribute('data-flickity-lazyload');
4101  this.img.removeAttribute('data-flickity-lazyload-src');
4102  this.img.removeAttribute('data-flickity-lazyload-srcset');
4103};
4104
4105LazyLoader.prototype.onload = function( event ) {
4106  this.complete( event, 'flickity-lazyloaded' );
4107};
4108
4109LazyLoader.prototype.onerror = function( event ) {
4110  this.complete( event, 'flickity-lazyerror' );
4111};
4112
4113LazyLoader.prototype.complete = function( event, className ) {
4114  // unbind events
4115  this.img.removeEventListener( 'load', this );
4116  this.img.removeEventListener( 'error', this );
4117
4118  var cell = this.flickity.getParentCell( this.img );
4119  var cellElem = cell && cell.element;
4120  this.flickity.cellSizeChange( cellElem );
4121
4122  this.img.classList.add( className );
4123  this.flickity.dispatchEvent( 'lazyLoad', event, cellElem );
4124};
4125
4126// -----  ----- //
4127
4128Flickity.LazyLoader = LazyLoader;
4129
4130return Flickity;
4131
4132}));
4133
4134/*!
4135 * Flickity v2.1.2
4136 * Touch, responsive, flickable carousels
4137 *
4138 * Licensed GPLv3 for open source use
4139 * or Flickity Commercial License for commercial use
4140 *
4141 * https://flickity.metafizzy.co
4142 * Copyright 2015-2018 Metafizzy
4143 */
4144
4145( function( window, factory ) {
4146  // universal module definition
4147  /* jshint strict: false */
4148  if ( typeof define == 'function' && define.amd ) {
4149    // AMD
4150    define( 'flickity/js/index',[
4151      './flickity',
4152      './drag',
4153      './prev-next-button',
4154      './page-dots',
4155      './player',
4156      './add-remove-cell',
4157      './lazyload'
4158    ], factory );
4159  } else if ( typeof module == 'object' && module.exports ) {
4160    // CommonJS
4161    module.exports = factory(
4162      require('./flickity'),
4163      require('./drag'),
4164      require('./prev-next-button'),
4165      require('./page-dots'),
4166      require('./player'),
4167      require('./add-remove-cell'),
4168      require('./lazyload')
4169    );
4170  }
4171
4172})( window, function factory( Flickity ) {
4173  /*jshint strict: false*/
4174  return Flickity;
4175});
4176
4177/*!
4178 * Flickity asNavFor v2.0.1
4179 * enable asNavFor for Flickity
4180 */
4181
4182/*jshint browser: true, undef: true, unused: true, strict: true*/
4183
4184( function( window, factory ) {
4185  // universal module definition
4186  /*jshint strict: false */ /*globals define, module, require */
4187  if ( typeof define == 'function' && define.amd ) {
4188    // AMD
4189    define( 'flickity-as-nav-for/as-nav-for',[
4190      'flickity/js/index',
4191      'fizzy-ui-utils/utils'
4192    ], factory );
4193  } else if ( typeof module == 'object' && module.exports ) {
4194    // CommonJS
4195    module.exports = factory(
4196      require('flickity'),
4197      require('fizzy-ui-utils')
4198    );
4199  } else {
4200    // browser global
4201    window.Flickity = factory(
4202      window.Flickity,
4203      window.fizzyUIUtils
4204    );
4205  }
4206
4207}( window, function factory( Flickity, utils ) {
4208
4209
4210
4211// -------------------------- asNavFor prototype -------------------------- //
4212
4213// Flickity.defaults.asNavFor = null;
4214
4215Flickity.createMethods.push('_createAsNavFor');
4216
4217var proto = Flickity.prototype;
4218
4219proto._createAsNavFor = function() {
4220  this.on( 'activate', this.activateAsNavFor );
4221  this.on( 'deactivate', this.deactivateAsNavFor );
4222  this.on( 'destroy', this.destroyAsNavFor );
4223
4224  var asNavForOption = this.options.asNavFor;
4225  if ( !asNavForOption ) {
4226    return;
4227  }
4228  // HACK do async, give time for other flickity to be initalized
4229  var _this = this;
4230  setTimeout( function initNavCompanion() {
4231    _this.setNavCompanion( asNavForOption );
4232  });
4233};
4234
4235proto.setNavCompanion = function( elem ) {
4236  elem = utils.getQueryElement( elem );
4237  var companion = Flickity.data( elem );
4238  // stop if no companion or companion is self
4239  if ( !companion || companion == this ) {
4240    return;
4241  }
4242
4243  this.navCompanion = companion;
4244  // companion select
4245  var _this = this;
4246  this.onNavCompanionSelect = function() {
4247    _this.navCompanionSelect();
4248  };
4249  companion.on( 'select', this.onNavCompanionSelect );
4250  // click
4251  this.on( 'staticClick', this.onNavStaticClick );
4252
4253  this.navCompanionSelect( true );
4254};
4255
4256proto.navCompanionSelect = function( isInstant ) {
4257  if ( !this.navCompanion ) {
4258    return;
4259  }
4260  // select slide that matches first cell of slide
4261  var selectedCell = this.navCompanion.selectedCells[0];
4262  var firstIndex = this.navCompanion.cells.indexOf( selectedCell );
4263  var lastIndex = firstIndex + this.navCompanion.selectedCells.length - 1;
4264  var selectIndex = Math.floor( lerp( firstIndex, lastIndex,
4265    this.navCompanion.cellAlign ) );
4266  this.selectCell( selectIndex, false, isInstant );
4267  // set nav selected class
4268  this.removeNavSelectedElements();
vendor: 4,404 bytes, lines 4269-4454
4269  // stop if companion has more cells than this one
4270  if ( selectIndex >= this.cells.length ) {
4271    return;
4272  }
4273
4274  var selectedCells = this.cells.slice( firstIndex, lastIndex + 1 );
4275  this.navSelectedElements = selectedCells.map( function( cell ) {
4276    return cell.element;
4277  });
4278  this.changeNavSelectedClass('add');
4279};
4280
4281function lerp( a, b, t ) {
4282  return ( b - a ) * t + a;
4283}
4284
4285proto.changeNavSelectedClass = function( method ) {
4286  this.navSelectedElements.forEach( function( navElem ) {
4287    navElem.classList[ method ]('is-nav-selected');
4288  });
4289};
4290
4291proto.activateAsNavFor = function() {
4292  this.navCompanionSelect( true );
4293};
4294
4295proto.removeNavSelectedElements = function() {
4296  if ( !this.navSelectedElements ) {
4297    return;
4298  }
4299  this.changeNavSelectedClass('remove');
4300  delete this.navSelectedElements;
4301};
4302
4303proto.onNavStaticClick = function( event, pointer, cellElement, cellIndex ) {
4304  if ( typeof cellIndex == 'number' ) {
4305    this.navCompanion.selectCell( cellIndex );
4306  }
4307};
4308
4309proto.deactivateAsNavFor = function() {
4310  this.removeNavSelectedElements();
4311};
4312
4313proto.destroyAsNavFor = function() {
4314  if ( !this.navCompanion ) {
4315    return;
4316  }
4317  this.navCompanion.off( 'select', this.onNavCompanionSelect );
4318  this.off( 'staticClick', this.onNavStaticClick );
4319  delete this.navCompanion;
4320};
4321
4322// -----  ----- //
4323
4324return Flickity;
4325
4326}));
4327
4328/*!
4329 * imagesLoaded v4.1.4
4330 * JavaScript is all like "You images are done yet or what?"
4331 * MIT License
4332 */
4333
4334( function( window, factory ) { 'use strict';
4335  // universal module definition
4336
4337  /*global define: false, module: false, require: false */
4338
4339  if ( typeof define == 'function' && define.amd ) {
4340    // AMD
4341    define( 'imagesloaded/imagesloaded',[
4342      'ev-emitter/ev-emitter'
4343    ], function( EvEmitter ) {
4344      return factory( window, EvEmitter );
4345    });
4346  } else if ( typeof module == 'object' && module.exports ) {
4347    // CommonJS
4348    module.exports = factory(
4349      window,
4350      require('ev-emitter')
4351    );
4352  } else {
4353    // browser global
4354    window.imagesLoaded = factory(
4355      window,
4356      window.EvEmitter
4357    );
4358  }
4359
4360})( typeof window !== 'undefined' ? window : this,
4361
4362// --------------------------  factory -------------------------- //
4363
4364function factory( window, EvEmitter ) {
4365
4366
4367
4368var $ = window.jQuery;
4369var console = window.console;
4370
4371// -------------------------- helpers -------------------------- //
4372
4373// extend objects
4374function extend( a, b ) {
4375  for ( var prop in b ) {
4376    a[ prop ] = b[ prop ];
4377  }
4378  return a;
4379}
4380
4381var arraySlice = Array.prototype.slice;
4382
4383// turn element or nodeList into an array
4384function makeArray( obj ) {
4385  if ( Array.isArray( obj ) ) {
4386    // use object if already an array
4387    return obj;
4388  }
4389
4390  var isArrayLike = typeof obj == 'object' && typeof obj.length == 'number';
4391  if ( isArrayLike ) {
4392    // convert nodeList to array
4393    return arraySlice.call( obj );
4394  }
4395
4396  // array of single index
4397  return [ obj ];
4398}
4399
4400// -------------------------- imagesLoaded -------------------------- //
4401
4402/**
4403 * @param {Array, Element, NodeList, String} elem
4404 * @param {Object or Function} options - if function, use as callback
4405 * @param {Function} onAlways - callback function
4406 */
4407function ImagesLoaded( elem, options, onAlways ) {
4408  // coerce ImagesLoaded() without new, to be new ImagesLoaded()
4409  if ( !( this instanceof ImagesLoaded ) ) {
4410    return new ImagesLoaded( elem, options, onAlways );
4411  }
4412  // use elem as selector string
4413  var queryElem = elem;
4414  if ( typeof elem == 'string' ) {
4415    queryElem = document.querySelectorAll( elem );
4416  }
4417  // bail if bad element
4418  if ( !queryElem ) {
4419    console.error( 'Bad element for imagesLoaded ' + ( queryElem || elem ) );
4420    return;
4421  }
4422
4423  this.elements = makeArray( queryElem );
4424  this.options = extend( {}, this.options );
4425  // shift arguments if no options set
4426  if ( typeof options == 'function' ) {
4427    onAlways = options;
4428  } else {
4429    extend( this.options, options );
4430  }
4431
4432  if ( onAlways ) {
4433    this.on( 'always', onAlways );
4434  }
4435
4436  this.getImages();
4437
4438  if ( $ ) {
4439    // add jQuery Deferred object
4440    this.jqDeferred = new $.Deferred();
4441  }
4442
4443  // HACK check async to allow time to bind listeners
4444  setTimeout( this.check.bind( this ) );
4445}
4446
4447ImagesLoaded.prototype = Object.create( EvEmitter.prototype );
4448
4449ImagesLoaded.prototype.options = {};
4450
4451ImagesLoaded.prototype.getImages = function() {
4452  this.images = [];
4453
4454  // filter & find items if we have an item selector
vendor: 4,347 bytes, lines 4455-4611
4455  this.elements.forEach( this.addElementImages, this );
4456};
4457
4458/**
4459 * @param {Node} element
4460 */
4461ImagesLoaded.prototype.addElementImages = function( elem ) {
4462  // filter siblings
4463  if ( elem.nodeName == 'IMG' ) {
4464    this.addImage( elem );
4465  }
4466  // get background image on element
4467  if ( this.options.background === true ) {
4468    this.addElementBackgroundImages( elem );
4469  }
4470
4471  // find children
4472  // no non-element nodes, #143
4473  var nodeType = elem.nodeType;
4474  if ( !nodeType || !elementNodeTypes[ nodeType ] ) {
4475    return;
4476  }
4477  var childImgs = elem.querySelectorAll('img');
4478  // concat childElems to filterFound array
4479  for ( var i=0; i < childImgs.length; i++ ) {
4480    var img = childImgs[i];
4481    this.addImage( img );
4482  }
4483
4484  // get child background images
4485  if ( typeof this.options.background == 'string' ) {
4486    var children = elem.querySelectorAll( this.options.background );
4487    for ( i=0; i < children.length; i++ ) {
4488      var child = children[i];
4489      this.addElementBackgroundImages( child );
4490    }
4491  }
4492};
4493
4494var elementNodeTypes = {
4495  1: true,
4496  9: true,
4497  11: true
4498};
4499
4500ImagesLoaded.prototype.addElementBackgroundImages = function( elem ) {
4501  var style = getComputedStyle( elem );
4502  if ( !style ) {
4503    // Firefox returns null if in a hidden iframe https://bugzil.la/548397
4504    return;
4505  }
4506  // get url inside url("...")
4507  var reURL = /url\((['"])?(.*?)\1\)/gi;
4508  var matches = reURL.exec( style.backgroundImage );
4509  while ( matches !== null ) {
4510    var url = matches && matches[2];
4511    if ( url ) {
4512      this.addBackground( url, elem );
4513    }
4514    matches = reURL.exec( style.backgroundImage );
4515  }
4516};
4517
4518/**
4519 * @param {Image} img
4520 */
4521ImagesLoaded.prototype.addImage = function( img ) {
4522  var loadingImage = new LoadingImage( img );
4523  this.images.push( loadingImage );
4524};
4525
4526ImagesLoaded.prototype.addBackground = function( url, elem ) {
4527  var background = new Background( url, elem );
4528  this.images.push( background );
4529};
4530
4531ImagesLoaded.prototype.check = function() {
4532  var _this = this;
4533  this.progressedCount = 0;
4534  this.hasAnyBroken = false;
4535  // complete if no images
4536  if ( !this.images.length ) {
4537    this.complete();
4538    return;
4539  }
4540
4541  function onProgress( image, elem, message ) {
4542    // HACK - Chrome triggers event before object properties have changed. #83
4543    setTimeout( function() {
4544      _this.progress( image, elem, message );
4545    });
4546  }
4547
4548  this.images.forEach( function( loadingImage ) {
4549    loadingImage.once( 'progress', onProgress );
4550    loadingImage.check();
4551  });
4552};
4553
4554ImagesLoaded.prototype.progress = function( image, elem, message ) {
4555  this.progressedCount++;
4556  this.hasAnyBroken = this.hasAnyBroken || !image.isLoaded;
4557  // progress event
4558  this.emitEvent( 'progress', [ this, image, elem ] );
4559  if ( this.jqDeferred && this.jqDeferred.notify ) {
4560    this.jqDeferred.notify( this, image );
4561  }
4562  // check if completed
4563  if ( this.progressedCount == this.images.length ) {
4564    this.complete();
4565  }
4566
4567  if ( this.options.debug && console ) {
4568    console.log( 'progress: ' + message, image, elem );
4569  }
4570};
4571
4572ImagesLoaded.prototype.complete = function() {
4573  var eventName = this.hasAnyBroken ? 'fail' : 'done';
4574  this.isComplete = true;
4575  this.emitEvent( eventName, [ this ] );
4576  this.emitEvent( 'always', [ this ] );
4577  if ( this.jqDeferred ) {
4578    var jqMethod = this.hasAnyBroken ? 'reject' : 'resolve';
4579    this.jqDeferred[ jqMethod ]( this );
4580  }
4581};
4582
4583// --------------------------  -------------------------- //
4584
4585function LoadingImage( img ) {
4586  this.img = img;
4587}
4588
4589LoadingImage.prototype = Object.create( EvEmitter.prototype );
4590
4591LoadingImage.prototype.check = function() {
4592  // If complete is true and browser supports natural sizes,
4593  // try to check for image status manually.
4594  var isComplete = this.getIsImageComplete();
4595  if ( isComplete ) {
4596    // report based on naturalWidth
4597    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
4598    return;
4599  }
4600
4601  // If none of the checks above matched, simulate loading on detached element.
4602  this.proxyImage = new Image();
4603  this.proxyImage.addEventListener( 'load', this );
4604  this.proxyImage.addEventListener( 'error', this );
4605  // bind to image as well for Firefox. #191
4606  this.img.addEventListener( 'load', this );
4607  this.img.addEventListener( 'error', this );
4608  this.proxyImage.src = this.img.src;
4609};
4610
4611LoadingImage.prototype.getIsImageComplete = function() {
vendor: 4,127 bytes, lines 4612-4769
4612  // check for non-zero, non-undefined naturalWidth
4613  // fixes Safari+InfiniteScroll+Masonry bug infinite-scroll#671
4614  return this.img.complete && this.img.naturalWidth;
4615};
4616
4617LoadingImage.prototype.confirm = function( isLoaded, message ) {
4618  this.isLoaded = isLoaded;
4619  this.emitEvent( 'progress', [ this, this.img, message ] );
4620};
4621
4622// ----- events ----- //
4623
4624// trigger specified handler for event type
4625LoadingImage.prototype.handleEvent = function( event ) {
4626  var method = 'on' + event.type;
4627  if ( this[ method ] ) {
4628    this[ method ]( event );
4629  }
4630};
4631
4632LoadingImage.prototype.onload = function() {
4633  this.confirm( true, 'onload' );
4634  this.unbindEvents();
4635};
4636
4637LoadingImage.prototype.onerror = function() {
4638  this.confirm( false, 'onerror' );
4639  this.unbindEvents();
4640};
4641
4642LoadingImage.prototype.unbindEvents = function() {
4643  this.proxyImage.removeEventListener( 'load', this );
4644  this.proxyImage.removeEventListener( 'error', this );
4645  this.img.removeEventListener( 'load', this );
4646  this.img.removeEventListener( 'error', this );
4647};
4648
4649// -------------------------- Background -------------------------- //
4650
4651function Background( url, element ) {
4652  this.url = url;
4653  this.element = element;
4654  this.img = new Image();
4655}
4656
4657// inherit LoadingImage prototype
4658Background.prototype = Object.create( LoadingImage.prototype );
4659
4660Background.prototype.check = function() {
4661  this.img.addEventListener( 'load', this );
4662  this.img.addEventListener( 'error', this );
4663  this.img.src = this.url;
4664  // check if image is already complete
4665  var isComplete = this.getIsImageComplete();
4666  if ( isComplete ) {
4667    this.confirm( this.img.naturalWidth !== 0, 'naturalWidth' );
4668    this.unbindEvents();
4669  }
4670};
4671
4672Background.prototype.unbindEvents = function() {
4673  this.img.removeEventListener( 'load', this );
4674  this.img.removeEventListener( 'error', this );
4675};
4676
4677Background.prototype.confirm = function( isLoaded, message ) {
4678  this.isLoaded = isLoaded;
4679  this.emitEvent( 'progress', [ this, this.element, message ] );
4680};
4681
4682// -------------------------- jQuery -------------------------- //
4683
4684ImagesLoaded.makeJQueryPlugin = function( jQuery ) {
4685  jQuery = jQuery || window.jQuery;
4686  if ( !jQuery ) {
4687    return;
4688  }
4689  // set local variable
4690  $ = jQuery;
4691  // $().imagesLoaded()
4692  $.fn.imagesLoaded = function( options, callback ) {
4693    var instance = new ImagesLoaded( this, options, callback );
4694    return instance.jqDeferred.promise( $(this) );
4695  };
4696};
4697// try making plugin
4698ImagesLoaded.makeJQueryPlugin();
4699
4700// --------------------------  -------------------------- //
4701
4702return ImagesLoaded;
4703
4704});
4705
4706/*!
4707 * Flickity imagesLoaded v2.0.0
4708 * enables imagesLoaded option for Flickity
4709 */
4710
4711/*jshint browser: true, strict: true, undef: true, unused: true */
4712
4713( function( window, factory ) {
4714  // universal module definition
4715  /*jshint strict: false */ /*globals define, module, require */
4716  if ( typeof define == 'function' && define.amd ) {
4717    // AMD
4718    define( [
4719      'flickity/js/index',
4720      'imagesloaded/imagesloaded'
4721    ], function( Flickity, imagesLoaded ) {
4722      return factory( window, Flickity, imagesLoaded );
4723    });
4724  } else if ( typeof module == 'object' && module.exports ) {
4725    // CommonJS
4726    module.exports = factory(
4727      window,
4728      require('flickity'),
4729      require('imagesloaded')
4730    );
4731  } else {
4732    // browser global
4733    window.Flickity = factory(
4734      window,
4735      window.Flickity,
4736      window.imagesLoaded
4737    );
4738  }
4739
4740}( window, function factory( window, Flickity, imagesLoaded ) {
4741'use strict';
4742
4743Flickity.createMethods.push('_createImagesLoaded');
4744
4745var proto = Flickity.prototype;
4746
4747proto._createImagesLoaded = function() {
4748  this.on( 'activate', this.imagesLoaded );
4749};
4750
4751proto.imagesLoaded = function() {
4752  if ( !this.options.imagesLoaded ) {
4753    return;
4754  }
4755  var _this = this;
4756  function onImagesLoadedProgress( instance, image ) {
4757    var cell = _this.getParentCell( image.img );
4758    _this.cellSizeChange( cell && cell.element );
4759    if ( !_this.options.freeScroll ) {
4760      _this.positionSliderAtSelected();
4761    }
4762  }
4763  imagesLoaded( this.slider ).on( 'progress', onImagesLoadedProgress );
4764};
4765
4766return Flickity;
4767
4768
4769}));

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.