PageSourceSearch

https://www.nirvanabeauty.com.au/wp-content/themes/salient/js/buil…/flickity.min.js?ver=a5a7faf57afd

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

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.