Parses trace events generated by gesture library for touchpad.
@constructor
496527
function GestureParser(importer) {
    Parser.call(this, importer);
    importer.registerEventHandler('tracing_mark_write:log',
        GestureParser.prototype.logEvent.bind(this));
    importer.registerEventHandler('tracing_mark_write:SyncInterpret',
        GestureParser.prototype.syncEvent.bind(this));
    importer.registerEventHandler('tracing_mark_write:HandleTimer',
        GestureParser.prototype.timerEvent.bind(this));
  }
1246038
function logHammerEvent(ev) {
		if(!ev.gesture) {
			return;
		}

		// store last event, that should might match the gremlin
		if(ev.gesture.eventType == 'end') {
			testLogger.lastEvent = ev;
		}

		// highlight gesture
		var event_el = getLogElement('gesture', ev.type);
		event_el.className = 'active';

		for(var i = 0, len = hammerProps.length; i < len; i++) {
			var prop = hammerProps[i];
			var value = ev.gesture[prop];
			switch(prop) {
				case 'center':
					value = value.pageX + 'x' + value.pageY;
					break;
				case 'gesture':
					value = ev.type;
					break;
				case 'target':
					value = ev.gesture.target.tagName;
					break;
				case 'touches':
					value = ev.gesture.touches.length;
					break;
			}
			getLogElement('prop', prop).innerHTML = value;
		}
	}
5423
function TouchMouseInput() {
  Input.apply(this, arguments);

  var handler = this.handler.bind(this);
  this.touch = new TouchInput(this.manager, handler);
  this.mouse = new MouseInput(this.manager, handler);
}
1362485
function fakeTouchSupport() {
        var objs = [window, document.documentElement];
        var props = ['ontouchstart', 'ontouchmove', 'ontouchcancel', 'ontouchend'];

        for(var o=0; o<objs.length; o++) {
            for(var p=0; p<props.length; p++) {
                if(objs[o] && objs[o][props[p]] == undefined) {
                    objs[o][props[p]] = null;
                }
            }
        }
    }
684167
function initEvents() {
        var bind = _this.h.addEventListener;
        var eventTarget = params.eventTarget === 'wrapper' ? _this.wrapper : _this.container;
        //Touch Events
        if (! (_this.browser.ie10 || _this.browser.ie11)) {
            if (_this.support.touch) {
                bind(eventTarget, 'touchstart', onTouchStart);
                bind(eventTarget, 'touchmove', onTouchMove);
                bind(eventTarget, 'touchend', onTouchEnd);
            }
            if (params.simulateTouch) {
                bind(eventTarget, 'mousedown', onTouchStart);
                bind(document, 'mousemove', onTouchMove);
                bind(document, 'mouseup', onTouchEnd);
            }
        }
        else {
            bind(eventTarget, _this.touchEvents.touchStart, onTouchStart);
            bind(document, _this.touchEvents.touchMove, onTouchMove);
            bind(document, _this.touchEvents.touchEnd, onTouchEnd);
        }

        //Resize Event
        if (params.autoResize) {
            bind(window, 'resize', _this.resizeFix);
        }
        //Slide Events
        addSlideEvents();
        //Mousewheel
        _this._wheelEvent = false;
        if (params.mousewheelControl) {
            if (document.onmousewheel !== undefined) {
                _this._wheelEvent = 'mousewheel';
            }
            if (!_this._wheelEvent) {
                try {
                    new WheelEvent('wheel');
                    _this._wheelEvent = 'wheel';
                } catch (e) {}
            }
            if (!_this._wheelEvent) {
                _this._wheelEvent = 'DOMMouseScroll';
            }
            if (_this._wheelEvent) {
                bind(_this.container, _this._wheelEvent, handleMousewheel);
            }
        }

        //Keyboard
        function _loadImage(src) {
            var image = new Image();
            image.onload = function () {
                if (typeof _this === 'undefined' || _this === null) return;
                if (_this.imagesLoaded !== undefined) _this.imagesLoaded++;
                if (_this.imagesLoaded === _this.imagesToLoad.length) {
                    _this.reInit();
                    if (params.onImagesReady) _this.fireCallback(params.onImagesReady, _this);
                }
            };
            image.src = src;
        }

        if (params.keyboardControl) {
            bind(document, 'keydown', handleKeyboardKeys);
        }
        if (params.updateOnImagesReady) {
            _this.imagesToLoad = $$('img', _this.container);

            for (var i = 0; i < _this.imagesToLoad.length; i++) {
                _loadImage(_this.imagesToLoad[i].getAttribute('src'));
            }
        }
    }
