    /** * A gesture recognizer for swipe events */Ext.define('Ext.event.gesture.Swipe', {    extend: 'Ext.event.gesture.SingleTouch',     priority: 600,     handledEvents: ['swipestart', 'swipe', 'swipecancel'],     /**     * @member Ext.dom.Element     * @event swipe     * Fires when there is a swipe     * When listening to this, ensure you know about the {@link Ext.event.Event#direction} property in the `event` object.     * @param {Ext.event.Event} event The {@link Ext.event.Event} event encapsulating the DOM event.     * @param {HTMLElement} node The target of the event.     * @param {Object} options The options object passed to Ext.mixin.Observable.addListener.     */     /**     * @property {Number} direction      * The direction of the swipe. Available options are:     *     * - up     * - down     * - left     * - right     *     * **This is only available when the event type is `swipe`**     * @member Ext.event.Event     */     /**     * @property {Number} duration      * The duration of the swipe.     *     * **This is only available when the event type is `swipe`**     * @member Ext.event.Event     */     config: {        minDistance: 80,        maxOffset: 35,        maxDuration: 1000    },     onTouchStart: function(e) {        var me = this,            ret = me.callParent([e]),            touch;         if (ret !== false) {            touch = e.changedTouches[0];             me.startTime = e.time;             me.isHorizontal = true;            me.isVertical = true;             me.startX = touch.pageX;            me.startY = touch.pageY;        }         return ret;    },     onTouchMove: function(e) {        var me = this,            touch = e.changedTouches[0],            x = touch.pageX,            y = touch.pageY,            deltaX = x - me.startX,            deltaY = y - me.startY,            absDeltaX = Math.abs(x - me.startX),            absDeltaY = Math.abs(y - me.startY),            duration = e.time - me.startTime,            minDistance, direction, distance;         // If delta is 0 on both axes that's not swipe         if ((absDeltaX === 0 && absDeltaY === 0) || (duration > me.getMaxDuration())) {            return me.cancel(e);        }         if (me.isHorizontal && absDeltaY > me.getMaxOffset()) {            me.isHorizontal = false;        }         if (me.isVertical && absDeltaX > me.getMaxOffset()) {            me.isVertical = false;        }         if (!me.isVertical || !me.isHorizontal) {            minDistance = me.getMinDistance();             if (me.isHorizontal && absDeltaX < minDistance) {                direction = (deltaX < 0) ? 'left' : 'right';                distance = absDeltaX;            }            else if (me.isVertical && absDeltaY < minDistance) {                direction = (deltaY < 0) ? 'up' : 'down';                distance = absDeltaY;            }        }         if (!me.isHorizontal && !me.isVertical) {            return me.cancel(e);        }         if (direction && !me.isStarted) {            me.isStarted = true;             me.fire('swipestart', e, {                touch: touch,                direction: direction,                distance: distance,                duration: duration            });        }    },     onTouchEnd: function(e) {        var me = this,            touch, x, y, deltaX, deltaY, absDeltaX, absDeltaY, minDistance, duration,            direction, distance;         if (me.onTouchMove(e) !== false) {            touch = e.changedTouches[0];            x = touch.pageX;            y = touch.pageY;            deltaX = x - me.startX;            deltaY = y - me.startY;            absDeltaX = Math.abs(deltaX);            absDeltaY = Math.abs(deltaY);            minDistance = me.getMinDistance();            duration = e.time - me.startTime;             if (me.isVertical && absDeltaY < minDistance) {                me.isVertical = false;            }             if (me.isHorizontal && absDeltaX < minDistance) {                me.isHorizontal = false;            }             if (me.isHorizontal) {                direction = (deltaX < 0) ? 'left' : 'right';                distance = absDeltaX;            } else if (me.isVertical) {                direction = (deltaY < 0) ? 'up' : 'down';                distance = absDeltaY;            }             me.fire('swipe', e, {                touch: touch,                direction: direction,                distance: distance,                duration: duration            });        }         return this.callParent([e]);    },     onCancel: function(e) {        this.fire('swipecancel', e, null, true);    },     reset: function() {        var me = this;         me.startTime = me.isHorizontal = me.isVertical = me.startX = me.startY = null;         return me.callParent();    }}, function(Swipe) {    var gestures = Ext.manifest.gestures;    Swipe.instance = new Swipe(gestures && gestures.swipe);});