text: // jQuery.event.swipe
  // 0.5
  // Stephen Band
  
  // Dependencies
  // jQuery.event.move 1.2
  
  // One of swipeleft, swiperight, swipeup or swipedown is triggered on
  // moveend, when the move has covered a threshold ratio of the dimension
  // of the target node, or has gone really fast. Threshold and velocity
  // sensitivity changed with:
  //
  // jQuery.event.special.swipe.settings.threshold
  // jQuery.event.special.swipe.settings.sensitivity
  
  (function (thisModule) {
  	if (typeof define === 'function' && define.amd) {
          // AMD. Register as an anonymous module.
          define(['jquery'], thisModule);
      } else if ((typeof module !== "undefined" && module !== null) && module.exports) {
          module.exports = thisModule;
  	} else {
  		// Browser globals
          thisModule(jQuery);
  	}
  })(function(jQuery, undefined){
  	var add = jQuery.event.add,
  	   
  	    remove = jQuery.event.remove,
  
  	    // Just sugar, so we can have arguments in the same order as
  	    // add and remove.
  	    trigger = function(node, type, data) {
  	    	jQuery.event.trigger(type, data, node);
  	    },
  
  	    settings = {
  	    	// Ratio of distance over target finger must travel to be
  	    	// considered a swipe.
  	    	threshold: 0.4,
  	    	// Faster fingers can travel shorter distances to be considered
  	    	// swipes. 'sensitivity' controls how much. Bigger is shorter.
  	    	sensitivity: 6
  	    };
  
  	function moveend(e) {
  		var w, h, event;
  
  		w = e.currentTarget.offsetWidth;
  		h = e.currentTarget.offsetHeight;
  
  		// Copy over some useful properties from the move event
  		event = {
  			distX: e.distX,
  			distY: e.distY,
  			velocityX: e.velocityX,
  			velocityY: e.velocityY,
  			finger: e.finger
  		};
  
  		// Find out which of the four directions was swiped
  		if (e.distX > e.distY) {
  			if (e.distX > -e.distY) {
  				if (e.distX/w > settings.threshold || e.velocityX * e.distX/w * settings.sensitivity > 1) {
  					event.type = 'swiperight';
  					trigger(e.currentTarget, event);
  				}
  			}
  			else {
  				if (-e.distY/h > settings.threshold || e.velocityY * e.distY/w * settings.sensitivity > 1) {
  					event.type = 'swipeup';
  					trigger(e.currentTarget, event);
  				}
  			}
  		}
  		else {
  			if (e.distX > -e.distY) {
  				if (e.distY/h > settings.threshold || e.velocityY * e.distY/w * settings.sensitivity > 1) {
  					event.type = 'swipedown';
  					trigger(e.currentTarget, event);
  				}
  			}
  			else {
  				if (-e.distX/w > settings.threshold || e.velocityX * e.distX/w * settings.sensitivity > 1) {
  					event.type = 'swipeleft';
  					trigger(e.currentTarget, event);
  				}
  			}
  		}
  	}
  
  	function getData(node) {
  		var data = jQuery.data(node, 'event_swipe');
  		
  		if (!data) {
  			data = { count: 0 };
  			jQuery.data(node, 'event_swipe', data);
  		}
  		
  		return data;
  	}
  
  	jQuery.event.special.swipe =
  	jQuery.event.special.swipeleft =
  	jQuery.event.special.swiperight =
  	jQuery.event.special.swipeup =
  	jQuery.event.special.swipedown = {
  		setup: function( data, namespaces, eventHandle ) {
  			var data = getData(this);
  
  			// If another swipe event is already setup, don't setup again.
  			if (data.count++ > 0) { return; }
  
  			add(this, 'moveend', moveend);
  
  			return true;
  		},
  
  		teardown: function() {
  			var data = getData(this);
  
  			// If another swipe event is still setup, don't teardown.
  			if (--data.count > 0) { return; }
  
  			remove(this, 'moveend', moveend);
  
  			return true;
  		},
  
  		settings: settings
  	};
  });