PageSourceSearch

https://www.hairdoc.de/wp-content/themes/salient/js/build/third-party/flickity.min.js?ver=2.3.1

js hairdoc.de collected 2026-09-25 10:10:45 UTC 122,651 bytes, 4,689 lines download raw bytes

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

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.