docs: function MouseTracker(options) {
  
  
  		var mouseDownX,
  			mouseDownY,
  			hasDragged,
  			selectionMarker,
  			zoomType = optionsChart.zoomType,
  			zoomX = /x/.test(zoomType),
  			zoomY = /y/.test(zoomType),
  			zoomHor = (zoomX && !inverted) || (zoomY && inverted),
  			zoomVert = (zoomY && !inverted) || (zoomX && inverted);
  
  		/**
  		 * Add crossbrowser support for chartX and chartY
  		 * @param {Object} e The event object in standard browsers
  		 */
  		function normalizeMouseEvent(e) {
  			var ePos,
  				pageZoomFix = isWebKit &&
  					doc.width / doc.body.scrollWidth -
  					1, // #224, #348
  				chartPosLeft,
  				chartPosTop,
  				chartX,
  				chartY;
  
  			// common IE normalizing
  			e = e || win.event;
  			if (!e.target) {
  				e.target = e.srcElement;
  			}
  
  			// iOS
  			ePos = e.touches ? e.touches.item(0) : e;
  
  			// in certain cases, get mouse position
  			if (e.type !== 'mousemove' || win.opera || pageZoomFix) { // only Opera needs position on mouse move, see below
  				chartPosition = getPosition(container);
  				chartPosLeft = chartPosition.left;
  				chartPosTop = chartPosition.top;
  			}
  
  			// chartX and chartY
  			if (isIE) { // IE including IE9 that has chartX but in a different meaning
  				chartX = e.x;
  				chartY = e.y;
  			} else {
  				if (ePos.layerX === UNDEFINED) { // Opera and iOS
  					chartX = ePos.pageX - chartPosLeft;
  					chartY = ePos.pageY - chartPosTop;
  				} else {
  					chartX = e.layerX;
  					chartY = e.layerY;
  				}
  			}
  
  			// correct for page zoom bug in WebKit
  			if (pageZoomFix) {
  				chartX += mathRound((pageZoomFix + 1) * chartPosLeft - chartPosLeft);
  				chartY += mathRound((pageZoomFix + 1) * chartPosTop - chartPosTop);
  			}
  
  			return extend(e, {
  				chartX: chartX,
  				chartY: chartY
  			});
  		}
  
  		/**
  		 * Get the click position in terms of axis values.
  		 *
  		 * @param {Object} e A mouse event
  		 */
  		function getMouseCoordinates(e) {
  			var coordinates = {
  				xAxis: [],
  				yAxis: []
  			};
  			each(axes, function (axis) {
  				var translate = axis.translate,
  					isXAxis = axis.isXAxis,
  					isHorizontal = inverted ? !isXAxis : isXAxis;
  
  				coordinates[isXAxis ? 'xAxis' : 'yAxis'].push({
  					axis: axis,
  					value: translate(
  						isHorizontal ?
  							e.chartX - plotLeft  :
  							plotHeight - e.chartY + plotTop,
  						true
  					)
  				});
  			});
  			return coordinates;
  		}
  
  		/**
  		 * With line type charts with a single tracker, get the point closest to the mouse
  		 */
  		function onmousemove(e) {
  			var point,
  				points,
  				hoverPoint = chart.hoverPoint,
  				hoverSeries = chart.hoverSeries,
  				i,
  				j,
  				distance = chartWidth,
  				index = inverted ? e.chartY : e.chartX - plotLeft; // wtf?
  
  			// shared tooltip
  			if (tooltip && options.shared) {
  				points = [];
  
  				// loop over all series and find the ones with points closest to the mouse
  				i = series.length;
  				for (j = 0; j < i; j++) {
  					if (series[j].visible && series[j].tooltipPoints.length) {
  						point = series[j].tooltipPoints[index];
  						point._dist = mathAbs(index - point.plotX);
  						distance = mathMin(distance, point._dist);
  						points.push(point);
  					}
  				}
  				// remove furthest points
  				i = points.length;
  				while (i--) {
  					if (points[i]._dist > distance) {
  						points.splice(i, 1);
  					}
  				}
  				// refresh the tooltip if necessary
  				if (points.length && (points[0].plotX !== hoverX)) {
  					tooltip.refresh(points);
  					hoverX = points[0].plotX;
  				}
  			}
  
  			// separate tooltip and general mouse events
  			if (hoverSeries && hoverSeries.tracker) { // only use for line-type series with common tracker
  
  				// get the point
  				point = hoverSeries.tooltipPoints[index];
  
  				// a new point is hovered, refresh the tooltip
  				if (point && point !== hoverPoint) {
  
  					// trigger the events
  					point.onMouseOver();
  
  				}
  			}
  		}
  
  
  
  		/**
  		 * Reset the tracking by hiding the tooltip, the hover series state and the hover point
  		 */
  		function resetTracker() {
  			var hoverSeries = chart.hoverSeries,
  				hoverPoint = chart.hoverPoint;
  
  			if (hoverPoint) {
  				hoverPoint.onMouseOut();
  			}
  
  			if (hoverSeries) {
  				hoverSeries.onMouseOut();
  			}
  
  			if (tooltip) {
  				tooltip.hide();
  			}
  
  			hoverX = null;
  		}
  
  		/**
  		 * Mouse up or outside the plot area
  		 */
  		function drop() {
  			if (selectionMarker) {
  				var selectionData = {
  						xAxis: [],
  						yAxis: []
  					},
  					selectionBox = selectionMarker.getBBox(),
  					selectionLeft = selectionBox.x - plotLeft,
  					selectionTop = selectionBox.y - plotTop;
  
  
  				// a selection has been made
  				if (hasDragged) {
  
  					// record each axis' min and max
  					each(axes, function (axis) {
  						var translate = axis.translate,
  							isXAxis = axis.isXAxis,
  							isHorizontal = inverted ? !isXAxis : isXAxis,
  							selectionMin = translate(
  								isHorizontal ?
  									selectionLeft :
  									plotHeight - selectionTop - selectionBox.height,
  								true,
  								0,
  								0,
  								1
  							),
  							selectionMax = translate(
  								isHorizontal ?
  									selectionLeft + selectionBox.width :
  									plotHeight - selectionTop,
  								true,
  								0,
  								0,
  								1
  							);
  
  							selectionData[isXAxis ? 'xAxis' : 'yAxis'].push({
  								axis: axis,
  								min: mathMin(selectionMin, selectionMax), // for reversed axes,
  								max: mathMax(selectionMin, selectionMax)
  							});
  
  					});
  					fireEvent(chart, 'selection', selectionData, zoom);
  
  				}
  				selectionMarker = selectionMarker.destroy();
  			}
  
  			chart.mouseIsDown = mouseIsDown = hasDragged = false;
  			removeEvent(doc, hasTouch ? 'touchend' : 'mouseup', drop);
  
  		}
  
  		/**
  		 * Special handler for mouse move that will hide the tooltip when the mouse leaves the plotarea.
  		 */
  		function hideTooltipOnMouseMove(e) {
  			var pageX = defined(e.pageX) ? e.pageX : e.page.x, // In mootools the event is wrapped and the page x/y position is named e.page.x
  				pageY = defined(e.pageX) ? e.pageY : e.page.y; // Ref: http://mootools.net/docs/core/Types/DOMEvent
  
  			if (chartPosition &&
  					!isInsidePlot(pageX - chartPosition.left - plotLeft,
  						pageY - chartPosition.top - plotTop)) {
  				resetTracker();
  			}
  		}
  
  		/**
  		 * Set the JS events on the container element
  		 */
  		function setDOMEvents() {
  			var lastWasOutsidePlot = true;
  			/*
  			 * Record the starting position of a dragoperation
  			 */
  			container.onmousedown = function (e) {
  				e = normalizeMouseEvent(e);
  
  				// issue #295, dragging not always working in Firefox
  				if (!hasTouch && e.preventDefault) {
  					e.preventDefault();
  				}
  
  				// record the start position
  				chart.mouseIsDown = mouseIsDown = true;
  				mouseDownX = e.chartX;
  				mouseDownY = e.chartY;
  
  				addEvent(doc, hasTouch ? 'touchend' : 'mouseup', drop);
  			};
  
  			// The mousemove, touchmove and touchstart event handler
  			var mouseMove = function (e) {
  
  				// let the system handle multitouch operations like two finger scroll
  				// and pinching
  				if (e && e.touches && e.touches.length > 1) {
  					return;
  				}
  
  				// normalize
  				e = normalizeMouseEvent(e);
  				if (!hasTouch) { // not for touch devices
  					e.returnValue = false;
  				}
  
  				var chartX = e.chartX,
  					chartY = e.chartY,
  					isOutsidePlot = !isInsidePlot(chartX - plotLeft, chartY - plotTop);
  
  				// cache chart position for issue #149 fix
  				if (!chartPosition) {
  					chartPosition = getPosition(container);
  				}
  
  				// on touch devices, only trigger click if a handler is defined
  				if (hasTouch && e.type === 'touchstart') {
  					if (attr(e.target, 'isTracker')) {
  						if (!chart.runTrackerClick) {
  							e.preventDefault();
  						}
  					} else if (!runChartClick && !isOutsidePlot) {
  						e.preventDefault();
  					}
  				}
  
  				// cancel on mouse outside
  				if (isOutsidePlot) {
  
  					/*if (!lastWasOutsidePlot) {
  						// reset the tracker
  						resetTracker();
  					}*/
  
  					// drop the selection if any and reset mouseIsDown and hasDragged
  					//drop();
  					if (chartX < plotLeft) {
  						chartX = plotLeft;
  					} else if (chartX > plotLeft + plotWidth) {
  						chartX = plotLeft + plotWidth;
  					}
  
  					if (chartY < plotTop) {
  						chartY = plotTop;
  					} else if (chartY > plotTop + plotHeight) {
  						chartY = plotTop + plotHeight;
  					}
  
  				}
  
  				if (mouseIsDown && e.type !== 'touchstart') { // make selection
  
  					// determine if the mouse has moved more than 10px
  					hasDragged = Math.sqrt(
  						Math.pow(mouseDownX - chartX, 2) +
  						Math.pow(mouseDownY - chartY, 2)
  					);
  					if (hasDragged > 10) {
  
  						// make a selection
  						if (hasCartesianSeries && (zoomX || zoomY) &&
  								isInsidePlot(mouseDownX - plotLeft, mouseDownY - plotTop)) {
  							if (!selectionMarker) {
  								selectionMarker = renderer.rect(
  									plotLeft,
  									plotTop,
  									zoomHor ? 1 : plotWidth,
  									zoomVert ? 1 : plotHeight,
  									0
  								)
  								.attr({
  									fill: optionsChart.selectionMarkerFill || 'rgba(69,114,167,0.25)',
  									zIndex: 7
  								})
  								.add();
  							}
  						}
  
  						// adjust the width of the selection marker
  						if (selectionMarker && zoomHor) {
  							var xSize = chartX - mouseDownX;
  							selectionMarker.attr({
  								width: mathAbs(xSize),
  								x: (xSize > 0 ? 0 : xSize) + mouseDownX
  							});
  						}
  						// adjust the height of the selection marker
  						if (selectionMarker && zoomVert) {
  							var ySize = chartY - mouseDownY;
  							selectionMarker.attr({
  								height: mathAbs(ySize),
  								y: (ySize > 0 ? 0 : ySize) + mouseDownY
  							});
  						}
  					}
  
  				} else if (!isOutsidePlot) {
  					// show the tooltip
  					onmousemove(e);
  				}
  
  				lastWasOutsidePlot = isOutsidePlot;
  
  				// when outside plot, allow touch-drag by returning true
  				return isOutsidePlot || !hasCartesianSeries;
  			};
  
  			/*
  			 * When the mouse enters the container, run mouseMove
  			 */
  			container.onmousemove = mouseMove;
  
  			/*
  			 * When the mouse leaves the container, hide the tracking (tooltip).
  			 */
  			addEvent(container, 'mouseleave', resetTracker);
  
  			// issue #149 workaround
  			// The mouseleave event above does not always fire. Whenever the mouse is moving
  			// outside the plotarea, hide the tooltip
  			addEvent(doc, 'mousemove', hideTooltipOnMouseMove);
  
  			container.ontouchstart = function (e) {
  				// For touch devices, use touchmove to zoom
  				if (zoomX || zoomY) {
  					container.onmousedown(e);
  				}
  				// Show tooltip and prevent the lower mouse pseudo event
  				mouseMove(e);
  			};
  
  			/*
  			 * Allow dragging the finger over the chart to read the values on touch
  			 * devices
  			 */
  			container.ontouchmove = mouseMove;
  
  			/*
  			 * Allow dragging the finger over the chart to read the values on touch
  			 * devices
  			 */
  			container.ontouchend = function () {
  				if (hasDragged) {
  					resetTracker();
  				}
  			};
  
  
  			// MooTools 1.2.3 doesn't fire this in IE when using addEvent
  			container.onclick = function (e) {
  				var hoverPoint = chart.hoverPoint;
  				e = normalizeMouseEvent(e);
  
  				e.cancelBubble = true; // IE specific
  
  
  				if (!hasDragged) {
  					if (hoverPoint && attr(e.target, 'isTracker')) {
  						var plotX = hoverPoint.plotX,
  							plotY = hoverPoint.plotY;
  
  						// add page position info
  						extend(hoverPoint, {
  							pageX: chartPosition.left + plotLeft +
  								(inverted ? plotWidth - plotY : plotX),
  							pageY: chartPosition.top + plotTop +
  								(inverted ? plotHeight - plotX : plotY)
  						});
  
  						// the series click event
  						fireEvent(hoverPoint.series, 'click', extend(e, {
  							point: hoverPoint
  						}));
  
  						// the point click event
  						hoverPoint.firePointEvent('click', e);
  
  					} else {
  						extend(e, getMouseCoordinates(e));
  
  						// fire a click event in the chart
  						if (isInsidePlot(e.chartX - plotLeft, e.chartY - plotTop)) {
  							fireEvent(chart, 'click', e);
  						}
  					}
  
  
  				}
  				// reset mouseIsDown and hasDragged
  				hasDragged = false;
  			};
  
  		}
  
  		/**
  		 * Destroys the MouseTracker object and disconnects DOM events.
  		 */
  		function destroy() {
  			// Destroy the tracker group element
  			if (chart.trackerGroup) {
  				chart.trackerGroup = trackerGroup = chart.trackerGroup.destroy();
  			}
  
  			removeEvent(doc, 'mousemove', hideTooltipOnMouseMove);
  			container.onclick = container.onmousedown = container.onmousemove = container.ontouchstart = container.ontouchend = container.ontouchmove = null;
  		}
  
  		/**
  		 * Create the image map that listens for mouseovers
  		 */
  		placeTrackerGroup = function () {
  
  			// first create - plot positions is not final at this stage
  			if (!trackerGroup) {
  				chart.trackerGroup = trackerGroup = renderer.g('tracker')
  					.attr({ zIndex: 9 })
  					.add();
  
  			// then position - this happens on load and after resizing and changing
  			// axis or box positions
  			} else {
  				trackerGroup.translate(plotLeft, plotTop);
  				if (inverted) {
  					trackerGroup.attr({
  						width: chart.plotWidth,
  						height: chart.plotHeight
  					}).invert();
  				}
  			}
  		};
  
  
  		// Run MouseTracker
  		placeTrackerGroup();
  		if (options.enabled) {
  			chart.tooltip = tooltip = Tooltip(options);
  		}
  
  		setDOMEvents();
  
  		// set the fixed interval ticking for the smooth tooltip
  		tooltipInterval = setInterval(function () {
  			if (tooltipTick) {
  				tooltipTick();
  			}
  		}, 32);
  
  		// expose properties
  		extend(this, {
  			zoomX: zoomX,
  			zoomY: zoomY,
  			resetTracker: resetTracker,
  			destroy: destroy
  		});
  	}