( function ( root , factory ) { if ( typeof define === 'function' && define . amd ) { define ( [ 'react' , 'prop-types' , 'create-react-class' ] , factory ) ; } else if ( typeof exports === 'object' ) { module . exports = factory ( require ( 'react' ) , require ( 'prop-types' ) , require ( 'create-react-class' ) ) ; } else { root . ReactSlider = factory ( root . React , root . PropTypes , root . createReactClass ) ; } } ( this , function ( React , PropTypes , createReactClass ) { /**
     * To prevent text selection while dragging.
     * http://stackoverflow.com/questions/5429827/how-can-i-prevent-text-element-selection-with-cursor-drag
     */ function pauseEvent ( e ) { if ( e . stopPropagation ) e . stopPropagation ( ) ; if ( e . preventDefault ) e . preventDefault ( ) ; return false ; } function stopPropagation ( e ) { if ( e . stopPropagation ) e . stopPropagation ( ) ; } /**
     * Spreads `count` values equally between `min` and `max`.
     */ function linspace ( min , max , count ) { var range = ( max - min ) / ( count - 1 ) ; var res = [ ] ; for ( var i = 0 ; i < count ; i ++ ) { res . push ( min + range * i ) ; } return res ; } function ensureArray ( x ) { return x == null ? [ ] : Array . isArray ( x ) ? x : [ x ] ; } function undoEnsureArray ( x ) { return x != null && x . length === 1 ? x [ 0 ] : x ; } var isArray = Array . isArray || function ( x ) { return Object . prototype . toString . call ( x ) === '[object Array]' ; } ; var ReactSlider = createReactClass ( { displayName : 'ReactSlider' , propTypes : { /**
             * The minimum value of the slider.
             */ min : PropTypes . number , /**
             * The maximum value of the slider.
             */ max : PropTypes . number , /**
             * Value to be added or subtracted on each step the slider makes.
             * Must be greater than zero.
             * `max - min` should be evenly divisible by the step value.
             */ step : PropTypes . number , /**
             * The minimal distance between any pair of handles.
             * Must be positive, but zero means they can sit on top of each other.
             */ minDistance : PropTypes . number , /**
             * Determines the initial positions of the handles and the number of handles if the component has no children.
             *
             * If a number is passed a slider with one handle will be rendered.
             * If an array is passed each value will determine the position of one handle.
             * The values in the array must be sorted.
             * If the component has children, the length of the array must match the number of children.
             */ defaultValue : PropTypes . oneOfType ( [ PropTypes . number , PropTypes . arrayOf ( PropTypes . number ) ] ) , /**
             * Like `defaultValue` but for [controlled components](http://facebook.github.io/react/docs/forms.html#controlled-components).
             */ value : PropTypes . oneOfType ( [ PropTypes . number , PropTypes . arrayOf ( PropTypes . number ) ] ) , /**
             * Determines whether the slider moves horizontally (from left to right) or vertically (from top to bottom).
             */ orientation : PropTypes . oneOf ( [ 'horizontal' , 'vertical' ] ) , /**
             * The css class set on the slider node.
             */ className : PropTypes . string , /**
             * The css class set on each handle node.
             *
             * In addition each handle will receive a numbered css class of the form `${handleClassName}-${i}`,
             * e.g. `handle-0`, `handle-1`, ...
             */ handleClassName : PropTypes . string , /**
             * The css class set on the handle that is currently being moved.
             */ handleActiveClassName : PropTypes . string , /**
             * If `true` bars between the handles will be rendered.
             */ withBars : PropTypes . bool , /**
             * The css class set on the bars between the handles.
             * In addition bar fragment will receive a numbered css class of the form `${barClassName}-${i}`,
             * e.g. `bar-0`, `bar-1`, ...
             */ barClassName : PropTypes . string , /**
             * If `true` the active handle will push other handles
             * within the constraints of `min`, `max`, `step` and `minDistance`.
             */ pearling : PropTypes . bool , /**
             * If `true` the handles can't be moved.
             */ disabled : PropTypes . bool , /**
             * Disables handle move when clicking the slider bar
             */ snapDragDisabled : PropTypes . bool , /**
             * Inverts the slider.
             */ invert : PropTypes . bool , /**
             * Callback called before starting to move a handle.
             */ onBeforeChange : PropTypes . func , /**
             * Callback called on every value change.
             */ onChange : PropTypes . func , /**
             * Callback called only after moving a handle has ended.
             */ onAfterChange : PropTypes . func , /**
             *  Callback called when the the slider is clicked (handle or bars).
             *  Receives the value at the clicked position as argument.
             */ onSliderClick : PropTypes . func } , getDefaultProps : function ( ) { return { min : 0 , max : 100 , step : 1 , minDistance : 0 , defaultValue : 0 , orientation : 'horizontal' , className : 'slider' , handleClassName : 'handle' , handleActiveClassName : 'active' , barClassName : 'bar' , withBars : false , pearling : false , disabled : false , snapDragDisabled : false , invert : false } ; } , getInitialState : function ( ) { var value = this . _or ( ensureArray ( this . props . value ) , ensureArray ( this . props . defaultValue ) ) ; this . tempArray = value . slice ( ) ; this . pendingResizeTimeouts = [ ] ; var zIndices = [ ] ; for ( var i = 0 ; i < value . length ; i ++ ) { value [ i ] = this . _trimAlignValue ( value [ i ] , this . props ) ; zIndices . push ( i ) ; } return { index : - 1 , upperBound : 0 , sliderLength : 0 , value : value , zIndices : zIndices } ; } , UNSAFE_componentWillReceiveProps : function ( newProps ) { var value = this . _or ( ensureArray ( newProps . value ) , this . state . value ) ; this . tempArray = value . slice ( ) ; for ( var i = 0 ; i < value . length ; i ++ ) { this . state . value [ i ] = this . _trimAlignValue ( value [ i ] , newProps ) ; } if ( this . state . value . length > value . length ) this . state . value . length = value . length ; if ( this . state . upperBound === 0 ) { this . _resize ( ) ; } } , _or : function ( value , defaultValue ) { var count = React . Children . count ( this . props . children ) ; switch ( count ) { case 0 : return value . length > 0 ? value : defaultValue ; case value . length : return value ; case defaultValue . length : return defaultValue ; default : if ( value . length !== count || defaultValue . length !== count ) { window . console . warn ( this . constructor . displayName + ": Number of values does not match number of children." ) ; } return linspace ( this . props . min , this . props . max , count ) ; } } , componentDidMount : function ( ) { window . addEventListener ( 'resize' , this . _handleResize ) ; this . _resize ( ) ; } , componentWillUnmount : function ( ) { this . _clearPendingResizeTimeouts ( ) ; window . removeEventListener ( 'resize' , this . _handleResize ) ; } , getValue : function ( ) { return undoEnsureArray ( this . state . value ) ; } , _resize : function ( ) { var slider = this . slider ; var handle = this . handle0 ; var rect = slider . getBoundingClientRect ( ) ; var size = this . _sizeKey ( ) ; var sliderMax = rect [ this . _posMaxKey ( ) ] ; var sliderMin = rect [ this . _posMinKey ( ) ] ; this . setState ( { upperBound : slider [ size ] - handle [ size ] , sliderLength : Math . abs ( sliderMax - sliderMin ) , handleSize : handle [ size ] , sliderStart : this . props . invert ? sliderMax : sliderMin } ) ; } , _handleResize : function ( ) { var resizeTimeout = window . setTimeout ( function ( ) { this . pendingResizeTimeouts . shift ( ) ; this . _resize ( ) ; } . bind ( this ) , 0 ) ; this . pendingResizeTimeouts . push ( resizeTimeout ) ; } , _clearPendingResizeTimeouts : function ( ) { do { var nextTimeout = this . pendingResizeTimeouts . shift ( ) ; clearTimeout ( nextTimeout ) ; } while ( this . pendingResizeTimeouts . length ) ; } , _calcOffset : function ( value ) { var range = this . props . max - this . props . min ; if ( range === 0 ) { return 0 ; } var ratio = ( value - this . props . min ) / range ; return ratio * this . state . upperBound ; } , _calcValue : function ( offset ) { var ratio = offset / this . state . upperBound ; return ratio * ( this . props . max - this . props . min ) + this . props . min ; } , _buildHandleStyle : function ( offset , i ) { var style = { position : 'absolute' , willChange : this . state . index >= 0 ? this . _posMinKey ( ) : '' , zIndex : this . state . zIndices . indexOf ( i ) + 1 } ; style [ this . _posMinKey ( ) ] = offset + 'px' ; return style ; } , _buildBarStyle : function ( min , max ) { var obj = { position : 'absolute' , willChange : this . state . index >= 0 ? this . _posMinKey ( ) + ',' + this . _posMaxKey ( ) : '' } ; obj [ this . _posMinKey ( ) ] = min ; obj [ this . _posMaxKey ( ) ] = max ; return obj ; } , _getClosestIndex : function ( pixelOffset ) { var minDist = Number . MAX_VALUE ; var closestIndex = - 1 ; var value = this . state . value ; var l = value . length ; for ( var i = 0 ; i < l ; i ++ ) { var offset = this . _calcOffset ( value [ i ] ) ; var dist = Math . abs ( pixelOffset - offset ) ; if ( dist < minDist ) { minDist = dist ; closestIndex = i ; } } return closestIndex ; } , _calcOffsetFromPosition : function ( position ) { var pixelOffset = position - this . state . sliderStart ; if ( this . props . invert ) pixelOffset = this . state . sliderLength - pixelOffset ; pixelOffset -= ( this . state . handleSize / 2 ) ; return pixelOffset ; } , _forceValueFromPosition : function ( position , callback ) { var pixelOffset = this . _calcOffsetFromPosition ( position ) ; var closestIndex = this . _getClosestIndex ( pixelOffset ) ; var nextValue = this . _trimAlignValue ( this . _calcValue ( pixelOffset ) ) ; var value = this . state . value . slice ( ) ; value [ closestIndex ] = nextValue ; for ( var i = 0 ; i < value . length - 1 ; i += 1 ) { if ( value [ i + 1 ] - value [ i ] < this . props . minDistance ) return ; } this . setState ( { value : value } , callback . bind ( this , closestIndex ) ) ; } , _getMousePosition : function ( e ) { return [ e [ 'page' + this . _axisKey ( ) ] , e [ 'page' + this . _orthogonalAxisKey ( ) ] ] ; } , _getTouchPosition : function ( e ) { var touch = e . touches [ 0 ] ; return [ touch [ 'page' + this . _axisKey ( ) ] , touch [ 'page' + this . _orthogonalAxisKey ( ) ] ] ; } , _getKeyDownEventMap : function ( ) { return { 'keydown' : this . _onKeyDown , 'focusout' : this . _onBlur } ; } , _getMouseEventMap : function ( ) { return { 'mousemove' : this . _onMouseMove , 'mouseup' : this . _onMouseUp } ; } , _getTouchEventMap : function ( ) { return { 'touchmove' : this . _onTouchMove , 'touchend' : this . _onTouchEnd } ; } , _createOnKeyDown : function ( i ) { return function ( e ) { if ( this . props . disabled ) return ; this . _start ( i ) ; this . _addHandlers ( this . _getKeyDownEventMap ( ) ) ; pauseEvent ( e ) ; } . bind ( this ) ; } , _createOnMouseDown : function ( i ) { return function ( e ) { if ( this . props . disabled ) return ; var position = this . _getMousePosition ( e ) ; this . _start ( i , position [ 0 ] ) ; this . _addHandlers ( this . _getMouseEventMap ( ) ) ; pauseEvent ( e ) ; } . bind ( this ) ; } , _createOnTouchStart : function ( i ) { return function ( e ) { if ( this . props . disabled || e . touches . length > 1 ) return ; var position = this . _getTouchPosition ( e ) ; this . startPosition = position ; this . isScrolling = undefined ; this . _start ( i , position [ 0 ] ) ; this . _addHandlers ( this . _getTouchEventMap ( ) ) ; stopPropagation ( e ) ; } . bind ( this ) ; } , _addHandlers : function ( eventMap ) { for ( var key in eventMap ) { document . addEventListener ( key , eventMap [ key ] , false ) ; } } , _removeHandlers : function ( eventMap ) { for ( var key in eventMap ) { document . removeEventListener ( key , eventMap [ key ] , false ) ; } } , _start : function ( i , position ) { var activeEl = document . activeElement ; var handleRef = this [ 'handle' + i ] ; if ( activeEl && activeEl != document . body && activeEl != handleRef ) { activeEl . blur && activeEl . blur ( ) ; } this . hasMoved = false ; this . _fireChangeEvent ( 'onBeforeChange' ) ; var zIndices = this . state . zIndices ; zIndices . splice ( zIndices . indexOf ( i ) , 1 ) ; zIndices . push ( i ) ; this . setState ( function ( prevState ) { return { startValue : this . state . value [ i ] , startPosition : position !== undefined ? position : prevState . startPosition , index : i , zIndices : zIndices } ; } ) ; } , _onMouseUp : function ( ) { this . _onEnd ( this . _getMouseEventMap ( ) ) ; } , _onTouchEnd : function ( ) { this . _onEnd ( this . _getTouchEventMap ( ) ) ; } , _onBlur : function ( ) { this . _onEnd ( this . _getKeyDownEventMap ( ) ) ; } , _onEnd : function ( eventMap ) { this . _removeHandlers ( eventMap ) ; this . setState ( { index : - 1 } , this . _fireChangeEvent . bind ( this , 'onAfterChange' ) ) ; } , _onMouseMove : function ( e ) { var position = this . _getMousePosition ( e ) ; var diffPosition = this . _getDiffPosition ( position [ 0 ] ) ; var newValue = this . _getValueFromPosition ( diffPosition ) ; this . _move ( newValue ) ; } , _onTouchMove : function ( e ) { if ( e . touches . length > 1 ) return ; var position = this . _getTouchPosition ( e ) ; if ( typeof this . isScrolling === 'undefined' ) { var diffMainDir = position [ 0 ] - this . startPosition [ 0 ] ; var diffScrollDir = position [ 1 ] - this . startPosition [ 1 ] ; this . isScrolling = Math . abs ( diffScrollDir ) > Math . abs ( diffMainDir ) ; } if ( this . isScrolling ) { this . setState ( { index : - 1 } ) ; return ; } pauseEvent ( e ) ; var diffPosition = this . _getDiffPosition ( position [ 0 ] ) ; var newValue = this . _getValueFromPosition ( diffPosition ) ; this . _move ( newValue ) ; } , _onKeyDown : function ( e ) { if ( e . ctrlKey || e . shiftKey || e . altKey ) return ; switch ( e . key ) { case "ArrowLeft" : case "ArrowUp" : e . preventDefault ( ) ; return this . _moveDownOneStep ( ) ; case "ArrowRight" : case "ArrowDown" : e . preventDefault ( ) ; return this . _moveUpOneStep ( ) ; case "Home" : return this . _move ( this . props . min ) ; case "End" : return this . _move ( this . props . max ) ; default : return ; } } , _moveUpOneStep : function ( ) { var oldValue = this . state . value [ this . state . index ] ; var newValue = oldValue + this . props . step ; this . _move ( Math . min ( newValue , this . props . max ) ) ; } , _moveDownOneStep : function ( ) { var oldValue = this . state . value [ this . state . index ] ; var newValue = oldValue - this . props . step ; this . _move ( Math . max ( newValue , this . props . min ) ) ; } , _getValueFromPosition : function ( position ) { var diffValue = position / ( this . state . sliderLength - this . state . handleSize ) * ( this . props . max - this . props . min ) ; return this . _trimAlignValue ( this . state . startValue + diffValue ) ; } , _getDiffPosition : function ( position ) { var diffPosition = position - this . state . startPosition ; if ( this . props . invert ) diffPosition *= - 1 ; return diffPosition ; } , _move : function ( newValue ) { this . hasMoved = true ; var props = this . props ; var state = this . state ; var index = state . index ; var value = state . value ; var length = value . length ; var oldValue = value [ index ] ; var minDistance = props . minDistance ; if ( ! props . pearling ) { if ( index > 0 ) { var valueBefore = value [ index - 1 ] ; if ( newValue < valueBefore + minDistance ) { newValue = valueBefore + minDistance ; } } if ( index < length - 1 ) { var valueAfter = value [ index + 1 ] ; if ( newValue > valueAfter - minDistance ) { newValue = valueAfter - minDistance ; } } } value [ index ] = newValue ; if ( props . pearling && length > 1 ) { if ( newValue > oldValue ) { this . _pushSucceeding ( value , minDistance , index ) ; this . _trimSucceeding ( length , value , minDistance , props . max ) ; } else if ( newValue < oldValue ) { this . _pushPreceding ( value , minDistance , index ) ; this . _trimPreceding ( length , value , minDistance , props . min ) ; } } if ( newValue !== oldValue ) { this . setState ( { value : value } , this . _fireChangeEvent . bind ( this , 'onChange' ) ) ; } } , _pushSucceeding : function ( value , minDistance , index ) { var i , padding ; for ( i = index , padding = value [ i ] + minDistance ; value [ i + 1 ] != null && padding > value [ i + 1 ] ; i ++ , padding = value [ i ] + minDistance ) { value [ i + 1 ] = this . _alignValue ( padding ) ; } } , _trimSucceeding : function ( length , nextValue , minDistance , max ) { for ( var i = 0 ; i < length ; i ++ ) { var padding = max - i * minDistance ; if ( nextValue [ length - 1 - i ] > padding ) { nextValue [ length - 1 - i ] = padding ; } } } , _pushPreceding : function ( value , minDistance , index ) { var i , padding ; for ( i = index , padding = value [ i ] - minDistance ; value [ i - 1 ] != null && padding < value [ i - 1 ] ; i -- , padding = value [ i ] - minDistance ) { value [ i - 1 ] = this . _alignValue ( padding ) ; } } , _trimPreceding : function ( length , nextValue , minDistance , min ) { for ( var i = 0 ; i < length ; i ++ ) { var padding = min + i * minDistance ; if ( nextValue [ i ] < padding ) { nextValue [ i ] = padding ; } } } , _axisKey : function ( ) { var orientation = this . props . orientation ; if ( orientation === 'horizontal' ) return 'X' ; if ( orientation === 'vertical' ) return 'Y' ; } , _orthogonalAxisKey : function ( ) { var orientation = this . props . orientation ; if ( orientation === 'horizontal' ) return 'Y' ; if ( orientation === 'vertical' ) return 'X' ; } , _posMinKey : function ( ) { var orientation = this . props . orientation ; if ( orientation === 'horizontal' ) return this . props . invert ? 'right' : 'left' ; if ( orientation === 'vertical' ) return this . props . invert ? 'bottom' : 'top' ; } , _posMaxKey : function ( ) { var orientation = this . props . orientation ; if ( orientation === 'horizontal' ) return this . props . invert ? 'left' : 'right' ; if ( orientation === 'vertical' ) return this . props . invert ? 'top' : 'bottom' ; } , _sizeKey : function ( ) { var orientation = this . props . orientation ; if ( orientation === 'horizontal' ) return 'clientWidth' ; if ( orientation === 'vertical' ) return 'clientHeight' ; } , _trimAlignValue : function ( val , props ) { return this . _alignValue ( this . _trimValue ( val , props ) , props ) ; } , _trimValue : function ( val , props ) { props = props || this . props ; if ( val <= props . min ) val = props . min ; if ( val >= props . max ) val = props . max ; return val ; } , _alignValue : function ( val , props ) { props = props || this . props ; var valModStep = ( val - props . min ) % props . step ; var alignValue = val - valModStep ; if ( Math . abs ( valModStep ) * 2 >= props . step ) { alignValue += ( valModStep > 0 ) ? props . step : ( - props . step ) ; } return parseFloat ( alignValue . toFixed ( 5 ) ) ; } , _renderHandle : function ( style , child , i ) { var self = this ; var className = this . props . handleClassName + ' ' + ( this . props . handleClassName + '-' + i ) + ' ' + ( this . state . index === i ? this . props . handleActiveClassName : '' ) ; return ( React . createElement ( 'div' , { ref : function ( r ) { self [ 'handle' + i ] = r ; } , key : 'handle' + i , className : className , style : style , onMouseDown : this . _createOnMouseDown ( i ) , onTouchStart : this . _createOnTouchStart ( i ) , onFocus : this . _createOnKeyDown ( i ) , tabIndex : 0 , role : "slider" , "aria-valuenow" : this . state . value [ i ] , "aria-valuemin" : this . props . min , "aria-valuemax" : this . props . max , "aria-label" : isArray ( this . props . ariaLabel ) ? this . props . ariaLabel [ i ] : this . props . ariaLabel , "aria-valuetext" : this . props . ariaValuetext , } , child ) ) ; } , _renderHandles : function ( offset ) { var length = offset . length ; var styles = this . tempArray ; for ( var i = 0 ; i < length ; i ++ ) { styles [ i ] = this . _buildHandleStyle ( offset [ i ] , i ) ; } var res = [ ] ; var renderHandle = this . _renderHandle ; if ( React . Children . count ( this . props . children ) > 0 ) { React . Children . forEach ( this . props . children , function ( child , i ) { res [ i ] = renderHandle ( styles [ i ] , child , i ) ; } ) ; } else { for ( i = 0 ; i < length ; i ++ ) { res [ i ] = renderHandle ( styles [ i ] , null , i ) ; } } return res ; } , _renderBar : function ( i , offsetFrom , offsetTo ) { var self = this ; return ( React . createElement ( 'div' , { key : 'bar' + i , ref : function ( r ) { self [ 'bar' + i ] = r ; } , className : this . props . barClassName + ' ' + this . props . barClassName + '-' + i , style : this . _buildBarStyle ( offsetFrom , this . state . upperBound - offsetTo ) } ) ) ; } , _renderBars : function ( offset ) { var bars = [ ] ; var lastIndex = offset . length - 1 ; bars . push ( this . _renderBar ( 0 , 0 , offset [ 0 ] ) ) ; for ( var i = 0 ; i < lastIndex ; i ++ ) { bars . push ( this . _renderBar ( i + 1 , offset [ i ] , offset [ i + 1 ] ) ) ; } bars . push ( this . _renderBar ( lastIndex + 1 , offset [ lastIndex ] , this . state . upperBound ) ) ; return bars ; } , _onSliderMouseDown : function ( e ) { if ( this . props . disabled ) return ; this . hasMoved = false ; if ( ! this . props . snapDragDisabled ) { var position = this . _getMousePosition ( e ) ; this . _forceValueFromPosition ( position [ 0 ] , function ( i ) { this . _start ( i , position [ 0 ] ) ; this . _fireChangeEvent ( 'onChange' ) ; this . _addHandlers ( this . _getMouseEventMap ( ) ) ; } . bind ( this ) ) ; } pauseEvent ( e ) ; } , _onSliderClick : function ( e ) { if ( this . props . disabled ) return ; if ( this . props . onSliderClick && ! this . hasMoved ) { var position = this . _getMousePosition ( e ) ; var valueAtPos = this . _trimAlignValue ( this . _calcValue ( this . _calcOffsetFromPosition ( position [ 0 ] ) ) ) ; this . props . onSliderClick ( valueAtPos ) ; } } , _fireChangeEvent : function ( event ) { if ( this . props [ event ] ) { this . props [ event ] ( undoEnsureArray ( this . state . value ) ) ; } } , render : function ( ) { var self = this ; var state = this . state ; var props = this . props ; var offset = this . tempArray ; var value = state . value ; var l = value . length ; for ( var i = 0 ; i < l ; i ++ ) { offset [ i ] = this . _calcOffset ( value [ i ] , i ) ; } var bars = props . withBars ? this . _renderBars ( offset ) : null ; var handles = this . _renderHandles ( offset ) ; return ( React . createElement ( 'div' , { ref : function ( r ) { self . slider = r ; } , style : { position : 'relative' } , className : props . className + ( props . disabled ? ' disabled' : '' ) , onMouseDown : this . _onSliderMouseDown , onClick : this . _onSliderClick } , bars , handles ) ) ; } } ) ; return ReactSlider ; } ) ) ;