From dac3d86dcd16618a0393693bc1aca27897bffba6 Mon Sep 17 00:00:00 2001
From: Starbeamrainbowlabs <sbrl@starbeamrainbowlabs.com>
Date: Tue, 7 Feb 2017 21:53:57 +0000
Subject: [PATCH] Remove client build process output

---
 Nibriboard/ClientFiles/NibriClient.js | 2310 -------------------------
 1 file changed, 2310 deletions(-)
 delete mode 100644 Nibriboard/ClientFiles/NibriClient.js

diff --git a/Nibriboard/ClientFiles/NibriClient.js b/Nibriboard/ClientFiles/NibriClient.js
deleted file mode 100644
index 497e9e3..0000000
--- a/Nibriboard/ClientFiles/NibriClient.js
+++ /dev/null
@@ -1,2310 +0,0 @@
-(function e(t,n,r){function s(o,u){if(!n[o]){if(!t[o]){var a=typeof require=="function"&&require;if(!u&&a)return a(o,!0);if(i)return i(o,!0);var f=new Error("Cannot find module '"+o+"'");throw f.code="MODULE_NOT_FOUND",f}var l=n[o]={exports:{}};t[o][0].call(l.exports,function(e){var n=t[o][1][e];return s(n?n:e)},l,l.exports,e,t,n,r)}return n[o].exports}var i=typeof require=="function"&&require;for(var o=0;o<r.length;o++)s(r[o]);return s})({1:[function(require,module,exports){
-'use strict';
-
-/**
- * Constants for the different readyStates that a WebSocket can be in.
- * @type {Object}
- */
-const WebSocketStates = {
-	/**
-	 * Indicates that the WebSocket is connecting to the remote server.
-	 * @type {Number}
-	 */
-	connecting: 0,
-	/**
-	 * Indicates that the WebSocket is connected to the remote server and ready to send / receive data.
-	 * @type {Number}
-	 */
-	ready: 1,
-	/**
-	 * Indicates that the WebSocket is in the process of closing the connection to the remote server.
-	 * @type {Number}
-	 */
-	closing: 2,
-	/**
-	 * Indicates that hte WebSocket is not connected to the remote server (either because the connection was closed, or dropped by the remote server).
-	 * @type {Number}
-	 */
-	closed: 3
-};
-
-const ReverseWebSocketStates = {
-	// The WebSocket is in the process of connecting.
-	0: "connecting",
-	// The WebSocket is connected and ready to exchange data with the remote server.
-	1: "ready",
-	// The WebSocket is in the process of closing.
-	2: "closing",
-	// The WebSocket is closed.
-	3: "closed"
-};
-
-const EventEmitter$1 = require("event-emitter-es6");
-
-class RippleLink extends EventEmitter$1
-{
-	constructor(inSocketUrl, inBoardWindow)
-	{
-		super();
-		
-		this.socketUrl = inSocketUrl;
-		this.boardWindow = inBoardWindow;
-		this.settings = this.boardWindow.settings;
-		
-		// Create the websocket and commect to the server
-		this.websocket = new WebSocket(this.socketUrl, [ this.settings.WebsocketProtocol ]);
-		this.websocket.addEventListener("open", this.handleConnection.bind(this));
-		this.websocket.addEventListener("message", this.handleMessage.bind(this));
-		this.websocket.addEventListener("close", this.handleDisconnection.bind(this));
-		
-		// Close the socket correctly
-		window.addEventListener("beforeunload", (function(event) {
-			this.websocket.close();
-		}).bind(this));
-	}
-	
-	handleConnection(event) {
-		console.info("[ripple link] Established connection successfully.");
-		// Tell everyone about it
-		this.emit("connect", event);
-	}
-	
-	handleDisconnection(event) {
-		console.error("[ripple link] Lost connection.");
-		this.emit("disconnect", event);
-	}
-	
-	handleMessage(event) {
-		// Decode the message form the server
-		var message = JSON.parse(event.data);
-		console.debug(message);
-		
-		// Pass it on to the board manager by triggering the appropriate event
-		this.emit(message.event, message);
-	}
-	
-	/**
-	 * Sends a message object to the server.
-	 */
-	send(message) {
-		if(this.websocket.readyState !== WebSocketStates.ready)
-		{
-			console.error(`Attempt to send data on the RippleLink when it is not ready (state ${ReverseWebSocketStates[this.websocket.readyState]})`);
-			return false;
-		}
-		
-		this.websocket.send(JSON.stringify(message));
-		return true;
-	}
-}
-
-class CursorSyncer
-{
-	constructor(inRippleLink, syncFrequency)
-	{
-		// The ripple link we should send the cursor updates down
-		this.rippleLink = inRippleLink;
-		// The target frequency in fps at we should send sursor updates.
-		this.cursorUpdateFrequency = syncFrequency;
-		
-		// Register ourselves to start sending cursor updates once the ripple
-		// link connects
-		this.rippleLink.on("connect", this.setup.bind(this));
-	}
-	
-	setup()
-	{
-		// The last time we sent a cursor update to the server.
-		this.lastCursorUpdate = 0;
-		
-		document.addEventListener("mousemove", (function(event) {
-			this.cursorPosition = {
-				X: event.clientX,
-				Y: event.clientY
-			};
-			
-			setTimeout((function() {
-			    // Throttle the cursor updates we send to the server - a high
-			    // update frequency here will just consume bandwidth and is only
-			    // noticable if you have a good connection
-				if(+new Date() - this.lastCursorUpdate < 1 / this.cursorUpdateFrequency)
-					return false;
-					
-				// Update the server on the mouse's position
-				this.sendCursorUpdate();
-				
-				this.lastFrameStart = +new Date();
-			}).bind(this), 1 / this.cursorUpdateFrequency);
-			
-		}).bind(this));
-		
-		this.sendCursorUpdate();
-	}
-	
-	sendCursorUpdate()
-	{
-		// Update the server on the mouse's position
-		this.rippleLink.send({
-			"event": "CursorPosition",
-			"AbsCursorPosition": this.cursorPosition
-		});
-	}
-}
-
-function get(u){return new Promise(function(r,t,a){a=new XMLHttpRequest();a.onload=function(b,c){b=a.status;c=a.response;if(b>199&&b<300){r(c);}else{t(c);}};a.open("GET",u,true);a.send(null);})}
-
-// npm modules
-window.EventEmitter = require("event-emitter-es6");
-window.FaviconNotification = require("favicon-notification");
-window.panzoom = require("pan-zoom");
-
-// Our files
-class BoardWindow extends EventEmitter
-{
-	constructor(canvas)
-	{
-		super(); // Run the parent constructor
-		
-		// The maximum target fps.
-		this.maxFps = 60;
-		// The target fps at which we should send sursor updates.
-		this.cursorUpdateFrequency = 5;
-		// Setup the fps indicator in the top right corner
-		this.renderTimeIndicator = document.createElement("span");
-		this.renderTimeIndicator.innerHTML = "0ms";
-		document.querySelector(".fps").appendChild(this.renderTimeIndicator);
-		
-		// Setup the canvas
-		this.canvas = canvas;
-		this.context = canvas.getContext("2d");
-		
-		// --~~~--
-		
-		// Setup the favicon thingy
-		
-		FaviconNotification.init({
-			color: '#ff6333'
-		});
-		FaviconNotification.add();
-		
-		// Setup the input controls
-		window.panzoom(canvas, this.handleCanvasMovement.bind(this));
-		
-		// Fetch the RippleLink connection information and other settings from
-		// the server
-		get("/Settings.json").then(JSON.parse).then((function(settings) {
-			console.info("[setup]", "Obtained settings from server:", settings);
-			this.settings = settings;
-			this.setup();
-		}).bind(this), function(errorMessage) {
-			console.error(`Error: Failed to fetch settings from server! Response: ${errorMessage}`);
-		});
-		
-		// Make the canvas track the window size
-		this.trackWindowSize();
-	}
-	
-	/**
-	 * Setup ready for user input.
-	 * This mainly consists of establishing the RippleLink connection to the server.
-	 */
-	setup() {
-		this.rippleLink = new RippleLink(this.settings.WebsocketUri, this);
-		this.rippleLink.on("connect", (function(event) {
-			// Send the handshake request
-			this.rippleLink.send({
-				event: "HandshakeRequest",
-				InitialViewport: { // TODO: Add support for persisting this between sessions
-					X: 0,
-					Y: 0,
-					Width: window.innerWidth,
-					Height: window.innerHeight
-				},
-				InitialAbsCursorPosition: this.cursorPosition
-			});
-		}).bind(this));
-		
-		// Track the mouse position
-		this.cursorSyncer = new CursorSyncer(this.rippleLink, this.cursorUpdateFrequency);
-		
-		// RippleLink message bindings
-		
-	}
-	
-	/**
-	 * Renders the next frame.
-	 */
-	nextFrame()
-	{
-		// The time at which the current frame started rendering.
-		let frameStart = +new Date();
-		
-		if(frameStart - this.lastFrameStart >= (1 / this.maxFps) * 1000)
-		{
-			this.update();
-			this.render(this.canvas, this.context);
-		}
-		
-		// Update the time the last frame started rendering
-		this.lastFrameStart = frameStart;
-		// Update the time we took rendering the last frame
-		this.lastFrameTime = +new Date() - frameStart;
-		
-		this.renderTimeIndicator.innerHTML = `${this.lastFrameTime}ms`;
-		
-		// Limit the maximum fps
-		requestAnimationFrame(this.nextFrame.bind(this));
-	}
-	
-	/**
-	 * Updates everything ready for the next frame to be rendered.
-	 */
-	update()
-	{
-		
-	}
-	
-	/**
-	 * Renders the next frame.
-	 */
-	render(canvas, context)
-	{
-		context.clearRect(0, 0, canvas.width, canvas.height);
-		
-		context.fillStyle = "red";
-		context.fillRect(10, 10, 100, 100);
-	}
-	
-	/**
-	 * Updates the canvas size to match the current viewport size.
-	 */
-	matchWindowSize() {
-		this.canvas.width = window.innerWidth;
-		this.canvas.height = window.innerHeight;
-		
-		this.render(this.canvas, this.context);
-	}
-	
-	/**
-	 * Makes the canvas size track the window size.
-	 */
-	trackWindowSize() {
-		this.matchWindowSize();
-		window.addEventListener("resize", this.matchWindowSize.bind(this));
-	}
-	
-	/**
-	 * Handles events generated by pan-zoom, the package that handles the
-	 * dragging and zooming of the whiteboard.
-	 */
-	handleCanvasMovement(event) {
-		this.viewportState = event; // Store the viewport information for later
-	}
-}
-
-window.FpsIndicator = require("fps-indicator");
-
-window.addEventListener("load", function (event) {
-	let fpsIndicator = FpsIndicator({
-		updatePeriod: 1000,
-		maxFps: 60
-	});
-	fpsIndicator.element.style.color = "rgb(114, 194, 179)";
-	
-	let canvas = document.getElementById("canvas-main"),
-		boardWindow = new BoardWindow(canvas);
-	boardWindow.nextFrame();
-	window.boardWindow = boardWindow;
-});
-
-},{"event-emitter-es6":3,"favicon-notification":4,"fps-indicator":5,"pan-zoom":10}],2:[function(require,module,exports){
-module.exports = defaultProperty
-
-function defaultProperty (get, set) {
-  return {
-    configurable: true,
-    enumerable: true,
-    get: get,
-    set: set
-  }
-}
-
-},{}],3:[function(require,module,exports){
-'use strict';
-
-var _createClass = function () { function defineProperties(target, props) { for (var i = 0; i < props.length; i++) { var descriptor = props[i]; descriptor.enumerable = descriptor.enumerable || false; descriptor.configurable = true; if ("value" in descriptor) descriptor.writable = true; Object.defineProperty(target, descriptor.key, descriptor); } } return function (Constructor, protoProps, staticProps) { if (protoProps) defineProperties(Constructor.prototype, protoProps); if (staticProps) defineProperties(Constructor, staticProps); return Constructor; }; }();
-
-function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError("Cannot call a class as a function"); } }
-
-var DEFAULT_VALUES = {
-    emitDelay: 10,
-    strictMode: false
-};
-
-/**
- * @typedef {object} EventEmitterListenerFunc
- * @property {boolean} once
- * @property {function} fn
- */
-
-/**
- * @class EventEmitter
- *
- * @private
- * @property {Object.<string, EventEmitterListenerFunc[]>} _listeners
- * @property {string[]} events
- */
-
-var EventEmitter = function () {
-
-    /**
-     * @constructor
-     * @param {{}}      [opts]
-     * @param {number}  [opts.emitDelay = 10] - Number in ms. Specifies whether emit will be sync or async. By default - 10ms. If 0 - fires sync
-     * @param {boolean} [opts.strictMode = false] - is true, Emitter throws error on emit error with no listeners
-     */
-
-    function EventEmitter() {
-        var opts = arguments.length <= 0 || arguments[0] === undefined ? DEFAULT_VALUES : arguments[0];
-
-        _classCallCheck(this, EventEmitter);
-
-        var emitDelay = void 0,
-            strictMode = void 0;
-
-        if (opts.hasOwnProperty('emitDelay')) {
-            emitDelay = opts.emitDelay;
-        } else {
-            emitDelay = DEFAULT_VALUES.emitDelay;
-        }
-        this._emitDelay = emitDelay;
-
-        if (opts.hasOwnProperty('strictMode')) {
-            strictMode = opts.strictMode;
-        } else {
-            strictMode = DEFAULT_VALUES.strictMode;
-        }
-        this._strictMode = strictMode;
-
-        this._listeners = {};
-        this.events = [];
-    }
-
-    /**
-     * @protected
-     * @param {string} type
-     * @param {function} listener
-     * @param {boolean} [once = false]
-     */
-
-
-    _createClass(EventEmitter, [{
-        key: '_addListenner',
-        value: function _addListenner(type, listener, once) {
-            if (typeof listener !== 'function') {
-                throw TypeError('listener must be a function');
-            }
-
-            if (this.events.indexOf(type) === -1) {
-                this._listeners[type] = [{
-                    once: once,
-                    fn: listener
-                }];
-                this.events.push(type);
-            } else {
-                this._listeners[type].push({
-                    once: once,
-                    fn: listener
-                });
-            }
-        }
-
-        /**
-         * Subscribes on event type specified function
-         * @param {string} type
-         * @param {function} listener
-         */
-
-    }, {
-        key: 'on',
-        value: function on(type, listener) {
-            this._addListenner(type, listener, false);
-        }
-
-        /**
-         * Subscribes on event type specified function to fire only once
-         * @param {string} type
-         * @param {function} listener
-         */
-
-    }, {
-        key: 'once',
-        value: function once(type, listener) {
-            this._addListenner(type, listener, true);
-        }
-
-        /**
-         * Removes event with specified type. If specified listenerFunc - deletes only one listener of specified type
-         * @param {string} eventType
-         * @param {function} [listenerFunc]
-         */
-
-    }, {
-        key: 'off',
-        value: function off(eventType, listenerFunc) {
-            var _this = this;
-
-            var typeIndex = this.events.indexOf(eventType);
-            var hasType = eventType && typeIndex !== -1;
-
-            if (hasType) {
-                if (!listenerFunc) {
-                    delete this._listeners[eventType];
-                    this.events.splice(typeIndex, 1);
-                } else {
-                    (function () {
-                        var removedEvents = [];
-                        var typeListeners = _this._listeners[eventType];
-
-                        typeListeners.forEach(
-                        /**
-                         * @param {EventEmitterListenerFunc} fn
-                         * @param {number} idx
-                         */
-                        function (fn, idx) {
-                            if (fn.fn === listenerFunc) {
-                                removedEvents.unshift(idx);
-                            }
-                        });
-
-                        removedEvents.forEach(function (idx) {
-                            typeListeners.splice(idx, 1);
-                        });
-
-                        if (!typeListeners.length) {
-                            _this.events.splice(typeIndex, 1);
-                            delete _this._listeners[eventType];
-                        }
-                    })();
-                }
-            }
-        }
-
-        /**
-         * Applies arguments to specified event type
-         * @param {string} eventType
-         * @param {*[]} eventArguments
-         * @protected
-         */
-
-    }, {
-        key: '_applyEvents',
-        value: function _applyEvents(eventType, eventArguments) {
-            var typeListeners = this._listeners[eventType];
-
-            if (!typeListeners || !typeListeners.length) {
-                if (this._strictMode) {
-                    throw 'No listeners specified for event: ' + eventType;
-                } else {
-                    return;
-                }
-            }
-
-            var removableListeners = [];
-            typeListeners.forEach(function (eeListener, idx) {
-                eeListener.fn.apply(null, eventArguments);
-                if (eeListener.once) {
-                    removableListeners.unshift(idx);
-                }
-            });
-
-            removableListeners.forEach(function (idx) {
-                typeListeners.splice(idx, 1);
-            });
-        }
-
-        /**
-         * Emits event with specified type and params.
-         * @param {string} type
-         * @param eventArgs
-         */
-
-    }, {
-        key: 'emit',
-        value: function emit(type) {
-            var _this2 = this;
-
-            for (var _len = arguments.length, eventArgs = Array(_len > 1 ? _len - 1 : 0), _key = 1; _key < _len; _key++) {
-                eventArgs[_key - 1] = arguments[_key];
-            }
-
-            if (this._emitDelay) {
-                setTimeout(function () {
-                    _this2._applyEvents.call(_this2, type, eventArgs);
-                }, this._emitDelay);
-            } else {
-                this._applyEvents(type, eventArgs);
-            }
-        }
-
-        /**
-         * Emits event with specified type and params synchronously.
-         * @param {string} type
-         * @param eventArgs
-         */
-
-    }, {
-        key: 'emitSync',
-        value: function emitSync(type) {
-            for (var _len2 = arguments.length, eventArgs = Array(_len2 > 1 ? _len2 - 1 : 0), _key2 = 1; _key2 < _len2; _key2++) {
-                eventArgs[_key2 - 1] = arguments[_key2];
-            }
-
-            this._applyEvents(type, eventArgs);
-        }
-
-        /**
-         * Destroys EventEmitter
-         */
-
-    }, {
-        key: 'destroy',
-        value: function destroy() {
-            this._listeners = {};
-            this.events = [];
-        }
-    }]);
-
-    return EventEmitter;
-}();
-
-module.exports = EventEmitter;
-
-},{}],4:[function(require,module,exports){
-(function (root, factory) {
-    if (typeof define === 'function' && define.amd) {
-        // AMD. Register as an anonymous module.
-        define([], factory);
-    } else if (typeof exports === 'object') {
-        // Node. Does not work with strict CommonJS, but
-        // only CommonJS-like environments that support module.exports,
-        // like Node.
-        module.exports = factory();
-    } else {
-        // Browser globals (root is window)
-        root.FaviconNotification = factory();
-  }
-}(this, function() {
-
-    // Just return a value to define the module export.
-    // This example returns an object, but the module
-    // can return a function as the exported value.
-
-    // Only run in browser
-    if (typeof document === 'undefined') {
-      console.log('This script only run in browsers.');
-      return;
-    }
-
-    // Private properties
-    var _options = {};
-
-    var _defaults = {
-      url: '/favicon.ico',
-      color: '#eb361e',
-      lineColor: '#ffffff'
-    };
-
-    var _generatedFavicon;
-    var _iconElement;
-
-    // Provate methods
-    var _addFavicon = function(src) {
-      var head = document.getElementsByTagName('head')[0];
-      _iconElement = document.createElement('link');
-      _iconElement.type = 'image/x-icon';
-      _iconElement.rel = 'icon';
-      _iconElement.href = src;
-
-      // remove existing favicons
-      var links = document.getElementsByTagName('link');
-      for(var i=0, len=links.length; i < len; i++) {
-    		var exists = (typeof(links[i]) !== 'undefined');
-    		if (exists && (links[i].getAttribute('rel') || '').match(/\bicon\b/)) {
-    			head.removeChild(links[i]);
-    		}
-    	}
-
-      head.appendChild(_iconElement);
-    };
-
-    var _generateIcon = function(cb) {
-      var img = document.createElement('img');
-      img.src = _options.url;
-
-      img.onload = function() {
-        var lineWidth = 2;
-        var canvas = document.createElement('canvas');
-        canvas.width = img.width;
-        canvas.height = img.height;
-
-        var context = canvas.getContext('2d');
-        context.clearRect(0, 0, img.width, img.height);
-        context.drawImage(img, 0, 0);
-
-        var centerX = img.width - (img.width / 4.5) - lineWidth;
-        var centerY = img.height - (img.height / 4.5) - lineWidth;
-        var radius = img.width / 4.5;
-
-        context.fillStyle = _options.color;
-        context.strokeStyle = _options.lineColor;
-        context.lineWidth = lineWidth;
-
-        context.beginPath();
-        context.arc(centerX, centerY, radius, 0, Math.PI * 2, false);
-        context.closePath();
-        context.fill();
-        context.stroke();
-
-        cb(null, context.canvas.toDataURL());
-      };
-    };
-
-    var _setOptions = function(options) {
-      if (!options) {
-        _options = _defaults;
-        return;
-      }
-
-      _options = {};
-
-      for(var key in _defaults){
-           _options[key] = options.hasOwnProperty(key) ? options[key] : _defaults[key];
-      }
-    };
-
-    var FaviconNotification = {
-      init: function(options) {
-
-        _setOptions(options);
-
-        _generateIcon(function(err, url){
-          _generatedFavicon = url;
-        });
-
-        _addFavicon(_options.url);
-
-      },
-
-      add: function() {
-        if (!_generatedFavicon && !_iconElement) {
-          _setOptions();
-          _generateIcon(function(err, url) {
-            _generatedFavicon = url;
-            _addFavicon(url);
-          });
-        } else {
-          _iconElement.href = _generatedFavicon;
-        }
-
-      },
-
-      remove: function() {
-        _iconElement.href = _options.url;
-      }
-    };
-
-
-    return FaviconNotification;
-
-
-}));
-
-},{}],5:[function(require,module,exports){
-/**
- * @module fps-indicator
- */
-
-const raf = require('raf');
-const now = require('right-now');
-
-module.exports = fps;
-
-
-
-function fps (opts) {
-	if (!(this instanceof fps)) return new fps(opts);
-
-	opts = opts || {};
-
-	if (opts.container) {
-		if (typeof opts.container === 'string') {
-			this.container = document.querySelector(opts.container);
-		}
-		else {
-			this.container = opts.container;
-		}
-	}
-	else {
-		this.container = document.body || document.documentElement;
-	}
-
-	//init fps
-	this.element = document.createElement('div');
-	this.element.classList.add('fps');
-	this.element.innerHTML = `
-		<div class="fps-bg"></div>
-		<canvas class="fps-canvas"></canvas>
-		<span class="fps-text">fps <span class="fps-value">60.0</span></span>
-	`;
-	this.container.appendChild(this.element);
-
-	this.canvas = this.element.querySelector('.fps-canvas');
-	this.textEl = this.element.querySelector('.fps-text');
-	this.valueEl = this.element.querySelector('.fps-value');
-	this.bgEl = this.element.querySelector('.fps-bg');
-
-	this.element.style.cssText = `
-		line-height: 1;
-		position: absolute;
-		z-index: 1;
-		top: 0;
-		right: 0;
-	`;
-
-	this.canvas.style.cssText = `
-		position: relative;
-		width: 2em;
-		height: 1em;
-		display: block;
-		float: left;
-		margin-right: .333em;
-	`;
-
-	this.bgEl.style.cssText = `
-		position: absolute;
-		height: 1em;
-		width: 2em;
-		background: currentcolor;
-		opacity: .1;
-	`;
-
-	this.canvas.width = parseInt(getComputedStyle(this.canvas).width) || 1;
-	this.canvas.height = parseInt(getComputedStyle(this.canvas).height) || 1;
-
-	this.context = this.canvas.getContext('2d');
-
-	let ctx = this.context;
-	let w = this.canvas.width;
-	let h = this.canvas.height;
-	let count = 0;
-	let lastTime = 0;
-	let values = opts.values || Array(this.canvas.width);
-	let updatePeriod = opts.updatePeriod || 1000;
-	let maxFps = opts.maxFps || 100;
-
-	//enable update routine
-	let that = this;
-	raf(function measure () {
-		count++;
-		let t = now();
-
-		if (t - lastTime > updatePeriod) {
-			let color = that.color;
-			lastTime = t;
-			values.push(count / (maxFps * updatePeriod * 0.001));
-			values = values.slice(-w);
-			count = 0;
-
-			ctx.clearRect(0, 0, w, h);
-			ctx.fillStyle = getComputedStyle(that.canvas).color;
-			for (let i = w; i--;) {
-				let value = values[i];
-				if (value == null) break;
-				ctx.fillRect(i, h - h * value, 1, h * value);
-			}
-
-			that.valueEl.innerHTML = (values[values.length - 1]*maxFps).toFixed(1);
-		}
-
-		raf(measure);
-	});
-}
-},{"raf":13,"right-now":14}],6:[function(require,module,exports){
-module.exports = distance
-
-/**
- * Calculates the euclidian distance between two vec2's
- *
- * @param {vec2} a the first operand
- * @param {vec2} b the second operand
- * @returns {Number} distance between a and b
- */
-function distance(a, b) {
-    var x = b[0] - a[0],
-        y = b[1] - a[1]
-    return Math.sqrt(x*x + y*y)
-}
-},{}],7:[function(require,module,exports){
-(function (global, factory) {
-	if (typeof define === 'function' && define.amd) {
-		define(['exports', 'module'], factory);
-	} else if (typeof exports !== 'undefined' && typeof module !== 'undefined') {
-		factory(exports, module);
-	} else {
-		var mod = {
-			exports: {}
-		};
-		factory(mod.exports, mod);
-		global.Impetus = mod.exports;
-	}
-})(this, function (exports, module) {
-	'use strict';
-
-	function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }
-
-	var stopThresholdDefault = 0.3;
-	var bounceDeceleration = 0.04;
-	var bounceAcceleration = 0.11;
-
-	var Impetus = function Impetus(_ref) {
-		var _ref$source = _ref.source;
-		var sourceEl = _ref$source === undefined ? document : _ref$source;
-		var updateCallback = _ref.update;
-		var _ref$multiplier = _ref.multiplier;
-		var multiplier = _ref$multiplier === undefined ? 1 : _ref$multiplier;
-		var _ref$friction = _ref.friction;
-		var friction = _ref$friction === undefined ? 0.92 : _ref$friction;
-		var initialValues = _ref.initialValues;
-		var boundX = _ref.boundX;
-		var boundY = _ref.boundY;
-		var _ref$bounce = _ref.bounce;
-		var bounce = _ref$bounce === undefined ? true : _ref$bounce;
-
-		_classCallCheck(this, Impetus);
-
-		var boundXmin, boundXmax, boundYmin, boundYmax, pointerLastX, pointerLastY, pointerCurrentX, pointerCurrentY, pointerId, decVelX, decVelY;
-		var targetX = 0;
-		var targetY = 0;
-		var stopThreshold = stopThresholdDefault * multiplier;
-		var ticking = false;
-		var pointerActive = false;
-		var paused = false;
-		var decelerating = false;
-		var trackingPoints = [];
-
-		/**
-   * Initialize instance
-   */
-		(function init() {
-			sourceEl = typeof sourceEl === 'string' ? document.querySelector(sourceEl) : sourceEl;
-			if (!sourceEl) {
-				throw new Error('IMPETUS: source not found.');
-			}
-
-			if (!updateCallback) {
-				throw new Error('IMPETUS: update function not defined.');
-			}
-
-			if (initialValues) {
-				if (initialValues[0]) {
-					targetX = initialValues[0];
-				}
-				if (initialValues[1]) {
-					targetY = initialValues[1];
-				}
-				callUpdateCallback();
-			}
-
-			// Initialize bound values
-			if (boundX) {
-				boundXmin = boundX[0];
-				boundXmax = boundX[1];
-			}
-			if (boundY) {
-				boundYmin = boundY[0];
-				boundYmax = boundY[1];
-			}
-
-			sourceEl.addEventListener('touchstart', onDown);
-			sourceEl.addEventListener('mousedown', onDown);
-		})();
-
-		/**
-   * Disable movement processing
-   * @public
-   */
-		this.pause = function () {
-			pointerActive = false;
-			paused = true;
-		};
-
-		/**
-   * Enable movement processing
-   * @public
-   */
-		this.resume = function () {
-			paused = false;
-		};
-
-		/**
-   * Update the current x and y values
-   * @public
-   * @param {Number} x
-   * @param {Number} y
-   */
-		this.setValues = function (x, y) {
-			if (typeof x === 'number') {
-				targetX = x;
-			}
-			if (typeof y === 'number') {
-				targetY = y;
-			}
-		};
-
-		/**
-   * Update the multiplier value
-   * @public
-   * @param {Number} val
-   */
-		this.setMultiplier = function (val) {
-			multiplier = val;
-			stopThreshold = stopThresholdDefault * multiplier;
-		};
-
-		/**
-   * Executes the update function
-   */
-		function callUpdateCallback() {
-			updateCallback.call(sourceEl, targetX, targetY);
-		}
-
-		/**
-   * Creates a custom normalized event object from touch and mouse events
-   * @param  {Event} ev
-   * @returns {Object} with x, y, and id properties
-   */
-		function normalizeEvent(ev) {
-			if (ev.type === 'touchmove' || ev.type === 'touchstart' || ev.type === 'touchend') {
-				var touch = ev.targetTouches[0] || ev.changedTouches[0];
-				return {
-					x: touch.clientX,
-					y: touch.clientY,
-					id: touch.identifier
-				};
-			} else {
-				// mouse events
-				return {
-					x: ev.clientX,
-					y: ev.clientY,
-					id: null
-				};
-			}
-		}
-
-		/**
-   * Initializes movement tracking
-   * @param  {Object} ev Normalized event
-   */
-		function onDown(ev) {
-			var event = normalizeEvent(ev);
-			if (!pointerActive && !paused) {
-				pointerActive = true;
-				decelerating = false;
-				pointerId = event.id;
-
-				pointerLastX = pointerCurrentX = event.x;
-				pointerLastY = pointerCurrentY = event.y;
-				trackingPoints = [];
-				addTrackingPoint(pointerLastX, pointerLastY);
-
-				document.addEventListener('touchmove', onMove);
-				document.addEventListener('touchend', onUp);
-				document.addEventListener('touchcancel', stopTracking);
-				document.addEventListener('mousemove', onMove);
-				document.addEventListener('mouseup', onUp);
-			}
-		}
-
-		/**
-   * Handles move events
-   * @param  {Object} ev Normalized event
-   */
-		function onMove(ev) {
-			ev.preventDefault();
-			var event = normalizeEvent(ev);
-
-			if (pointerActive && event.id === pointerId) {
-				pointerCurrentX = event.x;
-				pointerCurrentY = event.y;
-				addTrackingPoint(pointerLastX, pointerLastY);
-				requestTick();
-			}
-		}
-
-		/**
-   * Handles up/end events
-   * @param {Object} ev Normalized event
-   */
-		function onUp(ev) {
-			var event = normalizeEvent(ev);
-
-			if (pointerActive && event.id === pointerId) {
-				stopTracking();
-			}
-		}
-
-		/**
-   * Stops movement tracking, starts animation
-   */
-		function stopTracking() {
-			pointerActive = false;
-			addTrackingPoint(pointerLastX, pointerLastY);
-			startDecelAnim();
-
-			document.removeEventListener('touchmove', onMove);
-			document.removeEventListener('touchend', onUp);
-			document.removeEventListener('touchcancel', stopTracking);
-			document.removeEventListener('mouseup', onUp);
-			document.removeEventListener('mousemove', onMove);
-		}
-
-		/**
-   * Records movement for the last 100ms
-   * @param {number} x
-   * @param {number} y [description]
-   */
-		function addTrackingPoint(x, y) {
-			var time = Date.now();
-			while (trackingPoints.length > 0) {
-				if (time - trackingPoints[0].time <= 100) {
-					break;
-				}
-				trackingPoints.shift();
-			}
-
-			trackingPoints.push({ x: x, y: y, time: time });
-		}
-
-		/**
-   * Calculate new values, call update function
-   */
-		function updateAndRender() {
-			var pointerChangeX = pointerCurrentX - pointerLastX;
-			var pointerChangeY = pointerCurrentY - pointerLastY;
-
-			targetX += pointerChangeX * multiplier;
-			targetY += pointerChangeY * multiplier;
-
-			if (bounce) {
-				var diff = checkBounds();
-				if (diff.x !== 0) {
-					targetX -= pointerChangeX * dragOutOfBoundsMultiplier(diff.x) * multiplier;
-				}
-				if (diff.y !== 0) {
-					targetY -= pointerChangeY * dragOutOfBoundsMultiplier(diff.y) * multiplier;
-				}
-			} else {
-				checkBounds(true);
-			}
-
-			callUpdateCallback();
-
-			pointerLastX = pointerCurrentX;
-			pointerLastY = pointerCurrentY;
-			ticking = false;
-		}
-
-		/**
-   * Returns a value from around 0.5 to 1, based on distance
-   * @param {Number} val
-   */
-		function dragOutOfBoundsMultiplier(val) {
-			return 0.000005 * Math.pow(val, 2) + 0.0001 * val + 0.55;
-		}
-
-		/**
-   * prevents animating faster than current framerate
-   */
-		function requestTick() {
-			if (!ticking) {
-				requestAnimFrame(updateAndRender);
-			}
-			ticking = true;
-		}
-
-		/**
-   * Determine position relative to bounds
-   * @param {Boolean} restrict Whether to restrict target to bounds
-   */
-		function checkBounds(restrict) {
-			var xDiff = 0;
-			var yDiff = 0;
-
-			if (boundXmin !== undefined && targetX < boundXmin) {
-				xDiff = boundXmin - targetX;
-			} else if (boundXmax !== undefined && targetX > boundXmax) {
-				xDiff = boundXmax - targetX;
-			}
-
-			if (boundYmin !== undefined && targetY < boundYmin) {
-				yDiff = boundYmin - targetY;
-			} else if (boundYmax !== undefined && targetY > boundYmax) {
-				yDiff = boundYmax - targetY;
-			}
-
-			if (restrict) {
-				if (xDiff !== 0) {
-					targetX = xDiff > 0 ? boundXmin : boundXmax;
-				}
-				if (yDiff !== 0) {
-					targetY = yDiff > 0 ? boundYmin : boundYmax;
-				}
-			}
-
-			return {
-				x: xDiff,
-				y: yDiff,
-				inBounds: xDiff === 0 && yDiff === 0
-			};
-		}
-
-		/**
-   * Initialize animation of values coming to a stop
-   */
-		function startDecelAnim() {
-			var firstPoint = trackingPoints[0];
-			var lastPoint = trackingPoints[trackingPoints.length - 1];
-
-			var xOffset = lastPoint.x - firstPoint.x;
-			var yOffset = lastPoint.y - firstPoint.y;
-			var timeOffset = lastPoint.time - firstPoint.time;
-
-			var D = timeOffset / 15 / multiplier;
-
-			decVelX = xOffset / D || 0; // prevent NaN
-			decVelY = yOffset / D || 0;
-
-			var diff = checkBounds();
-
-			if (Math.abs(decVelX) > 1 || Math.abs(decVelY) > 1 || !diff.inBounds) {
-				decelerating = true;
-				requestAnimFrame(stepDecelAnim);
-			}
-		}
-
-		/**
-   * Animates values slowing down
-   */
-		function stepDecelAnim() {
-			if (!decelerating) {
-				return;
-			}
-
-			decVelX *= friction;
-			decVelY *= friction;
-
-			targetX += decVelX;
-			targetY += decVelY;
-
-			var diff = checkBounds();
-
-			if (Math.abs(decVelX) > stopThreshold || Math.abs(decVelY) > stopThreshold || !diff.inBounds) {
-
-				if (bounce) {
-					var reboundAdjust = 2.5;
-
-					if (diff.x !== 0) {
-						if (diff.x * decVelX <= 0) {
-							decVelX += diff.x * bounceDeceleration;
-						} else {
-							var adjust = diff.x > 0 ? reboundAdjust : -reboundAdjust;
-							decVelX = (diff.x + adjust) * bounceAcceleration;
-						}
-					}
-					if (diff.y !== 0) {
-						if (diff.y * decVelY <= 0) {
-							decVelY += diff.y * bounceDeceleration;
-						} else {
-							var adjust = diff.y > 0 ? reboundAdjust : -reboundAdjust;
-							decVelY = (diff.y + adjust) * bounceAcceleration;
-						}
-					}
-				} else {
-					if (diff.x !== 0) {
-						if (diff.x > 0) {
-							targetX = boundXmin;
-						} else {
-							targetX = boundXmax;
-						}
-						decVelX = 0;
-					}
-					if (diff.y !== 0) {
-						if (diff.y > 0) {
-							targetY = boundYmin;
-						} else {
-							targetY = boundYmax;
-						}
-						decVelY = 0;
-					}
-				}
-
-				callUpdateCallback();
-
-				requestAnimFrame(stepDecelAnim);
-			} else {
-				decelerating = false;
-			}
-		}
-	}
-
-	/**
-  * @see http://www.paulirish.com/2011/requestanimationframe-for-smart-animating/
-  */
-	;
-
-	module.exports = Impetus;
-	var requestAnimFrame = (function () {
-		return window.requestAnimationFrame || window.webkitRequestAnimationFrame || window.mozRequestAnimationFrame || function (callback) {
-			window.setTimeout(callback, 1000 / 60);
-		};
-	})();
-});
-
-},{}],8:[function(require,module,exports){
-var rootPosition = { left: 0, top: 0 }
-
-module.exports = mouseEventOffset
-function mouseEventOffset (ev, target, out) {
-  target = target || ev.currentTarget || ev.srcElement
-  if (!Array.isArray(out)) {
-    out = [ 0, 0 ]
-  }
-  var cx = ev.clientX || 0
-  var cy = ev.clientY || 0
-  var rect = getBoundingClientOffset(target)
-  out[0] = cx - rect.left
-  out[1] = cy - rect.top
-  return out
-}
-
-function getBoundingClientOffset (element) {
-  if (element === window ||
-      element === document ||
-      element === document.body) {
-    return rootPosition
-  } else {
-    return element.getBoundingClientRect()
-  }
-}
-
-},{}],9:[function(require,module,exports){
-'use strict'
-
-var toPX = require('to-px')
-
-module.exports = mouseWheelListen
-
-function mouseWheelListen(element, callback, noScroll) {
-  if(typeof element === 'function') {
-    noScroll = !!callback
-    callback = element
-    element = window
-  }
-  var lineHeight = toPX('ex', element)
-  var listener = function(ev) {
-    if(noScroll) {
-      ev.preventDefault()
-    }
-    var dx = ev.deltaX || 0
-    var dy = ev.deltaY || 0
-    var dz = ev.deltaZ || 0
-    var mode = ev.deltaMode
-    var scale = 1
-    switch(mode) {
-      case 1:
-        scale = lineHeight
-      break
-      case 2:
-        scale = window.innerHeight
-      break
-    }
-    dx *= scale
-    dy *= scale
-    dz *= scale
-    if(dx || dy || dz) {
-      return callback(dx, dy, dz, ev)
-    }
-  }
-  element.addEventListener('wheel', listener)
-  return listener
-}
-
-},{"to-px":15}],10:[function(require,module,exports){
-/**
- * @module  pan-zoom
- *
- * Events for pan and zoom
- */
-'use strict';
-
-
-const Impetus = require('impetus');
-const wheel = require('mouse-wheel');
-const touchPinch = require('touch-pinch');
-const position = require('touch-position');
-
-
-module.exports = panzoom;
-
-
-function panzoom (target, cb) {
-	if (!target || !(cb instanceof Function)) return false;
-
-
-	//enable panning
-	let pos = position({
-		element: target
-	});
-
-	let impetus;
-
-	let lastY = 0, lastX = 0;
-	impetus = new Impetus({
-		source: target,
-		update: (x, y) => {
-			let e = {
-				type: 'mouse',
-				dx: x-lastX, dy: y-lastY, dz: 0,
-				x: pos[0], y: pos[1]
-			};
-
-			lastX = x;
-			lastY = y;
-
-			cb(e);
-		},
-		multiplier: 1,
-		friction: .75
-	});
-
-
-	//enable zooming
-	wheel(target, (dx, dy, dz, e) => {
-		e.preventDefault();
-		cb({
-			type: 'mouse',
-			dx: 0, dy: 0, dz: dy,
-			x: pos[0], y: pos[1]
-		});
-	});
-
-	//mobile pinch zoom
-	let pinch = touchPinch(target);
-	let mult = 2;
-	let initialCoords;
-
-	pinch.on('start', (curr) => {
-		impetus && impetus.pause();
-
-		let [f1, f2] = pinch.fingers;
-
-		initialCoords = [f2.position[0]*.5 + f1.position[0]*.5, f2.position[1]*.5 + f1.position[1]*.5];
-	});
-	pinch.on('end', () => {
-		initialCoords = null;
-
-		impetus && impetus.resume();
-	});
-	pinch.on('change', (curr, prev) => {
-		if (!pinch.pinching || !initialCoords) return;
-
-		cb({
-			type: 'touch',
-			dx: 0, dy: 0, dz: -(curr - prev)*mult,
-			x: initialCoords[0], y: initialCoords[1]
-		});
-	});
-}
-
-},{"impetus":7,"mouse-wheel":9,"touch-pinch":16,"touch-position":17}],11:[function(require,module,exports){
-module.exports = function parseUnit(str, out) {
-    if (!out)
-        out = [ 0, '' ]
-
-    str = String(str)
-    var num = parseFloat(str, 10)
-    out[0] = num
-    out[1] = str.match(/[\d.\-\+]*\s*(.*)/)[1] || ''
-    return out
-}
-},{}],12:[function(require,module,exports){
-(function (process){
-// Generated by CoffeeScript 1.7.1
-(function() {
-  var getNanoSeconds, hrtime, loadTime;
-
-  if ((typeof performance !== "undefined" && performance !== null) && performance.now) {
-    module.exports = function() {
-      return performance.now();
-    };
-  } else if ((typeof process !== "undefined" && process !== null) && process.hrtime) {
-    module.exports = function() {
-      return (getNanoSeconds() - loadTime) / 1e6;
-    };
-    hrtime = process.hrtime;
-    getNanoSeconds = function() {
-      var hr;
-      hr = hrtime();
-      return hr[0] * 1e9 + hr[1];
-    };
-    loadTime = getNanoSeconds();
-  } else if (Date.now) {
-    module.exports = function() {
-      return Date.now() - loadTime;
-    };
-    loadTime = Date.now();
-  } else {
-    module.exports = function() {
-      return new Date().getTime() - loadTime;
-    };
-    loadTime = new Date().getTime();
-  }
-
-}).call(this);
-
-}).call(this,require('_process'))
-},{"_process":19}],13:[function(require,module,exports){
-(function (global){
-var now = require('performance-now')
-  , root = typeof window === 'undefined' ? global : window
-  , vendors = ['moz', 'webkit']
-  , suffix = 'AnimationFrame'
-  , raf = root['request' + suffix]
-  , caf = root['cancel' + suffix] || root['cancelRequest' + suffix]
-
-for(var i = 0; !raf && i < vendors.length; i++) {
-  raf = root[vendors[i] + 'Request' + suffix]
-  caf = root[vendors[i] + 'Cancel' + suffix]
-      || root[vendors[i] + 'CancelRequest' + suffix]
-}
-
-// Some versions of FF have rAF but not cAF
-if(!raf || !caf) {
-  var last = 0
-    , id = 0
-    , queue = []
-    , frameDuration = 1000 / 60
-
-  raf = function(callback) {
-    if(queue.length === 0) {
-      var _now = now()
-        , next = Math.max(0, frameDuration - (_now - last))
-      last = next + _now
-      setTimeout(function() {
-        var cp = queue.slice(0)
-        // Clear queue here to prevent
-        // callbacks from appending listeners
-        // to the current frame's queue
-        queue.length = 0
-        for(var i = 0; i < cp.length; i++) {
-          if(!cp[i].cancelled) {
-            try{
-              cp[i].callback(last)
-            } catch(e) {
-              setTimeout(function() { throw e }, 0)
-            }
-          }
-        }
-      }, Math.round(next))
-    }
-    queue.push({
-      handle: ++id,
-      callback: callback,
-      cancelled: false
-    })
-    return id
-  }
-
-  caf = function(handle) {
-    for(var i = 0; i < queue.length; i++) {
-      if(queue[i].handle === handle) {
-        queue[i].cancelled = true
-      }
-    }
-  }
-}
-
-module.exports = function(fn) {
-  // Wrap in a new function to prevent
-  // `cancel` potentially being assigned
-  // to the native rAF function
-  return raf.call(root, fn)
-}
-module.exports.cancel = function() {
-  caf.apply(root, arguments)
-}
-module.exports.polyfill = function() {
-  root.requestAnimationFrame = raf
-  root.cancelAnimationFrame = caf
-}
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{"performance-now":12}],14:[function(require,module,exports){
-(function (global){
-module.exports =
-  global.performance &&
-  global.performance.now ? function now() {
-    return performance.now()
-  } : Date.now || function now() {
-    return +new Date
-  }
-
-}).call(this,typeof global !== "undefined" ? global : typeof self !== "undefined" ? self : typeof window !== "undefined" ? window : {})
-},{}],15:[function(require,module,exports){
-'use strict'
-
-var parseUnit = require('parse-unit')
-
-module.exports = toPX
-
-var PIXELS_PER_INCH = 96
-
-function getPropertyInPX(element, prop) {
-  var parts = parseUnit(getComputedStyle(element).getPropertyValue(prop))
-  return parts[0] * toPX(parts[1], element)
-}
-
-//This brutal hack is needed
-function getSizeBrutal(unit, element) {
-  var testDIV = document.createElement('div')
-  testDIV.style['font-size'] = '128' + unit
-  element.appendChild(testDIV)
-  var size = getPropertyInPX(testDIV, 'font-size') / 128
-  element.removeChild(testDIV)
-  return size
-}
-
-function toPX(str, element) {
-  element = element || document.body
-  str = (str || 'px').trim().toLowerCase()
-  if(element === window || element === document) {
-    element = document.body 
-  }
-  switch(str) {
-    case '%':  //Ambiguous, not sure if we should use width or height
-      return element.clientHeight / 100.0
-    case 'ch':
-    case 'ex':
-      return getSizeBrutal(str, element)
-    case 'em':
-      return getPropertyInPX(element, 'font-size')
-    case 'rem':
-      return getPropertyInPX(document.body, 'font-size')
-    case 'vw':
-      return window.innerWidth/100
-    case 'vh':
-      return window.innerHeight/100
-    case 'vmin':
-      return Math.min(window.innerWidth, window.innerHeight) / 100
-    case 'vmax':
-      return Math.max(window.innerWidth, window.innerHeight) / 100
-    case 'in':
-      return PIXELS_PER_INCH
-    case 'cm':
-      return PIXELS_PER_INCH / 2.54
-    case 'mm':
-      return PIXELS_PER_INCH / 25.4
-    case 'pt':
-      return PIXELS_PER_INCH / 72
-    case 'pc':
-      return PIXELS_PER_INCH / 6
-  }
-  return 1
-}
-},{"parse-unit":11}],16:[function(require,module,exports){
-var getDistance = require('gl-vec2/distance')
-var EventEmitter = require('events').EventEmitter
-var dprop = require('dprop')
-var eventOffset = require('mouse-event-offset')
-
-module.exports = touchPinch
-function touchPinch (target) {
-  target = target || window
-
-  var emitter = new EventEmitter()
-  var fingers = [ null, null ]
-  var activeCount = 0
-
-  var lastDistance = 0
-  var ended = false
-  var enabled = false
-
-  // some read-only values
-  Object.defineProperties(emitter, {
-    pinching: dprop(function () {
-      return activeCount === 2
-    }),
-
-    fingers: dprop(function () {
-      return fingers
-    })
-  })
-
-  enable()
-  emitter.enable = enable
-  emitter.disable = disable
-  emitter.indexOfTouch = indexOfTouch
-  return emitter
-
-  function indexOfTouch (touch) {
-    var id = touch.identifier
-    for (var i = 0; i < fingers.length; i++) {
-      if (fingers[i] &&
-        fingers[i].touch &&
-        fingers[i].touch.identifier === id) {
-        return i
-      }
-    }
-    return -1
-  }
-
-  function enable () {
-    if (enabled) return
-    enabled = true
-    target.addEventListener('touchstart', onTouchStart, false)
-    target.addEventListener('touchmove', onTouchMove, false)
-    target.addEventListener('touchend', onTouchRemoved, false)
-    target.addEventListener('touchcancel', onTouchRemoved, false)
-  }
-
-  function disable () {
-    if (!enabled) return
-    enabled = false
-    target.removeEventListener('touchstart', onTouchStart, false)
-    target.removeEventListener('touchmove', onTouchMove, false)
-    target.removeEventListener('touchend', onTouchRemoved, false)
-    target.removeEventListener('touchcancel', onTouchRemoved, false)
-  }
-
-  function onTouchStart (ev) {
-    for (var i = 0; i < ev.changedTouches.length; i++) {
-      var newTouch = ev.changedTouches[i]
-      var id = newTouch.identifier
-      var idx = indexOfTouch(id)
-
-      if (idx === -1 && activeCount < 2) {
-        var first = activeCount === 0
-
-        // newest and previous finger (previous may be undefined)
-        var newIndex = fingers[0] ? 1 : 0
-        var oldIndex = fingers[0] ? 0 : 1
-        var newFinger = new Finger()
-
-        // add to stack
-        fingers[newIndex] = newFinger
-        activeCount++
-
-        // update touch event & position
-        newFinger.touch = newTouch
-        eventOffset(newTouch, target, newFinger.position)
-
-        var oldTouch = fingers[oldIndex] ? fingers[oldIndex].touch : undefined
-        emitter.emit('place', newTouch, oldTouch)
-
-        if (!first) {
-          var initialDistance = computeDistance()
-          ended = false
-          emitter.emit('start', initialDistance)
-          lastDistance = initialDistance
-        }
-      }
-    }
-  }
-
-  function onTouchMove (ev) {
-    var changed = false
-    for (var i = 0; i < ev.changedTouches.length; i++) {
-      var movedTouch = ev.changedTouches[i]
-      var idx = indexOfTouch(movedTouch)
-      if (idx !== -1) {
-        changed = true
-        fingers[idx].touch = movedTouch // avoid caching touches
-        eventOffset(movedTouch, target, fingers[idx].position)
-      }
-    }
-
-    if (activeCount === 2 && changed) {
-      var currentDistance = computeDistance()
-      emitter.emit('change', currentDistance, lastDistance)
-      lastDistance = currentDistance
-    }
-  }
-
-  function onTouchRemoved (ev) {
-    for (var i = 0; i < ev.changedTouches.length; i++) {
-      var removed = ev.changedTouches[i]
-      var idx = indexOfTouch(removed)
-
-      if (idx !== -1) {
-        fingers[idx] = null
-        activeCount--
-        var otherIdx = idx === 0 ? 1 : 0
-        var otherTouch = fingers[otherIdx] ? fingers[otherIdx].touch : undefined
-        emitter.emit('lift', removed, otherTouch)
-      }
-    }
-
-    if (!ended && activeCount !== 2) {
-      ended = true
-      emitter.emit('end')
-    }
-  }
-
-  function computeDistance () {
-    if (activeCount < 2) return 0
-    return getDistance(fingers[0].position, fingers[1].position)
-  }
-}
-
-function Finger () {
-  this.position = [0, 0]
-  this.touch = null
-}
-
-},{"dprop":2,"events":18,"gl-vec2/distance":6,"mouse-event-offset":8}],17:[function(require,module,exports){
-var offset = require('mouse-event-offset');
-var EventEmitter = require('events').EventEmitter;
-
-function attach (opt) {
-  opt = opt || {};
-  var element = opt.element || window;
-
-  var emitter = new EventEmitter();
-
-  var position = opt.position || [0, 0];
-  if (opt.touchstart !== false) {
-    element.addEventListener('mousedown', update, false);
-    element.addEventListener('touchstart', updateTouch, false);
-  }
-
-  element.addEventListener('mousemove', update, false);
-  element.addEventListener('touchmove', updateTouch, false);
-
-  emitter.position = position;
-  emitter.dispose = dispose;
-  return emitter;
-
-  function updateTouch (ev) {
-    var touch = ev.targetTouches[0];
-    update(touch);
-  }
-
-  function update (ev) {
-    offset(ev, element, position);
-    emitter.emit('move', ev);
-  }
-
-  function dispose () {
-    element.removeEventListener('mousemove', update, false);
-    element.removeEventListener('mousedown', update, false);
-    element.removeEventListener('touchmove', updateTouch, false);
-    element.removeEventListener('touchstart', updateTouch, false);
-  }
-}
-
-module.exports = function (opt) {
-  return attach(opt).position;
-};
-
-module.exports.emitter = function (opt) {
-  return attach(opt);
-};
-
-},{"events":18,"mouse-event-offset":8}],18:[function(require,module,exports){
-// Copyright Joyent, Inc. and other Node contributors.
-//
-// Permission is hereby granted, free of charge, to any person obtaining a
-// copy of this software and associated documentation files (the
-// "Software"), to deal in the Software without restriction, including
-// without limitation the rights to use, copy, modify, merge, publish,
-// distribute, sublicense, and/or sell copies of the Software, and to permit
-// persons to whom the Software is furnished to do so, subject to the
-// following conditions:
-//
-// The above copyright notice and this permission notice shall be included
-// in all copies or substantial portions of the Software.
-//
-// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS
-// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
-// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN
-// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,
-// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR
-// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE
-// USE OR OTHER DEALINGS IN THE SOFTWARE.
-
-function EventEmitter() {
-  this._events = this._events || {};
-  this._maxListeners = this._maxListeners || undefined;
-}
-module.exports = EventEmitter;
-
-// Backwards-compat with node 0.10.x
-EventEmitter.EventEmitter = EventEmitter;
-
-EventEmitter.prototype._events = undefined;
-EventEmitter.prototype._maxListeners = undefined;
-
-// By default EventEmitters will print a warning if more than 10 listeners are
-// added to it. This is a useful default which helps finding memory leaks.
-EventEmitter.defaultMaxListeners = 10;
-
-// Obviously not all Emitters should be limited to 10. This function allows
-// that to be increased. Set to zero for unlimited.
-EventEmitter.prototype.setMaxListeners = function(n) {
-  if (!isNumber(n) || n < 0 || isNaN(n))
-    throw TypeError('n must be a positive number');
-  this._maxListeners = n;
-  return this;
-};
-
-EventEmitter.prototype.emit = function(type) {
-  var er, handler, len, args, i, listeners;
-
-  if (!this._events)
-    this._events = {};
-
-  // If there is no 'error' event listener then throw.
-  if (type === 'error') {
-    if (!this._events.error ||
-        (isObject(this._events.error) && !this._events.error.length)) {
-      er = arguments[1];
-      if (er instanceof Error) {
-        throw er; // Unhandled 'error' event
-      } else {
-        // At least give some kind of context to the user
-        var err = new Error('Uncaught, unspecified "error" event. (' + er + ')');
-        err.context = er;
-        throw err;
-      }
-    }
-  }
-
-  handler = this._events[type];
-
-  if (isUndefined(handler))
-    return false;
-
-  if (isFunction(handler)) {
-    switch (arguments.length) {
-      // fast cases
-      case 1:
-        handler.call(this);
-        break;
-      case 2:
-        handler.call(this, arguments[1]);
-        break;
-      case 3:
-        handler.call(this, arguments[1], arguments[2]);
-        break;
-      // slower
-      default:
-        args = Array.prototype.slice.call(arguments, 1);
-        handler.apply(this, args);
-    }
-  } else if (isObject(handler)) {
-    args = Array.prototype.slice.call(arguments, 1);
-    listeners = handler.slice();
-    len = listeners.length;
-    for (i = 0; i < len; i++)
-      listeners[i].apply(this, args);
-  }
-
-  return true;
-};
-
-EventEmitter.prototype.addListener = function(type, listener) {
-  var m;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events)
-    this._events = {};
-
-  // To avoid recursion in the case that type === "newListener"! Before
-  // adding it to the listeners, first emit "newListener".
-  if (this._events.newListener)
-    this.emit('newListener', type,
-              isFunction(listener.listener) ?
-              listener.listener : listener);
-
-  if (!this._events[type])
-    // Optimize the case of one listener. Don't need the extra array object.
-    this._events[type] = listener;
-  else if (isObject(this._events[type]))
-    // If we've already got an array, just append.
-    this._events[type].push(listener);
-  else
-    // Adding the second element, need to change to array.
-    this._events[type] = [this._events[type], listener];
-
-  // Check for listener leak
-  if (isObject(this._events[type]) && !this._events[type].warned) {
-    if (!isUndefined(this._maxListeners)) {
-      m = this._maxListeners;
-    } else {
-      m = EventEmitter.defaultMaxListeners;
-    }
-
-    if (m && m > 0 && this._events[type].length > m) {
-      this._events[type].warned = true;
-      console.error('(node) warning: possible EventEmitter memory ' +
-                    'leak detected. %d listeners added. ' +
-                    'Use emitter.setMaxListeners() to increase limit.',
-                    this._events[type].length);
-      if (typeof console.trace === 'function') {
-        // not supported in IE 10
-        console.trace();
-      }
-    }
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.on = EventEmitter.prototype.addListener;
-
-EventEmitter.prototype.once = function(type, listener) {
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  var fired = false;
-
-  function g() {
-    this.removeListener(type, g);
-
-    if (!fired) {
-      fired = true;
-      listener.apply(this, arguments);
-    }
-  }
-
-  g.listener = listener;
-  this.on(type, g);
-
-  return this;
-};
-
-// emits a 'removeListener' event iff the listener was removed
-EventEmitter.prototype.removeListener = function(type, listener) {
-  var list, position, length, i;
-
-  if (!isFunction(listener))
-    throw TypeError('listener must be a function');
-
-  if (!this._events || !this._events[type])
-    return this;
-
-  list = this._events[type];
-  length = list.length;
-  position = -1;
-
-  if (list === listener ||
-      (isFunction(list.listener) && list.listener === listener)) {
-    delete this._events[type];
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-
-  } else if (isObject(list)) {
-    for (i = length; i-- > 0;) {
-      if (list[i] === listener ||
-          (list[i].listener && list[i].listener === listener)) {
-        position = i;
-        break;
-      }
-    }
-
-    if (position < 0)
-      return this;
-
-    if (list.length === 1) {
-      list.length = 0;
-      delete this._events[type];
-    } else {
-      list.splice(position, 1);
-    }
-
-    if (this._events.removeListener)
-      this.emit('removeListener', type, listener);
-  }
-
-  return this;
-};
-
-EventEmitter.prototype.removeAllListeners = function(type) {
-  var key, listeners;
-
-  if (!this._events)
-    return this;
-
-  // not listening for removeListener, no need to emit
-  if (!this._events.removeListener) {
-    if (arguments.length === 0)
-      this._events = {};
-    else if (this._events[type])
-      delete this._events[type];
-    return this;
-  }
-
-  // emit removeListener for all listeners on all events
-  if (arguments.length === 0) {
-    for (key in this._events) {
-      if (key === 'removeListener') continue;
-      this.removeAllListeners(key);
-    }
-    this.removeAllListeners('removeListener');
-    this._events = {};
-    return this;
-  }
-
-  listeners = this._events[type];
-
-  if (isFunction(listeners)) {
-    this.removeListener(type, listeners);
-  } else if (listeners) {
-    // LIFO order
-    while (listeners.length)
-      this.removeListener(type, listeners[listeners.length - 1]);
-  }
-  delete this._events[type];
-
-  return this;
-};
-
-EventEmitter.prototype.listeners = function(type) {
-  var ret;
-  if (!this._events || !this._events[type])
-    ret = [];
-  else if (isFunction(this._events[type]))
-    ret = [this._events[type]];
-  else
-    ret = this._events[type].slice();
-  return ret;
-};
-
-EventEmitter.prototype.listenerCount = function(type) {
-  if (this._events) {
-    var evlistener = this._events[type];
-
-    if (isFunction(evlistener))
-      return 1;
-    else if (evlistener)
-      return evlistener.length;
-  }
-  return 0;
-};
-
-EventEmitter.listenerCount = function(emitter, type) {
-  return emitter.listenerCount(type);
-};
-
-function isFunction(arg) {
-  return typeof arg === 'function';
-}
-
-function isNumber(arg) {
-  return typeof arg === 'number';
-}
-
-function isObject(arg) {
-  return typeof arg === 'object' && arg !== null;
-}
-
-function isUndefined(arg) {
-  return arg === void 0;
-}
-
-},{}],19:[function(require,module,exports){
-// shim for using process in browser
-var process = module.exports = {};
-
-// cached from whatever global is present so that test runners that stub it
-// don't break things.  But we need to wrap it in a try catch in case it is
-// wrapped in strict mode code which doesn't define any globals.  It's inside a
-// function because try/catches deoptimize in certain engines.
-
-var cachedSetTimeout;
-var cachedClearTimeout;
-
-function defaultSetTimout() {
-    throw new Error('setTimeout has not been defined');
-}
-function defaultClearTimeout () {
-    throw new Error('clearTimeout has not been defined');
-}
-(function () {
-    try {
-        if (typeof setTimeout === 'function') {
-            cachedSetTimeout = setTimeout;
-        } else {
-            cachedSetTimeout = defaultSetTimout;
-        }
-    } catch (e) {
-        cachedSetTimeout = defaultSetTimout;
-    }
-    try {
-        if (typeof clearTimeout === 'function') {
-            cachedClearTimeout = clearTimeout;
-        } else {
-            cachedClearTimeout = defaultClearTimeout;
-        }
-    } catch (e) {
-        cachedClearTimeout = defaultClearTimeout;
-    }
-} ())
-function runTimeout(fun) {
-    if (cachedSetTimeout === setTimeout) {
-        //normal enviroments in sane situations
-        return setTimeout(fun, 0);
-    }
-    // if setTimeout wasn't available but was latter defined
-    if ((cachedSetTimeout === defaultSetTimout || !cachedSetTimeout) && setTimeout) {
-        cachedSetTimeout = setTimeout;
-        return setTimeout(fun, 0);
-    }
-    try {
-        // when when somebody has screwed with setTimeout but no I.E. maddness
-        return cachedSetTimeout(fun, 0);
-    } catch(e){
-        try {
-            // When we are in I.E. but the script has been evaled so I.E. doesn't trust the global object when called normally
-            return cachedSetTimeout.call(null, fun, 0);
-        } catch(e){
-            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error
-            return cachedSetTimeout.call(this, fun, 0);
-        }
-    }
-
-
-}
-function runClearTimeout(marker) {
-    if (cachedClearTimeout === clearTimeout) {
-        //normal enviroments in sane situations
-        return clearTimeout(marker);
-    }
-    // if clearTimeout wasn't available but was latter defined
-    if ((cachedClearTimeout === defaultClearTimeout || !cachedClearTimeout) && clearTimeout) {
-        cachedClearTimeout = clearTimeout;
-        return clearTimeout(marker);
-    }
-    try {
-        // when when somebody has screwed with setTimeout but no I.E. maddness
-        return cachedClearTimeout(marker);
-    } catch (e){
-        try {
-            // When we are in I.E. but the script has been evaled so I.E. doesn't  trust the global object when called normally
-            return cachedClearTimeout.call(null, marker);
-        } catch (e){
-            // same as above but when it's a version of I.E. that must have the global object for 'this', hopfully our context correct otherwise it will throw a global error.
-            // Some versions of I.E. have different rules for clearTimeout vs setTimeout
-            return cachedClearTimeout.call(this, marker);
-        }
-    }
-
-
-
-}
-var queue = [];
-var draining = false;
-var currentQueue;
-var queueIndex = -1;
-
-function cleanUpNextTick() {
-    if (!draining || !currentQueue) {
-        return;
-    }
-    draining = false;
-    if (currentQueue.length) {
-        queue = currentQueue.concat(queue);
-    } else {
-        queueIndex = -1;
-    }
-    if (queue.length) {
-        drainQueue();
-    }
-}
-
-function drainQueue() {
-    if (draining) {
-        return;
-    }
-    var timeout = runTimeout(cleanUpNextTick);
-    draining = true;
-
-    var len = queue.length;
-    while(len) {
-        currentQueue = queue;
-        queue = [];
-        while (++queueIndex < len) {
-            if (currentQueue) {
-                currentQueue[queueIndex].run();
-            }
-        }
-        queueIndex = -1;
-        len = queue.length;
-    }
-    currentQueue = null;
-    draining = false;
-    runClearTimeout(timeout);
-}
-
-process.nextTick = function (fun) {
-    var args = new Array(arguments.length - 1);
-    if (arguments.length > 1) {
-        for (var i = 1; i < arguments.length; i++) {
-            args[i - 1] = arguments[i];
-        }
-    }
-    queue.push(new Item(fun, args));
-    if (queue.length === 1 && !draining) {
-        runTimeout(drainQueue);
-    }
-};
-
-// v8 likes predictible objects
-function Item(fun, array) {
-    this.fun = fun;
-    this.array = array;
-}
-Item.prototype.run = function () {
-    this.fun.apply(null, this.array);
-};
-process.title = 'browser';
-process.browser = true;
-process.env = {};
-process.argv = [];
-process.version = ''; // empty string to avoid regexp issues
-process.versions = {};
-
-function noop() {}
-
-process.on = noop;
-process.addListener = noop;
-process.once = noop;
-process.off = noop;
-process.removeListener = noop;
-process.removeAllListeners = noop;
-process.emit = noop;
-
-process.binding = function (name) {
-    throw new Error('process.binding is not supported');
-};
-
-process.cwd = function () { return '/' };
-process.chdir = function (dir) {
-    throw new Error('process.chdir is not supported');
-};
-process.umask = function() { return 0; };
-
-},{}]},{},[1]);
