/*! * Draggabilly PACKAGED v2.1.1 * Make that shiz draggable * http://draggabilly.desandro.com * MIT license */ /** * Bridget makes jQuery widgets * v2.0.0 * MIT license */ /* jshint browser: true, strict: true, undef: true, unused: true */ ( function( window, factory ) { /* globals define: false, module: false, require: false */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'jquery-bridget/jquery-bridget',[ 'jquery' ], function( jQuery ) { factory( window, jQuery ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('jquery') ); } else { // browser global window.jQueryBridget = factory( window, window.jQuery ); } }( window, function factory( window, jQuery ) { // ----- utils ----- // var arraySlice = Array.prototype.slice; // helper function for logging errors // $.error breaks jQuery chaining var console = window.console; var logError = typeof console == 'undefined' ? function() {} : function( message ) { console.error( message ); }; // ----- jQueryBridget ----- // function jQueryBridget( namespace, PluginClass, $ ) { $ = $ || jQuery || window.jQuery; if ( !$ ) { return; } // add option method -> $().plugin('option', {...}) if ( !PluginClass.prototype.option ) { // option setter PluginClass.prototype.option = function( opts ) { // bail out if not an object if ( !$.isPlainObject( opts ) ){ return; } this.options = $.extend( true, this.options, opts ); }; } // make jQuery plugin $.fn[ namespace ] = function( arg0 /*, arg1 */ ) { if ( typeof arg0 == 'string' ) { // method call $().plugin( 'methodName', { options } ) // shift arguments by 1 var args = arraySlice.call( arguments, 1 ); return methodCall( this, arg0, args ); } // just $().plugin({ options }) plainCall( this, arg0 ); return this; }; // $().plugin('methodName') function methodCall( $elems, methodName, args ) { var returnValue; var pluginMethodStr = '$().' + namespace + '("' + methodName + '")'; $elems.each( function( i, elem ) { // get instance var instance = $.data( elem, namespace ); if ( !instance ) { logError( namespace + ' not initialized. Cannot call methods, i.e. ' + pluginMethodStr ); return; } var method = instance[ methodName ]; if ( !method || methodName.charAt(0) == '_' ) { logError( pluginMethodStr + ' is not a valid method' ); return; } // apply method, get return value var value = method.apply( instance, args ); // set return value if value is returned, use only first value returnValue = returnValue === undefined ? value : returnValue; }); return returnValue !== undefined ? returnValue : $elems; } function plainCall( $elems, options ) { $elems.each( function( i, elem ) { var instance = $.data( elem, namespace ); if ( instance ) { // set options & init instance.option( options ); instance._init(); } else { // initialize new instance instance = new PluginClass( elem, options ); $.data( elem, namespace, instance ); } }); } updateJQuery( $ ); } // ----- updateJQuery ----- // // set $.bridget for v1 backwards compatibility function updateJQuery( $ ) { if ( !$ || ( $ && $.bridget ) ) { return; } $.bridget = jQueryBridget; } updateJQuery( jQuery || window.jQuery ); // ----- ----- // return jQueryBridget; })); /*! * getSize v2.0.2 * measure size of elements * MIT license */ /*jshint browser: true, strict: true, undef: true, unused: true */ /*global define: false, module: false, console: false */ ( function( window, factory ) { if ( typeof define == 'function' && define.amd ) { // AMD define( 'get-size/get-size',[],function() { return factory(); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory(); } else { // browser global window.getSize = factory(); } })( window, function factory() { // -------------------------- helpers -------------------------- // // get a number from a string, not a percentage function getStyleSize( value ) { var num = parseFloat( value ); // not a percent like '100%', and a number var isValid = value.indexOf('%') == -1 && !isNaN( num ); return isValid && num; } function noop() {} var logError = typeof console == 'undefined' ? noop : function( message ) { console.error( message ); }; // -------------------------- measurements -------------------------- // var measurements = [ 'paddingLeft', 'paddingRight', 'paddingTop', 'paddingBottom', 'marginLeft', 'marginRight', 'marginTop', 'marginBottom', 'borderLeftWidth', 'borderRightWidth', 'borderTopWidth', 'borderBottomWidth' ]; var measurementsLength = measurements.length; function getZeroSize() { var size = { width: 0, height: 0, innerWidth: 0, innerHeight: 0, outerWidth: 0, outerHeight: 0 }; for ( var i=0; i < measurementsLength; i++ ) { var measurement = measurements[i]; size[ measurement ] = 0; } return size; } // -------------------------- getStyle -------------------------- // /** * getStyle, get style of element, check for Firefox bug * https://bugzilla.mozilla.org/show_bug.cgi?id=548397 */ function getStyle( elem ) { var style = getComputedStyle( elem ); if ( !style ) { logError( 'Style returned ' + style + '. Are you running this code in a hidden iframe on Firefox? ' + 'See http://bit.ly/getsizebug1' ); } return style; } // -------------------------- setup -------------------------- // var isSetup = false; var isBoxSizeOuter; /** * setup * check isBoxSizerOuter * do on first getSize() rather than on page load for Firefox bug */ function setup() { // setup once if ( isSetup ) { return; } isSetup = true; // -------------------------- box sizing -------------------------- // /** * WebKit measures the outer-width on style.width on border-box elems * IE & Firefox<29 measures the inner-width */ var div = document.createElement('div'); div.style.width = '200px'; div.style.padding = '1px 2px 3px 4px'; div.style.borderStyle = 'solid'; div.style.borderWidth = '1px 2px 3px 4px'; div.style.boxSizing = 'border-box'; var body = document.body || document.documentElement; body.appendChild( div ); var style = getStyle( div ); getSize.isBoxSizeOuter = isBoxSizeOuter = getStyleSize( style.width ) == 200; body.removeChild( div ); } // -------------------------- getSize -------------------------- // function getSize( elem ) { setup(); // use querySeletor if elem is string if ( typeof elem == 'string' ) { elem = document.querySelector( elem ); } // do not proceed on non-objects if ( !elem || typeof elem != 'object' || !elem.nodeType ) { return; } var style = getStyle( elem ); // if hidden, everything is 0 if ( style.display == 'none' ) { return getZeroSize(); } var size = {}; size.width = elem.offsetWidth; size.height = elem.offsetHeight; var isBorderBox = size.isBorderBox = style.boxSizing == 'border-box'; // get all measurements for ( var i=0; i < measurementsLength; i++ ) { var measurement = measurements[i]; var value = style[ measurement ]; var num = parseFloat( value ); // any 'auto', 'medium' value will be 0 size[ measurement ] = !isNaN( num ) ? num : 0; } var paddingWidth = size.paddingLeft + size.paddingRight; var paddingHeight = size.paddingTop + size.paddingBottom; var marginWidth = size.marginLeft + size.marginRight; var marginHeight = size.marginTop + size.marginBottom; var borderWidth = size.borderLeftWidth + size.borderRightWidth; var borderHeight = size.borderTopWidth + size.borderBottomWidth; var isBorderBoxSizeOuter = isBorderBox && isBoxSizeOuter; // overwrite width and height if we can get it from style var styleWidth = getStyleSize( style.width ); if ( styleWidth !== false ) { size.width = styleWidth + // add padding and border unless it's already including it ( isBorderBoxSizeOuter ? 0 : paddingWidth + borderWidth ); } var styleHeight = getStyleSize( style.height ); if ( styleHeight !== false ) { size.height = styleHeight + // add padding and border unless it's already including it ( isBorderBoxSizeOuter ? 0 : paddingHeight + borderHeight ); } size.innerWidth = size.width - ( paddingWidth + borderWidth ); size.innerHeight = size.height - ( paddingHeight + borderHeight ); size.outerWidth = size.width + marginWidth; size.outerHeight = size.height + marginHeight; return size; } return getSize; }); /** * EvEmitter v1.0.3 * Lil' event emitter * MIT License */ /* jshint unused: true, undef: true, strict: true */ ( function( global, factory ) { // universal module definition /* jshint strict: false */ /* globals define, module, window */ if ( typeof define == 'function' && define.amd ) { // AMD - RequireJS define( 'ev-emitter/ev-emitter',factory ); } else if ( typeof module == 'object' && module.exports ) { // CommonJS - Browserify, Webpack module.exports = factory(); } else { // Browser globals global.EvEmitter = factory(); } }( typeof window != 'undefined' ? window : this, function() { function EvEmitter() {} var proto = EvEmitter.prototype; proto.on = function( eventName, listener ) { if ( !eventName || !listener ) { return; } // set events hash var events = this._events = this._events || {}; // set listeners array var listeners = events[ eventName ] = events[ eventName ] || []; // only add once if ( listeners.indexOf( listener ) == -1 ) { listeners.push( listener ); } return this; }; proto.once = function( eventName, listener ) { if ( !eventName || !listener ) { return; } // add event this.on( eventName, listener ); // set once flag // set onceEvents hash var onceEvents = this._onceEvents = this._onceEvents || {}; // set onceListeners object var onceListeners = onceEvents[ eventName ] = onceEvents[ eventName ] || {}; // set flag onceListeners[ listener ] = true; return this; }; proto.off = function( eventName, listener ) { var listeners = this._events && this._events[ eventName ]; if ( !listeners || !listeners.length ) { return; } var index = listeners.indexOf( listener ); if ( index != -1 ) { listeners.splice( index, 1 ); } return this; }; proto.emitEvent = function( eventName, args ) { var listeners = this._events && this._events[ eventName ]; if ( !listeners || !listeners.length ) { return; } var i = 0; var listener = listeners[i]; args = args || []; // once stuff var onceListeners = this._onceEvents && this._onceEvents[ eventName ]; while ( listener ) { var isOnce = onceListeners && onceListeners[ listener ]; if ( isOnce ) { // remove listener // remove before trigger to prevent recursion this.off( eventName, listener ); // unset once flag delete onceListeners[ listener ]; } // trigger listener listener.apply( this, args ); // get next listener i += isOnce ? 0 : 1; listener = listeners[i]; } return this; }; return EvEmitter; })); /*! * Unipointer v2.1.0 * base class for doing one thing with pointer event * MIT license */ /*jshint browser: true, undef: true, unused: true, strict: true */ ( function( window, factory ) { // universal module definition /* jshint strict: false */ /*global define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'unipointer/unipointer',[ 'ev-emitter/ev-emitter' ], function( EvEmitter ) { return factory( window, EvEmitter ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('ev-emitter') ); } else { // browser global window.Unipointer = factory( window, window.EvEmitter ); } }( window, function factory( window, EvEmitter ) { function noop() {} function Unipointer() {} // inherit EvEmitter var proto = Unipointer.prototype = Object.create( EvEmitter.prototype ); proto.bindStartEvent = function( elem ) { this._bindStartEvent( elem, true ); }; proto.unbindStartEvent = function( elem ) { this._bindStartEvent( elem, false ); }; /** * works as unbinder, as you can ._bindStart( false ) to unbind * @param {Boolean} isBind - will unbind if falsey */ proto._bindStartEvent = function( elem, isBind ) { // munge isBind, default to true isBind = isBind === undefined ? true : !!isBind; var bindMethod = isBind ? 'addEventListener' : 'removeEventListener'; if ( window.navigator.pointerEnabled ) { // W3C Pointer Events, IE11. See https://coderwall.com/p/mfreca elem[ bindMethod ]( 'pointerdown', this ); } else if ( window.navigator.msPointerEnabled ) { // IE10 Pointer Events elem[ bindMethod ]( 'MSPointerDown', this ); } else { // listen for both, for devices like Chrome Pixel elem[ bindMethod ]( 'mousedown', this ); elem[ bindMethod ]( 'touchstart', this ); } }; // trigger handler methods for events proto.handleEvent = function( event ) { var method = 'on' + event.type; if ( this[ method ] ) { this[ method ]( event ); } }; // returns the touch that we're keeping track of proto.getTouch = function( touches ) { for ( var i=0; i < touches.length; i++ ) { var touch = touches[i]; if ( touch.identifier == this.pointerIdentifier ) { return touch; } } }; // ----- start event ----- // proto.onmousedown = function( event ) { // dismiss clicks from right or middle buttons var button = event.button; if ( button && ( button !== 0 && button !== 1 ) ) { return; } this._pointerDown( event, event ); }; proto.ontouchstart = function( event ) { this._pointerDown( event, event.changedTouches[0] ); }; proto.onMSPointerDown = proto.onpointerdown = function( event ) { this._pointerDown( event, event ); }; /** * pointer start * @param {Event} event * @param {Event or Touch} pointer */ proto._pointerDown = function( event, pointer ) { // dismiss other pointers if ( this.isPointerDown ) { return; } this.isPointerDown = true; // save pointer identifier to match up touch events this.pointerIdentifier = pointer.pointerId !== undefined ? // pointerId for pointer events, touch.indentifier for touch events pointer.pointerId : pointer.identifier; this.pointerDown( event, pointer ); }; proto.pointerDown = function( event, pointer ) { this._bindPostStartEvents( event ); this.emitEvent( 'pointerDown', [ event, pointer ] ); }; // hash of events to be bound after start event var postStartEvents = { mousedown: [ 'mousemove', 'mouseup' ], touchstart: [ 'touchmove', 'touchend', 'touchcancel' ], pointerdown: [ 'pointermove', 'pointerup', 'pointercancel' ], MSPointerDown: [ 'MSPointerMove', 'MSPointerUp', 'MSPointerCancel' ] }; proto._bindPostStartEvents = function( event ) { if ( !event ) { return; } // get proper events to match start event var events = postStartEvents[ event.type ]; // bind events to node events.forEach( function( eventName ) { window.addEventListener( eventName, this ); }, this ); // save these arguments this._boundPointerEvents = events; }; proto._unbindPostStartEvents = function() { // check for _boundEvents, in case dragEnd triggered twice (old IE8 bug) if ( !this._boundPointerEvents ) { return; } this._boundPointerEvents.forEach( function( eventName ) { window.removeEventListener( eventName, this ); }, this ); delete this._boundPointerEvents; }; // ----- move event ----- // proto.onmousemove = function( event ) { this._pointerMove( event, event ); }; proto.onMSPointerMove = proto.onpointermove = function( event ) { if ( event.pointerId == this.pointerIdentifier ) { this._pointerMove( event, event ); } }; proto.ontouchmove = function( event ) { var touch = this.getTouch( event.changedTouches ); if ( touch ) { this._pointerMove( event, touch ); } }; /** * pointer move * @param {Event} event * @param {Event or Touch} pointer * @private */ proto._pointerMove = function( event, pointer ) { this.pointerMove( event, pointer ); }; // public proto.pointerMove = function( event, pointer ) { this.emitEvent( 'pointerMove', [ event, pointer ] ); }; // ----- end event ----- // proto.onmouseup = function( event ) { this._pointerUp( event, event ); }; proto.onMSPointerUp = proto.onpointerup = function( event ) { if ( event.pointerId == this.pointerIdentifier ) { this._pointerUp( event, event ); } }; proto.ontouchend = function( event ) { var touch = this.getTouch( event.changedTouches ); if ( touch ) { this._pointerUp( event, touch ); } }; /** * pointer up * @param {Event} event * @param {Event or Touch} pointer * @private */ proto._pointerUp = function( event, pointer ) { this._pointerDone(); this.pointerUp( event, pointer ); }; // public proto.pointerUp = function( event, pointer ) { this.emitEvent( 'pointerUp', [ event, pointer ] ); }; // ----- pointer done ----- // // triggered on pointer up & pointer cancel proto._pointerDone = function() { // reset properties this.isPointerDown = false; delete this.pointerIdentifier; // remove events this._unbindPostStartEvents(); this.pointerDone(); }; proto.pointerDone = noop; // ----- pointer cancel ----- // proto.onMSPointerCancel = proto.onpointercancel = function( event ) { if ( event.pointerId == this.pointerIdentifier ) { this._pointerCancel( event, event ); } }; proto.ontouchcancel = function( event ) { var touch = this.getTouch( event.changedTouches ); if ( touch ) { this._pointerCancel( event, touch ); } }; /** * pointer cancel * @param {Event} event * @param {Event or Touch} pointer * @private */ proto._pointerCancel = function( event, pointer ) { this._pointerDone(); this.pointerCancel( event, pointer ); }; // public proto.pointerCancel = function( event, pointer ) { this.emitEvent( 'pointerCancel', [ event, pointer ] ); }; // ----- ----- // // utility function for getting x/y coords from event Unipointer.getPointerPoint = function( pointer ) { return { x: pointer.pageX, y: pointer.pageY }; }; // ----- ----- // return Unipointer; })); /*! * Unidragger v2.1.0 * Draggable base class * MIT license */ /*jshint browser: true, unused: true, undef: true, strict: true */ ( function( window, factory ) { // universal module definition /*jshint strict: false */ /*globals define, module, require */ if ( typeof define == 'function' && define.amd ) { // AMD define( 'unidragger/unidragger',[ 'unipointer/unipointer' ], function( Unipointer ) { return factory( window, Unipointer ); }); } else if ( typeof module == 'object' && module.exports ) { // CommonJS module.exports = factory( window, require('unipointer') ); } else { // browser global window.Unidragger = factory( window, window.Unipointer ); } }( window, function factory( window, Unipointer ) { // ----- ----- // function noop() {} // -------------------------- Unidragger -------------------------- // function Unidragger() {} // inherit Unipointer & EvEmitter var proto = Unidragger.prototype = Object.create( Unipointer.prototype ); // ----- bind start ----- // proto.bindHandles = function() { this._bindHandles( true ); }; proto.unbindHandles = function() { this._bindHandles( false ); }; var navigator = window.navigator; /** * works as unbinder, as you can .bindHandles( false ) to unbind * @param {Boolean} isBind - will unbind if falsey */ proto._bindHandles = function( isBind ) { // munge isBind, default to true isBind = isBind === undefined ? true : !!isBind; // extra bind logic var binderExtra; if ( navigator.pointerEnabled ) { binderExtra = function( handle ) { // disable scrolling on the element handle.style.touchAction = isBind ? 'none' : ''; }; } else if ( navigator.msPointerEnabled ) { binderExtra = function( handle ) { // disable scrolling on the element handle.style.msTouchAction = isBind ? 'none' : ''; }; } else { binderExtra = noop; } // bind each handle var bindMethod = isBind ? 'addEventListener' : 'removeEventListener'; for ( var i=0; i < this.handles.length; i++ ) { var handle = this.handles[i]; this._bindStartEvent( handle, isBind ); binderExtra( handle ); handle[ bindMethod ]( 'click', this ); } }; // ----- start event ----- // /** * pointer start * @param {Event} event * @param {Event or Touch} pointer */ proto.pointerDown = function( event, pointer ) { // dismiss range sliders if ( event.target.nodeName == 'INPUT' && event.target.type == 'range' ) { // reset pointerDown logic this.isPointerDown = false; delete this.pointerIdentifier; return; } this._dragPointerDown( event, pointer ); // kludge to blur focused inputs in dragger var focused = document.activeElement; if ( focused && focused.blur ) { focused.blur(); } // bind move and end events this._bindPostStartEvents( event ); this.emitEvent( 'pointerDown', [ event, pointer ] ); }; // base pointer down logic proto._dragPointerDown = function( event, pointer ) { // track to see when dragging starts this.pointerDownPoint = Unipointer.getPointerPoint( pointer ); var canPreventDefault = this.canPreventDefaultOnPointerDown( event, pointer ); if ( canPreventDefault ) { event.preventDefault(); } }; // overwriteable method so Flickity can prevent for scrolling proto.canPreventDefaultOnPointerDown = function( event ) { // prevent default, unless touchstart or s and