1299391
function(sType, oEvent) {

			if (!bHandleEvent) {
				return;
			}

			// we need mapping of the different event types to get the correct target
			var oMappedEvent = oEvent.type == "touchend" ? oEvent.changedTouches[0] : oEvent.touches[0];

			// create the synthetic event
			var newEvent = oDocument.createEvent('MouseEvent'); // trying to create an actual TouchEvent will create an error
			newEvent.initMouseEvent(sType, true, true, window, oEvent.detail,
				oMappedEvent.screenX, oMappedEvent.screenY, oMappedEvent.clientX, oMappedEvent.clientY,
				oEvent.ctrlKey, oEvent.shiftKey, oEvent.altKey, oEvent.metaKey,
				oEvent.button, oEvent.relatedTarget);

			newEvent.isSynthetic = true;

			// Timeout needed. Do not interrupt the native event handling.
			window.setTimeout(function() {
				oTarget.dispatchEvent(newEvent);
			}, 0);
		}
1327096
function(evt) {
        evt.preventDefault();
        evt.stopPropagation();

        //Detect if finger moves too much for it to be considered a tap
        var {x1, y1, time} = tapStart;
        var x2 = evt.touches[0].pageX;
        var y2 = evt.touches[0].pageY;
        var dx = x2 - x1;
        var dy = y2 - y1;
        tapDiff = Math.sqrt(dx * dx + dy * dy);

        //Detect if it's moved too little in too short a time to be considered a pan
        if((new Date() - tapStart.timeStart < tapDuration) && tapDiff <= 2){
          return;
        }

        if (debug) { timedLog("panmove"); }
        if (!transform.x1 && !transform.y1) {
          return;
        }
        if (evt.touches && evt.touches.length > 1) {
          return handlers.handleTouchRepositioning(evt);
        }
        if (debug) { timedLog("panmove - continued"); }

        var x = evt.clientX || evt.touches[0].pageX,
          y = evt.clientY || evt.touches[0].pageY;

        transform.modified = true;
        positionable.handleTranslation(x - transform.x1 + mark.x, y - transform.y1 + mark.y);
      }
420701
function getGestureEventName (gesture, active) {
  var eventName;

  if (!gesture) { return; }

  eventName = EVENTS[gesture];
  if (eventName === 'grip') {
    return eventName + (active ? 'close' : 'open');
  }
  if (eventName === 'point' || eventName === 'thumb') {
    return eventName + (active ? 'up' : 'down');
  }
  if (eventName === 'pointing' || eventName === 'pistol') {
    return eventName + (active ? 'start' : 'end');
  }
  return;
}
258445
function onEvent(gesture, handler){
      var gestures = gesture.split(' ');
      for(var t=0; t<gestures.length; t++) {
        this.element.addEventListener(gestures[t], handler, false);
      }
      return this;
    }
1337908
function getTouchList() {
    var touchlist = [];
    // we can use forEach since pointerEvents only is in IE10
    Utils.each(this.pointers, function(pointer) {
      touchlist.push(pointer);
    });
    return touchlist;
  }
88339
function startDetect(inst, eventData) {
    // already busy with a GestureDetector.gesture detection on an element
    if (this.current) {
      return;
    }

    this.stopped = false;

    // holds current session
    this.current = {
      inst: inst, // reference to GestureDetectorInstance we're working for
      startEvent: Utils.extend({}, eventData), // start eventData for distances, timing etc
      lastEvent: false, // last eventData
      lastCalcEvent: false, // last eventData for calculations.
      futureCalcEvent: false, // last eventData for calculations.
      lastCalcData: {}, // last lastCalcData
      name: '' // current gesture we're in/detected, can be 'tap', 'hold' etc
    };

    this.detect(eventData);
  }
