text: 
  	// Handler for attaching events trough a proxy.
  	function attach ( events, element, callback, data ) {
  
  		// This function can be used to 'filter' events to the slider.
  
  		// Add the noUiSlider namespace to all events.
  		events = events.replace( /\s/g, namespace + ' ' ) + namespace;
  
  		// Bind a closure on the target.
  		return element.on( events, function( e ){
  
  			// jQuery and Zepto (1) handle unset attributes differently,
  			// but always falsy; #208
  			if ( !!$Target.attr('disabled') ) {
  				return false;
  			}
  
  			// Stop if an active 'tap' transition is taking place.
  			if ( $Target.hasClass( Classes[14] ) ) {
  				return false;
  			}
  
  			e = fixEvent(e);
  			e.calcPoint = e.points[ options.ort ];
  
  			// Call the event handler with the event [ and additional data ].
  			callback ( e, data );
  		});
  	}
  
  	// Handle movement on document for handle and range drag.
  	function move ( event, data ) {
  
  		var handles = data.handles || $Handles, positions, state = false,
  			proposal = ((event.calcPoint - data.start) * 100) / baseSize(),
  			h = handles[0][0] !== $Handles[0][0] ? 1 : 0;
  
  		// Calculate relative positions for the handles.
  		positions = getPositions( proposal, data.positions, handles.length > 1);
  
  		state = setHandle ( handles[0], positions[h], handles.length === 1 );
  
  		if ( handles.length > 1 ) {
  			state = setHandle ( handles[1], positions[h?0:1], false ) || state;
  		}
  
  		// Fire the 'slide' event if any handle moved.
  		if ( state ) {
  			fireEvents(['slide']);
  		}
  	}
  
  	// Unbind move events on document, call callbacks.
  	function end ( event ) {
  
  		// The handle is no longer active, so remove the class.
  		$('.' + Classes[15]).removeClass(Classes[15]);
  
  		// Remove cursor styles and text-selection events bound to the body.
  		if ( event.cursor ) {
  			$('body').css('cursor', '').off( namespace );
  		}
  
  		// Unbind the move and end events, which are added on 'start'.
  		doc.off( namespace );
  
  		// Remove dragging class.
  		$Target.removeClass(Classes[12]);
  
  		// Fire the change and set events.
  		fireEvents(['set', 'change']);
  	}
  
  	// Bind move events on document.
  	function start ( event, data ) {
  
  		// Mark the handle as 'active' so it can be styled.
  		if( data.handles.length === 1 ) {
  			data.handles[0].children().addClass(Classes[15]);
  		}
  
  		// A drag should never propagate up to the 'tap' event.
  		event.stopPropagation();
  
  		// Attach the move event.
  		attach ( actions.move, doc, move, {
  			start: event.calcPoint,
  			handles: data.handles,
  			positions: [
  				$Locations[0],
  				$Locations[$Handles.length - 1]
  			]
  		});
  
  		// Unbind all movement when the drag ends.
  		attach ( actions.end, doc, end, null );
  
  		// Text selection isn't an issue on touch devices,
  		// so adding cursor styles can be skipped.
  		if ( event.cursor ) {
  
  			// Prevent the 'I' cursor and extend the range-drag cursor.
  			$('body').css('cursor', $(event.target).css('cursor'));
  
  			// Mark the target with a dragging state.
  			if ( $Handles.length > 1 ) {
  				$Target.addClass(Classes[12]);
  			}
  
  			// Prevent text selection when dragging the handles.
  			$('body').on('selectstart' + namespace, false);
  		}
  	}
  
  	// Move closest handle to tapped location.
  	function tap ( event ) {
  
  		var location = event.calcPoint, total = 0, to;
  
  		// The tap event shouldn't propagate up and cause 'edge' to run.
  		event.stopPropagation();
  
  		// Add up the handle offsets.
  		$.each( $Handles, function(){
  			total += this.offset()[ options.style ];
  		});
  
  		// Find the handle closest to the tapped position.
  		total = ( location < total/2 || $Handles.length === 1 ) ? 0 : 1;
  
  		location -= $Base.offset()[ options.style ];
  
  		// Calculate the new position.
  		to = ( location * 100 ) / baseSize();
  
  		if ( !options.events.snap ) {
  			// Flag the slider as it is now in a transitional state.
  			// Transition takes 300 ms, so re-enable the slider afterwards.
  			addClassFor( $Target, Classes[14], 300 );
  		}
  
  		// Find the closest handle and calculate the tapped point.
  		// The set handle to the new position.
  		setHandle( $Handles[total], to );
  
  		fireEvents(['slide', 'set', 'change']);
  
  		if ( options.events.snap ) {
  			start(event, { handles: [$Handles[total]] });
  		}
  	}
  
  	// Attach events to several slider parts.
  	function events ( behaviour ) {
  
  		var i, drag;
  
  		// Attach the standard drag event to the handles.
  		if ( !behaviour.fixed ) {
  
  			for ( i = 0; i < $Handles.length; i += 1 ) {
  
  				// These events are only bound to the visual handle
  				// element, not the 'real' origin element.
  				attach ( actions.start, $Handles[i].children(), start, {
  					handles: [ $Handles[i] ]
  				});
  			}
  		}
  
  		// Attach the tap event to the slider base.
  		if ( behaviour.tap ) {
  
  			attach ( actions.start, $Base, tap, {
  				handles: $Handles
  			});
  		}
  
  		// Make the range dragable.
  		if ( behaviour.drag ){
  
  			drag = $Base.find( '.' + Classes[7] ).addClass( Classes[10] );
  
  			// When the range is fixed, the entire range can
  			// be dragged by the handles. The handle in the first
  			// origin will propagate the start event upward,
  			// but it needs to be bound manually on the other.
  			if ( behaviour.fixed ) {
  				drag = drag.add($Base.children().not( drag ).children());
  			}
  
  			attach ( actions.start, drag, start, {
  				handles: $Handles
  			});
  		}
  	}
  