884694
function triggerTouch(type) {
        var event = document.createEvent('Event');
        var touchlist = this._createTouchList(this.touches);

        event.initEvent('touch' + type, true, true);
        event.touches = touchlist;
        event.changedTouches = touchlist;

        return this.element.dispatchEvent(event);
    }
127359
function determineEventTypes() {
    // determine the eventtype we want to set
    var types;

    // pointerEvents magic
    if(Hammer.HAS_POINTEREVENTS) {
      types = Hammer.PointerEvent.getEvents();
    }
    // on Android, iOS, blackberry, windows mobile we dont want any mouseevents
    else if(Hammer.NO_MOUSEEVENTS) {
      types = [
        'touchstart',
        'touchmove',
        'touchend touchcancel'];
    }
    // for non pointer events browsers and mixed browsers,
    // like chrome on windows8 touch laptop
    else {
      types = [
        'touchstart mousedown',
        'touchmove mousemove',
        'touchend touchcancel mouseup'];
    }

    Hammer.EVENT_TYPES[Hammer.EVENT_START] = types[0];
    Hammer.EVENT_TYPES[Hammer.EVENT_MOVE] = types[1];
    Hammer.EVENT_TYPES[Hammer.EVENT_END] = types[2];
  }
704771
function(inEvent) {
      var lts = mouse.lastTouches;
      var t = inEvent.changedTouches[0];

      // only the primary finger will synth mouse events
      if (this.isPrimaryTouch(t)) {

        // remember x/y of last touch
        var lt = { x: t.clientX, y: t.clientY };
        lts.push(lt);
        var fn = (function(lts, lt) {
          var i = lts.indexOf(lt);
          if (i > -1) {
            lts.splice(i, 1);
          }
        }).bind(null, lts, lt);
        setTimeout(fn, DEDUP_TIMEOUT);
      }
    }
1177246
function (event) {

        event = normalizeEvent(this.dom, event);

        // Mark touch, which is useful in distinguish touch and
        // mouse event in upper applicatoin.
        event.zrByTouch = true;

        this.handler.processGesture(this, event, 'end');

        domHandlers.mouseup.call(this, event);

        // Do not trigger `mouseout` here, in spite of `mousemove`(`mouseover`) is
        // triggered in `touchstart`. This seems to be illogical, but by this mechanism,
        // we can conveniently implement "hover style" in both PC and touch device just
        // by listening to `mouseover` to add "hover style" and listening to `mouseout`
        // to remove "hover style" on an element, without any additional code for
        // compatibility. (`mouseout` will not be triggered in `touchend`, so "hover
        // style" will remain for user view)

        // click event should always be triggered no matter whether
        // there is gestrue event. System click can not be prevented.
        if (+new Date() - this._lastTouchMoment < TOUCH_CLICK_DELAY) {
            domHandlers.click.call(this, event);
        }

        setTouchTimer(this);
    }
196975
function(title, ts, opt_args) {
      var thread = this.importer.getOrCreatePseudoThread('gesture').thread;
      thread.sliceGroup.beginSlice(
          'touchpad_gesture', title, ts, opt_args);
    }
1332205
function setup(opts) {
  if (GestureDetector.READY) {
    return;
  }

  // find what eventtypes we add listeners to
  Event.determineEventTypes();

  // Register all gestures inside GestureDetector.gestures
  Utils.each(GestureDetector.gestures, function(gesture) {
    Detection.register(gesture);
  });

  // Add touch events on the document
  Event.onTouch(GestureDetector.DOCUMENT, EVENT_MOVE, Detection.detect, opts);
  Event.onTouch(GestureDetector.DOCUMENT, EVENT_END, Detection.detect, opts);

  // GestureDetector is ready...!
  GestureDetector.READY = true;
}