diff --git a/dist/vizicities-worker.js b/dist/vizicities-worker.js new file mode 100644 index 0000000..6569d96 --- /dev/null +++ b/dist/vizicities-worker.js @@ -0,0 +1,9190 @@ +(function webpackUniversalModuleDefinition(root, factory) { + if(typeof exports === 'object' && typeof module === 'object') + module.exports = factory(require("THREE")); + else if(typeof define === 'function' && define.amd) + define(["THREE"], factory); + else if(typeof exports === 'object') + exports["VIZI"] = factory(require("THREE")); + else + root["VIZI"] = factory(root["THREE"]); +})(this, function(__WEBPACK_EXTERNAL_MODULE_18__) { +return /******/ (function(modules) { // webpackBootstrap +/******/ // The module cache +/******/ var installedModules = {}; +/******/ +/******/ // The require function +/******/ function __webpack_require__(moduleId) { +/******/ +/******/ // Check if module is in cache +/******/ if(installedModules[moduleId]) +/******/ return installedModules[moduleId].exports; +/******/ +/******/ // Create a new module (and put it into the cache) +/******/ var module = installedModules[moduleId] = { +/******/ exports: {}, +/******/ id: moduleId, +/******/ loaded: false +/******/ }; +/******/ +/******/ // Execute the module function +/******/ modules[moduleId].call(module.exports, module, module.exports, __webpack_require__); +/******/ +/******/ // Flag the module as loaded +/******/ module.loaded = true; +/******/ +/******/ // Return the exports of the module +/******/ return module.exports; +/******/ } +/******/ +/******/ +/******/ // expose the modules object (__webpack_modules__) +/******/ __webpack_require__.m = modules; +/******/ +/******/ // expose the module cache +/******/ __webpack_require__.c = installedModules; +/******/ +/******/ // __webpack_public_path__ +/******/ __webpack_require__.p = ""; +/******/ +/******/ // Load entry module and return exports +/******/ return __webpack_require__(0); +/******/ }) +/************************************************************************/ +/******/ ([ +/* 0 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _geoGeoJs = __webpack_require__(1); + + var _geoGeoJs2 = _interopRequireDefault(_geoGeoJs); + + var _layerLayer = __webpack_require__(4); + + var _layerLayer2 = _interopRequireDefault(_layerLayer); + + var _layerGeoJSONWorkerLayer = __webpack_require__(22); + + var _layerGeoJSONWorkerLayer2 = _interopRequireDefault(_layerGeoJSONWorkerLayer); + + var _layerGeometryPolygonLayer = __webpack_require__(36); + + var _layerGeometryPolygonLayer2 = _interopRequireDefault(_layerGeometryPolygonLayer); + + var _geoPoint = __webpack_require__(3); + + var _geoPoint2 = _interopRequireDefault(_geoPoint); + + var _geoLatLon = __webpack_require__(2); + + var _geoLatLon2 = _interopRequireDefault(_geoLatLon); + + var _utilIndex = __webpack_require__(41); + + var _utilIndex2 = _interopRequireDefault(_utilIndex); + + var VIZI = { + version: '0.3', + + Geo: _geoGeoJs2['default'], + Layer: _layerLayer2['default'], + layer: _layerLayer.layer, + GeoJSONWorkerLayer: _layerGeoJSONWorkerLayer2['default'], + geoJSONWorkerLayer: _layerGeoJSONWorkerLayer.geoJSONWorkerLayer, + PolygonLayer: _layerGeometryPolygonLayer2['default'], + polygonLayer: _layerGeometryPolygonLayer.polygonLayer, + Point: _geoPoint2['default'], + point: _geoPoint.point, + LatLon: _geoLatLon2['default'], + latLon: _geoLatLon.latLon, + Util: _utilIndex2['default'] + }; + + exports['default'] = VIZI; + module.exports = exports['default']; + +/***/ }, +/* 1 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var _LatLon = __webpack_require__(2); + + var _Point = __webpack_require__(3); + + var Geo = {}; + + // Radius / WGS84 semi-major axis + Geo.R = 6378137; + Geo.MAX_LATITUDE = 85.0511287798; + + // WGS84 eccentricity + Geo.ECC = 0.081819191; + Geo.ECC2 = 0.081819191 * 0.081819191; + + Geo.project = function (latlon) { + var d = Math.PI / 180; + var max = Geo.MAX_LATITUDE; + var lat = Math.max(Math.min(max, latlon.lat), -max); + var sin = Math.sin(lat * d); + + return (0, _Point.point)(Geo.R * latlon.lon * d, Geo.R * Math.log((1 + sin) / (1 - sin)) / 2); + }, Geo.unproject = function (point) { + var d = 180 / Math.PI; + + return (0, _LatLon.latLon)((2 * Math.atan(Math.exp(point.y / Geo.R)) - Math.PI / 2) * d, point.x * d / Geo.R); + }; + + // Converts geo coords to pixel / WebGL ones + // This just reverses the Y axis to match WebGL + Geo.latLonToPoint = function (latlon) { + var projected = Geo.project(latlon); + projected.y *= -1; + + return projected; + }; + + // Converts pixel / WebGL coords to geo coords + // This just reverses the Y axis to match WebGL + Geo.pointToLatLon = function (point) { + var _point = (0, _Point.point)(point.x, point.y * -1); + return Geo.unproject(_point); + }; + + // Scale factor for converting between real metres and projected metres + // + // projectedMetres = realMetres * pointScale + // realMetres = projectedMetres / pointScale + // + // Accurate scale factor uses proper Web Mercator scaling + // See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf + // See: http://jsfiddle.net/robhawkes/yws924cf/ + Geo.pointScale = function (latlon, accurate) { + var rad = Math.PI / 180; + + var k; + + if (!accurate) { + k = 1 / Math.cos(latlon.lat * rad); + + // [scaleX, scaleY] + return [k, k]; + } else { + var lat = latlon.lat * rad; + var lon = latlon.lon * rad; + + var a = Geo.R; + + var sinLat = Math.sin(lat); + var sinLat2 = sinLat * sinLat; + + var cosLat = Math.cos(lat); + + // Radius meridian + var p = a * (1 - Geo.ECC2) / Math.pow(1 - Geo.ECC2 * sinLat2, 3 / 2); + + // Radius prime meridian + var v = a / Math.sqrt(1 - Geo.ECC2 * sinLat2); + + // Scale N/S + var h = a / p / cosLat; + + // Scale E/W + k = a / v / cosLat; + + // [scaleX, scaleY] + return [k, h]; + } + }; + + // Convert real metres to projected units + // + // Latitude scale is chosen because it fluctuates more than longitude + Geo.metresToProjected = function (metres, pointScale) { + return metres * pointScale[1]; + }; + + // Convert projected units to real metres + // + // Latitude scale is chosen because it fluctuates more than longitude + Geo.projectedToMetres = function (projectedUnits, pointScale) { + return projectedUnits / pointScale[1]; + }; + + // Convert real metres to a value in world (WebGL) units + Geo.metresToWorld = function (metres, pointScale) { + // Transform metres to projected metres using the latitude point scale + // + // Latitude scale is chosen because it fluctuates more than longitude + var projectedMetres = Geo.metresToProjected(metres, pointScale); + + var scale = Geo.scale(); + + // Scale projected metres + var scaledMetres = scale * projectedMetres; + + return scaledMetres; + }; + + // Convert world (WebGL) units to a value in real metres + Geo.worldToMetres = function (worldUnits, pointScale) { + var scale = Geo.scale(); + + var projectedUnits = worldUnits / scale; + var realMetres = Geo.projectedToMetres(projectedUnits, pointScale); + + return realMetres; + }; + + // If zoom is provided, returns the map width in pixels for a given zoom + // Else, provides fixed scale value + Geo.scale = function (zoom) { + // If zoom is provided then return scale based on map tile zoom + if (zoom >= 0) { + return 256 * Math.pow(2, zoom); + // Else, return fixed scale value to expand projected coordinates from + // their 0 to 1 range into something more practical + } else { + return 1; + } + }; + + // Returns zoom level for a given scale value + // This only works with a scale value that is based on map pixel width + Geo.zoom = function (scale) { + return Math.log(scale / 256) / Math.LN2; + }; + + // Distance between two geographical points using spherical law of cosines + // approximation or Haversine + // + // See: http://www.movable-type.co.uk/scripts/latlong.html + Geo.distance = function (latlon1, latlon2, accurate) { + var rad = Math.PI / 180; + + var lat1; + var lat2; + + var a; + + if (!accurate) { + lat1 = latlon1.lat * rad; + lat2 = latlon2.lat * rad; + + a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad); + + return Geo.R * Math.acos(Math.min(a, 1)); + } else { + lat1 = latlon1.lat * rad; + lat2 = latlon2.lat * rad; + + var lon1 = latlon1.lon * rad; + var lon2 = latlon2.lon * rad; + + var deltaLat = lat2 - lat1; + var deltaLon = lon2 - lon1; + + var halfDeltaLat = deltaLat / 2; + var halfDeltaLon = deltaLon / 2; + + a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon); + + var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + + return Geo.R * c; + } + }; + + Geo.bounds = (function () { + var d = Geo.R * Math.PI; + return [[-d, -d], [d, d]]; + })(); + + exports['default'] = Geo; + module.exports = exports['default']; + +/***/ }, +/* 2 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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'); } } + + /* + * LatLon is a helper class for ensuring consistent geographic coordinates. + * + * Based on: + * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js + */ + + var LatLon = (function () { + function LatLon(lat, lon, alt) { + _classCallCheck(this, LatLon); + + if (isNaN(lat) || isNaN(lon)) { + throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')'); + } + + this.lat = +lat; + this.lon = +lon; + + if (alt !== undefined) { + this.alt = +alt; + } + } + + _createClass(LatLon, [{ + key: 'clone', + value: function clone() { + return new LatLon(this.lat, this.lon, this.alt); + } + }]); + + return LatLon; + })(); + + exports['default'] = LatLon; + + // Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt) + // Also converts between lng and lon + var noNew = function noNew(a, b, c) { + if (a instanceof LatLon) { + return a; + } + if (Array.isArray(a) && typeof a[0] !== 'object') { + if (a.length === 3) { + return new LatLon(a[0], a[1], a[2]); + } + if (a.length === 2) { + return new LatLon(a[0], a[1]); + } + return null; + } + if (a === undefined || a === null) { + return a; + } + if (typeof a === 'object' && 'lat' in a) { + return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt); + } + if (b === undefined) { + return null; + } + return new LatLon(a, b, c); + }; + + // Initialise without requiring new keyword + exports.latLon = noNew; + +/***/ }, +/* 3 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + 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"); } } + + /* + * Point is a helper class for ensuring consistent world positions. + * + * Based on: + * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js + */ + + var Point = (function () { + function Point(x, y, round) { + _classCallCheck(this, Point); + + this.x = round ? Math.round(x) : x; + this.y = round ? Math.round(y) : y; + } + + _createClass(Point, [{ + key: "clone", + value: function clone() { + return new Point(this.x, this.y); + } + + // Non-destructive + }, { + key: "add", + value: function add(point) { + return this.clone()._add(_point(point)); + } + + // Destructive + }, { + key: "_add", + value: function _add(point) { + this.x += point.x; + this.y += point.y; + return this; + } + + // Non-destructive + }, { + key: "subtract", + value: function subtract(point) { + return this.clone()._subtract(_point(point)); + } + + // Destructive + }, { + key: "_subtract", + value: function _subtract(point) { + this.x -= point.x; + this.y -= point.y; + return this; + } + }]); + + return Point; + })(); + + exports["default"] = Point; + + // Accepts (point), ([x, y]) and (x, y, round) + var _point = function _point(x, y, round) { + if (x instanceof Point) { + return x; + } + if (Array.isArray(x)) { + return new Point(x[0], x[1]); + } + if (x === undefined || x === null) { + return x; + } + return new Point(x, y, round); + }; + + // Initialise without requiring new keyword + exports.point = _point; + +/***/ }, +/* 4 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _eventemitter3 = __webpack_require__(5); + + var _eventemitter32 = _interopRequireDefault(_eventemitter3); + + var _lodashAssign = __webpack_require__(6); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _shortid = __webpack_require__(9); + + var _shortid2 = _interopRequireDefault(_shortid); + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var _engineScene = __webpack_require__(19); + + var _engineScene2 = _interopRequireDefault(_engineScene); + + var _vendorCSS3DRenderer = __webpack_require__(20); + + var _vendorCSS2DRenderer = __webpack_require__(21); + + // TODO: Make sure nothing is left behind in the heap after calling destroy() + + // TODO: Need a single move method that handles moving all the various object + // layers so that the DOM layers stay in sync with the 3D layer + + // TODO: Double check that objects within the _object3D Object3D parent are frustum + // culled even if the layer position stays at the default (0,0,0) and the child + // objects are positioned much further away + // + // Or does the layer being at (0,0,0) prevent the child objects from being + // culled because the layer parent is effectively always in view even if the + // child is actually out of camera + + var Layer = (function (_EventEmitter) { + _inherits(Layer, _EventEmitter); + + function Layer(options) { + _classCallCheck(this, Layer); + + _get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this); + + var defaults = { + id: _shortid2['default'].generate(), + output: true, + outputToScene: true + }; + + this._options = (0, _lodashAssign2['default'])({}, defaults, options); + + if (this.isOutput()) { + this._object3D = new _three2['default'].Object3D(); + + this._dom3D = document.createElement('div'); + this._domObject3D = new _vendorCSS3DRenderer.CSS3DObject(this._dom3D); + + this._dom2D = document.createElement('div'); + this._domObject2D = new _vendorCSS2DRenderer.CSS2DObject(this._dom2D); + } + } + + // Add THREE object directly to layer + + _createClass(Layer, [{ + key: 'add', + value: function add(object) { + this._object3D.add(object); + } + + // Remove THREE object from to layer + }, { + key: 'remove', + value: function remove(object) { + this._object3D.remove(object); + } + }, { + key: 'addDOM3D', + value: function addDOM3D(object) { + this._domObject3D.add(object); + } + }, { + key: 'removeDOM3D', + value: function removeDOM3D(object) { + this._domObject3D.remove(object); + } + }, { + key: 'addDOM2D', + value: function addDOM2D(object) { + this._domObject2D.add(object); + } + }, { + key: 'removeDOM2D', + value: function removeDOM2D(object) { + this._domObject2D.remove(object); + } + + // Add layer to world instance and store world reference + }, { + key: 'addTo', + value: function addTo(world) { + return world.addLayer(this); + } + + // Internal method called by World.addLayer to actually add the layer + }, { + key: '_addToWorld', + value: function _addToWorld(world) { + var _this = this; + + this._world = world; + + return new Promise(function (resolve, reject) { + _this._onAdd(world).then(function () { + _this.emit('added'); + resolve(_this); + })['catch'](reject); + }); + } + + // Must return a promise + }, { + key: '_onAdd', + value: function _onAdd(world) { + return Promise.resolve(this); + } + }, { + key: 'getPickingId', + value: function getPickingId() { + if (this._world._engine._picking) { + return this._world._engine._picking.getNextId(); + } + + return false; + } + + // TODO: Tidy this up and don't access so many private properties to work + }, { + key: 'addToPicking', + value: function addToPicking(object) { + if (!this._world._engine._picking) { + return; + } + + this._world._engine._picking.add(object); + } + }, { + key: 'removeFromPicking', + value: function removeFromPicking(object) { + if (!this._world._engine._picking) { + return; + } + + this._world._engine._picking.remove(object); + } + }, { + key: 'isOutput', + value: function isOutput() { + return this._options.output; + } + }, { + key: 'isOutputToScene', + value: function isOutputToScene() { + return this._options.outputToScene; + } + + // TODO: Also hide any attached DOM layers + }, { + key: 'hide', + value: function hide() { + this._object3D.visible = false; + + if (this._pickingMesh) { + this._pickingMesh.visible = false; + } + } + + // TODO: Also show any attached DOM layers + }, { + key: 'show', + value: function show() { + this._object3D.visible = true; + + if (this._pickingMesh) { + this._pickingMesh.visible = true; + } + } + + // Destroys the layer and removes it from the scene and memory + }, { + key: 'destroy', + value: function destroy() { + if (this._object3D && this._object3D.children) { + // Remove everything else in the layer + var child; + for (var i = this._object3D.children.length - 1; i >= 0; i--) { + child = this._object3D.children[i]; + + if (!child) { + continue; + } + + this.remove(child); + + if (child.geometry) { + // Dispose of mesh and materials + child.geometry.dispose(); + child.geometry = null; + } + + if (child.material) { + if (child.material.map) { + child.material.map.dispose(); + child.material.map = null; + } + + child.material.dispose(); + child.material = null; + } + } + } + + if (this._domObject3D && this._domObject3D.children) { + // Remove everything else in the layer + var child; + for (var i = this._domObject3D.children.length - 1; i >= 0; i--) { + child = this._domObject3D.children[i]; + + if (!child) { + continue; + } + + this.removeDOM3D(child); + } + } + + if (this._domObject2D && this._domObject2D.children) { + // Remove everything else in the layer + var child; + for (var i = this._domObject2D.children.length - 1; i >= 0; i--) { + child = this._domObject2D.children[i]; + + if (!child) { + continue; + } + + this.removeDOM2D(child); + } + } + + this._domObject3D = null; + this._domObject2D = null; + + this._world = null; + this._object3D = null; + } + }]); + + return Layer; + })(_eventemitter32['default']); + + exports['default'] = Layer; + + var noNew = function noNew(options) { + return new Layer(options); + }; + + exports.layer = noNew; + +/***/ }, +/* 5 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var has = Object.prototype.hasOwnProperty; + + // + // We store our EE objects in a plain object whose properties are event names. + // If `Object.create(null)` is not supported we prefix the event names with a + // `~` to make sure that the built-in object properties are not overridden or + // used as an attack vector. + // We also assume that `Object.create(null)` is available when the event name + // is an ES6 Symbol. + // + var prefix = typeof Object.create !== 'function' ? '~' : false; + + /** + * Representation of a single EventEmitter function. + * + * @param {Function} fn Event handler to be called. + * @param {Mixed} context Context for function execution. + * @param {Boolean} [once=false] Only emit once + * @api private + */ + function EE(fn, context, once) { + this.fn = fn; + this.context = context; + this.once = once || false; + } + + /** + * Minimal EventEmitter interface that is molded against the Node.js + * EventEmitter interface. + * + * @constructor + * @api public + */ + function EventEmitter() { /* Nothing to set */ } + + /** + * Hold the assigned EventEmitters by name. + * + * @type {Object} + * @private + */ + EventEmitter.prototype._events = undefined; + + /** + * Return an array listing the events for which the emitter has registered + * listeners. + * + * @returns {Array} + * @api public + */ + EventEmitter.prototype.eventNames = function eventNames() { + var events = this._events + , names = [] + , name; + + if (!events) return names; + + for (name in events) { + if (has.call(events, name)) names.push(prefix ? name.slice(1) : name); + } + + if (Object.getOwnPropertySymbols) { + return names.concat(Object.getOwnPropertySymbols(events)); + } + + return names; + }; + + /** + * Return a list of assigned event listeners. + * + * @param {String} event The events that should be listed. + * @param {Boolean} exists We only need to know if there are listeners. + * @returns {Array|Boolean} + * @api public + */ + EventEmitter.prototype.listeners = function listeners(event, exists) { + var evt = prefix ? prefix + event : event + , available = this._events && this._events[evt]; + + if (exists) return !!available; + if (!available) return []; + if (available.fn) return [available.fn]; + + for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) { + ee[i] = available[i].fn; + } + + return ee; + }; + + /** + * Emit an event to all registered event listeners. + * + * @param {String} event The name of the event. + * @returns {Boolean} Indication if we've emitted an event. + * @api public + */ + EventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) { + var evt = prefix ? prefix + event : event; + + if (!this._events || !this._events[evt]) return false; + + var listeners = this._events[evt] + , len = arguments.length + , args + , i; + + if ('function' === typeof listeners.fn) { + if (listeners.once) this.removeListener(event, listeners.fn, undefined, true); + + switch (len) { + case 1: return listeners.fn.call(listeners.context), true; + case 2: return listeners.fn.call(listeners.context, a1), true; + case 3: return listeners.fn.call(listeners.context, a1, a2), true; + case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true; + case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true; + case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true; + } + + for (i = 1, args = new Array(len -1); i < len; i++) { + args[i - 1] = arguments[i]; + } + + listeners.fn.apply(listeners.context, args); + } else { + var length = listeners.length + , j; + + for (i = 0; i < length; i++) { + if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true); + + switch (len) { + case 1: listeners[i].fn.call(listeners[i].context); break; + case 2: listeners[i].fn.call(listeners[i].context, a1); break; + case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break; + default: + if (!args) for (j = 1, args = new Array(len -1); j < len; j++) { + args[j - 1] = arguments[j]; + } + + listeners[i].fn.apply(listeners[i].context, args); + } + } + } + + return true; + }; + + /** + * Register a new EventListener for the given event. + * + * @param {String} event Name of the event. + * @param {Function} fn Callback function. + * @param {Mixed} [context=this] The context of the function. + * @api public + */ + EventEmitter.prototype.on = function on(event, fn, context) { + var listener = new EE(fn, context || this) + , evt = prefix ? prefix + event : event; + + if (!this._events) this._events = prefix ? {} : Object.create(null); + if (!this._events[evt]) this._events[evt] = listener; + else { + if (!this._events[evt].fn) this._events[evt].push(listener); + else this._events[evt] = [ + this._events[evt], listener + ]; + } + + return this; + }; + + /** + * Add an EventListener that's only called once. + * + * @param {String} event Name of the event. + * @param {Function} fn Callback function. + * @param {Mixed} [context=this] The context of the function. + * @api public + */ + EventEmitter.prototype.once = function once(event, fn, context) { + var listener = new EE(fn, context || this, true) + , evt = prefix ? prefix + event : event; + + if (!this._events) this._events = prefix ? {} : Object.create(null); + if (!this._events[evt]) this._events[evt] = listener; + else { + if (!this._events[evt].fn) this._events[evt].push(listener); + else this._events[evt] = [ + this._events[evt], listener + ]; + } + + return this; + }; + + /** + * Remove event listeners. + * + * @param {String} event The event we want to remove. + * @param {Function} fn The listener that we need to find. + * @param {Mixed} context Only remove listeners matching this context. + * @param {Boolean} once Only remove once listeners. + * @api public + */ + EventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) { + var evt = prefix ? prefix + event : event; + + if (!this._events || !this._events[evt]) return this; + + var listeners = this._events[evt] + , events = []; + + if (fn) { + if (listeners.fn) { + if ( + listeners.fn !== fn + || (once && !listeners.once) + || (context && listeners.context !== context) + ) { + events.push(listeners); + } + } else { + for (var i = 0, length = listeners.length; i < length; i++) { + if ( + listeners[i].fn !== fn + || (once && !listeners[i].once) + || (context && listeners[i].context !== context) + ) { + events.push(listeners[i]); + } + } + } + } + + // + // Reset the array, or remove it completely if we have no more listeners. + // + if (events.length) { + this._events[evt] = events.length === 1 ? events[0] : events; + } else { + delete this._events[evt]; + } + + return this; + }; + + /** + * Remove all listeners or only the listeners for the specified event. + * + * @param {String} event The event want to remove all listeners for. + * @api public + */ + EventEmitter.prototype.removeAllListeners = function removeAllListeners(event) { + if (!this._events) return this; + + if (event) delete this._events[prefix ? prefix + event : event]; + else this._events = prefix ? {} : Object.create(null); + + return this; + }; + + // + // Alias methods names because people roll like that. + // + EventEmitter.prototype.off = EventEmitter.prototype.removeListener; + EventEmitter.prototype.addListener = EventEmitter.prototype.on; + + // + // This function doesn't apply anymore. + // + EventEmitter.prototype.setMaxListeners = function setMaxListeners() { + return this; + }; + + // + // Expose the prefix. + // + EventEmitter.prefixed = prefix; + + // + // Expose the module. + // + if (true) { + module.exports = EventEmitter; + } + + +/***/ }, +/* 6 */ +/***/ function(module, exports, __webpack_require__) { + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + var keys = __webpack_require__(7), + rest = __webpack_require__(8); + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]'; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto.propertyIsEnumerable; + + /** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */ + var nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf'); + + /** + * Assigns `value` to `key` of `object` if the existing value is not equivalent + * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * for equality comparisons. + * + * @private + * @param {Object} object The object to modify. + * @param {string} key The key of the property to assign. + * @param {*} value The value to assign. + */ + function assignValue(object, key, value) { + var objValue = object[key]; + if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) || + (value === undefined && !(key in object))) { + object[key] = value; + } + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * Copies properties of `source` to `object`. + * + * @private + * @param {Object} source The object to copy properties from. + * @param {Array} props The property identifiers to copy. + * @param {Object} [object={}] The object to copy properties to. + * @param {Function} [customizer] The function to customize copied values. + * @returns {Object} Returns `object`. + */ + function copyObject(source, props, object, customizer) { + object || (object = {}); + + var index = -1, + length = props.length; + + while (++index < length) { + var key = props[index]; + + var newValue = customizer + ? customizer(object[key], source[key], key, object, source) + : source[key]; + + assignValue(object, key, newValue); + } + return object; + } + + /** + * Creates a function like `_.assign`. + * + * @private + * @param {Function} assigner The function to assign values. + * @returns {Function} Returns the new assigner function. + */ + function createAssigner(assigner) { + return rest(function(object, sources) { + var index = -1, + length = sources.length, + customizer = length > 1 ? sources[length - 1] : undefined, + guard = length > 2 ? sources[2] : undefined; + + customizer = (assigner.length > 3 && typeof customizer == 'function') + ? (length--, customizer) + : undefined; + + if (guard && isIterateeCall(sources[0], sources[1], guard)) { + customizer = length < 3 ? undefined : customizer; + length = 1; + } + object = Object(object); + while (++index < length) { + var source = sources[index]; + if (source) { + assigner(object, source, index, customizer); + } + } + return object; + }); + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a + * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects + * Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if the given arguments are from an iteratee call. + * + * @private + * @param {*} value The potential iteratee value argument. + * @param {*} index The potential iteratee index or key argument. + * @param {*} object The potential iteratee object argument. + * @returns {boolean} Returns `true` if the arguments are from an iteratee call, + * else `false`. + */ + function isIterateeCall(value, index, object) { + if (!isObject(object)) { + return false; + } + var type = typeof index; + if (type == 'number' + ? (isArrayLike(object) && isIndex(index, object.length)) + : (type == 'string' && index in object) + ) { + return eq(object[index], value); + } + return false; + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Performs a + * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero) + * comparison between two values to determine if they are equivalent. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to compare. + * @param {*} other The other value to compare. + * @returns {boolean} Returns `true` if the values are equivalent, else `false`. + * @example + * + * var object = { 'user': 'fred' }; + * var other = { 'user': 'fred' }; + * + * _.eq(object, object); + * // => true + * + * _.eq(object, other); + * // => false + * + * _.eq('a', 'a'); + * // => true + * + * _.eq('a', Object('a')); + * // => false + * + * _.eq(NaN, NaN); + * // => true + */ + function eq(value, other) { + return value === other || (value !== value && other !== other); + } + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, + * else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Assigns own enumerable string keyed properties of source objects to the + * destination object. Source objects are applied from left to right. + * Subsequent sources overwrite property assignments of previous sources. + * + * **Note:** This method mutates `object` and is loosely based on + * [`Object.assign`](https://mdn.io/Object/assign). + * + * @static + * @memberOf _ + * @since 0.10.0 + * @category Object + * @param {Object} object The destination object. + * @param {...Object} [sources] The source objects. + * @returns {Object} Returns `object`. + * @see _.assignIn + * @example + * + * function Foo() { + * this.c = 3; + * } + * + * function Bar() { + * this.e = 5; + * } + * + * Foo.prototype.d = 4; + * Bar.prototype.f = 6; + * + * _.assign({ 'a': 1 }, new Foo, new Bar); + * // => { 'a': 1, 'c': 3, 'e': 5 } + */ + var assign = createAssigner(function(object, source) { + if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) { + copyObject(source, keys(source), object); + return; + } + for (var key in source) { + if (hasOwnProperty.call(source, key)) { + assignValue(object, key, source[key]); + } + } + }); + + module.exports = assign; + + +/***/ }, +/* 7 */ +/***/ function(module, exports) { + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as references for various `Number` constants. */ + var MAX_SAFE_INTEGER = 9007199254740991; + + /** `Object#toString` result references. */ + var argsTag = '[object Arguments]', + funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + stringTag = '[object String]'; + + /** Used to detect unsigned integer values. */ + var reIsUint = /^(?:0|[1-9]\d*)$/; + + /** + * The base implementation of `_.times` without support for iteratee shorthands + * or max array length checks. + * + * @private + * @param {number} n The number of times to invoke `iteratee`. + * @param {Function} iteratee The function invoked per iteration. + * @returns {Array} Returns the array of results. + */ + function baseTimes(n, iteratee) { + var index = -1, + result = Array(n); + + while (++index < n) { + result[index] = iteratee(index); + } + return result; + } + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** Used to check objects for own properties. */ + var hasOwnProperty = objectProto.hasOwnProperty; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /** Built-in value references. */ + var propertyIsEnumerable = objectProto.propertyIsEnumerable; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeGetPrototype = Object.getPrototypeOf, + nativeKeys = Object.keys; + + /** + * The base implementation of `_.has` without support for deep paths. + * + * @private + * @param {Object} object The object to query. + * @param {Array|string} key The key to check. + * @returns {boolean} Returns `true` if `key` exists, else `false`. + */ + function baseHas(object, key) { + // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`, + // that are composed entirely of index properties, return `false` for + // `hasOwnProperty` checks of them. + return hasOwnProperty.call(object, key) || + (typeof object == 'object' && key in object && getPrototype(object) === null); + } + + /** + * The base implementation of `_.keys` which doesn't skip the constructor + * property of prototypes or treat sparse arrays as dense. + * + * @private + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + */ + function baseKeys(object) { + return nativeKeys(Object(object)); + } + + /** + * The base implementation of `_.property` without support for deep paths. + * + * @private + * @param {string} key The key of the property to get. + * @returns {Function} Returns the new accessor function. + */ + function baseProperty(key) { + return function(object) { + return object == null ? undefined : object[key]; + }; + } + + /** + * Gets the "length" property value of `object`. + * + * **Note:** This function is used to avoid a + * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects + * Safari on at least iOS 8.1-8.3 ARM64. + * + * @private + * @param {Object} object The object to query. + * @returns {*} Returns the "length" value. + */ + var getLength = baseProperty('length'); + + /** + * Gets the `[[Prototype]]` of `value`. + * + * @private + * @param {*} value The value to query. + * @returns {null|Object} Returns the `[[Prototype]]`. + */ + function getPrototype(value) { + return nativeGetPrototype(Object(value)); + } + + /** + * Creates an array of index keys for `object` values of arrays, + * `arguments` objects, and strings, otherwise `null` is returned. + * + * @private + * @param {Object} object The object to query. + * @returns {Array|null} Returns index keys, else `null`. + */ + function indexKeys(object) { + var length = object ? object.length : undefined; + if (isLength(length) && + (isArray(object) || isString(object) || isArguments(object))) { + return baseTimes(length, String); + } + return null; + } + + /** + * Checks if `value` is a valid array-like index. + * + * @private + * @param {*} value The value to check. + * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index. + * @returns {boolean} Returns `true` if `value` is a valid index, else `false`. + */ + function isIndex(value, length) { + length = length == null ? MAX_SAFE_INTEGER : length; + return !!length && + (typeof value == 'number' || reIsUint.test(value)) && + (value > -1 && value % 1 == 0 && value < length); + } + + /** + * Checks if `value` is likely a prototype object. + * + * @private + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a prototype, else `false`. + */ + function isPrototype(value) { + var Ctor = value && value.constructor, + proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto; + + return value === proto; + } + + /** + * Checks if `value` is likely an `arguments` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isArguments(function() { return arguments; }()); + * // => true + * + * _.isArguments([1, 2, 3]); + * // => false + */ + function isArguments(value) { + // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode. + return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') && + (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag); + } + + /** + * Checks if `value` is classified as an `Array` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @type {Function} + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isArray([1, 2, 3]); + * // => true + * + * _.isArray(document.body.children); + * // => false + * + * _.isArray('abc'); + * // => false + * + * _.isArray(_.noop); + * // => false + */ + var isArray = Array.isArray; + + /** + * Checks if `value` is array-like. A value is considered array-like if it's + * not a function and has a `value.length` that's an integer greater than or + * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is array-like, else `false`. + * @example + * + * _.isArrayLike([1, 2, 3]); + * // => true + * + * _.isArrayLike(document.body.children); + * // => true + * + * _.isArrayLike('abc'); + * // => true + * + * _.isArrayLike(_.noop); + * // => false + */ + function isArrayLike(value) { + return value != null && isLength(getLength(value)) && !isFunction(value); + } + + /** + * This method is like `_.isArrayLike` except that it also checks if `value` + * is an object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an array-like object, + * else `false`. + * @example + * + * _.isArrayLikeObject([1, 2, 3]); + * // => true + * + * _.isArrayLikeObject(document.body.children); + * // => true + * + * _.isArrayLikeObject('abc'); + * // => false + * + * _.isArrayLikeObject(_.noop); + * // => false + */ + function isArrayLikeObject(value) { + return isObjectLike(value) && isArrayLike(value); + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is a valid array-like length. + * + * **Note:** This function is loosely based on + * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is a valid length, + * else `false`. + * @example + * + * _.isLength(3); + * // => true + * + * _.isLength(Number.MIN_VALUE); + * // => false + * + * _.isLength(Infinity); + * // => false + * + * _.isLength('3'); + * // => false + */ + function isLength(value) { + return typeof value == 'number' && + value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `String` primitive or object. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isString('abc'); + * // => true + * + * _.isString(1); + * // => false + */ + function isString(value) { + return typeof value == 'string' || + (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag); + } + + /** + * Creates an array of the own enumerable property names of `object`. + * + * **Note:** Non-object values are coerced to objects. See the + * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys) + * for more details. + * + * @static + * @since 0.1.0 + * @memberOf _ + * @category Object + * @param {Object} object The object to query. + * @returns {Array} Returns the array of property names. + * @example + * + * function Foo() { + * this.a = 1; + * this.b = 2; + * } + * + * Foo.prototype.c = 3; + * + * _.keys(new Foo); + * // => ['a', 'b'] (iteration order is not guaranteed) + * + * _.keys('hi'); + * // => ['0', '1'] + */ + function keys(object) { + var isProto = isPrototype(object); + if (!(isProto || isArrayLike(object))) { + return baseKeys(object); + } + var indexes = indexKeys(object), + skipIndexes = !!indexes, + result = indexes || [], + length = result.length; + + for (var key in object) { + if (baseHas(object, key) && + !(skipIndexes && (key == 'length' || isIndex(key, length))) && + !(isProto && key == 'constructor')) { + result.push(key); + } + } + return result; + } + + module.exports = keys; + + +/***/ }, +/* 8 */ +/***/ function(module, exports) { + + /** + * lodash (Custom Build) + * Build: `lodash modularize exports="npm" -o ./` + * Copyright jQuery Foundation and other contributors + * Released under MIT license + * Based on Underscore.js 1.8.3 + * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors + */ + + /** Used as the `TypeError` message for "Functions" methods. */ + var FUNC_ERROR_TEXT = 'Expected a function'; + + /** Used as references for various `Number` constants. */ + var INFINITY = 1 / 0, + MAX_INTEGER = 1.7976931348623157e+308, + NAN = 0 / 0; + + /** `Object#toString` result references. */ + var funcTag = '[object Function]', + genTag = '[object GeneratorFunction]', + symbolTag = '[object Symbol]'; + + /** Used to match leading and trailing whitespace. */ + var reTrim = /^\s+|\s+$/g; + + /** Used to detect bad signed hexadecimal string values. */ + var reIsBadHex = /^[-+]0x[0-9a-f]+$/i; + + /** Used to detect binary string values. */ + var reIsBinary = /^0b[01]+$/i; + + /** Used to detect octal string values. */ + var reIsOctal = /^0o[0-7]+$/i; + + /** Built-in method references without a dependency on `root`. */ + var freeParseInt = parseInt; + + /** + * A faster alternative to `Function#apply`, this function invokes `func` + * with the `this` binding of `thisArg` and the arguments of `args`. + * + * @private + * @param {Function} func The function to invoke. + * @param {*} thisArg The `this` binding of `func`. + * @param {Array} args The arguments to invoke `func` with. + * @returns {*} Returns the result of `func`. + */ + function apply(func, thisArg, args) { + var length = args.length; + switch (length) { + case 0: return func.call(thisArg); + case 1: return func.call(thisArg, args[0]); + case 2: return func.call(thisArg, args[0], args[1]); + case 3: return func.call(thisArg, args[0], args[1], args[2]); + } + return func.apply(thisArg, args); + } + + /** Used for built-in method references. */ + var objectProto = Object.prototype; + + /** + * Used to resolve the + * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring) + * of values. + */ + var objectToString = objectProto.toString; + + /* Built-in method references for those with the same name as other `lodash` methods. */ + var nativeMax = Math.max; + + /** + * Creates a function that invokes `func` with the `this` binding of the + * created function and arguments from `start` and beyond provided as + * an array. + * + * **Note:** This method is based on the + * [rest parameter](https://mdn.io/rest_parameters). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Function + * @param {Function} func The function to apply a rest parameter to. + * @param {number} [start=func.length-1] The start position of the rest parameter. + * @returns {Function} Returns the new function. + * @example + * + * var say = _.rest(function(what, names) { + * return what + ' ' + _.initial(names).join(', ') + + * (_.size(names) > 1 ? ', & ' : '') + _.last(names); + * }); + * + * say('hello', 'fred', 'barney', 'pebbles'); + * // => 'hello fred, barney, & pebbles' + */ + function rest(func, start) { + if (typeof func != 'function') { + throw new TypeError(FUNC_ERROR_TEXT); + } + start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0); + return function() { + var args = arguments, + index = -1, + length = nativeMax(args.length - start, 0), + array = Array(length); + + while (++index < length) { + array[index] = args[start + index]; + } + switch (start) { + case 0: return func.call(this, array); + case 1: return func.call(this, args[0], array); + case 2: return func.call(this, args[0], args[1], array); + } + var otherArgs = Array(start + 1); + index = -1; + while (++index < start) { + otherArgs[index] = args[index]; + } + otherArgs[start] = array; + return apply(func, this, otherArgs); + }; + } + + /** + * Checks if `value` is classified as a `Function` object. + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isFunction(_); + * // => true + * + * _.isFunction(/abc/); + * // => false + */ + function isFunction(value) { + // The use of `Object#toString` avoids issues with the `typeof` operator + // in Safari 8 which returns 'object' for typed array and weak map constructors, + // and PhantomJS 1.9 which returns 'function' for `NodeList` instances. + var tag = isObject(value) ? objectToString.call(value) : ''; + return tag == funcTag || tag == genTag; + } + + /** + * Checks if `value` is the + * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types) + * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`) + * + * @static + * @memberOf _ + * @since 0.1.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is an object, else `false`. + * @example + * + * _.isObject({}); + * // => true + * + * _.isObject([1, 2, 3]); + * // => true + * + * _.isObject(_.noop); + * // => true + * + * _.isObject(null); + * // => false + */ + function isObject(value) { + var type = typeof value; + return !!value && (type == 'object' || type == 'function'); + } + + /** + * Checks if `value` is object-like. A value is object-like if it's not `null` + * and has a `typeof` result of "object". + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is object-like, else `false`. + * @example + * + * _.isObjectLike({}); + * // => true + * + * _.isObjectLike([1, 2, 3]); + * // => true + * + * _.isObjectLike(_.noop); + * // => false + * + * _.isObjectLike(null); + * // => false + */ + function isObjectLike(value) { + return !!value && typeof value == 'object'; + } + + /** + * Checks if `value` is classified as a `Symbol` primitive or object. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to check. + * @returns {boolean} Returns `true` if `value` is correctly classified, + * else `false`. + * @example + * + * _.isSymbol(Symbol.iterator); + * // => true + * + * _.isSymbol('abc'); + * // => false + */ + function isSymbol(value) { + return typeof value == 'symbol' || + (isObjectLike(value) && objectToString.call(value) == symbolTag); + } + + /** + * Converts `value` to a finite number. + * + * @static + * @memberOf _ + * @since 4.12.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted number. + * @example + * + * _.toFinite(3.2); + * // => 3.2 + * + * _.toFinite(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toFinite(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toFinite('3.2'); + * // => 3.2 + */ + function toFinite(value) { + if (!value) { + return value === 0 ? value : 0; + } + value = toNumber(value); + if (value === INFINITY || value === -INFINITY) { + var sign = (value < 0 ? -1 : 1); + return sign * MAX_INTEGER; + } + return value === value ? value : 0; + } + + /** + * Converts `value` to an integer. + * + * **Note:** This function is loosely based on + * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger). + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to convert. + * @returns {number} Returns the converted integer. + * @example + * + * _.toInteger(3.2); + * // => 3 + * + * _.toInteger(Number.MIN_VALUE); + * // => 0 + * + * _.toInteger(Infinity); + * // => 1.7976931348623157e+308 + * + * _.toInteger('3.2'); + * // => 3 + */ + function toInteger(value) { + var result = toFinite(value), + remainder = result % 1; + + return result === result ? (remainder ? result - remainder : result) : 0; + } + + /** + * Converts `value` to a number. + * + * @static + * @memberOf _ + * @since 4.0.0 + * @category Lang + * @param {*} value The value to process. + * @returns {number} Returns the number. + * @example + * + * _.toNumber(3.2); + * // => 3.2 + * + * _.toNumber(Number.MIN_VALUE); + * // => 5e-324 + * + * _.toNumber(Infinity); + * // => Infinity + * + * _.toNumber('3.2'); + * // => 3.2 + */ + function toNumber(value) { + if (typeof value == 'number') { + return value; + } + if (isSymbol(value)) { + return NAN; + } + if (isObject(value)) { + var other = isFunction(value.valueOf) ? value.valueOf() : value; + value = isObject(other) ? (other + '') : other; + } + if (typeof value != 'string') { + return value === 0 ? value : +value; + } + value = value.replace(reTrim, ''); + var isBinary = reIsBinary.test(value); + return (isBinary || reIsOctal.test(value)) + ? freeParseInt(value.slice(2), isBinary ? 2 : 8) + : (reIsBadHex.test(value) ? NAN : +value); + } + + module.exports = rest; + + +/***/ }, +/* 9 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + module.exports = __webpack_require__(10); + + +/***/ }, +/* 10 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var alphabet = __webpack_require__(11); + var encode = __webpack_require__(13); + var decode = __webpack_require__(15); + var isValid = __webpack_require__(16); + + // Ignore all milliseconds before a certain time to reduce the size of the date entropy without sacrificing uniqueness. + // This number should be updated every year or so to keep the generated id short. + // To regenerate `new Date() - 0` and bump the version. Always bump the version! + var REDUCE_TIME = 1459707606518; + + // don't change unless we change the algos or REDUCE_TIME + // must be an integer and less than 16 + var version = 6; + + // if you are using cluster or multiple servers use this to make each instance + // has a unique value for worker + // Note: I don't know if this is automatically set when using third + // party cluster solutions such as pm2. + var clusterWorkerId = __webpack_require__(17) || 0; + + // Counter is used when shortid is called multiple times in one second. + var counter; + + // Remember the last time shortid was called in case counter is needed. + var previousSeconds; + + /** + * Generate unique id + * Returns string id + */ + function generate() { + + var str = ''; + + var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001); + + if (seconds === previousSeconds) { + counter++; + } else { + counter = 0; + previousSeconds = seconds; + } + + str = str + encode(alphabet.lookup, version); + str = str + encode(alphabet.lookup, clusterWorkerId); + if (counter > 0) { + str = str + encode(alphabet.lookup, counter); + } + str = str + encode(alphabet.lookup, seconds); + + return str; + } + + + /** + * Set the seed. + * Highly recommended if you don't want people to try to figure out your id schema. + * exposed as shortid.seed(int) + * @param seed Integer value to seed the random alphabet. ALWAYS USE THE SAME SEED or you might get overlaps. + */ + function seed(seedValue) { + alphabet.seed(seedValue); + return module.exports; + } + + /** + * Set the cluster worker or machine id + * exposed as shortid.worker(int) + * @param workerId worker must be positive integer. Number less than 16 is recommended. + * returns shortid module so it can be chained. + */ + function worker(workerId) { + clusterWorkerId = workerId; + return module.exports; + } + + /** + * + * sets new characters to use in the alphabet + * returns the shuffled alphabet + */ + function characters(newCharacters) { + if (newCharacters !== undefined) { + alphabet.characters(newCharacters); + } + + return alphabet.shuffled(); + } + + + // Export all other functions as properties of the generate function + module.exports = generate; + module.exports.generate = generate; + module.exports.seed = seed; + module.exports.worker = worker; + module.exports.characters = characters; + module.exports.decode = decode; + module.exports.isValid = isValid; + + +/***/ }, +/* 11 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var randomFromSeed = __webpack_require__(12); + + var ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-'; + var alphabet; + var previousSeed; + + var shuffled; + + function reset() { + shuffled = false; + } + + function setCharacters(_alphabet_) { + if (!_alphabet_) { + if (alphabet !== ORIGINAL) { + alphabet = ORIGINAL; + reset(); + } + return; + } + + if (_alphabet_ === alphabet) { + return; + } + + if (_alphabet_.length !== ORIGINAL.length) { + throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_); + } + + var unique = _alphabet_.split('').filter(function(item, ind, arr){ + return ind !== arr.lastIndexOf(item); + }); + + if (unique.length) { + throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', ')); + } + + alphabet = _alphabet_; + reset(); + } + + function characters(_alphabet_) { + setCharacters(_alphabet_); + return alphabet; + } + + function setSeed(seed) { + randomFromSeed.seed(seed); + if (previousSeed !== seed) { + reset(); + previousSeed = seed; + } + } + + function shuffle() { + if (!alphabet) { + setCharacters(ORIGINAL); + } + + var sourceArray = alphabet.split(''); + var targetArray = []; + var r = randomFromSeed.nextValue(); + var characterIndex; + + while (sourceArray.length > 0) { + r = randomFromSeed.nextValue(); + characterIndex = Math.floor(r * sourceArray.length); + targetArray.push(sourceArray.splice(characterIndex, 1)[0]); + } + return targetArray.join(''); + } + + function getShuffled() { + if (shuffled) { + return shuffled; + } + shuffled = shuffle(); + return shuffled; + } + + /** + * lookup shuffled letter + * @param index + * @returns {string} + */ + function lookup(index) { + var alphabetShuffled = getShuffled(); + return alphabetShuffled[index]; + } + + module.exports = { + characters: characters, + seed: setSeed, + lookup: lookup, + shuffled: getShuffled + }; + + +/***/ }, +/* 12 */ +/***/ function(module, exports) { + + 'use strict'; + + // Found this seed-based random generator somewhere + // Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu) + + var seed = 1; + + /** + * return a random number based on a seed + * @param seed + * @returns {number} + */ + function getNextValue() { + seed = (seed * 9301 + 49297) % 233280; + return seed/(233280.0); + } + + function setSeed(_seed_) { + seed = _seed_; + } + + module.exports = { + nextValue: getNextValue, + seed: setSeed + }; + + +/***/ }, +/* 13 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var randomByte = __webpack_require__(14); + + function encode(lookup, number) { + var loopCounter = 0; + var done; + + var str = ''; + + while (!done) { + str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() ); + done = number < (Math.pow(16, loopCounter + 1 ) ); + loopCounter++; + } + return str; + } + + module.exports = encode; + + +/***/ }, +/* 14 */ +/***/ function(module, exports) { + + 'use strict'; + + var crypto = typeof window === 'object' && (window.crypto || window.msCrypto); // IE 11 uses window.msCrypto + + function randomByte() { + if (!crypto || !crypto.getRandomValues) { + return Math.floor(Math.random() * 256) & 0x30; + } + var dest = new Uint8Array(1); + crypto.getRandomValues(dest); + return dest[0] & 0x30; + } + + module.exports = randomByte; + + +/***/ }, +/* 15 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + var alphabet = __webpack_require__(11); + + /** + * Decode the id to get the version and worker + * Mainly for debugging and testing. + * @param id - the shortid-generated id. + */ + function decode(id) { + var characters = alphabet.shuffled(); + return { + version: characters.indexOf(id.substr(0, 1)) & 0x0f, + worker: characters.indexOf(id.substr(1, 1)) & 0x0f + }; + } + + module.exports = decode; + + +/***/ }, +/* 16 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + var alphabet = __webpack_require__(11); + + function isShortId(id) { + if (!id || typeof id !== 'string' || id.length < 6 ) { + return false; + } + + var characters = alphabet.characters(); + var len = id.length; + for(var i = 0; i < len;i++) { + if (characters.indexOf(id[i]) === -1) { + return false; + } + } + return true; + } + + module.exports = isShortId; + + +/***/ }, +/* 17 */ +/***/ function(module, exports) { + + 'use strict'; + + module.exports = 0; + + +/***/ }, +/* 18 */ +/***/ function(module, exports) { + + module.exports = __WEBPACK_EXTERNAL_MODULE_18__; + +/***/ }, +/* 19 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + // This can be imported from anywhere and will still reference the same scene, + // though there is a helper reference in Engine.scene + + exports['default'] = (function () { + var scene = new _three2['default'].Scene(); + + // TODO: Re-enable when this works with the skybox + // scene.fog = new THREE.Fog(0xffffff, 1, 15000); + return scene; + })(); + + module.exports = exports['default']; + +/***/ }, +/* 20 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // jscs:disable + /* eslint-disable */ + + /** + * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs + * @author mrdoob / http://mrdoob.com/ + */ + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var CSS3DObject = function CSS3DObject(element) { + + _three2['default'].Object3D.call(this); + + this.element = element; + this.element.style.position = 'absolute'; + + this.addEventListener('removed', function (event) { + + if (this.element.parentNode !== null) { + + this.element.parentNode.removeChild(this.element); + } + }); + }; + + CSS3DObject.prototype = Object.create(_three2['default'].Object3D.prototype); + CSS3DObject.prototype.constructor = CSS3DObject; + + var CSS3DSprite = function CSS3DSprite(element) { + + CSS3DObject.call(this, element); + }; + + CSS3DSprite.prototype = Object.create(CSS3DObject.prototype); + CSS3DSprite.prototype.constructor = CSS3DSprite; + + // + + var CSS3DRenderer = function CSS3DRenderer() { + + console.log('THREE.CSS3DRenderer', _three2['default'].REVISION); + + var _width, _height; + var _widthHalf, _heightHalf; + + var matrix = new _three2['default'].Matrix4(); + + var cache = { + camera: { fov: 0, style: '' }, + objects: {} + }; + + var domElement = document.createElement('div'); + domElement.style.overflow = 'hidden'; + + domElement.style.WebkitTransformStyle = 'preserve-3d'; + domElement.style.MozTransformStyle = 'preserve-3d'; + domElement.style.oTransformStyle = 'preserve-3d'; + domElement.style.transformStyle = 'preserve-3d'; + + this.domElement = domElement; + + var cameraElement = document.createElement('div'); + + cameraElement.style.WebkitTransformStyle = 'preserve-3d'; + cameraElement.style.MozTransformStyle = 'preserve-3d'; + cameraElement.style.oTransformStyle = 'preserve-3d'; + cameraElement.style.transformStyle = 'preserve-3d'; + + domElement.appendChild(cameraElement); + + this.setClearColor = function () {}; + + this.getSize = function () { + + return { + width: _width, + height: _height + }; + }; + + this.setSize = function (width, height) { + + _width = width; + _height = height; + + _widthHalf = _width / 2; + _heightHalf = _height / 2; + + domElement.style.width = width + 'px'; + domElement.style.height = height + 'px'; + + cameraElement.style.width = width + 'px'; + cameraElement.style.height = height + 'px'; + }; + + var epsilon = function epsilon(value) { + + return Math.abs(value) < Number.EPSILON ? 0 : value; + }; + + var getCameraCSSMatrix = function getCameraCSSMatrix(matrix) { + + var elements = matrix.elements; + + return 'matrix3d(' + epsilon(elements[0]) + ',' + epsilon(-elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(elements[6]) + ',' + epsilon(elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(-elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(-elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')'; + }; + + var getObjectCSSMatrix = function getObjectCSSMatrix(matrix) { + + var elements = matrix.elements; + + return 'translate3d(-50%,-50%,0) matrix3d(' + epsilon(elements[0]) + ',' + epsilon(elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(-elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(-elements[6]) + ',' + epsilon(-elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')'; + }; + + var renderObject = function renderObject(object, camera) { + + if (object instanceof CSS3DObject) { + + var style; + + if (object instanceof CSS3DSprite) { + + // http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/ + + matrix.copy(camera.matrixWorldInverse); + matrix.transpose(); + matrix.copyPosition(object.matrixWorld); + matrix.scale(object.scale); + + matrix.elements[3] = 0; + matrix.elements[7] = 0; + matrix.elements[11] = 0; + matrix.elements[15] = 1; + + style = getObjectCSSMatrix(matrix); + } else { + + style = getObjectCSSMatrix(object.matrixWorld); + } + + var element = object.element; + var cachedStyle = cache.objects[object.id]; + + if (cachedStyle === undefined || cachedStyle !== style) { + + element.style.WebkitTransform = style; + element.style.MozTransform = style; + element.style.oTransform = style; + element.style.transform = style; + + cache.objects[object.id] = style; + } + + if (element.parentNode !== cameraElement) { + + cameraElement.appendChild(element); + } + } + + for (var i = 0, l = object.children.length; i < l; i++) { + + renderObject(object.children[i], camera); + } + }; + + this.render = function (scene, camera) { + + var fov = 0.5 / Math.tan(_three2['default'].Math.degToRad(camera.fov * 0.5)) * _height; + + if (cache.camera.fov !== fov) { + + domElement.style.WebkitPerspective = fov + 'px'; + domElement.style.MozPerspective = fov + 'px'; + domElement.style.oPerspective = fov + 'px'; + domElement.style.perspective = fov + 'px'; + + cache.camera.fov = fov; + } + + scene.updateMatrixWorld(); + + if (camera.parent === null) camera.updateMatrixWorld(); + + camera.matrixWorldInverse.getInverse(camera.matrixWorld); + + var style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix(camera.matrixWorldInverse) + ' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)'; + + if (cache.camera.style !== style) { + + cameraElement.style.WebkitTransform = style; + cameraElement.style.MozTransform = style; + cameraElement.style.oTransform = style; + cameraElement.style.transform = style; + + cache.camera.style = style; + } + + renderObject(scene, camera); + }; + }; + + exports.CSS3DObject = CSS3DObject; + exports.CSS3DSprite = CSS3DSprite; + exports.CSS3DRenderer = CSS3DRenderer; + + _three2['default'].CSS3DObject = CSS3DObject; + _three2['default'].CSS3DSprite = CSS3DSprite; + _three2['default'].CSS3DRenderer = CSS3DRenderer; + +/***/ }, +/* 21 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // jscs:disable + /* eslint-disable */ + + /** + * @author mrdoob / http://mrdoob.com/ + */ + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var CSS2DObject = function CSS2DObject(element) { + + _three2['default'].Object3D.call(this); + + this.element = element; + this.element.style.position = 'absolute'; + + this.addEventListener('removed', function (event) { + + if (this.element.parentNode !== null) { + + this.element.parentNode.removeChild(this.element); + } + }); + }; + + CSS2DObject.prototype = Object.create(_three2['default'].Object3D.prototype); + CSS2DObject.prototype.constructor = CSS2DObject; + + // + + var CSS2DRenderer = function CSS2DRenderer() { + + console.log('THREE.CSS2DRenderer', _three2['default'].REVISION); + + var _width, _height; + var _widthHalf, _heightHalf; + + var vector = new _three2['default'].Vector3(); + var viewMatrix = new _three2['default'].Matrix4(); + var viewProjectionMatrix = new _three2['default'].Matrix4(); + + var frustum = new _three2['default'].Frustum(); + + var domElement = document.createElement('div'); + domElement.style.overflow = 'hidden'; + + this.domElement = domElement; + + this.setSize = function (width, height) { + + _width = width; + _height = height; + + _widthHalf = _width / 2; + _heightHalf = _height / 2; + + domElement.style.width = width + 'px'; + domElement.style.height = height + 'px'; + }; + + var renderObject = function renderObject(object, camera) { + + if (object instanceof CSS2DObject) { + + vector.setFromMatrixPosition(object.matrixWorld); + vector.applyProjection(viewProjectionMatrix); + + var element = object.element; + var style = 'translate(-50%,-50%) translate(' + (vector.x * _widthHalf + _widthHalf) + 'px,' + (-vector.y * _heightHalf + _heightHalf) + 'px)'; + + element.style.WebkitTransform = style; + element.style.MozTransform = style; + element.style.oTransform = style; + element.style.transform = style; + + if (element.parentNode !== domElement) { + + domElement.appendChild(element); + } + + // Hide if outside view frustum + if (!frustum.containsPoint(object.position)) { + element.style.display = 'none'; + } else { + element.style.display = 'block'; + } + } + + for (var i = 0, l = object.children.length; i < l; i++) { + + renderObject(object.children[i], camera); + } + }; + + this.render = function (scene, camera) { + + scene.updateMatrixWorld(); + + if (camera.parent === null) camera.updateMatrixWorld(); + + camera.matrixWorldInverse.getInverse(camera.matrixWorld); + + viewMatrix.copy(camera.matrixWorldInverse.getInverse(camera.matrixWorld)); + viewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, viewMatrix); + + frustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse)); + + renderObject(scene, camera); + }; + }; + + exports.CSS2DObject = CSS2DObject; + exports.CSS2DRenderer = CSS2DRenderer; + + _three2['default'].CSS2DObject = CSS2DObject; + _three2['default'].CSS2DRenderer = CSS2DRenderer; + +/***/ }, +/* 22 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _Layer2 = __webpack_require__(4); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(6); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _reqwest = __webpack_require__(23); + + var _reqwest2 = _interopRequireDefault(_reqwest); + + var _utilGeoJSON = __webpack_require__(25); + + var _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON); + + var _utilWorker = __webpack_require__(31); + + var _utilWorker2 = _interopRequireDefault(_utilWorker); + + var _utilBuffer = __webpack_require__(34); + + var _utilBuffer2 = _interopRequireDefault(_utilBuffer); + + var _utilStringify = __webpack_require__(35); + + var _utilStringify2 = _interopRequireDefault(_utilStringify); + + var _geometryPolygonLayer = __webpack_require__(36); + + var _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer); + + var _geometryPolylineLayer = __webpack_require__(39); + + var _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer); + + var _geometryPointLayer = __webpack_require__(40); + + var _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer); + + var _geoLatLon = __webpack_require__(2); + + var _geoPoint = __webpack_require__(3); + + var _geoGeo = __webpack_require__(1); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + + var _enginePickingMaterial = __webpack_require__(37); + + var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); + + // TODO: Allow filter method to be run inside a worker to improve performance + // TODO: Allow onEachFeature method to be run inside a worker to improve performance + + var GeoJSONWorkerLayer = (function (_Layer) { + _inherits(GeoJSONWorkerLayer, _Layer); + + function GeoJSONWorkerLayer(geojson, options) { + _classCallCheck(this, GeoJSONWorkerLayer); + + var defaults = { + topojson: false, + style: _utilGeoJSON2['default'].defaultStyle, + onEachFeature: null, + onEachFeatureWorker: null, + onAddAttributes: null, + interactive: false, + pointGeometry: null, + onClick: null, + headers: {} + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + if (typeof options.style === 'object') { + _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style); + } + + _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'constructor', this).call(this, _options); + + this._aborted = false; + this._geojson = geojson; + } + + _createClass(GeoJSONWorkerLayer, [{ + key: '_onAdd', + value: function _onAdd(world) { + if (this._options.interactive) { + // Worker layer always controls output to add a picking mesh + this._pickingMesh = new THREE.Object3D(); + } + + // Process GeoJSON + return this._process(this._geojson); + } + + // Use workers to request and process GeoJSON, returning data structure + // containing geometry and any supplementary data for output + }, { + key: '_process', + value: function _process(_geojson) { + var _this = this; + + return new Promise(function (resolve, reject) { + var style = _this._options.style; + + // TODO: Convert to buffer and use transferrable objects + if (typeof _this._options.style === 'function') { + style = _utilStringify2['default'].functionToString(_this._options.style); + } + + var pointGeometry = _this._options.pointGeometry; + + // TODO: Convert to buffer and use transferrable objects + if (typeof _this._options.pointGeometry === 'function') { + pointGeometry = _utilStringify2['default'].functionToString(_this._options.pointGeometry); + } + + var geojson = _geojson; + var transferrables = []; + + if (typeof geojson !== 'string') { + _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(geojson)); + transferrables.push(geojson.buffer); + _this._execWorker(geojson, _this._options.topojson, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () { + resolve(); + })['catch'](reject); + } else if (typeof _this._options.filter === 'function' || typeof _this._options.onEachFeature === 'function') { + GeoJSONWorkerLayer.RequestGeoJSON(geojson).then(function (res) { + // if (this._aborted) { + // resolve(); + // return; + // } + + var fc = _utilGeoJSON2['default'].collectFeatures(res, _this._options.topojson); + var features = fc.features; + + // Run filter, if provided + if (_this._options.filter) { + fc.features = features.filter(_this._options.filter); + } + + if (_this._options.onEachFeature) { + var feature; + for (var i = 0; i < features.length; i++) { + feature = features[i]; + _this._options.onEachFeature(feature); + }; + } + + _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(fc)); + transferrables.push(geojson.buffer); + + _this._execWorker(geojson, false, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () { + resolve(); + })['catch'](reject); + }); + } else { + _this._execWorker(geojson, _this._options.topojson, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () { + resolve(); + })['catch'](reject); + } + }); + } + }, { + key: '_execWorker', + value: function _execWorker(geojson, topojson, headers, originPoint, style, interactive, pointGeometry, transferrables) { + var _this2 = this; + + return new Promise(function (resolve, reject) { + console.time('Worker round trip'); + + _utilWorker2['default'].exec('GeoJSONWorkerLayer.Process', [geojson, topojson, headers, originPoint, style, interactive, pointGeometry], transferrables).then(function (results) { + console.timeEnd('Worker round trip'); + + // if (this._aborted) { + // resolve(); + // return; + // } + + var processPromises = []; + + if (results.polygons) { + processPromises.push(_this2._processPolygonResults(results.polygons)); + } + + if (results.polylines) { + processPromises.push(_this2._processPolylineResults(results.polylines)); + } + + if (results.points) { + processPromises.push(_this2._processPointResults(results.points)); + } + + if (processPromises.length > 0) { + Promise.all(processPromises).then(function () { + resolve(); + })['catch'](reject); + } else { + resolve(); + } + }); + }); + } + + // TODO: Dedupe with polyline method + }, { + key: '_processPolygonResults', + value: function _processPolygonResults(results) { + var _this3 = this; + + return new Promise(function (resolve, reject) { + var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions); + var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals); + var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors); + var splitTops = _utilBuffer2['default'].splitFloat32Array(results.attributes.tops); + + var splitOutlinePositions; + var splitOutlineColors; + + if (results.outlineAttributes) { + splitOutlinePositions = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.positions); + splitOutlineColors = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.colors); + } + + var splitProperties; + if (results.properties) { + splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties); + } + + var flats = results.flats; + + var objects = []; + var outlineObjects = []; + + var obj; + var pickingId; + var pickingIds; + var properties; + + var polygonAttributeLengths = { + positions: 3, + normals: 3, + colors: 3, + tops: 1 + }; + + var polygonOutlineAttributeLengths = { + positions: 3, + colors: 3 + }; + + for (var i = 0; i < splitPositions.length; i++) { + if (splitProperties && splitProperties[i]) { + properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i])); + } else { + properties = {}; + } + + // WORKERS: obj.attributes should actually an array of polygons for + // the feature, though the current logic isn't aware of that + obj = { + attributes: [{ + positions: splitPositions[i], + normals: splitNormals[i], + colors: splitColors[i], + tops: splitTops[i] + }], + properties: properties, + flat: flats[i] + }; + + // WORKERS: If interactive, generate unique ID for each feature, create + // the buffer attributes and set up event listeners + if (_this3._options.interactive) { + pickingId = _this3.getPickingId(); + + pickingIds = new Float32Array(splitPositions[i].length / 3); + pickingIds.fill(pickingId); + + obj.attributes[0].pickingIds = pickingIds; + + polygonAttributeLengths.pickingIds = 1; + + _this3._addPicking(pickingId, properties); + } + + // TODO: Make this specific to polygon attributes + if (typeof _this3._options.onAddAttributes === 'function') { + var customAttributes = _this3._options.onAddAttributes(obj.attributes[0], properties); + var customAttribute; + for (var key in customAttributes) { + customAttribute = customAttributes[key]; + obj.attributes[0][key] = customAttribute.value; + polygonAttributeLengths[key] = customAttribute.length; + } + } + + objects.push(obj); + } + + for (var i = 0; i < splitOutlinePositions.length; i++) { + obj = { + attributes: [{ + positions: splitOutlinePositions[i], + colors: splitOutlineColors[i] + }], + flat: true + }; + + outlineObjects.push(obj); + } + + var polygonAttributes = []; + var polygonOutlineAttributes = []; + + var polygonFlat = true; + + for (var i = 0; i < objects.length; i++) { + obj = objects[i]; + + // TODO: Work out why obj.flat is rarely set to something other than + // true or false. Potentially undefined. + if (polygonFlat && obj.flat === false) { + polygonFlat = false; + } + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + polygonAttributes.push(bufferAttributes); + }; + + for (var i = 0; i < outlineObjects.length; i++) { + obj = outlineObjects[i]; + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + polygonOutlineAttributes.push(bufferAttributes); + }; + + var outputPromises = []; + + var style; + + if (polygonAttributes.length > 0) { + var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes); + + // TODO: Make this work when style is a function per feature + style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + outputPromises.push(_this3._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat)); + } + + if (polygonOutlineAttributes.length > 0) { + var mergedPolygonOutlineAttributes = _utilBuffer2['default'].mergeAttributes(polygonOutlineAttributes); + + style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + if (style.outlineRenderOrder !== undefined) { + style.lineRenderOrder = style.outlineRenderOrder; + } else { + style.lineRenderOrder = style.renderOrder ? style.renderOrder + 1 : 4; + } + + if (style.outlineWidth) { + style.lineWidth = style.outlineWidth; + } + + outputPromises.push(_this3._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true)); + } + + Promise.all(outputPromises).then(function (results) { + var _results = _slicedToArray(results, 2); + + var polygonResult = _results[0]; + var outlineResult = _results[1]; + + if (polygonResult) { + _this3._polygonMesh = polygonResult.mesh; + _this3.add(_this3._polygonMesh); + + if (polygonResult.pickingMesh) { + _this3._pickingMesh.add(polygonResult.pickingMesh); + } + } + + if (outlineResult) { + _this3.add(outlineResult.mesh); + } + + resolve(); + })['catch'](reject); + }); + } + + // TODO: Dedupe with polygon method + }, { + key: '_processPolylineResults', + value: function _processPolylineResults(results) { + var _this4 = this; + + return new Promise(function (resolve, reject) { + var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions); + var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors); + + var splitProperties; + if (results.properties) { + splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties); + } + + var flats = results.flats; + + var objects = []; + var obj; + var pickingId; + var pickingIds; + var properties; + + var polylineAttributeLengths = { + positions: 3, + colors: 3 + }; + + for (var i = 0; i < splitPositions.length; i++) { + if (splitProperties && splitProperties[i]) { + properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i])); + } else { + properties = {}; + } + + // WORKERS: obj.attributes should actually an array of polygons for + // the feature, though the current logic isn't aware of that + obj = { + attributes: [{ + positions: splitPositions[i], + colors: splitColors[i] + }], + properties: properties, + flat: flats[i] + }; + + // WORKERS: If interactive, generate unique ID for each feature, create + // the buffer attributes and set up event listeners + if (_this4._options.interactive) { + pickingId = _this4.getPickingId(); + + pickingIds = new Float32Array(splitPositions[i].length / 3); + pickingIds.fill(pickingId); + + obj.attributes[0].pickingIds = pickingIds; + + polylineAttributeLengths.pickingIds = 1; + + _this4._addPicking(pickingId, properties); + } + + // TODO: Make this specific to polyline attributes + if (typeof _this4._options.onAddAttributes === 'function') { + var customAttributes = _this4._options.onAddAttributes(obj.attributes[0], properties); + var customAttribute; + for (var key in customAttributes) { + customAttribute = customAttributes[key]; + obj.attributes[0][key] = customAttribute.value; + polylineAttributeLengths[key] = customAttribute.length; + } + } + + objects.push(obj); + } + + var polylineAttributes = []; + + var polylineFlat = true; + + for (var i = 0; i < objects.length; i++) { + obj = objects[i]; + + if (polylineFlat && !obj.flat) { + polylineFlat = false; + } + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + polylineAttributes.push(bufferAttributes); + }; + + if (polylineAttributes.length > 0) { + var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes); + + // TODO: Make this work when style is a function per feature + var style = typeof _this4._options.style === 'function' ? _this4._options.style(objects[0]) : _this4._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this4._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then(function (result) { + _this4._polylineMesh = result.mesh; + _this4.add(_this4._polylineMesh); + + if (result.pickingMesh) { + _this4._pickingMesh.add(result.pickingMesh); + } + + resolve(); + })['catch'](reject); + } else { + resolve(); + } + }); + } + }, { + key: '_processPointResults', + value: function _processPointResults(results) { + var _this5 = this; + + return new Promise(function (resolve, reject) { + var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions); + var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals); + var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors); + + var splitProperties; + if (results.properties) { + splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties); + } + + var flats = results.flats; + + var objects = []; + var obj; + var pickingId; + var pickingIds; + var properties; + + var pointAttributeLengths = { + positions: 3, + normals: 3, + colors: 3 + }; + + for (var i = 0; i < splitPositions.length; i++) { + if (splitProperties && splitProperties[i]) { + properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i])); + } else { + properties = {}; + } + + // WORKERS: obj.attributes should actually an array of polygons for + // the feature, though the current logic isn't aware of that + obj = { + attributes: [{ + positions: splitPositions[i], + normals: splitNormals[i], + colors: splitColors[i] + }], + properties: properties, + flat: flats[i] + }; + + // WORKERS: If interactive, generate unique ID for each feature, create + // the buffer attributes and set up event listeners + if (_this5._options.interactive) { + pickingId = _this5.getPickingId(); + + pickingIds = new Float32Array(splitPositions[i].length / 3); + pickingIds.fill(pickingId); + + obj.attributes[0].pickingIds = pickingIds; + + pointAttributeLengths.pickingIds = 1; + + _this5._addPicking(pickingId, properties); + } + + // TODO: Make this specific to polygon attributes + if (typeof _this5._options.onAddAttributes === 'function') { + var customAttributes = _this5._options.onAddAttributes(obj.attributes[0], properties); + var customAttribute; + for (var key in customAttributes) { + customAttribute = customAttributes[key]; + obj.attributes[0][key] = customAttribute.value; + pointAttributeLengths[key] = customAttribute.length; + } + } + + objects.push(obj); + } + + var pointAttributes = []; + + var pointFlat = true; + + for (var i = 0; i < objects.length; i++) { + obj = objects[i]; + + if (pointFlat && !obj.flat) { + pointFlat = false; + } + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + pointAttributes.push(bufferAttributes); + }; + + if (pointAttributes.length > 0) { + var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes); + + // TODO: Make this work when style is a function per feature + var style = typeof _this5._options.style === 'function' ? _this5._options.style(objects[0]) : _this5._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this5._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then(function (result) { + _this5._pointMesh = result.mesh; + _this5.add(_this5._pointMesh); + + if (result.pickingMesh) { + _this5._pickingMesh.add(result.pickingMesh); + } + + resolve(); + })['catch'](reject); + } else { + resolve(); + } + }); + } + + // TODO: At some point this needs to return all the features to the main thread + // so it can generate meshes and output to the scene, as well as perhaps creating + // individual layers / components for each feature to track things like picking + // and properties + // + // TODO: Find a way so the origin point isn't needed to be passed in as it + // feels a bit messy and against the idea of a static Geo class + // + // TODO: Support passing custom geometry for point layers + }, { + key: '_setPolygonMesh', + + // Create and store mesh from buffer attributes + // + // Could make this an abstract method for each geometry layer + value: function _setPolygonMesh(attributes, attributeLengths, style, flat) { + if (!this._world) { + return Promise.reject(); + } + + return _geometryPolygonLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox); + } + }, { + key: '_setPolylineMesh', + value: function _setPolylineMesh(attributes, attributeLengths, style, flat) { + if (!this._world) { + return Promise.reject(); + } + + return _geometryPolylineLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options); + } + }, { + key: '_setPointMesh', + value: function _setPointMesh(attributes, attributeLengths, style, flat) { + if (!this._world) { + return Promise.reject(); + } + + return _geometryPointLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox); + } + + // Set up and re-emit interaction events + }, { + key: '_addPicking', + value: function _addPicking(pickingId, properties) { + var _this6 = this; + + this._world.on('pick-click-' + pickingId, function (pickingId, point2d, point3d, intersects) { + _this6._world.emit('click', _this6, properties, point2d, point3d); + }); + + this._world.on('pick-hover-' + pickingId, function (pickingId, point2d, point3d, intersects) { + _this6._world.emit('hover', _this6, properties, point2d, point3d); + }); + } + + // TODO: Finish cleanup + }, { + key: 'destroy', + value: function destroy() { + // Run common destruction logic from parent + _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'destroy', this).call(this); + } + }], [{ + key: 'Process', + value: function Process(geojson, topojson, headers, originPoint, _style, _properties, _pointGeometry) { + return new Promise(function (resolve, reject) { + GeoJSONWorkerLayer.ProcessGeoJSON(geojson, headers).then(function (res) { + // Collects features into a single FeatureCollection + // + // Also converts TopoJSON to GeoJSON if instructed + var geojson = _utilGeoJSON2['default'].collectFeatures(res, topojson); + + // TODO: Check that GeoJSON is valid / usable + + var features = geojson.features; + + // TODO: Run filter, if provided (must be static) + + var pointScale; + var polygons = []; + var polylines = []; + var points = []; + + // Deserialise style function if provided + if (typeof _style === 'string') { + _style = _utilStringify2['default'].stringToFunction(_style); + } + + // Assume that a style won't be set per feature + var style = _style; + + var pointGeometry; + // Deserialise pointGeometry function if provided + if (typeof _pointGeometry === 'string') { + pointGeometry = _utilStringify2['default'].stringToFunction(_pointGeometry); + } + + var feature; + for (var i = 0; i < features.length; i++) { + feature = features[i]; + + var geometry = feature.geometry; + var coordinates = geometry.coordinates ? geometry.coordinates : null; + + if (!coordinates || !geometry) { + return; + } + + // Get per-feature style object, if provided + if (typeof _style === 'function') { + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _style(feature)); + // console.log(feature, style); + } + + if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') { + coordinates = _geometryPolygonLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates; + + var converted = coordinates.map(function (_coordinates) { + return _coordinates.map(function (ring) { + return ring.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + }); + }); + + var point; + var projected = converted.map(function (_coordinates) { + return _coordinates.map(function (ring) { + return ring.map(function (latlon) { + point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint); + + if (!pointScale) { + pointScale = _geoGeo2['default'].pointScale(latlon); + } + + return point; + }); + }); + }); + + var polygon = { + projected: projected, + options: { + pointScale: pointScale, + style: style + } + }; + + if (_properties) { + polygon.properties = feature.properties; + } + + polygons.push(polygon); + } + + if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') { + coordinates = _geometryPolylineLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates; + + var converted = coordinates.map(function (_coordinates) { + return _coordinates.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + }); + + var point; + var projected = converted.map(function (_coordinates) { + return _coordinates.map(function (latlon) { + point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint); + + if (!pointScale) { + pointScale = _geoGeo2['default'].pointScale(latlon); + } + + return point; + }); + }); + + var polyline = { + projected: projected, + options: { + pointScale: pointScale, + style: style + } + }; + + if (_properties) { + polyline.properties = feature.properties; + } + + polylines.push(polyline); + } + + if (geometry.type === 'Point' || geometry.type === 'MultiPoint') { + coordinates = _geometryPointLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates; + + var converted = coordinates.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + + var point; + var projected = converted.map(function (latlon) { + point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint); + + if (!pointScale) { + pointScale = _geoGeo2['default'].pointScale(latlon); + } + + return point; + }); + + var point = { + projected: projected, + options: { + pointGeometry: pointGeometry(feature), + pointScale: pointScale, + style: style + } + }; + + if (_properties) { + point.properties = feature.properties; + } + + points.push(point); + } + }; + + var polygonBufferPromises = []; + var polylineBufferPromises = []; + var pointBufferPromises = []; + + var polygon; + for (var i = 0; i < polygons.length; i++) { + polygon = polygons[i]; + polygonBufferPromises.push(_geometryPolygonLayer2['default'].SetBufferAttributes(polygon.projected, polygon.options)); + }; + + var polyline; + for (var i = 0; i < polylines.length; i++) { + polyline = polylines[i]; + polylineBufferPromises.push(_geometryPolylineLayer2['default'].SetBufferAttributes(polyline.projected, polyline.options)); + }; + + var point; + for (var i = 0; i < points.length; i++) { + point = points[i]; + pointBufferPromises.push(_geometryPointLayer2['default'].SetBufferAttributes(point.projected, point.options)); + }; + + var data = {}; + var transferrables = []; + + // TODO: Make this work with polylines too + // TODO: Make this so it's not a nest of promises + GeoJSONWorkerLayer.ProcessPolygons(polygonBufferPromises, polygons, _properties).then(function (result) { + data.polygons = result.data; + transferrables = transferrables.concat(result.transferrables); + + GeoJSONWorkerLayer.ProcessPolylines(polylineBufferPromises, polylines, _properties).then(function (result) { + data.polylines = result.data; + transferrables = transferrables.concat(result.transferrables); + + GeoJSONWorkerLayer.ProcessPoints(pointBufferPromises, points, _properties).then(function (result) { + data.points = result.data; + transferrables = transferrables.concat(result.transferrables); + + resolve({ + data: data, + transferrables: transferrables + }); + }); + }); + }); + }); + }); + } + }, { + key: 'ProcessPolygons', + value: function ProcessPolygons(polygonPromises, polygons, _properties) { + return new Promise(function (resolve, reject) { + Promise.all(polygonPromises).then(function (results) { + var transferrables = []; + + var positions = []; + var normals = []; + var colors = []; + var tops = []; + + var outlinePositions = []; + var outlineColors = []; + + var properties = []; + + var flats = []; + var polygon; + + var result; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + polygon = polygons[i]; + + // WORKERS: Making this a typed array will speed up transfer time + // As things stand this adds on a few milliseconds + flats.push(result.flat); + + // WORKERS: result.attributes is actually an array of polygons for each + // feature, though the current logic isn't keeping these all together + + var attributes; + for (var j = 0; j < result.attributes.length; j++) { + attributes = result.attributes[j]; + + positions.push(attributes.positions); + normals.push(attributes.normals); + colors.push(attributes.colors); + tops.push(attributes.tops); + + if (_properties) { + properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties))); + } + }; + + var outlineAttributes; + for (var j = 0; j < result.outlineAttributes.length; j++) { + outlineAttributes = result.outlineAttributes[j]; + + outlinePositions.push(outlineAttributes.positions); + outlineColors.push(outlineAttributes.colors); + }; + }; + + var mergedAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(positions), + normals: _utilBuffer2['default'].mergeFloat32Arrays(normals), + colors: _utilBuffer2['default'].mergeFloat32Arrays(colors), + tops: _utilBuffer2['default'].mergeFloat32Arrays(tops) + }; + + var mergedOutlineAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(outlinePositions), + colors: _utilBuffer2['default'].mergeFloat32Arrays(outlineColors) + }; + + transferrables.push(mergedAttributes.positions[0].buffer); + transferrables.push(mergedAttributes.positions[1].buffer); + + transferrables.push(mergedAttributes.normals[0].buffer); + transferrables.push(mergedAttributes.normals[1].buffer); + + transferrables.push(mergedAttributes.colors[0].buffer); + transferrables.push(mergedAttributes.colors[1].buffer); + + transferrables.push(mergedAttributes.tops[0].buffer); + transferrables.push(mergedAttributes.tops[1].buffer); + + transferrables.push(mergedOutlineAttributes.positions[0].buffer); + transferrables.push(mergedOutlineAttributes.positions[1].buffer); + + transferrables.push(mergedOutlineAttributes.colors[0].buffer); + transferrables.push(mergedOutlineAttributes.colors[1].buffer); + + var mergedProperties; + if (_properties) { + mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties); + + transferrables.push(mergedProperties[0].buffer); + transferrables.push(mergedProperties[1].buffer); + } + + var output = { + attributes: mergedAttributes, + outlineAttributes: mergedOutlineAttributes, + flats: flats + }; + + if (_properties) { + output.properties = mergedProperties; + } + + // TODO: Also return GeoJSON features that can be mapped to objects on + // the main thread. Allow user to provide filter / toggles to only return + // properties from the GeoJSON that they need (eg. don't return geometry, + // or don't return properties.height) + resolve({ + data: output, + transferrables: transferrables + }); + })['catch'](reject); + }); + } + }, { + key: 'ProcessPolylines', + value: function ProcessPolylines(polylinePromises, polylines, _properties) { + return new Promise(function (resolve, reject) { + Promise.all(polylinePromises).then(function (results) { + var transferrables = []; + + var positions = []; + var colors = []; + + var properties = []; + + var flats = []; + var polyline; + + var result; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + polyline = polylines[i]; + + // WORKERS: Making this a typed array will speed up transfer time + // As things stand this adds on a few milliseconds + flats.push(result.flat); + + // WORKERS: result.attributes is actually an array of polygons for each + // feature, though the current logic isn't keeping these all together + + var attributes; + for (var j = 0; j < result.attributes.length; j++) { + attributes = result.attributes[j]; + + positions.push(attributes.positions); + colors.push(attributes.colors); + + if (_properties) { + properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polyline.properties))); + } + }; + }; + + var mergedAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(positions), + colors: _utilBuffer2['default'].mergeFloat32Arrays(colors) + }; + + transferrables.push(mergedAttributes.positions[0].buffer); + transferrables.push(mergedAttributes.positions[1].buffer); + + transferrables.push(mergedAttributes.colors[0].buffer); + transferrables.push(mergedAttributes.colors[1].buffer); + + var mergedProperties; + if (_properties) { + mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties); + + transferrables.push(mergedProperties[0].buffer); + transferrables.push(mergedProperties[1].buffer); + } + + var output = { + attributes: mergedAttributes, + flats: flats + }; + + if (_properties) { + output.properties = mergedProperties; + } + + // TODO: Also return GeoJSON features that can be mapped to objects on + // the main thread. Allow user to provide filter / toggles to only return + // properties from the GeoJSON that they need (eg. don't return geometry, + // or don't return properties.height) + resolve({ + data: output, + transferrables: transferrables + }); + })['catch'](reject); + }); + } + + // TODO: Dedupe with ProcessPolygons as they are identical + }, { + key: 'ProcessPoints', + value: function ProcessPoints(pointPromises, points, _properties) { + return new Promise(function (resolve, reject) { + Promise.all(pointPromises).then(function (results) { + var transferrables = []; + + var positions = []; + var normals = []; + var colors = []; + + var properties = []; + + var flats = []; + var point; + + var result; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + point = points[i]; + + // WORKERS: Making this a typed array will speed up transfer time + // As things stand this adds on a few milliseconds + flats.push(result.flat); + + // WORKERS: result.attributes is actually an array of polygons for each + // feature, though the current logic isn't keeping these all together + + var attributes; + for (var j = 0; j < result.attributes.length; j++) { + attributes = result.attributes[j]; + + positions.push(attributes.positions); + normals.push(attributes.normals); + colors.push(attributes.colors); + + if (_properties) { + properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties))); + } + }; + }; + + var mergedAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(positions), + normals: _utilBuffer2['default'].mergeFloat32Arrays(normals), + colors: _utilBuffer2['default'].mergeFloat32Arrays(colors) + }; + + transferrables.push(mergedAttributes.positions[0].buffer); + transferrables.push(mergedAttributes.positions[1].buffer); + + transferrables.push(mergedAttributes.normals[0].buffer); + transferrables.push(mergedAttributes.normals[1].buffer); + + transferrables.push(mergedAttributes.colors[0].buffer); + transferrables.push(mergedAttributes.colors[1].buffer); + + var mergedProperties; + if (_properties) { + mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties); + + transferrables.push(mergedProperties[0].buffer); + transferrables.push(mergedProperties[1].buffer); + } + + var output = { + attributes: mergedAttributes, + flats: flats + }; + + if (_properties) { + output.properties = mergedProperties; + } + + // TODO: Also return GeoJSON features that can be mapped to objects on + // the main thread. Allow user to provide filter / toggles to only return + // properties from the GeoJSON that they need (eg. don't return geometry, + // or don't return properties.height) + resolve({ + data: output, + transferrables: transferrables + }); + })['catch'](reject); + }); + } + }, { + key: 'ProcessGeoJSON', + value: function ProcessGeoJSON(geojson, headers) { + if (typeof geojson === 'string') { + return GeoJSONWorkerLayer.RequestGeoJSON(geojson, headers); + } else { + return Promise.resolve(JSON.parse(_utilBuffer2['default'].uint8ArrayToString(geojson))); + } + } + }, { + key: 'RequestGeoJSON', + value: function RequestGeoJSON(path, headers) { + return (0, _reqwest2['default'])({ + url: path, + type: 'json', + crossOrigin: true, + headers: headers + }); + } + }]); + + return GeoJSONWorkerLayer; + })(_Layer3['default']); + + exports['default'] = GeoJSONWorkerLayer; + + var noNew = function noNew(geojson, options) { + return new GeoJSONWorkerLayer(geojson, options); + }; + + exports.geoJSONWorkerLayer = noNew; + +/***/ }, +/* 23 */ +/***/ function(module, exports, __webpack_require__) { + + var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! + * Reqwest! A general purpose XHR connection manager + * license MIT (c) Dustin Diaz 2015 + * https://github.com/ded/reqwest + */ + + !function (name, context, definition) { + if (typeof module != 'undefined' && module.exports) module.exports = definition() + else if (true) !(__WEBPACK_AMD_DEFINE_FACTORY__ = (definition), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__)) + else context[name] = definition() + }('reqwest', this, function () { + + var context = this + + if ('window' in context) { + var doc = document + , byTag = 'getElementsByTagName' + , head = doc[byTag]('head')[0] + } else { + var XHR2 + try { + XHR2 = __webpack_require__(24) + } catch (ex) { + throw new Error('Peer dependency `xhr2` required! Please npm install xhr2') + } + } + + + var httpsRe = /^http/ + , protocolRe = /(^\w+):\/\// + , twoHundo = /^(20\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request + , readyState = 'readyState' + , contentType = 'Content-Type' + , requestedWith = 'X-Requested-With' + , uniqid = 0 + , callbackPrefix = 'reqwest_' + (+new Date()) + , lastValue // data stored by the most recent JSONP callback + , xmlHttpRequest = 'XMLHttpRequest' + , xDomainRequest = 'XDomainRequest' + , noop = function () {} + + , isArray = typeof Array.isArray == 'function' + ? Array.isArray + : function (a) { + return a instanceof Array + } + + , defaultHeaders = { + 'contentType': 'application/x-www-form-urlencoded' + , 'requestedWith': xmlHttpRequest + , 'accept': { + '*': 'text/javascript, text/html, application/xml, text/xml, */*' + , 'xml': 'application/xml, text/xml' + , 'html': 'text/html' + , 'text': 'text/plain' + , 'json': 'application/json, text/javascript' + , 'js': 'application/javascript, text/javascript' + } + } + + , xhr = function(o) { + // is it x-domain + if (o['crossOrigin'] === true) { + var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null + if (xhr && 'withCredentials' in xhr) { + return xhr + } else if (context[xDomainRequest]) { + return new XDomainRequest() + } else { + throw new Error('Browser does not support cross-origin requests') + } + } else if (context[xmlHttpRequest]) { + return new XMLHttpRequest() + } else if (XHR2) { + return new XHR2() + } else { + return new ActiveXObject('Microsoft.XMLHTTP') + } + } + , globalSetupOptions = { + dataFilter: function (data) { + return data + } + } + + function succeed(r) { + var protocol = protocolRe.exec(r.url) + protocol = (protocol && protocol[1]) || context.location.protocol + return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response + } + + function handleReadyState(r, success, error) { + return function () { + // use _aborted to mitigate against IE err c00c023f + // (can't read props on aborted request objects) + if (r._aborted) return error(r.request) + if (r._timedOut) return error(r.request, 'Request is aborted: timeout') + if (r.request && r.request[readyState] == 4) { + r.request.onreadystatechange = noop + if (succeed(r)) success(r.request) + else + error(r.request) + } + } + } + + function setHeaders(http, o) { + var headers = o['headers'] || {} + , h + + headers['Accept'] = headers['Accept'] + || defaultHeaders['accept'][o['type']] + || defaultHeaders['accept']['*'] + + var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData); + // breaks cross-origin requests with legacy browsers + if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith'] + if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType'] + for (h in headers) + headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h]) + } + + function setCredentials(http, o) { + if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') { + http.withCredentials = !!o['withCredentials'] + } + } + + function generalCallback(data) { + lastValue = data + } + + function urlappend (url, s) { + return url + (/\?/.test(url) ? '&' : '?') + s + } + + function handleJsonp(o, fn, err, url) { + var reqId = uniqid++ + , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key + , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId) + , cbreg = new RegExp('((^|\\?|&)' + cbkey + ')=([^&]+)') + , match = url.match(cbreg) + , script = doc.createElement('script') + , loaded = 0 + , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1 + + if (match) { + if (match[3] === '?') { + url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name + } else { + cbval = match[3] // provided callback func name + } + } else { + url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em + } + + context[cbval] = generalCallback + + script.type = 'text/javascript' + script.src = url + script.async = true + if (typeof script.onreadystatechange !== 'undefined' && !isIE10) { + // need this for IE due to out-of-order onreadystatechange(), binding script + // execution to an event listener gives us control over when the script + // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html + script.htmlFor = script.id = '_reqwest_' + reqId + } + + script.onload = script.onreadystatechange = function () { + if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) { + return false + } + script.onload = script.onreadystatechange = null + script.onclick && script.onclick() + // Call the user callback with the last value stored and clean up values and scripts. + fn(lastValue) + lastValue = undefined + head.removeChild(script) + loaded = 1 + } + + // Add the script to the DOM head + head.appendChild(script) + + // Enable JSONP timeout + return { + abort: function () { + script.onload = script.onreadystatechange = null + err({}, 'Request is aborted: timeout', {}) + lastValue = undefined + head.removeChild(script) + loaded = 1 + } + } + } + + function getRequest(fn, err) { + var o = this.o + , method = (o['method'] || 'GET').toUpperCase() + , url = typeof o === 'string' ? o : o['url'] + // convert non-string objects to query-string form unless o['processData'] is false + , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string') + ? reqwest.toQueryString(o['data']) + : (o['data'] || null) + , http + , sendWait = false + + // if we're working on a GET request and we have data then we should append + // query string to end of URL and not post data + if ((o['type'] == 'jsonp' || method == 'GET') && data) { + url = urlappend(url, data) + data = null + } + + if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url) + + // get the xhr from the factory if passed + // if the factory returns null, fall-back to ours + http = (o.xhr && o.xhr(o)) || xhr(o) + + http.open(method, url, o['async'] === false ? false : true) + setHeaders(http, o) + setCredentials(http, o) + if (context[xDomainRequest] && http instanceof context[xDomainRequest]) { + http.onload = fn + http.onerror = err + // NOTE: see + // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e + http.onprogress = function() {} + sendWait = true + } else { + http.onreadystatechange = handleReadyState(this, fn, err) + } + o['before'] && o['before'](http) + if (sendWait) { + setTimeout(function () { + http.send(data) + }, 200) + } else { + http.send(data) + } + return http + } + + function Reqwest(o, fn) { + this.o = o + this.fn = fn + + init.apply(this, arguments) + } + + function setType(header) { + // json, javascript, text/plain, text/html, xml + if (header === null) return undefined; //In case of no content-type. + if (header.match('json')) return 'json' + if (header.match('javascript')) return 'js' + if (header.match('text')) return 'html' + if (header.match('xml')) return 'xml' + } + + function init(o, fn) { + + this.url = typeof o == 'string' ? o : o['url'] + this.timeout = null + + // whether request has been fulfilled for purpose + // of tracking the Promises + this._fulfilled = false + // success handlers + this._successHandler = function(){} + this._fulfillmentHandlers = [] + // error handlers + this._errorHandlers = [] + // complete (both success and fail) handlers + this._completeHandlers = [] + this._erred = false + this._responseArgs = {} + + var self = this + + fn = fn || function () {} + + if (o['timeout']) { + this.timeout = setTimeout(function () { + timedOut() + }, o['timeout']) + } + + if (o['success']) { + this._successHandler = function () { + o['success'].apply(o, arguments) + } + } + + if (o['error']) { + this._errorHandlers.push(function () { + o['error'].apply(o, arguments) + }) + } + + if (o['complete']) { + this._completeHandlers.push(function () { + o['complete'].apply(o, arguments) + }) + } + + function complete (resp) { + o['timeout'] && clearTimeout(self.timeout) + self.timeout = null + while (self._completeHandlers.length > 0) { + self._completeHandlers.shift()(resp) + } + } + + function success (resp) { + var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE + resp = (type !== 'jsonp') ? self.request : resp + // use global data filter on response text + var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type) + , r = filteredResponse + try { + resp.responseText = r + } catch (e) { + // can't assign this in IE<=8, just ignore + } + if (r) { + switch (type) { + case 'json': + try { + resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')') + } catch (err) { + return error(resp, 'Could not parse JSON in response', err) + } + break + case 'js': + resp = eval(r) + break + case 'html': + resp = r + break + case 'xml': + resp = resp.responseXML + && resp.responseXML.parseError // IE trololo + && resp.responseXML.parseError.errorCode + && resp.responseXML.parseError.reason + ? null + : resp.responseXML + break + } + } + + self._responseArgs.resp = resp + self._fulfilled = true + fn(resp) + self._successHandler(resp) + while (self._fulfillmentHandlers.length > 0) { + resp = self._fulfillmentHandlers.shift()(resp) + } + + complete(resp) + } + + function timedOut() { + self._timedOut = true + self.request.abort() + } + + function error(resp, msg, t) { + resp = self.request + self._responseArgs.resp = resp + self._responseArgs.msg = msg + self._responseArgs.t = t + self._erred = true + while (self._errorHandlers.length > 0) { + self._errorHandlers.shift()(resp, msg, t) + } + complete(resp) + } + + this.request = getRequest.call(this, success, error) + } + + Reqwest.prototype = { + abort: function () { + this._aborted = true + this.request.abort() + } + + , retry: function () { + init.call(this, this.o, this.fn) + } + + /** + * Small deviation from the Promises A CommonJs specification + * http://wiki.commonjs.org/wiki/Promises/A + */ + + /** + * `then` will execute upon successful requests + */ + , then: function (success, fail) { + success = success || function () {} + fail = fail || function () {} + if (this._fulfilled) { + this._responseArgs.resp = success(this._responseArgs.resp) + } else if (this._erred) { + fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t) + } else { + this._fulfillmentHandlers.push(success) + this._errorHandlers.push(fail) + } + return this + } + + /** + * `always` will execute whether the request succeeds or fails + */ + , always: function (fn) { + if (this._fulfilled || this._erred) { + fn(this._responseArgs.resp) + } else { + this._completeHandlers.push(fn) + } + return this + } + + /** + * `fail` will execute when the request fails + */ + , fail: function (fn) { + if (this._erred) { + fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t) + } else { + this._errorHandlers.push(fn) + } + return this + } + , 'catch': function (fn) { + return this.fail(fn) + } + } + + function reqwest(o, fn) { + return new Reqwest(o, fn) + } + + // normalize newline variants according to spec -> CRLF + function normalize(s) { + return s ? s.replace(/\r?\n/g, '\r\n') : '' + } + + function serial(el, cb) { + var n = el.name + , t = el.tagName.toLowerCase() + , optCb = function (o) { + // IE gives value="" even where there is no value attribute + // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273 + if (o && !o['disabled']) + cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text'])) + } + , ch, ra, val, i + + // don't serialize elements that are disabled or without a name + if (el.disabled || !n) return + + switch (t) { + case 'input': + if (!/reset|button|image|file/i.test(el.type)) { + ch = /checkbox/i.test(el.type) + ra = /radio/i.test(el.type) + val = el.value + // WebKit gives us "" instead of "on" if a checkbox has no value, so correct it here + ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val)) + } + break + case 'textarea': + cb(n, normalize(el.value)) + break + case 'select': + if (el.type.toLowerCase() === 'select-one') { + optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null) + } else { + for (i = 0; el.length && i < el.length; i++) { + el.options[i].selected && optCb(el.options[i]) + } + } + break + } + } + + // collect up all form elements found from the passed argument elements all + // the way down to child elements; pass a '
' or form fields. + // called with 'this'=callback to use for serial() on each element + function eachFormElement() { + var cb = this + , e, i + , serializeSubtags = function (e, tags) { + var i, j, fa + for (i = 0; i < tags.length; i++) { + fa = e[byTag](tags[i]) + for (j = 0; j < fa.length; j++) serial(fa[j], cb) + } + } + + for (i = 0; i < arguments.length; i++) { + e = arguments[i] + if (/input|select|textarea/i.test(e.tagName)) serial(e, cb) + serializeSubtags(e, [ 'input', 'select', 'textarea' ]) + } + } + + // standard query string style serialization + function serializeQueryString() { + return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments)) + } + + // { 'name': 'value', ... } style serialization + function serializeHash() { + var hash = {} + eachFormElement.apply(function (name, value) { + if (name in hash) { + hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]]) + hash[name].push(value) + } else hash[name] = value + }, arguments) + return hash + } + + // [ { name: 'name', value: 'value' }, ... ] style serialization + reqwest.serializeArray = function () { + var arr = [] + eachFormElement.apply(function (name, value) { + arr.push({name: name, value: value}) + }, arguments) + return arr + } + + reqwest.serialize = function () { + if (arguments.length === 0) return '' + var opt, fn + , args = Array.prototype.slice.call(arguments, 0) + + opt = args.pop() + opt && opt.nodeType && args.push(opt) && (opt = null) + opt && (opt = opt.type) + + if (opt == 'map') fn = serializeHash + else if (opt == 'array') fn = reqwest.serializeArray + else fn = serializeQueryString + + return fn.apply(null, args) + } + + reqwest.toQueryString = function (o, trad) { + var prefix, i + , traditional = trad || false + , s = [] + , enc = encodeURIComponent + , add = function (key, value) { + // If value is a function, invoke it and return its value + value = ('function' === typeof value) ? value() : (value == null ? '' : value) + s[s.length] = enc(key) + '=' + enc(value) + } + // If an array was passed in, assume that it is an array of form elements. + if (isArray(o)) { + for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value']) + } else { + // If traditional, encode the "old" way (the way 1.3.2 or older + // did it), otherwise encode params recursively. + for (prefix in o) { + if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add) + } + } + + // spaces should be + according to spec + return s.join('&').replace(/%20/g, '+') + } + + function buildParams(prefix, obj, traditional, add) { + var name, i, v + , rbracket = /\[\]$/ + + if (isArray(obj)) { + // Serialize array item. + for (i = 0; obj && i < obj.length; i++) { + v = obj[i] + if (traditional || rbracket.test(prefix)) { + // Treat each array item as a scalar. + add(prefix, v) + } else { + buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add) + } + } + } else if (obj && obj.toString() === '[object Object]') { + // Serialize object item. + for (name in obj) { + buildParams(prefix + '[' + name + ']', obj[name], traditional, add) + } + + } else { + // Serialize scalar item. + add(prefix, obj) + } + } + + reqwest.getcallbackPrefix = function () { + return callbackPrefix + } + + // jQuery and Zepto compatibility, differences can be remapped here so you can call + // .ajax.compat(options, callback) + reqwest.compat = function (o, fn) { + if (o) { + o['type'] && (o['method'] = o['type']) && delete o['type'] + o['dataType'] && (o['type'] = o['dataType']) + o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback'] + o['jsonp'] && (o['jsonpCallback'] = o['jsonp']) + } + return new Reqwest(o, fn) + } + + reqwest.ajaxSetup = function (options) { + options = options || {} + for (var k in options) { + globalSetupOptions[k] = options[k] + } + } + + return reqwest + }); + + +/***/ }, +/* 24 */ +/***/ function(module, exports) { + + /* (ignored) */ + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + /* + * GeoJSON helpers for handling data and generating objects + */ + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var _topojson2 = __webpack_require__(26); + + var topojson = _interopRequireWildcard(_topojson2); + + var _geojsonMerge = __webpack_require__(27); + + var _geojsonMerge2 = _interopRequireDefault(_geojsonMerge); + + var _earcut = __webpack_require__(29); + + var _earcut2 = _interopRequireDefault(_earcut); + + var _extrudePolygon = __webpack_require__(30); + + var _extrudePolygon2 = _interopRequireDefault(_extrudePolygon); + + // TODO: Make it so height can be per-coordinate / point but connected together + // as a linestring (eg. GPS points with an elevation at each point) + // + // This isn't really valid GeoJSON so perhaps something best left to an external + // component for now, until a better approach can be considered + // + // See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html + + // Light and dark colours used for poor-mans AO gradient on object sides + var light = new _three2['default'].Color(0xffffff); + var shadow = new _three2['default'].Color(0x666666); + + var GeoJSON = (function () { + var defaultStyle = { + color: '#ffffff', + outline: false, + outlineColor: '#000000', + transparent: false, + opacity: 1, + blending: _three2['default'].NormalBlending, + height: 0, + lineOpacity: 1, + lineTransparent: false, + lineColor: '#ffffff', + lineWidth: 1, + lineBlending: _three2['default'].NormalBlending + }; + + // Attempts to merge together multiple GeoJSON Features or FeatureCollections + // into a single FeatureCollection + var collectFeatures = function collectFeatures(data, _topojson) { + var collections = []; + + if (_topojson) { + // TODO: Allow TopoJSON objects to be overridden as an option + + // If not overridden, merge all features from all objects + for (var tk in data.objects) { + collections.push(topojson.feature(data, data.objects[tk])); + } + + return (0, _geojsonMerge2['default'])(collections); + } else { + // If root doesn't have a type then let's see if there are features in the + // next step down + if (!data.type) { + // TODO: Allow GeoJSON objects to be overridden as an option + + // If not overridden, merge all features from all objects + for (var gk in data) { + if (!data[gk].type) { + continue; + } + + collections.push(data[gk]); + } + + return (0, _geojsonMerge2['default'])(collections); + } else if (Array.isArray(data)) { + return (0, _geojsonMerge2['default'])(data); + } else { + return data; + } + } + }; + + // TODO: This is only used by GeoJSONTile so either roll it into that or + // update GeoJSONTile to use the new GeoJSONLayer or geometry layers + var lineStringAttributes = function lineStringAttributes(coordinates, colour, height) { + var _coords = []; + var _colours = []; + + var nextCoord; + + // Connect coordinate with the next to make a pair + // + // LineSegments requires pairs of vertices so repeat the last point if + // there's an odd number of vertices + coordinates.forEach(function (coordinate, index) { + _colours.push([colour.r, colour.g, colour.b]); + _coords.push([coordinate[0], height, coordinate[1]]); + + nextCoord = coordinates[index + 1] ? coordinates[index + 1] : coordinate; + + _colours.push([colour.r, colour.g, colour.b]); + _coords.push([nextCoord[0], height, nextCoord[1]]); + }); + + return { + vertices: _coords, + colours: _colours + }; + }; + + // TODO: This is only used by GeoJSONTile so either roll it into that or + // update GeoJSONTile to use the new GeoJSONLayer or geometry layers + var multiLineStringAttributes = function multiLineStringAttributes(coordinates, colour, height) { + var _coords = []; + var _colours = []; + + var result; + coordinates.forEach(function (coordinate) { + result = lineStringAttributes(coordinate, colour, height); + + result.vertices.forEach(function (coord) { + _coords.push(coord); + }); + + result.colours.forEach(function (colour) { + _colours.push(colour); + }); + }); + + return { + vertices: _coords, + colours: _colours + }; + }; + + // TODO: This is only used by GeoJSONTile so either roll it into that or + // update GeoJSONTile to use the new GeoJSONLayer or geometry layers + var polygonAttributes = function polygonAttributes(coordinates, colour, height) { + var earcutData = _toEarcut(coordinates); + + var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions); + + var groupedVertices = []; + for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) { + groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions)); + } + + var extruded = (0, _extrudePolygon2['default'])(groupedVertices, faces, { + bottom: 0, + top: height + }); + + var topColor = colour.clone().multiply(light); + var bottomColor = colour.clone().multiply(shadow); + + var _vertices = extruded.positions; + var _faces = []; + var _colours = []; + + var _colour; + extruded.top.forEach(function (face, fi) { + _colour = []; + + _colour.push([colour.r, colour.g, colour.b]); + _colour.push([colour.r, colour.g, colour.b]); + _colour.push([colour.r, colour.g, colour.b]); + + _faces.push(face); + _colours.push(_colour); + }); + + var allFlat = true; + + if (extruded.sides) { + if (allFlat) { + allFlat = false; + } + + // Set up colours for every vertex with poor-mans AO on the sides + extruded.sides.forEach(function (face, fi) { + _colour = []; + + // First face is always bottom-bottom-top + if (fi % 2 === 0) { + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + _colour.push([topColor.r, topColor.g, topColor.b]); + // Reverse winding for the second face + // top-top-bottom + } else { + _colour.push([topColor.r, topColor.g, topColor.b]); + _colour.push([topColor.r, topColor.g, topColor.b]); + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + } + + _faces.push(face); + _colours.push(_colour); + }); + } + + // Skip bottom as there's no point rendering it + // allFaces.push(extruded.faces); + + return { + vertices: _vertices, + faces: _faces, + colours: _colours, + flat: allFlat + }; + }; + + // TODO: This is only used by GeoJSONTile so either roll it into that or + // update GeoJSONTile to use the new GeoJSONLayer or geometry layers + var _toEarcut = function _toEarcut(data) { + var dim = data[0][0].length; + var result = { vertices: [], holes: [], dimensions: dim }; + var holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) { + result.vertices.push(data[i][j][d]); + } + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + + return result; + }; + + // TODO: This is only used by GeoJSONTile so either roll it into that or + // update GeoJSONTile to use the new GeoJSONLayer or geometry layers + var _triangulate = function _triangulate(contour, holes, dim) { + // console.time('earcut'); + + var faces = (0, _earcut2['default'])(contour, holes, dim); + var result = []; + + for (i = 0, il = faces.length; i < il; i += 3) { + result.push(faces.slice(i, i + 3)); + } + + // console.timeEnd('earcut'); + + return result; + }; + + return { + defaultStyle: defaultStyle, + collectFeatures: collectFeatures, + lineStringAttributes: lineStringAttributes, + multiLineStringAttributes: multiLineStringAttributes, + polygonAttributes: polygonAttributes + }; + })(); + + exports['default'] = GeoJSON; + module.exports = exports['default']; + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + (function (global, factory) { + true ? factory(exports) : + typeof define === 'function' && define.amd ? define(['exports'], factory) : + (factory((global.topojson = global.topojson || {}))); + }(this, (function (exports) { 'use strict'; + + function noop() {} + + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; + }; + } + + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = Math.round((point[0] - dx) / kx), + y1 = Math.round((point[1] - dy) / ky); + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } + + function reverse(array, n) { + var t, j = array.length, i = j - n; + while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } + + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + function feature(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature$1(topology, o); }) + } : feature$1(topology, o); + } + + function feature$1(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } + + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; + + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); + } + + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; + } + + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; + } + + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; + } + + function polygon(arcs) { + return arcs.map(ring); + } + + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; + } + + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; + + return geometry(o); + } + + function stitchArcs(topology, arcs) { + var stitchedArcs = {}, + fragmentByStart = {}, + fragmentByEnd = {}, + fragments = [], + emptyIndex = -1; + + // Stitch empty arcs first, since they may be subsumed by other arcs. + arcs.forEach(function(i, j) { + var arc = topology.arcs[i < 0 ? ~i : i], t; + if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { + t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; + } + }); + + arcs.forEach(function(i) { + var e = ends(i), + start = e[0], + end = e[1], + f, g; + + if (f = fragmentByEnd[start]) { + delete fragmentByEnd[f.end]; + f.push(i); + f.end = end; + if (g = fragmentByStart[end]) { + delete fragmentByStart[g.start]; + var fg = g === f ? f : f.concat(g); + fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; + } else { + fragmentByStart[f.start] = fragmentByEnd[f.end] = f; + } + } else if (f = fragmentByStart[end]) { + delete fragmentByStart[f.start]; + f.unshift(i); + f.start = start; + if (g = fragmentByEnd[start]) { + delete fragmentByEnd[g.end]; + var gf = g === f ? f : g.concat(f); + fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; + } else { + fragmentByStart[f.start] = fragmentByEnd[f.end] = f; + } + } else { + f = [i]; + fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; + } + }); + + function ends(i) { + var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; + if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); + else p1 = arc[arc.length - 1]; + return i < 0 ? [p1, p0] : [p0, p1]; + } + + function flush(fragmentByEnd, fragmentByStart) { + for (var k in fragmentByEnd) { + var f = fragmentByEnd[k]; + delete fragmentByStart[f.start]; + delete f.start; + delete f.end; + f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); + fragments.push(f); + } + } + + flush(fragmentByEnd, fragmentByStart); + flush(fragmentByStart, fragmentByEnd); + arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); + + return fragments; + } + + function mesh(topology) { + return object(topology, meshArcs.apply(this, arguments)); + } + + function meshArcs(topology, o, filter) { + var arcs = []; + + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); + } + + function line(arcs) { + arcs.forEach(arc); + } + + function polygon(arcs) { + arcs.forEach(line); + } + + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } + + if (arguments.length > 1) { + var geomsByArc = [], + geom; + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs) { arcs.forEach(polygon); } + }; + + geometry(o); + + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + } + + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } + + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } + + function ring(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; + + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; + } + + return area / 2; + } + + function merge(topology) { + return object(topology, mergeArcs.apply(this, arguments)); + } + + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; + + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); + + function register(polygon) { + polygon.forEach(function(ring$$) { + ring$$.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); + }); + }); + polygons.push(polygon); + } + + function area(ring$$) { + return Math.abs(ring(object(topology, {type: "Polygon", arcs: [ring$$]}).coordinates[0])); + } + + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring$$) { + ring$$.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); + + polygons.forEach(function(polygon) { + delete polygon._; + }); + + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = [], n; + + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring$$) { + ring$$.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); + + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // choose the one with the greatest absolute area. + if ((n = arcs.length) > 1) { + for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) { + if ((ki = area(arcs[i])) > k) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki; + } + } + } + + return arcs; + }) + }; + } + + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); + + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } + + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } + + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; + + objects.forEach(geometry); + + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); + } + } + } + + return neighbors; + } + + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } + + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; + + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; + + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; + }; + + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; + + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } + + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } + } + + return heap; + } + + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); + + if (!triangleArea) triangleArea = cartesianTriangleArea; + + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle, + i, + n, + p; + + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (i = 0, n = arc.length; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } + + for (i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); + triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); + heap.push(triangle); + } + + for (i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } + + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; + + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; + + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); + } + + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } + + arc.forEach(relative); + }); + + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); + } + + return topology; + } + + var version = "1.6.27"; + + exports.version = version; + exports.mesh = mesh; + exports.meshArcs = meshArcs; + exports.merge = merge; + exports.mergeArcs = mergeArcs; + exports.feature = feature; + exports.neighbors = neighbors; + exports.presimplify = presimplify; + + Object.defineProperty(exports, '__esModule', { value: true }); + + }))); + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + var normalize = __webpack_require__(28); + + module.exports = function(inputs) { + return { + type: 'FeatureCollection', + features: inputs.reduce(function(memo, input) { + return memo.concat(normalize(input).features); + }, []) + }; + }; + + +/***/ }, +/* 28 */ +/***/ function(module, exports) { + + module.exports = normalize; + + var types = { + Point: 'geometry', + MultiPoint: 'geometry', + LineString: 'geometry', + MultiLineString: 'geometry', + Polygon: 'geometry', + MultiPolygon: 'geometry', + GeometryCollection: 'geometry', + Feature: 'feature', + FeatureCollection: 'featurecollection' + }; + + /** + * Normalize a GeoJSON feature into a FeatureCollection. + * + * @param {object} gj geojson data + * @returns {object} normalized geojson data + */ + function normalize(gj) { + if (!gj || !gj.type) return null; + var type = types[gj.type]; + if (!type) return null; + + if (type === 'geometry') { + return { + type: 'FeatureCollection', + features: [{ + type: 'Feature', + properties: {}, + geometry: gj + }] + }; + } else if (type === 'feature') { + return { + type: 'FeatureCollection', + features: [gj] + }; + } else if (type === 'featurecollection') { + return gj; + } + } + + +/***/ }, +/* 29 */ +/***/ function(module, exports) { + + 'use strict'; + + module.exports = earcut; + + function earcut(data, holeIndices, dim) { + + dim = dim || 2; + + var hasHoles = holeIndices && holeIndices.length, + outerLen = hasHoles ? holeIndices[0] * dim : data.length, + outerNode = linkedList(data, 0, outerLen, dim, true), + triangles = []; + + if (!outerNode) return triangles; + + var minX, minY, maxX, maxY, x, y, size; + + if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim); + + // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox + if (data.length > 80 * dim) { + minX = maxX = data[0]; + minY = maxY = data[1]; + + for (var i = dim; i < outerLen; i += dim) { + x = data[i]; + y = data[i + 1]; + if (x < minX) minX = x; + if (y < minY) minY = y; + if (x > maxX) maxX = x; + if (y > maxY) maxY = y; + } + + // minX, minY and size are later used to transform coords into integers for z-order calculation + size = Math.max(maxX - minX, maxY - minY); + } + + earcutLinked(outerNode, triangles, dim, minX, minY, size); + + return triangles; + } + + // create a circular doubly linked list from polygon points in the specified winding order + function linkedList(data, start, end, dim, clockwise) { + var i, last; + + if (clockwise === (signedArea(data, start, end, dim) > 0)) { + for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last); + } else { + for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last); + } + + if (last && equals(last, last.next)) { + removeNode(last); + last = last.next; + } + + return last; + } + + // eliminate colinear or duplicate points + function filterPoints(start, end) { + if (!start) return start; + if (!end) end = start; + + var p = start, + again; + do { + again = false; + + if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) { + removeNode(p); + p = end = p.prev; + if (p === p.next) return null; + again = true; + + } else { + p = p.next; + } + } while (again || p !== end); + + return end; + } + + // main ear slicing loop which triangulates a polygon (given as a linked list) + function earcutLinked(ear, triangles, dim, minX, minY, size, pass) { + if (!ear) return; + + // interlink polygon nodes in z-order + if (!pass && size) indexCurve(ear, minX, minY, size); + + var stop = ear, + prev, next; + + // iterate through ears, slicing them one by one + while (ear.prev !== ear.next) { + prev = ear.prev; + next = ear.next; + + if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) { + // cut off the triangle + triangles.push(prev.i / dim); + triangles.push(ear.i / dim); + triangles.push(next.i / dim); + + removeNode(ear); + + // skipping the next vertice leads to less sliver triangles + ear = next.next; + stop = next.next; + + continue; + } + + ear = next; + + // if we looped through the whole remaining polygon and can't find any more ears + if (ear === stop) { + // try filtering points and slicing again + if (!pass) { + earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1); + + // if this didn't work, try curing all small self-intersections locally + } else if (pass === 1) { + ear = cureLocalIntersections(ear, triangles, dim); + earcutLinked(ear, triangles, dim, minX, minY, size, 2); + + // as a last resort, try splitting the remaining polygon into two + } else if (pass === 2) { + splitEarcut(ear, triangles, dim, minX, minY, size); + } + + break; + } + } + } + + // check whether a polygon node forms a valid ear with adjacent nodes + function isEar(ear) { + var a = ear.prev, + b = ear, + c = ear.next; + + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + + // now make sure we don't have other points inside the potential ear + var p = ear.next.next; + + while (p !== ear.prev) { + if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.next; + } + + return true; + } + + function isEarHashed(ear, minX, minY, size) { + var a = ear.prev, + b = ear, + c = ear.next; + + if (area(a, b, c) >= 0) return false; // reflex, can't be an ear + + // triangle bbox; min & max are calculated like this for speed + var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x), + minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y), + maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x), + maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y); + + // z-order range for the current triangle bbox; + var minZ = zOrder(minTX, minTY, minX, minY, size), + maxZ = zOrder(maxTX, maxTY, minX, minY, size); + + // first look for points inside the triangle in increasing z-order + var p = ear.nextZ; + + while (p && p.z <= maxZ) { + if (p !== ear.prev && p !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.nextZ; + } + + // then look for points in decreasing z-order + p = ear.prevZ; + + while (p && p.z >= minZ) { + if (p !== ear.prev && p !== ear.next && + pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) && + area(p.prev, p, p.next) >= 0) return false; + p = p.prevZ; + } + + return true; + } + + // go through all polygon nodes and cure small local self-intersections + function cureLocalIntersections(start, triangles, dim) { + var p = start; + do { + var a = p.prev, + b = p.next.next; + + if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) { + + triangles.push(a.i / dim); + triangles.push(p.i / dim); + triangles.push(b.i / dim); + + // remove two nodes involved + removeNode(p); + removeNode(p.next); + + p = start = b; + } + p = p.next; + } while (p !== start); + + return p; + } + + // try splitting polygon into two and triangulate them independently + function splitEarcut(start, triangles, dim, minX, minY, size) { + // look for a valid diagonal that divides the polygon into two + var a = start; + do { + var b = a.next.next; + while (b !== a.prev) { + if (a.i !== b.i && isValidDiagonal(a, b)) { + // split the polygon in two by the diagonal + var c = splitPolygon(a, b); + + // filter colinear points around the cuts + a = filterPoints(a, a.next); + c = filterPoints(c, c.next); + + // run earcut on each half + earcutLinked(a, triangles, dim, minX, minY, size); + earcutLinked(c, triangles, dim, minX, minY, size); + return; + } + b = b.next; + } + a = a.next; + } while (a !== start); + } + + // link every hole into the outer loop, producing a single-ring polygon without holes + function eliminateHoles(data, holeIndices, outerNode, dim) { + var queue = [], + i, len, start, end, list; + + for (i = 0, len = holeIndices.length; i < len; i++) { + start = holeIndices[i] * dim; + end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + list = linkedList(data, start, end, dim, false); + if (list === list.next) list.steiner = true; + queue.push(getLeftmost(list)); + } + + queue.sort(compareX); + + // process holes from left to right + for (i = 0; i < queue.length; i++) { + eliminateHole(queue[i], outerNode); + outerNode = filterPoints(outerNode, outerNode.next); + } + + return outerNode; + } + + function compareX(a, b) { + return a.x - b.x; + } + + // find a bridge between vertices that connects hole with an outer ring and and link it + function eliminateHole(hole, outerNode) { + outerNode = findHoleBridge(hole, outerNode); + if (outerNode) { + var b = splitPolygon(outerNode, hole); + filterPoints(b, b.next); + } + } + + // David Eberly's algorithm for finding a bridge between hole and outer polygon + function findHoleBridge(hole, outerNode) { + var p = outerNode, + hx = hole.x, + hy = hole.y, + qx = -Infinity, + m; + + // find a segment intersected by a ray from the hole's leftmost point to the left; + // segment's endpoint with lesser x will be potential connection point + do { + if (hy <= p.y && hy >= p.next.y) { + var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y); + if (x <= hx && x > qx) { + qx = x; + if (x === hx) { + if (hy === p.y) return p; + if (hy === p.next.y) return p.next; + } + m = p.x < p.next.x ? p : p.next; + } + } + p = p.next; + } while (p !== outerNode); + + if (!m) return null; + + if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint + + // look for points inside the triangle of hole point, segment intersection and endpoint; + // if there are no points found, we have a valid connection; + // otherwise choose the point of the minimum angle with the ray as connection point + + var stop = m, + mx = m.x, + my = m.y, + tanMin = Infinity, + tan; + + p = m.next; + + while (p !== stop) { + if (hx >= p.x && p.x >= mx && + pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) { + + tan = Math.abs(hy - p.y) / (hx - p.x); // tangential + + if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) { + m = p; + tanMin = tan; + } + } + + p = p.next; + } + + return m; + } + + // interlink polygon nodes in z-order + function indexCurve(start, minX, minY, size) { + var p = start; + do { + if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size); + p.prevZ = p.prev; + p.nextZ = p.next; + p = p.next; + } while (p !== start); + + p.prevZ.nextZ = null; + p.prevZ = null; + + sortLinked(p); + } + + // Simon Tatham's linked list merge sort algorithm + // http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html + function sortLinked(list) { + var i, p, q, e, tail, numMerges, pSize, qSize, + inSize = 1; + + do { + p = list; + list = null; + tail = null; + numMerges = 0; + + while (p) { + numMerges++; + q = p; + pSize = 0; + for (i = 0; i < inSize; i++) { + pSize++; + q = q.nextZ; + if (!q) break; + } + + qSize = inSize; + + while (pSize > 0 || (qSize > 0 && q)) { + + if (pSize === 0) { + e = q; + q = q.nextZ; + qSize--; + } else if (qSize === 0 || !q) { + e = p; + p = p.nextZ; + pSize--; + } else if (p.z <= q.z) { + e = p; + p = p.nextZ; + pSize--; + } else { + e = q; + q = q.nextZ; + qSize--; + } + + if (tail) tail.nextZ = e; + else list = e; + + e.prevZ = tail; + tail = e; + } + + p = q; + } + + tail.nextZ = null; + inSize *= 2; + + } while (numMerges > 1); + + return list; + } + + // z-order of a point given coords and size of the data bounding box + function zOrder(x, y, minX, minY, size) { + // coords are transformed into non-negative 15-bit integer range + x = 32767 * (x - minX) / size; + y = 32767 * (y - minY) / size; + + x = (x | (x << 8)) & 0x00FF00FF; + x = (x | (x << 4)) & 0x0F0F0F0F; + x = (x | (x << 2)) & 0x33333333; + x = (x | (x << 1)) & 0x55555555; + + y = (y | (y << 8)) & 0x00FF00FF; + y = (y | (y << 4)) & 0x0F0F0F0F; + y = (y | (y << 2)) & 0x33333333; + y = (y | (y << 1)) & 0x55555555; + + return x | (y << 1); + } + + // find the leftmost node of a polygon ring + function getLeftmost(start) { + var p = start, + leftmost = start; + do { + if (p.x < leftmost.x) leftmost = p; + p = p.next; + } while (p !== start); + + return leftmost; + } + + // check if a point lies within a convex triangle + function pointInTriangle(ax, ay, bx, by, cx, cy, px, py) { + return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 && + (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 && + (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0; + } + + // check if a diagonal between two polygon nodes is valid (lies in polygon interior) + function isValidDiagonal(a, b) { + return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) && + locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b); + } + + // signed area of a triangle + function area(p, q, r) { + return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y); + } + + // check if two points are equal + function equals(p1, p2) { + return p1.x === p2.x && p1.y === p2.y; + } + + // check if two segments intersect + function intersects(p1, q1, p2, q2) { + if ((equals(p1, q1) && equals(p2, q2)) || + (equals(p1, q2) && equals(p2, q1))) return true; + return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 && + area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0; + } + + // check if a polygon diagonal intersects any polygon segments + function intersectsPolygon(a, b) { + var p = a; + do { + if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i && + intersects(p, p.next, a, b)) return true; + p = p.next; + } while (p !== a); + + return false; + } + + // check if a polygon diagonal is locally inside the polygon + function locallyInside(a, b) { + return area(a.prev, a, a.next) < 0 ? + area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 : + area(a, b, a.prev) < 0 || area(a, a.next, b) < 0; + } + + // check if the middle point of a polygon diagonal is inside the polygon + function middleInside(a, b) { + var p = a, + inside = false, + px = (a.x + b.x) / 2, + py = (a.y + b.y) / 2; + do { + if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x)) + inside = !inside; + p = p.next; + } while (p !== a); + + return inside; + } + + // link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two; + // if one belongs to the outer ring and another to a hole, it merges it into a single ring + function splitPolygon(a, b) { + var a2 = new Node(a.i, a.x, a.y), + b2 = new Node(b.i, b.x, b.y), + an = a.next, + bp = b.prev; + + a.next = b; + b.prev = a; + + a2.next = an; + an.prev = a2; + + b2.next = a2; + a2.prev = b2; + + bp.next = b2; + b2.prev = bp; + + return b2; + } + + // create a node and optionally link it with previous one (in a circular doubly linked list) + function insertNode(i, x, y, last) { + var p = new Node(i, x, y); + + if (!last) { + p.prev = p; + p.next = p; + + } else { + p.next = last.next; + p.prev = last; + last.next.prev = p; + last.next = p; + } + return p; + } + + function removeNode(p) { + p.next.prev = p.prev; + p.prev.next = p.next; + + if (p.prevZ) p.prevZ.nextZ = p.nextZ; + if (p.nextZ) p.nextZ.prevZ = p.prevZ; + } + + function Node(i, x, y) { + // vertice index in coordinates array + this.i = i; + + // vertex coordinates + this.x = x; + this.y = y; + + // previous and next vertice nodes in a polygon ring + this.prev = null; + this.next = null; + + // z-order curve value + this.z = null; + + // previous and next nodes in z-order + this.prevZ = null; + this.nextZ = null; + + // indicates whether this is a steiner point + this.steiner = false; + } + + // return a percentage difference between the polygon area and its triangulation area; + // used to verify correctness of triangulation + earcut.deviation = function (data, holeIndices, dim, triangles) { + var hasHoles = holeIndices && holeIndices.length; + var outerLen = hasHoles ? holeIndices[0] * dim : data.length; + + var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim)); + if (hasHoles) { + for (var i = 0, len = holeIndices.length; i < len; i++) { + var start = holeIndices[i] * dim; + var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length; + polygonArea -= Math.abs(signedArea(data, start, end, dim)); + } + } + + var trianglesArea = 0; + for (i = 0; i < triangles.length; i += 3) { + var a = triangles[i] * dim; + var b = triangles[i + 1] * dim; + var c = triangles[i + 2] * dim; + trianglesArea += Math.abs( + (data[a] - data[c]) * (data[b + 1] - data[a + 1]) - + (data[a] - data[b]) * (data[c + 1] - data[a + 1])); + } + + return polygonArea === 0 && trianglesArea === 0 ? 0 : + Math.abs((trianglesArea - polygonArea) / polygonArea); + }; + + function signedArea(data, start, end, dim) { + var sum = 0; + for (var i = start, j = end - dim; i < end; i += dim) { + sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]); + j = i; + } + return sum; + } + + // turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts + earcut.flatten = function (data) { + var dim = data[0][0].length, + result = {vertices: [], holes: [], dimensions: dim}, + holeIndex = 0; + + for (var i = 0; i < data.length; i++) { + for (var j = 0; j < data[i].length; j++) { + for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]); + } + if (i > 0) { + holeIndex += data[i - 1].length; + result.holes.push(holeIndex); + } + } + return result; + }; + + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + /* + * Extrude a polygon given its vertices and triangulated faces + * + * Based on: + * https://github.com/freeman-lab/extrude + */ + + var _lodashAssign = __webpack_require__(6); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var extrudePolygon = function extrudePolygon(points, faces, _options) { + var defaults = { + top: 1, + bottom: 0, + closed: true + }; + + var options = (0, _lodashAssign2['default'])({}, defaults, _options); + + var n = points.length; + var positions; + var cells; + var topCells; + var bottomCells; + var sideCells; + + // If bottom and top values are identical then return the flat shape + options.top === options.bottom ? flat() : full(); + + function flat() { + positions = points.map(function (p) { + return [p[0], options.top, p[1]]; + }); + cells = faces; + topCells = faces; + } + + function full() { + positions = []; + points.forEach(function (p) { + positions.push([p[0], options.top, p[1]]); + }); + points.forEach(function (p) { + positions.push([p[0], options.bottom, p[1]]); + }); + + cells = []; + for (var i = 0; i < n; i++) { + if (i === n - 1) { + cells.push([i + n, n, i]); + cells.push([0, i, n]); + } else { + cells.push([i + n, i + n + 1, i]); + cells.push([i + 1, i, i + n + 1]); + } + } + + sideCells = [].concat(cells); + + if (options.closed) { + var top = faces; + var bottom = top.map(function (p) { + return p.map(function (v) { + return v + n; + }); + }); + bottom = bottom.map(function (p) { + return [p[0], p[2], p[1]]; + }); + cells = cells.concat(top).concat(bottom); + + topCells = top; + bottomCells = bottom; + } + } + + return { + positions: positions, + faces: cells, + top: topCells, + bottom: bottomCells, + sides: sideCells + }; + }; + + exports['default'] = extrudePolygon; + module.exports = exports['default']; + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _WorkerPool = __webpack_require__(32); + + var _WorkerPool2 = _interopRequireDefault(_WorkerPool); + + var Worker = (function () { + var _maxWorkers = 2; + var pool; + + var createWorkers = function createWorkers(maxWorkers, workerScript) { + pool = new _WorkerPool2['default']({ + numThreads: maxWorkers ? maxWorkers : _maxWorkers, + workerScript: workerScript ? workerScript : 'vizicities-worker.js' + }); + + return pool.createWorkers(); + }; + + var exec = function exec(method, args, transferrables) { + return pool.exec(method, args, transferrables); + }; + + return { + createWorkers: createWorkers, + exec: exec + }; + })(); + + exports['default'] = Worker; + module.exports = exports['default']; + +/***/ }, +/* 32 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + var _WorkerPoolWorker = __webpack_require__(33); + + var _WorkerPoolWorker2 = _interopRequireDefault(_WorkerPoolWorker); + + var DEBUG = false; + + var WorkerPool = (function () { + function WorkerPool(options) { + _classCallCheck(this, WorkerPool); + + this.numThreads = options.numThreads || 2; + this.workerScript = options.workerScript; + + this.workers = []; + this.tasks = []; + } + + _createClass(WorkerPool, [{ + key: 'createWorkers', + value: function createWorkers() { + var _this = this; + + return new Promise(function (resolve, reject) { + var workerPromises = []; + + for (var i = 0; i < _this.numThreads; i++) { + workerPromises.push(_this.createWorker()); + } + + Promise.all(workerPromises).then(function () { + if (DEBUG) { + console.log('All workers ready', performance.now()); + } + resolve(); + })['catch'](reject); + }); + } + }, { + key: 'createWorker', + value: function createWorker() { + var _this2 = this; + + return new Promise(function (resolve, reject) { + // Initialise worker + var worker = new _WorkerPoolWorker2['default']({ + workerScript: _this2.workerScript + }); + + // Start worker and wait for it to be ready + return worker.start().then(function () { + if (DEBUG) { + console.log('Worker ready', performance.now()); + } + + // Add worker to pool + _this2.workers.push(worker); + + resolve(); + })['catch'](reject); + }); + } + }, { + key: 'getFreeWorker', + value: function getFreeWorker() { + return this.workers.find(function (worker) { + return !worker.busy; + }); + } + + // Execute task on a worker + }, { + key: 'exec', + value: function exec(method, args, transferrables) { + var deferred = Promise.deferred(); + + // Create task + var task = { + method: method, + args: args, + transferrables: transferrables, + deferred: deferred + }; + + // Add task to queue + this.tasks.push(task); + + // Trigger task processing + this.processTasks(); + + // Return task promise + return task.deferred.promise; + } + }, { + key: 'processTasks', + value: function processTasks() { + var _this3 = this; + + if (DEBUG) { + console.log('Processing tasks'); + } + + if (this.tasks.length === 0) { + return; + } + + // Find free worker + var worker = this.getFreeWorker(); + + if (!worker) { + if (DEBUG) { + console.log('No workers free'); + } + return; + } + + // Get oldest task + var task = this.tasks.shift(); + + // Execute task on worker + worker.exec(task.method, task.args, task.transferrables).then(function (result) { + // Trigger task processing + _this3.processTasks(); + + // Return result in deferred task promise + task.deferred.resolve(result); + }); + } + }]); + + return WorkerPool; + })(); + + exports['default'] = WorkerPool; + + // Quick shim to create deferred native promises + Promise.deferred = function () { + var result = {}; + + result.promise = new Promise(function (resolve, reject) { + result.resolve = resolve; + result.reject = reject; + }); + + return result; + }; + module.exports = exports['default']; + +/***/ }, +/* 33 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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 DEBUG = false; + + var WorkerPoolWorker = (function () { + function WorkerPoolWorker(options) { + _classCallCheck(this, WorkerPoolWorker); + + this.workerScript = options.workerScript; + + this.ready = false; + this.busy = false; + this.deferred = null; + } + + _createClass(WorkerPoolWorker, [{ + key: 'start', + value: function start() { + var _this = this; + + return new Promise(function (resolve, reject) { + _this.worker = new Worker(_this.workerScript); + + var onStartup = function onStartup(event) { + if (!event.data || event.data.type !== 'startup') { + reject(); + return; + } + + _this.ready = true; + + // Remove temporary message handler + _this.worker.removeEventListener('message', onStartup); + + // Set up listener to respond to normal events now + _this.worker.addEventListener('message', function (event) { + _this.onMessage(event); + }); + + // Resolve once worker is ready + resolve(); + }; + + // Set up temporary event listener for warmup + _this.worker.addEventListener('message', onStartup); + }); + } + }, { + key: 'exec', + value: function exec(method, args, transferrables) { + if (DEBUG) { + console.log('Execute', method, args, transferrables); + } + + var deferred = Promise.deferred(); + + this.busy = true; + this.deferred = deferred; + + this.worker.postMessage({ + method: method, + args: args + }, transferrables); + + return deferred.promise; + } + }, { + key: 'onMessage', + value: function onMessage(event) { + console.log('Message received from worker', performance.now()); + + this.busy = false; + + if (!event.data || event.data.type === 'error' || event.data.type !== 'result') { + this.deferred.reject(event.data.payload); + return; + } + + this.deferred.resolve(event.data.payload); + } + }]); + + return WorkerPoolWorker; + })(); + + exports['default'] = WorkerPoolWorker; + + // Quick shim to create deferred native promises + Promise.deferred = function () { + var result = {}; + + result.promise = new Promise(function (resolve, reject) { + result.resolve = resolve; + result.reject = reject; + }); + + return result; + }; + module.exports = exports['default']; + +/***/ }, +/* 34 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + /* + * BufferGeometry helpers + */ + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var Buffer = (function () { + // Merge TypedArrays of the same type + // Returns merged array as well as indexes for splitting the array + var mergeFloat32Arrays = function mergeFloat32Arrays(arrays) { + var size = 0; + var map = new Int32Array(arrays.length * 2); + + var lastIndex = 0; + var length; + + // Find size of each array + arrays.forEach(function (_array, index) { + length = _array.length; + size += length; + map.set([lastIndex, lastIndex + length], index * 2); + lastIndex += length; + }); + + // Create a new array of total size + var mergedArray = new Float32Array(size); + + // Add each array to the new array + arrays.forEach(function (_array, index) { + mergedArray.set(_array, map[index * 2]); + }); + + return [mergedArray, map]; + }; + + var splitFloat32Array = function splitFloat32Array(data) { + var arr = data[0]; + var map = data[1]; + + var start; + var arrays = []; + + // Iterate over map + for (var i = 0; i < map.length / 2; i++) { + start = i * 2; + arrays.push(arr.subarray(map[start], map[start + 1])); + } + + return arrays; + }; + + // TODO: Create a generic method that can work for any typed array + var mergeUint8Arrays = function mergeUint8Arrays(arrays) { + var size = 0; + var map = new Int32Array(arrays.length * 2); + + var lastIndex = 0; + var length; + + // Find size of each array + arrays.forEach(function (_array, index) { + length = _array.length; + size += length; + map.set([lastIndex, lastIndex + length], index * 2); + lastIndex += length; + }); + + // Create a new array of total size + var mergedArray = new Uint8Array(size); + + // Add each array to the new array + arrays.forEach(function (_array, index) { + mergedArray.set(_array, map[index * 2]); + }); + + return [mergedArray, map]; + }; + + // TODO: Dedupe with splitFloat32Array + var splitUint8Array = function splitUint8Array(data) { + var arr = data[0]; + var map = data[1]; + + var start; + var arrays = []; + + // Iterate over map + for (var i = 0; i < map.length / 2; i++) { + start = i * 2; + arrays.push(arr.subarray(map[start], map[start + 1])); + } + + return arrays; + }; + + // Merge multiple attribute objects into a single attribute object + // + // Attribute objects must all use the same attribute keys + var mergeAttributes = function mergeAttributes(attributes) { + var lengths = {}; + + // Find array lengths + attributes.forEach(function (_attributes) { + for (var k in _attributes) { + if (!lengths[k]) { + lengths[k] = 0; + } + + lengths[k] += _attributes[k].length; + } + }); + + var mergedAttributes = {}; + + // Set up arrays to merge into + for (var k in lengths) { + mergedAttributes[k] = new Float32Array(lengths[k]); + } + + var lastLengths = {}; + + attributes.forEach(function (_attributes) { + for (var k in _attributes) { + if (!lastLengths[k]) { + lastLengths[k] = 0; + } + + mergedAttributes[k].set(_attributes[k], lastLengths[k]); + + lastLengths[k] += _attributes[k].length; + } + }); + + return mergedAttributes; + }; + + var createLineGeometry = function createLineGeometry(lines, offset) { + var geometry = new _three2['default'].BufferGeometry(); + + var vertices = new Float32Array(lines.verticesCount * 3); + var colours = new Float32Array(lines.verticesCount * 3); + + var pickingIds; + if (lines.pickingIds) { + // One component per vertex (1) + pickingIds = new Float32Array(lines.verticesCount); + } + + var _vertices; + var _colour; + var _pickingId; + + var lastIndex = 0; + + for (var i = 0; i < lines.vertices.length; i++) { + _vertices = lines.vertices[i]; + _colour = lines.colours[i]; + + if (pickingIds) { + _pickingId = lines.pickingIds[i]; + } + + for (var j = 0; j < _vertices.length; j++) { + var ax = _vertices[j][0] + offset.x; + var ay = _vertices[j][1]; + var az = _vertices[j][2] + offset.y; + + var c1 = _colour[j]; + + vertices[lastIndex * 3 + 0] = ax; + vertices[lastIndex * 3 + 1] = ay; + vertices[lastIndex * 3 + 2] = az; + + colours[lastIndex * 3 + 0] = c1[0]; + colours[lastIndex * 3 + 1] = c1[1]; + colours[lastIndex * 3 + 2] = c1[2]; + + if (pickingIds) { + pickingIds[lastIndex] = _pickingId; + } + + lastIndex++; + } + } + + // itemSize = 3 because there are 3 values (components) per vertex + geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3)); + geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3)); + + if (pickingIds) { + geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1)); + } + + geometry.computeBoundingBox(); + + return geometry; + }; + + // TODO: Make picking IDs optional + var createGeometry = function createGeometry(attributes, offset) { + var geometry = new _three2['default'].BufferGeometry(); + + // Three components per vertex per face (3 x 3 = 9) + var vertices = new Float32Array(attributes.facesCount * 9); + var normals = new Float32Array(attributes.facesCount * 9); + var colours = new Float32Array(attributes.facesCount * 9); + + var pickingIds; + if (attributes.pickingIds) { + // One component per vertex per face (1 x 3 = 3) + pickingIds = new Float32Array(attributes.facesCount * 3); + } + + var pA = new _three2['default'].Vector3(); + var pB = new _three2['default'].Vector3(); + var pC = new _three2['default'].Vector3(); + + var cb = new _three2['default'].Vector3(); + var ab = new _three2['default'].Vector3(); + + var index; + var _faces; + var _vertices; + var _colour; + var _pickingId; + var lastIndex = 0; + for (var i = 0; i < attributes.faces.length; i++) { + _faces = attributes.faces[i]; + _vertices = attributes.vertices[i]; + _colour = attributes.colours[i]; + + if (pickingIds) { + _pickingId = attributes.pickingIds[i]; + } + + for (var j = 0; j < _faces.length; j++) { + // Array of vertex indexes for the face + index = _faces[j][0]; + + var ax = _vertices[index][0] + offset.x; + var ay = _vertices[index][1]; + var az = _vertices[index][2] + offset.y; + + var c1 = _colour[j][0]; + + index = _faces[j][1]; + + var bx = _vertices[index][0] + offset.x; + var by = _vertices[index][1]; + var bz = _vertices[index][2] + offset.y; + + var c2 = _colour[j][1]; + + index = _faces[j][2]; + + var cx = _vertices[index][0] + offset.x; + var cy = _vertices[index][1]; + var cz = _vertices[index][2] + offset.y; + + var c3 = _colour[j][2]; + + // Flat face normals + // From: http://threejs.org/examples/webgl_buffergeometry.html + pA.set(ax, ay, az); + pB.set(bx, by, bz); + pC.set(cx, cy, cz); + + cb.subVectors(pC, pB); + ab.subVectors(pA, pB); + cb.cross(ab); + + cb.normalize(); + + var nx = cb.x; + var ny = cb.y; + var nz = cb.z; + + vertices[lastIndex * 9 + 0] = ax; + vertices[lastIndex * 9 + 1] = ay; + vertices[lastIndex * 9 + 2] = az; + + normals[lastIndex * 9 + 0] = nx; + normals[lastIndex * 9 + 1] = ny; + normals[lastIndex * 9 + 2] = nz; + + colours[lastIndex * 9 + 0] = c1[0]; + colours[lastIndex * 9 + 1] = c1[1]; + colours[lastIndex * 9 + 2] = c1[2]; + + vertices[lastIndex * 9 + 3] = bx; + vertices[lastIndex * 9 + 4] = by; + vertices[lastIndex * 9 + 5] = bz; + + normals[lastIndex * 9 + 3] = nx; + normals[lastIndex * 9 + 4] = ny; + normals[lastIndex * 9 + 5] = nz; + + colours[lastIndex * 9 + 3] = c2[0]; + colours[lastIndex * 9 + 4] = c2[1]; + colours[lastIndex * 9 + 5] = c2[2]; + + vertices[lastIndex * 9 + 6] = cx; + vertices[lastIndex * 9 + 7] = cy; + vertices[lastIndex * 9 + 8] = cz; + + normals[lastIndex * 9 + 6] = nx; + normals[lastIndex * 9 + 7] = ny; + normals[lastIndex * 9 + 8] = nz; + + colours[lastIndex * 9 + 6] = c3[0]; + colours[lastIndex * 9 + 7] = c3[1]; + colours[lastIndex * 9 + 8] = c3[2]; + + if (pickingIds) { + pickingIds[lastIndex * 3 + 0] = _pickingId; + pickingIds[lastIndex * 3 + 1] = _pickingId; + pickingIds[lastIndex * 3 + 2] = _pickingId; + } + + lastIndex++; + } + } + + // itemSize = 3 because there are 3 values (components) per vertex + geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3)); + geometry.addAttribute('normal', new _three2['default'].BufferAttribute(normals, 3)); + geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3)); + + if (pickingIds) { + geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1)); + } + + geometry.computeBoundingBox(); + + return geometry; + }; + + var textEncoder = new TextEncoder('utf-8'); + var textDecoder = new TextDecoder('utf-8'); + + var stringToUint8Array = function stringToUint8Array(str) { + return textEncoder.encode(str); + }; + + var uint8ArrayToString = function uint8ArrayToString(ab) { + return textDecoder.decode(ab); + }; + + return { + mergeFloat32Arrays: mergeFloat32Arrays, + splitFloat32Array: splitFloat32Array, + mergeUint8Arrays: mergeUint8Arrays, + splitUint8Array: splitUint8Array, + mergeAttributes: mergeAttributes, + createLineGeometry: createLineGeometry, + createGeometry: createGeometry, + stringToUint8Array: stringToUint8Array, + uint8ArrayToString: uint8ArrayToString + }; + })(); + + exports['default'] = Buffer; + module.exports = exports['default']; + +/***/ }, +/* 35 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + var Stringify = (function () { + var functionToString = function functionToString(f) { + return f.toString(); + }; + + // Based on https://github.com/tangrams/tangram/blob/2a31893c814cf15d5077f87ffa10af20160716b9/src/utils/utils.js#L245 + var stringToFunction = function stringToFunction(str) { + if (typeof str === 'string' && str.match(/^\s*function\s*\w*\s*\([\s\S]*\)\s*\{[\s\S]*\}/m) != null) { + var f; + + try { + eval('f = ' + str); + return f; + } catch (err) { + return str; + } + } + }; + + return { + functionToString: functionToString, + stringToFunction: stringToFunction + }; + })(); + + exports['default'] = Stringify; + module.exports = exports['default']; + +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + // TODO: Move duplicated logic between geometry layrs into GeometryLayer + + // TODO: Look at ways to drop unneeded references to array buffers, etc to + // reduce memory footprint + + // TODO: Support dynamic updating / hiding / animation of geometry + // + // This could be pretty hard as it's all packed away within BufferGeometry and + // may even be merged by another layer (eg. GeoJSONLayer) + // + // How much control should this layer support? Perhaps a different or custom + // layer would be better suited for animation, for example. + + // TODO: Allow _setBufferAttributes to use a custom function passed in to + // generate a custom mesh + + var _Layer2 = __webpack_require__(4); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(6); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var _geoGeo = __webpack_require__(1); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + + var _geoLatLon = __webpack_require__(2); + + var _geoPoint = __webpack_require__(3); + + var _earcut2 = __webpack_require__(29); + + var _earcut3 = _interopRequireDefault(_earcut2); + + var _utilExtrudePolygon = __webpack_require__(30); + + var _utilExtrudePolygon2 = _interopRequireDefault(_utilExtrudePolygon); + + var _enginePickingMaterial = __webpack_require__(37); + + var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); + + var _utilBuffer = __webpack_require__(34); + + var _utilBuffer2 = _interopRequireDefault(_utilBuffer); + + var PolygonLayer = (function (_Layer) { + _inherits(PolygonLayer, _Layer); + + function PolygonLayer(coordinates, options) { + _classCallCheck(this, PolygonLayer); + + var defaults = { + output: true, + interactive: false, + // Custom material override + // + // TODO: Should this be in the style object? + polygonMaterial: null, + onPolygonMesh: null, + onBufferAttributes: null, + // This default style is separate to Util.GeoJSON.defaultStyle + style: { + color: '#ffffff', + transparent: false, + opacity: 1, + blending: _three2['default'].NormalBlending, + height: 0 + } + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + _get(Object.getPrototypeOf(PolygonLayer.prototype), 'constructor', this).call(this, _options); + + // Return coordinates as array of polygons so it's easy to support + // MultiPolygon features (a single polygon would be a MultiPolygon with a + // single polygon in the array) + this._coordinates = PolygonLayer.isSingle(coordinates) ? [coordinates] : coordinates; + } + + _createClass(PolygonLayer, [{ + key: '_onAdd', + value: function _onAdd(world) { + var _this = this; + + return new Promise(function (resolve, reject) { + _this._setCoordinates(); + + if (_this._options.interactive) { + // Only add to picking mesh if this layer is controlling output + // + // Otherwise, assume another component will eventually add a mesh to + // the picking scene + if (_this.isOutput()) { + _this._pickingMesh = new _three2['default'].Object3D(); + _this.addToPicking(_this._pickingMesh); + } + + _this._setPickingId(); + _this._addPickingEvents(); + } + + PolygonLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) { + _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes); + + if (result.outlineAttributes.length > 0) { + _this._outlineBufferAttributes = _utilBuffer2['default'].mergeAttributes(result.outlineAttributes); + } + + _this._flat = result.flat; + + if (_this.isOutput()) { + var attributeLengths = { + positions: 3, + normals: 3, + colors: 3, + tops: 1 + }; + + if (_this._options.interactive) { + attributeLengths.pickingIds = 1; + } + + var style = _this._options.style; + + // Set mesh if not merging elsewhere + PolygonLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) { + // Output mesh + _this.add(result.mesh); + + if (result.pickingMesh) { + _this._pickingMesh.add(result.pickingMesh); + } + }); + } + + result.attributes = null; + result.outlineAttributes = null; + result = null; + + resolve(_this); + })['catch'](reject); + }); + } + + // Return center of polygon as a LatLon + // + // This is used for things like placing popups / UI elements on the layer + // + // TODO: Find proper center position instead of returning first coordinate + // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15 + }, { + key: 'getCenter', + value: function getCenter() { + return this._center; + } + + // Return polygon bounds in geographic coordinates + // + // TODO: Implement getBounds() + }, { + key: 'getBounds', + value: function getBounds() {} + + // Get unique ID for picking interaction + }, { + key: '_setPickingId', + value: function _setPickingId() { + this._pickingId = this.getPickingId(); + } + + // Set up and re-emit interaction events + }, { + key: '_addPickingEvents', + value: function _addPickingEvents() { + var _this2 = this; + + // TODO: Find a way to properly remove this listener on destroy + this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) { + // Re-emit click event from the layer + _this2.emit('click', _this2, point2d, point3d, intersects); + }); + } + + // Create and store reference to THREE.BufferAttribute data for this layer + }, { + key: 'getBufferAttributes', + value: function getBufferAttributes() { + return this._bufferAttributes; + } + }, { + key: 'getOutlineBufferAttributes', + value: function getOutlineBufferAttributes() { + return this._outlineBufferAttributes; + } + + // Used by external components to clear some memory when the attributes + // are no longer required to be stored in this layer + // + // For example, you would want to clear the attributes here after merging them + // using something like the GeoJSONLayer + }, { + key: 'clearBufferAttributes', + value: function clearBufferAttributes() { + this._bufferAttributes = null; + this._outlineBufferAttributes = null; + } + + // Threshold angle is currently in rads + }, { + key: 'clearCoordinates', + + // Used by external components to clear some memory when the coordinates + // are no longer required to be stored in this layer + // + // For example, you would want to clear the coordinates here after this + // layer is merged in something like the GeoJSONLayer + value: function clearCoordinates() { + this._coordinates = null; + this._projectedCoordinates = null; + } + }, { + key: '_setCoordinates', + + // Convert and project coordinates + // + // TODO: Calculate bounds + value: function _setCoordinates() { + this._bounds = []; + this._coordinates = this._convertCoordinates(this._coordinates); + + this._projectedBounds = []; + this._projectedCoordinates = this._projectCoordinates(); + + this._center = this._coordinates[0][0][0]; + } + + // Recursively convert input coordinates into LatLon objects + // + // Calculate geographic bounds at the same time + // + // TODO: Calculate geographic bounds + }, { + key: '_convertCoordinates', + value: function _convertCoordinates(coordinates) { + return coordinates.map(function (_coordinates) { + return _coordinates.map(function (ring) { + return ring.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + }); + }); + } + + // Recursively project coordinates into world positions + // + // Calculate world bounds, offset and pointScale at the same time + // + // TODO: Calculate world bounds + }, { + key: '_projectCoordinates', + value: function _projectCoordinates() { + var _this3 = this; + + var point; + return this._coordinates.map(function (_coordinates) { + return _coordinates.map(function (ring) { + return ring.map(function (latlon) { + point = _this3._world.latLonToPoint(latlon); + + // TODO: Is offset ever being used or needed? + if (!_this3._offset) { + _this3._offset = (0, _geoPoint.point)(0, 0); + _this3._offset.x = -1 * point.x; + _this3._offset.y = -1 * point.y; + + _this3._options.pointScale = _this3._world.pointScale(latlon); + } + + return point; + }); + }); + }); + } + + // Convert coordinates array to something earcut can understand + }, { + key: 'isFlat', + + // Returns true if the polygon is flat (has no height) + value: function isFlat() { + return this._flat; + } + + // Returns true if coordinates refer to a single geometry + // + // For example, not coordinates for a MultiPolygon GeoJSON feature + }, { + key: 'destroy', + + // TODO: Make sure this is cleaning everything + value: function destroy() { + if (this._pickingMesh) { + // TODO: Properly dispose of picking mesh + this._pickingMesh = null; + } + + this.clearCoordinates(); + this.clearBufferAttributes(); + + // Run common destruction logic from parent + _get(Object.getPrototypeOf(PolygonLayer.prototype), 'destroy', this).call(this); + } + }], [{ + key: 'SetBufferAttributes', + value: function SetBufferAttributes(coordinates, options) { + return new Promise(function (resolve) { + var height = 0; + + // Convert height into world units + if (options.style.height && options.style.height !== 0) { + height = _geoGeo2['default'].metresToWorld(options.style.height, options.pointScale); + } + + var colour = new _three2['default'].Color(); + colour.set(options.style.color); + + // Light and dark colours used for poor-mans AO gradient on object sides + var light = new _three2['default'].Color(0xffffff); + var shadow = new _three2['default'].Color(0x666666); + + var flat = true; + + var outlineAttributes = []; + + // For each polygon + var attributes = coordinates.map(function (_coordinates) { + // Convert coordinates to earcut format + var _earcut = PolygonLayer.ToEarcut(_coordinates); + + // Triangulate faces using earcut + var faces = PolygonLayer.Triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions); + + var groupedVertices = []; + for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) { + groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions)); + } + + var extruded = (0, _utilExtrudePolygon2['default'])(groupedVertices, faces, { + bottom: 0, + top: height + }); + + var topColor = colour.clone().multiply(light); + var bottomColor = colour.clone().multiply(shadow); + + var _vertices = extruded.positions; + var _faces = []; + var _colours = []; + var _tops = []; + + var _colour; + extruded.top.forEach(function (face, fi) { + _colour = []; + + _colour.push([colour.r, colour.g, colour.b]); + _colour.push([colour.r, colour.g, colour.b]); + _colour.push([colour.r, colour.g, colour.b]); + + _tops.push([true, true, true]); + + _faces.push(face); + _colours.push(_colour); + }); + + if (extruded.sides) { + flat = false; + + // Set up colours for every vertex with poor-mans AO on the sides + extruded.sides.forEach(function (face, fi) { + _colour = []; + + // First face is always bottom-bottom-top + if (fi % 2 === 0) { + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + _colour.push([topColor.r, topColor.g, topColor.b]); + + _tops.push([false, false, true]); + // Reverse winding for the second face + // top-top-bottom + } else { + _colour.push([topColor.r, topColor.g, topColor.b]); + _colour.push([topColor.r, topColor.g, topColor.b]); + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + + _tops.push([true, true, false]); + } + + _faces.push(face); + _colours.push(_colour); + }); + } + + // Skip bottom as there's no point rendering it + // allFaces.push(extruded.faces); + + var polygon = { + vertices: _vertices, + faces: _faces, + colours: _colours, + tops: _tops, + facesCount: _faces.length + }; + + if (options.style.outline) { + var outlineColour = new _three2['default'].Color(); + outlineColour.set(options.style.outlineColor || 0x000000); + + outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour)); + } + + if (options.interactive && options.pickingId) { + // Inject picking ID + polygon.pickingId = options.pickingId; + } + + // Convert polygon representation to proper attribute arrays + return PolygonLayer.ToAttributes(polygon); + }); + + resolve({ + attributes: attributes, + outlineAttributes: outlineAttributes, + flat: flat + }); + }); + } + }, { + key: 'Set2DOutline', + value: function Set2DOutline(coordinates, colour) { + var _vertices = []; + + coordinates.forEach(function (ring) { + var _ring = ring.map(function (coordinate) { + return [coordinate.x, 0, coordinate.y]; + }); + + // Add in duplicate vertices for line segments to work + var verticeCount = _ring.length; + var first = true; + while (--verticeCount) { + if (first || verticeCount === 0) { + first = false; + continue; + } + + _ring.splice(verticeCount + 1, 0, _ring[verticeCount]); + } + + _vertices = _vertices.concat(_ring); + }); + + _colour = [colour.r, colour.g, colour.b]; + + var vertices = new Float32Array(_vertices.length * 3); + var colours = new Float32Array(_vertices.length * 3); + + var lastIndex = 0; + + for (var i = 0; i < _vertices.length; i++) { + var ax = _vertices[i][0]; + var ay = _vertices[i][1]; + var az = _vertices[i][2]; + + var c1 = _colour; + + vertices[lastIndex * 3 + 0] = ax; + vertices[lastIndex * 3 + 1] = ay; + vertices[lastIndex * 3 + 2] = az; + + colours[lastIndex * 3 + 0] = c1[0]; + colours[lastIndex * 3 + 1] = c1[1]; + colours[lastIndex * 3 + 2] = c1[2]; + + lastIndex++; + } + + var attributes = { + positions: vertices, + colors: colours + }; + + return attributes; + } + }, { + key: 'SetMesh', + value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) { + var geometry = new _three2['default'].BufferGeometry(); + + for (var key in attributes) { + geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key])); + } + + geometry.computeBoundingBox(); + + var material; + if (options.polygonMaterial && options.polygonMaterial instanceof _three2['default'].Material) { + material = options.polygonMaterial; + } else if (!skybox) { + material = new _three2['default'].MeshPhongMaterial({ + vertexColors: _three2['default'].VertexColors, + side: _three2['default'].BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + } else { + material = new _three2['default'].MeshStandardMaterial({ + vertexColors: _three2['default'].VertexColors, + side: _three2['default'].BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + material.roughness = 1; + material.metalness = 0.1; + material.envMapIntensity = 3; + material.envMap = skybox.getRenderTarget(); + } + + var mesh; + + // Pass mesh through callback, if defined + if (typeof options.onPolygonMesh === 'function') { + mesh = options.onPolygonMesh(geometry, material); + } else { + mesh = new _three2['default'].Mesh(geometry, material); + + mesh.castShadow = true; + mesh.receiveShadow = true; + } + + if (flat) { + material.depthWrite = false; + + var renderOrder = style.renderOrder !== undefined ? style.renderOrder : 3; + mesh.renderOrder = renderOrder; + } + + if (options.interactive) { + material = new _enginePickingMaterial2['default'](); + material.side = _three2['default'].BackSide; + + var pickingMesh = new _three2['default'].Mesh(geometry, material); + } + + return Promise.resolve({ + mesh: mesh, + pickingMesh: pickingMesh + }); + } + }, { + key: 'ToEarcut', + value: function ToEarcut(coordinates) { + var dim = 2; + var result = { vertices: [], holes: [], dimensions: dim }; + var holeIndex = 0; + + for (var i = 0; i < coordinates.length; i++) { + for (var j = 0; j < coordinates[i].length; j++) { + // for (var d = 0; d < dim; d++) { + result.vertices.push(coordinates[i][j].x); + result.vertices.push(coordinates[i][j].y); + // } + } + if (i > 0) { + holeIndex += coordinates[i - 1].length; + result.holes.push(holeIndex); + } + } + + return result; + } + + // Triangulate earcut-based input using earcut + }, { + key: 'Triangulate', + value: function Triangulate(contour, holes, dim) { + // console.time('earcut'); + + var faces = (0, _earcut3['default'])(contour, holes, dim); + var result = []; + + for (i = 0, il = faces.length; i < il; i += 3) { + result.push(faces.slice(i, i + 3)); + } + + // console.timeEnd('earcut'); + + return result; + } + + // Transform polygon representation into attribute arrays that can be used by + // THREE.BufferGeometry + // + // TODO: Can this be simplified? It's messy and huge + }, { + key: 'ToAttributes', + value: function ToAttributes(polygon) { + // Three components per vertex per face (3 x 3 = 9) + var positions = new Float32Array(polygon.facesCount * 9); + var normals = new Float32Array(polygon.facesCount * 9); + var colours = new Float32Array(polygon.facesCount * 9); + + // One component per vertex per face (1 x 3 = 3) + var tops = new Float32Array(polygon.facesCount * 3); + + var pickingIds; + if (polygon.pickingId) { + // One component per vertex per face (1 x 3 = 3) + pickingIds = new Float32Array(polygon.facesCount * 3); + } + + var pA = new _three2['default'].Vector3(); + var pB = new _three2['default'].Vector3(); + var pC = new _three2['default'].Vector3(); + + var cb = new _three2['default'].Vector3(); + var ab = new _three2['default'].Vector3(); + + var index; + + var _faces = polygon.faces; + var _vertices = polygon.vertices; + var _colour = polygon.colours; + var _tops = polygon.tops; + + var _pickingId; + if (pickingIds) { + _pickingId = polygon.pickingId; + } + + var lastIndex = 0; + + for (var i = 0; i < _faces.length; i++) { + // Array of vertex indexes for the face + index = _faces[i][0]; + + var ax = _vertices[index][0]; + var ay = _vertices[index][1]; + var az = _vertices[index][2]; + + var c1 = _colour[i][0]; + var t1 = _tops[i][0]; + + index = _faces[i][1]; + + var bx = _vertices[index][0]; + var by = _vertices[index][1]; + var bz = _vertices[index][2]; + + var c2 = _colour[i][1]; + var t2 = _tops[i][1]; + + index = _faces[i][2]; + + var cx = _vertices[index][0]; + var cy = _vertices[index][1]; + var cz = _vertices[index][2]; + + var c3 = _colour[i][2]; + var t3 = _tops[i][2]; + + // Flat face normals + // From: http://threejs.org/examples/webgl_buffergeometry.html + pA.set(ax, ay, az); + pB.set(bx, by, bz); + pC.set(cx, cy, cz); + + cb.subVectors(pC, pB); + ab.subVectors(pA, pB); + cb.cross(ab); + + cb.normalize(); + + var nx = cb.x; + var ny = cb.y; + var nz = cb.z; + + positions[lastIndex * 9 + 0] = ax; + positions[lastIndex * 9 + 1] = ay; + positions[lastIndex * 9 + 2] = az; + + normals[lastIndex * 9 + 0] = nx; + normals[lastIndex * 9 + 1] = ny; + normals[lastIndex * 9 + 2] = nz; + + colours[lastIndex * 9 + 0] = c1[0]; + colours[lastIndex * 9 + 1] = c1[1]; + colours[lastIndex * 9 + 2] = c1[2]; + + positions[lastIndex * 9 + 3] = bx; + positions[lastIndex * 9 + 4] = by; + positions[lastIndex * 9 + 5] = bz; + + normals[lastIndex * 9 + 3] = nx; + normals[lastIndex * 9 + 4] = ny; + normals[lastIndex * 9 + 5] = nz; + + colours[lastIndex * 9 + 3] = c2[0]; + colours[lastIndex * 9 + 4] = c2[1]; + colours[lastIndex * 9 + 5] = c2[2]; + + positions[lastIndex * 9 + 6] = cx; + positions[lastIndex * 9 + 7] = cy; + positions[lastIndex * 9 + 8] = cz; + + normals[lastIndex * 9 + 6] = nx; + normals[lastIndex * 9 + 7] = ny; + normals[lastIndex * 9 + 8] = nz; + + colours[lastIndex * 9 + 6] = c3[0]; + colours[lastIndex * 9 + 7] = c3[1]; + colours[lastIndex * 9 + 8] = c3[2]; + + tops[lastIndex * 3 + 0] = t1; + tops[lastIndex * 3 + 1] = t2; + tops[lastIndex * 3 + 2] = t3; + + if (pickingIds) { + pickingIds[lastIndex * 3 + 0] = _pickingId; + pickingIds[lastIndex * 3 + 1] = _pickingId; + pickingIds[lastIndex * 3 + 2] = _pickingId; + } + + lastIndex++; + } + + var attributes = { + positions: positions, + normals: normals, + colors: colours, + tops: tops + }; + + if (pickingIds) { + attributes.pickingIds = pickingIds; + } + + return attributes; + } + }, { + key: 'isSingle', + value: function isSingle(coordinates) { + return !Array.isArray(coordinates[0][0][0]); + } + }]); + + return PolygonLayer; + })(_Layer3['default']); + + exports['default'] = PolygonLayer; + + var noNew = function noNew(coordinates, options) { + return new PolygonLayer(coordinates, options); + }; + + exports.polygonLayer = noNew; + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var _PickingShader = __webpack_require__(38); + + var _PickingShader2 = _interopRequireDefault(_PickingShader); + + // FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js + + var PickingMaterial = function PickingMaterial() { + _three2['default'].ShaderMaterial.call(this, { + uniforms: { + size: { + type: 'f', + value: 0.01 + }, + scale: { + type: 'f', + value: 400 + } + }, + // attributes: ['position', 'id'], + vertexShader: _PickingShader2['default'].vertexShader, + fragmentShader: _PickingShader2['default'].fragmentShader + }); + + this.linePadding = 2; + }; + + PickingMaterial.prototype = Object.create(_three2['default'].ShaderMaterial.prototype); + + PickingMaterial.prototype.constructor = PickingMaterial; + + PickingMaterial.prototype.setPointSize = function (size) { + this.uniforms.size.value = size; + }; + + PickingMaterial.prototype.setPointScale = function (scale) { + this.uniforms.scale.value = scale; + }; + + exports['default'] = PickingMaterial; + module.exports = exports['default']; + +/***/ }, +/* 38 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + // FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js + + var PickingShader = { + vertexShader: ['attribute float pickingId;', + // '', + // 'uniform float size;', + // 'uniform float scale;', + '', 'varying vec4 worldId;', '', 'void main() {', ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );', + // ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );', + ' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);', ' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);', ' worldId = vec4(a,1);', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'), + + fragmentShader: ['#ifdef GL_ES\n', 'precision highp float;\n', '#endif\n', '', 'varying vec4 worldId;', '', 'void main() {', ' gl_FragColor = worldId;', '}'].join('\n') + }; + + exports['default'] = PickingShader; + module.exports = exports['default']; + +/***/ }, +/* 39 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + // TODO: Move duplicated logic between geometry layrs into GeometryLayer + + // TODO: Look at ways to drop unneeded references to array buffers, etc to + // reduce memory footprint + + // TODO: Provide alternative output using tubes and splines / curves + + // TODO: Support dynamic updating / hiding / animation of geometry + // + // This could be pretty hard as it's all packed away within BufferGeometry and + // may even be merged by another layer (eg. GeoJSONLayer) + // + // How much control should this layer support? Perhaps a different or custom + // layer would be better suited for animation, for example. + + // TODO: Allow _setBufferAttributes to use a custom function passed in to + // generate a custom mesh + + var _Layer2 = __webpack_require__(4); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(6); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var _geoGeo = __webpack_require__(1); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + + var _geoLatLon = __webpack_require__(2); + + var _geoPoint = __webpack_require__(3); + + var _enginePickingMaterial = __webpack_require__(37); + + var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); + + var _utilBuffer = __webpack_require__(34); + + var _utilBuffer2 = _interopRequireDefault(_utilBuffer); + + var PolylineLayer = (function (_Layer) { + _inherits(PolylineLayer, _Layer); + + function PolylineLayer(coordinates, options) { + _classCallCheck(this, PolylineLayer); + + var defaults = { + output: true, + interactive: false, + // Custom material override + // + // TODO: Should this be in the style object? + polylineMaterial: null, + onPolylineMesh: null, + onBufferAttributes: null, + // This default style is separate to Util.GeoJSON.defaultStyle + style: { + lineOpacity: 1, + lineTransparent: false, + lineColor: '#ffffff', + lineWidth: 1, + lineBlending: _three2['default'].NormalBlending + } + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + _get(Object.getPrototypeOf(PolylineLayer.prototype), 'constructor', this).call(this, _options); + + // Return coordinates as array of lines so it's easy to support + // MultiLineString features (a single line would be a MultiLineString with a + // single line in the array) + this._coordinates = PolylineLayer.isSingle(coordinates) ? [coordinates] : coordinates; + + // Polyline features are always flat (for now at least) + this._flat = true; + } + + _createClass(PolylineLayer, [{ + key: '_onAdd', + value: function _onAdd(world) { + var _this = this; + + return new Promise(function (resolve, reject) { + _this._setCoordinates(); + + if (_this._options.interactive) { + // Only add to picking mesh if this layer is controlling output + // + // Otherwise, assume another component will eventually add a mesh to + // the picking scene + if (_this.isOutput()) { + _this._pickingMesh = new _three2['default'].Object3D(); + _this.addToPicking(_this._pickingMesh); + } + + _this._setPickingId(); + _this._addPickingEvents(); + } + + // Store geometry representation as instances of THREE.BufferAttribute + PolylineLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) { + _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes); + _this._flat = result.flat; + + var attributeLengths = { + positions: 3, + colors: 3 + }; + + if (_this._options.interactive) { + attributeLengths.pickingIds = 1; + } + + if (_this.isOutput()) { + var style = _this._options.style; + + // Set mesh if not merging elsewhere + PolylineLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options).then(function (result) { + // Output mesh + _this.add(result.mesh); + + if (result.pickingMesh) { + _this._pickingMesh.add(result.pickingMesh); + } + }); + } + + result.attributes = null; + result = null; + + resolve(_this); + }); + }); + } + + // Return center of polyline as a LatLon + // + // This is used for things like placing popups / UI elements on the layer + // + // TODO: Find proper center position instead of returning first coordinate + // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59 + }, { + key: 'getCenter', + value: function getCenter() { + return this._center; + } + + // Return line bounds in geographic coordinates + // + // TODO: Implement getBounds() + }, { + key: 'getBounds', + value: function getBounds() {} + + // Get unique ID for picking interaction + }, { + key: '_setPickingId', + value: function _setPickingId() { + this._pickingId = this.getPickingId(); + } + + // Set up and re-emit interaction events + }, { + key: '_addPickingEvents', + value: function _addPickingEvents() { + var _this2 = this; + + // TODO: Find a way to properly remove this listener on destroy + this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) { + // Re-emit click event from the layer + _this2.emit('click', _this2, point2d, point3d, intersects); + }); + } + }, { + key: 'getBufferAttributes', + value: function getBufferAttributes() { + return this._bufferAttributes; + } + + // Used by external components to clear some memory when the attributes + // are no longer required to be stored in this layer + // + // For example, you would want to clear the attributes here after merging them + // using something like the GeoJSONLayer + }, { + key: 'clearBufferAttributes', + value: function clearBufferAttributes() { + this._bufferAttributes = null; + } + + // Used by external components to clear some memory when the coordinates + // are no longer required to be stored in this layer + // + // For example, you would want to clear the coordinates here after this + // layer is merged in something like the GeoJSONLayer + }, { + key: 'clearCoordinates', + value: function clearCoordinates() { + this._coordinates = null; + this._projectedCoordinates = null; + } + }, { + key: '_setCoordinates', + + // Convert and project coordinates + // + // TODO: Calculate bounds + value: function _setCoordinates() { + this._bounds = []; + this._coordinates = this._convertCoordinates(this._coordinates); + + this._projectedBounds = []; + this._projectedCoordinates = this._projectCoordinates(); + + this._center = this._coordinates[0][0]; + } + + // Recursively convert input coordinates into LatLon objects + // + // Calculate geographic bounds at the same time + // + // TODO: Calculate geographic bounds + }, { + key: '_convertCoordinates', + value: function _convertCoordinates(coordinates) { + return coordinates.map(function (_coordinates) { + return _coordinates.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + }); + } + + // Recursively project coordinates into world positions + // + // Calculate world bounds, offset and pointScale at the same time + // + // TODO: Calculate world bounds + }, { + key: '_projectCoordinates', + value: function _projectCoordinates() { + var _this3 = this; + + var point; + return this._coordinates.map(function (_coordinates) { + return _coordinates.map(function (latlon) { + point = _this3._world.latLonToPoint(latlon); + + // TODO: Is offset ever being used or needed? + if (!_this3._offset) { + _this3._offset = (0, _geoPoint.point)(0, 0); + _this3._offset.x = -1 * point.x; + _this3._offset.y = -1 * point.y; + + _this3._options.pointScale = _this3._world.pointScale(latlon); + } + + return point; + }); + }); + } + }, { + key: 'isFlat', + + // Returns true if the line is flat (has no height) + value: function isFlat() { + return this._flat; + } + + // Returns true if coordinates refer to a single geometry + // + // For example, not coordinates for a MultiLineString GeoJSON feature + }, { + key: 'destroy', + value: function destroy() { + if (this._pickingMesh) { + // TODO: Properly dispose of picking mesh + this._pickingMesh = null; + } + + this.clearCoordinates(); + this.clearBufferAttributes(); + + // Run common destruction logic from parent + _get(Object.getPrototypeOf(PolylineLayer.prototype), 'destroy', this).call(this); + } + }], [{ + key: 'SetBufferAttributes', + value: function SetBufferAttributes(coordinates, options) { + return new Promise(function (resolve) { + var height = 0; + + // Convert height into world units + if (options.style.lineHeight) { + height = _geoGeo2['default'].metresToWorld(options.style.lineHeight, options.pointScale); + } + + var colour = new _three2['default'].Color(); + colour.set(options.style.lineColor); + + var flat = true; + + // For each line + var attributes = coordinates.map(function (_projectedCoordinates) { + var _vertices = []; + var _colours = []; + + // Connect coordinate with the next to make a pair + // + // LineSegments requires pairs of vertices so repeat the last point if + // there's an odd number of vertices + var nextCoord; + _projectedCoordinates.forEach(function (coordinate, index) { + _colours.push([colour.r, colour.g, colour.b]); + _vertices.push([coordinate.x, height, coordinate.y]); + + nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate; + + _colours.push([colour.r, colour.g, colour.b]); + _vertices.push([nextCoord.x, height, nextCoord.y]); + }); + + var line = { + vertices: _vertices, + colours: _colours, + verticesCount: _vertices.length + }; + + if (options.interactive && options.pickingId) { + // Inject picking ID + line.pickingId = options.pickingId; + } + + // Convert line representation to proper attribute arrays + return PolylineLayer.ToAttributes(line); + }); + + resolve({ + attributes: attributes, + flat: flat + }); + }); + } + }, { + key: 'SetMesh', + value: function SetMesh(attributes, attributeLengths, flat, style, options) { + var geometry = new _three2['default'].BufferGeometry(); + + for (var key in attributes) { + geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key])); + } + + geometry.computeBoundingBox(); + + var material; + if (options.polylineMaterial && options.polylineMaterial instanceof _three2['default'].Material) { + material = options.polylineMaterial; + } else { + material = new _three2['default'].LineBasicMaterial({ + vertexColors: _three2['default'].VertexColors, + linewidth: style.lineWidth, + transparent: style.lineTransparent, + opacity: style.lineOpacity, + blending: style.lineBlending + }); + } + + var mesh; + + // Pass mesh through callback, if defined + if (typeof options.onPolylineMesh === 'function') { + mesh = options.onPolylineMesh(geometry, material); + } else { + mesh = new _three2['default'].LineSegments(geometry, material); + + if (style.lineRenderOrder !== undefined) { + material.depthWrite = false; + mesh.renderOrder = style.lineRenderOrder; + } + + mesh.castShadow = true; + // mesh.receiveShadow = true; + } + + if (options.interactive) { + material = new _enginePickingMaterial2['default'](); + // material.side = THREE.BackSide; + + // Make the line wider / easier to pick + material.linewidth = style.lineWidth + material.linePadding; + + var pickingMesh = new _three2['default'].LineSegments(geometry, material); + } + + return Promise.resolve({ + mesh: mesh, + pickingMesh: pickingMesh + }); + } + }, { + key: 'ToAttributes', + value: function ToAttributes(line) { + // Three components per vertex + var vertices = new Float32Array(line.verticesCount * 3); + var colours = new Float32Array(line.verticesCount * 3); + + var pickingIds; + if (line.pickingId) { + // One component per vertex + pickingIds = new Float32Array(line.verticesCount); + } + + var _vertices = line.vertices; + var _colour = line.colours; + + var _pickingId; + if (pickingIds) { + _pickingId = line.pickingId; + } + + var lastIndex = 0; + + for (var i = 0; i < _vertices.length; i++) { + var ax = _vertices[i][0]; + var ay = _vertices[i][1]; + var az = _vertices[i][2]; + + var c1 = _colour[i]; + + vertices[lastIndex * 3 + 0] = ax; + vertices[lastIndex * 3 + 1] = ay; + vertices[lastIndex * 3 + 2] = az; + + colours[lastIndex * 3 + 0] = c1[0]; + colours[lastIndex * 3 + 1] = c1[1]; + colours[lastIndex * 3 + 2] = c1[2]; + + if (pickingIds) { + pickingIds[lastIndex] = _pickingId; + } + + lastIndex++; + } + + var attributes = { + positions: vertices, + colors: colours + }; + + if (pickingIds) { + attributes.pickingIds = pickingIds; + } + + return attributes; + } + }, { + key: 'isSingle', + value: function isSingle(coordinates) { + return !Array.isArray(coordinates[0][0]); + } + }]); + + return PolylineLayer; + })(_Layer3['default']); + + exports['default'] = PolylineLayer; + + var noNew = function noNew(coordinates, options) { + return new PolylineLayer(coordinates, options); + }; + + exports.polylineLayer = noNew; + +/***/ }, +/* 40 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + // TODO: Move duplicated logic between geometry layrs into GeometryLayer + + // TODO: Look at ways to drop unneeded references to array buffers, etc to + // reduce memory footprint + + // TODO: Point features may be using custom models / meshes and so an approach + // needs to be found to allow these to be brokwn down into buffer attributes for + // merging + // + // Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry + // and pull out the attributes + + // TODO: Support sprite objects using textures + + // TODO: Provide option to billboard geometry so it always faces the camera + + // TODO: Support dynamic updating / hiding / animation of geometry + // + // This could be pretty hard as it's all packed away within BufferGeometry and + // may even be merged by another layer (eg. GeoJSONLayer) + // + // How much control should this layer support? Perhaps a different or custom + // layer would be better suited for animation, for example. + + var _Layer2 = __webpack_require__(4); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(6); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _three = __webpack_require__(18); + + var _three2 = _interopRequireDefault(_three); + + var _geoGeo = __webpack_require__(1); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + + var _geoLatLon = __webpack_require__(2); + + var _geoPoint = __webpack_require__(3); + + var _enginePickingMaterial = __webpack_require__(37); + + var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); + + var _utilBuffer = __webpack_require__(34); + + var _utilBuffer2 = _interopRequireDefault(_utilBuffer); + + var _PolygonLayer = __webpack_require__(36); + + var _PolygonLayer2 = _interopRequireDefault(_PolygonLayer); + + var PointLayer = (function (_Layer) { + _inherits(PointLayer, _Layer); + + function PointLayer(coordinates, options) { + _classCallCheck(this, PointLayer); + + var defaults = { + output: true, + interactive: false, + // THREE.Geometry or THREE.BufferGeometry to use for point output + pointGeometry: null, + // Custom material override + // + // TODO: Should this be in the style object? + pointMaterial: null, + onPointMesh: null, + // This default style is separate to Util.GeoJSON.defaultStyle + style: { + pointColor: '#ff0000' + } + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + _get(Object.getPrototypeOf(PointLayer.prototype), 'constructor', this).call(this, _options); + + // Return coordinates as array of points so it's easy to support + // MultiPoint features (a single point would be a MultiPoint with a + // single point in the array) + this._coordinates = PointLayer.isSingle(coordinates) ? [coordinates] : coordinates; + + this._flat = false; + } + + _createClass(PointLayer, [{ + key: '_onAdd', + value: function _onAdd(world) { + var _this = this; + + return new Promise(function (resolve, reject) { + _this._setCoordinates(); + + if (_this._options.interactive) { + // Only add to picking mesh if this layer is controlling output + // + // Otherwise, assume another component will eventually add a mesh to + // the picking scene + if (_this.isOutput()) { + _this._pickingMesh = new _three2['default'].Object3D(); + _this.addToPicking(_this._pickingMesh); + } + + _this._setPickingId(); + _this._addPickingEvents(); + } + + // Store geometry representation as instances of THREE.BufferAttribute + PointLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) { + _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes); + _this._flat = result.flat; + + var attributeLengths = { + positions: 3, + normals: 3, + colors: 3 + }; + + if (_this._options.interactive) { + attributeLengths.pickingIds = 1; + } + + if (_this.isOutput()) { + var style = _this._options.style; + + // Set mesh if not merging elsewhere + // TODO: Dedupe with PolygonLayer as they are identical + PointLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) { + // Output mesh + _this.add(result.mesh); + + if (result.pickingMesh) { + _this._pickingMesh.add(result.pickingMesh); + } + }); + } + + result.attributes = null; + result = null; + + resolve(_this); + })['catch'](reject); + }); + } + + // Return center of point as a LatLon + // + // This is used for things like placing popups / UI elements on the layer + }, { + key: 'getCenter', + value: function getCenter() { + return this._center; + } + + // Return point bounds in geographic coordinates + // + // While not useful for single points, it could be useful for MultiPoint + // + // TODO: Implement getBounds() + }, { + key: 'getBounds', + value: function getBounds() {} + + // Get unique ID for picking interaction + }, { + key: '_setPickingId', + value: function _setPickingId() { + this._pickingId = this.getPickingId(); + } + + // Set up and re-emit interaction events + }, { + key: '_addPickingEvents', + value: function _addPickingEvents() { + var _this2 = this; + + // TODO: Find a way to properly remove this listener on destroy + this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) { + // Re-emit click event from the layer + _this2.emit('click', _this2, point2d, point3d, intersects); + }); + } + }, { + key: 'getBufferAttributes', + value: function getBufferAttributes() { + return this._bufferAttributes; + } + + // Used by external components to clear some memory when the attributes + // are no longer required to be stored in this layer + // + // For example, you would want to clear the attributes here after merging them + // using something like the GeoJSONLayer + }, { + key: 'clearBufferAttributes', + value: function clearBufferAttributes() { + this._bufferAttributes = null; + } + + // Used by external components to clear some memory when the coordinates + // are no longer required to be stored in this layer + // + // For example, you would want to clear the coordinates here after this + // layer is merged in something like the GeoJSONLayer + }, { + key: 'clearCoordinates', + value: function clearCoordinates() { + this._coordinates = null; + this._projectedCoordinates = null; + } + }, { + key: '_setCoordinates', + + // Convert and project coordinates + // + // TODO: Calculate bounds + value: function _setCoordinates() { + this._bounds = []; + this._coordinates = this._convertCoordinates(this._coordinates); + + this._projectedBounds = []; + this._projectedCoordinates = this._projectCoordinates(); + + this._center = this._coordinates; + } + + // Recursively convert input coordinates into LatLon objects + // + // Calculate geographic bounds at the same time + // + // TODO: Calculate geographic bounds + }, { + key: '_convertCoordinates', + value: function _convertCoordinates(coordinates) { + return coordinates.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + } + + // Recursively project coordinates into world positions + // + // Calculate world bounds, offset and pointScale at the same time + // + // TODO: Calculate world bounds + }, { + key: '_projectCoordinates', + value: function _projectCoordinates() { + var _this3 = this; + + var _point; + return this._coordinates.map(function (latlon) { + _point = _this3._world.latLonToPoint(latlon); + + // TODO: Is offset ever being used or needed? + if (!_this3._offset) { + _this3._offset = (0, _geoPoint.point)(0, 0); + _this3._offset.x = -1 * _point.x; + _this3._offset.y = -1 * _point.y; + + _this3._options.pointScale = _this3._world.pointScale(latlon); + } + + return _point; + }); + } + + // Returns true if the line is flat (has no height) + }, { + key: 'isFlat', + value: function isFlat() { + return this._flat; + } + + // Returns true if coordinates refer to a single geometry + // + // For example, not coordinates for a MultiPoint GeoJSON feature + }, { + key: 'destroy', + value: function destroy() { + if (this._pickingMesh) { + // TODO: Properly dispose of picking mesh + this._pickingMesh = null; + } + + this.clearCoordinates(); + this.clearBufferAttributes(); + + // Run common destruction logic from parent + _get(Object.getPrototypeOf(PointLayer.prototype), 'destroy', this).call(this); + } + }], [{ + key: 'SetBufferAttributes', + value: function SetBufferAttributes(coordinates, options) { + return new Promise(function (resolve) { + var height = 0; + + // Convert height into world units + if (options.style.pointHeight) { + height = _geoGeo2['default'].metresToWorld(options.style.pointHeight, options.pointScale); + } + + var colour = new _three2['default'].Color(); + colour.set(options.style.pointColor); + + // Use default geometry if none has been provided or the provided geometry + // isn't valid + if (!options.pointGeometry || !options.pointGeometry instanceof _three2['default'].Geometry || !options.pointGeometry instanceof _three2['default'].BufferGeometry) { + // Debug geometry for points is a thin bar + // + // TODO: Allow point geometry to be customised / overridden + var geometryWidth = _geoGeo2['default'].metresToWorld(25, options.pointScale); + var geometryHeight = _geoGeo2['default'].metresToWorld(200, options.pointScale); + var _geometry = new _three2['default'].BoxGeometry(geometryWidth, geometryHeight, geometryWidth); + + // Shift geometry up so it sits on the ground + _geometry.translate(0, geometryHeight * 0.5, 0); + + // Pull attributes out of debug geometry + geometry = new _three2['default'].BufferGeometry().fromGeometry(_geometry); + } else { + if (options.geometry instanceof _three2['default'].BufferGeometry) { + geometry = options.pointGeometry; + } else { + geometry = new _three2['default'].BufferGeometry().fromGeometry(options.pointGeometry); + } + } + + var attributes = coordinates.map(function (coordinate) { + var _vertices = []; + var _normals = []; + var _colours = []; + + var _geometry = geometry.clone(); + _geometry.translate(coordinate.x, height, coordinate.y); + + var _vertices = _geometry.attributes.position.clone().array; + var _normals = _geometry.attributes.normal.clone().array; + var _colours = _geometry.attributes.color.clone().array; + + for (var i = 0; i < _colours.length; i += 3) { + _colours[i] = colour.r; + _colours[i + 1] = colour.g; + _colours[i + 2] = colour.b; + } + + var _point = { + positions: _vertices, + normals: _normals, + colors: _colours + }; + + if (options.interactive && options.pickingId) { + // Inject picking ID + _point.pickingId = options.pickingId; + } + + return _point; + }); + + resolve({ + attributes: attributes, + flat: false + }); + }); + } + }, { + key: 'SetMesh', + value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) { + var geometry = new _three2['default'].BufferGeometry(); + + for (var key in attributes) { + geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key])); + } + + geometry.computeBoundingBox(); + + var material; + if (options.pointMaterial && options.pointMaterial instanceof _three2['default'].Material) { + material = options.pointMaterial; + } else if (!skybox) { + material = new _three2['default'].MeshPhongMaterial({ + vertexColors: _three2['default'].VertexColors, + // side: THREE.BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + } else { + material = new _three2['default'].MeshStandardMaterial({ + vertexColors: _three2['default'].VertexColors, + // side: THREE.BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + material.roughness = 1; + material.metalness = 0.1; + material.envMapIntensity = 3; + material.envMap = skybox.getRenderTarget(); + } + + var mesh; + + // Pass mesh through callback, if defined + if (typeof options.onPolygonMesh === 'function') { + mesh = options.onPolygonMesh(geometry, material); + } else { + mesh = new _three2['default'].Mesh(geometry, material); + + mesh.castShadow = true; + mesh.receiveShadow = true; + } + + if (flat) { + material.depthWrite = false; + mesh.renderOrder = 4; + } + + if (options.interactive) { + material = new _enginePickingMaterial2['default'](); + material.side = _three2['default'].BackSide; + + var pickingMesh = new _three2['default'].Mesh(geometry, material); + } + + return Promise.resolve({ + mesh: mesh, + pickingMesh: pickingMesh + }); + } + }, { + key: 'isSingle', + value: function isSingle(coordinates) { + return !Array.isArray(coordinates[0]); + } + }]); + + return PointLayer; + })(_Layer3['default']); + + exports['default'] = PointLayer; + + var noNew = function noNew(coordinates, options) { + return new PointLayer(coordinates, options); + }; + + exports.pointLayer = noNew; + +/***/ }, +/* 41 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // TODO: A lot of these utils don't need to be in separate, tiny files + + var _wrapNum = __webpack_require__(42); + + var _wrapNum2 = _interopRequireDefault(_wrapNum); + + var _extrudePolygon = __webpack_require__(30); + + var _extrudePolygon2 = _interopRequireDefault(_extrudePolygon); + + var _GeoJSON = __webpack_require__(25); + + var _GeoJSON2 = _interopRequireDefault(_GeoJSON); + + var _Buffer = __webpack_require__(34); + + var _Buffer2 = _interopRequireDefault(_Buffer); + + var _Worker = __webpack_require__(31); + + var _Worker2 = _interopRequireDefault(_Worker); + + var _Stringify = __webpack_require__(35); + + var _Stringify2 = _interopRequireDefault(_Stringify); + + var Util = {}; + + Util.wrapNum = _wrapNum2['default']; + Util.extrudePolygon = _extrudePolygon2['default']; + Util.GeoJSON = _GeoJSON2['default']; + Util.Buffer = _Buffer2['default']; + Util.Worker = _Worker2['default']; + Util.Stringify = _Stringify2['default']; + + exports['default'] = Util; + module.exports = exports['default']; + +/***/ }, +/* 42 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + /* + * Wrap the given number to lie within a certain range (eg. longitude) + * + * Based on: + * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js + */ + + var wrapNum = function wrapNum(x, range, includeMax) { + var max = range[1]; + var min = range[0]; + var d = max - min; + return x === max && includeMax ? x : ((x - min) % d + d) % d + min; + }; + + exports["default"] = wrapNum; + module.exports = exports["default"]; + +/***/ } +/******/ ]) +}); +; \ No newline at end of file diff --git a/dist/vizicities-worker.min.js b/dist/vizicities-worker.min.js new file mode 100644 index 0000000..53c0e20 --- /dev/null +++ b/dist/vizicities-worker.min.js @@ -0,0 +1,4 @@ +!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("THREE")):"function"==typeof define&&define.amd?define(["THREE"],t):"object"==typeof exports?exports.VIZI=t(require("THREE")):e.VIZI=t(e.THREE)}(this,function(__WEBPACK_EXTERNAL_MODULE_18__){return function(e){function t(n){if(r[n])return r[n].exports;var o=r[n]={exports:{},id:n,loaded:!1};return e[n].call(o.exports,o,o.exports,t),o.loaded=!0,o.exports}var r={};return t.m=e,t.c=r,t.p="",t(0)}([function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(1),i=n(o),s=r(4),a=n(s),u=r(22),l=n(u),c=r(36),f=n(c),p=r(3),d=n(p),h=r(2),v=n(h),y=r(41),g=n(y),_={version:"0.3",Geo:i["default"],Layer:a["default"],layer:s.layer,GeoJSONWorkerLayer:l["default"],geoJSONWorkerLayer:u.geoJSONWorkerLayer,PolygonLayer:f["default"],polygonLayer:c.polygonLayer,Point:d["default"],point:p.point,LatLon:v["default"],latLon:h.latLon,Util:g["default"]};t["default"]=_,e.exports=t["default"]},function(e,t,r){Object.defineProperty(t,"__esModule",{value:!0});var n=r(2),o=r(3),i={};i.R=6378137,i.MAX_LATITUDE=85.0511287798,i.ECC=.081819191,i.ECC2=.006694380015894481,i.project=function(e){var t=Math.PI/180,r=i.MAX_LATITUDE,n=Math.max(Math.min(r,e.lat),-r),s=Math.sin(n*t);return(0,o.point)(i.R*e.lon*t,i.R*Math.log((1+s)/(1-s))/2)},i.unproject=function(e){var t=180/Math.PI;return(0,n.latLon)((2*Math.atan(Math.exp(e.y/i.R))-Math.PI/2)*t,e.x*t/i.R)},i.latLonToPoint=function(e){var t=i.project(e);return t.y*=-1,t},i.pointToLatLon=function(e){var t=(0,o.point)(e.x,-1*e.y);return i.unproject(t)},i.pointScale=function(e,t){var r,n=Math.PI/180;if(t){var o=e.lat*n,s=(e.lon*n,i.R),a=Math.sin(o),u=a*a,l=Math.cos(o),c=s*(1-i.ECC2)/Math.pow(1-i.ECC2*u,1.5),f=s/Math.sqrt(1-i.ECC2*u),p=s/c/l;return r=s/f/l,[r,p]}return r=1/Math.cos(e.lat*n),[r,r]},i.metresToProjected=function(e,t){return e*t[1]},i.projectedToMetres=function(e,t){return e/t[1]},i.metresToWorld=function(e,t){var r=i.metresToProjected(e,t),n=i.scale(),o=n*r;return o},i.worldToMetres=function(e,t){var r=i.scale(),n=e/r,o=i.projectedToMetres(n,t);return o},i.scale=function(e){return e>=0?256*Math.pow(2,e):1},i.zoom=function(e){return Math.log(e/256)/Math.LN2},i.distance=function(e,t,r){var n,o,s,a=Math.PI/180;if(r){n=e.lat*a,o=t.lat*a;var u=e.lon*a,l=t.lon*a,c=o-n,f=l-u,p=c/2,d=f/2;s=Math.sin(p)*Math.sin(p)+Math.cos(n)*Math.cos(o)*Math.sin(d)*Math.sin(d);var h=2*Math.atan2(Math.sqrt(s),Math.sqrt(1-s));return i.R*h}return n=e.lat*a,o=t.lat*a,s=Math.sin(n)*Math.sin(o)+Math.cos(n)*Math.cos(o)*Math.cos((t.lon-e.lon)*a),i.R*Math.acos(Math.min(s,1))},i.bounds=function(){var e=i.R*Math.PI;return[[-e,-e],[e,e]]}(),t["default"]=i,e.exports=t["default"]},function(e,t){function r(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var n=function(){function e(e,t){for(var r=0;r=0;t--)e=this._object3D.children[t],e&&(this.remove(e),e.geometry&&(e.geometry.dispose(),e.geometry=null),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));if(this._domObject3D&&this._domObject3D.children)for(var e,t=this._domObject3D.children.length-1;t>=0;t--)e=this._domObject3D.children[t],e&&this.removeDOM3D(e);if(this._domObject2D&&this._domObject2D.children)for(var e,t=this._domObject2D.children.length-1;t>=0;t--)e=this._domObject2D.children[t],e&&this.removeDOM2D(e);this._domObject3D=null,this._domObject2D=null,this._world=null,this._object3D=null}}]),t}(l["default"]);t["default"]=m;var b=function(e){return new m(e)};t.layer=b},function(e,t,r){"use strict";function n(e,t,r){this.fn=e,this.context=t,this.once=r||!1}function o(){}var i=Object.prototype.hasOwnProperty,s="function"!=typeof Object.create?"~":!1;o.prototype._events=void 0,o.prototype.eventNames=function(){var e,t=this._events,r=[];if(!t)return r;for(e in t)i.call(t,e)&&r.push(s?e.slice(1):e);return Object.getOwnPropertySymbols?r.concat(Object.getOwnPropertySymbols(t)):r},o.prototype.listeners=function(e,t){var r=s?s+e:e,n=this._events&&this._events[r];if(t)return!!n;if(!n)return[];if(n.fn)return[n.fn];for(var o=0,i=n.length,a=new Array(i);i>o;o++)a[o]=n[o].fn;return a},o.prototype.emit=function(e,t,r,n,o,i){var a=s?s+e:e;if(!this._events||!this._events[a])return!1;var u,l,c=this._events[a],f=arguments.length;if("function"==typeof c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),f){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,r),!0;case 4:return c.fn.call(c.context,t,r,n),!0;case 5:return c.fn.call(c.context,t,r,n,o),!0;case 6:return c.fn.call(c.context,t,r,n,o,i),!0}for(l=1,u=new Array(f-1);f>l;l++)u[l-1]=arguments[l];c.fn.apply(c.context,u)}else{var p,d=c.length;for(l=0;d>l;l++)switch(c[l].once&&this.removeListener(e,c[l].fn,void 0,!0),f){case 1:c[l].fn.call(c[l].context);break;case 2:c[l].fn.call(c[l].context,t);break;case 3:c[l].fn.call(c[l].context,t,r);break;default:if(!u)for(p=1,u=new Array(f-1);f>p;p++)u[p-1]=arguments[p];c[l].fn.apply(c[l].context,u)}}return!0},o.prototype.on=function(e,t,r){var o=new n(t,r||this),i=s?s+e:e;return this._events||(this._events=s?{}:Object.create(null)),this._events[i]?this._events[i].fn?this._events[i]=[this._events[i],o]:this._events[i].push(o):this._events[i]=o,this},o.prototype.once=function(e,t,r){var o=new n(t,r||this,!0),i=s?s+e:e;return this._events||(this._events=s?{}:Object.create(null)),this._events[i]?this._events[i].fn?this._events[i]=[this._events[i],o]:this._events[i].push(o):this._events[i]=o,this},o.prototype.removeListener=function(e,t,r,n){var o=s?s+e:e;if(!this._events||!this._events[o])return this;var i=this._events[o],a=[];if(t)if(i.fn)(i.fn!==t||n&&!i.once||r&&i.context!==r)&&a.push(i);else for(var u=0,l=i.length;l>u;u++)(i[u].fn!==t||n&&!i[u].once||r&&i[u].context!==r)&&a.push(i[u]);return a.length?this._events[o]=1===a.length?a[0]:a:delete this._events[o],this},o.prototype.removeAllListeners=function(e){return this._events?(e?delete this._events[s?s+e:e]:this._events=s?{}:Object.create(null),this):this},o.prototype.off=o.prototype.removeListener,o.prototype.addListener=o.prototype.on,o.prototype.setMaxListeners=function(){return this},o.prefixed=s,e.exports=o},function(e,t,r){function n(e,t,r){var n=e[t];w.call(e,t)&&c(n,r)&&(void 0!==r||t in e)||(e[t]=r)}function o(e){return function(t){return null==t?void 0:t[e]}}function i(e,t,r,o){r||(r={});for(var i=-1,s=t.length;++i1?r[o-1]:void 0,s=o>2?r[2]:void 0;for(i=e.length>3&&"function"==typeof i?(o--,i):void 0,s&&u(r[0],r[1],s)&&(i=3>o?void 0:i,o=1),t=Object(t);++n-1&&e%1==0&&t>e}function u(e,t,r){if(!h(r))return!1;var n=typeof t;return("number"==n?f(r)&&a(t,r.length):"string"==n&&t in r)?c(r[t],e):!1}function l(e){var t=e&&e.constructor,r="function"==typeof t&&t.prototype||x;return e===r}function c(e,t){return e===t||e!==e&&t!==t}function f(e){return null!=e&&d(P(e))&&!p(e)}function p(e){var t=h(e)?k.call(e):"";return t==_||t==m}function d(e){return"number"==typeof e&&e>-1&&e%1==0&&g>=e}function h(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var v=r(7),y=r(8),g=9007199254740991,_="[object Function]",m="[object GeneratorFunction]",b=/^(?:0|[1-9]\d*)$/,x=Object.prototype,w=x.hasOwnProperty,k=x.toString,M=x.propertyIsEnumerable,A=!M.call({valueOf:1},"valueOf"),P=o("length"),j=s(function(e,t){if(A||l(t)||f(t))return void i(t,v(t),e);for(var r in t)w.call(t,r)&&n(e,r,t[r])});e.exports=j},function(e,t){function r(e,t){for(var r=-1,n=Array(e);++r-1&&e%1==0&&t>e}function l(e){var t=e&&e.constructor,r="function"==typeof t&&t.prototype||A;return e===r}function c(e){return p(e)&&P.call(e,"callee")&&(!O.call(e,"callee")||j.call(e)==b)}function f(e){return null!=e&&h(E(e))&&!d(e)}function p(e){return y(e)&&f(e)}function d(e){var t=v(e)?j.call(e):"";return t==x||t==w}function h(e){return"number"==typeof e&&e>-1&&e%1==0&&m>=e}function v(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function y(e){return!!e&&"object"==typeof e}function g(e){return"string"==typeof e||!T(e)&&y(e)&&j.call(e)==k}function _(e){var t=l(e);if(!t&&!f(e))return o(e);var r=a(e),i=!!r,s=r||[],c=s.length;for(var p in e)!n(e,p)||i&&("length"==p||u(p,c))||t&&"constructor"==p||s.push(p);return s}var m=9007199254740991,b="[object Arguments]",x="[object Function]",w="[object GeneratorFunction]",k="[object String]",M=/^(?:0|[1-9]\d*)$/,A=Object.prototype,P=A.hasOwnProperty,j=A.toString,O=A.propertyIsEnumerable,S=Object.getPrototypeOf,C=Object.keys,E=i("length"),T=Array.isArray;e.exports=_},function(e,t){function r(e,t,r){var n=r.length;switch(n){case 0:return e.call(t);case 1:return e.call(t,r[0]);case 2:return e.call(t,r[0],r[1]);case 3:return e.call(t,r[0],r[1],r[2])}return e.apply(t,r)}function n(e,t){if("function"!=typeof e)throw new TypeError(f);return t=A(void 0===t?e.length-1:l(t),0),function(){for(var n=arguments,o=-1,i=A(n.length-t,0),s=Array(i);++oe?-1:1;return t*d}return e===e?e:0}function l(e){var t=u(e),r=t%1;return t===t?r?t-r:t:0}function c(e){if("number"==typeof e)return e;if(a(e))return h;if(i(e)){var t=o(e.valueOf)?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(_,"");var r=b.test(e);return r||x.test(e)?w(e.slice(2),r?2:8):m.test(e)?h:+e}var f="Expected a function",p=1/0,d=1.7976931348623157e308,h=NaN,v="[object Function]",y="[object GeneratorFunction]",g="[object Symbol]",_=/^\s+|\s+$/g,m=/^[-+]0x[0-9a-f]+$/i,b=/^0b[01]+$/i,x=/^0o[0-7]+$/i,w=parseInt,k=Object.prototype,M=k.toString,A=Math.max;e.exports=n},function(e,t,r){"use strict";e.exports=r(10)},function(e,t,r){"use strict";function n(){var e="",t=Math.floor(.001*(Date.now()-d));return t===u?a++:(a=0,u=t),e+=c(l.lookup,h),e+=c(l.lookup,v),a>0&&(e+=c(l.lookup,a)),e+=c(l.lookup,t)}function o(t){return l.seed(t),e.exports}function i(t){return v=t,e.exports}function s(e){return void 0!==e&&l.characters(e),l.shuffled()}var a,u,l=r(11),c=r(13),f=r(15),p=r(16),d=1459707606518,h=6,v=r(17)||0;e.exports=n,e.exports.generate=n,e.exports.seed=o,e.exports.worker=i,e.exports.characters=s,e.exports.decode=f,e.exports.isValid=p},function(e,t,r){"use strict";function n(){p=!1}function o(e){if(!e)return void(c!==h&&(c=h,n()));if(e!==c){if(e.length!==h.length)throw new Error("Custom alphabet for shortid must be "+h.length+" unique characters. You submitted "+e.length+" characters: "+e);var t=e.split("").filter(function(e,t,r){return t!==r.lastIndexOf(e)});if(t.length)throw new Error("Custom alphabet for shortid must be "+h.length+" unique characters. These characters were not unique: "+t.join(", "));c=e,n()}}function i(e){return o(e),c}function s(e){d.seed(e),f!==e&&(n(),f=e)}function a(){c||o(h);for(var e,t=c.split(""),r=[],n=d.nextValue();t.length>0;)n=d.nextValue(),e=Math.floor(n*t.length),r.push(t.splice(e,1)[0]);return r.join("")}function u(){return p?p:p=a()}function l(e){var t=u();return t[e]}var c,f,p,d=r(12),h="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";e.exports={characters:i,seed:s,lookup:l,shuffled:u}},function(e,t){"use strict";function r(){return o=(9301*o+49297)%233280,o/233280}function n(e){o=e}var o=1;e.exports={nextValue:r,seed:n}},function(e,t,r){"use strict";function n(e,t){for(var r,n=0,i="";!r;)i+=e(t>>4*n&15|o()),r=tn;n++)if(-1===t.indexOf(e[n]))return!1;return!0}var o=r(11);e.exports=n},function(e,t){"use strict";e.exports=0},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE_18__},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(18),i=n(o);t["default"]=function(){var e=new i["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(18),i=n(o),s=function(e){i["default"].Object3D.call(this),this.element=e,this.element.style.position="absolute",this.addEventListener("removed",function(e){null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element)})};s.prototype=Object.create(i["default"].Object3D.prototype),s.prototype.constructor=s;var a=function(e){s.call(this,e)};a.prototype=Object.create(s.prototype),a.prototype.constructor=a;var u=function(){console.log("THREE.CSS3DRenderer",i["default"].REVISION);var e,t,r,n,o=new i["default"].Matrix4,u={camera:{fov:0,style:""},objects:{}},l=document.createElement("div");l.style.overflow="hidden",l.style.WebkitTransformStyle="preserve-3d",l.style.MozTransformStyle="preserve-3d",l.style.oTransformStyle="preserve-3d",l.style.transformStyle="preserve-3d",this.domElement=l;var c=document.createElement("div");c.style.WebkitTransformStyle="preserve-3d",c.style.MozTransformStyle="preserve-3d",c.style.oTransformStyle="preserve-3d",c.style.transformStyle="preserve-3d",l.appendChild(c),this.setClearColor=function(){},this.getSize=function(){return{width:e,height:t}},this.setSize=function(o,i){e=o,t=i,r=e/2,n=t/2,l.style.width=o+"px",l.style.height=i+"px",c.style.width=o+"px",c.style.height=i+"px"};var f=function(e){return Math.abs(e)l;l++)v(e.children[l],t)};this.render=function(e,o){var s=.5/Math.tan(i["default"].Math.degToRad(.5*o.fov))*t;u.camera.fov!==s&&(l.style.WebkitPerspective=s+"px",l.style.MozPerspective=s+"px",l.style.oPerspective=s+"px",l.style.perspective=s+"px",u.camera.fov=s),e.updateMatrixWorld(),null===o.parent&&o.updateMatrixWorld(),o.matrixWorldInverse.getInverse(o.matrixWorld);var a="translate3d(0,0,"+s+"px)"+p(o.matrixWorldInverse)+" translate3d("+r+"px,"+n+"px, 0)";u.camera.style!==a&&(c.style.WebkitTransform=a,c.style.MozTransform=a,c.style.oTransform=a,c.style.transform=a,u.camera.style=a),h(e,o)}};t.CSS3DObject=s,t.CSS3DSprite=a,t.CSS3DRenderer=u,i["default"].CSS3DObject=s,i["default"].CSS3DSprite=a,i["default"].CSS3DRenderer=u},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(18),i=n(o),s=function(e){i["default"].Object3D.call(this),this.element=e,this.element.style.position="absolute",this.addEventListener("removed",function(e){null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element)})};s.prototype=Object.create(i["default"].Object3D.prototype),s.prototype.constructor=s;var a=function(){console.log("THREE.CSS2DRenderer",i["default"].REVISION);var e,t,r,n,o=new i["default"].Vector3,a=new i["default"].Matrix4,u=new i["default"].Matrix4,l=new i["default"].Frustum,c=document.createElement("div");c.style.overflow="hidden",this.domElement=c,this.setSize=function(o,i){e=o,t=i,r=e/2,n=t/2,c.style.width=o+"px",c.style.height=i+"px"};var f=function p(e,t){if(e instanceof s){o.setFromMatrixPosition(e.matrixWorld),o.applyProjection(u);var i=e.element,a="translate(-50%,-50%) translate("+(o.x*r+r)+"px,"+(-o.y*n+n)+"px)";i.style.WebkitTransform=a,i.style.MozTransform=a,i.style.oTransform=a,i.style.transform=a,i.parentNode!==c&&c.appendChild(i),l.containsPoint(e.position)?i.style.display="block":i.style.display="none"}for(var f=0,d=e.children.length;d>f;f++)p(e.children[f],t)};this.render=function(e,t){e.updateMatrixWorld(),null===t.parent&&t.updateMatrixWorld(),t.matrixWorldInverse.getInverse(t.matrixWorld),a.copy(t.matrixWorldInverse.getInverse(t.matrixWorld)),u.multiplyMatrices(t.projectionMatrix,a),l.setFromMatrix((new i["default"].Matrix4).multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse)),f(e,t)}};t.CSS2DObject=s,t.CSS2DRenderer=a,i["default"].CSS2DObject=s,i["default"].CSS2DRenderer=a},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function i(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var s=function(){function e(e,t){var r=[],n=!0,o=!1,i=void 0;try{for(var s,a=e[Symbol.iterator]();!(n=(s=a.next()).done)&&(r.push(s.value),!t||r.length!==t);n=!0);}catch(u){o=!0,i=u}finally{try{!n&&a["return"]&&a["return"]()}finally{if(o)throw i}}return r}return function(t,r){if(Array.isArray(t))return t;if(Symbol.iterator in Object(t))return e(t,r);throw new TypeError("Invalid attempt to destructure non-iterable instance")}}(),a=function(){function e(e,t){for(var r=0;r0?Promise.all(t).then(function(){l()})["catch"](c):l()})})}},{key:"_processPolygonResults",value:function(e){var t=this;return new Promise(function(r,n){var o,i,a=b["default"].splitFloat32Array(e.attributes.positions),u=b["default"].splitFloat32Array(e.attributes.normals),l=b["default"].splitFloat32Array(e.attributes.colors),c=b["default"].splitFloat32Array(e.attributes.tops);e.outlineAttributes&&(o=b["default"].splitFloat32Array(e.outlineAttributes.positions),i=b["default"].splitFloat32Array(e.outlineAttributes.colors));var f;e.properties&&(f=b["default"].splitUint8Array(e.properties));for(var d,h,v,g,_=e.flats,m=[],x=[],w={positions:3,normals:3,colors:3,tops:1},k={positions:3,colors:3},M=0;M0){var D=b["default"].mergeAttributes(O);T="function"==typeof t._options.style?t._options.style(m[0]):t._options.style,T=(0,p["default"])({},y["default"].defaultStyle,T),F.push(t._setPolygonMesh(D,w,T,C))}if(S.length>0){var I=b["default"].mergeAttributes(S);T="function"==typeof t._options.style?t._options.style(m[0]):t._options.style,T=(0,p["default"])({},y["default"].defaultStyle,T),void 0!==T.outlineRenderOrder?T.lineRenderOrder=T.outlineRenderOrder:T.lineRenderOrder=T.renderOrder?T.renderOrder+1:4,T.outlineWidth&&(T.lineWidth=T.outlineWidth),F.push(t._setPolylineMesh(I,k,T,!0))}Promise.all(F).then(function(e){var n=s(e,2),o=n[0],i=n[1];o&&(t._polygonMesh=o.mesh,t.add(t._polygonMesh),o.pickingMesh&&t._pickingMesh.add(o.pickingMesh)),i&&t.add(i.mesh),r()})["catch"](n)})}},{key:"_processPolylineResults",value:function(e){var t=this;return new Promise(function(r,n){var o,i=b["default"].splitFloat32Array(e.attributes.positions),s=b["default"].splitFloat32Array(e.attributes.colors);e.properties&&(o=b["default"].splitUint8Array(e.properties));for(var a,u,l,c,f=e.flats,d=[],h={positions:3,colors:3},v=0;v0){var M=b["default"].mergeAttributes(x),A="function"==typeof t._options.style?t._options.style(d[0]):t._options.style;A=(0,p["default"])({},y["default"].defaultStyle,A),t._setPolylineMesh(M,h,A,w).then(function(e){t._polylineMesh=e.mesh,t.add(t._polylineMesh),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh),r()})["catch"](n)}else r()})}},{key:"_processPointResults",value:function(e){var t=this;return new Promise(function(r,n){var o,i=b["default"].splitFloat32Array(e.attributes.positions),s=b["default"].splitFloat32Array(e.attributes.normals),a=b["default"].splitFloat32Array(e.attributes.colors);e.properties&&(o=b["default"].splitUint8Array(e.properties));for(var u,l,c,f,d=e.flats,h=[],v={positions:3,normals:3,colors:3},g=0;g0){var A=b["default"].mergeAttributes(w),P="function"==typeof t._options.style?t._options.style(h[0]):t._options.style;P=(0,p["default"])({},y["default"].defaultStyle,P),t._setPointMesh(A,v,P,k).then(function(e){ +t._pointMesh=e.mesh,t.add(t._pointMesh),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh),r()})["catch"](n)}else r()})}},{key:"_setPolygonMesh",value:function(e,t,r,n){return this._world?M["default"].SetMesh(e,t,n,r,this._options,this._world._environment._skybox):Promise.reject()}},{key:"_setPolylineMesh",value:function(e,t,r,n){return this._world?P["default"].SetMesh(e,t,n,r,this._options):Promise.reject()}},{key:"_setPointMesh",value:function(e,t,r,n){return this._world?O["default"].SetMesh(e,t,n,r,this._options,this._world._environment._skybox):Promise.reject()}},{key:"_addPicking",value:function(e,t){var r=this;this._world.on("pick-click-"+e,function(e,n,o,i){r._world.emit("click",r,t,n,o)}),this._world.on("pick-hover-"+e,function(e,n,o,i){r._world.emit("hover",r,t,n,o)})}},{key:"destroy",value:function(){u(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}],[{key:"Process",value:function(e,r,n,o,i,s,a){return new Promise(function(u,l){t.ProcessGeoJSON(e,n).then(function(e){var n,l=y["default"].collectFeatures(e,r),c=l.features,f=[],d=[],h=[];"string"==typeof i&&(i=w["default"].stringToFunction(i));var v,g=i;"string"==typeof a&&(v=w["default"].stringToFunction(a));for(var _,m=0;m0;)self._completeHandlers.shift()(e)}function success(resp){var type=o.type||resp&&setType(resp.getResponseHeader("Content-Type"));resp="jsonp"!==type?self.request:resp;var filteredResponse=globalSetupOptions.dataFilter(resp.responseText,type),r=filteredResponse;try{resp.responseText=r}catch(e){}if(r)switch(type){case"json":try{resp=context.JSON?context.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r;break;case"xml":resp=resp.responseXML&&resp.responseXML.parseError&&resp.responseXML.parseError.errorCode&&resp.responseXML.parseError.reason?null:resp.responseXML}for(self._responseArgs.resp=resp,self._fulfilled=!0,fn(resp),self._successHandler(resp);self._fulfillmentHandlers.length>0;)resp=self._fulfillmentHandlers.shift()(resp);complete(resp)}function timedOut(){self._timedOut=!0,self.request.abort()}function error(e,t,r){for(e=self.request,self._responseArgs.resp=e,self._responseArgs.msg=t,self._responseArgs.t=r,self._erred=!0;self._errorHandlers.length>0;)self._errorHandlers.shift()(e,t,r);complete(e)}this.url="string"==typeof o?o:o.url,this.timeout=null,this._fulfilled=!1,this._successHandler=function(){},this._fulfillmentHandlers=[],this._errorHandlers=[],this._completeHandlers=[],this._erred=!1,this._responseArgs={};var self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){timedOut()},o.timeout)),o.success&&(this._successHandler=function(){o.success.apply(o,arguments)}),o.error&&this._errorHandlers.push(function(){o.error.apply(o,arguments)}),o.complete&&this._completeHandlers.push(function(){o.complete.apply(o,arguments)}),this.request=getRequest.call(this,success,error)}function reqwest(e,t){return new Reqwest(e,t)}function normalize(e){return e?e.replace(/\r?\n/g,"\r\n"):""}function serial(e,t){var r,n,o,i,s=e.name,a=e.tagName.toLowerCase(),u=function(e){e&&!e.disabled&&t(s,normalize(e.attributes.value&&e.attributes.value.specified?e.value:e.text))};if(!e.disabled&&s)switch(a){case"input":/reset|button|image|file/i.test(e.type)||(r=/checkbox/i.test(e.type),n=/radio/i.test(e.type),o=e.value,(!(r||n)||e.checked)&&t(s,normalize(r&&""===o?"on":o)));break;case"textarea":t(s,normalize(e.value));break;case"select":if("select-one"===e.type.toLowerCase())u(e.selectedIndex>=0?e.options[e.selectedIndex]:null);else for(i=0;e.length&&is;s++)r.vertices.push(e[o][i][s]);o>0&&(n+=e[o-1].length,r.holes.push(n))}return r},u=function(e,t,r){var n=(0,d["default"])(e,t,r),o=[];for(i=0,il=n.length;ir;){var o=r+n>>>1;e[o]e?~e:e],i=0,s=n.length;s>i;++i)t.push(r=n[i].slice()),c(r,i);0>e&&o(t,s)}function i(e){return e=e.slice(),c(e,0),e}function s(e){for(var t=[],r=0,o=e.length;o>r;++r)n(e[r],t);return t.length<2&&t.push(t[0].slice()),t}function a(e){for(var t=s(e);t.length<4;)t.push(t[0].slice());return t}function u(e){return e.map(a)}function l(e){var t=e.type;return"GeometryCollection"===t?{type:t,geometries:e.geometries.map(l)}:t in p?{type:t,coordinates:p[t](e)}:null}var c=r(e.transform),f=e.arcs,p={Point:function(e){return i(e.coordinates)},MultiPoint:function(e){return e.coordinates.map(i)},LineString:function(e){return s(e.arcs)},MultiLineString:function(e){return e.arcs.map(s)},Polygon:function(e){return u(e.arcs)},MultiPolygon:function(e){return e.arcs.map(u)}};return l(t)}function l(e,t){function r(t){var r,n=e.arcs[0>t?~t:t],o=n[0];return e.transform?(r=[0,0],n.forEach(function(e){r[0]+=e[0],r[1]+=e[1]})):r=n[n.length-1],0>t?[r,o]:[o,r]}function n(e,t){for(var r in e){var n=e[r];delete t[n.start],delete n.start,delete n.end,n.forEach(function(e){o[0>e?~e:e]=1}),a.push(n)}}var o={},i={},s={},a=[],u=-1;return t.forEach(function(r,n){var o,i=e.arcs[0>r?~r:r];i.length<3&&!i[1][0]&&!i[1][1]&&(o=t[++u],t[u]=r,t[n]=o)}),t.forEach(function(e){var t,n,o=r(e),a=o[0],u=o[1];if(t=s[a])if(delete s[t.end],t.push(e),t.end=u,n=i[u]){delete i[n.start];var l=n===t?t:t.concat(n);i[l.start=t.start]=s[l.end=n.end]=l}else i[t.start]=s[t.end]=t;else if(t=i[u])if(delete i[t.start],t.unshift(e),t.start=a,n=s[a]){delete s[n.end];var c=n===t?t:n.concat(t);i[c.start=n.start]=s[c.end=t.end]=c}else i[t.start]=s[t.end]=t;else t=[e],i[t.start=a]=s[t.end=u]=t}),n(s,i),n(i,s),t.forEach(function(e){o[0>e?~e:e]||a.push([e])}),a}function c(e){return u(e,f.apply(this,arguments))}function f(e,t,r){function n(e){var t=0>e?~e:e;(c[t]||(c[t]=[])).push({i:e,g:u})}function o(e){e.forEach(n)}function i(e){e.forEach(o)}function s(e){"GeometryCollection"===e.type?e.geometries.forEach(s):e.type in f&&(u=e,f[e.type](e.arcs))}var a=[];if(arguments.length>1){var u,c=[],f={LineString:o,MultiLineString:i,Polygon:i,MultiPolygon:function(e){e.forEach(i)}};s(t),c.forEach(arguments.length<3?function(e){a.push(e[0].i)}:function(e){r(e[0].g,e[e.length-1].g)&&a.push(e[0].i)})}else for(var p=0,d=e.arcs.length;d>p;++p)a.push(p);return{type:"MultiLineString",arcs:l(e,a)}}function p(e){var t=e[0],r=e[1],n=e[2];return Math.abs((t[0]-n[0])*(r[1]-t[1])-(t[0]-r[0])*(n[1]-t[1]))}function d(e){for(var t,r=-1,n=e.length,o=e[n-1],i=0;++rt?~t:t]||(o[t]=[])).push(e)})}),i.push(e)}function n(t){return Math.abs(d(u(e,{type:"Polygon",arcs:[t]}).coordinates[0]))}var o={},i=[],s=[];return t.forEach(function(e){"Polygon"===e.type?r(e.arcs):"MultiPolygon"===e.type&&e.arcs.forEach(r)}),i.forEach(function(e){if(!e._){var t=[],r=[e];for(e._=1,s.push(t);e=r.pop();)t.push(e),e.forEach(function(e){e.forEach(function(e){o[0>e?~e:e].forEach(function(e){e._||(e._=1,r.push(e))})})})}}),i.forEach(function(e){delete e._}),{type:"MultiPolygon",arcs:s.map(function(t){var r,i=[];if(t.forEach(function(e){e.forEach(function(e){e.forEach(function(e){o[0>e?~e:e].length<2&&i.push(e)})})}),i=l(e,i),(r=i.length)>1)for(var s,a,u=1,c=n(i[0]);r>u;++u)(s=n(i[u]))>c&&(a=i[0],i[0]=i[u],i[u]=a,c=s);return i})}}function y(e){function t(e,t){e.forEach(function(e){0>e&&(e=~e);var r=o[e];r?r.push(t):o[e]=[t]})}function r(e,r){e.forEach(function(e){t(e,r)})}function n(e,t){"GeometryCollection"===e.type?e.geometries.forEach(function(e){n(e,t)}):e.type in a&&a[e.type](e.arcs,t)}var o={},s=e.map(function(){return[]}),a={LineString:t,MultiLineString:r,Polygon:r,MultiPolygon:function(e,t){e.forEach(function(e){r(e,t)})}};e.forEach(n);for(var u in o)for(var l=o[u],c=l.length,f=0;c>f;++f)for(var p=f+1;c>p;++p){var d,h=l[f],v=l[p];(d=s[h])[u=i(d,v)]!==v&&d.splice(u,0,v),(d=s[v])[u=i(d,h)]!==h&&d.splice(u,0,h)}return s}function g(e,t){return e[1][2]-t[1][2]}function _(){function e(e,t){for(;t>0;){var r=(t+1>>1)-1,o=n[r];if(g(e,o)>=0)break;n[o._=t]=o,n[e._=t=r]=e}}function t(e,t){for(;;){var r=t+1<<1,i=r-1,s=t,a=n[s];if(o>i&&g(n[i],a)<0&&(a=n[s=i]),o>r&&g(n[r],a)<0&&(a=n[s=r]),s===t)break;n[a._=t]=a,n[e._=t=s]=e}}var r={},n=[],o=0;return r.push=function(t){return e(n[t._=o]=t,o++),o},r.pop=function(){if(!(0>=o)){var e,r=n[0];return--o>0&&(e=n[o],t(n[e._=0]=e,0)),r}},r.remove=function(r){var i,s=r._;if(n[s]===r)return s!==--o&&(i=n[o],(g(i,r)<0?e:t)(n[i._=s]=i,s)),s},r}function m(e,t){function o(e){a.remove(e),e[1][2]=t(e),a.push(e)}var i=r(e.transform),s=n(e.transform),a=_();return t||(t=p),e.arcs.forEach(function(e){var r,n,u,l,c=[],f=0;for(n=0,u=e.length;u>n;++n)l=e[n],i(e[n]=[l[0],l[1],1/0],n);for(n=1,u=e.length-1;u>n;++n)r=e.slice(n-1,n+2),r[1][2]=t(r),c.push(r),a.push(r);for(n=0,u=c.length;u>n;++n)r=c[n],r.previous=c[n-1],r.next=c[n+1];for(;r=a.pop();){var p=r.previous,d=r.next;r[1][2]80*r){l=p=e[0],f=d=e[1];for(var g=r;s>g;g+=r)h=e[g],v=e[g+1],l>h&&(l=h),f>v&&(f=v),h>p&&(p=h),v>d&&(d=v);y=Math.max(p-l,d-f)}return i(a,u,r,l,f,y),u}function n(e,t,r,n,o){var i,s;if(o===C(e,t,r,n)>0)for(i=t;r>i;i+=n)s=j(i,e[i],e[i+1],s);else for(i=r-n;i>=t;i-=n)s=j(i,e[i],e[i+1],s);return s&&x(s,s.next)&&(O(s),s=s.next),s}function o(e,t){if(!e)return e;t||(t=e);var r,n=e;do if(r=!1,n.steiner||!x(n,n.next)&&0!==b(n.prev,n,n.next))n=n.next;else{if(O(n),n=t=n.prev,n===n.next)return null;r=!0}while(r||n!==t);return t}function i(e,t,r,n,c,f,p){if(e){!p&&f&&h(e,n,c,f);for(var d,v,y=e;e.prev!==e.next;)if(d=e.prev,v=e.next,f?a(e,n,c,f):s(e))t.push(d.i/r),t.push(e.i/r),t.push(v.i/r),O(e),e=v.next,y=v.next;else if(e=v,e===y){p?1===p?(e=u(e,t,r),i(e,t,r,n,c,f,2)):2===p&&l(e,t,r,n,c,f):i(o(e),t,r,n,c,f,1);break}}}function s(e){var t=e.prev,r=e,n=e.next;if(b(t,r,n)>=0)return!1;for(var o=e.next.next;o!==e.prev;){if(_(t.x,t.y,r.x,r.y,n.x,n.y,o.x,o.y)&&b(o.prev,o,o.next)>=0)return!1;o=o.next}return!0}function a(e,t,r,n){var o=e.prev,i=e,s=e.next;if(b(o,i,s)>=0)return!1;for(var a=o.xi.x?o.x>s.x?o.x:s.x:i.x>s.x?i.x:s.x,c=o.y>i.y?o.y>s.y?o.y:s.y:i.y>s.y?i.y:s.y,f=y(a,u,t,r,n),p=y(l,c,t,r,n),d=e.nextZ;d&&d.z<=p;){if(d!==e.prev&&d!==e.next&&_(o.x,o.y,i.x,i.y,s.x,s.y,d.x,d.y)&&b(d.prev,d,d.next)>=0)return!1;d=d.nextZ}for(d=e.prevZ;d&&d.z>=f;){if(d!==e.prev&&d!==e.next&&_(o.x,o.y,i.x,i.y,s.x,s.y,d.x,d.y)&&b(d.prev,d,d.next)>=0)return!1;d=d.prevZ}return!0}function u(e,t,r){var n=e;do{var o=n.prev,i=n.next.next;!x(o,i)&&w(o,n,n.next,i)&&M(o,i)&&M(i,o)&&(t.push(o.i/r),t.push(n.i/r),t.push(i.i/r),O(n),O(n.next),n=e=i),n=n.next}while(n!==e);return n}function l(e,t,r,n,s,a){var u=e;do{for(var l=u.next.next;l!==u.prev;){if(u.i!==l.i&&m(u,l)){var c=P(u,l);return u=o(u,u.next),c=o(c,c.next),i(u,t,r,n,s,a),void i(c,t,r,n,s,a)}l=l.next}u=u.next}while(u!==e)}function c(e,t,r,i){var s,a,u,l,c,d=[];for(s=0,a=t.length;a>s;s++)u=t[s]*i,l=a-1>s?t[s+1]*i:e.length,c=n(e,u,l,i,!1),c===c.next&&(c.steiner=!0),d.push(g(c));for(d.sort(f),s=0;s=n.next.y){var a=n.x+(i-n.y)*(n.next.x-n.x)/(n.next.y-n.y);if(o>=a&&a>s){if(s=a,a===o){if(i===n.y)return n;if(i===n.next.y)return n.next}r=n.x=n.x&&n.x>=c&&_(f>i?o:s,i,c,f,f>i?s:o,i,n.x,n.y)&&(u=Math.abs(i-n.y)/(o-n.x),(p>u||u===p&&n.x>r.x)&&M(n,e)&&(r=n,p=u)),n=n.next;return r}function h(e,t,r,n){var o=e;do null===o.z&&(o.z=y(o.x,o.y,t,r,n)),o.prevZ=o.prev,o.nextZ=o.next,o=o.next;while(o!==e);o.prevZ.nextZ=null,o.prevZ=null,v(o)}function v(e){var t,r,n,o,i,s,a,u,l=1;do{for(r=e,e=null,i=null,s=0;r;){for(s++,n=r,a=0,t=0;l>t&&(a++,n=n.nextZ,n);t++);for(u=l;a>0||u>0&&n;)0===a?(o=n,n=n.nextZ,u--):0!==u&&n?r.z<=n.z?(o=r,r=r.nextZ,a--):(o=n,n=n.nextZ,u--):(o=r,r=r.nextZ,a--),i?i.nextZ=o:e=o,o.prevZ=i,i=o;r=n}i.nextZ=null,l*=2}while(s>1);return e}function y(e,t,r,n,o){return e=32767*(e-r)/o,t=32767*(t-n)/o,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function g(e){var t=e,r=e;do t.x=0&&(e-s)*(n-a)-(r-s)*(t-a)>=0&&(r-s)*(i-a)-(o-s)*(n-a)>=0}function m(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!k(e,t)&&M(e,t)&&M(t,e)&&A(e,t)}function b(e,t,r){return(t.y-e.y)*(r.x-t.x)-(t.x-e.x)*(r.y-t.y)}function x(e,t){return e.x===t.x&&e.y===t.y}function w(e,t,r,n){return x(e,t)&&x(r,n)||x(e,n)&&x(r,t)?!0:b(e,t,r)>0!=b(e,t,n)>0&&b(r,n,e)>0!=b(r,n,t)>0}function k(e,t){var r=e;do{if(r.i!==e.i&&r.next.i!==e.i&&r.i!==t.i&&r.next.i!==t.i&&w(r,r.next,e,t))return!0;r=r.next}while(r!==e);return!1}function M(e,t){return b(e.prev,e,e.next)<0?b(e,t,e.next)>=0&&b(e,e.prev,t)>=0:b(e,t,e.prev)<0||b(e,e.next,t)<0}function A(e,t){var r=e,n=!1,o=(e.x+t.x)/2,i=(e.y+t.y)/2;do r.y>i!=r.next.y>i&&o<(r.next.x-r.x)*(i-r.y)/(r.next.y-r.y)+r.x&&(n=!n),r=r.next;while(r!==e);return n}function P(e,t){var r=new S(e.i,e.x,e.y),n=new S(t.i,t.x,t.y),o=e.next,i=t.prev;return e.next=t,t.prev=e,r.next=o,o.prev=r,n.next=r,r.prev=n,i.next=n,n.prev=i,n}function j(e,t,r,n){var o=new S(e,t,r);return n?(o.next=n.next,o.prev=n,n.next.prev=o,n.next=o):(o.prev=o,o.next=o),o}function O(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function S(e,t,r){this.i=e,this.x=t,this.y=r,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function C(e,t,r,n){for(var o=0,i=t,s=r-n;r>i;i+=n)o+=(e[s]-e[i])*(e[i+1]+e[s+1]),s=i;return o}e.exports=r,r.deviation=function(e,t,r,n){var o=t&&t.length,i=o?t[0]*r:e.length,s=Math.abs(C(e,0,i,r));if(o)for(var a=0,u=t.length;u>a;a++){var l=t[a]*r,c=u-1>a?t[a+1]*r:e.length;s-=Math.abs(C(e,l,c,r))}var f=0;for(a=0;as;s++)r.vertices.push(e[o][i][s]);o>0&&(n+=e[o-1].length,r.holes.push(n))}return r}},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(6),i=n(o),s=function(e,t,r){function n(){s=e.map(function(e){return[e[0],p.top,e[1]]}),a=t,u=t}function o(){s=[],e.forEach(function(e){s.push([e[0],p.top,e[1]])}),e.forEach(function(e){s.push([e[0],p.bottom,e[1]])}),a=[];for(var r=0;d>r;r++)r===d-1?(a.push([r+d,d,r]), +a.push([0,r,d])):(a.push([r+d,r+d+1,r]),a.push([r+1,r,r+d+1]));if(c=[].concat(a),p.closed){var n=t,o=n.map(function(e){return e.map(function(e){return e+d})});o=o.map(function(e){return[e[0],e[2],e[1]]}),a=a.concat(n).concat(o),u=n,l=o}}var s,a,u,l,c,f={top:1,bottom:0,closed:!0},p=(0,i["default"])({},f,r),d=e.length;return p.top===p.bottom?n():o(),{positions:s,faces:a,top:u,bottom:l,sides:c}};t["default"]=s,e.exports=t["default"]},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var o=r(32),i=n(o),s=function(){var e,t=2,r=function(r,n){return e=new i["default"]({numThreads:r?r:t,workerScript:n?n:"vizicities-worker.js"}),e.createWorkers()},n=function(t,r,n){return e.exec(t,r,n)};return{createWorkers:r,exec:n}}();t["default"]=s,e.exports=t["default"]},function(e,t,r){function n(e){return e&&e.__esModule?e:{"default":e}}function o(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var i=function(){function e(e,t){for(var r=0;r0&&(r._outlineBufferAttributes=P["default"].mergeAttributes(n.outlineAttributes)),r._flat=n.flat,r.isOutput()){var o={positions:3,normals:3,colors:3,tops:1};r._options.interactive&&(o.pickingIds=1);var i=r._options.style;t.SetMesh(r._bufferAttributes,o,r._flat,i,r._options,r._world._environment._skybox).then(function(e){r.add(e.mesh),e.pickingMesh&&r._pickingMesh.add(e.pickingMesh)})}n.attributes=null,n.outlineAttributes=null,n=null,e(r)})["catch"](n)})}},{key:"getCenter",value:function(){return this._center}},{key:"getBounds",value:function(){}},{key:"_setPickingId",value:function(){this._pickingId=this.getPickingId()}},{key:"_addPickingEvents",value:function(){var e=this;this._world.on("pick-"+this._pickingId,function(t,r,n){e.emit("click",e,t,r,n)})}},{key:"getBufferAttributes",value:function(){return this._bufferAttributes}},{key:"getOutlineBufferAttributes",value:function(){return this._outlineBufferAttributes}},{key:"clearBufferAttributes",value:function(){this._bufferAttributes=null,this._outlineBufferAttributes=null}},{key:"clearCoordinates",value:function(){this._coordinates=null,this._projectedCoordinates=null}},{key:"_setCoordinates",value:function(){this._bounds=[],this._coordinates=this._convertCoordinates(this._coordinates),this._projectedBounds=[],this._projectedCoordinates=this._projectCoordinates(),this._center=this._coordinates[0][0][0]}},{key:"_convertCoordinates",value:function(e){return e.map(function(e){return e.map(function(e){return e.map(function(e){return(0,g.latLon)(e[1],e[0])})})})}},{key:"_projectCoordinates",value:function(){var e,t=this;return this._coordinates.map(function(r){return r.map(function(r){return r.map(function(r){return e=t._world.latLonToPoint(r),t._offset||(t._offset=(0,_.point)(0,0),t._offset.x=-1*e.x,t._offset.y=-1*e.y,t._options.pointScale=t._world.pointScale(r)),e})})})}},{key:"isFlat",value:function(){return this._flat}},{key:"destroy",value:function(){this._pickingMesh&&(this._pickingMesh=null),this.clearCoordinates(),this.clearBufferAttributes(),u(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}],[{key:"SetBufferAttributes",value:function(e,r){return new Promise(function(n){var o=0;r.style.height&&0!==r.style.height&&(o=y["default"].metresToWorld(r.style.height,r.pointScale));var s=new h["default"].Color;s.set(r.style.color);var a=new h["default"].Color(16777215),u=new h["default"].Color(6710886),l=!0,c=[],f=e.map(function(e){var n=t.ToEarcut(e),f=t.Triangulate(n.vertices,n.holes,n.dimensions),p=[];for(i=0,il=n.vertices.length;i0&&(n+=e[o-1].length,r.holes.push(n))}return r}},{key:"Triangulate",value:function(e,t,r){var n=(0,b["default"])(e,t,r),o=[];for(i=0,il=n.length;i= 0) {\n\t return 256 * Math.pow(2, zoom);\n\t // Else, return fixed scale value to expand projected coordinates from\n\t // their 0 to 1 range into something more practical\n\t } else {\n\t return 1;\n\t }\n\t};\n\t\n\t// Returns zoom level for a given scale value\n\t// This only works with a scale value that is based on map pixel width\n\tGeo.zoom = function (scale) {\n\t return Math.log(scale / 256) / Math.LN2;\n\t};\n\t\n\t// Distance between two geographical points using spherical law of cosines\n\t// approximation or Haversine\n\t//\n\t// See: http://www.movable-type.co.uk/scripts/latlong.html\n\tGeo.distance = function (latlon1, latlon2, accurate) {\n\t var rad = Math.PI / 180;\n\t\n\t var lat1;\n\t var lat2;\n\t\n\t var a;\n\t\n\t if (!accurate) {\n\t lat1 = latlon1.lat * rad;\n\t lat2 = latlon2.lat * rad;\n\t\n\t a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);\n\t\n\t return Geo.R * Math.acos(Math.min(a, 1));\n\t } else {\n\t lat1 = latlon1.lat * rad;\n\t lat2 = latlon2.lat * rad;\n\t\n\t var lon1 = latlon1.lon * rad;\n\t var lon2 = latlon2.lon * rad;\n\t\n\t var deltaLat = lat2 - lat1;\n\t var deltaLon = lon2 - lon1;\n\t\n\t var halfDeltaLat = deltaLat / 2;\n\t var halfDeltaLon = deltaLon / 2;\n\t\n\t a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);\n\t\n\t var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\t\n\t return Geo.R * c;\n\t }\n\t};\n\t\n\tGeo.bounds = (function () {\n\t var d = Geo.R * Math.PI;\n\t return [[-d, -d], [d, d]];\n\t})();\n\t\n\texports['default'] = Geo;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 2 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\t/*\n\t * LatLon is a helper class for ensuring consistent geographic coordinates.\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js\n\t */\n\t\n\tvar LatLon = (function () {\n\t function LatLon(lat, lon, alt) {\n\t _classCallCheck(this, LatLon);\n\t\n\t if (isNaN(lat) || isNaN(lon)) {\n\t throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');\n\t }\n\t\n\t this.lat = +lat;\n\t this.lon = +lon;\n\t\n\t if (alt !== undefined) {\n\t this.alt = +alt;\n\t }\n\t }\n\t\n\t _createClass(LatLon, [{\n\t key: 'clone',\n\t value: function clone() {\n\t return new LatLon(this.lat, this.lon, this.alt);\n\t }\n\t }]);\n\t\n\t return LatLon;\n\t})();\n\t\n\texports['default'] = LatLon;\n\t\n\t// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)\n\t// Also converts between lng and lon\n\tvar noNew = function noNew(a, b, c) {\n\t if (a instanceof LatLon) {\n\t return a;\n\t }\n\t if (Array.isArray(a) && typeof a[0] !== 'object') {\n\t if (a.length === 3) {\n\t return new LatLon(a[0], a[1], a[2]);\n\t }\n\t if (a.length === 2) {\n\t return new LatLon(a[0], a[1]);\n\t }\n\t return null;\n\t }\n\t if (a === undefined || a === null) {\n\t return a;\n\t }\n\t if (typeof a === 'object' && 'lat' in a) {\n\t return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\n\t }\n\t if (b === undefined) {\n\t return null;\n\t }\n\t return new LatLon(a, b, c);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.latLon = noNew;\n\n/***/ },\n/* 3 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/*\n\t * Point is a helper class for ensuring consistent world positions.\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js\n\t */\n\t\n\tvar Point = (function () {\n\t function Point(x, y, round) {\n\t _classCallCheck(this, Point);\n\t\n\t this.x = round ? Math.round(x) : x;\n\t this.y = round ? Math.round(y) : y;\n\t }\n\t\n\t _createClass(Point, [{\n\t key: \"clone\",\n\t value: function clone() {\n\t return new Point(this.x, this.y);\n\t }\n\t\n\t // Non-destructive\n\t }, {\n\t key: \"add\",\n\t value: function add(point) {\n\t return this.clone()._add(_point(point));\n\t }\n\t\n\t // Destructive\n\t }, {\n\t key: \"_add\",\n\t value: function _add(point) {\n\t this.x += point.x;\n\t this.y += point.y;\n\t return this;\n\t }\n\t\n\t // Non-destructive\n\t }, {\n\t key: \"subtract\",\n\t value: function subtract(point) {\n\t return this.clone()._subtract(_point(point));\n\t }\n\t\n\t // Destructive\n\t }, {\n\t key: \"_subtract\",\n\t value: function _subtract(point) {\n\t this.x -= point.x;\n\t this.y -= point.y;\n\t return this;\n\t }\n\t }]);\n\t\n\t return Point;\n\t})();\n\t\n\texports[\"default\"] = Point;\n\t\n\t// Accepts (point), ([x, y]) and (x, y, round)\n\tvar _point = function _point(x, y, round) {\n\t if (x instanceof Point) {\n\t return x;\n\t }\n\t if (Array.isArray(x)) {\n\t return new Point(x[0], x[1]);\n\t }\n\t if (x === undefined || x === null) {\n\t return x;\n\t }\n\t return new Point(x, y, round);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.point = _point;\n\n/***/ },\n/* 4 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(5);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _lodashAssign = __webpack_require__(6);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _shortid = __webpack_require__(9);\n\t\n\tvar _shortid2 = _interopRequireDefault(_shortid);\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _engineScene = __webpack_require__(19);\n\t\n\tvar _engineScene2 = _interopRequireDefault(_engineScene);\n\t\n\tvar _vendorCSS3DRenderer = __webpack_require__(20);\n\t\n\tvar _vendorCSS2DRenderer = __webpack_require__(21);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Need a single move method that handles moving all the various object\n\t// layers so that the DOM layers stay in sync with the 3D layer\n\t\n\t// TODO: Double check that objects within the _object3D Object3D parent are frustum\n\t// culled even if the layer position stays at the default (0,0,0) and the child\n\t// objects are positioned much further away\n\t//\n\t// Or does the layer being at (0,0,0) prevent the child objects from being\n\t// culled because the layer parent is effectively always in view even if the\n\t// child is actually out of camera\n\t\n\tvar Layer = (function (_EventEmitter) {\n\t _inherits(Layer, _EventEmitter);\n\t\n\t function Layer(options) {\n\t _classCallCheck(this, Layer);\n\t\n\t _get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this);\n\t\n\t var defaults = {\n\t id: _shortid2['default'].generate(),\n\t output: true,\n\t outputToScene: true\n\t };\n\t\n\t this._options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (this.isOutput()) {\n\t this._object3D = new _three2['default'].Object3D();\n\t\n\t this._dom3D = document.createElement('div');\n\t this._domObject3D = new _vendorCSS3DRenderer.CSS3DObject(this._dom3D);\n\t\n\t this._dom2D = document.createElement('div');\n\t this._domObject2D = new _vendorCSS2DRenderer.CSS2DObject(this._dom2D);\n\t }\n\t }\n\t\n\t // Add THREE object directly to layer\n\t\n\t _createClass(Layer, [{\n\t key: 'add',\n\t value: function add(object) {\n\t this._object3D.add(object);\n\t }\n\t\n\t // Remove THREE object from to layer\n\t }, {\n\t key: 'remove',\n\t value: function remove(object) {\n\t this._object3D.remove(object);\n\t }\n\t }, {\n\t key: 'addDOM3D',\n\t value: function addDOM3D(object) {\n\t this._domObject3D.add(object);\n\t }\n\t }, {\n\t key: 'removeDOM3D',\n\t value: function removeDOM3D(object) {\n\t this._domObject3D.remove(object);\n\t }\n\t }, {\n\t key: 'addDOM2D',\n\t value: function addDOM2D(object) {\n\t this._domObject2D.add(object);\n\t }\n\t }, {\n\t key: 'removeDOM2D',\n\t value: function removeDOM2D(object) {\n\t this._domObject2D.remove(object);\n\t }\n\t\n\t // Add layer to world instance and store world reference\n\t }, {\n\t key: 'addTo',\n\t value: function addTo(world) {\n\t return world.addLayer(this);\n\t }\n\t\n\t // Internal method called by World.addLayer to actually add the layer\n\t }, {\n\t key: '_addToWorld',\n\t value: function _addToWorld(world) {\n\t var _this = this;\n\t\n\t this._world = world;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._onAdd(world).then(function () {\n\t _this.emit('added');\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Must return a promise\n\t }, {\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t return Promise.resolve(this);\n\t }\n\t }, {\n\t key: 'getPickingId',\n\t value: function getPickingId() {\n\t if (this._world._engine._picking) {\n\t return this._world._engine._picking.getNextId();\n\t }\n\t\n\t return false;\n\t }\n\t\n\t // TODO: Tidy this up and don't access so many private properties to work\n\t }, {\n\t key: 'addToPicking',\n\t value: function addToPicking(object) {\n\t if (!this._world._engine._picking) {\n\t return;\n\t }\n\t\n\t this._world._engine._picking.add(object);\n\t }\n\t }, {\n\t key: 'removeFromPicking',\n\t value: function removeFromPicking(object) {\n\t if (!this._world._engine._picking) {\n\t return;\n\t }\n\t\n\t this._world._engine._picking.remove(object);\n\t }\n\t }, {\n\t key: 'isOutput',\n\t value: function isOutput() {\n\t return this._options.output;\n\t }\n\t }, {\n\t key: 'isOutputToScene',\n\t value: function isOutputToScene() {\n\t return this._options.outputToScene;\n\t }\n\t\n\t // TODO: Also hide any attached DOM layers\n\t }, {\n\t key: 'hide',\n\t value: function hide() {\n\t this._object3D.visible = false;\n\t\n\t if (this._pickingMesh) {\n\t this._pickingMesh.visible = false;\n\t }\n\t }\n\t\n\t // TODO: Also show any attached DOM layers\n\t }, {\n\t key: 'show',\n\t value: function show() {\n\t this._object3D.visible = true;\n\t\n\t if (this._pickingMesh) {\n\t this._pickingMesh.visible = true;\n\t }\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._object3D && this._object3D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._object3D.children.length - 1; i >= 0; i--) {\n\t child = this._object3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.remove(child);\n\t\n\t if (child.geometry) {\n\t // Dispose of mesh and materials\n\t child.geometry.dispose();\n\t child.geometry = null;\n\t }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t }\n\t }\n\t\n\t if (this._domObject3D && this._domObject3D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._domObject3D.children.length - 1; i >= 0; i--) {\n\t child = this._domObject3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.removeDOM3D(child);\n\t }\n\t }\n\t\n\t if (this._domObject2D && this._domObject2D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._domObject2D.children.length - 1; i >= 0; i--) {\n\t child = this._domObject2D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.removeDOM2D(child);\n\t }\n\t }\n\t\n\t this._domObject3D = null;\n\t this._domObject2D = null;\n\t\n\t this._world = null;\n\t this._object3D = null;\n\t }\n\t }]);\n\t\n\t return Layer;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Layer;\n\t\n\tvar noNew = function noNew(options) {\n\t return new Layer(options);\n\t};\n\t\n\texports.layer = noNew;\n\n/***/ },\n/* 5 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar has = Object.prototype.hasOwnProperty;\n\t\n\t//\n\t// We store our EE objects in a plain object whose properties are event names.\n\t// If `Object.create(null)` is not supported we prefix the event names with a\n\t// `~` to make sure that the built-in object properties are not overridden or\n\t// used as an attack vector.\n\t// We also assume that `Object.create(null)` is available when the event name\n\t// is an ES6 Symbol.\n\t//\n\tvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\t\n\t/**\n\t * Representation of a single EventEmitter function.\n\t *\n\t * @param {Function} fn Event handler to be called.\n\t * @param {Mixed} context Context for function execution.\n\t * @param {Boolean} [once=false] Only emit once\n\t * @api private\n\t */\n\tfunction EE(fn, context, once) {\n\t this.fn = fn;\n\t this.context = context;\n\t this.once = once || false;\n\t}\n\t\n\t/**\n\t * Minimal EventEmitter interface that is molded against the Node.js\n\t * EventEmitter interface.\n\t *\n\t * @constructor\n\t * @api public\n\t */\n\tfunction EventEmitter() { /* Nothing to set */ }\n\t\n\t/**\n\t * Hold the assigned EventEmitters by name.\n\t *\n\t * @type {Object}\n\t * @private\n\t */\n\tEventEmitter.prototype._events = undefined;\n\t\n\t/**\n\t * Return an array listing the events for which the emitter has registered\n\t * listeners.\n\t *\n\t * @returns {Array}\n\t * @api public\n\t */\n\tEventEmitter.prototype.eventNames = function eventNames() {\n\t var events = this._events\n\t , names = []\n\t , name;\n\t\n\t if (!events) return names;\n\t\n\t for (name in events) {\n\t if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n\t }\n\t\n\t if (Object.getOwnPropertySymbols) {\n\t return names.concat(Object.getOwnPropertySymbols(events));\n\t }\n\t\n\t return names;\n\t};\n\t\n\t/**\n\t * Return a list of assigned event listeners.\n\t *\n\t * @param {String} event The events that should be listed.\n\t * @param {Boolean} exists We only need to know if there are listeners.\n\t * @returns {Array|Boolean}\n\t * @api public\n\t */\n\tEventEmitter.prototype.listeners = function listeners(event, exists) {\n\t var evt = prefix ? prefix + event : event\n\t , available = this._events && this._events[evt];\n\t\n\t if (exists) return !!available;\n\t if (!available) return [];\n\t if (available.fn) return [available.fn];\n\t\n\t for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n\t ee[i] = available[i].fn;\n\t }\n\t\n\t return ee;\n\t};\n\t\n\t/**\n\t * Emit an event to all registered event listeners.\n\t *\n\t * @param {String} event The name of the event.\n\t * @returns {Boolean} Indication if we've emitted an event.\n\t * @api public\n\t */\n\tEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n\t var evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events || !this._events[evt]) return false;\n\t\n\t var listeners = this._events[evt]\n\t , len = arguments.length\n\t , args\n\t , i;\n\t\n\t if ('function' === typeof listeners.fn) {\n\t if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\t\n\t switch (len) {\n\t case 1: return listeners.fn.call(listeners.context), true;\n\t case 2: return listeners.fn.call(listeners.context, a1), true;\n\t case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n\t case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n\t case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n\t case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n\t }\n\t\n\t for (i = 1, args = new Array(len -1); i < len; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t\n\t listeners.fn.apply(listeners.context, args);\n\t } else {\n\t var length = listeners.length\n\t , j;\n\t\n\t for (i = 0; i < length; i++) {\n\t if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\t\n\t switch (len) {\n\t case 1: listeners[i].fn.call(listeners[i].context); break;\n\t case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n\t case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n\t default:\n\t if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n\t args[j - 1] = arguments[j];\n\t }\n\t\n\t listeners[i].fn.apply(listeners[i].context, args);\n\t }\n\t }\n\t }\n\t\n\t return true;\n\t};\n\t\n\t/**\n\t * Register a new EventListener for the given event.\n\t *\n\t * @param {String} event Name of the event.\n\t * @param {Function} fn Callback function.\n\t * @param {Mixed} [context=this] The context of the function.\n\t * @api public\n\t */\n\tEventEmitter.prototype.on = function on(event, fn, context) {\n\t var listener = new EE(fn, context || this)\n\t , evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events) this._events = prefix ? {} : Object.create(null);\n\t if (!this._events[evt]) this._events[evt] = listener;\n\t else {\n\t if (!this._events[evt].fn) this._events[evt].push(listener);\n\t else this._events[evt] = [\n\t this._events[evt], listener\n\t ];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Add an EventListener that's only called once.\n\t *\n\t * @param {String} event Name of the event.\n\t * @param {Function} fn Callback function.\n\t * @param {Mixed} [context=this] The context of the function.\n\t * @api public\n\t */\n\tEventEmitter.prototype.once = function once(event, fn, context) {\n\t var listener = new EE(fn, context || this, true)\n\t , evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events) this._events = prefix ? {} : Object.create(null);\n\t if (!this._events[evt]) this._events[evt] = listener;\n\t else {\n\t if (!this._events[evt].fn) this._events[evt].push(listener);\n\t else this._events[evt] = [\n\t this._events[evt], listener\n\t ];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Remove event listeners.\n\t *\n\t * @param {String} event The event we want to remove.\n\t * @param {Function} fn The listener that we need to find.\n\t * @param {Mixed} context Only remove listeners matching this context.\n\t * @param {Boolean} once Only remove once listeners.\n\t * @api public\n\t */\n\tEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n\t var evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events || !this._events[evt]) return this;\n\t\n\t var listeners = this._events[evt]\n\t , events = [];\n\t\n\t if (fn) {\n\t if (listeners.fn) {\n\t if (\n\t listeners.fn !== fn\n\t || (once && !listeners.once)\n\t || (context && listeners.context !== context)\n\t ) {\n\t events.push(listeners);\n\t }\n\t } else {\n\t for (var i = 0, length = listeners.length; i < length; i++) {\n\t if (\n\t listeners[i].fn !== fn\n\t || (once && !listeners[i].once)\n\t || (context && listeners[i].context !== context)\n\t ) {\n\t events.push(listeners[i]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t //\n\t // Reset the array, or remove it completely if we have no more listeners.\n\t //\n\t if (events.length) {\n\t this._events[evt] = events.length === 1 ? events[0] : events;\n\t } else {\n\t delete this._events[evt];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Remove all listeners or only the listeners for the specified event.\n\t *\n\t * @param {String} event The event want to remove all listeners for.\n\t * @api public\n\t */\n\tEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n\t if (!this._events) return this;\n\t\n\t if (event) delete this._events[prefix ? prefix + event : event];\n\t else this._events = prefix ? {} : Object.create(null);\n\t\n\t return this;\n\t};\n\t\n\t//\n\t// Alias methods names because people roll like that.\n\t//\n\tEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\tEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\t\n\t//\n\t// This function doesn't apply anymore.\n\t//\n\tEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n\t return this;\n\t};\n\t\n\t//\n\t// Expose the prefix.\n\t//\n\tEventEmitter.prefixed = prefix;\n\t\n\t//\n\t// Expose the module.\n\t//\n\tif (true) {\n\t module.exports = EventEmitter;\n\t}\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\tvar keys = __webpack_require__(7),\n\t rest = __webpack_require__(8);\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]';\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\t\n\t/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\n\tvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\t\n\t/**\n\t * Assigns `value` to `key` of `object` if the existing value is not equivalent\n\t * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n\t * for equality comparisons.\n\t *\n\t * @private\n\t * @param {Object} object The object to modify.\n\t * @param {string} key The key of the property to assign.\n\t * @param {*} value The value to assign.\n\t */\n\tfunction assignValue(object, key, value) {\n\t var objValue = object[key];\n\t if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n\t (value === undefined && !(key in object))) {\n\t object[key] = value;\n\t }\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * Copies properties of `source` to `object`.\n\t *\n\t * @private\n\t * @param {Object} source The object to copy properties from.\n\t * @param {Array} props The property identifiers to copy.\n\t * @param {Object} [object={}] The object to copy properties to.\n\t * @param {Function} [customizer] The function to customize copied values.\n\t * @returns {Object} Returns `object`.\n\t */\n\tfunction copyObject(source, props, object, customizer) {\n\t object || (object = {});\n\t\n\t var index = -1,\n\t length = props.length;\n\t\n\t while (++index < length) {\n\t var key = props[index];\n\t\n\t var newValue = customizer\n\t ? customizer(object[key], source[key], key, object, source)\n\t : source[key];\n\t\n\t assignValue(object, key, newValue);\n\t }\n\t return object;\n\t}\n\t\n\t/**\n\t * Creates a function like `_.assign`.\n\t *\n\t * @private\n\t * @param {Function} assigner The function to assign values.\n\t * @returns {Function} Returns the new assigner function.\n\t */\n\tfunction createAssigner(assigner) {\n\t return rest(function(object, sources) {\n\t var index = -1,\n\t length = sources.length,\n\t customizer = length > 1 ? sources[length - 1] : undefined,\n\t guard = length > 2 ? sources[2] : undefined;\n\t\n\t customizer = (assigner.length > 3 && typeof customizer == 'function')\n\t ? (length--, customizer)\n\t : undefined;\n\t\n\t if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n\t customizer = length < 3 ? undefined : customizer;\n\t length = 1;\n\t }\n\t object = Object(object);\n\t while (++index < length) {\n\t var source = sources[index];\n\t if (source) {\n\t assigner(object, source, index, customizer);\n\t }\n\t }\n\t return object;\n\t });\n\t}\n\t\n\t/**\n\t * Gets the \"length\" property value of `object`.\n\t *\n\t * **Note:** This function is used to avoid a\n\t * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n\t * Safari on at least iOS 8.1-8.3 ARM64.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {*} Returns the \"length\" value.\n\t */\n\tvar getLength = baseProperty('length');\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if the given arguments are from an iteratee call.\n\t *\n\t * @private\n\t * @param {*} value The potential iteratee value argument.\n\t * @param {*} index The potential iteratee index or key argument.\n\t * @param {*} object The potential iteratee object argument.\n\t * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n\t * else `false`.\n\t */\n\tfunction isIterateeCall(value, index, object) {\n\t if (!isObject(object)) {\n\t return false;\n\t }\n\t var type = typeof index;\n\t if (type == 'number'\n\t ? (isArrayLike(object) && isIndex(index, object.length))\n\t : (type == 'string' && index in object)\n\t ) {\n\t return eq(object[index], value);\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Performs a\n\t * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n\t * comparison between two values to determine if they are equivalent.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'user': 'fred' };\n\t * var other = { 'user': 'fred' };\n\t *\n\t * _.eq(object, object);\n\t * // => true\n\t *\n\t * _.eq(object, other);\n\t * // => false\n\t *\n\t * _.eq('a', 'a');\n\t * // => true\n\t *\n\t * _.eq('a', Object('a'));\n\t * // => false\n\t *\n\t * _.eq(NaN, NaN);\n\t * // => true\n\t */\n\tfunction eq(value, other) {\n\t return value === other || (value !== value && other !== other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(getLength(value)) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Assigns own enumerable string keyed properties of source objects to the\n\t * destination object. Source objects are applied from left to right.\n\t * Subsequent sources overwrite property assignments of previous sources.\n\t *\n\t * **Note:** This method mutates `object` and is loosely based on\n\t * [`Object.assign`](https://mdn.io/Object/assign).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.10.0\n\t * @category Object\n\t * @param {Object} object The destination object.\n\t * @param {...Object} [sources] The source objects.\n\t * @returns {Object} Returns `object`.\n\t * @see _.assignIn\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.c = 3;\n\t * }\n\t *\n\t * function Bar() {\n\t * this.e = 5;\n\t * }\n\t *\n\t * Foo.prototype.d = 4;\n\t * Bar.prototype.f = 6;\n\t *\n\t * _.assign({ 'a': 1 }, new Foo, new Bar);\n\t * // => { 'a': 1, 'c': 3, 'e': 5 }\n\t */\n\tvar assign = createAssigner(function(object, source) {\n\t if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n\t copyObject(source, keys(source), object);\n\t return;\n\t }\n\t for (var key in source) {\n\t if (hasOwnProperty.call(source, key)) {\n\t assignValue(object, key, source[key]);\n\t }\n\t }\n\t});\n\t\n\tmodule.exports = assign;\n\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar argsTag = '[object Arguments]',\n\t funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t stringTag = '[object String]';\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/**\n\t * The base implementation of `_.times` without support for iteratee shorthands\n\t * or max array length checks.\n\t *\n\t * @private\n\t * @param {number} n The number of times to invoke `iteratee`.\n\t * @param {Function} iteratee The function invoked per iteration.\n\t * @returns {Array} Returns the array of results.\n\t */\n\tfunction baseTimes(n, iteratee) {\n\t var index = -1,\n\t result = Array(n);\n\t\n\t while (++index < n) {\n\t result[index] = iteratee(index);\n\t }\n\t return result;\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeGetPrototype = Object.getPrototypeOf,\n\t nativeKeys = Object.keys;\n\t\n\t/**\n\t * The base implementation of `_.has` without support for deep paths.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} key The key to check.\n\t * @returns {boolean} Returns `true` if `key` exists, else `false`.\n\t */\n\tfunction baseHas(object, key) {\n\t // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n\t // that are composed entirely of index properties, return `false` for\n\t // `hasOwnProperty` checks of them.\n\t return hasOwnProperty.call(object, key) ||\n\t (typeof object == 'object' && key in object && getPrototype(object) === null);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.keys` which doesn't skip the constructor\n\t * property of prototypes or treat sparse arrays as dense.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction baseKeys(object) {\n\t return nativeKeys(Object(object));\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * Gets the \"length\" property value of `object`.\n\t *\n\t * **Note:** This function is used to avoid a\n\t * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n\t * Safari on at least iOS 8.1-8.3 ARM64.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {*} Returns the \"length\" value.\n\t */\n\tvar getLength = baseProperty('length');\n\t\n\t/**\n\t * Gets the `[[Prototype]]` of `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {null|Object} Returns the `[[Prototype]]`.\n\t */\n\tfunction getPrototype(value) {\n\t return nativeGetPrototype(Object(value));\n\t}\n\t\n\t/**\n\t * Creates an array of index keys for `object` values of arrays,\n\t * `arguments` objects, and strings, otherwise `null` is returned.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array|null} Returns index keys, else `null`.\n\t */\n\tfunction indexKeys(object) {\n\t var length = object ? object.length : undefined;\n\t if (isLength(length) &&\n\t (isArray(object) || isString(object) || isArguments(object))) {\n\t return baseTimes(length, String);\n\t }\n\t return null;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely an `arguments` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArguments(function() { return arguments; }());\n\t * // => true\n\t *\n\t * _.isArguments([1, 2, 3]);\n\t * // => false\n\t */\n\tfunction isArguments(value) {\n\t // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n\t return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n\t (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as an `Array` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @type {Function}\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArray([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArray(document.body.children);\n\t * // => false\n\t *\n\t * _.isArray('abc');\n\t * // => false\n\t *\n\t * _.isArray(_.noop);\n\t * // => false\n\t */\n\tvar isArray = Array.isArray;\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(getLength(value)) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * This method is like `_.isArrayLike` except that it also checks if `value`\n\t * is an object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array-like object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArrayLikeObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject('abc');\n\t * // => false\n\t *\n\t * _.isArrayLikeObject(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLikeObject(value) {\n\t return isObjectLike(value) && isArrayLike(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `String` primitive or object.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isString('abc');\n\t * // => true\n\t *\n\t * _.isString(1);\n\t * // => false\n\t */\n\tfunction isString(value) {\n\t return typeof value == 'string' ||\n\t (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n\t}\n\t\n\t/**\n\t * Creates an array of the own enumerable property names of `object`.\n\t *\n\t * **Note:** Non-object values are coerced to objects. See the\n\t * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n\t * for more details.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.a = 1;\n\t * this.b = 2;\n\t * }\n\t *\n\t * Foo.prototype.c = 3;\n\t *\n\t * _.keys(new Foo);\n\t * // => ['a', 'b'] (iteration order is not guaranteed)\n\t *\n\t * _.keys('hi');\n\t * // => ['0', '1']\n\t */\n\tfunction keys(object) {\n\t var isProto = isPrototype(object);\n\t if (!(isProto || isArrayLike(object))) {\n\t return baseKeys(object);\n\t }\n\t var indexes = indexKeys(object),\n\t skipIndexes = !!indexes,\n\t result = indexes || [],\n\t length = result.length;\n\t\n\t for (var key in object) {\n\t if (baseHas(object, key) &&\n\t !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n\t !(isProto && key == 'constructor')) {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\tmodule.exports = keys;\n\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar INFINITY = 1 / 0,\n\t MAX_INTEGER = 1.7976931348623157e+308,\n\t NAN = 0 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t symbolTag = '[object Symbol]';\n\t\n\t/** Used to match leading and trailing whitespace. */\n\tvar reTrim = /^\\s+|\\s+$/g;\n\t\n\t/** Used to detect bad signed hexadecimal string values. */\n\tvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\t\n\t/** Used to detect binary string values. */\n\tvar reIsBinary = /^0b[01]+$/i;\n\t\n\t/** Used to detect octal string values. */\n\tvar reIsOctal = /^0o[0-7]+$/i;\n\t\n\t/** Built-in method references without a dependency on `root`. */\n\tvar freeParseInt = parseInt;\n\t\n\t/**\n\t * A faster alternative to `Function#apply`, this function invokes `func`\n\t * with the `this` binding of `thisArg` and the arguments of `args`.\n\t *\n\t * @private\n\t * @param {Function} func The function to invoke.\n\t * @param {*} thisArg The `this` binding of `func`.\n\t * @param {Array} args The arguments to invoke `func` with.\n\t * @returns {*} Returns the result of `func`.\n\t */\n\tfunction apply(func, thisArg, args) {\n\t var length = args.length;\n\t switch (length) {\n\t case 0: return func.call(thisArg);\n\t case 1: return func.call(thisArg, args[0]);\n\t case 2: return func.call(thisArg, args[0], args[1]);\n\t case 3: return func.call(thisArg, args[0], args[1], args[2]);\n\t }\n\t return func.apply(thisArg, args);\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeMax = Math.max;\n\t\n\t/**\n\t * Creates a function that invokes `func` with the `this` binding of the\n\t * created function and arguments from `start` and beyond provided as\n\t * an array.\n\t *\n\t * **Note:** This method is based on the\n\t * [rest parameter](https://mdn.io/rest_parameters).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Function\n\t * @param {Function} func The function to apply a rest parameter to.\n\t * @param {number} [start=func.length-1] The start position of the rest parameter.\n\t * @returns {Function} Returns the new function.\n\t * @example\n\t *\n\t * var say = _.rest(function(what, names) {\n\t * return what + ' ' + _.initial(names).join(', ') +\n\t * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n\t * });\n\t *\n\t * say('hello', 'fred', 'barney', 'pebbles');\n\t * // => 'hello fred, barney, & pebbles'\n\t */\n\tfunction rest(func, start) {\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n\t return function() {\n\t var args = arguments,\n\t index = -1,\n\t length = nativeMax(args.length - start, 0),\n\t array = Array(length);\n\t\n\t while (++index < length) {\n\t array[index] = args[start + index];\n\t }\n\t switch (start) {\n\t case 0: return func.call(this, array);\n\t case 1: return func.call(this, args[0], array);\n\t case 2: return func.call(this, args[0], args[1], array);\n\t }\n\t var otherArgs = Array(start + 1);\n\t index = -1;\n\t while (++index < start) {\n\t otherArgs[index] = args[index];\n\t }\n\t otherArgs[start] = array;\n\t return apply(func, this, otherArgs);\n\t };\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a finite number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.12.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted number.\n\t * @example\n\t *\n\t * _.toFinite(3.2);\n\t * // => 3.2\n\t *\n\t * _.toFinite(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toFinite(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toFinite('3.2');\n\t * // => 3.2\n\t */\n\tfunction toFinite(value) {\n\t if (!value) {\n\t return value === 0 ? value : 0;\n\t }\n\t value = toNumber(value);\n\t if (value === INFINITY || value === -INFINITY) {\n\t var sign = (value < 0 ? -1 : 1);\n\t return sign * MAX_INTEGER;\n\t }\n\t return value === value ? value : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to an integer.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted integer.\n\t * @example\n\t *\n\t * _.toInteger(3.2);\n\t * // => 3\n\t *\n\t * _.toInteger(Number.MIN_VALUE);\n\t * // => 0\n\t *\n\t * _.toInteger(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toInteger('3.2');\n\t * // => 3\n\t */\n\tfunction toInteger(value) {\n\t var result = toFinite(value),\n\t remainder = result % 1;\n\t\n\t return result === result ? (remainder ? result - remainder : result) : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to a number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {number} Returns the number.\n\t * @example\n\t *\n\t * _.toNumber(3.2);\n\t * // => 3.2\n\t *\n\t * _.toNumber(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toNumber(Infinity);\n\t * // => Infinity\n\t *\n\t * _.toNumber('3.2');\n\t * // => 3.2\n\t */\n\tfunction toNumber(value) {\n\t if (typeof value == 'number') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return NAN;\n\t }\n\t if (isObject(value)) {\n\t var other = isFunction(value.valueOf) ? value.valueOf() : value;\n\t value = isObject(other) ? (other + '') : other;\n\t }\n\t if (typeof value != 'string') {\n\t return value === 0 ? value : +value;\n\t }\n\t value = value.replace(reTrim, '');\n\t var isBinary = reIsBinary.test(value);\n\t return (isBinary || reIsOctal.test(value))\n\t ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n\t : (reIsBadHex.test(value) ? NAN : +value);\n\t}\n\t\n\tmodule.exports = rest;\n\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\tmodule.exports = __webpack_require__(10);\n\n\n/***/ },\n/* 10 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar alphabet = __webpack_require__(11);\n\tvar encode = __webpack_require__(13);\n\tvar decode = __webpack_require__(15);\n\tvar isValid = __webpack_require__(16);\n\t\n\t// Ignore all milliseconds before a certain time to reduce the size of the date entropy without sacrificing uniqueness.\n\t// This number should be updated every year or so to keep the generated id short.\n\t// To regenerate `new Date() - 0` and bump the version. Always bump the version!\n\tvar REDUCE_TIME = 1459707606518;\n\t\n\t// don't change unless we change the algos or REDUCE_TIME\n\t// must be an integer and less than 16\n\tvar version = 6;\n\t\n\t// if you are using cluster or multiple servers use this to make each instance\n\t// has a unique value for worker\n\t// Note: I don't know if this is automatically set when using third\n\t// party cluster solutions such as pm2.\n\tvar clusterWorkerId = __webpack_require__(17) || 0;\n\t\n\t// Counter is used when shortid is called multiple times in one second.\n\tvar counter;\n\t\n\t// Remember the last time shortid was called in case counter is needed.\n\tvar previousSeconds;\n\t\n\t/**\n\t * Generate unique id\n\t * Returns string id\n\t */\n\tfunction generate() {\n\t\n\t var str = '';\n\t\n\t var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);\n\t\n\t if (seconds === previousSeconds) {\n\t counter++;\n\t } else {\n\t counter = 0;\n\t previousSeconds = seconds;\n\t }\n\t\n\t str = str + encode(alphabet.lookup, version);\n\t str = str + encode(alphabet.lookup, clusterWorkerId);\n\t if (counter > 0) {\n\t str = str + encode(alphabet.lookup, counter);\n\t }\n\t str = str + encode(alphabet.lookup, seconds);\n\t\n\t return str;\n\t}\n\t\n\t\n\t/**\n\t * Set the seed.\n\t * Highly recommended if you don't want people to try to figure out your id schema.\n\t * exposed as shortid.seed(int)\n\t * @param seed Integer value to seed the random alphabet. ALWAYS USE THE SAME SEED or you might get overlaps.\n\t */\n\tfunction seed(seedValue) {\n\t alphabet.seed(seedValue);\n\t return module.exports;\n\t}\n\t\n\t/**\n\t * Set the cluster worker or machine id\n\t * exposed as shortid.worker(int)\n\t * @param workerId worker must be positive integer. Number less than 16 is recommended.\n\t * returns shortid module so it can be chained.\n\t */\n\tfunction worker(workerId) {\n\t clusterWorkerId = workerId;\n\t return module.exports;\n\t}\n\t\n\t/**\n\t *\n\t * sets new characters to use in the alphabet\n\t * returns the shuffled alphabet\n\t */\n\tfunction characters(newCharacters) {\n\t if (newCharacters !== undefined) {\n\t alphabet.characters(newCharacters);\n\t }\n\t\n\t return alphabet.shuffled();\n\t}\n\t\n\t\n\t// Export all other functions as properties of the generate function\n\tmodule.exports = generate;\n\tmodule.exports.generate = generate;\n\tmodule.exports.seed = seed;\n\tmodule.exports.worker = worker;\n\tmodule.exports.characters = characters;\n\tmodule.exports.decode = decode;\n\tmodule.exports.isValid = isValid;\n\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar randomFromSeed = __webpack_require__(12);\n\t\n\tvar ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';\n\tvar alphabet;\n\tvar previousSeed;\n\t\n\tvar shuffled;\n\t\n\tfunction reset() {\n\t shuffled = false;\n\t}\n\t\n\tfunction setCharacters(_alphabet_) {\n\t if (!_alphabet_) {\n\t if (alphabet !== ORIGINAL) {\n\t alphabet = ORIGINAL;\n\t reset();\n\t }\n\t return;\n\t }\n\t\n\t if (_alphabet_ === alphabet) {\n\t return;\n\t }\n\t\n\t if (_alphabet_.length !== ORIGINAL.length) {\n\t throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_);\n\t }\n\t\n\t var unique = _alphabet_.split('').filter(function(item, ind, arr){\n\t return ind !== arr.lastIndexOf(item);\n\t });\n\t\n\t if (unique.length) {\n\t throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', '));\n\t }\n\t\n\t alphabet = _alphabet_;\n\t reset();\n\t}\n\t\n\tfunction characters(_alphabet_) {\n\t setCharacters(_alphabet_);\n\t return alphabet;\n\t}\n\t\n\tfunction setSeed(seed) {\n\t randomFromSeed.seed(seed);\n\t if (previousSeed !== seed) {\n\t reset();\n\t previousSeed = seed;\n\t }\n\t}\n\t\n\tfunction shuffle() {\n\t if (!alphabet) {\n\t setCharacters(ORIGINAL);\n\t }\n\t\n\t var sourceArray = alphabet.split('');\n\t var targetArray = [];\n\t var r = randomFromSeed.nextValue();\n\t var characterIndex;\n\t\n\t while (sourceArray.length > 0) {\n\t r = randomFromSeed.nextValue();\n\t characterIndex = Math.floor(r * sourceArray.length);\n\t targetArray.push(sourceArray.splice(characterIndex, 1)[0]);\n\t }\n\t return targetArray.join('');\n\t}\n\t\n\tfunction getShuffled() {\n\t if (shuffled) {\n\t return shuffled;\n\t }\n\t shuffled = shuffle();\n\t return shuffled;\n\t}\n\t\n\t/**\n\t * lookup shuffled letter\n\t * @param index\n\t * @returns {string}\n\t */\n\tfunction lookup(index) {\n\t var alphabetShuffled = getShuffled();\n\t return alphabetShuffled[index];\n\t}\n\t\n\tmodule.exports = {\n\t characters: characters,\n\t seed: setSeed,\n\t lookup: lookup,\n\t shuffled: getShuffled\n\t};\n\n\n/***/ },\n/* 12 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\t// Found this seed-based random generator somewhere\n\t// Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu)\n\t\n\tvar seed = 1;\n\t\n\t/**\n\t * return a random number based on a seed\n\t * @param seed\n\t * @returns {number}\n\t */\n\tfunction getNextValue() {\n\t seed = (seed * 9301 + 49297) % 233280;\n\t return seed/(233280.0);\n\t}\n\t\n\tfunction setSeed(_seed_) {\n\t seed = _seed_;\n\t}\n\t\n\tmodule.exports = {\n\t nextValue: getNextValue,\n\t seed: setSeed\n\t};\n\n\n/***/ },\n/* 13 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar randomByte = __webpack_require__(14);\n\t\n\tfunction encode(lookup, number) {\n\t var loopCounter = 0;\n\t var done;\n\t\n\t var str = '';\n\t\n\t while (!done) {\n\t str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );\n\t done = number < (Math.pow(16, loopCounter + 1 ) );\n\t loopCounter++;\n\t }\n\t return str;\n\t}\n\t\n\tmodule.exports = encode;\n\n\n/***/ },\n/* 14 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tvar crypto = typeof window === 'object' && (window.crypto || window.msCrypto); // IE 11 uses window.msCrypto\n\t\n\tfunction randomByte() {\n\t if (!crypto || !crypto.getRandomValues) {\n\t return Math.floor(Math.random() * 256) & 0x30;\n\t }\n\t var dest = new Uint8Array(1);\n\t crypto.getRandomValues(dest);\n\t return dest[0] & 0x30;\n\t}\n\t\n\tmodule.exports = randomByte;\n\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\tvar alphabet = __webpack_require__(11);\n\t\n\t/**\n\t * Decode the id to get the version and worker\n\t * Mainly for debugging and testing.\n\t * @param id - the shortid-generated id.\n\t */\n\tfunction decode(id) {\n\t var characters = alphabet.shuffled();\n\t return {\n\t version: characters.indexOf(id.substr(0, 1)) & 0x0f,\n\t worker: characters.indexOf(id.substr(1, 1)) & 0x0f\n\t };\n\t}\n\t\n\tmodule.exports = decode;\n\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\tvar alphabet = __webpack_require__(11);\n\t\n\tfunction isShortId(id) {\n\t if (!id || typeof id !== 'string' || id.length < 6 ) {\n\t return false;\n\t }\n\t\n\t var characters = alphabet.characters();\n\t var len = id.length;\n\t for(var i = 0; i < len;i++) {\n\t if (characters.indexOf(id[i]) === -1) {\n\t return false;\n\t }\n\t }\n\t return true;\n\t}\n\t\n\tmodule.exports = isShortId;\n\n\n/***/ },\n/* 17 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = 0;\n\n\n/***/ },\n/* 18 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_18__;\n\n/***/ },\n/* 19 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t\n\t // TODO: Re-enable when this works with the skybox\n\t // scene.fog = new THREE.Fog(0xffffff, 1, 15000);\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\t/**\n\t * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar CSS3DObject = function CSS3DObject(element) {\n\t\n\t\t_three2['default'].Object3D.call(this);\n\t\n\t\tthis.element = element;\n\t\tthis.element.style.position = 'absolute';\n\t\n\t\tthis.addEventListener('removed', function (event) {\n\t\n\t\t\tif (this.element.parentNode !== null) {\n\t\n\t\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t\t}\n\t\t});\n\t};\n\t\n\tCSS3DObject.prototype = Object.create(_three2['default'].Object3D.prototype);\n\tCSS3DObject.prototype.constructor = CSS3DObject;\n\t\n\tvar CSS3DSprite = function CSS3DSprite(element) {\n\t\n\t\tCSS3DObject.call(this, element);\n\t};\n\t\n\tCSS3DSprite.prototype = Object.create(CSS3DObject.prototype);\n\tCSS3DSprite.prototype.constructor = CSS3DSprite;\n\t\n\t//\n\t\n\tvar CSS3DRenderer = function CSS3DRenderer() {\n\t\n\t\tconsole.log('THREE.CSS3DRenderer', _three2['default'].REVISION);\n\t\n\t\tvar _width, _height;\n\t\tvar _widthHalf, _heightHalf;\n\t\n\t\tvar matrix = new _three2['default'].Matrix4();\n\t\n\t\tvar cache = {\n\t\t\tcamera: { fov: 0, style: '' },\n\t\t\tobjects: {}\n\t\t};\n\t\n\t\tvar domElement = document.createElement('div');\n\t\tdomElement.style.overflow = 'hidden';\n\t\n\t\tdomElement.style.WebkitTransformStyle = 'preserve-3d';\n\t\tdomElement.style.MozTransformStyle = 'preserve-3d';\n\t\tdomElement.style.oTransformStyle = 'preserve-3d';\n\t\tdomElement.style.transformStyle = 'preserve-3d';\n\t\n\t\tthis.domElement = domElement;\n\t\n\t\tvar cameraElement = document.createElement('div');\n\t\n\t\tcameraElement.style.WebkitTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.MozTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.oTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.transformStyle = 'preserve-3d';\n\t\n\t\tdomElement.appendChild(cameraElement);\n\t\n\t\tthis.setClearColor = function () {};\n\t\n\t\tthis.getSize = function () {\n\t\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\t\t};\n\t\n\t\tthis.setSize = function (width, height) {\n\t\n\t\t\t_width = width;\n\t\t\t_height = height;\n\t\n\t\t\t_widthHalf = _width / 2;\n\t\t\t_heightHalf = _height / 2;\n\t\n\t\t\tdomElement.style.width = width + 'px';\n\t\t\tdomElement.style.height = height + 'px';\n\t\n\t\t\tcameraElement.style.width = width + 'px';\n\t\t\tcameraElement.style.height = height + 'px';\n\t\t};\n\t\n\t\tvar epsilon = function epsilon(value) {\n\t\n\t\t\treturn Math.abs(value) < Number.EPSILON ? 0 : value;\n\t\t};\n\t\n\t\tvar getCameraCSSMatrix = function getCameraCSSMatrix(matrix) {\n\t\n\t\t\tvar elements = matrix.elements;\n\t\n\t\t\treturn 'matrix3d(' + epsilon(elements[0]) + ',' + epsilon(-elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(elements[6]) + ',' + epsilon(elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(-elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(-elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')';\n\t\t};\n\t\n\t\tvar getObjectCSSMatrix = function getObjectCSSMatrix(matrix) {\n\t\n\t\t\tvar elements = matrix.elements;\n\t\n\t\t\treturn 'translate3d(-50%,-50%,0) matrix3d(' + epsilon(elements[0]) + ',' + epsilon(elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(-elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(-elements[6]) + ',' + epsilon(-elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')';\n\t\t};\n\t\n\t\tvar renderObject = function renderObject(object, camera) {\n\t\n\t\t\tif (object instanceof CSS3DObject) {\n\t\n\t\t\t\tvar style;\n\t\n\t\t\t\tif (object instanceof CSS3DSprite) {\n\t\n\t\t\t\t\t// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/\n\t\n\t\t\t\t\tmatrix.copy(camera.matrixWorldInverse);\n\t\t\t\t\tmatrix.transpose();\n\t\t\t\t\tmatrix.copyPosition(object.matrixWorld);\n\t\t\t\t\tmatrix.scale(object.scale);\n\t\n\t\t\t\t\tmatrix.elements[3] = 0;\n\t\t\t\t\tmatrix.elements[7] = 0;\n\t\t\t\t\tmatrix.elements[11] = 0;\n\t\t\t\t\tmatrix.elements[15] = 1;\n\t\n\t\t\t\t\tstyle = getObjectCSSMatrix(matrix);\n\t\t\t\t} else {\n\t\n\t\t\t\t\tstyle = getObjectCSSMatrix(object.matrixWorld);\n\t\t\t\t}\n\t\n\t\t\t\tvar element = object.element;\n\t\t\t\tvar cachedStyle = cache.objects[object.id];\n\t\n\t\t\t\tif (cachedStyle === undefined || cachedStyle !== style) {\n\t\n\t\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\t\telement.style.MozTransform = style;\n\t\t\t\t\telement.style.oTransform = style;\n\t\t\t\t\telement.style.transform = style;\n\t\n\t\t\t\t\tcache.objects[object.id] = style;\n\t\t\t\t}\n\t\n\t\t\t\tif (element.parentNode !== cameraElement) {\n\t\n\t\t\t\t\tcameraElement.appendChild(element);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (var i = 0, l = object.children.length; i < l; i++) {\n\t\n\t\t\t\trenderObject(object.children[i], camera);\n\t\t\t}\n\t\t};\n\t\n\t\tthis.render = function (scene, camera) {\n\t\n\t\t\tvar fov = 0.5 / Math.tan(_three2['default'].Math.degToRad(camera.fov * 0.5)) * _height;\n\t\n\t\t\tif (cache.camera.fov !== fov) {\n\t\n\t\t\t\tdomElement.style.WebkitPerspective = fov + 'px';\n\t\t\t\tdomElement.style.MozPerspective = fov + 'px';\n\t\t\t\tdomElement.style.oPerspective = fov + 'px';\n\t\t\t\tdomElement.style.perspective = fov + 'px';\n\t\n\t\t\t\tcache.camera.fov = fov;\n\t\t\t}\n\t\n\t\t\tscene.updateMatrixWorld();\n\t\n\t\t\tif (camera.parent === null) camera.updateMatrixWorld();\n\t\n\t\t\tcamera.matrixWorldInverse.getInverse(camera.matrixWorld);\n\t\n\t\t\tvar style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix(camera.matrixWorldInverse) + ' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)';\n\t\n\t\t\tif (cache.camera.style !== style) {\n\t\n\t\t\t\tcameraElement.style.WebkitTransform = style;\n\t\t\t\tcameraElement.style.MozTransform = style;\n\t\t\t\tcameraElement.style.oTransform = style;\n\t\t\t\tcameraElement.style.transform = style;\n\t\n\t\t\t\tcache.camera.style = style;\n\t\t\t}\n\t\n\t\t\trenderObject(scene, camera);\n\t\t};\n\t};\n\t\n\texports.CSS3DObject = CSS3DObject;\n\texports.CSS3DSprite = CSS3DSprite;\n\texports.CSS3DRenderer = CSS3DRenderer;\n\t\n\t_three2['default'].CSS3DObject = CSS3DObject;\n\t_three2['default'].CSS3DSprite = CSS3DSprite;\n\t_three2['default'].CSS3DRenderer = CSS3DRenderer;\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar CSS2DObject = function CSS2DObject(element) {\n\t\n\t\t_three2['default'].Object3D.call(this);\n\t\n\t\tthis.element = element;\n\t\tthis.element.style.position = 'absolute';\n\t\n\t\tthis.addEventListener('removed', function (event) {\n\t\n\t\t\tif (this.element.parentNode !== null) {\n\t\n\t\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t\t}\n\t\t});\n\t};\n\t\n\tCSS2DObject.prototype = Object.create(_three2['default'].Object3D.prototype);\n\tCSS2DObject.prototype.constructor = CSS2DObject;\n\t\n\t//\n\t\n\tvar CSS2DRenderer = function CSS2DRenderer() {\n\t\n\t\tconsole.log('THREE.CSS2DRenderer', _three2['default'].REVISION);\n\t\n\t\tvar _width, _height;\n\t\tvar _widthHalf, _heightHalf;\n\t\n\t\tvar vector = new _three2['default'].Vector3();\n\t\tvar viewMatrix = new _three2['default'].Matrix4();\n\t\tvar viewProjectionMatrix = new _three2['default'].Matrix4();\n\t\n\t\tvar frustum = new _three2['default'].Frustum();\n\t\n\t\tvar domElement = document.createElement('div');\n\t\tdomElement.style.overflow = 'hidden';\n\t\n\t\tthis.domElement = domElement;\n\t\n\t\tthis.setSize = function (width, height) {\n\t\n\t\t\t_width = width;\n\t\t\t_height = height;\n\t\n\t\t\t_widthHalf = _width / 2;\n\t\t\t_heightHalf = _height / 2;\n\t\n\t\t\tdomElement.style.width = width + 'px';\n\t\t\tdomElement.style.height = height + 'px';\n\t\t};\n\t\n\t\tvar renderObject = function renderObject(object, camera) {\n\t\n\t\t\tif (object instanceof CSS2DObject) {\n\t\n\t\t\t\tvector.setFromMatrixPosition(object.matrixWorld);\n\t\t\t\tvector.applyProjection(viewProjectionMatrix);\n\t\n\t\t\t\tvar element = object.element;\n\t\t\t\tvar style = 'translate(-50%,-50%) translate(' + (vector.x * _widthHalf + _widthHalf) + 'px,' + (-vector.y * _heightHalf + _heightHalf) + 'px)';\n\t\n\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\telement.style.MozTransform = style;\n\t\t\t\telement.style.oTransform = style;\n\t\t\t\telement.style.transform = style;\n\t\n\t\t\t\tif (element.parentNode !== domElement) {\n\t\n\t\t\t\t\tdomElement.appendChild(element);\n\t\t\t\t}\n\t\n\t\t\t\t// Hide if outside view frustum\n\t\t\t\tif (!frustum.containsPoint(object.position)) {\n\t\t\t\t\telement.style.display = 'none';\n\t\t\t\t} else {\n\t\t\t\t\telement.style.display = 'block';\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (var i = 0, l = object.children.length; i < l; i++) {\n\t\n\t\t\t\trenderObject(object.children[i], camera);\n\t\t\t}\n\t\t};\n\t\n\t\tthis.render = function (scene, camera) {\n\t\n\t\t\tscene.updateMatrixWorld();\n\t\n\t\t\tif (camera.parent === null) camera.updateMatrixWorld();\n\t\n\t\t\tcamera.matrixWorldInverse.getInverse(camera.matrixWorld);\n\t\n\t\t\tviewMatrix.copy(camera.matrixWorldInverse.getInverse(camera.matrixWorld));\n\t\t\tviewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, viewMatrix);\n\t\n\t\t\tfrustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n\t\n\t\t\trenderObject(scene, camera);\n\t\t};\n\t};\n\t\n\texports.CSS2DObject = CSS2DObject;\n\texports.CSS2DRenderer = CSS2DRenderer;\n\t\n\t_three2['default'].CSS2DObject = CSS2DObject;\n\t_three2['default'].CSS2DRenderer = CSS2DRenderer;\n\n/***/ },\n/* 22 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(4);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(6);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _reqwest = __webpack_require__(23);\n\t\n\tvar _reqwest2 = _interopRequireDefault(_reqwest);\n\t\n\tvar _utilGeoJSON = __webpack_require__(25);\n\t\n\tvar _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON);\n\t\n\tvar _utilWorker = __webpack_require__(31);\n\t\n\tvar _utilWorker2 = _interopRequireDefault(_utilWorker);\n\t\n\tvar _utilBuffer = __webpack_require__(34);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _utilStringify = __webpack_require__(35);\n\t\n\tvar _utilStringify2 = _interopRequireDefault(_utilStringify);\n\t\n\tvar _geometryPolygonLayer = __webpack_require__(36);\n\t\n\tvar _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer);\n\t\n\tvar _geometryPolylineLayer = __webpack_require__(39);\n\t\n\tvar _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer);\n\t\n\tvar _geometryPointLayer = __webpack_require__(40);\n\t\n\tvar _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer);\n\t\n\tvar _geoLatLon = __webpack_require__(2);\n\t\n\tvar _geoPoint = __webpack_require__(3);\n\t\n\tvar _geoGeo = __webpack_require__(1);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(37);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\t// TODO: Allow filter method to be run inside a worker to improve performance\n\t// TODO: Allow onEachFeature method to be run inside a worker to improve performance\n\t\n\tvar GeoJSONWorkerLayer = (function (_Layer) {\n\t _inherits(GeoJSONWorkerLayer, _Layer);\n\t\n\t function GeoJSONWorkerLayer(geojson, options) {\n\t _classCallCheck(this, GeoJSONWorkerLayer);\n\t\n\t var defaults = {\n\t topojson: false,\n\t style: _utilGeoJSON2['default'].defaultStyle,\n\t onEachFeature: null,\n\t onEachFeatureWorker: null,\n\t onAddAttributes: null,\n\t interactive: false,\n\t pointGeometry: null,\n\t onClick: null,\n\t headers: {}\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (typeof options.style === 'object') {\n\t _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);\n\t }\n\t\n\t _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._aborted = false;\n\t this._geojson = geojson;\n\t }\n\t\n\t _createClass(GeoJSONWorkerLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t if (this._options.interactive) {\n\t // Worker layer always controls output to add a picking mesh\n\t this._pickingMesh = new THREE.Object3D();\n\t }\n\t\n\t // Process GeoJSON\n\t return this._process(this._geojson);\n\t }\n\t\n\t // Use workers to request and process GeoJSON, returning data structure\n\t // containing geometry and any supplementary data for output\n\t }, {\n\t key: '_process',\n\t value: function _process(_geojson) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var style = _this._options.style;\n\t\n\t // TODO: Convert to buffer and use transferrable objects\n\t if (typeof _this._options.style === 'function') {\n\t style = _utilStringify2['default'].functionToString(_this._options.style);\n\t }\n\t\n\t var pointGeometry = _this._options.pointGeometry;\n\t\n\t // TODO: Convert to buffer and use transferrable objects\n\t if (typeof _this._options.pointGeometry === 'function') {\n\t pointGeometry = _utilStringify2['default'].functionToString(_this._options.pointGeometry);\n\t }\n\t\n\t var geojson = _geojson;\n\t var transferrables = [];\n\t\n\t if (typeof geojson !== 'string') {\n\t _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(geojson));\n\t transferrables.push(geojson.buffer);\n\t _this._execWorker(geojson, _this._options.topojson, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t } else if (typeof _this._options.filter === 'function' || typeof _this._options.onEachFeature === 'function') {\n\t GeoJSONWorkerLayer.RequestGeoJSON(geojson).then(function (res) {\n\t // if (this._aborted) {\n\t // resolve();\n\t // return;\n\t // }\n\t\n\t var fc = _utilGeoJSON2['default'].collectFeatures(res, _this._options.topojson);\n\t var features = fc.features;\n\t\n\t // Run filter, if provided\n\t if (_this._options.filter) {\n\t fc.features = features.filter(_this._options.filter);\n\t }\n\t\n\t if (_this._options.onEachFeature) {\n\t var feature;\n\t for (var i = 0; i < features.length; i++) {\n\t feature = features[i];\n\t _this._options.onEachFeature(feature);\n\t };\n\t }\n\t\n\t _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(fc));\n\t transferrables.push(geojson.buffer);\n\t\n\t _this._execWorker(geojson, false, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t } else {\n\t _this._execWorker(geojson, _this._options.topojson, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t }\n\t });\n\t }\n\t }, {\n\t key: '_execWorker',\n\t value: function _execWorker(geojson, topojson, headers, originPoint, style, interactive, pointGeometry, transferrables) {\n\t var _this2 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t console.time('Worker round trip');\n\t\n\t _utilWorker2['default'].exec('GeoJSONWorkerLayer.Process', [geojson, topojson, headers, originPoint, style, interactive, pointGeometry], transferrables).then(function (results) {\n\t console.timeEnd('Worker round trip');\n\t\n\t // if (this._aborted) {\n\t // resolve();\n\t // return;\n\t // }\n\t\n\t var processPromises = [];\n\t\n\t if (results.polygons) {\n\t processPromises.push(_this2._processPolygonResults(results.polygons));\n\t }\n\t\n\t if (results.polylines) {\n\t processPromises.push(_this2._processPolylineResults(results.polylines));\n\t }\n\t\n\t if (results.points) {\n\t processPromises.push(_this2._processPointResults(results.points));\n\t }\n\t\n\t if (processPromises.length > 0) {\n\t Promise.all(processPromises).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t } else {\n\t resolve();\n\t }\n\t });\n\t });\n\t }\n\t\n\t // TODO: Dedupe with polyline method\n\t }, {\n\t key: '_processPolygonResults',\n\t value: function _processPolygonResults(results) {\n\t var _this3 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions);\n\t var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals);\n\t var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors);\n\t var splitTops = _utilBuffer2['default'].splitFloat32Array(results.attributes.tops);\n\t\n\t var splitOutlinePositions;\n\t var splitOutlineColors;\n\t\n\t if (results.outlineAttributes) {\n\t splitOutlinePositions = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.positions);\n\t splitOutlineColors = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.colors);\n\t }\n\t\n\t var splitProperties;\n\t if (results.properties) {\n\t splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties);\n\t }\n\t\n\t var flats = results.flats;\n\t\n\t var objects = [];\n\t var outlineObjects = [];\n\t\n\t var obj;\n\t var pickingId;\n\t var pickingIds;\n\t var properties;\n\t\n\t var polygonAttributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3,\n\t tops: 1\n\t };\n\t\n\t var polygonOutlineAttributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t\n\t for (var i = 0; i < splitPositions.length; i++) {\n\t if (splitProperties && splitProperties[i]) {\n\t properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i]));\n\t } else {\n\t properties = {};\n\t }\n\t\n\t // WORKERS: obj.attributes should actually an array of polygons for\n\t // the feature, though the current logic isn't aware of that\n\t obj = {\n\t attributes: [{\n\t positions: splitPositions[i],\n\t normals: splitNormals[i],\n\t colors: splitColors[i],\n\t tops: splitTops[i]\n\t }],\n\t properties: properties,\n\t flat: flats[i]\n\t };\n\t\n\t // WORKERS: If interactive, generate unique ID for each feature, create\n\t // the buffer attributes and set up event listeners\n\t if (_this3._options.interactive) {\n\t pickingId = _this3.getPickingId();\n\t\n\t pickingIds = new Float32Array(splitPositions[i].length / 3);\n\t pickingIds.fill(pickingId);\n\t\n\t obj.attributes[0].pickingIds = pickingIds;\n\t\n\t polygonAttributeLengths.pickingIds = 1;\n\t\n\t _this3._addPicking(pickingId, properties);\n\t }\n\t\n\t // TODO: Make this specific to polygon attributes\n\t if (typeof _this3._options.onAddAttributes === 'function') {\n\t var customAttributes = _this3._options.onAddAttributes(obj.attributes[0], properties);\n\t var customAttribute;\n\t for (var key in customAttributes) {\n\t customAttribute = customAttributes[key];\n\t obj.attributes[0][key] = customAttribute.value;\n\t polygonAttributeLengths[key] = customAttribute.length;\n\t }\n\t }\n\t\n\t objects.push(obj);\n\t }\n\t\n\t for (var i = 0; i < splitOutlinePositions.length; i++) {\n\t obj = {\n\t attributes: [{\n\t positions: splitOutlinePositions[i],\n\t colors: splitOutlineColors[i]\n\t }],\n\t flat: true\n\t };\n\t\n\t outlineObjects.push(obj);\n\t }\n\t\n\t var polygonAttributes = [];\n\t var polygonOutlineAttributes = [];\n\t\n\t var polygonFlat = true;\n\t\n\t for (var i = 0; i < objects.length; i++) {\n\t obj = objects[i];\n\t\n\t // TODO: Work out why obj.flat is rarely set to something other than\n\t // true or false. Potentially undefined.\n\t if (polygonFlat && obj.flat === false) {\n\t polygonFlat = false;\n\t }\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t polygonAttributes.push(bufferAttributes);\n\t };\n\t\n\t for (var i = 0; i < outlineObjects.length; i++) {\n\t obj = outlineObjects[i];\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t polygonOutlineAttributes.push(bufferAttributes);\n\t };\n\t\n\t var outputPromises = [];\n\t\n\t var style;\n\t\n\t if (polygonAttributes.length > 0) {\n\t var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes);\n\t\n\t // TODO: Make this work when style is a function per feature\n\t style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t outputPromises.push(_this3._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat));\n\t }\n\t\n\t if (polygonOutlineAttributes.length > 0) {\n\t var mergedPolygonOutlineAttributes = _utilBuffer2['default'].mergeAttributes(polygonOutlineAttributes);\n\t\n\t style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t if (style.outlineRenderOrder !== undefined) {\n\t style.lineRenderOrder = style.outlineRenderOrder;\n\t } else {\n\t style.lineRenderOrder = style.renderOrder ? style.renderOrder + 1 : 4;\n\t }\n\t\n\t if (style.outlineWidth) {\n\t style.lineWidth = style.outlineWidth;\n\t }\n\t\n\t outputPromises.push(_this3._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true));\n\t }\n\t\n\t Promise.all(outputPromises).then(function (results) {\n\t var _results = _slicedToArray(results, 2);\n\t\n\t var polygonResult = _results[0];\n\t var outlineResult = _results[1];\n\t\n\t if (polygonResult) {\n\t _this3._polygonMesh = polygonResult.mesh;\n\t _this3.add(_this3._polygonMesh);\n\t\n\t if (polygonResult.pickingMesh) {\n\t _this3._pickingMesh.add(polygonResult.pickingMesh);\n\t }\n\t }\n\t\n\t if (outlineResult) {\n\t _this3.add(outlineResult.mesh);\n\t }\n\t\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // TODO: Dedupe with polygon method\n\t }, {\n\t key: '_processPolylineResults',\n\t value: function _processPolylineResults(results) {\n\t var _this4 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions);\n\t var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors);\n\t\n\t var splitProperties;\n\t if (results.properties) {\n\t splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties);\n\t }\n\t\n\t var flats = results.flats;\n\t\n\t var objects = [];\n\t var obj;\n\t var pickingId;\n\t var pickingIds;\n\t var properties;\n\t\n\t var polylineAttributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t\n\t for (var i = 0; i < splitPositions.length; i++) {\n\t if (splitProperties && splitProperties[i]) {\n\t properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i]));\n\t } else {\n\t properties = {};\n\t }\n\t\n\t // WORKERS: obj.attributes should actually an array of polygons for\n\t // the feature, though the current logic isn't aware of that\n\t obj = {\n\t attributes: [{\n\t positions: splitPositions[i],\n\t colors: splitColors[i]\n\t }],\n\t properties: properties,\n\t flat: flats[i]\n\t };\n\t\n\t // WORKERS: If interactive, generate unique ID for each feature, create\n\t // the buffer attributes and set up event listeners\n\t if (_this4._options.interactive) {\n\t pickingId = _this4.getPickingId();\n\t\n\t pickingIds = new Float32Array(splitPositions[i].length / 3);\n\t pickingIds.fill(pickingId);\n\t\n\t obj.attributes[0].pickingIds = pickingIds;\n\t\n\t polylineAttributeLengths.pickingIds = 1;\n\t\n\t _this4._addPicking(pickingId, properties);\n\t }\n\t\n\t // TODO: Make this specific to polyline attributes\n\t if (typeof _this4._options.onAddAttributes === 'function') {\n\t var customAttributes = _this4._options.onAddAttributes(obj.attributes[0], properties);\n\t var customAttribute;\n\t for (var key in customAttributes) {\n\t customAttribute = customAttributes[key];\n\t obj.attributes[0][key] = customAttribute.value;\n\t polylineAttributeLengths[key] = customAttribute.length;\n\t }\n\t }\n\t\n\t objects.push(obj);\n\t }\n\t\n\t var polylineAttributes = [];\n\t\n\t var polylineFlat = true;\n\t\n\t for (var i = 0; i < objects.length; i++) {\n\t obj = objects[i];\n\t\n\t if (polylineFlat && !obj.flat) {\n\t polylineFlat = false;\n\t }\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t polylineAttributes.push(bufferAttributes);\n\t };\n\t\n\t if (polylineAttributes.length > 0) {\n\t var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes);\n\t\n\t // TODO: Make this work when style is a function per feature\n\t var style = typeof _this4._options.style === 'function' ? _this4._options.style(objects[0]) : _this4._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this4._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then(function (result) {\n\t _this4._polylineMesh = result.mesh;\n\t _this4.add(_this4._polylineMesh);\n\t\n\t if (result.pickingMesh) {\n\t _this4._pickingMesh.add(result.pickingMesh);\n\t }\n\t\n\t resolve();\n\t })['catch'](reject);\n\t } else {\n\t resolve();\n\t }\n\t });\n\t }\n\t }, {\n\t key: '_processPointResults',\n\t value: function _processPointResults(results) {\n\t var _this5 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions);\n\t var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals);\n\t var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors);\n\t\n\t var splitProperties;\n\t if (results.properties) {\n\t splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties);\n\t }\n\t\n\t var flats = results.flats;\n\t\n\t var objects = [];\n\t var obj;\n\t var pickingId;\n\t var pickingIds;\n\t var properties;\n\t\n\t var pointAttributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3\n\t };\n\t\n\t for (var i = 0; i < splitPositions.length; i++) {\n\t if (splitProperties && splitProperties[i]) {\n\t properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i]));\n\t } else {\n\t properties = {};\n\t }\n\t\n\t // WORKERS: obj.attributes should actually an array of polygons for\n\t // the feature, though the current logic isn't aware of that\n\t obj = {\n\t attributes: [{\n\t positions: splitPositions[i],\n\t normals: splitNormals[i],\n\t colors: splitColors[i]\n\t }],\n\t properties: properties,\n\t flat: flats[i]\n\t };\n\t\n\t // WORKERS: If interactive, generate unique ID for each feature, create\n\t // the buffer attributes and set up event listeners\n\t if (_this5._options.interactive) {\n\t pickingId = _this5.getPickingId();\n\t\n\t pickingIds = new Float32Array(splitPositions[i].length / 3);\n\t pickingIds.fill(pickingId);\n\t\n\t obj.attributes[0].pickingIds = pickingIds;\n\t\n\t pointAttributeLengths.pickingIds = 1;\n\t\n\t _this5._addPicking(pickingId, properties);\n\t }\n\t\n\t // TODO: Make this specific to polygon attributes\n\t if (typeof _this5._options.onAddAttributes === 'function') {\n\t var customAttributes = _this5._options.onAddAttributes(obj.attributes[0], properties);\n\t var customAttribute;\n\t for (var key in customAttributes) {\n\t customAttribute = customAttributes[key];\n\t obj.attributes[0][key] = customAttribute.value;\n\t pointAttributeLengths[key] = customAttribute.length;\n\t }\n\t }\n\t\n\t objects.push(obj);\n\t }\n\t\n\t var pointAttributes = [];\n\t\n\t var pointFlat = true;\n\t\n\t for (var i = 0; i < objects.length; i++) {\n\t obj = objects[i];\n\t\n\t if (pointFlat && !obj.flat) {\n\t pointFlat = false;\n\t }\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t pointAttributes.push(bufferAttributes);\n\t };\n\t\n\t if (pointAttributes.length > 0) {\n\t var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes);\n\t\n\t // TODO: Make this work when style is a function per feature\n\t var style = typeof _this5._options.style === 'function' ? _this5._options.style(objects[0]) : _this5._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this5._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then(function (result) {\n\t _this5._pointMesh = result.mesh;\n\t _this5.add(_this5._pointMesh);\n\t\n\t if (result.pickingMesh) {\n\t _this5._pickingMesh.add(result.pickingMesh);\n\t }\n\t\n\t resolve();\n\t })['catch'](reject);\n\t } else {\n\t resolve();\n\t }\n\t });\n\t }\n\t\n\t // TODO: At some point this needs to return all the features to the main thread\n\t // so it can generate meshes and output to the scene, as well as perhaps creating\n\t // individual layers / components for each feature to track things like picking\n\t // and properties\n\t //\n\t // TODO: Find a way so the origin point isn't needed to be passed in as it\n\t // feels a bit messy and against the idea of a static Geo class\n\t //\n\t // TODO: Support passing custom geometry for point layers\n\t }, {\n\t key: '_setPolygonMesh',\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // Could make this an abstract method for each geometry layer\n\t value: function _setPolygonMesh(attributes, attributeLengths, style, flat) {\n\t if (!this._world) {\n\t return Promise.reject();\n\t }\n\t\n\t return _geometryPolygonLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n\t }\n\t }, {\n\t key: '_setPolylineMesh',\n\t value: function _setPolylineMesh(attributes, attributeLengths, style, flat) {\n\t if (!this._world) {\n\t return Promise.reject();\n\t }\n\t\n\t return _geometryPolylineLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options);\n\t }\n\t }, {\n\t key: '_setPointMesh',\n\t value: function _setPointMesh(attributes, attributeLengths, style, flat) {\n\t if (!this._world) {\n\t return Promise.reject();\n\t }\n\t\n\t return _geometryPointLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPicking',\n\t value: function _addPicking(pickingId, properties) {\n\t var _this6 = this;\n\t\n\t this._world.on('pick-click-' + pickingId, function (pickingId, point2d, point3d, intersects) {\n\t _this6._world.emit('click', _this6, properties, point2d, point3d);\n\t });\n\t\n\t this._world.on('pick-hover-' + pickingId, function (pickingId, point2d, point3d, intersects) {\n\t _this6._world.emit('hover', _this6, properties, point2d, point3d);\n\t });\n\t }\n\t\n\t // TODO: Finish cleanup\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'Process',\n\t value: function Process(geojson, topojson, headers, originPoint, _style, _properties, _pointGeometry) {\n\t return new Promise(function (resolve, reject) {\n\t GeoJSONWorkerLayer.ProcessGeoJSON(geojson, headers).then(function (res) {\n\t // Collects features into a single FeatureCollection\n\t //\n\t // Also converts TopoJSON to GeoJSON if instructed\n\t var geojson = _utilGeoJSON2['default'].collectFeatures(res, topojson);\n\t\n\t // TODO: Check that GeoJSON is valid / usable\n\t\n\t var features = geojson.features;\n\t\n\t // TODO: Run filter, if provided (must be static)\n\t\n\t var pointScale;\n\t var polygons = [];\n\t var polylines = [];\n\t var points = [];\n\t\n\t // Deserialise style function if provided\n\t if (typeof _style === 'string') {\n\t _style = _utilStringify2['default'].stringToFunction(_style);\n\t }\n\t\n\t // Assume that a style won't be set per feature\n\t var style = _style;\n\t\n\t var pointGeometry;\n\t // Deserialise pointGeometry function if provided\n\t if (typeof _pointGeometry === 'string') {\n\t pointGeometry = _utilStringify2['default'].stringToFunction(_pointGeometry);\n\t }\n\t\n\t var feature;\n\t for (var i = 0; i < features.length; i++) {\n\t feature = features[i];\n\t\n\t var geometry = feature.geometry;\n\t var coordinates = geometry.coordinates ? geometry.coordinates : null;\n\t\n\t if (!coordinates || !geometry) {\n\t return;\n\t }\n\t\n\t // Get per-feature style object, if provided\n\t if (typeof _style === 'function') {\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _style(feature));\n\t // console.log(feature, style);\n\t }\n\t\n\t if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n\t coordinates = _geometryPolygonLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t var converted = coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t });\n\t\n\t var point;\n\t var projected = converted.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (latlon) {\n\t point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint);\n\t\n\t if (!pointScale) {\n\t pointScale = _geoGeo2['default'].pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t });\n\t\n\t var polygon = {\n\t projected: projected,\n\t options: {\n\t pointScale: pointScale,\n\t style: style\n\t }\n\t };\n\t\n\t if (_properties) {\n\t polygon.properties = feature.properties;\n\t }\n\t\n\t polygons.push(polygon);\n\t }\n\t\n\t if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n\t coordinates = _geometryPolylineLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t var converted = coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t\n\t var point;\n\t var projected = converted.map(function (_coordinates) {\n\t return _coordinates.map(function (latlon) {\n\t point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint);\n\t\n\t if (!pointScale) {\n\t pointScale = _geoGeo2['default'].pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t\n\t var polyline = {\n\t projected: projected,\n\t options: {\n\t pointScale: pointScale,\n\t style: style\n\t }\n\t };\n\t\n\t if (_properties) {\n\t polyline.properties = feature.properties;\n\t }\n\t\n\t polylines.push(polyline);\n\t }\n\t\n\t if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n\t coordinates = _geometryPointLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t var converted = coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t\n\t var point;\n\t var projected = converted.map(function (latlon) {\n\t point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint);\n\t\n\t if (!pointScale) {\n\t pointScale = _geoGeo2['default'].pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t\n\t var point = {\n\t projected: projected,\n\t options: {\n\t pointGeometry: pointGeometry(feature),\n\t pointScale: pointScale,\n\t style: style\n\t }\n\t };\n\t\n\t if (_properties) {\n\t point.properties = feature.properties;\n\t }\n\t\n\t points.push(point);\n\t }\n\t };\n\t\n\t var polygonBufferPromises = [];\n\t var polylineBufferPromises = [];\n\t var pointBufferPromises = [];\n\t\n\t var polygon;\n\t for (var i = 0; i < polygons.length; i++) {\n\t polygon = polygons[i];\n\t polygonBufferPromises.push(_geometryPolygonLayer2['default'].SetBufferAttributes(polygon.projected, polygon.options));\n\t };\n\t\n\t var polyline;\n\t for (var i = 0; i < polylines.length; i++) {\n\t polyline = polylines[i];\n\t polylineBufferPromises.push(_geometryPolylineLayer2['default'].SetBufferAttributes(polyline.projected, polyline.options));\n\t };\n\t\n\t var point;\n\t for (var i = 0; i < points.length; i++) {\n\t point = points[i];\n\t pointBufferPromises.push(_geometryPointLayer2['default'].SetBufferAttributes(point.projected, point.options));\n\t };\n\t\n\t var data = {};\n\t var transferrables = [];\n\t\n\t // TODO: Make this work with polylines too\n\t // TODO: Make this so it's not a nest of promises\n\t GeoJSONWorkerLayer.ProcessPolygons(polygonBufferPromises, polygons, _properties).then(function (result) {\n\t data.polygons = result.data;\n\t transferrables = transferrables.concat(result.transferrables);\n\t\n\t GeoJSONWorkerLayer.ProcessPolylines(polylineBufferPromises, polylines, _properties).then(function (result) {\n\t data.polylines = result.data;\n\t transferrables = transferrables.concat(result.transferrables);\n\t\n\t GeoJSONWorkerLayer.ProcessPoints(pointBufferPromises, points, _properties).then(function (result) {\n\t data.points = result.data;\n\t transferrables = transferrables.concat(result.transferrables);\n\t\n\t resolve({\n\t data: data,\n\t transferrables: transferrables\n\t });\n\t });\n\t });\n\t });\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'ProcessPolygons',\n\t value: function ProcessPolygons(polygonPromises, polygons, _properties) {\n\t return new Promise(function (resolve, reject) {\n\t Promise.all(polygonPromises).then(function (results) {\n\t var transferrables = [];\n\t\n\t var positions = [];\n\t var normals = [];\n\t var colors = [];\n\t var tops = [];\n\t\n\t var outlinePositions = [];\n\t var outlineColors = [];\n\t\n\t var properties = [];\n\t\n\t var flats = [];\n\t var polygon;\n\t\n\t var result;\n\t for (var i = 0; i < results.length; i++) {\n\t result = results[i];\n\t\n\t polygon = polygons[i];\n\t\n\t // WORKERS: Making this a typed array will speed up transfer time\n\t // As things stand this adds on a few milliseconds\n\t flats.push(result.flat);\n\t\n\t // WORKERS: result.attributes is actually an array of polygons for each\n\t // feature, though the current logic isn't keeping these all together\n\t\n\t var attributes;\n\t for (var j = 0; j < result.attributes.length; j++) {\n\t attributes = result.attributes[j];\n\t\n\t positions.push(attributes.positions);\n\t normals.push(attributes.normals);\n\t colors.push(attributes.colors);\n\t tops.push(attributes.tops);\n\t\n\t if (_properties) {\n\t properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties)));\n\t }\n\t };\n\t\n\t var outlineAttributes;\n\t for (var j = 0; j < result.outlineAttributes.length; j++) {\n\t outlineAttributes = result.outlineAttributes[j];\n\t\n\t outlinePositions.push(outlineAttributes.positions);\n\t outlineColors.push(outlineAttributes.colors);\n\t };\n\t };\n\t\n\t var mergedAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(positions),\n\t normals: _utilBuffer2['default'].mergeFloat32Arrays(normals),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(colors),\n\t tops: _utilBuffer2['default'].mergeFloat32Arrays(tops)\n\t };\n\t\n\t var mergedOutlineAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(outlinePositions),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(outlineColors)\n\t };\n\t\n\t transferrables.push(mergedAttributes.positions[0].buffer);\n\t transferrables.push(mergedAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.normals[0].buffer);\n\t transferrables.push(mergedAttributes.normals[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.colors[0].buffer);\n\t transferrables.push(mergedAttributes.colors[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.tops[0].buffer);\n\t transferrables.push(mergedAttributes.tops[1].buffer);\n\t\n\t transferrables.push(mergedOutlineAttributes.positions[0].buffer);\n\t transferrables.push(mergedOutlineAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedOutlineAttributes.colors[0].buffer);\n\t transferrables.push(mergedOutlineAttributes.colors[1].buffer);\n\t\n\t var mergedProperties;\n\t if (_properties) {\n\t mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties);\n\t\n\t transferrables.push(mergedProperties[0].buffer);\n\t transferrables.push(mergedProperties[1].buffer);\n\t }\n\t\n\t var output = {\n\t attributes: mergedAttributes,\n\t outlineAttributes: mergedOutlineAttributes,\n\t flats: flats\n\t };\n\t\n\t if (_properties) {\n\t output.properties = mergedProperties;\n\t }\n\t\n\t // TODO: Also return GeoJSON features that can be mapped to objects on\n\t // the main thread. Allow user to provide filter / toggles to only return\n\t // properties from the GeoJSON that they need (eg. don't return geometry,\n\t // or don't return properties.height)\n\t resolve({\n\t data: output,\n\t transferrables: transferrables\n\t });\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'ProcessPolylines',\n\t value: function ProcessPolylines(polylinePromises, polylines, _properties) {\n\t return new Promise(function (resolve, reject) {\n\t Promise.all(polylinePromises).then(function (results) {\n\t var transferrables = [];\n\t\n\t var positions = [];\n\t var colors = [];\n\t\n\t var properties = [];\n\t\n\t var flats = [];\n\t var polyline;\n\t\n\t var result;\n\t for (var i = 0; i < results.length; i++) {\n\t result = results[i];\n\t\n\t polyline = polylines[i];\n\t\n\t // WORKERS: Making this a typed array will speed up transfer time\n\t // As things stand this adds on a few milliseconds\n\t flats.push(result.flat);\n\t\n\t // WORKERS: result.attributes is actually an array of polygons for each\n\t // feature, though the current logic isn't keeping these all together\n\t\n\t var attributes;\n\t for (var j = 0; j < result.attributes.length; j++) {\n\t attributes = result.attributes[j];\n\t\n\t positions.push(attributes.positions);\n\t colors.push(attributes.colors);\n\t\n\t if (_properties) {\n\t properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polyline.properties)));\n\t }\n\t };\n\t };\n\t\n\t var mergedAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(positions),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(colors)\n\t };\n\t\n\t transferrables.push(mergedAttributes.positions[0].buffer);\n\t transferrables.push(mergedAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.colors[0].buffer);\n\t transferrables.push(mergedAttributes.colors[1].buffer);\n\t\n\t var mergedProperties;\n\t if (_properties) {\n\t mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties);\n\t\n\t transferrables.push(mergedProperties[0].buffer);\n\t transferrables.push(mergedProperties[1].buffer);\n\t }\n\t\n\t var output = {\n\t attributes: mergedAttributes,\n\t flats: flats\n\t };\n\t\n\t if (_properties) {\n\t output.properties = mergedProperties;\n\t }\n\t\n\t // TODO: Also return GeoJSON features that can be mapped to objects on\n\t // the main thread. Allow user to provide filter / toggles to only return\n\t // properties from the GeoJSON that they need (eg. don't return geometry,\n\t // or don't return properties.height)\n\t resolve({\n\t data: output,\n\t transferrables: transferrables\n\t });\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // TODO: Dedupe with ProcessPolygons as they are identical\n\t }, {\n\t key: 'ProcessPoints',\n\t value: function ProcessPoints(pointPromises, points, _properties) {\n\t return new Promise(function (resolve, reject) {\n\t Promise.all(pointPromises).then(function (results) {\n\t var transferrables = [];\n\t\n\t var positions = [];\n\t var normals = [];\n\t var colors = [];\n\t\n\t var properties = [];\n\t\n\t var flats = [];\n\t var point;\n\t\n\t var result;\n\t for (var i = 0; i < results.length; i++) {\n\t result = results[i];\n\t\n\t point = points[i];\n\t\n\t // WORKERS: Making this a typed array will speed up transfer time\n\t // As things stand this adds on a few milliseconds\n\t flats.push(result.flat);\n\t\n\t // WORKERS: result.attributes is actually an array of polygons for each\n\t // feature, though the current logic isn't keeping these all together\n\t\n\t var attributes;\n\t for (var j = 0; j < result.attributes.length; j++) {\n\t attributes = result.attributes[j];\n\t\n\t positions.push(attributes.positions);\n\t normals.push(attributes.normals);\n\t colors.push(attributes.colors);\n\t\n\t if (_properties) {\n\t properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties)));\n\t }\n\t };\n\t };\n\t\n\t var mergedAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(positions),\n\t normals: _utilBuffer2['default'].mergeFloat32Arrays(normals),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(colors)\n\t };\n\t\n\t transferrables.push(mergedAttributes.positions[0].buffer);\n\t transferrables.push(mergedAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.normals[0].buffer);\n\t transferrables.push(mergedAttributes.normals[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.colors[0].buffer);\n\t transferrables.push(mergedAttributes.colors[1].buffer);\n\t\n\t var mergedProperties;\n\t if (_properties) {\n\t mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties);\n\t\n\t transferrables.push(mergedProperties[0].buffer);\n\t transferrables.push(mergedProperties[1].buffer);\n\t }\n\t\n\t var output = {\n\t attributes: mergedAttributes,\n\t flats: flats\n\t };\n\t\n\t if (_properties) {\n\t output.properties = mergedProperties;\n\t }\n\t\n\t // TODO: Also return GeoJSON features that can be mapped to objects on\n\t // the main thread. Allow user to provide filter / toggles to only return\n\t // properties from the GeoJSON that they need (eg. don't return geometry,\n\t // or don't return properties.height)\n\t resolve({\n\t data: output,\n\t transferrables: transferrables\n\t });\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'ProcessGeoJSON',\n\t value: function ProcessGeoJSON(geojson, headers) {\n\t if (typeof geojson === 'string') {\n\t return GeoJSONWorkerLayer.RequestGeoJSON(geojson, headers);\n\t } else {\n\t return Promise.resolve(JSON.parse(_utilBuffer2['default'].uint8ArrayToString(geojson)));\n\t }\n\t }\n\t }, {\n\t key: 'RequestGeoJSON',\n\t value: function RequestGeoJSON(path, headers) {\n\t return (0, _reqwest2['default'])({\n\t url: path,\n\t type: 'json',\n\t crossOrigin: true,\n\t headers: headers\n\t });\n\t }\n\t }]);\n\t\n\t return GeoJSONWorkerLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = GeoJSONWorkerLayer;\n\t\n\tvar noNew = function noNew(geojson, options) {\n\t return new GeoJSONWorkerLayer(geojson, options);\n\t};\n\t\n\texports.geoJSONWorkerLayer = noNew;\n\n/***/ },\n/* 23 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n\t * Reqwest! A general purpose XHR connection manager\n\t * license MIT (c) Dustin Diaz 2015\n\t * https://github.com/ded/reqwest\n\t */\n\t\n\t!function (name, context, definition) {\n\t if (typeof module != 'undefined' && module.exports) module.exports = definition()\n\t else if (true) !(__WEBPACK_AMD_DEFINE_FACTORY__ = (definition), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))\n\t else context[name] = definition()\n\t}('reqwest', this, function () {\n\t\n\t var context = this\n\t\n\t if ('window' in context) {\n\t var doc = document\n\t , byTag = 'getElementsByTagName'\n\t , head = doc[byTag]('head')[0]\n\t } else {\n\t var XHR2\n\t try {\n\t XHR2 = __webpack_require__(24)\n\t } catch (ex) {\n\t throw new Error('Peer dependency `xhr2` required! Please npm install xhr2')\n\t }\n\t }\n\t\n\t\n\t var httpsRe = /^http/\n\t , protocolRe = /(^\\w+):\\/\\//\n\t , twoHundo = /^(20\\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\n\t , readyState = 'readyState'\n\t , contentType = 'Content-Type'\n\t , requestedWith = 'X-Requested-With'\n\t , uniqid = 0\n\t , callbackPrefix = 'reqwest_' + (+new Date())\n\t , lastValue // data stored by the most recent JSONP callback\n\t , xmlHttpRequest = 'XMLHttpRequest'\n\t , xDomainRequest = 'XDomainRequest'\n\t , noop = function () {}\n\t\n\t , isArray = typeof Array.isArray == 'function'\n\t ? Array.isArray\n\t : function (a) {\n\t return a instanceof Array\n\t }\n\t\n\t , defaultHeaders = {\n\t 'contentType': 'application/x-www-form-urlencoded'\n\t , 'requestedWith': xmlHttpRequest\n\t , 'accept': {\n\t '*': 'text/javascript, text/html, application/xml, text/xml, */*'\n\t , 'xml': 'application/xml, text/xml'\n\t , 'html': 'text/html'\n\t , 'text': 'text/plain'\n\t , 'json': 'application/json, text/javascript'\n\t , 'js': 'application/javascript, text/javascript'\n\t }\n\t }\n\t\n\t , xhr = function(o) {\n\t // is it x-domain\n\t if (o['crossOrigin'] === true) {\n\t var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null\n\t if (xhr && 'withCredentials' in xhr) {\n\t return xhr\n\t } else if (context[xDomainRequest]) {\n\t return new XDomainRequest()\n\t } else {\n\t throw new Error('Browser does not support cross-origin requests')\n\t }\n\t } else if (context[xmlHttpRequest]) {\n\t return new XMLHttpRequest()\n\t } else if (XHR2) {\n\t return new XHR2()\n\t } else {\n\t return new ActiveXObject('Microsoft.XMLHTTP')\n\t }\n\t }\n\t , globalSetupOptions = {\n\t dataFilter: function (data) {\n\t return data\n\t }\n\t }\n\t\n\t function succeed(r) {\n\t var protocol = protocolRe.exec(r.url)\n\t protocol = (protocol && protocol[1]) || context.location.protocol\n\t return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response\n\t }\n\t\n\t function handleReadyState(r, success, error) {\n\t return function () {\n\t // use _aborted to mitigate against IE err c00c023f\n\t // (can't read props on aborted request objects)\n\t if (r._aborted) return error(r.request)\n\t if (r._timedOut) return error(r.request, 'Request is aborted: timeout')\n\t if (r.request && r.request[readyState] == 4) {\n\t r.request.onreadystatechange = noop\n\t if (succeed(r)) success(r.request)\n\t else\n\t error(r.request)\n\t }\n\t }\n\t }\n\t\n\t function setHeaders(http, o) {\n\t var headers = o['headers'] || {}\n\t , h\n\t\n\t headers['Accept'] = headers['Accept']\n\t || defaultHeaders['accept'][o['type']]\n\t || defaultHeaders['accept']['*']\n\t\n\t var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData);\n\t // breaks cross-origin requests with legacy browsers\n\t if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']\n\t if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']\n\t for (h in headers)\n\t headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])\n\t }\n\t\n\t function setCredentials(http, o) {\n\t if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n\t http.withCredentials = !!o['withCredentials']\n\t }\n\t }\n\t\n\t function generalCallback(data) {\n\t lastValue = data\n\t }\n\t\n\t function urlappend (url, s) {\n\t return url + (/\\?/.test(url) ? '&' : '?') + s\n\t }\n\t\n\t function handleJsonp(o, fn, err, url) {\n\t var reqId = uniqid++\n\t , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key\n\t , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)\n\t , cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)')\n\t , match = url.match(cbreg)\n\t , script = doc.createElement('script')\n\t , loaded = 0\n\t , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1\n\t\n\t if (match) {\n\t if (match[3] === '?') {\n\t url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name\n\t } else {\n\t cbval = match[3] // provided callback func name\n\t }\n\t } else {\n\t url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em\n\t }\n\t\n\t context[cbval] = generalCallback\n\t\n\t script.type = 'text/javascript'\n\t script.src = url\n\t script.async = true\n\t if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n\t // need this for IE due to out-of-order onreadystatechange(), binding script\n\t // execution to an event listener gives us control over when the script\n\t // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n\t script.htmlFor = script.id = '_reqwest_' + reqId\n\t }\n\t\n\t script.onload = script.onreadystatechange = function () {\n\t if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {\n\t return false\n\t }\n\t script.onload = script.onreadystatechange = null\n\t script.onclick && script.onclick()\n\t // Call the user callback with the last value stored and clean up values and scripts.\n\t fn(lastValue)\n\t lastValue = undefined\n\t head.removeChild(script)\n\t loaded = 1\n\t }\n\t\n\t // Add the script to the DOM head\n\t head.appendChild(script)\n\t\n\t // Enable JSONP timeout\n\t return {\n\t abort: function () {\n\t script.onload = script.onreadystatechange = null\n\t err({}, 'Request is aborted: timeout', {})\n\t lastValue = undefined\n\t head.removeChild(script)\n\t loaded = 1\n\t }\n\t }\n\t }\n\t\n\t function getRequest(fn, err) {\n\t var o = this.o\n\t , method = (o['method'] || 'GET').toUpperCase()\n\t , url = typeof o === 'string' ? o : o['url']\n\t // convert non-string objects to query-string form unless o['processData'] is false\n\t , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')\n\t ? reqwest.toQueryString(o['data'])\n\t : (o['data'] || null)\n\t , http\n\t , sendWait = false\n\t\n\t // if we're working on a GET request and we have data then we should append\n\t // query string to end of URL and not post data\n\t if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n\t url = urlappend(url, data)\n\t data = null\n\t }\n\t\n\t if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)\n\t\n\t // get the xhr from the factory if passed\n\t // if the factory returns null, fall-back to ours\n\t http = (o.xhr && o.xhr(o)) || xhr(o)\n\t\n\t http.open(method, url, o['async'] === false ? false : true)\n\t setHeaders(http, o)\n\t setCredentials(http, o)\n\t if (context[xDomainRequest] && http instanceof context[xDomainRequest]) {\n\t http.onload = fn\n\t http.onerror = err\n\t // NOTE: see\n\t // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e\n\t http.onprogress = function() {}\n\t sendWait = true\n\t } else {\n\t http.onreadystatechange = handleReadyState(this, fn, err)\n\t }\n\t o['before'] && o['before'](http)\n\t if (sendWait) {\n\t setTimeout(function () {\n\t http.send(data)\n\t }, 200)\n\t } else {\n\t http.send(data)\n\t }\n\t return http\n\t }\n\t\n\t function Reqwest(o, fn) {\n\t this.o = o\n\t this.fn = fn\n\t\n\t init.apply(this, arguments)\n\t }\n\t\n\t function setType(header) {\n\t // json, javascript, text/plain, text/html, xml\n\t if (header === null) return undefined; //In case of no content-type.\n\t if (header.match('json')) return 'json'\n\t if (header.match('javascript')) return 'js'\n\t if (header.match('text')) return 'html'\n\t if (header.match('xml')) return 'xml'\n\t }\n\t\n\t function init(o, fn) {\n\t\n\t this.url = typeof o == 'string' ? o : o['url']\n\t this.timeout = null\n\t\n\t // whether request has been fulfilled for purpose\n\t // of tracking the Promises\n\t this._fulfilled = false\n\t // success handlers\n\t this._successHandler = function(){}\n\t this._fulfillmentHandlers = []\n\t // error handlers\n\t this._errorHandlers = []\n\t // complete (both success and fail) handlers\n\t this._completeHandlers = []\n\t this._erred = false\n\t this._responseArgs = {}\n\t\n\t var self = this\n\t\n\t fn = fn || function () {}\n\t\n\t if (o['timeout']) {\n\t this.timeout = setTimeout(function () {\n\t timedOut()\n\t }, o['timeout'])\n\t }\n\t\n\t if (o['success']) {\n\t this._successHandler = function () {\n\t o['success'].apply(o, arguments)\n\t }\n\t }\n\t\n\t if (o['error']) {\n\t this._errorHandlers.push(function () {\n\t o['error'].apply(o, arguments)\n\t })\n\t }\n\t\n\t if (o['complete']) {\n\t this._completeHandlers.push(function () {\n\t o['complete'].apply(o, arguments)\n\t })\n\t }\n\t\n\t function complete (resp) {\n\t o['timeout'] && clearTimeout(self.timeout)\n\t self.timeout = null\n\t while (self._completeHandlers.length > 0) {\n\t self._completeHandlers.shift()(resp)\n\t }\n\t }\n\t\n\t function success (resp) {\n\t var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE\n\t resp = (type !== 'jsonp') ? self.request : resp\n\t // use global data filter on response text\n\t var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)\n\t , r = filteredResponse\n\t try {\n\t resp.responseText = r\n\t } catch (e) {\n\t // can't assign this in IE<=8, just ignore\n\t }\n\t if (r) {\n\t switch (type) {\n\t case 'json':\n\t try {\n\t resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')')\n\t } catch (err) {\n\t return error(resp, 'Could not parse JSON in response', err)\n\t }\n\t break\n\t case 'js':\n\t resp = eval(r)\n\t break\n\t case 'html':\n\t resp = r\n\t break\n\t case 'xml':\n\t resp = resp.responseXML\n\t && resp.responseXML.parseError // IE trololo\n\t && resp.responseXML.parseError.errorCode\n\t && resp.responseXML.parseError.reason\n\t ? null\n\t : resp.responseXML\n\t break\n\t }\n\t }\n\t\n\t self._responseArgs.resp = resp\n\t self._fulfilled = true\n\t fn(resp)\n\t self._successHandler(resp)\n\t while (self._fulfillmentHandlers.length > 0) {\n\t resp = self._fulfillmentHandlers.shift()(resp)\n\t }\n\t\n\t complete(resp)\n\t }\n\t\n\t function timedOut() {\n\t self._timedOut = true\n\t self.request.abort()\n\t }\n\t\n\t function error(resp, msg, t) {\n\t resp = self.request\n\t self._responseArgs.resp = resp\n\t self._responseArgs.msg = msg\n\t self._responseArgs.t = t\n\t self._erred = true\n\t while (self._errorHandlers.length > 0) {\n\t self._errorHandlers.shift()(resp, msg, t)\n\t }\n\t complete(resp)\n\t }\n\t\n\t this.request = getRequest.call(this, success, error)\n\t }\n\t\n\t Reqwest.prototype = {\n\t abort: function () {\n\t this._aborted = true\n\t this.request.abort()\n\t }\n\t\n\t , retry: function () {\n\t init.call(this, this.o, this.fn)\n\t }\n\t\n\t /**\n\t * Small deviation from the Promises A CommonJs specification\n\t * http://wiki.commonjs.org/wiki/Promises/A\n\t */\n\t\n\t /**\n\t * `then` will execute upon successful requests\n\t */\n\t , then: function (success, fail) {\n\t success = success || function () {}\n\t fail = fail || function () {}\n\t if (this._fulfilled) {\n\t this._responseArgs.resp = success(this._responseArgs.resp)\n\t } else if (this._erred) {\n\t fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n\t } else {\n\t this._fulfillmentHandlers.push(success)\n\t this._errorHandlers.push(fail)\n\t }\n\t return this\n\t }\n\t\n\t /**\n\t * `always` will execute whether the request succeeds or fails\n\t */\n\t , always: function (fn) {\n\t if (this._fulfilled || this._erred) {\n\t fn(this._responseArgs.resp)\n\t } else {\n\t this._completeHandlers.push(fn)\n\t }\n\t return this\n\t }\n\t\n\t /**\n\t * `fail` will execute when the request fails\n\t */\n\t , fail: function (fn) {\n\t if (this._erred) {\n\t fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n\t } else {\n\t this._errorHandlers.push(fn)\n\t }\n\t return this\n\t }\n\t , 'catch': function (fn) {\n\t return this.fail(fn)\n\t }\n\t }\n\t\n\t function reqwest(o, fn) {\n\t return new Reqwest(o, fn)\n\t }\n\t\n\t // normalize newline variants according to spec -> CRLF\n\t function normalize(s) {\n\t return s ? s.replace(/\\r?\\n/g, '\\r\\n') : ''\n\t }\n\t\n\t function serial(el, cb) {\n\t var n = el.name\n\t , t = el.tagName.toLowerCase()\n\t , optCb = function (o) {\n\t // IE gives value=\"\" even where there is no value attribute\n\t // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273\n\t if (o && !o['disabled'])\n\t cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))\n\t }\n\t , ch, ra, val, i\n\t\n\t // don't serialize elements that are disabled or without a name\n\t if (el.disabled || !n) return\n\t\n\t switch (t) {\n\t case 'input':\n\t if (!/reset|button|image|file/i.test(el.type)) {\n\t ch = /checkbox/i.test(el.type)\n\t ra = /radio/i.test(el.type)\n\t val = el.value\n\t // WebKit gives us \"\" instead of \"on\" if a checkbox has no value, so correct it here\n\t ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))\n\t }\n\t break\n\t case 'textarea':\n\t cb(n, normalize(el.value))\n\t break\n\t case 'select':\n\t if (el.type.toLowerCase() === 'select-one') {\n\t optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)\n\t } else {\n\t for (i = 0; el.length && i < el.length; i++) {\n\t el.options[i].selected && optCb(el.options[i])\n\t }\n\t }\n\t break\n\t }\n\t }\n\t\n\t // collect up all form elements found from the passed argument elements all\n\t // the way down to child elements; pass a '' or form fields.\n\t // called with 'this'=callback to use for serial() on each element\n\t function eachFormElement() {\n\t var cb = this\n\t , e, i\n\t , serializeSubtags = function (e, tags) {\n\t var i, j, fa\n\t for (i = 0; i < tags.length; i++) {\n\t fa = e[byTag](tags[i])\n\t for (j = 0; j < fa.length; j++) serial(fa[j], cb)\n\t }\n\t }\n\t\n\t for (i = 0; i < arguments.length; i++) {\n\t e = arguments[i]\n\t if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)\n\t serializeSubtags(e, [ 'input', 'select', 'textarea' ])\n\t }\n\t }\n\t\n\t // standard query string style serialization\n\t function serializeQueryString() {\n\t return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))\n\t }\n\t\n\t // { 'name': 'value', ... } style serialization\n\t function serializeHash() {\n\t var hash = {}\n\t eachFormElement.apply(function (name, value) {\n\t if (name in hash) {\n\t hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])\n\t hash[name].push(value)\n\t } else hash[name] = value\n\t }, arguments)\n\t return hash\n\t }\n\t\n\t // [ { name: 'name', value: 'value' }, ... ] style serialization\n\t reqwest.serializeArray = function () {\n\t var arr = []\n\t eachFormElement.apply(function (name, value) {\n\t arr.push({name: name, value: value})\n\t }, arguments)\n\t return arr\n\t }\n\t\n\t reqwest.serialize = function () {\n\t if (arguments.length === 0) return ''\n\t var opt, fn\n\t , args = Array.prototype.slice.call(arguments, 0)\n\t\n\t opt = args.pop()\n\t opt && opt.nodeType && args.push(opt) && (opt = null)\n\t opt && (opt = opt.type)\n\t\n\t if (opt == 'map') fn = serializeHash\n\t else if (opt == 'array') fn = reqwest.serializeArray\n\t else fn = serializeQueryString\n\t\n\t return fn.apply(null, args)\n\t }\n\t\n\t reqwest.toQueryString = function (o, trad) {\n\t var prefix, i\n\t , traditional = trad || false\n\t , s = []\n\t , enc = encodeURIComponent\n\t , add = function (key, value) {\n\t // If value is a function, invoke it and return its value\n\t value = ('function' === typeof value) ? value() : (value == null ? '' : value)\n\t s[s.length] = enc(key) + '=' + enc(value)\n\t }\n\t // If an array was passed in, assume that it is an array of form elements.\n\t if (isArray(o)) {\n\t for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])\n\t } else {\n\t // If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t // did it), otherwise encode params recursively.\n\t for (prefix in o) {\n\t if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)\n\t }\n\t }\n\t\n\t // spaces should be + according to spec\n\t return s.join('&').replace(/%20/g, '+')\n\t }\n\t\n\t function buildParams(prefix, obj, traditional, add) {\n\t var name, i, v\n\t , rbracket = /\\[\\]$/\n\t\n\t if (isArray(obj)) {\n\t // Serialize array item.\n\t for (i = 0; obj && i < obj.length; i++) {\n\t v = obj[i]\n\t if (traditional || rbracket.test(prefix)) {\n\t // Treat each array item as a scalar.\n\t add(prefix, v)\n\t } else {\n\t buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)\n\t }\n\t }\n\t } else if (obj && obj.toString() === '[object Object]') {\n\t // Serialize object item.\n\t for (name in obj) {\n\t buildParams(prefix + '[' + name + ']', obj[name], traditional, add)\n\t }\n\t\n\t } else {\n\t // Serialize scalar item.\n\t add(prefix, obj)\n\t }\n\t }\n\t\n\t reqwest.getcallbackPrefix = function () {\n\t return callbackPrefix\n\t }\n\t\n\t // jQuery and Zepto compatibility, differences can be remapped here so you can call\n\t // .ajax.compat(options, callback)\n\t reqwest.compat = function (o, fn) {\n\t if (o) {\n\t o['type'] && (o['method'] = o['type']) && delete o['type']\n\t o['dataType'] && (o['type'] = o['dataType'])\n\t o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']\n\t o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])\n\t }\n\t return new Reqwest(o, fn)\n\t }\n\t\n\t reqwest.ajaxSetup = function (options) {\n\t options = options || {}\n\t for (var k in options) {\n\t globalSetupOptions[k] = options[k]\n\t }\n\t }\n\t\n\t return reqwest\n\t});\n\n\n/***/ },\n/* 24 */\n/***/ function(module, exports) {\n\n\t/* (ignored) */\n\n/***/ },\n/* 25 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * GeoJSON helpers for handling data and generating objects\n\t */\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _topojson2 = __webpack_require__(26);\n\t\n\tvar topojson = _interopRequireWildcard(_topojson2);\n\t\n\tvar _geojsonMerge = __webpack_require__(27);\n\t\n\tvar _geojsonMerge2 = _interopRequireDefault(_geojsonMerge);\n\t\n\tvar _earcut = __webpack_require__(29);\n\t\n\tvar _earcut2 = _interopRequireDefault(_earcut);\n\t\n\tvar _extrudePolygon = __webpack_require__(30);\n\t\n\tvar _extrudePolygon2 = _interopRequireDefault(_extrudePolygon);\n\t\n\t// TODO: Make it so height can be per-coordinate / point but connected together\n\t// as a linestring (eg. GPS points with an elevation at each point)\n\t//\n\t// This isn't really valid GeoJSON so perhaps something best left to an external\n\t// component for now, until a better approach can be considered\n\t//\n\t// See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html\n\t\n\t// Light and dark colours used for poor-mans AO gradient on object sides\n\tvar light = new _three2['default'].Color(0xffffff);\n\tvar shadow = new _three2['default'].Color(0x666666);\n\t\n\tvar GeoJSON = (function () {\n\t var defaultStyle = {\n\t color: '#ffffff',\n\t outline: false,\n\t outlineColor: '#000000',\n\t transparent: false,\n\t opacity: 1,\n\t blending: _three2['default'].NormalBlending,\n\t height: 0,\n\t lineOpacity: 1,\n\t lineTransparent: false,\n\t lineColor: '#ffffff',\n\t lineWidth: 1,\n\t lineBlending: _three2['default'].NormalBlending\n\t };\n\t\n\t // Attempts to merge together multiple GeoJSON Features or FeatureCollections\n\t // into a single FeatureCollection\n\t var collectFeatures = function collectFeatures(data, _topojson) {\n\t var collections = [];\n\t\n\t if (_topojson) {\n\t // TODO: Allow TopoJSON objects to be overridden as an option\n\t\n\t // If not overridden, merge all features from all objects\n\t for (var tk in data.objects) {\n\t collections.push(topojson.feature(data, data.objects[tk]));\n\t }\n\t\n\t return (0, _geojsonMerge2['default'])(collections);\n\t } else {\n\t // If root doesn't have a type then let's see if there are features in the\n\t // next step down\n\t if (!data.type) {\n\t // TODO: Allow GeoJSON objects to be overridden as an option\n\t\n\t // If not overridden, merge all features from all objects\n\t for (var gk in data) {\n\t if (!data[gk].type) {\n\t continue;\n\t }\n\t\n\t collections.push(data[gk]);\n\t }\n\t\n\t return (0, _geojsonMerge2['default'])(collections);\n\t } else if (Array.isArray(data)) {\n\t return (0, _geojsonMerge2['default'])(data);\n\t } else {\n\t return data;\n\t }\n\t }\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var lineStringAttributes = function lineStringAttributes(coordinates, colour, height) {\n\t var _coords = [];\n\t var _colours = [];\n\t\n\t var nextCoord;\n\t\n\t // Connect coordinate with the next to make a pair\n\t //\n\t // LineSegments requires pairs of vertices so repeat the last point if\n\t // there's an odd number of vertices\n\t coordinates.forEach(function (coordinate, index) {\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _coords.push([coordinate[0], height, coordinate[1]]);\n\t\n\t nextCoord = coordinates[index + 1] ? coordinates[index + 1] : coordinate;\n\t\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _coords.push([nextCoord[0], height, nextCoord[1]]);\n\t });\n\t\n\t return {\n\t vertices: _coords,\n\t colours: _colours\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var multiLineStringAttributes = function multiLineStringAttributes(coordinates, colour, height) {\n\t var _coords = [];\n\t var _colours = [];\n\t\n\t var result;\n\t coordinates.forEach(function (coordinate) {\n\t result = lineStringAttributes(coordinate, colour, height);\n\t\n\t result.vertices.forEach(function (coord) {\n\t _coords.push(coord);\n\t });\n\t\n\t result.colours.forEach(function (colour) {\n\t _colours.push(colour);\n\t });\n\t });\n\t\n\t return {\n\t vertices: _coords,\n\t colours: _colours\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var polygonAttributes = function polygonAttributes(coordinates, colour, height) {\n\t var earcutData = _toEarcut(coordinates);\n\t\n\t var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions);\n\t\n\t var groupedVertices = [];\n\t for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) {\n\t groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions));\n\t }\n\t\n\t var extruded = (0, _extrudePolygon2['default'])(groupedVertices, faces, {\n\t bottom: 0,\n\t top: height\n\t });\n\t\n\t var topColor = colour.clone().multiply(light);\n\t var bottomColor = colour.clone().multiply(shadow);\n\t\n\t var _vertices = extruded.positions;\n\t var _faces = [];\n\t var _colours = [];\n\t\n\t var _colour;\n\t extruded.top.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t\n\t var allFlat = true;\n\t\n\t if (extruded.sides) {\n\t if (allFlat) {\n\t allFlat = false;\n\t }\n\t\n\t // Set up colours for every vertex with poor-mans AO on the sides\n\t extruded.sides.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t // First face is always bottom-bottom-top\n\t if (fi % 2 === 0) {\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t // Reverse winding for the second face\n\t // top-top-bottom\n\t } else {\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t }\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t }\n\t\n\t // Skip bottom as there's no point rendering it\n\t // allFaces.push(extruded.faces);\n\t\n\t return {\n\t vertices: _vertices,\n\t faces: _faces,\n\t colours: _colours,\n\t flat: allFlat\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var _toEarcut = function _toEarcut(data) {\n\t var dim = data[0][0].length;\n\t var result = { vertices: [], holes: [], dimensions: dim };\n\t var holeIndex = 0;\n\t\n\t for (var i = 0; i < data.length; i++) {\n\t for (var j = 0; j < data[i].length; j++) {\n\t for (var d = 0; d < dim; d++) {\n\t result.vertices.push(data[i][j][d]);\n\t }\n\t }\n\t if (i > 0) {\n\t holeIndex += data[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t\n\t return result;\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var _triangulate = function _triangulate(contour, holes, dim) {\n\t // console.time('earcut');\n\t\n\t var faces = (0, _earcut2['default'])(contour, holes, dim);\n\t var result = [];\n\t\n\t for (i = 0, il = faces.length; i < il; i += 3) {\n\t result.push(faces.slice(i, i + 3));\n\t }\n\t\n\t // console.timeEnd('earcut');\n\t\n\t return result;\n\t };\n\t\n\t return {\n\t defaultStyle: defaultStyle,\n\t collectFeatures: collectFeatures,\n\t lineStringAttributes: lineStringAttributes,\n\t multiLineStringAttributes: multiLineStringAttributes,\n\t polygonAttributes: polygonAttributes\n\t };\n\t})();\n\t\n\texports['default'] = GeoJSON;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 26 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t(function (global, factory) {\n\t true ? factory(exports) :\n\t typeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t (factory((global.topojson = global.topojson || {})));\n\t}(this, (function (exports) { 'use strict';\n\t\n\tfunction noop() {}\n\t\n\tfunction transformAbsolute(transform) {\n\t if (!transform) return noop;\n\t var x0,\n\t y0,\n\t kx = transform.scale[0],\n\t ky = transform.scale[1],\n\t dx = transform.translate[0],\n\t dy = transform.translate[1];\n\t return function(point, i) {\n\t if (!i) x0 = y0 = 0;\n\t point[0] = (x0 += point[0]) * kx + dx;\n\t point[1] = (y0 += point[1]) * ky + dy;\n\t };\n\t}\n\t\n\tfunction transformRelative(transform) {\n\t if (!transform) return noop;\n\t var x0,\n\t y0,\n\t kx = transform.scale[0],\n\t ky = transform.scale[1],\n\t dx = transform.translate[0],\n\t dy = transform.translate[1];\n\t return function(point, i) {\n\t if (!i) x0 = y0 = 0;\n\t var x1 = Math.round((point[0] - dx) / kx),\n\t y1 = Math.round((point[1] - dy) / ky);\n\t point[0] = x1 - x0;\n\t point[1] = y1 - y0;\n\t x0 = x1;\n\t y0 = y1;\n\t };\n\t}\n\t\n\tfunction reverse(array, n) {\n\t var t, j = array.length, i = j - n;\n\t while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n\t}\n\t\n\tfunction bisect(a, x) {\n\t var lo = 0, hi = a.length;\n\t while (lo < hi) {\n\t var mid = lo + hi >>> 1;\n\t if (a[mid] < x) lo = mid + 1;\n\t else hi = mid;\n\t }\n\t return lo;\n\t}\n\t\n\tfunction feature(topology, o) {\n\t return o.type === \"GeometryCollection\" ? {\n\t type: \"FeatureCollection\",\n\t features: o.geometries.map(function(o) { return feature$1(topology, o); })\n\t } : feature$1(topology, o);\n\t}\n\t\n\tfunction feature$1(topology, o) {\n\t var f = {\n\t type: \"Feature\",\n\t id: o.id,\n\t properties: o.properties || {},\n\t geometry: object(topology, o)\n\t };\n\t if (o.id == null) delete f.id;\n\t return f;\n\t}\n\t\n\tfunction object(topology, o) {\n\t var absolute = transformAbsolute(topology.transform),\n\t arcs = topology.arcs;\n\t\n\t function arc(i, points) {\n\t if (points.length) points.pop();\n\t for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {\n\t points.push(p = a[k].slice());\n\t absolute(p, k);\n\t }\n\t if (i < 0) reverse(points, n);\n\t }\n\t\n\t function point(p) {\n\t p = p.slice();\n\t absolute(p, 0);\n\t return p;\n\t }\n\t\n\t function line(arcs) {\n\t var points = [];\n\t for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n\t if (points.length < 2) points.push(points[0].slice());\n\t return points;\n\t }\n\t\n\t function ring(arcs) {\n\t var points = line(arcs);\n\t while (points.length < 4) points.push(points[0].slice());\n\t return points;\n\t }\n\t\n\t function polygon(arcs) {\n\t return arcs.map(ring);\n\t }\n\t\n\t function geometry(o) {\n\t var t = o.type;\n\t return t === \"GeometryCollection\" ? {type: t, geometries: o.geometries.map(geometry)}\n\t : t in geometryType ? {type: t, coordinates: geometryType[t](o)}\n\t : null;\n\t }\n\t\n\t var geometryType = {\n\t Point: function(o) { return point(o.coordinates); },\n\t MultiPoint: function(o) { return o.coordinates.map(point); },\n\t LineString: function(o) { return line(o.arcs); },\n\t MultiLineString: function(o) { return o.arcs.map(line); },\n\t Polygon: function(o) { return polygon(o.arcs); },\n\t MultiPolygon: function(o) { return o.arcs.map(polygon); }\n\t };\n\t\n\t return geometry(o);\n\t}\n\t\n\tfunction stitchArcs(topology, arcs) {\n\t var stitchedArcs = {},\n\t fragmentByStart = {},\n\t fragmentByEnd = {},\n\t fragments = [],\n\t emptyIndex = -1;\n\t\n\t // Stitch empty arcs first, since they may be subsumed by other arcs.\n\t arcs.forEach(function(i, j) {\n\t var arc = topology.arcs[i < 0 ? ~i : i], t;\n\t if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n\t t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n\t }\n\t });\n\t\n\t arcs.forEach(function(i) {\n\t var e = ends(i),\n\t start = e[0],\n\t end = e[1],\n\t f, g;\n\t\n\t if (f = fragmentByEnd[start]) {\n\t delete fragmentByEnd[f.end];\n\t f.push(i);\n\t f.end = end;\n\t if (g = fragmentByStart[end]) {\n\t delete fragmentByStart[g.start];\n\t var fg = g === f ? f : f.concat(g);\n\t fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n\t } else {\n\t fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n\t }\n\t } else if (f = fragmentByStart[end]) {\n\t delete fragmentByStart[f.start];\n\t f.unshift(i);\n\t f.start = start;\n\t if (g = fragmentByEnd[start]) {\n\t delete fragmentByEnd[g.end];\n\t var gf = g === f ? f : g.concat(f);\n\t fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n\t } else {\n\t fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n\t }\n\t } else {\n\t f = [i];\n\t fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n\t }\n\t });\n\t\n\t function ends(i) {\n\t var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n\t if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n\t else p1 = arc[arc.length - 1];\n\t return i < 0 ? [p1, p0] : [p0, p1];\n\t }\n\t\n\t function flush(fragmentByEnd, fragmentByStart) {\n\t for (var k in fragmentByEnd) {\n\t var f = fragmentByEnd[k];\n\t delete fragmentByStart[f.start];\n\t delete f.start;\n\t delete f.end;\n\t f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n\t fragments.push(f);\n\t }\n\t }\n\t\n\t flush(fragmentByEnd, fragmentByStart);\n\t flush(fragmentByStart, fragmentByEnd);\n\t arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\t\n\t return fragments;\n\t}\n\t\n\tfunction mesh(topology) {\n\t return object(topology, meshArcs.apply(this, arguments));\n\t}\n\t\n\tfunction meshArcs(topology, o, filter) {\n\t var arcs = [];\n\t\n\t function arc(i) {\n\t var j = i < 0 ? ~i : i;\n\t (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n\t }\n\t\n\t function line(arcs) {\n\t arcs.forEach(arc);\n\t }\n\t\n\t function polygon(arcs) {\n\t arcs.forEach(line);\n\t }\n\t\n\t function geometry(o) {\n\t if (o.type === \"GeometryCollection\") o.geometries.forEach(geometry);\n\t else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);\n\t }\n\t\n\t if (arguments.length > 1) {\n\t var geomsByArc = [],\n\t geom;\n\t\n\t var geometryType = {\n\t LineString: line,\n\t MultiLineString: polygon,\n\t Polygon: polygon,\n\t MultiPolygon: function(arcs) { arcs.forEach(polygon); }\n\t };\n\t\n\t geometry(o);\n\t\n\t geomsByArc.forEach(arguments.length < 3\n\t ? function(geoms) { arcs.push(geoms[0].i); }\n\t : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n\t } else {\n\t for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);\n\t }\n\t\n\t return {type: \"MultiLineString\", arcs: stitchArcs(topology, arcs)};\n\t}\n\t\n\tfunction cartesianTriangleArea(triangle) {\n\t var a = triangle[0], b = triangle[1], c = triangle[2];\n\t return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));\n\t}\n\t\n\tfunction ring(ring) {\n\t var i = -1,\n\t n = ring.length,\n\t a,\n\t b = ring[n - 1],\n\t area = 0;\n\t\n\t while (++i < n) {\n\t a = b;\n\t b = ring[i];\n\t area += a[0] * b[1] - a[1] * b[0];\n\t }\n\t\n\t return area / 2;\n\t}\n\t\n\tfunction merge(topology) {\n\t return object(topology, mergeArcs.apply(this, arguments));\n\t}\n\t\n\tfunction mergeArcs(topology, objects) {\n\t var polygonsByArc = {},\n\t polygons = [],\n\t components = [];\n\t\n\t objects.forEach(function(o) {\n\t if (o.type === \"Polygon\") register(o.arcs);\n\t else if (o.type === \"MultiPolygon\") o.arcs.forEach(register);\n\t });\n\t\n\t function register(polygon) {\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n\t });\n\t });\n\t polygons.push(polygon);\n\t }\n\t\n\t function area(ring$$) {\n\t return Math.abs(ring(object(topology, {type: \"Polygon\", arcs: [ring$$]}).coordinates[0]));\n\t }\n\t\n\t polygons.forEach(function(polygon) {\n\t if (!polygon._) {\n\t var component = [],\n\t neighbors = [polygon];\n\t polygon._ = 1;\n\t components.push(component);\n\t while (polygon = neighbors.pop()) {\n\t component.push(polygon);\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n\t if (!polygon._) {\n\t polygon._ = 1;\n\t neighbors.push(polygon);\n\t }\n\t });\n\t });\n\t });\n\t }\n\t }\n\t });\n\t\n\t polygons.forEach(function(polygon) {\n\t delete polygon._;\n\t });\n\t\n\t return {\n\t type: \"MultiPolygon\",\n\t arcs: components.map(function(polygons) {\n\t var arcs = [], n;\n\t\n\t // Extract the exterior (unique) arcs.\n\t polygons.forEach(function(polygon) {\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n\t arcs.push(arc);\n\t }\n\t });\n\t });\n\t });\n\t\n\t // Stitch the arcs into one or more rings.\n\t arcs = stitchArcs(topology, arcs);\n\t\n\t // If more than one ring is returned,\n\t // at most one of these rings can be the exterior;\n\t // choose the one with the greatest absolute area.\n\t if ((n = arcs.length) > 1) {\n\t for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n\t if ((ki = area(arcs[i])) > k) {\n\t t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n\t }\n\t }\n\t }\n\t\n\t return arcs;\n\t })\n\t };\n\t}\n\t\n\tfunction neighbors(objects) {\n\t var indexesByArc = {}, // arc index -> array of object indexes\n\t neighbors = objects.map(function() { return []; });\n\t\n\t function line(arcs, i) {\n\t arcs.forEach(function(a) {\n\t if (a < 0) a = ~a;\n\t var o = indexesByArc[a];\n\t if (o) o.push(i);\n\t else indexesByArc[a] = [i];\n\t });\n\t }\n\t\n\t function polygon(arcs, i) {\n\t arcs.forEach(function(arc) { line(arc, i); });\n\t }\n\t\n\t function geometry(o, i) {\n\t if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n\t else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n\t }\n\t\n\t var geometryType = {\n\t LineString: line,\n\t MultiLineString: polygon,\n\t Polygon: polygon,\n\t MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n\t };\n\t\n\t objects.forEach(geometry);\n\t\n\t for (var i in indexesByArc) {\n\t for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n\t for (var k = j + 1; k < m; ++k) {\n\t var ij = indexes[j], ik = indexes[k], n;\n\t if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);\n\t if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);\n\t }\n\t }\n\t }\n\t\n\t return neighbors;\n\t}\n\t\n\tfunction compareArea(a, b) {\n\t return a[1][2] - b[1][2];\n\t}\n\t\n\tfunction minAreaHeap() {\n\t var heap = {},\n\t array = [],\n\t size = 0;\n\t\n\t heap.push = function(object) {\n\t up(array[object._ = size] = object, size++);\n\t return size;\n\t };\n\t\n\t heap.pop = function() {\n\t if (size <= 0) return;\n\t var removed = array[0], object;\n\t if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);\n\t return removed;\n\t };\n\t\n\t heap.remove = function(removed) {\n\t var i = removed._, object;\n\t if (array[i] !== removed) return; // invalid request\n\t if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);\n\t return i;\n\t };\n\t\n\t function up(object, i) {\n\t while (i > 0) {\n\t var j = ((i + 1) >> 1) - 1,\n\t parent = array[j];\n\t if (compareArea(object, parent) >= 0) break;\n\t array[parent._ = i] = parent;\n\t array[object._ = i = j] = object;\n\t }\n\t }\n\t\n\t function down(object, i) {\n\t while (true) {\n\t var r = (i + 1) << 1,\n\t l = r - 1,\n\t j = i,\n\t child = array[j];\n\t if (l < size && compareArea(array[l], child) < 0) child = array[j = l];\n\t if (r < size && compareArea(array[r], child) < 0) child = array[j = r];\n\t if (j === i) break;\n\t array[child._ = i] = child;\n\t array[object._ = i = j] = object;\n\t }\n\t }\n\t\n\t return heap;\n\t}\n\t\n\tfunction presimplify(topology, triangleArea) {\n\t var absolute = transformAbsolute(topology.transform),\n\t relative = transformRelative(topology.transform),\n\t heap = minAreaHeap();\n\t\n\t if (!triangleArea) triangleArea = cartesianTriangleArea;\n\t\n\t topology.arcs.forEach(function(arc) {\n\t var triangles = [],\n\t maxArea = 0,\n\t triangle,\n\t i,\n\t n,\n\t p;\n\t\n\t // To store each point’s effective area, we create a new array rather than\n\t // extending the passed-in point to workaround a Chrome/V8 bug (getting\n\t // stuck in smi mode). For midpoints, the initial effective area of\n\t // Infinity will be computed in the next step.\n\t for (i = 0, n = arc.length; i < n; ++i) {\n\t p = arc[i];\n\t absolute(arc[i] = [p[0], p[1], Infinity], i);\n\t }\n\t\n\t for (i = 1, n = arc.length - 1; i < n; ++i) {\n\t triangle = arc.slice(i - 1, i + 2);\n\t triangle[1][2] = triangleArea(triangle);\n\t triangles.push(triangle);\n\t heap.push(triangle);\n\t }\n\t\n\t for (i = 0, n = triangles.length; i < n; ++i) {\n\t triangle = triangles[i];\n\t triangle.previous = triangles[i - 1];\n\t triangle.next = triangles[i + 1];\n\t }\n\t\n\t while (triangle = heap.pop()) {\n\t var previous = triangle.previous,\n\t next = triangle.next;\n\t\n\t // If the area of the current point is less than that of the previous point\n\t // to be eliminated, use the latter's area instead. This ensures that the\n\t // current point cannot be eliminated without eliminating previously-\n\t // eliminated points.\n\t if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;\n\t else maxArea = triangle[1][2];\n\t\n\t if (previous) {\n\t previous.next = next;\n\t previous[2] = triangle[2];\n\t update(previous);\n\t }\n\t\n\t if (next) {\n\t next.previous = previous;\n\t next[0] = triangle[0];\n\t update(next);\n\t }\n\t }\n\t\n\t arc.forEach(relative);\n\t });\n\t\n\t function update(triangle) {\n\t heap.remove(triangle);\n\t triangle[1][2] = triangleArea(triangle);\n\t heap.push(triangle);\n\t }\n\t\n\t return topology;\n\t}\n\t\n\tvar version = \"1.6.27\";\n\t\n\texports.version = version;\n\texports.mesh = mesh;\n\texports.meshArcs = meshArcs;\n\texports.merge = merge;\n\texports.mergeArcs = mergeArcs;\n\texports.feature = feature;\n\texports.neighbors = neighbors;\n\texports.presimplify = presimplify;\n\t\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\t\n\t})));\n\n/***/ },\n/* 27 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar normalize = __webpack_require__(28);\n\t\n\tmodule.exports = function(inputs) {\n\t return {\n\t type: 'FeatureCollection',\n\t features: inputs.reduce(function(memo, input) {\n\t return memo.concat(normalize(input).features);\n\t }, [])\n\t };\n\t};\n\n\n/***/ },\n/* 28 */\n/***/ function(module, exports) {\n\n\tmodule.exports = normalize;\n\t\n\tvar types = {\n\t Point: 'geometry',\n\t MultiPoint: 'geometry',\n\t LineString: 'geometry',\n\t MultiLineString: 'geometry',\n\t Polygon: 'geometry',\n\t MultiPolygon: 'geometry',\n\t GeometryCollection: 'geometry',\n\t Feature: 'feature',\n\t FeatureCollection: 'featurecollection'\n\t};\n\t\n\t/**\n\t * Normalize a GeoJSON feature into a FeatureCollection.\n\t *\n\t * @param {object} gj geojson data\n\t * @returns {object} normalized geojson data\n\t */\n\tfunction normalize(gj) {\n\t if (!gj || !gj.type) return null;\n\t var type = types[gj.type];\n\t if (!type) return null;\n\t\n\t if (type === 'geometry') {\n\t return {\n\t type: 'FeatureCollection',\n\t features: [{\n\t type: 'Feature',\n\t properties: {},\n\t geometry: gj\n\t }]\n\t };\n\t } else if (type === 'feature') {\n\t return {\n\t type: 'FeatureCollection',\n\t features: [gj]\n\t };\n\t } else if (type === 'featurecollection') {\n\t return gj;\n\t }\n\t}\n\n\n/***/ },\n/* 29 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = earcut;\n\t\n\tfunction earcut(data, holeIndices, dim) {\n\t\n\t dim = dim || 2;\n\t\n\t var hasHoles = holeIndices && holeIndices.length,\n\t outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n\t outerNode = linkedList(data, 0, outerLen, dim, true),\n\t triangles = [];\n\t\n\t if (!outerNode) return triangles;\n\t\n\t var minX, minY, maxX, maxY, x, y, size;\n\t\n\t if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\t\n\t // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n\t if (data.length > 80 * dim) {\n\t minX = maxX = data[0];\n\t minY = maxY = data[1];\n\t\n\t for (var i = dim; i < outerLen; i += dim) {\n\t x = data[i];\n\t y = data[i + 1];\n\t if (x < minX) minX = x;\n\t if (y < minY) minY = y;\n\t if (x > maxX) maxX = x;\n\t if (y > maxY) maxY = y;\n\t }\n\t\n\t // minX, minY and size are later used to transform coords into integers for z-order calculation\n\t size = Math.max(maxX - minX, maxY - minY);\n\t }\n\t\n\t earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\t\n\t return triangles;\n\t}\n\t\n\t// create a circular doubly linked list from polygon points in the specified winding order\n\tfunction linkedList(data, start, end, dim, clockwise) {\n\t var i, last;\n\t\n\t if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n\t for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n\t } else {\n\t for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n\t }\n\t\n\t if (last && equals(last, last.next)) {\n\t removeNode(last);\n\t last = last.next;\n\t }\n\t\n\t return last;\n\t}\n\t\n\t// eliminate colinear or duplicate points\n\tfunction filterPoints(start, end) {\n\t if (!start) return start;\n\t if (!end) end = start;\n\t\n\t var p = start,\n\t again;\n\t do {\n\t again = false;\n\t\n\t if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n\t removeNode(p);\n\t p = end = p.prev;\n\t if (p === p.next) return null;\n\t again = true;\n\t\n\t } else {\n\t p = p.next;\n\t }\n\t } while (again || p !== end);\n\t\n\t return end;\n\t}\n\t\n\t// main ear slicing loop which triangulates a polygon (given as a linked list)\n\tfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n\t if (!ear) return;\n\t\n\t // interlink polygon nodes in z-order\n\t if (!pass && size) indexCurve(ear, minX, minY, size);\n\t\n\t var stop = ear,\n\t prev, next;\n\t\n\t // iterate through ears, slicing them one by one\n\t while (ear.prev !== ear.next) {\n\t prev = ear.prev;\n\t next = ear.next;\n\t\n\t if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n\t // cut off the triangle\n\t triangles.push(prev.i / dim);\n\t triangles.push(ear.i / dim);\n\t triangles.push(next.i / dim);\n\t\n\t removeNode(ear);\n\t\n\t // skipping the next vertice leads to less sliver triangles\n\t ear = next.next;\n\t stop = next.next;\n\t\n\t continue;\n\t }\n\t\n\t ear = next;\n\t\n\t // if we looped through the whole remaining polygon and can't find any more ears\n\t if (ear === stop) {\n\t // try filtering points and slicing again\n\t if (!pass) {\n\t earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\t\n\t // if this didn't work, try curing all small self-intersections locally\n\t } else if (pass === 1) {\n\t ear = cureLocalIntersections(ear, triangles, dim);\n\t earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\t\n\t // as a last resort, try splitting the remaining polygon into two\n\t } else if (pass === 2) {\n\t splitEarcut(ear, triangles, dim, minX, minY, size);\n\t }\n\t\n\t break;\n\t }\n\t }\n\t}\n\t\n\t// check whether a polygon node forms a valid ear with adjacent nodes\n\tfunction isEar(ear) {\n\t var a = ear.prev,\n\t b = ear,\n\t c = ear.next;\n\t\n\t if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\t\n\t // now make sure we don't have other points inside the potential ear\n\t var p = ear.next.next;\n\t\n\t while (p !== ear.prev) {\n\t if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.next;\n\t }\n\t\n\t return true;\n\t}\n\t\n\tfunction isEarHashed(ear, minX, minY, size) {\n\t var a = ear.prev,\n\t b = ear,\n\t c = ear.next;\n\t\n\t if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\t\n\t // triangle bbox; min & max are calculated like this for speed\n\t var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n\t minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n\t maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n\t maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\t\n\t // z-order range for the current triangle bbox;\n\t var minZ = zOrder(minTX, minTY, minX, minY, size),\n\t maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\t\n\t // first look for points inside the triangle in increasing z-order\n\t var p = ear.nextZ;\n\t\n\t while (p && p.z <= maxZ) {\n\t if (p !== ear.prev && p !== ear.next &&\n\t pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.nextZ;\n\t }\n\t\n\t // then look for points in decreasing z-order\n\t p = ear.prevZ;\n\t\n\t while (p && p.z >= minZ) {\n\t if (p !== ear.prev && p !== ear.next &&\n\t pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.prevZ;\n\t }\n\t\n\t return true;\n\t}\n\t\n\t// go through all polygon nodes and cure small local self-intersections\n\tfunction cureLocalIntersections(start, triangles, dim) {\n\t var p = start;\n\t do {\n\t var a = p.prev,\n\t b = p.next.next;\n\t\n\t if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\t\n\t triangles.push(a.i / dim);\n\t triangles.push(p.i / dim);\n\t triangles.push(b.i / dim);\n\t\n\t // remove two nodes involved\n\t removeNode(p);\n\t removeNode(p.next);\n\t\n\t p = start = b;\n\t }\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t return p;\n\t}\n\t\n\t// try splitting polygon into two and triangulate them independently\n\tfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n\t // look for a valid diagonal that divides the polygon into two\n\t var a = start;\n\t do {\n\t var b = a.next.next;\n\t while (b !== a.prev) {\n\t if (a.i !== b.i && isValidDiagonal(a, b)) {\n\t // split the polygon in two by the diagonal\n\t var c = splitPolygon(a, b);\n\t\n\t // filter colinear points around the cuts\n\t a = filterPoints(a, a.next);\n\t c = filterPoints(c, c.next);\n\t\n\t // run earcut on each half\n\t earcutLinked(a, triangles, dim, minX, minY, size);\n\t earcutLinked(c, triangles, dim, minX, minY, size);\n\t return;\n\t }\n\t b = b.next;\n\t }\n\t a = a.next;\n\t } while (a !== start);\n\t}\n\t\n\t// link every hole into the outer loop, producing a single-ring polygon without holes\n\tfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n\t var queue = [],\n\t i, len, start, end, list;\n\t\n\t for (i = 0, len = holeIndices.length; i < len; i++) {\n\t start = holeIndices[i] * dim;\n\t end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n\t list = linkedList(data, start, end, dim, false);\n\t if (list === list.next) list.steiner = true;\n\t queue.push(getLeftmost(list));\n\t }\n\t\n\t queue.sort(compareX);\n\t\n\t // process holes from left to right\n\t for (i = 0; i < queue.length; i++) {\n\t eliminateHole(queue[i], outerNode);\n\t outerNode = filterPoints(outerNode, outerNode.next);\n\t }\n\t\n\t return outerNode;\n\t}\n\t\n\tfunction compareX(a, b) {\n\t return a.x - b.x;\n\t}\n\t\n\t// find a bridge between vertices that connects hole with an outer ring and and link it\n\tfunction eliminateHole(hole, outerNode) {\n\t outerNode = findHoleBridge(hole, outerNode);\n\t if (outerNode) {\n\t var b = splitPolygon(outerNode, hole);\n\t filterPoints(b, b.next);\n\t }\n\t}\n\t\n\t// David Eberly's algorithm for finding a bridge between hole and outer polygon\n\tfunction findHoleBridge(hole, outerNode) {\n\t var p = outerNode,\n\t hx = hole.x,\n\t hy = hole.y,\n\t qx = -Infinity,\n\t m;\n\t\n\t // find a segment intersected by a ray from the hole's leftmost point to the left;\n\t // segment's endpoint with lesser x will be potential connection point\n\t do {\n\t if (hy <= p.y && hy >= p.next.y) {\n\t var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n\t if (x <= hx && x > qx) {\n\t qx = x;\n\t if (x === hx) {\n\t if (hy === p.y) return p;\n\t if (hy === p.next.y) return p.next;\n\t }\n\t m = p.x < p.next.x ? p : p.next;\n\t }\n\t }\n\t p = p.next;\n\t } while (p !== outerNode);\n\t\n\t if (!m) return null;\n\t\n\t if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint\n\t\n\t // look for points inside the triangle of hole point, segment intersection and endpoint;\n\t // if there are no points found, we have a valid connection;\n\t // otherwise choose the point of the minimum angle with the ray as connection point\n\t\n\t var stop = m,\n\t mx = m.x,\n\t my = m.y,\n\t tanMin = Infinity,\n\t tan;\n\t\n\t p = m.next;\n\t\n\t while (p !== stop) {\n\t if (hx >= p.x && p.x >= mx &&\n\t pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\t\n\t tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\t\n\t if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n\t m = p;\n\t tanMin = tan;\n\t }\n\t }\n\t\n\t p = p.next;\n\t }\n\t\n\t return m;\n\t}\n\t\n\t// interlink polygon nodes in z-order\n\tfunction indexCurve(start, minX, minY, size) {\n\t var p = start;\n\t do {\n\t if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n\t p.prevZ = p.prev;\n\t p.nextZ = p.next;\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t p.prevZ.nextZ = null;\n\t p.prevZ = null;\n\t\n\t sortLinked(p);\n\t}\n\t\n\t// Simon Tatham's linked list merge sort algorithm\n\t// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\n\tfunction sortLinked(list) {\n\t var i, p, q, e, tail, numMerges, pSize, qSize,\n\t inSize = 1;\n\t\n\t do {\n\t p = list;\n\t list = null;\n\t tail = null;\n\t numMerges = 0;\n\t\n\t while (p) {\n\t numMerges++;\n\t q = p;\n\t pSize = 0;\n\t for (i = 0; i < inSize; i++) {\n\t pSize++;\n\t q = q.nextZ;\n\t if (!q) break;\n\t }\n\t\n\t qSize = inSize;\n\t\n\t while (pSize > 0 || (qSize > 0 && q)) {\n\t\n\t if (pSize === 0) {\n\t e = q;\n\t q = q.nextZ;\n\t qSize--;\n\t } else if (qSize === 0 || !q) {\n\t e = p;\n\t p = p.nextZ;\n\t pSize--;\n\t } else if (p.z <= q.z) {\n\t e = p;\n\t p = p.nextZ;\n\t pSize--;\n\t } else {\n\t e = q;\n\t q = q.nextZ;\n\t qSize--;\n\t }\n\t\n\t if (tail) tail.nextZ = e;\n\t else list = e;\n\t\n\t e.prevZ = tail;\n\t tail = e;\n\t }\n\t\n\t p = q;\n\t }\n\t\n\t tail.nextZ = null;\n\t inSize *= 2;\n\t\n\t } while (numMerges > 1);\n\t\n\t return list;\n\t}\n\t\n\t// z-order of a point given coords and size of the data bounding box\n\tfunction zOrder(x, y, minX, minY, size) {\n\t // coords are transformed into non-negative 15-bit integer range\n\t x = 32767 * (x - minX) / size;\n\t y = 32767 * (y - minY) / size;\n\t\n\t x = (x | (x << 8)) & 0x00FF00FF;\n\t x = (x | (x << 4)) & 0x0F0F0F0F;\n\t x = (x | (x << 2)) & 0x33333333;\n\t x = (x | (x << 1)) & 0x55555555;\n\t\n\t y = (y | (y << 8)) & 0x00FF00FF;\n\t y = (y | (y << 4)) & 0x0F0F0F0F;\n\t y = (y | (y << 2)) & 0x33333333;\n\t y = (y | (y << 1)) & 0x55555555;\n\t\n\t return x | (y << 1);\n\t}\n\t\n\t// find the leftmost node of a polygon ring\n\tfunction getLeftmost(start) {\n\t var p = start,\n\t leftmost = start;\n\t do {\n\t if (p.x < leftmost.x) leftmost = p;\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t return leftmost;\n\t}\n\t\n\t// check if a point lies within a convex triangle\n\tfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n\t return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n\t (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n\t (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n\t}\n\t\n\t// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\n\tfunction isValidDiagonal(a, b) {\n\t return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n\t locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n\t}\n\t\n\t// signed area of a triangle\n\tfunction area(p, q, r) {\n\t return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n\t}\n\t\n\t// check if two points are equal\n\tfunction equals(p1, p2) {\n\t return p1.x === p2.x && p1.y === p2.y;\n\t}\n\t\n\t// check if two segments intersect\n\tfunction intersects(p1, q1, p2, q2) {\n\t if ((equals(p1, q1) && equals(p2, q2)) ||\n\t (equals(p1, q2) && equals(p2, q1))) return true;\n\t return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n\t area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n\t}\n\t\n\t// check if a polygon diagonal intersects any polygon segments\n\tfunction intersectsPolygon(a, b) {\n\t var p = a;\n\t do {\n\t if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n\t intersects(p, p.next, a, b)) return true;\n\t p = p.next;\n\t } while (p !== a);\n\t\n\t return false;\n\t}\n\t\n\t// check if a polygon diagonal is locally inside the polygon\n\tfunction locallyInside(a, b) {\n\t return area(a.prev, a, a.next) < 0 ?\n\t area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n\t area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n\t}\n\t\n\t// check if the middle point of a polygon diagonal is inside the polygon\n\tfunction middleInside(a, b) {\n\t var p = a,\n\t inside = false,\n\t px = (a.x + b.x) / 2,\n\t py = (a.y + b.y) / 2;\n\t do {\n\t if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n\t inside = !inside;\n\t p = p.next;\n\t } while (p !== a);\n\t\n\t return inside;\n\t}\n\t\n\t// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n\t// if one belongs to the outer ring and another to a hole, it merges it into a single ring\n\tfunction splitPolygon(a, b) {\n\t var a2 = new Node(a.i, a.x, a.y),\n\t b2 = new Node(b.i, b.x, b.y),\n\t an = a.next,\n\t bp = b.prev;\n\t\n\t a.next = b;\n\t b.prev = a;\n\t\n\t a2.next = an;\n\t an.prev = a2;\n\t\n\t b2.next = a2;\n\t a2.prev = b2;\n\t\n\t bp.next = b2;\n\t b2.prev = bp;\n\t\n\t return b2;\n\t}\n\t\n\t// create a node and optionally link it with previous one (in a circular doubly linked list)\n\tfunction insertNode(i, x, y, last) {\n\t var p = new Node(i, x, y);\n\t\n\t if (!last) {\n\t p.prev = p;\n\t p.next = p;\n\t\n\t } else {\n\t p.next = last.next;\n\t p.prev = last;\n\t last.next.prev = p;\n\t last.next = p;\n\t }\n\t return p;\n\t}\n\t\n\tfunction removeNode(p) {\n\t p.next.prev = p.prev;\n\t p.prev.next = p.next;\n\t\n\t if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n\t if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n\t}\n\t\n\tfunction Node(i, x, y) {\n\t // vertice index in coordinates array\n\t this.i = i;\n\t\n\t // vertex coordinates\n\t this.x = x;\n\t this.y = y;\n\t\n\t // previous and next vertice nodes in a polygon ring\n\t this.prev = null;\n\t this.next = null;\n\t\n\t // z-order curve value\n\t this.z = null;\n\t\n\t // previous and next nodes in z-order\n\t this.prevZ = null;\n\t this.nextZ = null;\n\t\n\t // indicates whether this is a steiner point\n\t this.steiner = false;\n\t}\n\t\n\t// return a percentage difference between the polygon area and its triangulation area;\n\t// used to verify correctness of triangulation\n\tearcut.deviation = function (data, holeIndices, dim, triangles) {\n\t var hasHoles = holeIndices && holeIndices.length;\n\t var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\t\n\t var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n\t if (hasHoles) {\n\t for (var i = 0, len = holeIndices.length; i < len; i++) {\n\t var start = holeIndices[i] * dim;\n\t var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n\t polygonArea -= Math.abs(signedArea(data, start, end, dim));\n\t }\n\t }\n\t\n\t var trianglesArea = 0;\n\t for (i = 0; i < triangles.length; i += 3) {\n\t var a = triangles[i] * dim;\n\t var b = triangles[i + 1] * dim;\n\t var c = triangles[i + 2] * dim;\n\t trianglesArea += Math.abs(\n\t (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n\t (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n\t }\n\t\n\t return polygonArea === 0 && trianglesArea === 0 ? 0 :\n\t Math.abs((trianglesArea - polygonArea) / polygonArea);\n\t};\n\t\n\tfunction signedArea(data, start, end, dim) {\n\t var sum = 0;\n\t for (var i = start, j = end - dim; i < end; i += dim) {\n\t sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n\t j = i;\n\t }\n\t return sum;\n\t}\n\t\n\t// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\n\tearcut.flatten = function (data) {\n\t var dim = data[0][0].length,\n\t result = {vertices: [], holes: [], dimensions: dim},\n\t holeIndex = 0;\n\t\n\t for (var i = 0; i < data.length; i++) {\n\t for (var j = 0; j < data[i].length; j++) {\n\t for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n\t }\n\t if (i > 0) {\n\t holeIndex += data[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t return result;\n\t};\n\n\n/***/ },\n/* 30 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * Extrude a polygon given its vertices and triangulated faces\n\t *\n\t * Based on:\n\t * https://github.com/freeman-lab/extrude\n\t */\n\t\n\tvar _lodashAssign = __webpack_require__(6);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar extrudePolygon = function extrudePolygon(points, faces, _options) {\n\t var defaults = {\n\t top: 1,\n\t bottom: 0,\n\t closed: true\n\t };\n\t\n\t var options = (0, _lodashAssign2['default'])({}, defaults, _options);\n\t\n\t var n = points.length;\n\t var positions;\n\t var cells;\n\t var topCells;\n\t var bottomCells;\n\t var sideCells;\n\t\n\t // If bottom and top values are identical then return the flat shape\n\t options.top === options.bottom ? flat() : full();\n\t\n\t function flat() {\n\t positions = points.map(function (p) {\n\t return [p[0], options.top, p[1]];\n\t });\n\t cells = faces;\n\t topCells = faces;\n\t }\n\t\n\t function full() {\n\t positions = [];\n\t points.forEach(function (p) {\n\t positions.push([p[0], options.top, p[1]]);\n\t });\n\t points.forEach(function (p) {\n\t positions.push([p[0], options.bottom, p[1]]);\n\t });\n\t\n\t cells = [];\n\t for (var i = 0; i < n; i++) {\n\t if (i === n - 1) {\n\t cells.push([i + n, n, i]);\n\t cells.push([0, i, n]);\n\t } else {\n\t cells.push([i + n, i + n + 1, i]);\n\t cells.push([i + 1, i, i + n + 1]);\n\t }\n\t }\n\t\n\t sideCells = [].concat(cells);\n\t\n\t if (options.closed) {\n\t var top = faces;\n\t var bottom = top.map(function (p) {\n\t return p.map(function (v) {\n\t return v + n;\n\t });\n\t });\n\t bottom = bottom.map(function (p) {\n\t return [p[0], p[2], p[1]];\n\t });\n\t cells = cells.concat(top).concat(bottom);\n\t\n\t topCells = top;\n\t bottomCells = bottom;\n\t }\n\t }\n\t\n\t return {\n\t positions: positions,\n\t faces: cells,\n\t top: topCells,\n\t bottom: bottomCells,\n\t sides: sideCells\n\t };\n\t};\n\t\n\texports['default'] = extrudePolygon;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 31 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _WorkerPool = __webpack_require__(32);\n\t\n\tvar _WorkerPool2 = _interopRequireDefault(_WorkerPool);\n\t\n\tvar Worker = (function () {\n\t var _maxWorkers = 2;\n\t var pool;\n\t\n\t var createWorkers = function createWorkers(maxWorkers, workerScript) {\n\t pool = new _WorkerPool2['default']({\n\t numThreads: maxWorkers ? maxWorkers : _maxWorkers,\n\t workerScript: workerScript ? workerScript : 'vizicities-worker.js'\n\t });\n\t\n\t return pool.createWorkers();\n\t };\n\t\n\t var exec = function exec(method, args, transferrables) {\n\t return pool.exec(method, args, transferrables);\n\t };\n\t\n\t return {\n\t createWorkers: createWorkers,\n\t exec: exec\n\t };\n\t})();\n\t\n\texports['default'] = Worker;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _WorkerPoolWorker = __webpack_require__(33);\n\t\n\tvar _WorkerPoolWorker2 = _interopRequireDefault(_WorkerPoolWorker);\n\t\n\tvar DEBUG = false;\n\t\n\tvar WorkerPool = (function () {\n\t function WorkerPool(options) {\n\t _classCallCheck(this, WorkerPool);\n\t\n\t this.numThreads = options.numThreads || 2;\n\t this.workerScript = options.workerScript;\n\t\n\t this.workers = [];\n\t this.tasks = [];\n\t }\n\t\n\t _createClass(WorkerPool, [{\n\t key: 'createWorkers',\n\t value: function createWorkers() {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var workerPromises = [];\n\t\n\t for (var i = 0; i < _this.numThreads; i++) {\n\t workerPromises.push(_this.createWorker());\n\t }\n\t\n\t Promise.all(workerPromises).then(function () {\n\t if (DEBUG) {\n\t console.log('All workers ready', performance.now());\n\t }\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'createWorker',\n\t value: function createWorker() {\n\t var _this2 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t // Initialise worker\n\t var worker = new _WorkerPoolWorker2['default']({\n\t workerScript: _this2.workerScript\n\t });\n\t\n\t // Start worker and wait for it to be ready\n\t return worker.start().then(function () {\n\t if (DEBUG) {\n\t console.log('Worker ready', performance.now());\n\t }\n\t\n\t // Add worker to pool\n\t _this2.workers.push(worker);\n\t\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'getFreeWorker',\n\t value: function getFreeWorker() {\n\t return this.workers.find(function (worker) {\n\t return !worker.busy;\n\t });\n\t }\n\t\n\t // Execute task on a worker\n\t }, {\n\t key: 'exec',\n\t value: function exec(method, args, transferrables) {\n\t var deferred = Promise.deferred();\n\t\n\t // Create task\n\t var task = {\n\t method: method,\n\t args: args,\n\t transferrables: transferrables,\n\t deferred: deferred\n\t };\n\t\n\t // Add task to queue\n\t this.tasks.push(task);\n\t\n\t // Trigger task processing\n\t this.processTasks();\n\t\n\t // Return task promise\n\t return task.deferred.promise;\n\t }\n\t }, {\n\t key: 'processTasks',\n\t value: function processTasks() {\n\t var _this3 = this;\n\t\n\t if (DEBUG) {\n\t console.log('Processing tasks');\n\t }\n\t\n\t if (this.tasks.length === 0) {\n\t return;\n\t }\n\t\n\t // Find free worker\n\t var worker = this.getFreeWorker();\n\t\n\t if (!worker) {\n\t if (DEBUG) {\n\t console.log('No workers free');\n\t }\n\t return;\n\t }\n\t\n\t // Get oldest task\n\t var task = this.tasks.shift();\n\t\n\t // Execute task on worker\n\t worker.exec(task.method, task.args, task.transferrables).then(function (result) {\n\t // Trigger task processing\n\t _this3.processTasks();\n\t\n\t // Return result in deferred task promise\n\t task.deferred.resolve(result);\n\t });\n\t }\n\t }]);\n\t\n\t return WorkerPool;\n\t})();\n\t\n\texports['default'] = WorkerPool;\n\t\n\t// Quick shim to create deferred native promises\n\tPromise.deferred = function () {\n\t var result = {};\n\t\n\t result.promise = new Promise(function (resolve, reject) {\n\t result.resolve = resolve;\n\t result.reject = reject;\n\t });\n\t\n\t return result;\n\t};\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 33 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar DEBUG = false;\n\t\n\tvar WorkerPoolWorker = (function () {\n\t function WorkerPoolWorker(options) {\n\t _classCallCheck(this, WorkerPoolWorker);\n\t\n\t this.workerScript = options.workerScript;\n\t\n\t this.ready = false;\n\t this.busy = false;\n\t this.deferred = null;\n\t }\n\t\n\t _createClass(WorkerPoolWorker, [{\n\t key: 'start',\n\t value: function start() {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this.worker = new Worker(_this.workerScript);\n\t\n\t var onStartup = function onStartup(event) {\n\t if (!event.data || event.data.type !== 'startup') {\n\t reject();\n\t return;\n\t }\n\t\n\t _this.ready = true;\n\t\n\t // Remove temporary message handler\n\t _this.worker.removeEventListener('message', onStartup);\n\t\n\t // Set up listener to respond to normal events now\n\t _this.worker.addEventListener('message', function (event) {\n\t _this.onMessage(event);\n\t });\n\t\n\t // Resolve once worker is ready\n\t resolve();\n\t };\n\t\n\t // Set up temporary event listener for warmup\n\t _this.worker.addEventListener('message', onStartup);\n\t });\n\t }\n\t }, {\n\t key: 'exec',\n\t value: function exec(method, args, transferrables) {\n\t if (DEBUG) {\n\t console.log('Execute', method, args, transferrables);\n\t }\n\t\n\t var deferred = Promise.deferred();\n\t\n\t this.busy = true;\n\t this.deferred = deferred;\n\t\n\t this.worker.postMessage({\n\t method: method,\n\t args: args\n\t }, transferrables);\n\t\n\t return deferred.promise;\n\t }\n\t }, {\n\t key: 'onMessage',\n\t value: function onMessage(event) {\n\t console.log('Message received from worker', performance.now());\n\t\n\t this.busy = false;\n\t\n\t if (!event.data || event.data.type === 'error' || event.data.type !== 'result') {\n\t this.deferred.reject(event.data.payload);\n\t return;\n\t }\n\t\n\t this.deferred.resolve(event.data.payload);\n\t }\n\t }]);\n\t\n\t return WorkerPoolWorker;\n\t})();\n\t\n\texports['default'] = WorkerPoolWorker;\n\t\n\t// Quick shim to create deferred native promises\n\tPromise.deferred = function () {\n\t var result = {};\n\t\n\t result.promise = new Promise(function (resolve, reject) {\n\t result.resolve = resolve;\n\t result.reject = reject;\n\t });\n\t\n\t return result;\n\t};\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 34 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * BufferGeometry helpers\n\t */\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar Buffer = (function () {\n\t // Merge TypedArrays of the same type\n\t // Returns merged array as well as indexes for splitting the array\n\t var mergeFloat32Arrays = function mergeFloat32Arrays(arrays) {\n\t var size = 0;\n\t var map = new Int32Array(arrays.length * 2);\n\t\n\t var lastIndex = 0;\n\t var length;\n\t\n\t // Find size of each array\n\t arrays.forEach(function (_array, index) {\n\t length = _array.length;\n\t size += length;\n\t map.set([lastIndex, lastIndex + length], index * 2);\n\t lastIndex += length;\n\t });\n\t\n\t // Create a new array of total size\n\t var mergedArray = new Float32Array(size);\n\t\n\t // Add each array to the new array\n\t arrays.forEach(function (_array, index) {\n\t mergedArray.set(_array, map[index * 2]);\n\t });\n\t\n\t return [mergedArray, map];\n\t };\n\t\n\t var splitFloat32Array = function splitFloat32Array(data) {\n\t var arr = data[0];\n\t var map = data[1];\n\t\n\t var start;\n\t var arrays = [];\n\t\n\t // Iterate over map\n\t for (var i = 0; i < map.length / 2; i++) {\n\t start = i * 2;\n\t arrays.push(arr.subarray(map[start], map[start + 1]));\n\t }\n\t\n\t return arrays;\n\t };\n\t\n\t // TODO: Create a generic method that can work for any typed array\n\t var mergeUint8Arrays = function mergeUint8Arrays(arrays) {\n\t var size = 0;\n\t var map = new Int32Array(arrays.length * 2);\n\t\n\t var lastIndex = 0;\n\t var length;\n\t\n\t // Find size of each array\n\t arrays.forEach(function (_array, index) {\n\t length = _array.length;\n\t size += length;\n\t map.set([lastIndex, lastIndex + length], index * 2);\n\t lastIndex += length;\n\t });\n\t\n\t // Create a new array of total size\n\t var mergedArray = new Uint8Array(size);\n\t\n\t // Add each array to the new array\n\t arrays.forEach(function (_array, index) {\n\t mergedArray.set(_array, map[index * 2]);\n\t });\n\t\n\t return [mergedArray, map];\n\t };\n\t\n\t // TODO: Dedupe with splitFloat32Array\n\t var splitUint8Array = function splitUint8Array(data) {\n\t var arr = data[0];\n\t var map = data[1];\n\t\n\t var start;\n\t var arrays = [];\n\t\n\t // Iterate over map\n\t for (var i = 0; i < map.length / 2; i++) {\n\t start = i * 2;\n\t arrays.push(arr.subarray(map[start], map[start + 1]));\n\t }\n\t\n\t return arrays;\n\t };\n\t\n\t // Merge multiple attribute objects into a single attribute object\n\t //\n\t // Attribute objects must all use the same attribute keys\n\t var mergeAttributes = function mergeAttributes(attributes) {\n\t var lengths = {};\n\t\n\t // Find array lengths\n\t attributes.forEach(function (_attributes) {\n\t for (var k in _attributes) {\n\t if (!lengths[k]) {\n\t lengths[k] = 0;\n\t }\n\t\n\t lengths[k] += _attributes[k].length;\n\t }\n\t });\n\t\n\t var mergedAttributes = {};\n\t\n\t // Set up arrays to merge into\n\t for (var k in lengths) {\n\t mergedAttributes[k] = new Float32Array(lengths[k]);\n\t }\n\t\n\t var lastLengths = {};\n\t\n\t attributes.forEach(function (_attributes) {\n\t for (var k in _attributes) {\n\t if (!lastLengths[k]) {\n\t lastLengths[k] = 0;\n\t }\n\t\n\t mergedAttributes[k].set(_attributes[k], lastLengths[k]);\n\t\n\t lastLengths[k] += _attributes[k].length;\n\t }\n\t });\n\t\n\t return mergedAttributes;\n\t };\n\t\n\t var createLineGeometry = function createLineGeometry(lines, offset) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t var vertices = new Float32Array(lines.verticesCount * 3);\n\t var colours = new Float32Array(lines.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (lines.pickingIds) {\n\t // One component per vertex (1)\n\t pickingIds = new Float32Array(lines.verticesCount);\n\t }\n\t\n\t var _vertices;\n\t var _colour;\n\t var _pickingId;\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < lines.vertices.length; i++) {\n\t _vertices = lines.vertices[i];\n\t _colour = lines.colours[i];\n\t\n\t if (pickingIds) {\n\t _pickingId = lines.pickingIds[i];\n\t }\n\t\n\t for (var j = 0; j < _vertices.length; j++) {\n\t var ax = _vertices[j][0] + offset.x;\n\t var ay = _vertices[j][1];\n\t var az = _vertices[j][2] + offset.y;\n\t\n\t var c1 = _colour[j];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t }\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3));\n\t\n\t if (pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t return geometry;\n\t };\n\t\n\t // TODO: Make picking IDs optional\n\t var createGeometry = function createGeometry(attributes, offset) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t // Three components per vertex per face (3 x 3 = 9)\n\t var vertices = new Float32Array(attributes.facesCount * 9);\n\t var normals = new Float32Array(attributes.facesCount * 9);\n\t var colours = new Float32Array(attributes.facesCount * 9);\n\t\n\t var pickingIds;\n\t if (attributes.pickingIds) {\n\t // One component per vertex per face (1 x 3 = 3)\n\t pickingIds = new Float32Array(attributes.facesCount * 3);\n\t }\n\t\n\t var pA = new _three2['default'].Vector3();\n\t var pB = new _three2['default'].Vector3();\n\t var pC = new _three2['default'].Vector3();\n\t\n\t var cb = new _three2['default'].Vector3();\n\t var ab = new _three2['default'].Vector3();\n\t\n\t var index;\n\t var _faces;\n\t var _vertices;\n\t var _colour;\n\t var _pickingId;\n\t var lastIndex = 0;\n\t for (var i = 0; i < attributes.faces.length; i++) {\n\t _faces = attributes.faces[i];\n\t _vertices = attributes.vertices[i];\n\t _colour = attributes.colours[i];\n\t\n\t if (pickingIds) {\n\t _pickingId = attributes.pickingIds[i];\n\t }\n\t\n\t for (var j = 0; j < _faces.length; j++) {\n\t // Array of vertex indexes for the face\n\t index = _faces[j][0];\n\t\n\t var ax = _vertices[index][0] + offset.x;\n\t var ay = _vertices[index][1];\n\t var az = _vertices[index][2] + offset.y;\n\t\n\t var c1 = _colour[j][0];\n\t\n\t index = _faces[j][1];\n\t\n\t var bx = _vertices[index][0] + offset.x;\n\t var by = _vertices[index][1];\n\t var bz = _vertices[index][2] + offset.y;\n\t\n\t var c2 = _colour[j][1];\n\t\n\t index = _faces[j][2];\n\t\n\t var cx = _vertices[index][0] + offset.x;\n\t var cy = _vertices[index][1];\n\t var cz = _vertices[index][2] + offset.y;\n\t\n\t var c3 = _colour[j][2];\n\t\n\t // Flat face normals\n\t // From: http://threejs.org/examples/webgl_buffergeometry.html\n\t pA.set(ax, ay, az);\n\t pB.set(bx, by, bz);\n\t pC.set(cx, cy, cz);\n\t\n\t cb.subVectors(pC, pB);\n\t ab.subVectors(pA, pB);\n\t cb.cross(ab);\n\t\n\t cb.normalize();\n\t\n\t var nx = cb.x;\n\t var ny = cb.y;\n\t var nz = cb.z;\n\t\n\t vertices[lastIndex * 9 + 0] = ax;\n\t vertices[lastIndex * 9 + 1] = ay;\n\t vertices[lastIndex * 9 + 2] = az;\n\t\n\t normals[lastIndex * 9 + 0] = nx;\n\t normals[lastIndex * 9 + 1] = ny;\n\t normals[lastIndex * 9 + 2] = nz;\n\t\n\t colours[lastIndex * 9 + 0] = c1[0];\n\t colours[lastIndex * 9 + 1] = c1[1];\n\t colours[lastIndex * 9 + 2] = c1[2];\n\t\n\t vertices[lastIndex * 9 + 3] = bx;\n\t vertices[lastIndex * 9 + 4] = by;\n\t vertices[lastIndex * 9 + 5] = bz;\n\t\n\t normals[lastIndex * 9 + 3] = nx;\n\t normals[lastIndex * 9 + 4] = ny;\n\t normals[lastIndex * 9 + 5] = nz;\n\t\n\t colours[lastIndex * 9 + 3] = c2[0];\n\t colours[lastIndex * 9 + 4] = c2[1];\n\t colours[lastIndex * 9 + 5] = c2[2];\n\t\n\t vertices[lastIndex * 9 + 6] = cx;\n\t vertices[lastIndex * 9 + 7] = cy;\n\t vertices[lastIndex * 9 + 8] = cz;\n\t\n\t normals[lastIndex * 9 + 6] = nx;\n\t normals[lastIndex * 9 + 7] = ny;\n\t normals[lastIndex * 9 + 8] = nz;\n\t\n\t colours[lastIndex * 9 + 6] = c3[0];\n\t colours[lastIndex * 9 + 7] = c3[1];\n\t colours[lastIndex * 9 + 8] = c3[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex * 3 + 0] = _pickingId;\n\t pickingIds[lastIndex * 3 + 1] = _pickingId;\n\t pickingIds[lastIndex * 3 + 2] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t }\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3));\n\t geometry.addAttribute('normal', new _three2['default'].BufferAttribute(normals, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3));\n\t\n\t if (pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t return geometry;\n\t };\n\t\n\t var textEncoder = new TextEncoder('utf-8');\n\t var textDecoder = new TextDecoder('utf-8');\n\t\n\t var stringToUint8Array = function stringToUint8Array(str) {\n\t return textEncoder.encode(str);\n\t };\n\t\n\t var uint8ArrayToString = function uint8ArrayToString(ab) {\n\t return textDecoder.decode(ab);\n\t };\n\t\n\t return {\n\t mergeFloat32Arrays: mergeFloat32Arrays,\n\t splitFloat32Array: splitFloat32Array,\n\t mergeUint8Arrays: mergeUint8Arrays,\n\t splitUint8Array: splitUint8Array,\n\t mergeAttributes: mergeAttributes,\n\t createLineGeometry: createLineGeometry,\n\t createGeometry: createGeometry,\n\t stringToUint8Array: stringToUint8Array,\n\t uint8ArrayToString: uint8ArrayToString\n\t };\n\t})();\n\t\n\texports['default'] = Buffer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 35 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\tvar Stringify = (function () {\n\t var functionToString = function functionToString(f) {\n\t return f.toString();\n\t };\n\t\n\t // Based on https://github.com/tangrams/tangram/blob/2a31893c814cf15d5077f87ffa10af20160716b9/src/utils/utils.js#L245\n\t var stringToFunction = function stringToFunction(str) {\n\t if (typeof str === 'string' && str.match(/^\\s*function\\s*\\w*\\s*\\([\\s\\S]*\\)\\s*\\{[\\s\\S]*\\}/m) != null) {\n\t var f;\n\t\n\t try {\n\t eval('f = ' + str);\n\t return f;\n\t } catch (err) {\n\t return str;\n\t }\n\t }\n\t };\n\t\n\t return {\n\t functionToString: functionToString,\n\t stringToFunction: stringToFunction\n\t };\n\t})();\n\t\n\texports['default'] = Stringify;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 36 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\t// TODO: Allow _setBufferAttributes to use a custom function passed in to\n\t// generate a custom mesh\n\t\n\tvar _Layer2 = __webpack_require__(4);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(6);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoGeo = __webpack_require__(1);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoLatLon = __webpack_require__(2);\n\t\n\tvar _geoPoint = __webpack_require__(3);\n\t\n\tvar _earcut2 = __webpack_require__(29);\n\t\n\tvar _earcut3 = _interopRequireDefault(_earcut2);\n\t\n\tvar _utilExtrudePolygon = __webpack_require__(30);\n\t\n\tvar _utilExtrudePolygon2 = _interopRequireDefault(_utilExtrudePolygon);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(37);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(34);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PolygonLayer = (function (_Layer) {\n\t _inherits(PolygonLayer, _Layer);\n\t\n\t function PolygonLayer(coordinates, options) {\n\t _classCallCheck(this, PolygonLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t polygonMaterial: null,\n\t onPolygonMesh: null,\n\t onBufferAttributes: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t color: '#ffffff',\n\t transparent: false,\n\t opacity: 1,\n\t blending: _three2['default'].NormalBlending,\n\t height: 0\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PolygonLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of polygons so it's easy to support\n\t // MultiPolygon features (a single polygon would be a MultiPolygon with a\n\t // single polygon in the array)\n\t this._coordinates = PolygonLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t }\n\t\n\t _createClass(PolygonLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._setCoordinates();\n\t\n\t if (_this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (_this.isOutput()) {\n\t _this._pickingMesh = new _three2['default'].Object3D();\n\t _this.addToPicking(_this._pickingMesh);\n\t }\n\t\n\t _this._setPickingId();\n\t _this._addPickingEvents();\n\t }\n\t\n\t PolygonLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) {\n\t _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes);\n\t\n\t if (result.outlineAttributes.length > 0) {\n\t _this._outlineBufferAttributes = _utilBuffer2['default'].mergeAttributes(result.outlineAttributes);\n\t }\n\t\n\t _this._flat = result.flat;\n\t\n\t if (_this.isOutput()) {\n\t var attributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3,\n\t tops: 1\n\t };\n\t\n\t if (_this._options.interactive) {\n\t attributeLengths.pickingIds = 1;\n\t }\n\t\n\t var style = _this._options.style;\n\t\n\t // Set mesh if not merging elsewhere\n\t PolygonLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) {\n\t // Output mesh\n\t _this.add(result.mesh);\n\t\n\t if (result.pickingMesh) {\n\t _this._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t result.attributes = null;\n\t result.outlineAttributes = null;\n\t result = null;\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Return center of polygon as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t //\n\t // TODO: Find proper center position instead of returning first coordinate\n\t // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return polygon bounds in geographic coordinates\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this2 = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this2.emit('click', _this2, point2d, point3d, intersects);\n\t });\n\t }\n\t\n\t // Create and store reference to THREE.BufferAttribute data for this layer\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t }, {\n\t key: 'getOutlineBufferAttributes',\n\t value: function getOutlineBufferAttributes() {\n\t return this._outlineBufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t this._outlineBufferAttributes = null;\n\t }\n\t\n\t // Threshold angle is currently in rads\n\t }, {\n\t key: 'clearCoordinates',\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t }, {\n\t key: '_setCoordinates',\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates[0][0][0];\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var point;\n\t return this._coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (latlon) {\n\t point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * point.x;\n\t _this3._offset.y = -1 * point.y;\n\t\n\t _this3._options.pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t });\n\t }\n\t\n\t // Convert coordinates array to something earcut can understand\n\t }, {\n\t key: 'isFlat',\n\t\n\t // Returns true if the polygon is flat (has no height)\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiPolygon GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t\n\t // TODO: Make sure this is cleaning everything\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PolygonLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'SetBufferAttributes',\n\t value: function SetBufferAttributes(coordinates, options) {\n\t return new Promise(function (resolve) {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (options.style.height && options.style.height !== 0) {\n\t height = _geoGeo2['default'].metresToWorld(options.style.height, options.pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(options.style.color);\n\t\n\t // Light and dark colours used for poor-mans AO gradient on object sides\n\t var light = new _three2['default'].Color(0xffffff);\n\t var shadow = new _three2['default'].Color(0x666666);\n\t\n\t var flat = true;\n\t\n\t var outlineAttributes = [];\n\t\n\t // For each polygon\n\t var attributes = coordinates.map(function (_coordinates) {\n\t // Convert coordinates to earcut format\n\t var _earcut = PolygonLayer.ToEarcut(_coordinates);\n\t\n\t // Triangulate faces using earcut\n\t var faces = PolygonLayer.Triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions);\n\t\n\t var groupedVertices = [];\n\t for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) {\n\t groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions));\n\t }\n\t\n\t var extruded = (0, _utilExtrudePolygon2['default'])(groupedVertices, faces, {\n\t bottom: 0,\n\t top: height\n\t });\n\t\n\t var topColor = colour.clone().multiply(light);\n\t var bottomColor = colour.clone().multiply(shadow);\n\t\n\t var _vertices = extruded.positions;\n\t var _faces = [];\n\t var _colours = [];\n\t var _tops = [];\n\t\n\t var _colour;\n\t extruded.top.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t\n\t _tops.push([true, true, true]);\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t\n\t if (extruded.sides) {\n\t flat = false;\n\t\n\t // Set up colours for every vertex with poor-mans AO on the sides\n\t extruded.sides.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t // First face is always bottom-bottom-top\n\t if (fi % 2 === 0) {\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t\n\t _tops.push([false, false, true]);\n\t // Reverse winding for the second face\n\t // top-top-bottom\n\t } else {\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t\n\t _tops.push([true, true, false]);\n\t }\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t }\n\t\n\t // Skip bottom as there's no point rendering it\n\t // allFaces.push(extruded.faces);\n\t\n\t var polygon = {\n\t vertices: _vertices,\n\t faces: _faces,\n\t colours: _colours,\n\t tops: _tops,\n\t facesCount: _faces.length\n\t };\n\t\n\t if (options.style.outline) {\n\t var outlineColour = new _three2['default'].Color();\n\t outlineColour.set(options.style.outlineColor || 0x000000);\n\t\n\t outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour));\n\t }\n\t\n\t if (options.interactive && options.pickingId) {\n\t // Inject picking ID\n\t polygon.pickingId = options.pickingId;\n\t }\n\t\n\t // Convert polygon representation to proper attribute arrays\n\t return PolygonLayer.ToAttributes(polygon);\n\t });\n\t\n\t resolve({\n\t attributes: attributes,\n\t outlineAttributes: outlineAttributes,\n\t flat: flat\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'Set2DOutline',\n\t value: function Set2DOutline(coordinates, colour) {\n\t var _vertices = [];\n\t\n\t coordinates.forEach(function (ring) {\n\t var _ring = ring.map(function (coordinate) {\n\t return [coordinate.x, 0, coordinate.y];\n\t });\n\t\n\t // Add in duplicate vertices for line segments to work\n\t var verticeCount = _ring.length;\n\t var first = true;\n\t while (--verticeCount) {\n\t if (first || verticeCount === 0) {\n\t first = false;\n\t continue;\n\t }\n\t\n\t _ring.splice(verticeCount + 1, 0, _ring[verticeCount]);\n\t }\n\t\n\t _vertices = _vertices.concat(_ring);\n\t });\n\t\n\t _colour = [colour.r, colour.g, colour.b];\n\t\n\t var vertices = new Float32Array(_vertices.length * 3);\n\t var colours = new Float32Array(_vertices.length * 3);\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _vertices.length; i++) {\n\t var ax = _vertices[i][0];\n\t var ay = _vertices[i][1];\n\t var az = _vertices[i][2];\n\t\n\t var c1 = _colour;\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t positions: vertices,\n\t colors: colours\n\t };\n\t\n\t return attributes;\n\t }\n\t }, {\n\t key: 'SetMesh',\n\t value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t for (var key in attributes) {\n\t geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key]));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (options.polygonMaterial && options.polygonMaterial instanceof _three2['default'].Material) {\n\t material = options.polygonMaterial;\n\t } else if (!skybox) {\n\t material = new _three2['default'].MeshPhongMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t side: _three2['default'].BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t side: _three2['default'].BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof options.onPolygonMesh === 'function') {\n\t mesh = options.onPolygonMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t mesh.receiveShadow = true;\n\t }\n\t\n\t if (flat) {\n\t material.depthWrite = false;\n\t\n\t var renderOrder = style.renderOrder !== undefined ? style.renderOrder : 3;\n\t mesh.renderOrder = renderOrder;\n\t }\n\t\n\t if (options.interactive) {\n\t material = new _enginePickingMaterial2['default']();\n\t material.side = _three2['default'].BackSide;\n\t\n\t var pickingMesh = new _three2['default'].Mesh(geometry, material);\n\t }\n\t\n\t return Promise.resolve({\n\t mesh: mesh,\n\t pickingMesh: pickingMesh\n\t });\n\t }\n\t }, {\n\t key: 'ToEarcut',\n\t value: function ToEarcut(coordinates) {\n\t var dim = 2;\n\t var result = { vertices: [], holes: [], dimensions: dim };\n\t var holeIndex = 0;\n\t\n\t for (var i = 0; i < coordinates.length; i++) {\n\t for (var j = 0; j < coordinates[i].length; j++) {\n\t // for (var d = 0; d < dim; d++) {\n\t result.vertices.push(coordinates[i][j].x);\n\t result.vertices.push(coordinates[i][j].y);\n\t // }\n\t }\n\t if (i > 0) {\n\t holeIndex += coordinates[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t\n\t return result;\n\t }\n\t\n\t // Triangulate earcut-based input using earcut\n\t }, {\n\t key: 'Triangulate',\n\t value: function Triangulate(contour, holes, dim) {\n\t // console.time('earcut');\n\t\n\t var faces = (0, _earcut3['default'])(contour, holes, dim);\n\t var result = [];\n\t\n\t for (i = 0, il = faces.length; i < il; i += 3) {\n\t result.push(faces.slice(i, i + 3));\n\t }\n\t\n\t // console.timeEnd('earcut');\n\t\n\t return result;\n\t }\n\t\n\t // Transform polygon representation into attribute arrays that can be used by\n\t // THREE.BufferGeometry\n\t //\n\t // TODO: Can this be simplified? It's messy and huge\n\t }, {\n\t key: 'ToAttributes',\n\t value: function ToAttributes(polygon) {\n\t // Three components per vertex per face (3 x 3 = 9)\n\t var positions = new Float32Array(polygon.facesCount * 9);\n\t var normals = new Float32Array(polygon.facesCount * 9);\n\t var colours = new Float32Array(polygon.facesCount * 9);\n\t\n\t // One component per vertex per face (1 x 3 = 3)\n\t var tops = new Float32Array(polygon.facesCount * 3);\n\t\n\t var pickingIds;\n\t if (polygon.pickingId) {\n\t // One component per vertex per face (1 x 3 = 3)\n\t pickingIds = new Float32Array(polygon.facesCount * 3);\n\t }\n\t\n\t var pA = new _three2['default'].Vector3();\n\t var pB = new _three2['default'].Vector3();\n\t var pC = new _three2['default'].Vector3();\n\t\n\t var cb = new _three2['default'].Vector3();\n\t var ab = new _three2['default'].Vector3();\n\t\n\t var index;\n\t\n\t var _faces = polygon.faces;\n\t var _vertices = polygon.vertices;\n\t var _colour = polygon.colours;\n\t var _tops = polygon.tops;\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = polygon.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _faces.length; i++) {\n\t // Array of vertex indexes for the face\n\t index = _faces[i][0];\n\t\n\t var ax = _vertices[index][0];\n\t var ay = _vertices[index][1];\n\t var az = _vertices[index][2];\n\t\n\t var c1 = _colour[i][0];\n\t var t1 = _tops[i][0];\n\t\n\t index = _faces[i][1];\n\t\n\t var bx = _vertices[index][0];\n\t var by = _vertices[index][1];\n\t var bz = _vertices[index][2];\n\t\n\t var c2 = _colour[i][1];\n\t var t2 = _tops[i][1];\n\t\n\t index = _faces[i][2];\n\t\n\t var cx = _vertices[index][0];\n\t var cy = _vertices[index][1];\n\t var cz = _vertices[index][2];\n\t\n\t var c3 = _colour[i][2];\n\t var t3 = _tops[i][2];\n\t\n\t // Flat face normals\n\t // From: http://threejs.org/examples/webgl_buffergeometry.html\n\t pA.set(ax, ay, az);\n\t pB.set(bx, by, bz);\n\t pC.set(cx, cy, cz);\n\t\n\t cb.subVectors(pC, pB);\n\t ab.subVectors(pA, pB);\n\t cb.cross(ab);\n\t\n\t cb.normalize();\n\t\n\t var nx = cb.x;\n\t var ny = cb.y;\n\t var nz = cb.z;\n\t\n\t positions[lastIndex * 9 + 0] = ax;\n\t positions[lastIndex * 9 + 1] = ay;\n\t positions[lastIndex * 9 + 2] = az;\n\t\n\t normals[lastIndex * 9 + 0] = nx;\n\t normals[lastIndex * 9 + 1] = ny;\n\t normals[lastIndex * 9 + 2] = nz;\n\t\n\t colours[lastIndex * 9 + 0] = c1[0];\n\t colours[lastIndex * 9 + 1] = c1[1];\n\t colours[lastIndex * 9 + 2] = c1[2];\n\t\n\t positions[lastIndex * 9 + 3] = bx;\n\t positions[lastIndex * 9 + 4] = by;\n\t positions[lastIndex * 9 + 5] = bz;\n\t\n\t normals[lastIndex * 9 + 3] = nx;\n\t normals[lastIndex * 9 + 4] = ny;\n\t normals[lastIndex * 9 + 5] = nz;\n\t\n\t colours[lastIndex * 9 + 3] = c2[0];\n\t colours[lastIndex * 9 + 4] = c2[1];\n\t colours[lastIndex * 9 + 5] = c2[2];\n\t\n\t positions[lastIndex * 9 + 6] = cx;\n\t positions[lastIndex * 9 + 7] = cy;\n\t positions[lastIndex * 9 + 8] = cz;\n\t\n\t normals[lastIndex * 9 + 6] = nx;\n\t normals[lastIndex * 9 + 7] = ny;\n\t normals[lastIndex * 9 + 8] = nz;\n\t\n\t colours[lastIndex * 9 + 6] = c3[0];\n\t colours[lastIndex * 9 + 7] = c3[1];\n\t colours[lastIndex * 9 + 8] = c3[2];\n\t\n\t tops[lastIndex * 3 + 0] = t1;\n\t tops[lastIndex * 3 + 1] = t2;\n\t tops[lastIndex * 3 + 2] = t3;\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex * 3 + 0] = _pickingId;\n\t pickingIds[lastIndex * 3 + 1] = _pickingId;\n\t pickingIds[lastIndex * 3 + 2] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t positions: positions,\n\t normals: normals,\n\t colors: colours,\n\t tops: tops\n\t };\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t }, {\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0][0][0]);\n\t }\n\t }]);\n\t\n\t return PolygonLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PolygonLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PolygonLayer(coordinates, options);\n\t};\n\t\n\texports.polygonLayer = noNew;\n\n/***/ },\n/* 37 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _PickingShader = __webpack_require__(38);\n\t\n\tvar _PickingShader2 = _interopRequireDefault(_PickingShader);\n\t\n\t// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\t\n\tvar PickingMaterial = function PickingMaterial() {\n\t _three2['default'].ShaderMaterial.call(this, {\n\t uniforms: {\n\t size: {\n\t type: 'f',\n\t value: 0.01\n\t },\n\t scale: {\n\t type: 'f',\n\t value: 400\n\t }\n\t },\n\t // attributes: ['position', 'id'],\n\t vertexShader: _PickingShader2['default'].vertexShader,\n\t fragmentShader: _PickingShader2['default'].fragmentShader\n\t });\n\t\n\t this.linePadding = 2;\n\t};\n\t\n\tPickingMaterial.prototype = Object.create(_three2['default'].ShaderMaterial.prototype);\n\t\n\tPickingMaterial.prototype.constructor = PickingMaterial;\n\t\n\tPickingMaterial.prototype.setPointSize = function (size) {\n\t this.uniforms.size.value = size;\n\t};\n\t\n\tPickingMaterial.prototype.setPointScale = function (scale) {\n\t this.uniforms.scale.value = scale;\n\t};\n\t\n\texports['default'] = PickingMaterial;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 38 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\t\n\tvar PickingShader = {\n\t\tvertexShader: ['attribute float pickingId;',\n\t\t// '',\n\t\t// 'uniform float size;',\n\t\t// 'uniform float scale;',\n\t\t'', 'varying vec4 worldId;', '', 'void main() {', ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',\n\t\t// ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );',\n\t\t' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);', ' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);', ' worldId = vec4(a,1);', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t\tfragmentShader: ['#ifdef GL_ES\\n', 'precision highp float;\\n', '#endif\\n', '', 'varying vec4 worldId;', '', 'void main() {', ' gl_FragColor = worldId;', '}'].join('\\n')\n\t};\n\t\n\texports['default'] = PickingShader;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 39 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Provide alternative output using tubes and splines / curves\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\t// TODO: Allow _setBufferAttributes to use a custom function passed in to\n\t// generate a custom mesh\n\t\n\tvar _Layer2 = __webpack_require__(4);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(6);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoGeo = __webpack_require__(1);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoLatLon = __webpack_require__(2);\n\t\n\tvar _geoPoint = __webpack_require__(3);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(37);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(34);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PolylineLayer = (function (_Layer) {\n\t _inherits(PolylineLayer, _Layer);\n\t\n\t function PolylineLayer(coordinates, options) {\n\t _classCallCheck(this, PolylineLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t polylineMaterial: null,\n\t onPolylineMesh: null,\n\t onBufferAttributes: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t lineOpacity: 1,\n\t lineTransparent: false,\n\t lineColor: '#ffffff',\n\t lineWidth: 1,\n\t lineBlending: _three2['default'].NormalBlending\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PolylineLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of lines so it's easy to support\n\t // MultiLineString features (a single line would be a MultiLineString with a\n\t // single line in the array)\n\t this._coordinates = PolylineLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t // Polyline features are always flat (for now at least)\n\t this._flat = true;\n\t }\n\t\n\t _createClass(PolylineLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._setCoordinates();\n\t\n\t if (_this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (_this.isOutput()) {\n\t _this._pickingMesh = new _three2['default'].Object3D();\n\t _this.addToPicking(_this._pickingMesh);\n\t }\n\t\n\t _this._setPickingId();\n\t _this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t PolylineLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) {\n\t _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes);\n\t _this._flat = result.flat;\n\t\n\t var attributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t\n\t if (_this._options.interactive) {\n\t attributeLengths.pickingIds = 1;\n\t }\n\t\n\t if (_this.isOutput()) {\n\t var style = _this._options.style;\n\t\n\t // Set mesh if not merging elsewhere\n\t PolylineLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options).then(function (result) {\n\t // Output mesh\n\t _this.add(result.mesh);\n\t\n\t if (result.pickingMesh) {\n\t _this._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t result.attributes = null;\n\t result = null;\n\t\n\t resolve(_this);\n\t });\n\t });\n\t }\n\t\n\t // Return center of polyline as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t //\n\t // TODO: Find proper center position instead of returning first coordinate\n\t // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return line bounds in geographic coordinates\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this2 = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this2.emit('click', _this2, point2d, point3d, intersects);\n\t });\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t }, {\n\t key: '_setCoordinates',\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates[0][0];\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var point;\n\t return this._coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (latlon) {\n\t point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * point.x;\n\t _this3._offset.y = -1 * point.y;\n\t\n\t _this3._options.pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'isFlat',\n\t\n\t // Returns true if the line is flat (has no height)\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiLineString GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PolylineLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'SetBufferAttributes',\n\t value: function SetBufferAttributes(coordinates, options) {\n\t return new Promise(function (resolve) {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (options.style.lineHeight) {\n\t height = _geoGeo2['default'].metresToWorld(options.style.lineHeight, options.pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(options.style.lineColor);\n\t\n\t var flat = true;\n\t\n\t // For each line\n\t var attributes = coordinates.map(function (_projectedCoordinates) {\n\t var _vertices = [];\n\t var _colours = [];\n\t\n\t // Connect coordinate with the next to make a pair\n\t //\n\t // LineSegments requires pairs of vertices so repeat the last point if\n\t // there's an odd number of vertices\n\t var nextCoord;\n\t _projectedCoordinates.forEach(function (coordinate, index) {\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _vertices.push([coordinate.x, height, coordinate.y]);\n\t\n\t nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate;\n\t\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _vertices.push([nextCoord.x, height, nextCoord.y]);\n\t });\n\t\n\t var line = {\n\t vertices: _vertices,\n\t colours: _colours,\n\t verticesCount: _vertices.length\n\t };\n\t\n\t if (options.interactive && options.pickingId) {\n\t // Inject picking ID\n\t line.pickingId = options.pickingId;\n\t }\n\t\n\t // Convert line representation to proper attribute arrays\n\t return PolylineLayer.ToAttributes(line);\n\t });\n\t\n\t resolve({\n\t attributes: attributes,\n\t flat: flat\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'SetMesh',\n\t value: function SetMesh(attributes, attributeLengths, flat, style, options) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t for (var key in attributes) {\n\t geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key]));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (options.polylineMaterial && options.polylineMaterial instanceof _three2['default'].Material) {\n\t material = options.polylineMaterial;\n\t } else {\n\t material = new _three2['default'].LineBasicMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t linewidth: style.lineWidth,\n\t transparent: style.lineTransparent,\n\t opacity: style.lineOpacity,\n\t blending: style.lineBlending\n\t });\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof options.onPolylineMesh === 'function') {\n\t mesh = options.onPolylineMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].LineSegments(geometry, material);\n\t\n\t if (style.lineRenderOrder !== undefined) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = style.lineRenderOrder;\n\t }\n\t\n\t mesh.castShadow = true;\n\t // mesh.receiveShadow = true;\n\t }\n\t\n\t if (options.interactive) {\n\t material = new _enginePickingMaterial2['default']();\n\t // material.side = THREE.BackSide;\n\t\n\t // Make the line wider / easier to pick\n\t material.linewidth = style.lineWidth + material.linePadding;\n\t\n\t var pickingMesh = new _three2['default'].LineSegments(geometry, material);\n\t }\n\t\n\t return Promise.resolve({\n\t mesh: mesh,\n\t pickingMesh: pickingMesh\n\t });\n\t }\n\t }, {\n\t key: 'ToAttributes',\n\t value: function ToAttributes(line) {\n\t // Three components per vertex\n\t var vertices = new Float32Array(line.verticesCount * 3);\n\t var colours = new Float32Array(line.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (line.pickingId) {\n\t // One component per vertex\n\t pickingIds = new Float32Array(line.verticesCount);\n\t }\n\t\n\t var _vertices = line.vertices;\n\t var _colour = line.colours;\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = line.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _vertices.length; i++) {\n\t var ax = _vertices[i][0];\n\t var ay = _vertices[i][1];\n\t var az = _vertices[i][2];\n\t\n\t var c1 = _colour[i];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t positions: vertices,\n\t colors: colours\n\t };\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t }, {\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0][0]);\n\t }\n\t }]);\n\t\n\t return PolylineLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PolylineLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PolylineLayer(coordinates, options);\n\t};\n\t\n\texports.polylineLayer = noNew;\n\n/***/ },\n/* 40 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Point features may be using custom models / meshes and so an approach\n\t// needs to be found to allow these to be brokwn down into buffer attributes for\n\t// merging\n\t//\n\t// Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry\n\t// and pull out the attributes\n\t\n\t// TODO: Support sprite objects using textures\n\t\n\t// TODO: Provide option to billboard geometry so it always faces the camera\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\tvar _Layer2 = __webpack_require__(4);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(6);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(18);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoGeo = __webpack_require__(1);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoLatLon = __webpack_require__(2);\n\t\n\tvar _geoPoint = __webpack_require__(3);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(37);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(34);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _PolygonLayer = __webpack_require__(36);\n\t\n\tvar _PolygonLayer2 = _interopRequireDefault(_PolygonLayer);\n\t\n\tvar PointLayer = (function (_Layer) {\n\t _inherits(PointLayer, _Layer);\n\t\n\t function PointLayer(coordinates, options) {\n\t _classCallCheck(this, PointLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // THREE.Geometry or THREE.BufferGeometry to use for point output\n\t pointGeometry: null,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t pointMaterial: null,\n\t onPointMesh: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t pointColor: '#ff0000'\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PointLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of points so it's easy to support\n\t // MultiPoint features (a single point would be a MultiPoint with a\n\t // single point in the array)\n\t this._coordinates = PointLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t this._flat = false;\n\t }\n\t\n\t _createClass(PointLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._setCoordinates();\n\t\n\t if (_this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (_this.isOutput()) {\n\t _this._pickingMesh = new _three2['default'].Object3D();\n\t _this.addToPicking(_this._pickingMesh);\n\t }\n\t\n\t _this._setPickingId();\n\t _this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t PointLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) {\n\t _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes);\n\t _this._flat = result.flat;\n\t\n\t var attributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3\n\t };\n\t\n\t if (_this._options.interactive) {\n\t attributeLengths.pickingIds = 1;\n\t }\n\t\n\t if (_this.isOutput()) {\n\t var style = _this._options.style;\n\t\n\t // Set mesh if not merging elsewhere\n\t // TODO: Dedupe with PolygonLayer as they are identical\n\t PointLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) {\n\t // Output mesh\n\t _this.add(result.mesh);\n\t\n\t if (result.pickingMesh) {\n\t _this._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t result.attributes = null;\n\t result = null;\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Return center of point as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return point bounds in geographic coordinates\n\t //\n\t // While not useful for single points, it could be useful for MultiPoint\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this2 = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this2.emit('click', _this2, point2d, point3d, intersects);\n\t });\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t }, {\n\t key: '_setCoordinates',\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates;\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var _point;\n\t return this._coordinates.map(function (latlon) {\n\t _point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * _point.x;\n\t _this3._offset.y = -1 * _point.y;\n\t\n\t _this3._options.pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return _point;\n\t });\n\t }\n\t\n\t // Returns true if the line is flat (has no height)\n\t }, {\n\t key: 'isFlat',\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiPoint GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PointLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'SetBufferAttributes',\n\t value: function SetBufferAttributes(coordinates, options) {\n\t return new Promise(function (resolve) {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (options.style.pointHeight) {\n\t height = _geoGeo2['default'].metresToWorld(options.style.pointHeight, options.pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(options.style.pointColor);\n\t\n\t // Use default geometry if none has been provided or the provided geometry\n\t // isn't valid\n\t if (!options.pointGeometry || !options.pointGeometry instanceof _three2['default'].Geometry || !options.pointGeometry instanceof _three2['default'].BufferGeometry) {\n\t // Debug geometry for points is a thin bar\n\t //\n\t // TODO: Allow point geometry to be customised / overridden\n\t var geometryWidth = _geoGeo2['default'].metresToWorld(25, options.pointScale);\n\t var geometryHeight = _geoGeo2['default'].metresToWorld(200, options.pointScale);\n\t var _geometry = new _three2['default'].BoxGeometry(geometryWidth, geometryHeight, geometryWidth);\n\t\n\t // Shift geometry up so it sits on the ground\n\t _geometry.translate(0, geometryHeight * 0.5, 0);\n\t\n\t // Pull attributes out of debug geometry\n\t geometry = new _three2['default'].BufferGeometry().fromGeometry(_geometry);\n\t } else {\n\t if (options.geometry instanceof _three2['default'].BufferGeometry) {\n\t geometry = options.pointGeometry;\n\t } else {\n\t geometry = new _three2['default'].BufferGeometry().fromGeometry(options.pointGeometry);\n\t }\n\t }\n\t\n\t var attributes = coordinates.map(function (coordinate) {\n\t var _vertices = [];\n\t var _normals = [];\n\t var _colours = [];\n\t\n\t var _geometry = geometry.clone();\n\t _geometry.translate(coordinate.x, height, coordinate.y);\n\t\n\t var _vertices = _geometry.attributes.position.clone().array;\n\t var _normals = _geometry.attributes.normal.clone().array;\n\t var _colours = _geometry.attributes.color.clone().array;\n\t\n\t for (var i = 0; i < _colours.length; i += 3) {\n\t _colours[i] = colour.r;\n\t _colours[i + 1] = colour.g;\n\t _colours[i + 2] = colour.b;\n\t }\n\t\n\t var _point = {\n\t positions: _vertices,\n\t normals: _normals,\n\t colors: _colours\n\t };\n\t\n\t if (options.interactive && options.pickingId) {\n\t // Inject picking ID\n\t _point.pickingId = options.pickingId;\n\t }\n\t\n\t return _point;\n\t });\n\t\n\t resolve({\n\t attributes: attributes,\n\t flat: false\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'SetMesh',\n\t value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t for (var key in attributes) {\n\t geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key]));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (options.pointMaterial && options.pointMaterial instanceof _three2['default'].Material) {\n\t material = options.pointMaterial;\n\t } else if (!skybox) {\n\t material = new _three2['default'].MeshPhongMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t // side: THREE.BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t // side: THREE.BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof options.onPolygonMesh === 'function') {\n\t mesh = options.onPolygonMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t mesh.receiveShadow = true;\n\t }\n\t\n\t if (flat) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = 4;\n\t }\n\t\n\t if (options.interactive) {\n\t material = new _enginePickingMaterial2['default']();\n\t material.side = _three2['default'].BackSide;\n\t\n\t var pickingMesh = new _three2['default'].Mesh(geometry, material);\n\t }\n\t\n\t return Promise.resolve({\n\t mesh: mesh,\n\t pickingMesh: pickingMesh\n\t });\n\t }\n\t }, {\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0]);\n\t }\n\t }]);\n\t\n\t return PointLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PointLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PointLayer(coordinates, options);\n\t};\n\t\n\texports.pointLayer = noNew;\n\n/***/ },\n/* 41 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// TODO: A lot of these utils don't need to be in separate, tiny files\n\t\n\tvar _wrapNum = __webpack_require__(42);\n\t\n\tvar _wrapNum2 = _interopRequireDefault(_wrapNum);\n\t\n\tvar _extrudePolygon = __webpack_require__(30);\n\t\n\tvar _extrudePolygon2 = _interopRequireDefault(_extrudePolygon);\n\t\n\tvar _GeoJSON = __webpack_require__(25);\n\t\n\tvar _GeoJSON2 = _interopRequireDefault(_GeoJSON);\n\t\n\tvar _Buffer = __webpack_require__(34);\n\t\n\tvar _Buffer2 = _interopRequireDefault(_Buffer);\n\t\n\tvar _Worker = __webpack_require__(31);\n\t\n\tvar _Worker2 = _interopRequireDefault(_Worker);\n\t\n\tvar _Stringify = __webpack_require__(35);\n\t\n\tvar _Stringify2 = _interopRequireDefault(_Stringify);\n\t\n\tvar Util = {};\n\t\n\tUtil.wrapNum = _wrapNum2['default'];\n\tUtil.extrudePolygon = _extrudePolygon2['default'];\n\tUtil.GeoJSON = _GeoJSON2['default'];\n\tUtil.Buffer = _Buffer2['default'];\n\tUtil.Worker = _Worker2['default'];\n\tUtil.Stringify = _Stringify2['default'];\n\t\n\texports['default'] = Util;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 42 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t/*\n\t * Wrap the given number to lie within a certain range (eg. longitude)\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js\n\t */\n\t\n\tvar wrapNum = function wrapNum(x, range, includeMax) {\n\t var max = range[1];\n\t var min = range[0];\n\t var d = max - min;\n\t return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\n\t};\n\t\n\texports[\"default\"] = wrapNum;\n\tmodule.exports = exports[\"default\"];\n\n/***/ }\n/******/ ])\n});\n;"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 8912944b678b5a293f37\n **/","import Geo from './geo/Geo.js';\nimport Layer, {layer} from './layer/Layer';\nimport GeoJSONWorkerLayer, {geoJSONWorkerLayer} from './layer/GeoJSONWorkerLayer';\nimport PolygonLayer, {polygonLayer} from './layer/geometry/PolygonLayer';\n\nimport Point, {point} from './geo/Point';\nimport LatLon, {latLon} from './geo/LatLon';\n\nimport Util from './util/index';\n\nconst VIZI = {\n version: '0.3',\n\n Geo: Geo,\n Layer: Layer,\n layer: layer,\n GeoJSONWorkerLayer: GeoJSONWorkerLayer,\n geoJSONWorkerLayer: geoJSONWorkerLayer,\n PolygonLayer: PolygonLayer,\n polygonLayer: polygonLayer,\n Point: Point,\n point: point,\n LatLon: LatLon,\n latLon: latLon,\n Util: Util\n};\n\nexport default VIZI;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vizicities-worker.js\n **/","import {latLon as LatLon} from './LatLon';\nimport {point as Point} from './Point';\n\nvar Geo = {};\n\n// Radius / WGS84 semi-major axis\nGeo.R = 6378137;\nGeo.MAX_LATITUDE = 85.0511287798;\n\n// WGS84 eccentricity\nGeo.ECC = 0.081819191;\nGeo.ECC2 = 0.081819191 * 0.081819191;\n\nGeo.project = function(latlon) {\n var d = Math.PI / 180;\n var max = Geo.MAX_LATITUDE;\n var lat = Math.max(Math.min(max, latlon.lat), -max);\n var sin = Math.sin(lat * d);\n\n return Point(\n Geo.R * latlon.lon * d,\n Geo.R * Math.log((1 + sin) / (1 - sin)) / 2\n );\n},\n\nGeo.unproject = function(point) {\n var d = 180 / Math.PI;\n\n return LatLon(\n (2 * Math.atan(Math.exp(point.y / Geo.R)) - (Math.PI / 2)) * d,\n point.x * d / Geo.R\n );\n};\n\n// Converts geo coords to pixel / WebGL ones\n// This just reverses the Y axis to match WebGL\nGeo.latLonToPoint = function(latlon) {\n var projected = Geo.project(latlon);\n projected.y *= -1;\n\n return projected;\n};\n\n// Converts pixel / WebGL coords to geo coords\n// This just reverses the Y axis to match WebGL\nGeo.pointToLatLon = function(point) {\n var _point = Point(point.x, point.y * -1);\n return Geo.unproject(_point);\n};\n\n// Scale factor for converting between real metres and projected metres\n//\n// projectedMetres = realMetres * pointScale\n// realMetres = projectedMetres / pointScale\n//\n// Accurate scale factor uses proper Web Mercator scaling\n// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf\n// See: http://jsfiddle.net/robhawkes/yws924cf/\nGeo.pointScale = function(latlon, accurate) {\n var rad = Math.PI / 180;\n\n var k;\n\n if (!accurate) {\n k = 1 / Math.cos(latlon.lat * rad);\n\n // [scaleX, scaleY]\n return [k, k];\n } else {\n var lat = latlon.lat * rad;\n var lon = latlon.lon * rad;\n\n var a = Geo.R;\n\n var sinLat = Math.sin(lat);\n var sinLat2 = sinLat * sinLat;\n\n var cosLat = Math.cos(lat);\n\n // Radius meridian\n var p = a * (1 - Geo.ECC2) / Math.pow(1 - Geo.ECC2 * sinLat2, 3 / 2);\n\n // Radius prime meridian\n var v = a / Math.sqrt(1 - Geo.ECC2 * sinLat2);\n\n // Scale N/S\n var h = (a / p) / cosLat;\n\n // Scale E/W\n k = (a / v) / cosLat;\n\n // [scaleX, scaleY]\n return [k, h];\n }\n};\n\n// Convert real metres to projected units\n//\n// Latitude scale is chosen because it fluctuates more than longitude\nGeo.metresToProjected = function(metres, pointScale) {\n return metres * pointScale[1];\n};\n\n// Convert projected units to real metres\n//\n// Latitude scale is chosen because it fluctuates more than longitude\nGeo.projectedToMetres = function(projectedUnits, pointScale) {\n return projectedUnits / pointScale[1];\n};\n\n// Convert real metres to a value in world (WebGL) units\nGeo.metresToWorld = function(metres, pointScale) {\n // Transform metres to projected metres using the latitude point scale\n //\n // Latitude scale is chosen because it fluctuates more than longitude\n var projectedMetres = Geo.metresToProjected(metres, pointScale);\n\n var scale = Geo.scale();\n\n // Scale projected metres\n var scaledMetres = (scale * projectedMetres);\n\n return scaledMetres;\n};\n\n// Convert world (WebGL) units to a value in real metres\nGeo.worldToMetres = function(worldUnits, pointScale) {\n var scale = Geo.scale();\n\n var projectedUnits = worldUnits / scale;\n var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);\n\n return realMetres;\n};\n\n// If zoom is provided, returns the map width in pixels for a given zoom\n// Else, provides fixed scale value\nGeo.scale = function(zoom) {\n // If zoom is provided then return scale based on map tile zoom\n if (zoom >= 0) {\n return 256 * Math.pow(2, zoom);\n // Else, return fixed scale value to expand projected coordinates from\n // their 0 to 1 range into something more practical\n } else {\n return 1;\n }\n};\n\n// Returns zoom level for a given scale value\n// This only works with a scale value that is based on map pixel width\nGeo.zoom = function(scale) {\n return Math.log(scale / 256) / Math.LN2;\n};\n\n// Distance between two geographical points using spherical law of cosines\n// approximation or Haversine\n//\n// See: http://www.movable-type.co.uk/scripts/latlong.html\nGeo.distance = function(latlon1, latlon2, accurate) {\n var rad = Math.PI / 180;\n\n var lat1;\n var lat2;\n\n var a;\n\n if (!accurate) {\n lat1 = latlon1.lat * rad;\n lat2 = latlon2.lat * rad;\n\n a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);\n\n return Geo.R * Math.acos(Math.min(a, 1));\n } else {\n lat1 = latlon1.lat * rad;\n lat2 = latlon2.lat * rad;\n\n var lon1 = latlon1.lon * rad;\n var lon2 = latlon2.lon * rad;\n\n var deltaLat = lat2 - lat1;\n var deltaLon = lon2 - lon1;\n\n var halfDeltaLat = deltaLat / 2;\n var halfDeltaLon = deltaLon / 2;\n\n a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);\n\n var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n return Geo.R * c;\n }\n};\n\nGeo.bounds = (function() {\n var d = Geo.R * Math.PI;\n return [[-d, -d], [d, d]];\n})();\n\nexport default Geo;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/Geo.js\n **/","/*\n * LatLon is a helper class for ensuring consistent geographic coordinates.\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js\n */\n\nclass LatLon {\n constructor(lat, lon, alt) {\n if (isNaN(lat) || isNaN(lon)) {\n throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');\n }\n\n this.lat = +lat;\n this.lon = +lon;\n\n if (alt !== undefined) {\n this.alt = +alt;\n }\n }\n\n clone() {\n return new LatLon(this.lat, this.lon, this.alt);\n }\n}\n\nexport default LatLon;\n\n// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)\n// Also converts between lng and lon\nvar noNew = function(a, b, c) {\n if (a instanceof LatLon) {\n return a;\n }\n if (Array.isArray(a) && typeof a[0] !== 'object') {\n if (a.length === 3) {\n return new LatLon(a[0], a[1], a[2]);\n }\n if (a.length === 2) {\n return new LatLon(a[0], a[1]);\n }\n return null;\n }\n if (a === undefined || a === null) {\n return a;\n }\n if (typeof a === 'object' && 'lat' in a) {\n return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\n }\n if (b === undefined) {\n return null;\n }\n return new LatLon(a, b, c);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as latLon};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/LatLon.js\n **/","/*\n * Point is a helper class for ensuring consistent world positions.\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js\n */\n\nclass Point {\n constructor(x, y, round) {\n this.x = (round ? Math.round(x) : x);\n this.y = (round ? Math.round(y) : y);\n }\n\n clone() {\n return new Point(this.x, this.y);\n }\n\n // Non-destructive\n add(point) {\n return this.clone()._add(_point(point));\n }\n\n // Destructive\n _add(point) {\n this.x += point.x;\n this.y += point.y;\n return this;\n }\n\n // Non-destructive\n subtract(point) {\n return this.clone()._subtract(_point(point));\n }\n\n // Destructive\n _subtract(point) {\n this.x -= point.x;\n this.y -= point.y;\n return this;\n }\n}\n\nexport default Point;\n\n// Accepts (point), ([x, y]) and (x, y, round)\nvar _point = function(x, y, round) {\n if (x instanceof Point) {\n return x;\n }\n if (Array.isArray(x)) {\n return new Point(x[0], x[1]);\n }\n if (x === undefined || x === null) {\n return x;\n }\n return new Point(x, y, round);\n};\n\n// Initialise without requiring new keyword\nexport {_point as point};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/Point.js\n **/","import EventEmitter from 'eventemitter3';\nimport extend from 'lodash.assign';\nimport shortid from 'shortid';\nimport THREE from 'three';\nimport Scene from '../engine/Scene';\nimport {CSS3DObject} from '../vendor/CSS3DRenderer';\nimport {CSS2DObject} from '../vendor/CSS2DRenderer';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Need a single move method that handles moving all the various object\n// layers so that the DOM layers stay in sync with the 3D layer\n\n// TODO: Double check that objects within the _object3D Object3D parent are frustum\n// culled even if the layer position stays at the default (0,0,0) and the child\n// objects are positioned much further away\n//\n// Or does the layer being at (0,0,0) prevent the child objects from being\n// culled because the layer parent is effectively always in view even if the\n// child is actually out of camera\n\nclass Layer extends EventEmitter {\n constructor(options) {\n super();\n\n var defaults = {\n id: shortid.generate(),\n output: true,\n outputToScene: true\n };\n\n this._options = extend({}, defaults, options);\n\n if (this.isOutput()) {\n this._object3D = new THREE.Object3D();\n\n this._dom3D = document.createElement('div');\n this._domObject3D = new CSS3DObject(this._dom3D);\n\n this._dom2D = document.createElement('div');\n this._domObject2D = new CSS2DObject(this._dom2D);\n }\n }\n\n // Add THREE object directly to layer\n add(object) {\n this._object3D.add(object);\n }\n\n // Remove THREE object from to layer\n remove(object) {\n this._object3D.remove(object);\n }\n\n addDOM3D(object) {\n this._domObject3D.add(object);\n }\n\n removeDOM3D(object) {\n this._domObject3D.remove(object);\n }\n\n addDOM2D(object) {\n this._domObject2D.add(object);\n }\n\n removeDOM2D(object) {\n this._domObject2D.remove(object);\n }\n\n // Add layer to world instance and store world reference\n addTo(world) {\n return world.addLayer(this);\n }\n\n // Internal method called by World.addLayer to actually add the layer\n _addToWorld(world) {\n this._world = world;\n\n return new Promise((resolve, reject) => {\n this._onAdd(world).then(() => {\n this.emit('added');\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Must return a promise\n _onAdd(world) {\n return Promise.resolve(this);\n }\n\n getPickingId() {\n if (this._world._engine._picking) {\n return this._world._engine._picking.getNextId();\n }\n\n return false;\n }\n\n // TODO: Tidy this up and don't access so many private properties to work\n addToPicking(object) {\n if (!this._world._engine._picking) {\n return;\n }\n\n this._world._engine._picking.add(object);\n }\n\n removeFromPicking(object) {\n if (!this._world._engine._picking) {\n return;\n }\n\n this._world._engine._picking.remove(object);\n }\n\n isOutput() {\n return this._options.output;\n }\n\n isOutputToScene() {\n return this._options.outputToScene;\n }\n\n // TODO: Also hide any attached DOM layers\n hide() {\n this._object3D.visible = false;\n\n if (this._pickingMesh) {\n this._pickingMesh.visible = false;\n }\n }\n\n // TODO: Also show any attached DOM layers\n show() {\n this._object3D.visible = true;\n\n if (this._pickingMesh) {\n this._pickingMesh.visible = true;\n }\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n if (this._object3D && this._object3D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._object3D.children.length - 1; i >= 0; i--) {\n child = this._object3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.remove(child);\n\n if (child.geometry) {\n // Dispose of mesh and materials\n child.geometry.dispose();\n child.geometry = null;\n }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n }\n }\n\n if (this._domObject3D && this._domObject3D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._domObject3D.children.length - 1; i >= 0; i--) {\n child = this._domObject3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.removeDOM3D(child);\n }\n }\n\n if (this._domObject2D && this._domObject2D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._domObject2D.children.length - 1; i >= 0; i--) {\n child = this._domObject2D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.removeDOM2D(child);\n }\n }\n\n this._domObject3D = null;\n this._domObject2D = null;\n\n this._world = null;\n this._object3D = null;\n }\n}\n\nexport default Layer;\n\nvar noNew = function(options) {\n return new Layer(options);\n};\n\nexport {noNew as layer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/Layer.js\n **/","'use strict';\n\nvar has = Object.prototype.hasOwnProperty;\n\n//\n// We store our EE objects in a plain object whose properties are event names.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// `~` to make sure that the built-in object properties are not overridden or\n// used as an attack vector.\n// We also assume that `Object.create(null)` is available when the event name\n// is an ES6 Symbol.\n//\nvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\n/**\n * Representation of a single EventEmitter function.\n *\n * @param {Function} fn Event handler to be called.\n * @param {Mixed} context Context for function execution.\n * @param {Boolean} [once=false] Only emit once\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal EventEmitter interface that is molded against the Node.js\n * EventEmitter interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() { /* Nothing to set */ }\n\n/**\n * Hold the assigned EventEmitters by name.\n *\n * @type {Object}\n * @private\n */\nEventEmitter.prototype._events = undefined;\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var events = this._events\n , names = []\n , name;\n\n if (!events) return names;\n\n for (name in events) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return a list of assigned event listeners.\n *\n * @param {String} event The events that should be listed.\n * @param {Boolean} exists We only need to know if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events && this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Emit an event to all registered event listeners.\n *\n * @param {String} event The name of the event.\n * @returns {Boolean} Indication if we've emitted an event.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events || !this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if ('function' === typeof listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Register a new EventListener for the given event.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} [context=this] The context of the function.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events) this._events = prefix ? {} : Object.create(null);\n if (!this._events[evt]) this._events[evt] = listener;\n else {\n if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [\n this._events[evt], listener\n ];\n }\n\n return this;\n};\n\n/**\n * Add an EventListener that's only called once.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} [context=this] The context of the function.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events) this._events = prefix ? {} : Object.create(null);\n if (!this._events[evt]) this._events[evt] = listener;\n else {\n if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [\n this._events[evt], listener\n ];\n }\n\n return this;\n};\n\n/**\n * Remove event listeners.\n *\n * @param {String} event The event we want to remove.\n * @param {Function} fn The listener that we need to find.\n * @param {Mixed} context Only remove listeners matching this context.\n * @param {Boolean} once Only remove once listeners.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events || !this._events[evt]) return this;\n\n var listeners = this._events[evt]\n , events = [];\n\n if (fn) {\n if (listeners.fn) {\n if (\n listeners.fn !== fn\n || (once && !listeners.once)\n || (context && listeners.context !== context)\n ) {\n events.push(listeners);\n }\n } else {\n for (var i = 0, length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) {\n this._events[evt] = events.length === 1 ? events[0] : events;\n } else {\n delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners or only the listeners for the specified event.\n *\n * @param {String} event The event want to remove all listeners for.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n if (!this._events) return this;\n\n if (event) delete this._events[prefix ? prefix + event : event];\n else this._events = prefix ? {} : Object.create(null);\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/eventemitter3/index.js\n ** module id = 5\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\nvar keys = require('lodash.keys'),\n rest = require('lodash.rest');\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\nvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : source[key];\n\n assignValue(object, key, newValue);\n }\n return object;\n}\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return rest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'user': 'fred' };\n * var other = { 'user': 'fred' };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.c = 3;\n * }\n *\n * function Bar() {\n * this.e = 5;\n * }\n *\n * Foo.prototype.d = 4;\n * Bar.prototype.f = 6;\n *\n * _.assign({ 'a': 1 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3, 'e': 5 }\n */\nvar assign = createAssigner(function(object, source) {\n if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.assign/index.js\n ** module id = 6\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n stringTag = '[object String]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetPrototype = Object.getPrototypeOf,\n nativeKeys = Object.keys;\n\n/**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHas(object, key) {\n // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n // that are composed entirely of index properties, return `false` for\n // `hasOwnProperty` checks of them.\n return hasOwnProperty.call(object, key) ||\n (typeof object == 'object' && key in object && getPrototype(object) === null);\n}\n\n/**\n * The base implementation of `_.keys` which doesn't skip the constructor\n * property of prototypes or treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n return nativeKeys(Object(object));\n}\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Gets the `[[Prototype]]` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {null|Object} Returns the `[[Prototype]]`.\n */\nfunction getPrototype(value) {\n return nativeGetPrototype(Object(value));\n}\n\n/**\n * Creates an array of index keys for `object` values of arrays,\n * `arguments` objects, and strings, otherwise `null` is returned.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array|null} Returns index keys, else `null`.\n */\nfunction indexKeys(object) {\n var length = object ? object.length : undefined;\n if (isLength(length) &&\n (isArray(object) || isString(object) || isArguments(object))) {\n return baseTimes(length, String);\n }\n return null;\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @type {Function}\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n var isProto = isPrototype(object);\n if (!(isProto || isArrayLike(object))) {\n return baseKeys(object);\n }\n var indexes = indexKeys(object),\n skipIndexes = !!indexes,\n result = indexes || [],\n length = result.length;\n\n for (var key in object) {\n if (baseHas(object, key) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n !(isProto && key == 'constructor')) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = keys;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.keys/index.js\n ** module id = 7\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308,\n NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n var length = args.length;\n switch (length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\nfunction rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n switch (start) {\n case 0: return func.call(this, array);\n case 1: return func.call(this, args[0], array);\n case 2: return func.call(this, args[0], args[1], array);\n }\n var otherArgs = Array(start + 1);\n index = -1;\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = array;\n return apply(func, this, otherArgs);\n };\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This function is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = isFunction(value.valueOf) ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = rest;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.rest/index.js\n ** module id = 8\n ** module chunks = 0\n **/","'use strict';\nmodule.exports = require('./lib/index');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/index.js\n ** module id = 9\n ** module chunks = 0\n **/","'use strict';\n\nvar alphabet = require('./alphabet');\nvar encode = require('./encode');\nvar decode = require('./decode');\nvar isValid = require('./is-valid');\n\n// Ignore all milliseconds before a certain time to reduce the size of the date entropy without sacrificing uniqueness.\n// This number should be updated every year or so to keep the generated id short.\n// To regenerate `new Date() - 0` and bump the version. Always bump the version!\nvar REDUCE_TIME = 1459707606518;\n\n// don't change unless we change the algos or REDUCE_TIME\n// must be an integer and less than 16\nvar version = 6;\n\n// if you are using cluster or multiple servers use this to make each instance\n// has a unique value for worker\n// Note: I don't know if this is automatically set when using third\n// party cluster solutions such as pm2.\nvar clusterWorkerId = require('./util/cluster-worker-id') || 0;\n\n// Counter is used when shortid is called multiple times in one second.\nvar counter;\n\n// Remember the last time shortid was called in case counter is needed.\nvar previousSeconds;\n\n/**\n * Generate unique id\n * Returns string id\n */\nfunction generate() {\n\n var str = '';\n\n var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);\n\n if (seconds === previousSeconds) {\n counter++;\n } else {\n counter = 0;\n previousSeconds = seconds;\n }\n\n str = str + encode(alphabet.lookup, version);\n str = str + encode(alphabet.lookup, clusterWorkerId);\n if (counter > 0) {\n str = str + encode(alphabet.lookup, counter);\n }\n str = str + encode(alphabet.lookup, seconds);\n\n return str;\n}\n\n\n/**\n * Set the seed.\n * Highly recommended if you don't want people to try to figure out your id schema.\n * exposed as shortid.seed(int)\n * @param seed Integer value to seed the random alphabet. ALWAYS USE THE SAME SEED or you might get overlaps.\n */\nfunction seed(seedValue) {\n alphabet.seed(seedValue);\n return module.exports;\n}\n\n/**\n * Set the cluster worker or machine id\n * exposed as shortid.worker(int)\n * @param workerId worker must be positive integer. Number less than 16 is recommended.\n * returns shortid module so it can be chained.\n */\nfunction worker(workerId) {\n clusterWorkerId = workerId;\n return module.exports;\n}\n\n/**\n *\n * sets new characters to use in the alphabet\n * returns the shuffled alphabet\n */\nfunction characters(newCharacters) {\n if (newCharacters !== undefined) {\n alphabet.characters(newCharacters);\n }\n\n return alphabet.shuffled();\n}\n\n\n// Export all other functions as properties of the generate function\nmodule.exports = generate;\nmodule.exports.generate = generate;\nmodule.exports.seed = seed;\nmodule.exports.worker = worker;\nmodule.exports.characters = characters;\nmodule.exports.decode = decode;\nmodule.exports.isValid = isValid;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/index.js\n ** module id = 10\n ** module chunks = 0\n **/","'use strict';\n\nvar randomFromSeed = require('./random/random-from-seed');\n\nvar ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';\nvar alphabet;\nvar previousSeed;\n\nvar shuffled;\n\nfunction reset() {\n shuffled = false;\n}\n\nfunction setCharacters(_alphabet_) {\n if (!_alphabet_) {\n if (alphabet !== ORIGINAL) {\n alphabet = ORIGINAL;\n reset();\n }\n return;\n }\n\n if (_alphabet_ === alphabet) {\n return;\n }\n\n if (_alphabet_.length !== ORIGINAL.length) {\n throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_);\n }\n\n var unique = _alphabet_.split('').filter(function(item, ind, arr){\n return ind !== arr.lastIndexOf(item);\n });\n\n if (unique.length) {\n throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', '));\n }\n\n alphabet = _alphabet_;\n reset();\n}\n\nfunction characters(_alphabet_) {\n setCharacters(_alphabet_);\n return alphabet;\n}\n\nfunction setSeed(seed) {\n randomFromSeed.seed(seed);\n if (previousSeed !== seed) {\n reset();\n previousSeed = seed;\n }\n}\n\nfunction shuffle() {\n if (!alphabet) {\n setCharacters(ORIGINAL);\n }\n\n var sourceArray = alphabet.split('');\n var targetArray = [];\n var r = randomFromSeed.nextValue();\n var characterIndex;\n\n while (sourceArray.length > 0) {\n r = randomFromSeed.nextValue();\n characterIndex = Math.floor(r * sourceArray.length);\n targetArray.push(sourceArray.splice(characterIndex, 1)[0]);\n }\n return targetArray.join('');\n}\n\nfunction getShuffled() {\n if (shuffled) {\n return shuffled;\n }\n shuffled = shuffle();\n return shuffled;\n}\n\n/**\n * lookup shuffled letter\n * @param index\n * @returns {string}\n */\nfunction lookup(index) {\n var alphabetShuffled = getShuffled();\n return alphabetShuffled[index];\n}\n\nmodule.exports = {\n characters: characters,\n seed: setSeed,\n lookup: lookup,\n shuffled: getShuffled\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/alphabet.js\n ** module id = 11\n ** module chunks = 0\n **/","'use strict';\n\n// Found this seed-based random generator somewhere\n// Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu)\n\nvar seed = 1;\n\n/**\n * return a random number based on a seed\n * @param seed\n * @returns {number}\n */\nfunction getNextValue() {\n seed = (seed * 9301 + 49297) % 233280;\n return seed/(233280.0);\n}\n\nfunction setSeed(_seed_) {\n seed = _seed_;\n}\n\nmodule.exports = {\n nextValue: getNextValue,\n seed: setSeed\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/random/random-from-seed.js\n ** module id = 12\n ** module chunks = 0\n **/","'use strict';\n\nvar randomByte = require('./random/random-byte');\n\nfunction encode(lookup, number) {\n var loopCounter = 0;\n var done;\n\n var str = '';\n\n while (!done) {\n str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );\n done = number < (Math.pow(16, loopCounter + 1 ) );\n loopCounter++;\n }\n return str;\n}\n\nmodule.exports = encode;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/encode.js\n ** module id = 13\n ** module chunks = 0\n **/","'use strict';\n\nvar crypto = typeof window === 'object' && (window.crypto || window.msCrypto); // IE 11 uses window.msCrypto\n\nfunction randomByte() {\n if (!crypto || !crypto.getRandomValues) {\n return Math.floor(Math.random() * 256) & 0x30;\n }\n var dest = new Uint8Array(1);\n crypto.getRandomValues(dest);\n return dest[0] & 0x30;\n}\n\nmodule.exports = randomByte;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/random/random-byte-browser.js\n ** module id = 14\n ** module chunks = 0\n **/","'use strict';\nvar alphabet = require('./alphabet');\n\n/**\n * Decode the id to get the version and worker\n * Mainly for debugging and testing.\n * @param id - the shortid-generated id.\n */\nfunction decode(id) {\n var characters = alphabet.shuffled();\n return {\n version: characters.indexOf(id.substr(0, 1)) & 0x0f,\n worker: characters.indexOf(id.substr(1, 1)) & 0x0f\n };\n}\n\nmodule.exports = decode;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/decode.js\n ** module id = 15\n ** module chunks = 0\n **/","'use strict';\nvar alphabet = require('./alphabet');\n\nfunction isShortId(id) {\n if (!id || typeof id !== 'string' || id.length < 6 ) {\n return false;\n }\n\n var characters = alphabet.characters();\n var len = id.length;\n for(var i = 0; i < len;i++) {\n if (characters.indexOf(id[i]) === -1) {\n return false;\n }\n }\n return true;\n}\n\nmodule.exports = isShortId;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/is-valid.js\n ** module id = 16\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = 0;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/util/cluster-worker-id-browser.js\n ** module id = 17\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_18__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"THREE\"\n ** module id = 18\n ** module chunks = 0\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n\n // TODO: Re-enable when this works with the skybox\n // scene.fog = new THREE.Fog(0xffffff, 1, 15000);\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Scene.js\n **/","// jscs:disable\n/* eslint-disable */\n\n/**\n * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs\n * @author mrdoob / http://mrdoob.com/\n */\n\nimport THREE from 'three';\n\nvar CSS3DObject = function ( element ) {\n\n\tTHREE.Object3D.call( this );\n\n\tthis.element = element;\n\tthis.element.style.position = 'absolute';\n\n\tthis.addEventListener( 'removed', function ( event ) {\n\n\t\tif ( this.element.parentNode !== null ) {\n\n\t\t\tthis.element.parentNode.removeChild( this.element );\n\n\t\t}\n\n\t} );\n\n};\n\nCSS3DObject.prototype = Object.create( THREE.Object3D.prototype );\nCSS3DObject.prototype.constructor = CSS3DObject;\n\nvar CSS3DSprite = function ( element ) {\n\n\tCSS3DObject.call( this, element );\n\n};\n\nCSS3DSprite.prototype = Object.create( CSS3DObject.prototype );\nCSS3DSprite.prototype.constructor = CSS3DSprite;\n\n//\n\nvar CSS3DRenderer = function () {\n\n\tconsole.log( 'THREE.CSS3DRenderer', THREE.REVISION );\n\n\tvar _width, _height;\n\tvar _widthHalf, _heightHalf;\n\n\tvar matrix = new THREE.Matrix4();\n\n\tvar cache = {\n\t\tcamera: { fov: 0, style: '' },\n\t\tobjects: {}\n\t};\n\n\tvar domElement = document.createElement( 'div' );\n\tdomElement.style.overflow = 'hidden';\n\n\tdomElement.style.WebkitTransformStyle = 'preserve-3d';\n\tdomElement.style.MozTransformStyle = 'preserve-3d';\n\tdomElement.style.oTransformStyle = 'preserve-3d';\n\tdomElement.style.transformStyle = 'preserve-3d';\n\n\tthis.domElement = domElement;\n\n\tvar cameraElement = document.createElement( 'div' );\n\n\tcameraElement.style.WebkitTransformStyle = 'preserve-3d';\n\tcameraElement.style.MozTransformStyle = 'preserve-3d';\n\tcameraElement.style.oTransformStyle = 'preserve-3d';\n\tcameraElement.style.transformStyle = 'preserve-3d';\n\n\tdomElement.appendChild( cameraElement );\n\n\tthis.setClearColor = function () {};\n\n\tthis.getSize = function() {\n\n\t\treturn {\n\t\t\twidth: _width,\n\t\t\theight: _height\n\t\t};\n\n\t};\n\n\tthis.setSize = function ( width, height ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_widthHalf = _width / 2;\n\t\t_heightHalf = _height / 2;\n\n\t\tdomElement.style.width = width + 'px';\n\t\tdomElement.style.height = height + 'px';\n\n\t\tcameraElement.style.width = width + 'px';\n\t\tcameraElement.style.height = height + 'px';\n\n\t};\n\n\tvar epsilon = function ( value ) {\n\n\t\treturn Math.abs( value ) < Number.EPSILON ? 0 : value;\n\n\t};\n\n\tvar getCameraCSSMatrix = function ( matrix ) {\n\n\t\tvar elements = matrix.elements;\n\n\t\treturn 'matrix3d(' +\n\t\t\tepsilon( elements[ 0 ] ) + ',' +\n\t\t\tepsilon( - elements[ 1 ] ) + ',' +\n\t\t\tepsilon( elements[ 2 ] ) + ',' +\n\t\t\tepsilon( elements[ 3 ] ) + ',' +\n\t\t\tepsilon( elements[ 4 ] ) + ',' +\n\t\t\tepsilon( - elements[ 5 ] ) + ',' +\n\t\t\tepsilon( elements[ 6 ] ) + ',' +\n\t\t\tepsilon( elements[ 7 ] ) + ',' +\n\t\t\tepsilon( elements[ 8 ] ) + ',' +\n\t\t\tepsilon( - elements[ 9 ] ) + ',' +\n\t\t\tepsilon( elements[ 10 ] ) + ',' +\n\t\t\tepsilon( elements[ 11 ] ) + ',' +\n\t\t\tepsilon( elements[ 12 ] ) + ',' +\n\t\t\tepsilon( - elements[ 13 ] ) + ',' +\n\t\t\tepsilon( elements[ 14 ] ) + ',' +\n\t\t\tepsilon( elements[ 15 ] ) +\n\t\t')';\n\n\t};\n\n\tvar getObjectCSSMatrix = function ( matrix ) {\n\n\t\tvar elements = matrix.elements;\n\n\t\treturn 'translate3d(-50%,-50%,0) matrix3d(' +\n\t\t\tepsilon( elements[ 0 ] ) + ',' +\n\t\t\tepsilon( elements[ 1 ] ) + ',' +\n\t\t\tepsilon( elements[ 2 ] ) + ',' +\n\t\t\tepsilon( elements[ 3 ] ) + ',' +\n\t\t\tepsilon( - elements[ 4 ] ) + ',' +\n\t\t\tepsilon( - elements[ 5 ] ) + ',' +\n\t\t\tepsilon( - elements[ 6 ] ) + ',' +\n\t\t\tepsilon( - elements[ 7 ] ) + ',' +\n\t\t\tepsilon( elements[ 8 ] ) + ',' +\n\t\t\tepsilon( elements[ 9 ] ) + ',' +\n\t\t\tepsilon( elements[ 10 ] ) + ',' +\n\t\t\tepsilon( elements[ 11 ] ) + ',' +\n\t\t\tepsilon( elements[ 12 ] ) + ',' +\n\t\t\tepsilon( elements[ 13 ] ) + ',' +\n\t\t\tepsilon( elements[ 14 ] ) + ',' +\n\t\t\tepsilon( elements[ 15 ] ) +\n\t\t')';\n\n\t};\n\n\tvar renderObject = function ( object, camera ) {\n\n\t\tif ( object instanceof CSS3DObject ) {\n\n\t\t\tvar style;\n\n\t\t\tif ( object instanceof CSS3DSprite ) {\n\n\t\t\t\t// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/\n\n\t\t\t\tmatrix.copy( camera.matrixWorldInverse );\n\t\t\t\tmatrix.transpose();\n\t\t\t\tmatrix.copyPosition( object.matrixWorld );\n\t\t\t\tmatrix.scale( object.scale );\n\n\t\t\t\tmatrix.elements[ 3 ] = 0;\n\t\t\t\tmatrix.elements[ 7 ] = 0;\n\t\t\t\tmatrix.elements[ 11 ] = 0;\n\t\t\t\tmatrix.elements[ 15 ] = 1;\n\n\t\t\t\tstyle = getObjectCSSMatrix( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tstyle = getObjectCSSMatrix( object.matrixWorld );\n\n\t\t\t}\n\n\t\t\tvar element = object.element;\n\t\t\tvar cachedStyle = cache.objects[ object.id ];\n\n\t\t\tif ( cachedStyle === undefined || cachedStyle !== style ) {\n\n\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\telement.style.MozTransform = style;\n\t\t\t\telement.style.oTransform = style;\n\t\t\t\telement.style.transform = style;\n\n\t\t\t\tcache.objects[ object.id ] = style;\n\n\t\t\t}\n\n\t\t\tif ( element.parentNode !== cameraElement ) {\n\n\t\t\t\tcameraElement.appendChild( element );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( var i = 0, l = object.children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( object.children[ i ], camera );\n\n\t\t}\n\n\t};\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tvar fov = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * _height;\n\n\t\tif ( cache.camera.fov !== fov ) {\n\n\t\t\tdomElement.style.WebkitPerspective = fov + 'px';\n\t\t\tdomElement.style.MozPerspective = fov + 'px';\n\t\t\tdomElement.style.oPerspective = fov + 'px';\n\t\t\tdomElement.style.perspective = fov + 'px';\n\n\t\t\tcache.camera.fov = fov;\n\n\t\t}\n\n\t\tscene.updateMatrixWorld();\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\tvar style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) +\n\t\t\t' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)';\n\n\t\tif ( cache.camera.style !== style ) {\n\n\t\t\tcameraElement.style.WebkitTransform = style;\n\t\t\tcameraElement.style.MozTransform = style;\n\t\t\tcameraElement.style.oTransform = style;\n\t\t\tcameraElement.style.transform = style;\n\n\t\t\tcache.camera.style = style;\n\n\t\t}\n\n\t\trenderObject( scene, camera );\n\n\t};\n\n};\n\nexport {CSS3DObject as CSS3DObject};\nexport {CSS3DSprite as CSS3DSprite};\nexport {CSS3DRenderer as CSS3DRenderer};\n\nTHREE.CSS3DObject = CSS3DObject;\nTHREE.CSS3DSprite = CSS3DSprite;\nTHREE.CSS3DRenderer = CSS3DRenderer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CSS3DRenderer.js\n **/","// jscs:disable\n/* eslint-disable */\n\n/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nimport THREE from 'three';\n\nvar CSS2DObject = function ( element ) {\n\n\tTHREE.Object3D.call( this );\n\n\tthis.element = element;\n\tthis.element.style.position = 'absolute';\n\n\tthis.addEventListener( 'removed', function ( event ) {\n\n\t\tif ( this.element.parentNode !== null ) {\n\n\t\t\tthis.element.parentNode.removeChild( this.element );\n\n\t\t}\n\n\t} );\n\n};\n\nCSS2DObject.prototype = Object.create( THREE.Object3D.prototype );\nCSS2DObject.prototype.constructor = CSS2DObject;\n\n//\n\nvar CSS2DRenderer = function () {\n\n\tconsole.log( 'THREE.CSS2DRenderer', THREE.REVISION );\n\n\tvar _width, _height;\n\tvar _widthHalf, _heightHalf;\n\n\tvar vector = new THREE.Vector3();\n\tvar viewMatrix = new THREE.Matrix4();\n\tvar viewProjectionMatrix = new THREE.Matrix4();\n\n\tvar frustum = new THREE.Frustum();\n\n\tvar domElement = document.createElement( 'div' );\n\tdomElement.style.overflow = 'hidden';\n\n\tthis.domElement = domElement;\n\n\tthis.setSize = function ( width, height ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_widthHalf = _width / 2;\n\t\t_heightHalf = _height / 2;\n\n\t\tdomElement.style.width = width + 'px';\n\t\tdomElement.style.height = height + 'px';\n\n\t};\n\n\tvar renderObject = function ( object, camera ) {\n\n\t\tif ( object instanceof CSS2DObject ) {\n\n\t\t\tvector.setFromMatrixPosition( object.matrixWorld );\n\t\t\tvector.applyProjection( viewProjectionMatrix );\n\n\t\t\tvar element = object.element;\n\t\t\tvar style = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';\n\n\t\t\telement.style.WebkitTransform = style;\n\t\t\telement.style.MozTransform = style;\n\t\t\telement.style.oTransform = style;\n\t\t\telement.style.transform = style;\n\n\t\t\tif ( element.parentNode !== domElement ) {\n\n\t\t\t\tdomElement.appendChild( element );\n\n\t\t\t}\n\n\t\t\t// Hide if outside view frustum\n\t\t\tif (!frustum.containsPoint(object.position)) {\n\t\t\t\telement.style.display = 'none';\n\t\t\t} else {\n\t\t\t\telement.style.display = 'block';\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( var i = 0, l = object.children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( object.children[ i ], camera );\n\n\t\t}\n\n\t};\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tscene.updateMatrixWorld();\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\tviewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );\n\t\tviewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );\n\n\t\tfrustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );\n\n\t\trenderObject( scene, camera );\n\n\t};\n\n};\n\nexport {CSS2DObject as CSS2DObject};\nexport {CSS2DRenderer as CSS2DRenderer};\n\nTHREE.CSS2DObject = CSS2DObject;\nTHREE.CSS2DRenderer = CSS2DRenderer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CSS2DRenderer.js\n **/","import Layer from './Layer';\nimport extend from 'lodash.assign';\nimport reqwest from 'reqwest';\nimport GeoJSON from '../util/GeoJSON';\nimport Worker from '../util/Worker';\nimport Buffer from '../util/Buffer';\nimport Stringify from '../util/Stringify';\nimport PolygonLayer from './geometry/PolygonLayer';\nimport PolylineLayer from './geometry/PolylineLayer';\nimport PointLayer from './geometry/PointLayer';\nimport {latLon as LatLon} from '../geo/LatLon';\nimport {point as Point} from '../geo/Point';\nimport Geo from '../geo/Geo';\nimport PickingMaterial from '../engine/PickingMaterial';\n\n// TODO: Allow filter method to be run inside a worker to improve performance\n// TODO: Allow onEachFeature method to be run inside a worker to improve performance\n\nclass GeoJSONWorkerLayer extends Layer {\n constructor(geojson, options) {\n var defaults = {\n topojson: false,\n style: GeoJSON.defaultStyle,\n onEachFeature: null,\n onEachFeatureWorker: null,\n onAddAttributes: null,\n interactive: false,\n pointGeometry: null,\n onClick: null,\n headers: {}\n };\n\n var _options = extend({}, defaults, options);\n\n if (typeof options.style === 'object') {\n _options.style = extend({}, defaults.style, options.style);\n }\n\n super(_options);\n\n this._aborted = false;\n this._geojson = geojson;\n }\n\n _onAdd(world) {\n if (this._options.interactive) {\n // Worker layer always controls output to add a picking mesh\n this._pickingMesh = new THREE.Object3D();\n }\n\n // Process GeoJSON\n return this._process(this._geojson);\n }\n\n // Use workers to request and process GeoJSON, returning data structure\n // containing geometry and any supplementary data for output\n _process(_geojson) {\n return new Promise((resolve, reject) => {\n var style = this._options.style;\n\n // TODO: Convert to buffer and use transferrable objects\n if (typeof this._options.style === 'function') {\n style = Stringify.functionToString(this._options.style);\n }\n\n var pointGeometry = this._options.pointGeometry;\n\n // TODO: Convert to buffer and use transferrable objects\n if (typeof this._options.pointGeometry === 'function') {\n pointGeometry = Stringify.functionToString(this._options.pointGeometry);\n }\n\n var geojson = _geojson;\n var transferrables = [];\n\n if (typeof geojson !== 'string') {\n this._geojson = geojson = Buffer.stringToUint8Array(JSON.stringify(geojson));\n transferrables.push(geojson.buffer);\n this._execWorker(geojson, this._options.topojson, this._world._originPoint, style, this._options.interactive, pointGeometry, transferrables).then(() => {\n resolve();\n }).catch(reject);\n } else if (typeof this._options.filter === 'function' || typeof this._options.onEachFeature === 'function') {\n GeoJSONWorkerLayer.RequestGeoJSON(geojson).then((res) => {\n // if (this._aborted) {\n // resolve();\n // return;\n // }\n\n var fc = GeoJSON.collectFeatures(res, this._options.topojson);\n var features = fc.features;\n\n // Run filter, if provided\n if (this._options.filter) {\n fc.features = features.filter(this._options.filter);\n }\n\n if (this._options.onEachFeature) {\n var feature;\n for (var i = 0; i < features.length; i++) {\n feature = features[i];\n this._options.onEachFeature(feature);\n };\n }\n\n this._geojson = geojson = Buffer.stringToUint8Array(JSON.stringify(fc));\n transferrables.push(geojson.buffer);\n\n this._execWorker(geojson, false, this._options.headers, this._world._originPoint, style, this._options.interactive, pointGeometry, transferrables).then(() => {\n resolve();\n }).catch(reject);\n });\n } else {\n this._execWorker(geojson, this._options.topojson, this._options.headers, this._world._originPoint, style, this._options.interactive, pointGeometry, transferrables).then(() => {\n resolve();\n }).catch(reject);\n }\n });\n }\n\n _execWorker(geojson, topojson, headers, originPoint, style, interactive, pointGeometry, transferrables) {\n return new Promise((resolve, reject) => {\n console.time('Worker round trip');\n\n Worker.exec('GeoJSONWorkerLayer.Process', [geojson, topojson, headers, originPoint, style, interactive, pointGeometry], transferrables).then((results) => {\n console.timeEnd('Worker round trip');\n\n // if (this._aborted) {\n // resolve();\n // return;\n // }\n\n var processPromises = [];\n\n if (results.polygons) {\n processPromises.push(this._processPolygonResults(results.polygons));\n }\n\n if (results.polylines) {\n processPromises.push(this._processPolylineResults(results.polylines));\n }\n\n if (results.points) {\n processPromises.push(this._processPointResults(results.points));\n }\n\n if (processPromises.length > 0) {\n Promise.all(processPromises).then(() => {\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n });\n });\n }\n\n // TODO: Dedupe with polyline method\n _processPolygonResults(results) {\n return new Promise((resolve, reject) => {\n var splitPositions = Buffer.splitFloat32Array(results.attributes.positions);\n var splitNormals = Buffer.splitFloat32Array(results.attributes.normals);\n var splitColors = Buffer.splitFloat32Array(results.attributes.colors);\n var splitTops = Buffer.splitFloat32Array(results.attributes.tops);\n\n var splitOutlinePositions;\n var splitOutlineColors;\n\n if (results.outlineAttributes) {\n splitOutlinePositions = Buffer.splitFloat32Array(results.outlineAttributes.positions);\n splitOutlineColors = Buffer.splitFloat32Array(results.outlineAttributes.colors);\n }\n\n var splitProperties;\n if (results.properties) {\n splitProperties = Buffer.splitUint8Array(results.properties);\n }\n\n var flats = results.flats;\n\n var objects = [];\n var outlineObjects = [];\n\n var obj;\n var pickingId;\n var pickingIds;\n var properties;\n\n var polygonAttributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3,\n tops: 1\n };\n\n var polygonOutlineAttributeLengths = {\n positions: 3,\n colors: 3\n };\n\n for (var i = 0; i < splitPositions.length; i++) {\n if (splitProperties && splitProperties[i]) {\n properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));\n } else {\n properties = {};\n }\n\n // WORKERS: obj.attributes should actually an array of polygons for\n // the feature, though the current logic isn't aware of that\n obj = {\n attributes: [{\n positions: splitPositions[i],\n normals: splitNormals[i],\n colors: splitColors[i],\n tops: splitTops[i]\n }],\n properties: properties,\n flat: flats[i]\n };\n\n // WORKERS: If interactive, generate unique ID for each feature, create\n // the buffer attributes and set up event listeners\n if (this._options.interactive) {\n pickingId = this.getPickingId();\n\n pickingIds = new Float32Array(splitPositions[i].length / 3);\n pickingIds.fill(pickingId);\n\n obj.attributes[0].pickingIds = pickingIds;\n\n polygonAttributeLengths.pickingIds = 1;\n\n this._addPicking(pickingId, properties);\n }\n\n // TODO: Make this specific to polygon attributes\n if (typeof this._options.onAddAttributes === 'function') {\n var customAttributes = this._options.onAddAttributes(obj.attributes[0], properties);\n var customAttribute;\n for (var key in customAttributes) {\n customAttribute = customAttributes[key];\n obj.attributes[0][key] = customAttribute.value;\n polygonAttributeLengths[key] = customAttribute.length;\n }\n }\n\n objects.push(obj);\n }\n\n for (var i = 0; i < splitOutlinePositions.length; i++) {\n obj = {\n attributes: [{\n positions: splitOutlinePositions[i],\n colors: splitOutlineColors[i]\n }],\n flat: true\n };\n\n outlineObjects.push(obj);\n }\n\n var polygonAttributes = [];\n var polygonOutlineAttributes = [];\n\n var polygonFlat = true;\n\n for (var i = 0; i < objects.length; i++) {\n obj = objects[i];\n\n // TODO: Work out why obj.flat is rarely set to something other than\n // true or false. Potentially undefined.\n if (polygonFlat && obj.flat === false) {\n polygonFlat = false;\n }\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n polygonAttributes.push(bufferAttributes);\n };\n\n for (var i = 0; i < outlineObjects.length; i++) {\n obj = outlineObjects[i];\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n polygonOutlineAttributes.push(bufferAttributes);\n };\n\n var outputPromises = [];\n\n var style;\n\n if (polygonAttributes.length > 0) {\n var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);\n\n // TODO: Make this work when style is a function per feature\n style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n outputPromises.push(this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat));\n }\n\n if (polygonOutlineAttributes.length > 0) {\n var mergedPolygonOutlineAttributes = Buffer.mergeAttributes(polygonOutlineAttributes);\n\n style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n if (style.outlineRenderOrder !== undefined) {\n style.lineRenderOrder = style.outlineRenderOrder;\n } else {\n style.lineRenderOrder = (style.renderOrder) ? style.renderOrder + 1 : 4;\n }\n\n if (style.outlineWidth) {\n style.lineWidth = style.outlineWidth;\n }\n\n outputPromises.push(this._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true));\n }\n\n Promise.all(outputPromises).then((results) => {\n var [polygonResult, outlineResult] = results;\n\n if (polygonResult) {\n this._polygonMesh = polygonResult.mesh;\n this.add(this._polygonMesh);\n\n if (polygonResult.pickingMesh) {\n this._pickingMesh.add(polygonResult.pickingMesh);\n }\n }\n\n if (outlineResult) {\n this.add(outlineResult.mesh);\n }\n\n resolve();\n }).catch(reject);\n });\n }\n\n // TODO: Dedupe with polygon method\n _processPolylineResults(results) {\n return new Promise((resolve, reject) => {\n var splitPositions = Buffer.splitFloat32Array(results.attributes.positions);\n var splitColors = Buffer.splitFloat32Array(results.attributes.colors);\n\n var splitProperties;\n if (results.properties) {\n splitProperties = Buffer.splitUint8Array(results.properties);\n }\n\n var flats = results.flats;\n\n var objects = [];\n var obj;\n var pickingId;\n var pickingIds;\n var properties;\n\n var polylineAttributeLengths = {\n positions: 3,\n colors: 3\n };\n\n for (var i = 0; i < splitPositions.length; i++) {\n if (splitProperties && splitProperties[i]) {\n properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));\n } else {\n properties = {};\n }\n\n // WORKERS: obj.attributes should actually an array of polygons for\n // the feature, though the current logic isn't aware of that\n obj = {\n attributes: [{\n positions: splitPositions[i],\n colors: splitColors[i]\n }],\n properties: properties,\n flat: flats[i]\n };\n\n // WORKERS: If interactive, generate unique ID for each feature, create\n // the buffer attributes and set up event listeners\n if (this._options.interactive) {\n pickingId = this.getPickingId();\n\n pickingIds = new Float32Array(splitPositions[i].length / 3);\n pickingIds.fill(pickingId);\n\n obj.attributes[0].pickingIds = pickingIds;\n\n polylineAttributeLengths.pickingIds = 1;\n\n this._addPicking(pickingId, properties);\n }\n\n // TODO: Make this specific to polyline attributes\n if (typeof this._options.onAddAttributes === 'function') {\n var customAttributes = this._options.onAddAttributes(obj.attributes[0], properties);\n var customAttribute;\n for (var key in customAttributes) {\n customAttribute = customAttributes[key];\n obj.attributes[0][key] = customAttribute.value;\n polylineAttributeLengths[key] = customAttribute.length;\n }\n }\n\n objects.push(obj);\n }\n\n var polylineAttributes = [];\n\n var polylineFlat = true;\n\n for (var i = 0; i < objects.length; i++) {\n obj = objects[i];\n\n if (polylineFlat && !obj.flat) {\n polylineFlat = false;\n }\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n polylineAttributes.push(bufferAttributes);\n };\n\n if (polylineAttributes.length > 0) {\n var mergedPolylineAttributes = Buffer.mergeAttributes(polylineAttributes);\n\n // TODO: Make this work when style is a function per feature\n var style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then((result) => {\n this._polylineMesh = result.mesh;\n this.add(this._polylineMesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n });\n }\n\n _processPointResults(results) {\n return new Promise((resolve, reject) => {\n var splitPositions = Buffer.splitFloat32Array(results.attributes.positions);\n var splitNormals = Buffer.splitFloat32Array(results.attributes.normals);\n var splitColors = Buffer.splitFloat32Array(results.attributes.colors);\n\n var splitProperties;\n if (results.properties) {\n splitProperties = Buffer.splitUint8Array(results.properties);\n }\n\n var flats = results.flats;\n\n var objects = [];\n var obj;\n var pickingId;\n var pickingIds;\n var properties;\n\n var pointAttributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3\n };\n\n for (var i = 0; i < splitPositions.length; i++) {\n if (splitProperties && splitProperties[i]) {\n properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));\n } else {\n properties = {};\n }\n\n // WORKERS: obj.attributes should actually an array of polygons for\n // the feature, though the current logic isn't aware of that\n obj = {\n attributes: [{\n positions: splitPositions[i],\n normals: splitNormals[i],\n colors: splitColors[i]\n }],\n properties: properties,\n flat: flats[i]\n };\n\n // WORKERS: If interactive, generate unique ID for each feature, create\n // the buffer attributes and set up event listeners\n if (this._options.interactive) {\n pickingId = this.getPickingId();\n\n pickingIds = new Float32Array(splitPositions[i].length / 3);\n pickingIds.fill(pickingId);\n\n obj.attributes[0].pickingIds = pickingIds;\n\n pointAttributeLengths.pickingIds = 1;\n\n this._addPicking(pickingId, properties);\n }\n\n // TODO: Make this specific to polygon attributes\n if (typeof this._options.onAddAttributes === 'function') {\n var customAttributes = this._options.onAddAttributes(obj.attributes[0], properties);\n var customAttribute;\n for (var key in customAttributes) {\n customAttribute = customAttributes[key];\n obj.attributes[0][key] = customAttribute.value;\n pointAttributeLengths[key] = customAttribute.length;\n }\n }\n\n objects.push(obj);\n }\n\n var pointAttributes = [];\n\n var pointFlat = true;\n\n for (var i = 0; i < objects.length; i++) {\n obj = objects[i];\n\n if (pointFlat && !obj.flat) {\n pointFlat = false;\n }\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n pointAttributes.push(bufferAttributes);\n };\n\n if (pointAttributes.length > 0) {\n var mergedPointAttributes = Buffer.mergeAttributes(pointAttributes);\n\n // TODO: Make this work when style is a function per feature\n var style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then((result) => {\n this._pointMesh = result.mesh;\n this.add(this._pointMesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n });\n }\n\n // TODO: At some point this needs to return all the features to the main thread\n // so it can generate meshes and output to the scene, as well as perhaps creating\n // individual layers / components for each feature to track things like picking\n // and properties\n //\n // TODO: Find a way so the origin point isn't needed to be passed in as it\n // feels a bit messy and against the idea of a static Geo class\n //\n // TODO: Support passing custom geometry for point layers\n static Process(geojson, topojson, headers, originPoint, _style, _properties, _pointGeometry) {\n return new Promise((resolve, reject) => {\n GeoJSONWorkerLayer.ProcessGeoJSON(geojson, headers).then((res) => {\n // Collects features into a single FeatureCollection\n //\n // Also converts TopoJSON to GeoJSON if instructed\n var geojson = GeoJSON.collectFeatures(res, topojson);\n\n // TODO: Check that GeoJSON is valid / usable\n\n var features = geojson.features;\n\n // TODO: Run filter, if provided (must be static)\n\n var pointScale;\n var polygons = [];\n var polylines = [];\n var points = [];\n\n // Deserialise style function if provided\n if (typeof _style === 'string') {\n _style = Stringify.stringToFunction(_style);\n }\n\n // Assume that a style won't be set per feature\n var style = _style;\n\n var pointGeometry;\n // Deserialise pointGeometry function if provided\n if (typeof _pointGeometry === 'string') {\n pointGeometry = Stringify.stringToFunction(_pointGeometry);\n }\n\n var feature;\n for (var i = 0; i < features.length; i++) {\n feature = features[i];\n\n var geometry = feature.geometry;\n var coordinates = (geometry.coordinates) ? geometry.coordinates : null;\n\n if (!coordinates || !geometry) {\n return;\n }\n\n // Get per-feature style object, if provided\n if (typeof _style === 'function') {\n style = extend({}, GeoJSON.defaultStyle, _style(feature));\n // console.log(feature, style);\n }\n\n if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n coordinates = (PolygonLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n var converted = coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n });\n\n var point;\n var projected = converted.map((_coordinates) => {\n return _coordinates.map((ring) => {\n return ring.map((latlon) => {\n point = Geo.latLonToPoint(latlon)._subtract(originPoint);\n\n if (!pointScale) {\n pointScale = Geo.pointScale(latlon);\n }\n\n return point;\n });\n });\n });\n\n var polygon = {\n projected: projected,\n options: {\n pointScale: pointScale,\n style: style\n }\n };\n\n if (_properties) {\n polygon.properties = feature.properties;\n }\n\n polygons.push(polygon);\n }\n\n if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n coordinates = (PolylineLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n var converted = coordinates.map(_coordinates => {\n return _coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n\n var point;\n var projected = converted.map((_coordinates) => {\n return _coordinates.map((latlon) => {\n point = Geo.latLonToPoint(latlon)._subtract(originPoint);\n\n if (!pointScale) {\n pointScale = Geo.pointScale(latlon);\n }\n\n return point;\n });\n });\n\n var polyline = {\n projected: projected,\n options: {\n pointScale: pointScale,\n style: style\n }\n };\n\n if (_properties) {\n polyline.properties = feature.properties;\n }\n\n polylines.push(polyline);\n }\n\n if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n coordinates = (PointLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n var converted = coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n\n var point;\n var projected = converted.map((latlon) => {\n point = Geo.latLonToPoint(latlon)._subtract(originPoint);\n\n if (!pointScale) {\n pointScale = Geo.pointScale(latlon);\n }\n\n return point;\n });\n\n var point = {\n projected: projected,\n options: {\n pointGeometry: pointGeometry(feature),\n pointScale: pointScale,\n style: style\n }\n };\n\n if (_properties) {\n point.properties = feature.properties;\n }\n\n points.push(point);\n }\n };\n\n var polygonBufferPromises = [];\n var polylineBufferPromises = [];\n var pointBufferPromises = [];\n\n var polygon;\n for (var i = 0; i < polygons.length; i++) {\n polygon = polygons[i];\n polygonBufferPromises.push(PolygonLayer.SetBufferAttributes(polygon.projected, polygon.options));\n };\n\n var polyline;\n for (var i = 0; i < polylines.length; i++) {\n polyline = polylines[i];\n polylineBufferPromises.push(PolylineLayer.SetBufferAttributes(polyline.projected, polyline.options));\n };\n\n var point;\n for (var i = 0; i < points.length; i++) {\n point = points[i];\n pointBufferPromises.push(PointLayer.SetBufferAttributes(point.projected, point.options));\n };\n\n var data = {};\n var transferrables = [];\n\n // TODO: Make this work with polylines too\n // TODO: Make this so it's not a nest of promises\n GeoJSONWorkerLayer.ProcessPolygons(polygonBufferPromises, polygons, _properties).then((result) => {\n data.polygons = result.data;\n transferrables = transferrables.concat(result.transferrables);\n\n GeoJSONWorkerLayer.ProcessPolylines(polylineBufferPromises, polylines, _properties).then((result) => {\n data.polylines = result.data;\n transferrables = transferrables.concat(result.transferrables);\n\n GeoJSONWorkerLayer.ProcessPoints(pointBufferPromises, points, _properties).then((result) => {\n data.points = result.data;\n transferrables = transferrables.concat(result.transferrables);\n\n resolve({\n data: data,\n transferrables: transferrables\n });\n });\n });\n });\n });\n });\n }\n\n static ProcessPolygons(polygonPromises, polygons, _properties) {\n return new Promise((resolve, reject) => {\n Promise.all(polygonPromises).then((results) => {\n var transferrables = [];\n\n var positions = [];\n var normals = [];\n var colors = [];\n var tops = [];\n\n var outlinePositions = [];\n var outlineColors = [];\n\n var properties = [];\n\n var flats = [];\n var polygon;\n\n var result;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n polygon = polygons[i];\n\n // WORKERS: Making this a typed array will speed up transfer time\n // As things stand this adds on a few milliseconds\n flats.push(result.flat);\n\n // WORKERS: result.attributes is actually an array of polygons for each\n // feature, though the current logic isn't keeping these all together\n\n var attributes;\n for (var j = 0; j < result.attributes.length; j++) {\n attributes = result.attributes[j];\n\n positions.push(attributes.positions);\n normals.push(attributes.normals);\n colors.push(attributes.colors);\n tops.push(attributes.tops);\n\n if (_properties) {\n properties.push(Buffer.stringToUint8Array(JSON.stringify(polygon.properties)));\n }\n };\n\n var outlineAttributes;\n for (var j = 0; j < result.outlineAttributes.length; j++) {\n outlineAttributes = result.outlineAttributes[j];\n\n outlinePositions.push(outlineAttributes.positions);\n outlineColors.push(outlineAttributes.colors);\n };\n };\n\n var mergedAttributes = {\n positions: Buffer.mergeFloat32Arrays(positions),\n normals: Buffer.mergeFloat32Arrays(normals),\n colors: Buffer.mergeFloat32Arrays(colors),\n tops: Buffer.mergeFloat32Arrays(tops)\n };\n\n var mergedOutlineAttributes = {\n positions: Buffer.mergeFloat32Arrays(outlinePositions),\n colors: Buffer.mergeFloat32Arrays(outlineColors)\n };\n\n transferrables.push(mergedAttributes.positions[0].buffer);\n transferrables.push(mergedAttributes.positions[1].buffer);\n\n transferrables.push(mergedAttributes.normals[0].buffer);\n transferrables.push(mergedAttributes.normals[1].buffer);\n\n transferrables.push(mergedAttributes.colors[0].buffer);\n transferrables.push(mergedAttributes.colors[1].buffer);\n\n transferrables.push(mergedAttributes.tops[0].buffer);\n transferrables.push(mergedAttributes.tops[1].buffer);\n\n transferrables.push(mergedOutlineAttributes.positions[0].buffer);\n transferrables.push(mergedOutlineAttributes.positions[1].buffer);\n\n transferrables.push(mergedOutlineAttributes.colors[0].buffer);\n transferrables.push(mergedOutlineAttributes.colors[1].buffer);\n\n var mergedProperties;\n if (_properties) {\n mergedProperties = Buffer.mergeUint8Arrays(properties);\n\n transferrables.push(mergedProperties[0].buffer);\n transferrables.push(mergedProperties[1].buffer);\n }\n\n var output = {\n attributes: mergedAttributes,\n outlineAttributes: mergedOutlineAttributes,\n flats: flats\n };\n\n if (_properties) {\n output.properties = mergedProperties;\n }\n\n // TODO: Also return GeoJSON features that can be mapped to objects on\n // the main thread. Allow user to provide filter / toggles to only return\n // properties from the GeoJSON that they need (eg. don't return geometry,\n // or don't return properties.height)\n resolve({\n data: output,\n transferrables: transferrables\n });\n }).catch(reject);\n });\n }\n\n static ProcessPolylines(polylinePromises, polylines, _properties) {\n return new Promise((resolve, reject) => {\n Promise.all(polylinePromises).then((results) => {\n var transferrables = [];\n\n var positions = [];\n var colors = [];\n\n var properties = [];\n\n var flats = [];\n var polyline;\n\n var result;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n polyline = polylines[i];\n\n // WORKERS: Making this a typed array will speed up transfer time\n // As things stand this adds on a few milliseconds\n flats.push(result.flat);\n\n // WORKERS: result.attributes is actually an array of polygons for each\n // feature, though the current logic isn't keeping these all together\n\n var attributes;\n for (var j = 0; j < result.attributes.length; j++) {\n attributes = result.attributes[j];\n\n positions.push(attributes.positions);\n colors.push(attributes.colors);\n\n if (_properties) {\n properties.push(Buffer.stringToUint8Array(JSON.stringify(polyline.properties)));\n }\n };\n };\n\n var mergedAttributes = {\n positions: Buffer.mergeFloat32Arrays(positions),\n colors: Buffer.mergeFloat32Arrays(colors)\n };\n\n transferrables.push(mergedAttributes.positions[0].buffer);\n transferrables.push(mergedAttributes.positions[1].buffer);\n\n transferrables.push(mergedAttributes.colors[0].buffer);\n transferrables.push(mergedAttributes.colors[1].buffer);\n\n var mergedProperties;\n if (_properties) {\n mergedProperties = Buffer.mergeUint8Arrays(properties);\n\n transferrables.push(mergedProperties[0].buffer);\n transferrables.push(mergedProperties[1].buffer);\n }\n\n var output = {\n attributes: mergedAttributes,\n flats: flats\n };\n\n if (_properties) {\n output.properties = mergedProperties;\n }\n\n // TODO: Also return GeoJSON features that can be mapped to objects on\n // the main thread. Allow user to provide filter / toggles to only return\n // properties from the GeoJSON that they need (eg. don't return geometry,\n // or don't return properties.height)\n resolve({\n data: output,\n transferrables: transferrables\n });\n }).catch(reject);\n });\n }\n\n // TODO: Dedupe with ProcessPolygons as they are identical\n static ProcessPoints(pointPromises, points, _properties) {\n return new Promise((resolve, reject) => {\n Promise.all(pointPromises).then((results) => {\n var transferrables = [];\n\n var positions = [];\n var normals = [];\n var colors = [];\n\n var properties = [];\n\n var flats = [];\n var point;\n\n var result;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n point = points[i];\n\n // WORKERS: Making this a typed array will speed up transfer time\n // As things stand this adds on a few milliseconds\n flats.push(result.flat);\n\n // WORKERS: result.attributes is actually an array of polygons for each\n // feature, though the current logic isn't keeping these all together\n\n var attributes;\n for (var j = 0; j < result.attributes.length; j++) {\n attributes = result.attributes[j];\n\n positions.push(attributes.positions);\n normals.push(attributes.normals);\n colors.push(attributes.colors);\n\n if (_properties) {\n properties.push(Buffer.stringToUint8Array(JSON.stringify(polygon.properties)));\n }\n };\n };\n\n var mergedAttributes = {\n positions: Buffer.mergeFloat32Arrays(positions),\n normals: Buffer.mergeFloat32Arrays(normals),\n colors: Buffer.mergeFloat32Arrays(colors)\n };\n\n transferrables.push(mergedAttributes.positions[0].buffer);\n transferrables.push(mergedAttributes.positions[1].buffer);\n\n transferrables.push(mergedAttributes.normals[0].buffer);\n transferrables.push(mergedAttributes.normals[1].buffer);\n\n transferrables.push(mergedAttributes.colors[0].buffer);\n transferrables.push(mergedAttributes.colors[1].buffer);\n\n var mergedProperties;\n if (_properties) {\n mergedProperties = Buffer.mergeUint8Arrays(properties);\n\n transferrables.push(mergedProperties[0].buffer);\n transferrables.push(mergedProperties[1].buffer);\n }\n\n var output = {\n attributes: mergedAttributes,\n flats: flats\n };\n\n if (_properties) {\n output.properties = mergedProperties;\n }\n\n // TODO: Also return GeoJSON features that can be mapped to objects on\n // the main thread. Allow user to provide filter / toggles to only return\n // properties from the GeoJSON that they need (eg. don't return geometry,\n // or don't return properties.height)\n resolve({\n data: output,\n transferrables: transferrables\n });\n }).catch(reject);\n });\n }\n\n static ProcessGeoJSON(geojson, headers) {\n if (typeof geojson === 'string') {\n return GeoJSONWorkerLayer.RequestGeoJSON(geojson, headers);\n } else {\n return Promise.resolve(JSON.parse(Buffer.uint8ArrayToString(geojson)));\n }\n }\n\n static RequestGeoJSON(path, headers) {\n return reqwest({\n url: path,\n type: 'json',\n crossOrigin: true,\n headers: headers\n });\n }\n\n // Create and store mesh from buffer attributes\n //\n // Could make this an abstract method for each geometry layer\n _setPolygonMesh(attributes, attributeLengths, style, flat) {\n if (!this._world) {\n return Promise.reject();\n }\n\n return PolygonLayer.SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n }\n\n _setPolylineMesh(attributes, attributeLengths, style, flat) {\n if (!this._world) {\n return Promise.reject();\n }\n\n return PolylineLayer.SetMesh(attributes, attributeLengths, flat, style, this._options);\n }\n\n _setPointMesh(attributes, attributeLengths, style, flat) {\n if (!this._world) {\n return Promise.reject();\n }\n\n return PointLayer.SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n }\n\n // Set up and re-emit interaction events\n _addPicking(pickingId, properties) {\n this._world.on('pick-click-' + pickingId, (pickingId, point2d, point3d, intersects) => {\n this._world.emit('click', this, properties, point2d, point3d);\n });\n\n this._world.on('pick-hover-' + pickingId, (pickingId, point2d, point3d, intersects) => {\n this._world.emit('hover', this, properties, point2d, point3d);\n });\n }\n\n // TODO: Finish cleanup\n destroy() {\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default GeoJSONWorkerLayer;\n\nvar noNew = function(geojson, options) {\n return new GeoJSONWorkerLayer(geojson, options);\n};\n\nexport {noNew as geoJSONWorkerLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/GeoJSONWorkerLayer.js\n **/","/*!\n * Reqwest! A general purpose XHR connection manager\n * license MIT (c) Dustin Diaz 2015\n * https://github.com/ded/reqwest\n */\n\n!function (name, context, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(definition)\n else context[name] = definition()\n}('reqwest', this, function () {\n\n var context = this\n\n if ('window' in context) {\n var doc = document\n , byTag = 'getElementsByTagName'\n , head = doc[byTag]('head')[0]\n } else {\n var XHR2\n try {\n XHR2 = require('xhr2')\n } catch (ex) {\n throw new Error('Peer dependency `xhr2` required! Please npm install xhr2')\n }\n }\n\n\n var httpsRe = /^http/\n , protocolRe = /(^\\w+):\\/\\//\n , twoHundo = /^(20\\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\n , readyState = 'readyState'\n , contentType = 'Content-Type'\n , requestedWith = 'X-Requested-With'\n , uniqid = 0\n , callbackPrefix = 'reqwest_' + (+new Date())\n , lastValue // data stored by the most recent JSONP callback\n , xmlHttpRequest = 'XMLHttpRequest'\n , xDomainRequest = 'XDomainRequest'\n , noop = function () {}\n\n , isArray = typeof Array.isArray == 'function'\n ? Array.isArray\n : function (a) {\n return a instanceof Array\n }\n\n , defaultHeaders = {\n 'contentType': 'application/x-www-form-urlencoded'\n , 'requestedWith': xmlHttpRequest\n , 'accept': {\n '*': 'text/javascript, text/html, application/xml, text/xml, */*'\n , 'xml': 'application/xml, text/xml'\n , 'html': 'text/html'\n , 'text': 'text/plain'\n , 'json': 'application/json, text/javascript'\n , 'js': 'application/javascript, text/javascript'\n }\n }\n\n , xhr = function(o) {\n // is it x-domain\n if (o['crossOrigin'] === true) {\n var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null\n if (xhr && 'withCredentials' in xhr) {\n return xhr\n } else if (context[xDomainRequest]) {\n return new XDomainRequest()\n } else {\n throw new Error('Browser does not support cross-origin requests')\n }\n } else if (context[xmlHttpRequest]) {\n return new XMLHttpRequest()\n } else if (XHR2) {\n return new XHR2()\n } else {\n return new ActiveXObject('Microsoft.XMLHTTP')\n }\n }\n , globalSetupOptions = {\n dataFilter: function (data) {\n return data\n }\n }\n\n function succeed(r) {\n var protocol = protocolRe.exec(r.url)\n protocol = (protocol && protocol[1]) || context.location.protocol\n return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response\n }\n\n function handleReadyState(r, success, error) {\n return function () {\n // use _aborted to mitigate against IE err c00c023f\n // (can't read props on aborted request objects)\n if (r._aborted) return error(r.request)\n if (r._timedOut) return error(r.request, 'Request is aborted: timeout')\n if (r.request && r.request[readyState] == 4) {\n r.request.onreadystatechange = noop\n if (succeed(r)) success(r.request)\n else\n error(r.request)\n }\n }\n }\n\n function setHeaders(http, o) {\n var headers = o['headers'] || {}\n , h\n\n headers['Accept'] = headers['Accept']\n || defaultHeaders['accept'][o['type']]\n || defaultHeaders['accept']['*']\n\n var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData);\n // breaks cross-origin requests with legacy browsers\n if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']\n if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']\n for (h in headers)\n headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])\n }\n\n function setCredentials(http, o) {\n if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n http.withCredentials = !!o['withCredentials']\n }\n }\n\n function generalCallback(data) {\n lastValue = data\n }\n\n function urlappend (url, s) {\n return url + (/\\?/.test(url) ? '&' : '?') + s\n }\n\n function handleJsonp(o, fn, err, url) {\n var reqId = uniqid++\n , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key\n , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)\n , cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)')\n , match = url.match(cbreg)\n , script = doc.createElement('script')\n , loaded = 0\n , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1\n\n if (match) {\n if (match[3] === '?') {\n url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name\n } else {\n cbval = match[3] // provided callback func name\n }\n } else {\n url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em\n }\n\n context[cbval] = generalCallback\n\n script.type = 'text/javascript'\n script.src = url\n script.async = true\n if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n // need this for IE due to out-of-order onreadystatechange(), binding script\n // execution to an event listener gives us control over when the script\n // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n script.htmlFor = script.id = '_reqwest_' + reqId\n }\n\n script.onload = script.onreadystatechange = function () {\n if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {\n return false\n }\n script.onload = script.onreadystatechange = null\n script.onclick && script.onclick()\n // Call the user callback with the last value stored and clean up values and scripts.\n fn(lastValue)\n lastValue = undefined\n head.removeChild(script)\n loaded = 1\n }\n\n // Add the script to the DOM head\n head.appendChild(script)\n\n // Enable JSONP timeout\n return {\n abort: function () {\n script.onload = script.onreadystatechange = null\n err({}, 'Request is aborted: timeout', {})\n lastValue = undefined\n head.removeChild(script)\n loaded = 1\n }\n }\n }\n\n function getRequest(fn, err) {\n var o = this.o\n , method = (o['method'] || 'GET').toUpperCase()\n , url = typeof o === 'string' ? o : o['url']\n // convert non-string objects to query-string form unless o['processData'] is false\n , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')\n ? reqwest.toQueryString(o['data'])\n : (o['data'] || null)\n , http\n , sendWait = false\n\n // if we're working on a GET request and we have data then we should append\n // query string to end of URL and not post data\n if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n url = urlappend(url, data)\n data = null\n }\n\n if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)\n\n // get the xhr from the factory if passed\n // if the factory returns null, fall-back to ours\n http = (o.xhr && o.xhr(o)) || xhr(o)\n\n http.open(method, url, o['async'] === false ? false : true)\n setHeaders(http, o)\n setCredentials(http, o)\n if (context[xDomainRequest] && http instanceof context[xDomainRequest]) {\n http.onload = fn\n http.onerror = err\n // NOTE: see\n // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e\n http.onprogress = function() {}\n sendWait = true\n } else {\n http.onreadystatechange = handleReadyState(this, fn, err)\n }\n o['before'] && o['before'](http)\n if (sendWait) {\n setTimeout(function () {\n http.send(data)\n }, 200)\n } else {\n http.send(data)\n }\n return http\n }\n\n function Reqwest(o, fn) {\n this.o = o\n this.fn = fn\n\n init.apply(this, arguments)\n }\n\n function setType(header) {\n // json, javascript, text/plain, text/html, xml\n if (header === null) return undefined; //In case of no content-type.\n if (header.match('json')) return 'json'\n if (header.match('javascript')) return 'js'\n if (header.match('text')) return 'html'\n if (header.match('xml')) return 'xml'\n }\n\n function init(o, fn) {\n\n this.url = typeof o == 'string' ? o : o['url']\n this.timeout = null\n\n // whether request has been fulfilled for purpose\n // of tracking the Promises\n this._fulfilled = false\n // success handlers\n this._successHandler = function(){}\n this._fulfillmentHandlers = []\n // error handlers\n this._errorHandlers = []\n // complete (both success and fail) handlers\n this._completeHandlers = []\n this._erred = false\n this._responseArgs = {}\n\n var self = this\n\n fn = fn || function () {}\n\n if (o['timeout']) {\n this.timeout = setTimeout(function () {\n timedOut()\n }, o['timeout'])\n }\n\n if (o['success']) {\n this._successHandler = function () {\n o['success'].apply(o, arguments)\n }\n }\n\n if (o['error']) {\n this._errorHandlers.push(function () {\n o['error'].apply(o, arguments)\n })\n }\n\n if (o['complete']) {\n this._completeHandlers.push(function () {\n o['complete'].apply(o, arguments)\n })\n }\n\n function complete (resp) {\n o['timeout'] && clearTimeout(self.timeout)\n self.timeout = null\n while (self._completeHandlers.length > 0) {\n self._completeHandlers.shift()(resp)\n }\n }\n\n function success (resp) {\n var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE\n resp = (type !== 'jsonp') ? self.request : resp\n // use global data filter on response text\n var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)\n , r = filteredResponse\n try {\n resp.responseText = r\n } catch (e) {\n // can't assign this in IE<=8, just ignore\n }\n if (r) {\n switch (type) {\n case 'json':\n try {\n resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')')\n } catch (err) {\n return error(resp, 'Could not parse JSON in response', err)\n }\n break\n case 'js':\n resp = eval(r)\n break\n case 'html':\n resp = r\n break\n case 'xml':\n resp = resp.responseXML\n && resp.responseXML.parseError // IE trololo\n && resp.responseXML.parseError.errorCode\n && resp.responseXML.parseError.reason\n ? null\n : resp.responseXML\n break\n }\n }\n\n self._responseArgs.resp = resp\n self._fulfilled = true\n fn(resp)\n self._successHandler(resp)\n while (self._fulfillmentHandlers.length > 0) {\n resp = self._fulfillmentHandlers.shift()(resp)\n }\n\n complete(resp)\n }\n\n function timedOut() {\n self._timedOut = true\n self.request.abort()\n }\n\n function error(resp, msg, t) {\n resp = self.request\n self._responseArgs.resp = resp\n self._responseArgs.msg = msg\n self._responseArgs.t = t\n self._erred = true\n while (self._errorHandlers.length > 0) {\n self._errorHandlers.shift()(resp, msg, t)\n }\n complete(resp)\n }\n\n this.request = getRequest.call(this, success, error)\n }\n\n Reqwest.prototype = {\n abort: function () {\n this._aborted = true\n this.request.abort()\n }\n\n , retry: function () {\n init.call(this, this.o, this.fn)\n }\n\n /**\n * Small deviation from the Promises A CommonJs specification\n * http://wiki.commonjs.org/wiki/Promises/A\n */\n\n /**\n * `then` will execute upon successful requests\n */\n , then: function (success, fail) {\n success = success || function () {}\n fail = fail || function () {}\n if (this._fulfilled) {\n this._responseArgs.resp = success(this._responseArgs.resp)\n } else if (this._erred) {\n fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n } else {\n this._fulfillmentHandlers.push(success)\n this._errorHandlers.push(fail)\n }\n return this\n }\n\n /**\n * `always` will execute whether the request succeeds or fails\n */\n , always: function (fn) {\n if (this._fulfilled || this._erred) {\n fn(this._responseArgs.resp)\n } else {\n this._completeHandlers.push(fn)\n }\n return this\n }\n\n /**\n * `fail` will execute when the request fails\n */\n , fail: function (fn) {\n if (this._erred) {\n fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n } else {\n this._errorHandlers.push(fn)\n }\n return this\n }\n , 'catch': function (fn) {\n return this.fail(fn)\n }\n }\n\n function reqwest(o, fn) {\n return new Reqwest(o, fn)\n }\n\n // normalize newline variants according to spec -> CRLF\n function normalize(s) {\n return s ? s.replace(/\\r?\\n/g, '\\r\\n') : ''\n }\n\n function serial(el, cb) {\n var n = el.name\n , t = el.tagName.toLowerCase()\n , optCb = function (o) {\n // IE gives value=\"\" even where there is no value attribute\n // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273\n if (o && !o['disabled'])\n cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))\n }\n , ch, ra, val, i\n\n // don't serialize elements that are disabled or without a name\n if (el.disabled || !n) return\n\n switch (t) {\n case 'input':\n if (!/reset|button|image|file/i.test(el.type)) {\n ch = /checkbox/i.test(el.type)\n ra = /radio/i.test(el.type)\n val = el.value\n // WebKit gives us \"\" instead of \"on\" if a checkbox has no value, so correct it here\n ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))\n }\n break\n case 'textarea':\n cb(n, normalize(el.value))\n break\n case 'select':\n if (el.type.toLowerCase() === 'select-one') {\n optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)\n } else {\n for (i = 0; el.length && i < el.length; i++) {\n el.options[i].selected && optCb(el.options[i])\n }\n }\n break\n }\n }\n\n // collect up all form elements found from the passed argument elements all\n // the way down to child elements; pass a '' or form fields.\n // called with 'this'=callback to use for serial() on each element\n function eachFormElement() {\n var cb = this\n , e, i\n , serializeSubtags = function (e, tags) {\n var i, j, fa\n for (i = 0; i < tags.length; i++) {\n fa = e[byTag](tags[i])\n for (j = 0; j < fa.length; j++) serial(fa[j], cb)\n }\n }\n\n for (i = 0; i < arguments.length; i++) {\n e = arguments[i]\n if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)\n serializeSubtags(e, [ 'input', 'select', 'textarea' ])\n }\n }\n\n // standard query string style serialization\n function serializeQueryString() {\n return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))\n }\n\n // { 'name': 'value', ... } style serialization\n function serializeHash() {\n var hash = {}\n eachFormElement.apply(function (name, value) {\n if (name in hash) {\n hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])\n hash[name].push(value)\n } else hash[name] = value\n }, arguments)\n return hash\n }\n\n // [ { name: 'name', value: 'value' }, ... ] style serialization\n reqwest.serializeArray = function () {\n var arr = []\n eachFormElement.apply(function (name, value) {\n arr.push({name: name, value: value})\n }, arguments)\n return arr\n }\n\n reqwest.serialize = function () {\n if (arguments.length === 0) return ''\n var opt, fn\n , args = Array.prototype.slice.call(arguments, 0)\n\n opt = args.pop()\n opt && opt.nodeType && args.push(opt) && (opt = null)\n opt && (opt = opt.type)\n\n if (opt == 'map') fn = serializeHash\n else if (opt == 'array') fn = reqwest.serializeArray\n else fn = serializeQueryString\n\n return fn.apply(null, args)\n }\n\n reqwest.toQueryString = function (o, trad) {\n var prefix, i\n , traditional = trad || false\n , s = []\n , enc = encodeURIComponent\n , add = function (key, value) {\n // If value is a function, invoke it and return its value\n value = ('function' === typeof value) ? value() : (value == null ? '' : value)\n s[s.length] = enc(key) + '=' + enc(value)\n }\n // If an array was passed in, assume that it is an array of form elements.\n if (isArray(o)) {\n for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])\n } else {\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for (prefix in o) {\n if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)\n }\n }\n\n // spaces should be + according to spec\n return s.join('&').replace(/%20/g, '+')\n }\n\n function buildParams(prefix, obj, traditional, add) {\n var name, i, v\n , rbracket = /\\[\\]$/\n\n if (isArray(obj)) {\n // Serialize array item.\n for (i = 0; obj && i < obj.length; i++) {\n v = obj[i]\n if (traditional || rbracket.test(prefix)) {\n // Treat each array item as a scalar.\n add(prefix, v)\n } else {\n buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)\n }\n }\n } else if (obj && obj.toString() === '[object Object]') {\n // Serialize object item.\n for (name in obj) {\n buildParams(prefix + '[' + name + ']', obj[name], traditional, add)\n }\n\n } else {\n // Serialize scalar item.\n add(prefix, obj)\n }\n }\n\n reqwest.getcallbackPrefix = function () {\n return callbackPrefix\n }\n\n // jQuery and Zepto compatibility, differences can be remapped here so you can call\n // .ajax.compat(options, callback)\n reqwest.compat = function (o, fn) {\n if (o) {\n o['type'] && (o['method'] = o['type']) && delete o['type']\n o['dataType'] && (o['type'] = o['dataType'])\n o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']\n o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])\n }\n return new Reqwest(o, fn)\n }\n\n reqwest.ajaxSetup = function (options) {\n options = options || {}\n for (var k in options) {\n globalSetupOptions[k] = options[k]\n }\n }\n\n return reqwest\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/reqwest/reqwest.js\n ** module id = 23\n ** module chunks = 0\n **/","/*\n * GeoJSON helpers for handling data and generating objects\n */\n\nimport THREE from 'three';\nimport * as topojson from 'topojson';\nimport geojsonMerge from 'geojson-merge';\nimport earcut from 'earcut';\nimport extrudePolygon from './extrudePolygon';\n\n// TODO: Make it so height can be per-coordinate / point but connected together\n// as a linestring (eg. GPS points with an elevation at each point)\n//\n// This isn't really valid GeoJSON so perhaps something best left to an external\n// component for now, until a better approach can be considered\n//\n// See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html\n\n// Light and dark colours used for poor-mans AO gradient on object sides\nvar light = new THREE.Color(0xffffff);\nvar shadow = new THREE.Color(0x666666);\n\nvar GeoJSON = (function() {\n var defaultStyle = {\n color: '#ffffff',\n outline: false,\n outlineColor: '#000000',\n transparent: false,\n opacity: 1,\n blending: THREE.NormalBlending,\n height: 0,\n lineOpacity: 1,\n lineTransparent: false,\n lineColor: '#ffffff',\n lineWidth: 1,\n lineBlending: THREE.NormalBlending\n };\n\n // Attempts to merge together multiple GeoJSON Features or FeatureCollections\n // into a single FeatureCollection\n var collectFeatures = function(data, _topojson) {\n var collections = [];\n\n if (_topojson) {\n // TODO: Allow TopoJSON objects to be overridden as an option\n\n // If not overridden, merge all features from all objects\n for (var tk in data.objects) {\n collections.push(topojson.feature(data, data.objects[tk]));\n }\n\n return geojsonMerge(collections);\n } else {\n // If root doesn't have a type then let's see if there are features in the\n // next step down\n if (!data.type) {\n // TODO: Allow GeoJSON objects to be overridden as an option\n\n // If not overridden, merge all features from all objects\n for (var gk in data) {\n if (!data[gk].type) {\n continue;\n }\n\n collections.push(data[gk]);\n }\n\n return geojsonMerge(collections);\n } else if (Array.isArray(data)) {\n return geojsonMerge(data);\n } else {\n return data;\n }\n }\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var lineStringAttributes = function(coordinates, colour, height) {\n var _coords = [];\n var _colours = [];\n\n var nextCoord;\n\n // Connect coordinate with the next to make a pair\n //\n // LineSegments requires pairs of vertices so repeat the last point if\n // there's an odd number of vertices\n coordinates.forEach((coordinate, index) => {\n _colours.push([colour.r, colour.g, colour.b]);\n _coords.push([coordinate[0], height, coordinate[1]]);\n\n nextCoord = (coordinates[index + 1]) ? coordinates[index + 1] : coordinate;\n\n _colours.push([colour.r, colour.g, colour.b]);\n _coords.push([nextCoord[0], height, nextCoord[1]]);\n });\n\n return {\n vertices: _coords,\n colours: _colours\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var multiLineStringAttributes = function(coordinates, colour, height) {\n var _coords = [];\n var _colours = [];\n\n var result;\n coordinates.forEach(coordinate => {\n result = lineStringAttributes(coordinate, colour, height);\n\n result.vertices.forEach(coord => {\n _coords.push(coord);\n });\n\n result.colours.forEach(colour => {\n _colours.push(colour);\n });\n });\n\n return {\n vertices: _coords,\n colours: _colours\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var polygonAttributes = function(coordinates, colour, height) {\n var earcutData = _toEarcut(coordinates);\n\n var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions);\n\n var groupedVertices = [];\n for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) {\n groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions));\n }\n\n var extruded = extrudePolygon(groupedVertices, faces, {\n bottom: 0,\n top: height\n });\n\n var topColor = colour.clone().multiply(light);\n var bottomColor = colour.clone().multiply(shadow);\n\n var _vertices = extruded.positions;\n var _faces = [];\n var _colours = [];\n\n var _colour;\n extruded.top.forEach((face, fi) => {\n _colour = [];\n\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n\n _faces.push(face);\n _colours.push(_colour);\n });\n\n var allFlat = true;\n\n if (extruded.sides) {\n if (allFlat) {\n allFlat = false;\n }\n\n // Set up colours for every vertex with poor-mans AO on the sides\n extruded.sides.forEach((face, fi) => {\n _colour = [];\n\n // First face is always bottom-bottom-top\n if (fi % 2 === 0) {\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n // Reverse winding for the second face\n // top-top-bottom\n } else {\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n }\n\n _faces.push(face);\n _colours.push(_colour);\n });\n }\n\n // Skip bottom as there's no point rendering it\n // allFaces.push(extruded.faces);\n\n return {\n vertices: _vertices,\n faces: _faces,\n colours: _colours,\n flat: allFlat\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var _toEarcut = function(data) {\n var dim = data[0][0].length;\n var result = {vertices: [], holes: [], dimensions: dim};\n var holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) {\n result.vertices.push(data[i][j][d]);\n }\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n\n return result;\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var _triangulate = function(contour, holes, dim) {\n // console.time('earcut');\n\n var faces = earcut(contour, holes, dim);\n var result = [];\n\n for (i = 0, il = faces.length; i < il; i += 3) {\n result.push(faces.slice(i, i + 3));\n }\n\n // console.timeEnd('earcut');\n\n return result;\n };\n\n return {\n defaultStyle: defaultStyle,\n collectFeatures: collectFeatures,\n lineStringAttributes: lineStringAttributes,\n multiLineStringAttributes: multiLineStringAttributes,\n polygonAttributes: polygonAttributes\n };\n})();\n\nexport default GeoJSON;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/GeoJSON.js\n **/","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (factory((global.topojson = global.topojson || {})));\n}(this, (function (exports) { 'use strict';\n\nfunction noop() {}\n\nfunction transformAbsolute(transform) {\n if (!transform) return noop;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n point[0] = (x0 += point[0]) * kx + dx;\n point[1] = (y0 += point[1]) * ky + dy;\n };\n}\n\nfunction transformRelative(transform) {\n if (!transform) return noop;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n var x1 = Math.round((point[0] - dx) / kx),\n y1 = Math.round((point[1] - dy) / ky);\n point[0] = x1 - x0;\n point[1] = y1 - y0;\n x0 = x1;\n y0 = y1;\n };\n}\n\nfunction reverse(array, n) {\n var t, j = array.length, i = j - n;\n while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n}\n\nfunction bisect(a, x) {\n var lo = 0, hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (a[mid] < x) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction feature(topology, o) {\n return o.type === \"GeometryCollection\" ? {\n type: \"FeatureCollection\",\n features: o.geometries.map(function(o) { return feature$1(topology, o); })\n } : feature$1(topology, o);\n}\n\nfunction feature$1(topology, o) {\n var f = {\n type: \"Feature\",\n id: o.id,\n properties: o.properties || {},\n geometry: object(topology, o)\n };\n if (o.id == null) delete f.id;\n return f;\n}\n\nfunction object(topology, o) {\n var absolute = transformAbsolute(topology.transform),\n arcs = topology.arcs;\n\n function arc(i, points) {\n if (points.length) points.pop();\n for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {\n points.push(p = a[k].slice());\n absolute(p, k);\n }\n if (i < 0) reverse(points, n);\n }\n\n function point(p) {\n p = p.slice();\n absolute(p, 0);\n return p;\n }\n\n function line(arcs) {\n var points = [];\n for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n if (points.length < 2) points.push(points[0].slice());\n return points;\n }\n\n function ring(arcs) {\n var points = line(arcs);\n while (points.length < 4) points.push(points[0].slice());\n return points;\n }\n\n function polygon(arcs) {\n return arcs.map(ring);\n }\n\n function geometry(o) {\n var t = o.type;\n return t === \"GeometryCollection\" ? {type: t, geometries: o.geometries.map(geometry)}\n : t in geometryType ? {type: t, coordinates: geometryType[t](o)}\n : null;\n }\n\n var geometryType = {\n Point: function(o) { return point(o.coordinates); },\n MultiPoint: function(o) { return o.coordinates.map(point); },\n LineString: function(o) { return line(o.arcs); },\n MultiLineString: function(o) { return o.arcs.map(line); },\n Polygon: function(o) { return polygon(o.arcs); },\n MultiPolygon: function(o) { return o.arcs.map(polygon); }\n };\n\n return geometry(o);\n}\n\nfunction stitchArcs(topology, arcs) {\n var stitchedArcs = {},\n fragmentByStart = {},\n fragmentByEnd = {},\n fragments = [],\n emptyIndex = -1;\n\n // Stitch empty arcs first, since they may be subsumed by other arcs.\n arcs.forEach(function(i, j) {\n var arc = topology.arcs[i < 0 ? ~i : i], t;\n if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n }\n });\n\n arcs.forEach(function(i) {\n var e = ends(i),\n start = e[0],\n end = e[1],\n f, g;\n\n if (f = fragmentByEnd[start]) {\n delete fragmentByEnd[f.end];\n f.push(i);\n f.end = end;\n if (g = fragmentByStart[end]) {\n delete fragmentByStart[g.start];\n var fg = g === f ? f : f.concat(g);\n fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else if (f = fragmentByStart[end]) {\n delete fragmentByStart[f.start];\n f.unshift(i);\n f.start = start;\n if (g = fragmentByEnd[start]) {\n delete fragmentByEnd[g.end];\n var gf = g === f ? f : g.concat(f);\n fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else {\n f = [i];\n fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n }\n });\n\n function ends(i) {\n var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n else p1 = arc[arc.length - 1];\n return i < 0 ? [p1, p0] : [p0, p1];\n }\n\n function flush(fragmentByEnd, fragmentByStart) {\n for (var k in fragmentByEnd) {\n var f = fragmentByEnd[k];\n delete fragmentByStart[f.start];\n delete f.start;\n delete f.end;\n f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n fragments.push(f);\n }\n }\n\n flush(fragmentByEnd, fragmentByStart);\n flush(fragmentByStart, fragmentByEnd);\n arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\n return fragments;\n}\n\nfunction mesh(topology) {\n return object(topology, meshArcs.apply(this, arguments));\n}\n\nfunction meshArcs(topology, o, filter) {\n var arcs = [];\n\n function arc(i) {\n var j = i < 0 ? ~i : i;\n (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n }\n\n function line(arcs) {\n arcs.forEach(arc);\n }\n\n function polygon(arcs) {\n arcs.forEach(line);\n }\n\n function geometry(o) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(geometry);\n else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);\n }\n\n if (arguments.length > 1) {\n var geomsByArc = [],\n geom;\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs) { arcs.forEach(polygon); }\n };\n\n geometry(o);\n\n geomsByArc.forEach(arguments.length < 3\n ? function(geoms) { arcs.push(geoms[0].i); }\n : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n } else {\n for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);\n }\n\n return {type: \"MultiLineString\", arcs: stitchArcs(topology, arcs)};\n}\n\nfunction cartesianTriangleArea(triangle) {\n var a = triangle[0], b = triangle[1], c = triangle[2];\n return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));\n}\n\nfunction ring(ring) {\n var i = -1,\n n = ring.length,\n a,\n b = ring[n - 1],\n area = 0;\n\n while (++i < n) {\n a = b;\n b = ring[i];\n area += a[0] * b[1] - a[1] * b[0];\n }\n\n return area / 2;\n}\n\nfunction merge(topology) {\n return object(topology, mergeArcs.apply(this, arguments));\n}\n\nfunction mergeArcs(topology, objects) {\n var polygonsByArc = {},\n polygons = [],\n components = [];\n\n objects.forEach(function(o) {\n if (o.type === \"Polygon\") register(o.arcs);\n else if (o.type === \"MultiPolygon\") o.arcs.forEach(register);\n });\n\n function register(polygon) {\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n });\n });\n polygons.push(polygon);\n }\n\n function area(ring$$) {\n return Math.abs(ring(object(topology, {type: \"Polygon\", arcs: [ring$$]}).coordinates[0]));\n }\n\n polygons.forEach(function(polygon) {\n if (!polygon._) {\n var component = [],\n neighbors = [polygon];\n polygon._ = 1;\n components.push(component);\n while (polygon = neighbors.pop()) {\n component.push(polygon);\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n if (!polygon._) {\n polygon._ = 1;\n neighbors.push(polygon);\n }\n });\n });\n });\n }\n }\n });\n\n polygons.forEach(function(polygon) {\n delete polygon._;\n });\n\n return {\n type: \"MultiPolygon\",\n arcs: components.map(function(polygons) {\n var arcs = [], n;\n\n // Extract the exterior (unique) arcs.\n polygons.forEach(function(polygon) {\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n arcs.push(arc);\n }\n });\n });\n });\n\n // Stitch the arcs into one or more rings.\n arcs = stitchArcs(topology, arcs);\n\n // If more than one ring is returned,\n // at most one of these rings can be the exterior;\n // choose the one with the greatest absolute area.\n if ((n = arcs.length) > 1) {\n for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n if ((ki = area(arcs[i])) > k) {\n t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n }\n }\n }\n\n return arcs;\n })\n };\n}\n\nfunction neighbors(objects) {\n var indexesByArc = {}, // arc index -> array of object indexes\n neighbors = objects.map(function() { return []; });\n\n function line(arcs, i) {\n arcs.forEach(function(a) {\n if (a < 0) a = ~a;\n var o = indexesByArc[a];\n if (o) o.push(i);\n else indexesByArc[a] = [i];\n });\n }\n\n function polygon(arcs, i) {\n arcs.forEach(function(arc) { line(arc, i); });\n }\n\n function geometry(o, i) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n }\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n };\n\n objects.forEach(geometry);\n\n for (var i in indexesByArc) {\n for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n for (var k = j + 1; k < m; ++k) {\n var ij = indexes[j], ik = indexes[k], n;\n if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);\n if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);\n }\n }\n }\n\n return neighbors;\n}\n\nfunction compareArea(a, b) {\n return a[1][2] - b[1][2];\n}\n\nfunction minAreaHeap() {\n var heap = {},\n array = [],\n size = 0;\n\n heap.push = function(object) {\n up(array[object._ = size] = object, size++);\n return size;\n };\n\n heap.pop = function() {\n if (size <= 0) return;\n var removed = array[0], object;\n if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);\n return removed;\n };\n\n heap.remove = function(removed) {\n var i = removed._, object;\n if (array[i] !== removed) return; // invalid request\n if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);\n return i;\n };\n\n function up(object, i) {\n while (i > 0) {\n var j = ((i + 1) >> 1) - 1,\n parent = array[j];\n if (compareArea(object, parent) >= 0) break;\n array[parent._ = i] = parent;\n array[object._ = i = j] = object;\n }\n }\n\n function down(object, i) {\n while (true) {\n var r = (i + 1) << 1,\n l = r - 1,\n j = i,\n child = array[j];\n if (l < size && compareArea(array[l], child) < 0) child = array[j = l];\n if (r < size && compareArea(array[r], child) < 0) child = array[j = r];\n if (j === i) break;\n array[child._ = i] = child;\n array[object._ = i = j] = object;\n }\n }\n\n return heap;\n}\n\nfunction presimplify(topology, triangleArea) {\n var absolute = transformAbsolute(topology.transform),\n relative = transformRelative(topology.transform),\n heap = minAreaHeap();\n\n if (!triangleArea) triangleArea = cartesianTriangleArea;\n\n topology.arcs.forEach(function(arc) {\n var triangles = [],\n maxArea = 0,\n triangle,\n i,\n n,\n p;\n\n // To store each point’s effective area, we create a new array rather than\n // extending the passed-in point to workaround a Chrome/V8 bug (getting\n // stuck in smi mode). For midpoints, the initial effective area of\n // Infinity will be computed in the next step.\n for (i = 0, n = arc.length; i < n; ++i) {\n p = arc[i];\n absolute(arc[i] = [p[0], p[1], Infinity], i);\n }\n\n for (i = 1, n = arc.length - 1; i < n; ++i) {\n triangle = arc.slice(i - 1, i + 2);\n triangle[1][2] = triangleArea(triangle);\n triangles.push(triangle);\n heap.push(triangle);\n }\n\n for (i = 0, n = triangles.length; i < n; ++i) {\n triangle = triangles[i];\n triangle.previous = triangles[i - 1];\n triangle.next = triangles[i + 1];\n }\n\n while (triangle = heap.pop()) {\n var previous = triangle.previous,\n next = triangle.next;\n\n // If the area of the current point is less than that of the previous point\n // to be eliminated, use the latter's area instead. This ensures that the\n // current point cannot be eliminated without eliminating previously-\n // eliminated points.\n if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;\n else maxArea = triangle[1][2];\n\n if (previous) {\n previous.next = next;\n previous[2] = triangle[2];\n update(previous);\n }\n\n if (next) {\n next.previous = previous;\n next[0] = triangle[0];\n update(next);\n }\n }\n\n arc.forEach(relative);\n });\n\n function update(triangle) {\n heap.remove(triangle);\n triangle[1][2] = triangleArea(triangle);\n heap.push(triangle);\n }\n\n return topology;\n}\n\nvar version = \"1.6.27\";\n\nexports.version = version;\nexports.mesh = mesh;\nexports.meshArcs = meshArcs;\nexports.merge = merge;\nexports.mergeArcs = mergeArcs;\nexports.feature = feature;\nexports.neighbors = neighbors;\nexports.presimplify = presimplify;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/topojson/build/topojson.js\n ** module id = 26\n ** module chunks = 0\n **/","var normalize = require('geojson-normalize');\n\nmodule.exports = function(inputs) {\n return {\n type: 'FeatureCollection',\n features: inputs.reduce(function(memo, input) {\n return memo.concat(normalize(input).features);\n }, [])\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/geojson-merge/index.js\n ** module id = 27\n ** module chunks = 0\n **/","module.exports = normalize;\n\nvar types = {\n Point: 'geometry',\n MultiPoint: 'geometry',\n LineString: 'geometry',\n MultiLineString: 'geometry',\n Polygon: 'geometry',\n MultiPolygon: 'geometry',\n GeometryCollection: 'geometry',\n Feature: 'feature',\n FeatureCollection: 'featurecollection'\n};\n\n/**\n * Normalize a GeoJSON feature into a FeatureCollection.\n *\n * @param {object} gj geojson data\n * @returns {object} normalized geojson data\n */\nfunction normalize(gj) {\n if (!gj || !gj.type) return null;\n var type = types[gj.type];\n if (!type) return null;\n\n if (type === 'geometry') {\n return {\n type: 'FeatureCollection',\n features: [{\n type: 'Feature',\n properties: {},\n geometry: gj\n }]\n };\n } else if (type === 'feature') {\n return {\n type: 'FeatureCollection',\n features: [gj]\n };\n } else if (type === 'featurecollection') {\n return gj;\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/geojson-normalize/index.js\n ** module id = 28\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = earcut;\n\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode) return triangles;\n\n var minX, minY, maxX, maxY, x, y, size;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and size are later used to transform coords into integers for z-order calculation\n size = Math.max(maxX - minX, maxY - minY);\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) return null;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && size) indexCurve(ear, minX, minY, size);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertice leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(ear, triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, size);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, size) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, size),\n maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\n // first look for points inside the triangle in increasing z-order\n var p = ear.nextZ;\n\n while (p && p.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.nextZ;\n }\n\n // then look for points in decreasing z-order\n p = ear.prevZ;\n\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return p;\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, size);\n earcutLinked(c, triangles, dim, minX, minY, size);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m.next;\n\n while (p !== stop) {\n if (hx >= p.x && p.x >= mx &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n }\n\n return m;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, size) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize === 0) {\n e = q;\n q = q.nextZ;\n qSize--;\n } else if (qSize === 0 || !q) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else if (p.z <= q.z) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and size of the data bounding box\nfunction zOrder(x, y, minX, minY, size) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) / size;\n y = 32767 * (y - minY) / size;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n if ((equals(p1, q1) && equals(p2, q2)) ||\n (equals(p1, q2) && equals(p2, q1))) return true;\n return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertice index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertice nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/earcut/src/earcut.js\n ** module id = 29\n ** module chunks = 0\n **/","/*\n * Extrude a polygon given its vertices and triangulated faces\n *\n * Based on:\n * https://github.com/freeman-lab/extrude\n */\n\nimport extend from 'lodash.assign';\n\nvar extrudePolygon = function(points, faces, _options) {\n var defaults = {\n top: 1,\n bottom: 0,\n closed: true\n };\n\n var options = extend({}, defaults, _options);\n\n var n = points.length;\n var positions;\n var cells;\n var topCells;\n var bottomCells;\n var sideCells;\n\n // If bottom and top values are identical then return the flat shape\n (options.top === options.bottom) ? flat() : full();\n\n function flat() {\n positions = points.map(function(p) { return [p[0], options.top, p[1]]; });\n cells = faces;\n topCells = faces;\n }\n\n function full() {\n positions = [];\n points.forEach(function(p) { positions.push([p[0], options.top, p[1]]); });\n points.forEach(function(p) { positions.push([p[0], options.bottom, p[1]]); });\n\n cells = [];\n for (var i = 0; i < n; i++) {\n if (i === (n - 1)) {\n cells.push([i + n, n, i]);\n cells.push([0, i, n]);\n } else {\n cells.push([i + n, i + n + 1, i]);\n cells.push([i + 1, i, i + n + 1]);\n }\n }\n\n sideCells = [].concat(cells);\n\n if (options.closed) {\n var top = faces;\n var bottom = top.map(function(p) { return p.map(function(v) { return v + n; }); });\n bottom = bottom.map(function(p) { return [p[0], p[2], p[1]]; });\n cells = cells.concat(top).concat(bottom);\n\n topCells = top;\n bottomCells = bottom;\n }\n }\n\n return {\n positions: positions,\n faces: cells,\n top: topCells,\n bottom: bottomCells,\n sides: sideCells\n };\n};\n\nexport default extrudePolygon;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/extrudePolygon.js\n **/","import WorkerPool from './WorkerPool';\n\nvar Worker = (function() {\n var _maxWorkers = 2;\n var pool;\n\n var createWorkers = function(maxWorkers, workerScript) {\n pool = new WorkerPool({\n numThreads: (maxWorkers) ? maxWorkers : _maxWorkers,\n workerScript: (workerScript) ? workerScript : 'vizicities-worker.js'\n });\n\n return pool.createWorkers();\n };\n\n var exec = function(method, args, transferrables) {\n return pool.exec(method, args, transferrables);\n };\n\n return {\n createWorkers: createWorkers,\n exec: exec\n };\n})();\n\nexport default Worker;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Worker.js\n **/","import WorkerPoolWorker from './WorkerPoolWorker';\n\nconst DEBUG = false;\n\nclass WorkerPool {\n constructor(options) {\n this.numThreads = options.numThreads || 2;\n this.workerScript = options.workerScript;\n\n this.workers = [];\n this.tasks = [];\n }\n\n createWorkers() {\n return new Promise((resolve, reject) => {\n var workerPromises = [];\n\n for (var i = 0; i < this.numThreads; i++) {\n workerPromises.push(this.createWorker());\n }\n\n Promise.all(workerPromises).then(() => {\n if (DEBUG) { console.log('All workers ready', performance.now()); }\n resolve();\n }).catch(reject);\n });\n }\n\n createWorker() {\n return new Promise((resolve, reject) => {\n // Initialise worker\n var worker = new WorkerPoolWorker({\n workerScript: this.workerScript\n });\n\n // Start worker and wait for it to be ready\n return worker.start().then(() => {\n if (DEBUG) { console.log('Worker ready', performance.now()); }\n\n // Add worker to pool\n this.workers.push(worker);\n\n resolve();\n }).catch(reject);\n });\n }\n\n getFreeWorker() {\n return this.workers.find((worker) => {\n return !worker.busy;\n });\n }\n\n // Execute task on a worker\n exec(method, args, transferrables) {\n var deferred = Promise.deferred();\n\n // Create task\n var task = {\n method: method,\n args: args,\n transferrables: transferrables,\n deferred: deferred\n };\n\n // Add task to queue\n this.tasks.push(task);\n\n // Trigger task processing\n this.processTasks();\n\n // Return task promise\n return task.deferred.promise;\n }\n\n processTasks() {\n if (DEBUG) { console.log('Processing tasks'); }\n\n if (this.tasks.length === 0) {\n return;\n }\n\n // Find free worker\n var worker = this.getFreeWorker();\n\n if (!worker) {\n if (DEBUG) { console.log('No workers free'); }\n return;\n }\n\n // Get oldest task\n var task = this.tasks.shift();\n\n // Execute task on worker\n worker.exec(task.method, task.args, task.transferrables).then((result) => {\n // Trigger task processing\n this.processTasks();\n\n // Return result in deferred task promise\n task.deferred.resolve(result);\n });\n }\n}\n\nexport default WorkerPool;\n\n// Quick shim to create deferred native promises\nPromise.deferred = function() {\n var result = {};\n\n result.promise = new Promise((resolve, reject) => {\n result.resolve = resolve;\n result.reject = reject;\n });\n\n return result;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/WorkerPool.js\n **/","const DEBUG = false;\n\nclass WorkerPoolWorker {\n constructor(options) {\n this.workerScript = options.workerScript;\n\n this.ready = false;\n this.busy = false;\n this.deferred = null;\n }\n\n start() {\n return new Promise((resolve, reject) => {\n this.worker = new Worker(this.workerScript);\n\n var onStartup = (event) => {\n if (!event.data || event.data.type !== 'startup') {\n reject();\n return;\n }\n\n this.ready = true;\n\n // Remove temporary message handler\n this.worker.removeEventListener('message', onStartup);\n\n // Set up listener to respond to normal events now\n this.worker.addEventListener('message', (event) => {\n this.onMessage(event);\n });\n\n // Resolve once worker is ready\n resolve();\n };\n\n // Set up temporary event listener for warmup\n this.worker.addEventListener('message', onStartup);\n });\n }\n\n exec(method, args, transferrables) {\n if (DEBUG) { console.log('Execute', method, args, transferrables); }\n\n var deferred = Promise.deferred();\n\n this.busy = true;\n this.deferred = deferred;\n\n this.worker.postMessage({\n method: method,\n args: args\n }, transferrables);\n\n return deferred.promise;\n }\n\n onMessage(event) {\n console.log('Message received from worker', performance.now());\n\n this.busy = false;\n\n if (!event.data || event.data.type === 'error' || event.data.type !== 'result') {\n this.deferred.reject(event.data.payload);\n return;\n }\n\n this.deferred.resolve(event.data.payload);\n }\n}\n\nexport default WorkerPoolWorker;\n\n// Quick shim to create deferred native promises\nPromise.deferred = function() {\n var result = {};\n\n result.promise = new Promise((resolve, reject) => {\n result.resolve = resolve;\n result.reject = reject;\n });\n\n return result;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/WorkerPoolWorker.js\n **/","/*\n * BufferGeometry helpers\n */\n\nimport THREE from 'three';\n\nvar Buffer = (function() {\n // Merge TypedArrays of the same type\n // Returns merged array as well as indexes for splitting the array\n var mergeFloat32Arrays = function(arrays) {\n var size = 0;\n var map = new Int32Array(arrays.length * 2);\n\n var lastIndex = 0;\n var length;\n\n // Find size of each array\n arrays.forEach((_array, index) => {\n length = _array.length;\n size += length;\n map.set([lastIndex, lastIndex + length], index * 2);\n lastIndex += length;\n });\n\n // Create a new array of total size\n var mergedArray = new Float32Array(size);\n\n // Add each array to the new array\n arrays.forEach((_array, index) => {\n mergedArray.set(_array, map[index * 2]);\n });\n\n return [\n mergedArray,\n map\n ];\n };\n\n var splitFloat32Array = function(data) {\n var arr = data[0];\n var map = data[1];\n\n var start;\n var arrays = [];\n\n // Iterate over map\n for (var i = 0; i < map.length / 2; i++) {\n start = i * 2;\n arrays.push(arr.subarray(map[start], map[start + 1]));\n }\n\n return arrays;\n };\n\n // TODO: Create a generic method that can work for any typed array\n var mergeUint8Arrays = function(arrays) {\n var size = 0;\n var map = new Int32Array(arrays.length * 2);\n\n var lastIndex = 0;\n var length;\n\n // Find size of each array\n arrays.forEach((_array, index) => {\n length = _array.length;\n size += length;\n map.set([lastIndex, lastIndex + length], index * 2);\n lastIndex += length;\n });\n\n // Create a new array of total size\n var mergedArray = new Uint8Array(size);\n\n // Add each array to the new array\n arrays.forEach((_array, index) => {\n mergedArray.set(_array, map[index * 2]);\n });\n\n return [\n mergedArray,\n map\n ];\n };\n\n // TODO: Dedupe with splitFloat32Array\n var splitUint8Array = function(data) {\n var arr = data[0];\n var map = data[1];\n\n var start;\n var arrays = [];\n\n // Iterate over map\n for (var i = 0; i < map.length / 2; i++) {\n start = i * 2;\n arrays.push(arr.subarray(map[start], map[start + 1]));\n }\n\n return arrays;\n };\n\n // Merge multiple attribute objects into a single attribute object\n //\n // Attribute objects must all use the same attribute keys\n var mergeAttributes = function(attributes) {\n var lengths = {};\n\n // Find array lengths\n attributes.forEach(_attributes => {\n for (var k in _attributes) {\n if (!lengths[k]) {\n lengths[k] = 0;\n }\n\n lengths[k] += _attributes[k].length;\n }\n });\n\n var mergedAttributes = {};\n\n // Set up arrays to merge into\n for (var k in lengths) {\n mergedAttributes[k] = new Float32Array(lengths[k]);\n }\n\n var lastLengths = {};\n\n attributes.forEach(_attributes => {\n for (var k in _attributes) {\n if (!lastLengths[k]) {\n lastLengths[k] = 0;\n }\n\n mergedAttributes[k].set(_attributes[k], lastLengths[k]);\n\n lastLengths[k] += _attributes[k].length;\n }\n });\n\n return mergedAttributes;\n };\n\n var createLineGeometry = function(lines, offset) {\n var geometry = new THREE.BufferGeometry();\n\n var vertices = new Float32Array(lines.verticesCount * 3);\n var colours = new Float32Array(lines.verticesCount * 3);\n\n var pickingIds;\n if (lines.pickingIds) {\n // One component per vertex (1)\n pickingIds = new Float32Array(lines.verticesCount);\n }\n\n var _vertices;\n var _colour;\n var _pickingId;\n\n var lastIndex = 0;\n\n for (var i = 0; i < lines.vertices.length; i++) {\n _vertices = lines.vertices[i];\n _colour = lines.colours[i];\n\n if (pickingIds) {\n _pickingId = lines.pickingIds[i];\n }\n\n for (var j = 0; j < _vertices.length; j++) {\n var ax = _vertices[j][0] + offset.x;\n var ay = _vertices[j][1];\n var az = _vertices[j][2] + offset.y;\n\n var c1 = _colour[j];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n }\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(colours, 3));\n\n if (pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n return geometry;\n };\n\n // TODO: Make picking IDs optional\n var createGeometry = function(attributes, offset) {\n var geometry = new THREE.BufferGeometry();\n\n // Three components per vertex per face (3 x 3 = 9)\n var vertices = new Float32Array(attributes.facesCount * 9);\n var normals = new Float32Array(attributes.facesCount * 9);\n var colours = new Float32Array(attributes.facesCount * 9);\n\n var pickingIds;\n if (attributes.pickingIds) {\n // One component per vertex per face (1 x 3 = 3)\n pickingIds = new Float32Array(attributes.facesCount * 3);\n }\n\n var pA = new THREE.Vector3();\n var pB = new THREE.Vector3();\n var pC = new THREE.Vector3();\n\n var cb = new THREE.Vector3();\n var ab = new THREE.Vector3();\n\n var index;\n var _faces;\n var _vertices;\n var _colour;\n var _pickingId;\n var lastIndex = 0;\n for (var i = 0; i < attributes.faces.length; i++) {\n _faces = attributes.faces[i];\n _vertices = attributes.vertices[i];\n _colour = attributes.colours[i];\n\n if (pickingIds) {\n _pickingId = attributes.pickingIds[i];\n }\n\n for (var j = 0; j < _faces.length; j++) {\n // Array of vertex indexes for the face\n index = _faces[j][0];\n\n var ax = _vertices[index][0] + offset.x;\n var ay = _vertices[index][1];\n var az = _vertices[index][2] + offset.y;\n\n var c1 = _colour[j][0];\n\n index = _faces[j][1];\n\n var bx = _vertices[index][0] + offset.x;\n var by = _vertices[index][1];\n var bz = _vertices[index][2] + offset.y;\n\n var c2 = _colour[j][1];\n\n index = _faces[j][2];\n\n var cx = _vertices[index][0] + offset.x;\n var cy = _vertices[index][1];\n var cz = _vertices[index][2] + offset.y;\n\n var c3 = _colour[j][2];\n\n // Flat face normals\n // From: http://threejs.org/examples/webgl_buffergeometry.html\n pA.set(ax, ay, az);\n pB.set(bx, by, bz);\n pC.set(cx, cy, cz);\n\n cb.subVectors(pC, pB);\n ab.subVectors(pA, pB);\n cb.cross(ab);\n\n cb.normalize();\n\n var nx = cb.x;\n var ny = cb.y;\n var nz = cb.z;\n\n vertices[lastIndex * 9 + 0] = ax;\n vertices[lastIndex * 9 + 1] = ay;\n vertices[lastIndex * 9 + 2] = az;\n\n normals[lastIndex * 9 + 0] = nx;\n normals[lastIndex * 9 + 1] = ny;\n normals[lastIndex * 9 + 2] = nz;\n\n colours[lastIndex * 9 + 0] = c1[0];\n colours[lastIndex * 9 + 1] = c1[1];\n colours[lastIndex * 9 + 2] = c1[2];\n\n vertices[lastIndex * 9 + 3] = bx;\n vertices[lastIndex * 9 + 4] = by;\n vertices[lastIndex * 9 + 5] = bz;\n\n normals[lastIndex * 9 + 3] = nx;\n normals[lastIndex * 9 + 4] = ny;\n normals[lastIndex * 9 + 5] = nz;\n\n colours[lastIndex * 9 + 3] = c2[0];\n colours[lastIndex * 9 + 4] = c2[1];\n colours[lastIndex * 9 + 5] = c2[2];\n\n vertices[lastIndex * 9 + 6] = cx;\n vertices[lastIndex * 9 + 7] = cy;\n vertices[lastIndex * 9 + 8] = cz;\n\n normals[lastIndex * 9 + 6] = nx;\n normals[lastIndex * 9 + 7] = ny;\n normals[lastIndex * 9 + 8] = nz;\n\n colours[lastIndex * 9 + 6] = c3[0];\n colours[lastIndex * 9 + 7] = c3[1];\n colours[lastIndex * 9 + 8] = c3[2];\n\n if (pickingIds) {\n pickingIds[lastIndex * 3 + 0] = _pickingId;\n pickingIds[lastIndex * 3 + 1] = _pickingId;\n pickingIds[lastIndex * 3 + 2] = _pickingId;\n }\n\n lastIndex++;\n }\n }\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(colours, 3));\n\n if (pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n return geometry;\n };\n\n var textEncoder = new TextEncoder('utf-8');\n var textDecoder = new TextDecoder('utf-8');\n\n var stringToUint8Array = function(str) {\n return textEncoder.encode(str);\n };\n\n var uint8ArrayToString = function(ab) {\n return textDecoder.decode(ab);\n };\n\n return {\n mergeFloat32Arrays: mergeFloat32Arrays,\n splitFloat32Array: splitFloat32Array,\n mergeUint8Arrays: mergeUint8Arrays,\n splitUint8Array: splitUint8Array,\n mergeAttributes: mergeAttributes,\n createLineGeometry: createLineGeometry,\n createGeometry: createGeometry,\n stringToUint8Array: stringToUint8Array,\n uint8ArrayToString: uint8ArrayToString\n };\n})();\n\nexport default Buffer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Buffer.js\n **/","var Stringify = (function() {\n var functionToString = function(f) {\n return f.toString();\n };\n\n // Based on https://github.com/tangrams/tangram/blob/2a31893c814cf15d5077f87ffa10af20160716b9/src/utils/utils.js#L245\n var stringToFunction = function(str) {\n if (typeof str === 'string' && str.match(/^\\s*function\\s*\\w*\\s*\\([\\s\\S]*\\)\\s*\\{[\\s\\S]*\\}/m) != null) {\n var f;\n\n try {\n eval('f = ' + str);\n return f;\n } catch (err) {\n return str;\n }\n }\n };\n\n return {\n functionToString: functionToString,\n stringToFunction: stringToFunction\n };\n})();\n\nexport default Stringify;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Stringify.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\n// TODO: Allow _setBufferAttributes to use a custom function passed in to\n// generate a custom mesh\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Geo from '../../geo/Geo';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport earcut from 'earcut';\nimport extrudePolygon from '../../util/extrudePolygon';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PolygonLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n polygonMaterial: null,\n onPolygonMesh: null,\n onBufferAttributes: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n color: '#ffffff',\n transparent: false,\n opacity: 1,\n blending: THREE.NormalBlending,\n height: 0\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of polygons so it's easy to support\n // MultiPolygon features (a single polygon would be a MultiPolygon with a\n // single polygon in the array)\n this._coordinates = (PolygonLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n PolygonLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {\n this._bufferAttributes = Buffer.mergeAttributes(result.attributes);\n\n if (result.outlineAttributes.length > 0) {\n this._outlineBufferAttributes = Buffer.mergeAttributes(result.outlineAttributes);\n }\n\n this._flat = result.flat;\n\n if (this.isOutput()) {\n var attributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3,\n tops: 1\n };\n\n if (this._options.interactive) {\n attributeLengths.pickingIds = 1;\n }\n\n var style = this._options.style;\n\n // Set mesh if not merging elsewhere\n PolygonLayer.SetMesh(this._bufferAttributes, attributeLengths, this._flat, style, this._options, this._world._environment._skybox).then((result) => {\n // Output mesh\n this.add(result.mesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n result.attributes = null;\n result.outlineAttributes = null;\n result = null;\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Return center of polygon as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n //\n // TODO: Find proper center position instead of returning first coordinate\n // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15\n getCenter() {\n return this._center;\n }\n\n // Return polygon bounds in geographic coordinates\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n // Create and store reference to THREE.BufferAttribute data for this layer\n static SetBufferAttributes(coordinates, options) {\n return new Promise((resolve) => {\n var height = 0;\n\n // Convert height into world units\n if (options.style.height && options.style.height !== 0) {\n height = Geo.metresToWorld(options.style.height, options.pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(options.style.color);\n\n // Light and dark colours used for poor-mans AO gradient on object sides\n var light = new THREE.Color(0xffffff);\n var shadow = new THREE.Color(0x666666);\n\n var flat = true;\n\n var outlineAttributes = [];\n\n // For each polygon\n var attributes = coordinates.map(_coordinates => {\n // Convert coordinates to earcut format\n var _earcut = PolygonLayer.ToEarcut(_coordinates);\n\n // Triangulate faces using earcut\n var faces = PolygonLayer.Triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions);\n\n var groupedVertices = [];\n for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) {\n groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions));\n }\n\n var extruded = extrudePolygon(groupedVertices, faces, {\n bottom: 0,\n top: height\n });\n\n var topColor = colour.clone().multiply(light);\n var bottomColor = colour.clone().multiply(shadow);\n\n var _vertices = extruded.positions;\n var _faces = [];\n var _colours = [];\n var _tops = [];\n\n var _colour;\n extruded.top.forEach((face, fi) => {\n _colour = [];\n\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n\n _tops.push([true, true, true]);\n\n _faces.push(face);\n _colours.push(_colour);\n });\n\n if (extruded.sides) {\n flat = false;\n\n // Set up colours for every vertex with poor-mans AO on the sides\n extruded.sides.forEach((face, fi) => {\n _colour = [];\n\n // First face is always bottom-bottom-top\n if (fi % 2 === 0) {\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n\n _tops.push([false, false, true]);\n // Reverse winding for the second face\n // top-top-bottom\n } else {\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\n _tops.push([true, true, false]);\n }\n\n _faces.push(face);\n _colours.push(_colour);\n });\n }\n\n // Skip bottom as there's no point rendering it\n // allFaces.push(extruded.faces);\n\n var polygon = {\n vertices: _vertices,\n faces: _faces,\n colours: _colours,\n tops: _tops,\n facesCount: _faces.length\n };\n\n if (options.style.outline) {\n var outlineColour = new THREE.Color();\n outlineColour.set(options.style.outlineColor || 0x000000);\n\n outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour));\n }\n\n if (options.interactive && options.pickingId) {\n // Inject picking ID\n polygon.pickingId = options.pickingId;\n }\n\n // Convert polygon representation to proper attribute arrays\n return PolygonLayer.ToAttributes(polygon);\n });\n\n resolve({\n attributes: attributes,\n outlineAttributes: outlineAttributes,\n flat: flat\n });\n });\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n getOutlineBufferAttributes() {\n return this._outlineBufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n this._outlineBufferAttributes = null;\n }\n\n // Threshold angle is currently in rads\n static Set2DOutline(coordinates, colour) {\n var _vertices = [];\n\n coordinates.forEach((ring) => {\n var _ring = ring.map((coordinate) => {\n return [coordinate.x, 0, coordinate.y];\n });\n\n // Add in duplicate vertices for line segments to work\n var verticeCount = _ring.length;\n var first = true;\n while (--verticeCount) {\n if (first || verticeCount === 0) {\n first = false;\n continue;\n }\n\n _ring.splice(verticeCount + 1, 0, _ring[verticeCount]);\n }\n\n _vertices = _vertices.concat(_ring);\n });\n\n _colour = [colour.r, colour.g, colour.b];\n\n var vertices = new Float32Array(_vertices.length * 3);\n var colours = new Float32Array(_vertices.length * 3);\n\n var lastIndex = 0;\n\n for (var i = 0; i < _vertices.length; i++) {\n var ax = _vertices[i][0];\n var ay = _vertices[i][1];\n var az = _vertices[i][2];\n\n var c1 = _colour;\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n lastIndex++;\n }\n\n var attributes = {\n positions: vertices,\n colors: colours\n };\n\n return attributes;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n static SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n var geometry = new THREE.BufferGeometry();\n\n for (var key in attributes) {\n geometry.addAttribute(key.slice(0, -1), new THREE.BufferAttribute(attributes[key], attributeLengths[key]));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (options.polygonMaterial && options.polygonMaterial instanceof THREE.Material) {\n material = options.polygonMaterial;\n } else if (!skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof options.onPolygonMesh === 'function') {\n mesh = options.onPolygonMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n }\n\n if (flat) {\n material.depthWrite = false;\n\n var renderOrder = (style.renderOrder !== undefined) ? style.renderOrder : 3;\n mesh.renderOrder = renderOrder;\n }\n\n if (options.interactive) {\n material = new PickingMaterial();\n material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n }\n\n return Promise.resolve({\n mesh: mesh,\n pickingMesh: pickingMesh\n });\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates[0][0][0];\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var point;\n return this._coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(latlon => {\n point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * point.x;\n this._offset.y = -1 * point.y;\n\n this._options.pointScale = this._world.pointScale(latlon);\n }\n\n return point;\n });\n });\n });\n }\n\n // Convert coordinates array to something earcut can understand\n static ToEarcut(coordinates) {\n var dim = 2;\n var result = {vertices: [], holes: [], dimensions: dim};\n var holeIndex = 0;\n\n for (var i = 0; i < coordinates.length; i++) {\n for (var j = 0; j < coordinates[i].length; j++) {\n // for (var d = 0; d < dim; d++) {\n result.vertices.push(coordinates[i][j].x);\n result.vertices.push(coordinates[i][j].y);\n // }\n }\n if (i > 0) {\n holeIndex += coordinates[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n\n return result;\n }\n\n // Triangulate earcut-based input using earcut\n static Triangulate(contour, holes, dim) {\n // console.time('earcut');\n\n var faces = earcut(contour, holes, dim);\n var result = [];\n\n for (i = 0, il = faces.length; i < il; i += 3) {\n result.push(faces.slice(i, i + 3));\n }\n\n // console.timeEnd('earcut');\n\n return result;\n }\n\n // Transform polygon representation into attribute arrays that can be used by\n // THREE.BufferGeometry\n //\n // TODO: Can this be simplified? It's messy and huge\n static ToAttributes(polygon) {\n // Three components per vertex per face (3 x 3 = 9)\n var positions = new Float32Array(polygon.facesCount * 9);\n var normals = new Float32Array(polygon.facesCount * 9);\n var colours = new Float32Array(polygon.facesCount * 9);\n\n // One component per vertex per face (1 x 3 = 3)\n var tops = new Float32Array(polygon.facesCount * 3);\n\n var pickingIds;\n if (polygon.pickingId) {\n // One component per vertex per face (1 x 3 = 3)\n pickingIds = new Float32Array(polygon.facesCount * 3);\n }\n\n var pA = new THREE.Vector3();\n var pB = new THREE.Vector3();\n var pC = new THREE.Vector3();\n\n var cb = new THREE.Vector3();\n var ab = new THREE.Vector3();\n\n var index;\n\n var _faces = polygon.faces;\n var _vertices = polygon.vertices;\n var _colour = polygon.colours;\n var _tops = polygon.tops;\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = polygon.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _faces.length; i++) {\n // Array of vertex indexes for the face\n index = _faces[i][0];\n\n var ax = _vertices[index][0];\n var ay = _vertices[index][1];\n var az = _vertices[index][2];\n\n var c1 = _colour[i][0];\n var t1 = _tops[i][0];\n\n index = _faces[i][1];\n\n var bx = _vertices[index][0];\n var by = _vertices[index][1];\n var bz = _vertices[index][2];\n\n var c2 = _colour[i][1];\n var t2 = _tops[i][1];\n\n index = _faces[i][2];\n\n var cx = _vertices[index][0];\n var cy = _vertices[index][1];\n var cz = _vertices[index][2];\n\n var c3 = _colour[i][2];\n var t3 = _tops[i][2];\n\n // Flat face normals\n // From: http://threejs.org/examples/webgl_buffergeometry.html\n pA.set(ax, ay, az);\n pB.set(bx, by, bz);\n pC.set(cx, cy, cz);\n\n cb.subVectors(pC, pB);\n ab.subVectors(pA, pB);\n cb.cross(ab);\n\n cb.normalize();\n\n var nx = cb.x;\n var ny = cb.y;\n var nz = cb.z;\n\n positions[lastIndex * 9 + 0] = ax;\n positions[lastIndex * 9 + 1] = ay;\n positions[lastIndex * 9 + 2] = az;\n\n normals[lastIndex * 9 + 0] = nx;\n normals[lastIndex * 9 + 1] = ny;\n normals[lastIndex * 9 + 2] = nz;\n\n colours[lastIndex * 9 + 0] = c1[0];\n colours[lastIndex * 9 + 1] = c1[1];\n colours[lastIndex * 9 + 2] = c1[2];\n\n positions[lastIndex * 9 + 3] = bx;\n positions[lastIndex * 9 + 4] = by;\n positions[lastIndex * 9 + 5] = bz;\n\n normals[lastIndex * 9 + 3] = nx;\n normals[lastIndex * 9 + 4] = ny;\n normals[lastIndex * 9 + 5] = nz;\n\n colours[lastIndex * 9 + 3] = c2[0];\n colours[lastIndex * 9 + 4] = c2[1];\n colours[lastIndex * 9 + 5] = c2[2];\n\n positions[lastIndex * 9 + 6] = cx;\n positions[lastIndex * 9 + 7] = cy;\n positions[lastIndex * 9 + 8] = cz;\n\n normals[lastIndex * 9 + 6] = nx;\n normals[lastIndex * 9 + 7] = ny;\n normals[lastIndex * 9 + 8] = nz;\n\n colours[lastIndex * 9 + 6] = c3[0];\n colours[lastIndex * 9 + 7] = c3[1];\n colours[lastIndex * 9 + 8] = c3[2];\n\n tops[lastIndex * 3 + 0] = t1;\n tops[lastIndex * 3 + 1] = t2;\n tops[lastIndex * 3 + 2] = t3;\n\n if (pickingIds) {\n pickingIds[lastIndex * 3 + 0] = _pickingId;\n pickingIds[lastIndex * 3 + 1] = _pickingId;\n pickingIds[lastIndex * 3 + 2] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n positions: positions,\n normals: normals,\n colors: colours,\n tops: tops\n };\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the polygon is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiPolygon GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0][0][0]);\n }\n\n // TODO: Make sure this is cleaning everything\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PolygonLayer;\n\nvar noNew = function(coordinates, options) {\n return new PolygonLayer(coordinates, options);\n};\n\nexport {noNew as polygonLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PolygonLayer.js\n **/","import THREE from 'three';\nimport PickingShader from './PickingShader';\n\n// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\nvar PickingMaterial = function() {\n THREE.ShaderMaterial.call(this, {\n uniforms: {\n size: {\n type: 'f',\n value: 0.01,\n },\n scale: {\n type: 'f',\n value: 400,\n }\n },\n // attributes: ['position', 'id'],\n vertexShader: PickingShader.vertexShader,\n fragmentShader: PickingShader.fragmentShader\n });\n\n this.linePadding = 2;\n};\n\nPickingMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype);\n\nPickingMaterial.prototype.constructor = PickingMaterial;\n\nPickingMaterial.prototype.setPointSize = function(size) {\n this.uniforms.size.value = size;\n};\n\nPickingMaterial.prototype.setPointScale = function(scale) {\n this.uniforms.scale.value = scale;\n};\n\nexport default PickingMaterial;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingMaterial.js\n **/","// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\nvar PickingShader = {\n vertexShader: [\n\t\t'attribute float pickingId;',\n\t\t// '',\n\t\t// 'uniform float size;',\n\t\t// 'uniform float scale;',\n\t\t'',\n\t\t'varying vec4 worldId;',\n\t\t'',\n\t\t'void main() {',\n\t\t' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',\n\t\t// ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );',\n\t\t' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);',\n\t\t' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);',\n\t\t' worldId = vec4(a,1);',\n\t\t' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\t\t'}'\n\t].join('\\n'),\n\n fragmentShader: [\n\t\t'#ifdef GL_ES\\n',\n\t\t'precision highp float;\\n',\n\t\t'#endif\\n',\n\t\t'',\n\t\t'varying vec4 worldId;',\n\t\t'',\n\t\t'void main() {',\n\t\t' gl_FragColor = worldId;',\n\t\t'}'\n\t].join('\\n')\n};\n\nexport default PickingShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingShader.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Provide alternative output using tubes and splines / curves\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\n// TODO: Allow _setBufferAttributes to use a custom function passed in to\n// generate a custom mesh\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Geo from '../../geo/Geo';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PolylineLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n polylineMaterial: null,\n onPolylineMesh: null,\n onBufferAttributes: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n lineOpacity: 1,\n lineTransparent: false,\n lineColor: '#ffffff',\n lineWidth: 1,\n lineBlending: THREE.NormalBlending\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of lines so it's easy to support\n // MultiLineString features (a single line would be a MultiLineString with a\n // single line in the array)\n this._coordinates = (PolylineLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n // Polyline features are always flat (for now at least)\n this._flat = true;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n PolylineLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {\n this._bufferAttributes = Buffer.mergeAttributes(result.attributes);\n this._flat = result.flat;\n\n var attributeLengths = {\n positions: 3,\n colors: 3\n };\n\n if (this._options.interactive) {\n attributeLengths.pickingIds = 1;\n }\n\n if (this.isOutput()) {\n var style = this._options.style;\n\n // Set mesh if not merging elsewhere\n PolylineLayer.SetMesh(this._bufferAttributes, attributeLengths, this._flat, style, this._options).then((result) => {\n // Output mesh\n this.add(result.mesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n result.attributes = null;\n result = null;\n\n resolve(this);\n });\n });\n }\n\n // Return center of polyline as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n //\n // TODO: Find proper center position instead of returning first coordinate\n // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59\n getCenter() {\n return this._center;\n }\n\n // Return line bounds in geographic coordinates\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n static SetBufferAttributes(coordinates, options) {\n return new Promise((resolve) => {\n var height = 0;\n\n // Convert height into world units\n if (options.style.lineHeight) {\n height = Geo.metresToWorld(options.style.lineHeight, options.pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(options.style.lineColor);\n\n var flat = true;\n\n // For each line\n var attributes = coordinates.map(_projectedCoordinates => {\n var _vertices = [];\n var _colours = [];\n\n // Connect coordinate with the next to make a pair\n //\n // LineSegments requires pairs of vertices so repeat the last point if\n // there's an odd number of vertices\n var nextCoord;\n _projectedCoordinates.forEach((coordinate, index) => {\n _colours.push([colour.r, colour.g, colour.b]);\n _vertices.push([coordinate.x, height, coordinate.y]);\n\n nextCoord = (_projectedCoordinates[index + 1]) ? _projectedCoordinates[index + 1] : coordinate;\n\n _colours.push([colour.r, colour.g, colour.b]);\n _vertices.push([nextCoord.x, height, nextCoord.y]);\n });\n\n var line = {\n vertices: _vertices,\n colours: _colours,\n verticesCount: _vertices.length\n };\n\n if (options.interactive && options.pickingId) {\n // Inject picking ID\n line.pickingId = options.pickingId;\n }\n\n // Convert line representation to proper attribute arrays\n return PolylineLayer.ToAttributes(line);\n });\n\n resolve({\n attributes: attributes,\n flat: flat\n });\n });\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n static SetMesh(attributes, attributeLengths, flat, style, options) {\n var geometry = new THREE.BufferGeometry();\n\n for (var key in attributes) {\n geometry.addAttribute(key.slice(0, -1), new THREE.BufferAttribute(attributes[key], attributeLengths[key]));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (options.polylineMaterial && options.polylineMaterial instanceof THREE.Material) {\n material = options.polylineMaterial;\n } else {\n material = new THREE.LineBasicMaterial({\n vertexColors: THREE.VertexColors,\n linewidth: style.lineWidth,\n transparent: style.lineTransparent,\n opacity: style.lineOpacity,\n blending: style.lineBlending\n });\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof options.onPolylineMesh === 'function') {\n mesh = options.onPolylineMesh(geometry, material);\n } else {\n mesh = new THREE.LineSegments(geometry, material);\n\n if (style.lineRenderOrder !== undefined) {\n material.depthWrite = false;\n mesh.renderOrder = style.lineRenderOrder;\n }\n\n mesh.castShadow = true;\n // mesh.receiveShadow = true;\n }\n\n if (options.interactive) {\n material = new PickingMaterial();\n // material.side = THREE.BackSide;\n\n // Make the line wider / easier to pick\n material.linewidth = style.lineWidth + material.linePadding;\n\n var pickingMesh = new THREE.LineSegments(geometry, material);\n }\n\n return Promise.resolve({\n mesh: mesh,\n pickingMesh: pickingMesh\n });\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates[0][0];\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(_coordinates => {\n return _coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var point;\n return this._coordinates.map(_coordinates => {\n return _coordinates.map(latlon => {\n point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * point.x;\n this._offset.y = -1 * point.y;\n\n this._options.pointScale = this._world.pointScale(latlon);\n }\n\n return point;\n });\n });\n }\n\n static ToAttributes(line) {\n // Three components per vertex\n var vertices = new Float32Array(line.verticesCount * 3);\n var colours = new Float32Array(line.verticesCount * 3);\n\n var pickingIds;\n if (line.pickingId) {\n // One component per vertex\n pickingIds = new Float32Array(line.verticesCount);\n }\n\n var _vertices = line.vertices;\n var _colour = line.colours;\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = line.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _vertices.length; i++) {\n var ax = _vertices[i][0];\n var ay = _vertices[i][1];\n var az = _vertices[i][2];\n\n var c1 = _colour[i];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n positions: vertices,\n colors: colours\n };\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the line is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiLineString GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0][0]);\n }\n\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PolylineLayer;\n\nvar noNew = function(coordinates, options) {\n return new PolylineLayer(coordinates, options);\n};\n\nexport {noNew as polylineLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PolylineLayer.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Point features may be using custom models / meshes and so an approach\n// needs to be found to allow these to be brokwn down into buffer attributes for\n// merging\n//\n// Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry\n// and pull out the attributes\n\n// TODO: Support sprite objects using textures\n\n// TODO: Provide option to billboard geometry so it always faces the camera\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Geo from '../../geo/Geo';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\nimport PolygonLayer from './PolygonLayer';\n\nclass PointLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // THREE.Geometry or THREE.BufferGeometry to use for point output\n pointGeometry: null,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n pointMaterial: null,\n onPointMesh: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n pointColor: '#ff0000'\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of points so it's easy to support\n // MultiPoint features (a single point would be a MultiPoint with a\n // single point in the array)\n this._coordinates = (PointLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n this._flat = false;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n PointLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {\n this._bufferAttributes = Buffer.mergeAttributes(result.attributes);\n this._flat = result.flat;\n\n var attributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3\n };\n\n if (this._options.interactive) {\n attributeLengths.pickingIds = 1;\n }\n\n if (this.isOutput()) {\n var style = this._options.style;\n\n // Set mesh if not merging elsewhere\n // TODO: Dedupe with PolygonLayer as they are identical\n PointLayer.SetMesh(this._bufferAttributes, attributeLengths, this._flat, style, this._options, this._world._environment._skybox).then((result) => {\n // Output mesh\n this.add(result.mesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n result.attributes = null;\n result = null;\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Return center of point as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n getCenter() {\n return this._center;\n }\n\n // Return point bounds in geographic coordinates\n //\n // While not useful for single points, it could be useful for MultiPoint\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n static SetBufferAttributes(coordinates, options) {\n return new Promise((resolve) => {\n var height = 0;\n\n // Convert height into world units\n if (options.style.pointHeight) {\n height = Geo.metresToWorld(options.style.pointHeight, options.pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(options.style.pointColor);\n\n // Use default geometry if none has been provided or the provided geometry\n // isn't valid\n if (!options.pointGeometry || (!options.pointGeometry instanceof THREE.Geometry || !options.pointGeometry instanceof THREE.BufferGeometry)) {\n // Debug geometry for points is a thin bar\n //\n // TODO: Allow point geometry to be customised / overridden\n var geometryWidth = Geo.metresToWorld(25, options.pointScale);\n var geometryHeight = Geo.metresToWorld(200, options.pointScale);\n var _geometry = new THREE.BoxGeometry(geometryWidth, geometryHeight, geometryWidth);\n\n // Shift geometry up so it sits on the ground\n _geometry.translate(0, geometryHeight * 0.5, 0);\n\n // Pull attributes out of debug geometry\n geometry = new THREE.BufferGeometry().fromGeometry(_geometry);\n } else {\n if (options.geometry instanceof THREE.BufferGeometry) {\n geometry = options.pointGeometry;\n } else {\n geometry = new THREE.BufferGeometry().fromGeometry(options.pointGeometry);\n }\n }\n\n var attributes = coordinates.map((coordinate) => {\n var _vertices = [];\n var _normals = [];\n var _colours = [];\n\n var _geometry = geometry.clone();\n _geometry.translate(coordinate.x, height, coordinate.y);\n\n var _vertices = _geometry.attributes.position.clone().array;\n var _normals = _geometry.attributes.normal.clone().array;\n var _colours = _geometry.attributes.color.clone().array;\n\n for (var i = 0; i < _colours.length; i += 3) {\n _colours[i] = colour.r;\n _colours[i + 1] = colour.g;\n _colours[i + 2] = colour.b;\n }\n\n var _point = {\n positions: _vertices,\n normals: _normals,\n colors: _colours\n };\n\n if (options.interactive && options.pickingId) {\n // Inject picking ID\n _point.pickingId = options.pickingId;\n }\n\n return _point;\n });\n\n resolve({\n attributes: attributes,\n flat: false\n });\n });\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n static SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n var geometry = new THREE.BufferGeometry();\n\n for (var key in attributes) {\n geometry.addAttribute(key.slice(0, -1), new THREE.BufferAttribute(attributes[key], attributeLengths[key]));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (options.pointMaterial && options.pointMaterial instanceof THREE.Material) {\n material = options.pointMaterial;\n } else if (!skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors,\n // side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors,\n // side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof options.onPolygonMesh === 'function') {\n mesh = options.onPolygonMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n }\n\n if (flat) {\n material.depthWrite = false;\n mesh.renderOrder = 4;\n }\n\n if (options.interactive) {\n material = new PickingMaterial();\n material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n }\n\n return Promise.resolve({\n mesh: mesh,\n pickingMesh: pickingMesh\n });\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates;\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var _point;\n return this._coordinates.map(latlon => {\n _point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * _point.x;\n this._offset.y = -1 * _point.y;\n\n this._options.pointScale = this._world.pointScale(latlon);\n }\n\n return _point;\n });\n }\n\n // Returns true if the line is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiPoint GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0]);\n }\n\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PointLayer;\n\nvar noNew = function(coordinates, options) {\n return new PointLayer(coordinates, options);\n};\n\nexport {noNew as pointLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PointLayer.js\n **/","// TODO: A lot of these utils don't need to be in separate, tiny files\n\nimport wrapNum from './wrapNum';\nimport extrudePolygon from './extrudePolygon';\nimport GeoJSON from './GeoJSON';\nimport Buffer from './Buffer';\nimport Worker from './Worker';\nimport Stringify from './Stringify';\n\nconst Util = {};\n\nUtil.wrapNum = wrapNum;\nUtil.extrudePolygon = extrudePolygon;\nUtil.GeoJSON = GeoJSON;\nUtil.Buffer = Buffer;\nUtil.Worker = Worker;\nUtil.Stringify = Stringify;\n\nexport default Util;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/index.js\n **/","/*\n * Wrap the given number to lie within a certain range (eg. longitude)\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js\n */\n\nvar wrapNum = function(x, range, includeMax) {\n var max = range[1];\n var min = range[0];\n var d = max - min;\n return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\n};\n\nexport default wrapNum;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/wrapNum.js\n **/"],"sourceRoot":"/source/"} \ No newline at end of file diff --git a/dist/vizicities.css b/dist/vizicities.css index 9bc601c..c313d5b 100644 --- a/dist/vizicities.css +++ b/dist/vizicities.css @@ -1,4 +1,5 @@ .vizicities-attribution { + position: relative; background: rgba(255, 255, 255, 0.9); border-radius: 3px 0 0; bottom: 0; @@ -16,7 +17,25 @@ text-decoration: none; } - .vizicities-attribution a:hover { - color: #2bb2ed; - text-decoration: underline; - } +.vizicities-attribution a:hover { +color: #2bb2ed; +text-decoration: underline; +} + +#attribution-container { + position: absolute; + right: 0; + bottom: 0; + z-index: -1; + width: 250px; + padding: 4px 7px; + padding-right: 120px; + background: #ffffff; + border-radius: 3px 0 0; + opacity: 0; + transition: opacity 100ms linear; +} + +.is-visible #attribution-container { + opacity: 1; +} diff --git a/dist/vizicities.js b/dist/vizicities.js index 96e745d..6ccf797 100644 --- a/dist/vizicities.js +++ b/dist/vizicities.js @@ -7,7 +7,7 @@ exports["VIZI"] = factory(require("THREE"), require("TweenLite")); else root["VIZI"] = factory(root["THREE"], root["TweenLite"]); -})(this, function(__WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_41__) { +})(this, function(__WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_53__) { return /******/ (function(modules) { // webpackBootstrap /******/ // The module cache /******/ var installedModules = {}; @@ -64,7 +64,7 @@ return /******/ (function(modules) { // webpackBootstrap var _World2 = _interopRequireDefault(_World); - var _controlsIndex = __webpack_require__(37); + var _controlsIndex = __webpack_require__(49); var _controlsIndex2 = _interopRequireDefault(_controlsIndex); @@ -72,43 +72,59 @@ return /******/ (function(modules) { // webpackBootstrap var _geoGeoJs2 = _interopRequireDefault(_geoGeoJs); - var _layerLayer = __webpack_require__(32); + var _layerLayer = __webpack_require__(34); var _layerLayer2 = _interopRequireDefault(_layerLayer); - var _layerEnvironmentEnvironmentLayer = __webpack_require__(31); + var _layerLayerGroup = __webpack_require__(54); + + var _layerLayerGroup2 = _interopRequireDefault(_layerLayerGroup); + + var _layerEnvironmentEnvironmentLayer = __webpack_require__(33); var _layerEnvironmentEnvironmentLayer2 = _interopRequireDefault(_layerEnvironmentEnvironmentLayer); - var _layerTileImageTileLayer = __webpack_require__(42); + var _layerTileImageTileLayer = __webpack_require__(55); var _layerTileImageTileLayer2 = _interopRequireDefault(_layerTileImageTileLayer); - var _layerTileGeoJSONTileLayer = __webpack_require__(57); + var _layerTileGeoJSONTileLayer = __webpack_require__(70); var _layerTileGeoJSONTileLayer2 = _interopRequireDefault(_layerTileGeoJSONTileLayer); - var _layerTileTopoJSONTileLayer = __webpack_require__(75); + var _layerTileTopoJSONTileLayer = __webpack_require__(89); var _layerTileTopoJSONTileLayer2 = _interopRequireDefault(_layerTileTopoJSONTileLayer); - var _layerGeoJSONLayer = __webpack_require__(59); + var _layerTileGeoJSONTile = __webpack_require__(71); + + var _layerTileGeoJSONTile2 = _interopRequireDefault(_layerTileGeoJSONTile); + + var _layerGeoJSONLayer = __webpack_require__(72); var _layerGeoJSONLayer2 = _interopRequireDefault(_layerGeoJSONLayer); - var _layerTopoJSONLayer = __webpack_require__(76); + var _layerTopoJSONLayer = __webpack_require__(90); var _layerTopoJSONLayer2 = _interopRequireDefault(_layerTopoJSONLayer); - var _layerGeometryPolygonLayer = __webpack_require__(72); + var _layerGeoJSONWorkerLayer = __webpack_require__(87); + + var _layerGeoJSONWorkerLayer2 = _interopRequireDefault(_layerGeoJSONWorkerLayer); + + var _layerTopoJSONWorkerLayer = __webpack_require__(91); + + var _layerTopoJSONWorkerLayer2 = _interopRequireDefault(_layerTopoJSONWorkerLayer); + + var _layerGeometryPolygonLayer = __webpack_require__(84); var _layerGeometryPolygonLayer2 = _interopRequireDefault(_layerGeometryPolygonLayer); - var _layerGeometryPolylineLayer = __webpack_require__(73); + var _layerGeometryPolylineLayer = __webpack_require__(85); var _layerGeometryPolylineLayer2 = _interopRequireDefault(_layerGeometryPolylineLayer); - var _layerGeometryPointLayer = __webpack_require__(74); + var _layerGeometryPointLayer = __webpack_require__(86); var _layerGeometryPointLayer2 = _interopRequireDefault(_layerGeometryPointLayer); @@ -120,11 +136,11 @@ return /******/ (function(modules) { // webpackBootstrap var _geoLatLon2 = _interopRequireDefault(_geoLatLon); - var _enginePickingMaterial = __webpack_require__(70); + var _enginePickingMaterial = __webpack_require__(82); var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); - var _utilIndex = __webpack_require__(77); + var _utilIndex = __webpack_require__(92); var _utilIndex2 = _interopRequireDefault(_utilIndex); @@ -144,12 +160,18 @@ return /******/ (function(modules) { // webpackBootstrap imageTileLayer: _layerTileImageTileLayer.imageTileLayer, GeoJSONTileLayer: _layerTileGeoJSONTileLayer2['default'], geoJSONTileLayer: _layerTileGeoJSONTileLayer.geoJSONTileLayer, + GeoJSONTile: _layerTileGeoJSONTile2['default'], + geoJSONTile: _layerTileGeoJSONTile.geoJSONTile, TopoJSONTileLayer: _layerTileTopoJSONTileLayer2['default'], topoJSONTileLayer: _layerTileTopoJSONTileLayer.topoJSONTileLayer, GeoJSONLayer: _layerGeoJSONLayer2['default'], geoJSONLayer: _layerGeoJSONLayer.geoJSONLayer, TopoJSONLayer: _layerTopoJSONLayer2['default'], topoJSONLayer: _layerTopoJSONLayer.topoJSONLayer, + GeoJSONWorkerLayer: _layerGeoJSONWorkerLayer2['default'], + geoJSONWorkerLayer: _layerGeoJSONWorkerLayer.geoJSONWorkerLayer, + TopoJSONWorkerLayer: _layerTopoJSONWorkerLayer2['default'], + topoJSONWorkerLayer: _layerTopoJSONWorkerLayer.topoJSONWorkerLayer, PolygonLayer: _layerGeometryPolygonLayer2['default'], polygonLayer: _layerGeometryPolygonLayer.polygonLayer, PolylineLayer: _layerGeometryPolylineLayer2['default'], @@ -205,10 +227,14 @@ return /******/ (function(modules) { // webpackBootstrap var _engineEngine2 = _interopRequireDefault(_engineEngine); - var _layerEnvironmentEnvironmentLayer = __webpack_require__(31); + var _layerEnvironmentEnvironmentLayer = __webpack_require__(33); var _layerEnvironmentEnvironmentLayer2 = _interopRequireDefault(_layerEnvironmentEnvironmentLayer); + var _utilWorker = __webpack_require__(46); + + var _utilWorker2 = _interopRequireDefault(_utilWorker); + // TODO: Make sure nothing is left behind in the heap after calling destroy() // Pretty much any event someone using ViziCities would need will be emitted or @@ -249,6 +275,11 @@ return /******/ (function(modules) { // webpackBootstrap } _createClass(World, [{ + key: 'createWorkers', + value: function createWorkers(maxWorkers, workerScript) { + return _utilWorker2['default'].createWorkers(maxWorkers, workerScript); + } + }, { key: '_initContainer', value: function _initContainer(domId) { this._container = document.getElementById(domId); @@ -256,14 +287,22 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_initAttribution', value: function _initAttribution() { - var message = 'Powered by ViziCities'; + var message = 'ViziCities | Attribution'; var element = document.createElement('div'); element.classList.add('vizicities-attribution'); + var additionalElem = document.createElement('div'); + additionalElem.id = 'attribution-container'; + element.innerHTML = message; + element.appendChild(additionalElem); this._container.appendChild(element); + + document.getElementById('show-attr').addEventListener('click', function (e) { + e.currentTarget.parentNode.classList.toggle('is-visible'); + }); } }, { key: '_initEngine', @@ -350,6 +389,23 @@ return /******/ (function(modules) { // webpackBootstrap this._engine.update(delta); this.emit('postUpdate', delta); } + }, { + key: '_addAttribution', + value: function _addAttribution(id, message) { + var container = document.getElementById('attribution-container'); + + var span = document.createElement('p'); + span.dataset.layer = id; + span.innerHTML = message; + + container.appendChild(span); + } + }, { + key: '_removeAttribution', + value: function _removeAttribution(id) { + var elem = document.querySelectorAll('#attribution-container [data-layer="' + id + '"]')[0]; + elem.remove(); + } // Set world view }, { @@ -460,6 +516,8 @@ return /******/ (function(modules) { // webpackBootstrap value: function addLayer(layer) { var _this2 = this; + // Is is right to assume that there will always be some other layer + // managing layers with output set to false? this._layers.push(layer); if (layer.isOutput() && layer.isOutputToScene()) { @@ -471,7 +529,14 @@ return /******/ (function(modules) { // webpackBootstrap return new Promise(function (resolve, reject) { layer._addToWorld(_this2).then(function () { + if (layer._options.attribution) { + _this2._addAttribution(layer._options.id, layer._options.attribution); + } + + // TODO: Consider moving this so it doesn't fire for layers that are + // actually managed by a parent layer (eg. tiles) _this2.emit('layerAdded', layer); + resolve(_this2); })['catch'](reject); }); @@ -2540,31 +2605,31 @@ return /******/ (function(modules) { // webpackBootstrap var _Picking2 = _interopRequireDefault(_Picking); - var _EffectComposer = __webpack_require__(22); + var _EffectComposer = __webpack_require__(24); var _EffectComposer2 = _interopRequireDefault(_EffectComposer); - var _vendorRenderPass = __webpack_require__(27); + var _vendorRenderPass = __webpack_require__(29); var _vendorRenderPass2 = _interopRequireDefault(_vendorRenderPass); - var _vendorShaderPass = __webpack_require__(25); + var _vendorShaderPass = __webpack_require__(27); var _vendorShaderPass2 = _interopRequireDefault(_vendorShaderPass); - var _vendorCopyShader = __webpack_require__(24); + var _vendorCopyShader = __webpack_require__(26); var _vendorCopyShader2 = _interopRequireDefault(_vendorCopyShader); - var _vendorHorizontalTiltShiftShader = __webpack_require__(28); + var _vendorHorizontalTiltShiftShader = __webpack_require__(30); var _vendorHorizontalTiltShiftShader2 = _interopRequireDefault(_vendorHorizontalTiltShiftShader); - var _vendorVerticalTiltShiftShader = __webpack_require__(29); + var _vendorVerticalTiltShiftShader = __webpack_require__(31); var _vendorVerticalTiltShiftShader2 = _interopRequireDefault(_vendorVerticalTiltShiftShader); - var _vendorFXAAShader = __webpack_require__(30); + var _vendorFXAAShader = __webpack_require__(32); var _vendorFXAAShader2 = _interopRequireDefault(_vendorFXAAShader); @@ -2861,6 +2926,12 @@ return /******/ (function(modules) { // webpackBootstrap exports['default'] = function (container, antialias) { var renderer = new _three2['default'].WebGLRenderer({ antialias: antialias + + // Enabling this removes a lot of z-index intersecting but it also removes + // shadows due to a bug in three.js + // + // See: https://github.com/mrdoob/three.js/issues/7815 + // logarithmicDepthBuffer: true }); // TODO: Re-enable when this works with the skybox @@ -3407,6 +3478,10 @@ return /******/ (function(modules) { // webpackBootstrap var _PickingScene2 = _interopRequireDefault(_PickingScene); + var _lodashThrottle = __webpack_require__(22); + + var _lodashThrottle2 = _interopRequireDefault(_lodashThrottle); + // TODO: Look into a way of setting this up without passing in a renderer and // camera from the engine @@ -3456,8 +3531,10 @@ return /******/ (function(modules) { // webpackBootstrap this._resizeHandler = this._resizeTexture.bind(this); window.addEventListener('resize', this._resizeHandler, false); + this._throttledMouseMoveHandler = (0, _lodashThrottle2['default'])(this._onMouseMove.bind(this), 50); this._mouseUpHandler = this._onMouseUp.bind(this); this._world._container.addEventListener('mouseup', this._mouseUpHandler, false); + this._world._container.addEventListener('mousemove', this._throttledMouseMoveHandler, false); this._world.on('move', this._onWorldMove, this); } @@ -3469,7 +3546,7 @@ return /******/ (function(modules) { // webpackBootstrap return; } - var point = (0, _geoPoint.point)(event.clientX, event.clientY); + var point = (0, _geoPoint.point)(event.clientX - this._world._container.offsetLeft, event.clientY - this._world._container.offsetTop); var normalisedPoint = (0, _geoPoint.point)(0, 0); normalisedPoint.x = point.x / this._width * 2 - 1; @@ -3477,6 +3554,17 @@ return /******/ (function(modules) { // webpackBootstrap this._pick(point, normalisedPoint); } + }, { + key: '_onMouseMove', + value: function _onMouseMove(event) { + var point = (0, _geoPoint.point)(event.clientX - this._world._container.offsetLeft, event.clientY - this._world._container.offsetTop); + + var normalisedPoint = (0, _geoPoint.point)(0, 0); + normalisedPoint.x = point.x / this._width * 2 - 1; + normalisedPoint.y = -(point.y / this._height) * 2 + 1; + + this._pick(point, normalisedPoint, true); + } }, { key: '_onWorldMove', value: function _onWorldMove() { @@ -3522,7 +3610,7 @@ return /******/ (function(modules) { // webpackBootstrap } }, { key: '_pick', - value: function _pick(point, normalisedPoint) { + value: function _pick(point, normalisedPoint, hover) { this._update(); var index = point.x + (this._pickingTexture.height - point.y) * this._pickingTexture.width; @@ -3532,6 +3620,12 @@ return /******/ (function(modules) { // webpackBootstrap // Skip if ID is 16646655 (white) as the background returns this if (id === 16646655) { + if (hover) { + this._world.emit('pick-hover-reset'); + } else { + this._world.emit('pick-click-reset'); + } + return; } @@ -3553,8 +3647,16 @@ return /******/ (function(modules) { // webpackBootstrap // people use the picking API and what the returned data should be // // TODO: Look into the leak potential for passing so much by reference here - this._world.emit('pick', id, _point2d, _point3d, intersects); - this._world.emit('pick-' + id, _point2d, _point3d, intersects); + // this._world.emit('pick', id, _point2d, _point3d, intersects); + // this._world.emit('pick-' + id, _point2d, _point3d, intersects); + + if (hover) { + this._world.emit('pick-hover', id, _point2d, _point3d, intersects); + this._world.emit('pick-hover-' + id, _point2d, _point3d, intersects); + } else { + this._world.emit('pick-click', id, _point2d, _point3d, intersects); + this._world.emit('pick-click-' + id, _point2d, _point3d, intersects); + } } // Add mesh to picking scene @@ -3588,6 +3690,7 @@ return /******/ (function(modules) { // webpackBootstrap // active at the moment window.removeEventListener('resize', this._resizeHandler, false); this._world._container.removeEventListener('mouseup', this._mouseUpHandler, false); + this._world._container.removeEventListener('mousemove', this._throttledMouseMoveHandler, false); this._world.off('move', this._onWorldMove); @@ -3669,1418 +3772,6 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, /* 22 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - var _vendorEffectComposer = __webpack_require__(23); - - var _vendorEffectComposer2 = _interopRequireDefault(_vendorEffectComposer); - - exports['default'] = function (renderer, container) { - var composer = new _vendorEffectComposer2['default'](renderer); - - var updateSize = function updateSize() { - // TODO: Re-enable this when perf issues can be solved - // - // Rendering double the resolution of the screen can be really slow - // var pixelRatio = window.devicePixelRatio; - var pixelRatio = 1; - - composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio); - }; - - window.addEventListener('resize', updateSize, false); - updateSize(); - - return composer; - }; - - ; - module.exports = exports['default']; - -/***/ }, -/* 23 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - var _CopyShader = __webpack_require__(24); - - var _CopyShader2 = _interopRequireDefault(_CopyShader); - - var _ShaderPass = __webpack_require__(25); - - var _ShaderPass2 = _interopRequireDefault(_ShaderPass); - - var _MaskPass = __webpack_require__(26); - - var _MaskPass2 = _interopRequireDefault(_MaskPass); - - /** - * @author alteredq / http://alteredqualia.com/ - */ - - var EffectComposer = function EffectComposer(renderer, renderTarget) { - - this.renderer = renderer; - - if (renderTarget === undefined) { - - var pixelRatio = renderer.getPixelRatio(); - - var width = Math.floor(renderer.context.canvas.width / pixelRatio) || 1; - var height = Math.floor(renderer.context.canvas.height / pixelRatio) || 1; - var parameters = { minFilter: _three2['default'].LinearFilter, magFilter: _three2['default'].LinearFilter, format: _three2['default'].RGBAFormat, stencilBuffer: false }; - - renderTarget = new _three2['default'].WebGLRenderTarget(width, height, parameters); - } - - this.renderTarget1 = renderTarget; - this.renderTarget2 = renderTarget.clone(); - - this.writeBuffer = this.renderTarget1; - this.readBuffer = this.renderTarget2; - - this.passes = []; - - if (_CopyShader2['default'] === undefined) console.error("EffectComposer relies on THREE.CopyShader"); - - this.copyPass = new _ShaderPass2['default'](_CopyShader2['default']); - }; - - EffectComposer.prototype = { - - swapBuffers: function swapBuffers() { - - var tmp = this.readBuffer; - this.readBuffer = this.writeBuffer; - this.writeBuffer = tmp; - }, - - addPass: function addPass(pass) { - - this.passes.push(pass); - }, - - insertPass: function insertPass(pass, index) { - - this.passes.splice(index, 0, pass); - }, - - render: function render(delta) { - - this.writeBuffer = this.renderTarget1; - this.readBuffer = this.renderTarget2; - - var maskActive = false; - - var pass, - i, - il = this.passes.length; - - for (i = 0; i < il; i++) { - - pass = this.passes[i]; - - if (!pass.enabled) continue; - - pass.render(this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive); - - if (pass.needsSwap) { - - if (maskActive) { - - var context = this.renderer.context; - - context.stencilFunc(context.NOTEQUAL, 1, 0xffffffff); - - this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, delta); - - context.stencilFunc(context.EQUAL, 1, 0xffffffff); - } - - this.swapBuffers(); - } - - if (pass instanceof _MaskPass2['default']) { - - maskActive = true; - } else if (pass instanceof _MaskPass.ClearMaskPass) { - - maskActive = false; - } - } - }, - - reset: function reset(renderTarget) { - - if (renderTarget === undefined) { - - renderTarget = this.renderTarget1.clone(); - - var pixelRatio = this.renderer.getPixelRatio(); - - renderTarget.setSize(Math.floor(this.renderer.context.canvas.width / pixelRatio), Math.floor(this.renderer.context.canvas.height / pixelRatio)); - } - - this.renderTarget1.dispose(); - this.renderTarget1 = renderTarget; - this.renderTarget2.dispose(); - this.renderTarget2 = renderTarget.clone(); - - this.writeBuffer = this.renderTarget1; - this.readBuffer = this.renderTarget2; - }, - - setSize: function setSize(width, height) { - - this.renderTarget1.setSize(width, height); - this.renderTarget2.setSize(width, height); - } - - }; - - exports['default'] = EffectComposer; - - _three2['default'].EffectComposer = EffectComposer; - module.exports = exports['default']; - -/***/ }, -/* 24 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - * - * Full-screen textured quad shader - */ - - var CopyShader = { - - uniforms: { - - "tDiffuse": { type: "t", value: null }, - "opacity": { type: "f", value: 1.0 } - - }, - - vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), - - fragmentShader: ["uniform float opacity;", "uniform sampler2D tDiffuse;", "varying vec2 vUv;", "void main() {", "vec4 texel = texture2D( tDiffuse, vUv );", "gl_FragColor = opacity * texel;", "}"].join("\n") - - }; - - exports["default"] = CopyShader; - - _three2["default"].CopyShader = CopyShader; - module.exports = exports["default"]; - -/***/ }, -/* 25 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - */ - - var ShaderPass = function ShaderPass(shader, textureID) { - - this.textureID = textureID !== undefined ? textureID : "tDiffuse"; - - if (shader instanceof _three2["default"].ShaderMaterial) { - - this.uniforms = shader.uniforms; - - this.material = shader; - } else if (shader) { - - this.uniforms = _three2["default"].UniformsUtils.clone(shader.uniforms); - - this.material = new _three2["default"].ShaderMaterial({ - - defines: shader.defines || {}, - uniforms: this.uniforms, - vertexShader: shader.vertexShader, - fragmentShader: shader.fragmentShader - - }); - } - - this.renderToScreen = false; - - this.enabled = true; - this.needsSwap = true; - this.clear = false; - - this.camera = new _three2["default"].OrthographicCamera(-1, 1, 1, -1, 0, 1); - this.scene = new _three2["default"].Scene(); - - this.quad = new _three2["default"].Mesh(new _three2["default"].PlaneBufferGeometry(2, 2), null); - this.scene.add(this.quad); - }; - - ShaderPass.prototype = { - - render: function render(renderer, writeBuffer, readBuffer, delta) { - - if (this.uniforms[this.textureID]) { - - this.uniforms[this.textureID].value = readBuffer; - } - - this.quad.material = this.material; - - if (this.renderToScreen) { - - renderer.render(this.scene, this.camera); - } else { - - renderer.render(this.scene, this.camera, writeBuffer, this.clear); - } - } - - }; - - exports["default"] = ShaderPass; - - _three2["default"].ShaderPass = ShaderPass; - module.exports = exports["default"]; - -/***/ }, -/* 26 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - */ - - var MaskPass = function MaskPass(scene, camera) { - - this.scene = scene; - this.camera = camera; - - this.enabled = true; - this.clear = true; - this.needsSwap = false; - - this.inverse = false; - }; - - MaskPass.prototype = { - - render: function render(renderer, writeBuffer, readBuffer, delta) { - - var context = renderer.context; - - // don't update color or depth - - context.colorMask(false, false, false, false); - context.depthMask(false); - - // set up stencil - - var writeValue, clearValue; - - if (this.inverse) { - - writeValue = 0; - clearValue = 1; - } else { - - writeValue = 1; - clearValue = 0; - } - - context.enable(context.STENCIL_TEST); - context.stencilOp(context.REPLACE, context.REPLACE, context.REPLACE); - context.stencilFunc(context.ALWAYS, writeValue, 0xffffffff); - context.clearStencil(clearValue); - - // draw into the stencil buffer - - renderer.render(this.scene, this.camera, readBuffer, this.clear); - renderer.render(this.scene, this.camera, writeBuffer, this.clear); - - // re-enable update of color and depth - - context.colorMask(true, true, true, true); - context.depthMask(true); - - // only render where stencil is set to 1 - - context.stencilFunc(context.EQUAL, 1, 0xffffffff); // draw if == 1 - context.stencilOp(context.KEEP, context.KEEP, context.KEEP); - } - - }; - - var ClearMaskPass = function ClearMaskPass() { - - this.enabled = true; - }; - - ClearMaskPass.prototype = { - - render: function render(renderer, writeBuffer, readBuffer, delta) { - - var context = renderer.context; - - context.disable(context.STENCIL_TEST); - } - - }; - - exports['default'] = MaskPass; - exports.ClearMaskPass = ClearMaskPass; - - _three2['default'].MaskPass = MaskPass; - _three2['default'].ClearMaskPass = ClearMaskPass; - -/***/ }, -/* 27 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - */ - - var RenderPass = function RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha) { - - this.scene = scene; - this.camera = camera; - - this.overrideMaterial = overrideMaterial; - - this.clearColor = clearColor; - this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 1; - - this.oldClearColor = new _three2['default'].Color(); - this.oldClearAlpha = 1; - - this.enabled = true; - this.clear = true; - this.needsSwap = false; - }; - - RenderPass.prototype = { - - render: function render(renderer, writeBuffer, readBuffer, delta) { - - this.scene.overrideMaterial = this.overrideMaterial; - - if (this.clearColor) { - - this.oldClearColor.copy(renderer.getClearColor()); - this.oldClearAlpha = renderer.getClearAlpha(); - - renderer.setClearColor(this.clearColor, this.clearAlpha); - } - - renderer.render(this.scene, this.camera, readBuffer, this.clear); - - if (this.clearColor) { - - renderer.setClearColor(this.oldClearColor, this.oldClearAlpha); - } - - this.scene.overrideMaterial = null; - } - - }; - - exports['default'] = RenderPass; - - _three2['default'].RenderPass = RenderPass; - module.exports = exports['default']; - -/***/ }, -/* 28 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - * - * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position - * - * - 9 samples per pass - * - standard deviation 2.7 - * - "h" and "v" parameters should be set to "1 / width" and "1 / height" - * - "r" parameter control where "focused" horizontal line lies - */ - - var HorizontalTiltShiftShader = { - - uniforms: { - - "tDiffuse": { type: "t", value: null }, - "h": { type: "f", value: 1.0 / 512.0 }, - "r": { type: "f", value: 0.35 } - - }, - - vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), - - fragmentShader: ["uniform sampler2D tDiffuse;", "uniform float h;", "uniform float r;", "varying vec2 vUv;", "void main() {", "vec4 sum = vec4( 0.0 );", "float hh = h * abs( r - vUv.y );", "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", "gl_FragColor = sum;", "}"].join("\n") - - }; - - exports["default"] = HorizontalTiltShiftShader; - - _three2["default"].HorizontalTiltShiftShader = HorizontalTiltShiftShader; - module.exports = exports["default"]; - -/***/ }, -/* 29 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - * - * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position - * - * - 9 samples per pass - * - standard deviation 2.7 - * - "h" and "v" parameters should be set to "1 / width" and "1 / height" - * - "r" parameter control where "focused" horizontal line lies - */ - - var VerticalTiltShiftShader = { - - uniforms: { - - "tDiffuse": { type: "t", value: null }, - "v": { type: "f", value: 1.0 / 512.0 }, - "r": { type: "f", value: 0.35 } - - }, - - vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), - - fragmentShader: ["uniform sampler2D tDiffuse;", "uniform float v;", "uniform float r;", "varying vec2 vUv;", "void main() {", "vec4 sum = vec4( 0.0 );", "float vv = v * abs( r - vUv.y );", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", "gl_FragColor = sum;", "}"].join("\n") - - }; - - exports["default"] = VerticalTiltShiftShader; - - _three2["default"].VerticalTiltShiftShader = VerticalTiltShiftShader; - module.exports = exports["default"]; - -/***/ }, -/* 30 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, "__esModule", { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } - - // jscs:disable - /* eslint-disable */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - /** - * @author alteredq / http://alteredqualia.com/ - * @author davidedc / http://www.sketchpatch.net/ - * - * NVIDIA FXAA by Timothy Lottes - * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html - * - WebGL port by @supereggbert - * http://www.glge.org/demos/fxaa/ - */ - - var FXAAShader = { - - uniforms: { - - "tDiffuse": { type: "t", value: null }, - "resolution": { type: "v2", value: new _three2["default"].Vector2(1 / 1024, 1 / 512) } - - }, - - vertexShader: ["void main() {", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), - - fragmentShader: ["uniform sampler2D tDiffuse;", "uniform vec2 resolution;", "#define FXAA_REDUCE_MIN (1.0/128.0)", "#define FXAA_REDUCE_MUL (1.0/8.0)", "#define FXAA_SPAN_MAX 8.0", "void main() {", "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );", "vec3 rgbM = rgbaM.xyz;", "vec3 luma = vec3( 0.299, 0.587, 0.114 );", "float lumaNW = dot( rgbNW, luma );", "float lumaNE = dot( rgbNE, luma );", "float lumaSW = dot( rgbSW, luma );", "float lumaSE = dot( rgbSE, luma );", "float lumaM = dot( rgbM, luma );", "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", "vec2 dir;", "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", "dir * rcpDirMin)) * resolution;", "vec4 rgbA = (1.0/2.0) * (", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));", "vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));", "float lumaB = dot(rgbB, vec4(luma, 0.0));", "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", "gl_FragColor = rgbA;", "} else {", "gl_FragColor = rgbB;", "}", "}"].join("\n") - - }; - - exports["default"] = FXAAShader; - - _three2["default"].FXAAShader = FXAAShader; - module.exports = exports["default"]; - -/***/ }, -/* 31 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - 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; }; })(); - - var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - - function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - - var _Layer2 = __webpack_require__(32); - - var _Layer3 = _interopRequireDefault(_Layer2); - - var _lodashAssign = __webpack_require__(3); - - var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - var _Skybox = __webpack_require__(33); - - var _Skybox2 = _interopRequireDefault(_Skybox); - - // TODO: Make sure nothing is left behind in the heap after calling destroy() - - var EnvironmentLayer = (function (_Layer) { - _inherits(EnvironmentLayer, _Layer); - - function EnvironmentLayer(options) { - _classCallCheck(this, EnvironmentLayer); - - var defaults = { - skybox: false - }; - - var _options = (0, _lodashAssign2['default'])({}, defaults, options); - - _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'constructor', this).call(this, _options); - } - - _createClass(EnvironmentLayer, [{ - key: '_onAdd', - value: function _onAdd() { - this._initLights(); - - if (this._options.skybox) { - this._initSkybox(); - } - - // this._initGrid(); - - return Promise.resolve(this); - } - - // Not fleshed out or thought through yet - // - // Lights could potentially be put it their own 'layer' to keep this class - // much simpler and less messy - }, { - key: '_initLights', - value: function _initLights() { - // Position doesn't really matter (the angle is important), however it's - // used here so the helpers look more natural. - - if (!this._options.skybox) { - var directionalLight = new _three2['default'].DirectionalLight(0xffffff, 1); - directionalLight.position.x = 10000; - directionalLight.position.y = 10000; - directionalLight.position.z = 10000; - - // TODO: Get shadows working in non-PBR scenes - - // directionalLight.castShadow = true; - // - // var d = 100; - // directionalLight.shadow.camera.left = -d; - // directionalLight.shadow.camera.right = d; - // directionalLight.shadow.camera.top = d; - // directionalLight.shadow.camera.bottom = -d; - // - // directionalLight.shadow.camera.near = 10; - // directionalLight.shadow.camera.far = 100; - // - // // TODO: Need to dial in on a good shadowmap size - // directionalLight.shadow.mapSize.width = 2048; - // directionalLight.shadow.mapSize.height = 2048; - // - // // directionalLight.shadowBias = -0.0010; - // // directionalLight.shadow.darkness = 0.15; - - var directionalLight2 = new _three2['default'].DirectionalLight(0xffffff, 0.5); - directionalLight2.position.x = -10000; - directionalLight2.position.y = 10000; - directionalLight2.position.z = 0; - - var directionalLight3 = new _three2['default'].DirectionalLight(0xffffff, 0.5); - directionalLight3.position.x = 10000; - directionalLight3.position.y = 10000; - directionalLight3.position.z = -10000; - - this.add(directionalLight); - this.add(directionalLight2); - this.add(directionalLight3); - - // var helper = new THREE.DirectionalLightHelper(directionalLight, 10); - // var helper2 = new THREE.DirectionalLightHelper(directionalLight2, 10); - // var helper3 = new THREE.DirectionalLightHelper(directionalLight3, 10); - // - // this.add(helper); - // this.add(helper2); - // this.add(helper3); - } else { - // Directional light that will be projected from the sun - this._skyboxLight = new _three2['default'].DirectionalLight(0xffffff, 1); - - this._skyboxLight.castShadow = true; - - var d = 10000; - this._skyboxLight.shadow.camera.left = -d; - this._skyboxLight.shadow.camera.right = d; - this._skyboxLight.shadow.camera.top = d; - this._skyboxLight.shadow.camera.bottom = -d; - - this._skyboxLight.shadow.camera.near = 10000; - this._skyboxLight.shadow.camera.far = 70000; - - // TODO: Need to dial in on a good shadowmap size - this._skyboxLight.shadow.mapSize.width = 2048; - this._skyboxLight.shadow.mapSize.height = 2048; - - // this._skyboxLight.shadowBias = -0.0010; - // this._skyboxLight.shadow.darkness = 0.15; - - // this._object3D.add(new THREE.CameraHelper(this._skyboxLight.shadow.camera)); - - this.add(this._skyboxLight); - } - } - }, { - key: '_initSkybox', - value: function _initSkybox() { - this._skybox = new _Skybox2['default'](this._world, this._skyboxLight); - this.add(this._skybox._mesh); - } - - // Add grid helper for context during initial development - }, { - key: '_initGrid', - value: function _initGrid() { - var size = 4000; - var step = 100; - - var gridHelper = new _three2['default'].GridHelper(size, step); - this.add(gridHelper); - } - - // Clean up environment - }, { - key: 'destroy', - value: function destroy() { - this._skyboxLight = null; - - this.remove(this._skybox._mesh); - this._skybox.destroy(); - this._skybox = null; - - _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'destroy', this).call(this); - } - }]); - - return EnvironmentLayer; - })(_Layer3['default']); - - exports['default'] = EnvironmentLayer; - - var noNew = function noNew(options) { - return new EnvironmentLayer(options); - }; - - // Initialise without requiring new keyword - exports.environmentLayer = noNew; - -/***/ }, -/* 32 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - 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; }; })(); - - var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - - function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - - var _eventemitter3 = __webpack_require__(2); - - var _eventemitter32 = _interopRequireDefault(_eventemitter3); - - var _lodashAssign = __webpack_require__(3); - - var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - var _engineScene = __webpack_require__(11); - - var _engineScene2 = _interopRequireDefault(_engineScene); - - var _vendorCSS3DRenderer = __webpack_require__(16); - - var _vendorCSS2DRenderer = __webpack_require__(18); - - // TODO: Make sure nothing is left behind in the heap after calling destroy() - - // TODO: Need a single move method that handles moving all the various object - // layers so that the DOM layers stay in sync with the 3D layer - - // TODO: Double check that objects within the _object3D Object3D parent are frustum - // culled even if the layer position stays at the default (0,0,0) and the child - // objects are positioned much further away - // - // Or does the layer being at (0,0,0) prevent the child objects from being - // culled because the layer parent is effectively always in view even if the - // child is actually out of camera - - var Layer = (function (_EventEmitter) { - _inherits(Layer, _EventEmitter); - - function Layer(options) { - _classCallCheck(this, Layer); - - _get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this); - - var defaults = { - output: true, - outputToScene: true - }; - - this._options = (0, _lodashAssign2['default'])({}, defaults, options); - - if (this.isOutput()) { - this._object3D = new _three2['default'].Object3D(); - - this._dom3D = document.createElement('div'); - this._domObject3D = new _vendorCSS3DRenderer.CSS3DObject(this._dom3D); - - this._dom2D = document.createElement('div'); - this._domObject2D = new _vendorCSS2DRenderer.CSS2DObject(this._dom2D); - } - } - - // Add THREE object directly to layer - - _createClass(Layer, [{ - key: 'add', - value: function add(object) { - this._object3D.add(object); - } - - // Remove THREE object from to layer - }, { - key: 'remove', - value: function remove(object) { - this._object3D.remove(object); - } - }, { - key: 'addDOM3D', - value: function addDOM3D(object) { - this._domObject3D.add(object); - } - }, { - key: 'removeDOM3D', - value: function removeDOM3D(object) { - this._domObject3D.remove(object); - } - }, { - key: 'addDOM2D', - value: function addDOM2D(object) { - this._domObject2D.add(object); - } - }, { - key: 'removeDOM2D', - value: function removeDOM2D(object) { - this._domObject2D.remove(object); - } - - // Add layer to world instance and store world reference - }, { - key: 'addTo', - value: function addTo(world) { - return world.addLayer(this); - } - - // Internal method called by World.addLayer to actually add the layer - }, { - key: '_addToWorld', - value: function _addToWorld(world) { - var _this = this; - - this._world = world; - - return new Promise(function (resolve, reject) { - _this._onAdd(world).then(function () { - _this.emit('added'); - resolve(_this); - })['catch'](reject); - }); - } - - // Must return a promise - }, { - key: '_onAdd', - value: function _onAdd(world) {} - }, { - key: 'getPickingId', - value: function getPickingId() { - if (this._world._engine._picking) { - return this._world._engine._picking.getNextId(); - } - - return false; - } - - // TODO: Tidy this up and don't access so many private properties to work - }, { - key: 'addToPicking', - value: function addToPicking(object) { - if (!this._world._engine._picking) { - return; - } - - this._world._engine._picking.add(object); - } - }, { - key: 'removeFromPicking', - value: function removeFromPicking(object) { - if (!this._world._engine._picking) { - return; - } - - this._world._engine._picking.remove(object); - } - }, { - key: 'isOutput', - value: function isOutput() { - return this._options.output; - } - }, { - key: 'isOutputToScene', - value: function isOutputToScene() { - return this._options.outputToScene; - } - - // Destroys the layer and removes it from the scene and memory - }, { - key: 'destroy', - value: function destroy() { - if (this._object3D && this._object3D.children) { - // Remove everything else in the layer - var child; - for (var i = this._object3D.children.length - 1; i >= 0; i--) { - child = this._object3D.children[i]; - - if (!child) { - continue; - } - - this.remove(child); - - if (child.geometry) { - // Dispose of mesh and materials - child.geometry.dispose(); - child.geometry = null; - } - - if (child.material) { - if (child.material.map) { - child.material.map.dispose(); - child.material.map = null; - } - - child.material.dispose(); - child.material = null; - } - } - } - - if (this._domObject3D && this._domObject3D.children) { - // Remove everything else in the layer - var child; - for (var i = this._domObject3D.children.length - 1; i >= 0; i--) { - child = this._domObject3D.children[i]; - - if (!child) { - continue; - } - - this.removeDOM3D(child); - } - } - - if (this._domObject2D && this._domObject2D.children) { - // Remove everything else in the layer - var child; - for (var i = this._domObject2D.children.length - 1; i >= 0; i--) { - child = this._domObject2D.children[i]; - - if (!child) { - continue; - } - - this.removeDOM2D(child); - } - } - - this._domObject3D = null; - this._domObject2D = null; - - this._world = null; - this._object3D = null; - } - }]); - - return Layer; - })(_eventemitter32['default']); - - exports['default'] = Layer; - - var noNew = function noNew(options) { - return new Layer(options); - }; - - exports.layer = noNew; - -/***/ }, -/* 33 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - var _Sky = __webpack_require__(34); - - var _Sky2 = _interopRequireDefault(_Sky); - - var _lodashThrottle = __webpack_require__(35); - - var _lodashThrottle2 = _interopRequireDefault(_lodashThrottle); - - // TODO: Make sure nothing is left behind in the heap after calling destroy() - - var cubemap = { - vertexShader: ['varying vec3 vPosition;', 'void main() {', 'vPosition = position;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'), - - fragmentShader: ['uniform samplerCube cubemap;', 'varying vec3 vPosition;', 'void main() {', 'gl_FragColor = textureCube(cubemap, normalize(vPosition));', '}'].join('\n') - }; - - var Skybox = (function () { - function Skybox(world, light) { - _classCallCheck(this, Skybox); - - this._world = world; - this._light = light; - - this._settings = { - distance: 38000, - turbidity: 10, - reileigh: 2, - mieCoefficient: 0.005, - mieDirectionalG: 0.8, - luminance: 1, - // 0.48 is a cracking dusk / sunset - // 0.4 is a beautiful early-morning / late-afternoon - // 0.2 is a nice day time - inclination: 0.48, // Elevation / inclination - azimuth: 0.25 }; - - // Facing front - this._initSkybox(); - this._updateUniforms(); - this._initEvents(); - } - - _createClass(Skybox, [{ - key: '_initEvents', - value: function _initEvents() { - // Throttled to 1 per 100ms - this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._update, 100); - this._world.on('preUpdate', this._throttledWorldUpdate, this); - } - }, { - key: '_initSkybox', - value: function _initSkybox() { - // Cube camera for skybox - this._cubeCamera = new _three2['default'].CubeCamera(1, 20000000, 128); - - // Cube material - var cubeTarget = this._cubeCamera.renderTarget; - - // Add Sky Mesh - this._sky = new _Sky2['default'](); - this._skyScene = new _three2['default'].Scene(); - this._skyScene.add(this._sky.mesh); - - // Add Sun Helper - this._sunSphere = new _three2['default'].Mesh(new _three2['default'].SphereBufferGeometry(2000, 16, 8), new _three2['default'].MeshBasicMaterial({ - color: 0xffffff - })); - - // TODO: This isn't actually visible because it's not added to the layer - // this._sunSphere.visible = true; - - var skyboxUniforms = { - cubemap: { type: 't', value: cubeTarget } - }; - - var skyboxMat = new _three2['default'].ShaderMaterial({ - uniforms: skyboxUniforms, - vertexShader: cubemap.vertexShader, - fragmentShader: cubemap.fragmentShader, - side: _three2['default'].BackSide - }); - - this._mesh = new _three2['default'].Mesh(new _three2['default'].BoxGeometry(1900000, 1900000, 1900000), skyboxMat); - - this._updateSkybox = true; - } - }, { - key: '_updateUniforms', - value: function _updateUniforms() { - var settings = this._settings; - var uniforms = this._sky.uniforms; - uniforms.turbidity.value = settings.turbidity; - uniforms.reileigh.value = settings.reileigh; - uniforms.luminance.value = settings.luminance; - uniforms.mieCoefficient.value = settings.mieCoefficient; - uniforms.mieDirectionalG.value = settings.mieDirectionalG; - - var theta = Math.PI * (settings.inclination - 0.5); - var phi = 2 * Math.PI * (settings.azimuth - 0.5); - - this._sunSphere.position.x = settings.distance * Math.cos(phi); - this._sunSphere.position.y = settings.distance * Math.sin(phi) * Math.sin(theta); - this._sunSphere.position.z = settings.distance * Math.sin(phi) * Math.cos(theta); - - // Move directional light to sun position - this._light.position.copy(this._sunSphere.position); - - this._sky.uniforms.sunPosition.value.copy(this._sunSphere.position); - } - }, { - key: '_update', - value: function _update(delta) { - if (this._updateSkybox) { - this._updateSkybox = false; - } else { - return; - } - - // if (!this._angle) { - // this._angle = 0; - // } - // - // // Animate inclination - // this._angle += Math.PI * delta; - // this._settings.inclination = 0.5 * (Math.sin(this._angle) / 2 + 0.5); - - // Update light intensity depending on elevation of sun (day to night) - this._light.intensity = 1 - 0.95 * (this._settings.inclination / 0.5); - - // // console.log(delta, this._angle, this._settings.inclination); - // - // TODO: Only do this when the uniforms have been changed - this._updateUniforms(); - - // TODO: Only do this when the cubemap has actually changed - this._cubeCamera.updateCubeMap(this._world._engine._renderer, this._skyScene); - } - }, { - key: 'getRenderTarget', - value: function getRenderTarget() { - return this._cubeCamera.renderTarget; - } - }, { - key: 'setInclination', - value: function setInclination(inclination) { - this._settings.inclination = inclination; - this._updateSkybox = true; - } - - // Destroy the skybox and remove it from memory - }, { - key: 'destroy', - value: function destroy() { - this._world.off('preUpdate', this._throttledWorldUpdate); - this._throttledWorldUpdate = null; - - this._world = null; - this._light = null; - - this._cubeCamera = null; - - this._sky.mesh.geometry.dispose(); - this._sky.mesh.geometry = null; - - if (this._sky.mesh.material.map) { - this._sky.mesh.material.map.dispose(); - this._sky.mesh.material.map = null; - } - - this._sky.mesh.material.dispose(); - this._sky.mesh.material = null; - - this._sky.mesh = null; - this._sky = null; - - this._skyScene = null; - - this._sunSphere.geometry.dispose(); - this._sunSphere.geometry = null; - - if (this._sunSphere.material.map) { - this._sunSphere.material.map.dispose(); - this._sunSphere.material.map = null; - } - - this._sunSphere.material.dispose(); - this._sunSphere.material = null; - - this._sunSphere = null; - - this._mesh.geometry.dispose(); - this._mesh.geometry = null; - - if (this._mesh.material.map) { - this._mesh.material.map.dispose(); - this._mesh.material.map = null; - } - - this._mesh.material.dispose(); - this._mesh.material = null; - } - }]); - - return Skybox; - })(); - - exports['default'] = Skybox; - - var noNew = function noNew(world, light) { - return new Skybox(world, light); - }; - - // Initialise without requiring new keyword - exports.skybox = noNew; - -/***/ }, -/* 34 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - // jscs:disable - /*eslint eqeqeq:0*/ - - /** - * @author zz85 / https://github.com/zz85 - * - * Based on 'A Practical Analytic Model for Daylight' - * aka The Preetham Model, the de facto standard analytic skydome model - * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf - * - * First implemented by Simon Wallner - * http://www.simonwallner.at/projects/atmospheric-scattering - * - * Improved by Martin Upitis - * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR - * - * Three.js integration by zz85 http://twitter.com/blurspline - */ - - var _three = __webpack_require__(10); - - var _three2 = _interopRequireDefault(_three); - - _three2['default'].ShaderLib['sky'] = { - - uniforms: { - - luminance: { type: 'f', value: 1 }, - turbidity: { type: 'f', value: 2 }, - reileigh: { type: 'f', value: 1 }, - mieCoefficient: { type: 'f', value: 0.005 }, - mieDirectionalG: { type: 'f', value: 0.8 }, - sunPosition: { type: 'v3', value: new _three2['default'].Vector3() } - - }, - - vertexShader: ['varying vec3 vWorldPosition;', 'void main() {', 'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', 'vWorldPosition = worldPosition.xyz;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'), - - fragmentShader: ['uniform sampler2D skySampler;', 'uniform vec3 sunPosition;', 'varying vec3 vWorldPosition;', 'vec3 cameraPos = vec3(0., 0., 0.);', '// uniform sampler2D sDiffuse;', '// const float turbidity = 10.0; //', '// const float reileigh = 2.; //', '// const float luminance = 1.0; //', '// const float mieCoefficient = 0.005;', '// const float mieDirectionalG = 0.8;', 'uniform float luminance;', 'uniform float turbidity;', 'uniform float reileigh;', 'uniform float mieCoefficient;', 'uniform float mieDirectionalG;', '// constants for atmospheric scattering', 'const float e = 2.71828182845904523536028747135266249775724709369995957;', 'const float pi = 3.141592653589793238462643383279502884197169;', 'const float n = 1.0003; // refractive index of air', 'const float N = 2.545E25; // number of molecules per unit volume for air at', '// 288.15K and 1013mb (sea level -45 celsius)', 'const float pn = 0.035; // depolatization factor for standard air', '// wavelength of used primaries, according to preetham', 'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);', '// mie stuff', '// K coefficient for the primaries', 'const vec3 K = vec3(0.686, 0.678, 0.666);', 'const float v = 4.0;', '// optical length at zenith for molecules', 'const float rayleighZenithLength = 8.4E3;', 'const float mieZenithLength = 1.25E3;', 'const vec3 up = vec3(0.0, 1.0, 0.0);', 'const float EE = 1000.0;', 'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;', '// 66 arc seconds -> degrees, and the cosine of that', '// earth shadow hack', 'const float cutoffAngle = pi/1.95;', 'const float steepness = 1.5;', 'vec3 totalRayleigh(vec3 lambda)', '{', 'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));', '}', - - // see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness - '// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE', 'vec3 simplifiedRayleigh()', '{', 'return 0.0005 / vec3(94, 40, 18);', - // return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245); - '}', 'float rayleighPhase(float cosTheta)', '{ ', 'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '// return (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '// return (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));', '}', 'vec3 totalMie(vec3 lambda, vec3 K, float T)', '{', 'float c = (0.2 * T ) * 10E-18;', 'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;', '}', 'float hgPhase(float cosTheta, float g)', '{', 'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));', '}', 'float sunIntensity(float zenithAngleCos)', '{', 'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));', '}', '// float logLuminance(vec3 c)', '// {', '// return log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);', '// }', '// Filmic ToneMapping http://filmicgames.com/archives/75', 'float A = 0.15;', 'float B = 0.50;', 'float C = 0.10;', 'float D = 0.20;', 'float E = 0.02;', 'float F = 0.30;', 'float W = 1000.0;', 'vec3 Uncharted2Tonemap(vec3 x)', '{', 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;', '}', 'void main() ', '{', 'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);', '// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;', '// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);', 'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));', 'vec3 sunDirection = normalize(sunPosition);', 'float sunE = sunIntensity(dot(sunDirection, up));', '// extinction (absorbtion + out scattering) ', '// rayleigh coefficients', - - // 'vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;', - 'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;', '// mie coefficients', 'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;', '// optical length', '// cutoff angle at 90 to avoid singularity in next formula.', 'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));', 'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', 'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', '// combined extinction factor ', 'vec3 Fex = exp(-(betaR * sR + betaM * sM));', '// in scattering', 'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);', 'float rPhase = rayleighPhase(cosTheta*0.5+0.5);', 'vec3 betaRTheta = betaR * rPhase;', 'float mPhase = hgPhase(cosTheta, mieDirectionalG);', 'vec3 betaMTheta = betaM * mPhase;', 'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));', 'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));', '//nightsky', 'vec3 direction = normalize(vWorldPosition - cameraPos);', 'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]', 'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]', 'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);', '// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;', 'vec3 L0 = vec3(0.1) * Fex;', '// composition + solar disc', '//if (cosTheta > sunAngularDiameterCos)', 'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);', '// if (normalize(vWorldPosition - cameraPos).y>0.0)', 'L0 += (sunE * 19000.0 * Fex)*sundisk;', 'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));', 'vec3 texColor = (Lin+L0); ', 'texColor *= 0.04 ;', 'texColor += vec3(0.0,0.001,0.0025)*0.3;', 'float g_fMaxLuminance = 1.0;', 'float fLumScaled = 0.1 / luminance; ', 'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ', 'float ExposureBias = fLumCompressed;', 'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);', 'vec3 color = curr*whiteScale;', 'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));', 'gl_FragColor.rgb = retColor;', 'gl_FragColor.a = 1.0;', '}'].join('\n') - - }; - - var Sky = function Sky() { - - var skyShader = _three2['default'].ShaderLib['sky']; - var skyUniforms = _three2['default'].UniformsUtils.clone(skyShader.uniforms); - - var skyMat = new _three2['default'].ShaderMaterial({ - fragmentShader: skyShader.fragmentShader, - vertexShader: skyShader.vertexShader, - uniforms: skyUniforms, - side: _three2['default'].BackSide - }); - - var skyGeo = new _three2['default'].SphereBufferGeometry(450000, 32, 15); - var skyMesh = new _three2['default'].Mesh(skyGeo, skyMat); - - // Expose variables - this.mesh = skyMesh; - this.uniforms = skyUniforms; - }; - - exports['default'] = Sky; - module.exports = exports['default']; - -/***/ }, -/* 35 */ /***/ function(module, exports, __webpack_require__) { /** @@ -5091,7 +3782,7 @@ return /******/ (function(modules) { // webpackBootstrap * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors * Available under MIT license */ - var debounce = __webpack_require__(36); + var debounce = __webpack_require__(23); /** Used as the `TypeError` message for "Functions" methods. */ var FUNC_ERROR_TEXT = 'Expected a function'; @@ -5186,7 +3877,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 36 */ +/* 23 */ /***/ function(module, exports) { /** @@ -5586,7 +4277,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 37 */ +/* 24 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -5595,7 +4286,2110 @@ return /******/ (function(modules) { // webpackBootstrap function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - var _ControlsOrbit = __webpack_require__(38); + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + var _vendorEffectComposer = __webpack_require__(25); + + var _vendorEffectComposer2 = _interopRequireDefault(_vendorEffectComposer); + + exports['default'] = function (renderer, container) { + var composer = new _vendorEffectComposer2['default'](renderer); + + var updateSize = function updateSize() { + // TODO: Re-enable this when perf issues can be solved + // + // Rendering double the resolution of the screen can be really slow + // var pixelRatio = window.devicePixelRatio; + var pixelRatio = 1; + + composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio); + }; + + window.addEventListener('resize', updateSize, false); + updateSize(); + + return composer; + }; + + ; + module.exports = exports['default']; + +/***/ }, +/* 25 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + var _CopyShader = __webpack_require__(26); + + var _CopyShader2 = _interopRequireDefault(_CopyShader); + + var _ShaderPass = __webpack_require__(27); + + var _ShaderPass2 = _interopRequireDefault(_ShaderPass); + + var _MaskPass = __webpack_require__(28); + + var _MaskPass2 = _interopRequireDefault(_MaskPass); + + /** + * @author alteredq / http://alteredqualia.com/ + */ + + var EffectComposer = function EffectComposer(renderer, renderTarget) { + + this.renderer = renderer; + + if (renderTarget === undefined) { + + var pixelRatio = renderer.getPixelRatio(); + + var width = Math.floor(renderer.context.canvas.width / pixelRatio) || 1; + var height = Math.floor(renderer.context.canvas.height / pixelRatio) || 1; + var parameters = { minFilter: _three2['default'].LinearFilter, magFilter: _three2['default'].LinearFilter, format: _three2['default'].RGBAFormat, stencilBuffer: false }; + + renderTarget = new _three2['default'].WebGLRenderTarget(width, height, parameters); + } + + this.renderTarget1 = renderTarget; + this.renderTarget2 = renderTarget.clone(); + + this.writeBuffer = this.renderTarget1; + this.readBuffer = this.renderTarget2; + + this.passes = []; + + if (_CopyShader2['default'] === undefined) console.error("EffectComposer relies on THREE.CopyShader"); + + this.copyPass = new _ShaderPass2['default'](_CopyShader2['default']); + }; + + EffectComposer.prototype = { + + swapBuffers: function swapBuffers() { + + var tmp = this.readBuffer; + this.readBuffer = this.writeBuffer; + this.writeBuffer = tmp; + }, + + addPass: function addPass(pass) { + + this.passes.push(pass); + }, + + insertPass: function insertPass(pass, index) { + + this.passes.splice(index, 0, pass); + }, + + render: function render(delta) { + + this.writeBuffer = this.renderTarget1; + this.readBuffer = this.renderTarget2; + + var maskActive = false; + + var pass, + i, + il = this.passes.length; + + for (i = 0; i < il; i++) { + + pass = this.passes[i]; + + if (!pass.enabled) continue; + + pass.render(this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive); + + if (pass.needsSwap) { + + if (maskActive) { + + var context = this.renderer.context; + + context.stencilFunc(context.NOTEQUAL, 1, 0xffffffff); + + this.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, delta); + + context.stencilFunc(context.EQUAL, 1, 0xffffffff); + } + + this.swapBuffers(); + } + + if (pass instanceof _MaskPass2['default']) { + + maskActive = true; + } else if (pass instanceof _MaskPass.ClearMaskPass) { + + maskActive = false; + } + } + }, + + reset: function reset(renderTarget) { + + if (renderTarget === undefined) { + + renderTarget = this.renderTarget1.clone(); + + var pixelRatio = this.renderer.getPixelRatio(); + + renderTarget.setSize(Math.floor(this.renderer.context.canvas.width / pixelRatio), Math.floor(this.renderer.context.canvas.height / pixelRatio)); + } + + this.renderTarget1.dispose(); + this.renderTarget1 = renderTarget; + this.renderTarget2.dispose(); + this.renderTarget2 = renderTarget.clone(); + + this.writeBuffer = this.renderTarget1; + this.readBuffer = this.renderTarget2; + }, + + setSize: function setSize(width, height) { + + this.renderTarget1.setSize(width, height); + this.renderTarget2.setSize(width, height); + } + + }; + + exports['default'] = EffectComposer; + + _three2['default'].EffectComposer = EffectComposer; + module.exports = exports['default']; + +/***/ }, +/* 26 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + * + * Full-screen textured quad shader + */ + + var CopyShader = { + + uniforms: { + + "tDiffuse": { type: "t", value: null }, + "opacity": { type: "f", value: 1.0 } + + }, + + vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), + + fragmentShader: ["uniform float opacity;", "uniform sampler2D tDiffuse;", "varying vec2 vUv;", "void main() {", "vec4 texel = texture2D( tDiffuse, vUv );", "gl_FragColor = opacity * texel;", "}"].join("\n") + + }; + + exports["default"] = CopyShader; + + _three2["default"].CopyShader = CopyShader; + module.exports = exports["default"]; + +/***/ }, +/* 27 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + */ + + var ShaderPass = function ShaderPass(shader, textureID) { + + this.textureID = textureID !== undefined ? textureID : "tDiffuse"; + + if (shader instanceof _three2["default"].ShaderMaterial) { + + this.uniforms = shader.uniforms; + + this.material = shader; + } else if (shader) { + + this.uniforms = _three2["default"].UniformsUtils.clone(shader.uniforms); + + this.material = new _three2["default"].ShaderMaterial({ + + defines: shader.defines || {}, + uniforms: this.uniforms, + vertexShader: shader.vertexShader, + fragmentShader: shader.fragmentShader + + }); + } + + this.renderToScreen = false; + + this.enabled = true; + this.needsSwap = true; + this.clear = false; + + this.camera = new _three2["default"].OrthographicCamera(-1, 1, 1, -1, 0, 1); + this.scene = new _three2["default"].Scene(); + + this.quad = new _three2["default"].Mesh(new _three2["default"].PlaneBufferGeometry(2, 2), null); + this.scene.add(this.quad); + }; + + ShaderPass.prototype = { + + render: function render(renderer, writeBuffer, readBuffer, delta) { + + if (this.uniforms[this.textureID]) { + + this.uniforms[this.textureID].value = readBuffer; + } + + this.quad.material = this.material; + + if (this.renderToScreen) { + + renderer.render(this.scene, this.camera); + } else { + + renderer.render(this.scene, this.camera, writeBuffer, this.clear); + } + } + + }; + + exports["default"] = ShaderPass; + + _three2["default"].ShaderPass = ShaderPass; + module.exports = exports["default"]; + +/***/ }, +/* 28 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + */ + + var MaskPass = function MaskPass(scene, camera) { + + this.scene = scene; + this.camera = camera; + + this.enabled = true; + this.clear = true; + this.needsSwap = false; + + this.inverse = false; + }; + + MaskPass.prototype = { + + render: function render(renderer, writeBuffer, readBuffer, delta) { + + var context = renderer.context; + + // don't update color or depth + + context.colorMask(false, false, false, false); + context.depthMask(false); + + // set up stencil + + var writeValue, clearValue; + + if (this.inverse) { + + writeValue = 0; + clearValue = 1; + } else { + + writeValue = 1; + clearValue = 0; + } + + context.enable(context.STENCIL_TEST); + context.stencilOp(context.REPLACE, context.REPLACE, context.REPLACE); + context.stencilFunc(context.ALWAYS, writeValue, 0xffffffff); + context.clearStencil(clearValue); + + // draw into the stencil buffer + + renderer.render(this.scene, this.camera, readBuffer, this.clear); + renderer.render(this.scene, this.camera, writeBuffer, this.clear); + + // re-enable update of color and depth + + context.colorMask(true, true, true, true); + context.depthMask(true); + + // only render where stencil is set to 1 + + context.stencilFunc(context.EQUAL, 1, 0xffffffff); // draw if == 1 + context.stencilOp(context.KEEP, context.KEEP, context.KEEP); + } + + }; + + var ClearMaskPass = function ClearMaskPass() { + + this.enabled = true; + }; + + ClearMaskPass.prototype = { + + render: function render(renderer, writeBuffer, readBuffer, delta) { + + var context = renderer.context; + + context.disable(context.STENCIL_TEST); + } + + }; + + exports['default'] = MaskPass; + exports.ClearMaskPass = ClearMaskPass; + + _three2['default'].MaskPass = MaskPass; + _three2['default'].ClearMaskPass = ClearMaskPass; + +/***/ }, +/* 29 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + */ + + var RenderPass = function RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha) { + + this.scene = scene; + this.camera = camera; + + this.overrideMaterial = overrideMaterial; + + this.clearColor = clearColor; + this.clearAlpha = clearAlpha !== undefined ? clearAlpha : 1; + + this.oldClearColor = new _three2['default'].Color(); + this.oldClearAlpha = 1; + + this.enabled = true; + this.clear = true; + this.needsSwap = false; + }; + + RenderPass.prototype = { + + render: function render(renderer, writeBuffer, readBuffer, delta) { + + this.scene.overrideMaterial = this.overrideMaterial; + + if (this.clearColor) { + + this.oldClearColor.copy(renderer.getClearColor()); + this.oldClearAlpha = renderer.getClearAlpha(); + + renderer.setClearColor(this.clearColor, this.clearAlpha); + } + + renderer.render(this.scene, this.camera, readBuffer, this.clear); + + if (this.clearColor) { + + renderer.setClearColor(this.oldClearColor, this.oldClearAlpha); + } + + this.scene.overrideMaterial = null; + } + + }; + + exports['default'] = RenderPass; + + _three2['default'].RenderPass = RenderPass; + module.exports = exports['default']; + +/***/ }, +/* 30 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + * + * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position + * + * - 9 samples per pass + * - standard deviation 2.7 + * - "h" and "v" parameters should be set to "1 / width" and "1 / height" + * - "r" parameter control where "focused" horizontal line lies + */ + + var HorizontalTiltShiftShader = { + + uniforms: { + + "tDiffuse": { type: "t", value: null }, + "h": { type: "f", value: 1.0 / 512.0 }, + "r": { type: "f", value: 0.35 } + + }, + + vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), + + fragmentShader: ["uniform sampler2D tDiffuse;", "uniform float h;", "uniform float r;", "varying vec2 vUv;", "void main() {", "vec4 sum = vec4( 0.0 );", "float hh = h * abs( r - vUv.y );", "sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;", "sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", "sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;", "gl_FragColor = sum;", "}"].join("\n") + + }; + + exports["default"] = HorizontalTiltShiftShader; + + _three2["default"].HorizontalTiltShiftShader = HorizontalTiltShiftShader; + module.exports = exports["default"]; + +/***/ }, +/* 31 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + * + * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position + * + * - 9 samples per pass + * - standard deviation 2.7 + * - "h" and "v" parameters should be set to "1 / width" and "1 / height" + * - "r" parameter control where "focused" horizontal line lies + */ + + var VerticalTiltShiftShader = { + + uniforms: { + + "tDiffuse": { type: "t", value: null }, + "v": { type: "f", value: 1.0 / 512.0 }, + "r": { type: "f", value: 0.35 } + + }, + + vertexShader: ["varying vec2 vUv;", "void main() {", "vUv = uv;", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), + + fragmentShader: ["uniform sampler2D tDiffuse;", "uniform float v;", "uniform float r;", "varying vec2 vUv;", "void main() {", "vec4 sum = vec4( 0.0 );", "float vv = v * abs( r - vUv.y );", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;", "sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;", "gl_FragColor = sum;", "}"].join("\n") + + }; + + exports["default"] = VerticalTiltShiftShader; + + _three2["default"].VerticalTiltShiftShader = VerticalTiltShiftShader; + module.exports = exports["default"]; + +/***/ }, +/* 32 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, "__esModule", { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { "default": obj }; } + + // jscs:disable + /* eslint-disable */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + /** + * @author alteredq / http://alteredqualia.com/ + * @author davidedc / http://www.sketchpatch.net/ + * + * NVIDIA FXAA by Timothy Lottes + * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html + * - WebGL port by @supereggbert + * http://www.glge.org/demos/fxaa/ + */ + + var FXAAShader = { + + uniforms: { + + "tDiffuse": { type: "t", value: null }, + "resolution": { type: "v2", value: new _three2["default"].Vector2(1 / 1024, 1 / 512) } + + }, + + vertexShader: ["void main() {", "gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );", "}"].join("\n"), + + fragmentShader: ["uniform sampler2D tDiffuse;", "uniform vec2 resolution;", "#define FXAA_REDUCE_MIN (1.0/128.0)", "#define FXAA_REDUCE_MUL (1.0/8.0)", "#define FXAA_SPAN_MAX 8.0", "void main() {", "vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;", "vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;", "vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;", "vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;", "vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );", "vec3 rgbM = rgbaM.xyz;", "vec3 luma = vec3( 0.299, 0.587, 0.114 );", "float lumaNW = dot( rgbNW, luma );", "float lumaNE = dot( rgbNE, luma );", "float lumaSW = dot( rgbSW, luma );", "float lumaSE = dot( rgbSE, luma );", "float lumaM = dot( rgbM, luma );", "float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );", "float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );", "vec2 dir;", "dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));", "dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));", "float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );", "float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );", "dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),", "max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),", "dir * rcpDirMin)) * resolution;", "vec4 rgbA = (1.0/2.0) * (", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));", "vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +", "texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));", "float lumaB = dot(rgbB, vec4(luma, 0.0));", "if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {", "gl_FragColor = rgbA;", "} else {", "gl_FragColor = rgbB;", "}", "}"].join("\n") + + }; + + exports["default"] = FXAAShader; + + _three2["default"].FXAAShader = FXAAShader; + module.exports = exports["default"]; + +/***/ }, +/* 33 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _Layer2 = __webpack_require__(34); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(3); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + var _Skybox = __webpack_require__(44); + + var _Skybox2 = _interopRequireDefault(_Skybox); + + // TODO: Make sure nothing is left behind in the heap after calling destroy() + + var EnvironmentLayer = (function (_Layer) { + _inherits(EnvironmentLayer, _Layer); + + function EnvironmentLayer(options) { + _classCallCheck(this, EnvironmentLayer); + + var defaults = { + skybox: false + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'constructor', this).call(this, _options); + } + + _createClass(EnvironmentLayer, [{ + key: '_onAdd', + value: function _onAdd() { + this._initLights(); + + if (this._options.skybox) { + this._initSkybox(); + } + + // this._initGrid(); + + return Promise.resolve(this); + } + + // Not fleshed out or thought through yet + // + // Lights could potentially be put it their own 'layer' to keep this class + // much simpler and less messy + }, { + key: '_initLights', + value: function _initLights() { + // Position doesn't really matter (the angle is important), however it's + // used here so the helpers look more natural. + + if (!this._options.skybox) { + var directionalLight = new _three2['default'].DirectionalLight(0xffffff, 1); + directionalLight.position.x = 10000; + directionalLight.position.y = 10000; + directionalLight.position.z = 10000; + + // TODO: Get shadows working in non-PBR scenes + + // directionalLight.castShadow = true; + // + // var d = 100; + // directionalLight.shadow.camera.left = -d; + // directionalLight.shadow.camera.right = d; + // directionalLight.shadow.camera.top = d; + // directionalLight.shadow.camera.bottom = -d; + // + // directionalLight.shadow.camera.near = 10; + // directionalLight.shadow.camera.far = 100; + // + // // TODO: Need to dial in on a good shadowmap size + // directionalLight.shadow.mapSize.width = 2048; + // directionalLight.shadow.mapSize.height = 2048; + // + // // directionalLight.shadowBias = -0.0010; + // // directionalLight.shadow.darkness = 0.15; + + var directionalLight2 = new _three2['default'].DirectionalLight(0xffffff, 0.5); + directionalLight2.position.x = -10000; + directionalLight2.position.y = 10000; + directionalLight2.position.z = 0; + + var directionalLight3 = new _three2['default'].DirectionalLight(0xffffff, 0.5); + directionalLight3.position.x = 10000; + directionalLight3.position.y = 10000; + directionalLight3.position.z = -10000; + + this.add(directionalLight); + this.add(directionalLight2); + this.add(directionalLight3); + + // var helper = new THREE.DirectionalLightHelper(directionalLight, 10); + // var helper2 = new THREE.DirectionalLightHelper(directionalLight2, 10); + // var helper3 = new THREE.DirectionalLightHelper(directionalLight3, 10); + // + // this.add(helper); + // this.add(helper2); + // this.add(helper3); + } else { + // Directional light that will be projected from the sun + this._skyboxLight = new _three2['default'].DirectionalLight(0xffffff, 1); + + this._skyboxLight.castShadow = true; + + var d = 10000; + this._skyboxLight.shadow.camera.left = -d; + this._skyboxLight.shadow.camera.right = d; + this._skyboxLight.shadow.camera.top = d; + this._skyboxLight.shadow.camera.bottom = -d; + + this._skyboxLight.shadow.camera.near = 10000; + this._skyboxLight.shadow.camera.far = 70000; + + // TODO: Need to dial in on a good shadowmap size + this._skyboxLight.shadow.mapSize.width = 2048; + this._skyboxLight.shadow.mapSize.height = 2048; + + // this._skyboxLight.shadowBias = -0.0010; + // this._skyboxLight.shadow.darkness = 0.15; + + // this._object3D.add(new THREE.CameraHelper(this._skyboxLight.shadow.camera)); + + this.add(this._skyboxLight); + } + } + }, { + key: '_initSkybox', + value: function _initSkybox() { + this._skybox = new _Skybox2['default'](this._world, this._skyboxLight); + this.add(this._skybox._mesh); + } + + // Add grid helper for context during initial development + }, { + key: '_initGrid', + value: function _initGrid() { + var size = 4000; + var step = 100; + + var gridHelper = new _three2['default'].GridHelper(size, step); + this.add(gridHelper); + } + + // Clean up environment + }, { + key: 'destroy', + value: function destroy() { + this._skyboxLight = null; + + this.remove(this._skybox._mesh); + this._skybox.destroy(); + this._skybox = null; + + _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'destroy', this).call(this); + } + }]); + + return EnvironmentLayer; + })(_Layer3['default']); + + exports['default'] = EnvironmentLayer; + + var noNew = function noNew(options) { + return new EnvironmentLayer(options); + }; + + // Initialise without requiring new keyword + exports.environmentLayer = noNew; + +/***/ }, +/* 34 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _eventemitter3 = __webpack_require__(2); + + var _eventemitter32 = _interopRequireDefault(_eventemitter3); + + var _lodashAssign = __webpack_require__(3); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _shortid = __webpack_require__(35); + + var _shortid2 = _interopRequireDefault(_shortid); + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + var _engineScene = __webpack_require__(11); + + var _engineScene2 = _interopRequireDefault(_engineScene); + + var _vendorCSS3DRenderer = __webpack_require__(16); + + var _vendorCSS2DRenderer = __webpack_require__(18); + + // TODO: Make sure nothing is left behind in the heap after calling destroy() + + // TODO: Need a single move method that handles moving all the various object + // layers so that the DOM layers stay in sync with the 3D layer + + // TODO: Double check that objects within the _object3D Object3D parent are frustum + // culled even if the layer position stays at the default (0,0,0) and the child + // objects are positioned much further away + // + // Or does the layer being at (0,0,0) prevent the child objects from being + // culled because the layer parent is effectively always in view even if the + // child is actually out of camera + + var Layer = (function (_EventEmitter) { + _inherits(Layer, _EventEmitter); + + function Layer(options) { + _classCallCheck(this, Layer); + + _get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this); + + var defaults = { + id: _shortid2['default'].generate(), + output: true, + outputToScene: true + }; + + this._options = (0, _lodashAssign2['default'])({}, defaults, options); + + if (this.isOutput()) { + this._object3D = new _three2['default'].Object3D(); + + this._dom3D = document.createElement('div'); + this._domObject3D = new _vendorCSS3DRenderer.CSS3DObject(this._dom3D); + + this._dom2D = document.createElement('div'); + this._domObject2D = new _vendorCSS2DRenderer.CSS2DObject(this._dom2D); + } + } + + // Add THREE object directly to layer + + _createClass(Layer, [{ + key: 'add', + value: function add(object) { + this._object3D.add(object); + } + + // Remove THREE object from to layer + }, { + key: 'remove', + value: function remove(object) { + this._object3D.remove(object); + } + }, { + key: 'addDOM3D', + value: function addDOM3D(object) { + this._domObject3D.add(object); + } + }, { + key: 'removeDOM3D', + value: function removeDOM3D(object) { + this._domObject3D.remove(object); + } + }, { + key: 'addDOM2D', + value: function addDOM2D(object) { + this._domObject2D.add(object); + } + }, { + key: 'removeDOM2D', + value: function removeDOM2D(object) { + this._domObject2D.remove(object); + } + + // Add layer to world instance and store world reference + }, { + key: 'addTo', + value: function addTo(world) { + return world.addLayer(this); + } + + // Internal method called by World.addLayer to actually add the layer + }, { + key: '_addToWorld', + value: function _addToWorld(world) { + var _this = this; + + this._world = world; + + return new Promise(function (resolve, reject) { + _this._onAdd(world).then(function () { + _this.emit('added'); + resolve(_this); + })['catch'](reject); + }); + } + + // Must return a promise + }, { + key: '_onAdd', + value: function _onAdd(world) { + return Promise.resolve(this); + } + }, { + key: 'getPickingId', + value: function getPickingId() { + if (this._world._engine._picking) { + return this._world._engine._picking.getNextId(); + } + + return false; + } + + // TODO: Tidy this up and don't access so many private properties to work + }, { + key: 'addToPicking', + value: function addToPicking(object) { + if (!this._world._engine._picking) { + return; + } + + this._world._engine._picking.add(object); + } + }, { + key: 'removeFromPicking', + value: function removeFromPicking(object) { + if (!this._world._engine._picking) { + return; + } + + this._world._engine._picking.remove(object); + } + }, { + key: 'isOutput', + value: function isOutput() { + return this._options.output; + } + }, { + key: 'isOutputToScene', + value: function isOutputToScene() { + return this._options.outputToScene; + } + + // TODO: Also hide any attached DOM layers + }, { + key: 'hide', + value: function hide() { + this._object3D.visible = false; + + if (this._pickingMesh) { + this._pickingMesh.visible = false; + } + } + + // TODO: Also show any attached DOM layers + }, { + key: 'show', + value: function show() { + this._object3D.visible = true; + + if (this._pickingMesh) { + this._pickingMesh.visible = true; + } + } + + // Destroys the layer and removes it from the scene and memory + }, { + key: 'destroy', + value: function destroy() { + if (this._object3D && this._object3D.children) { + // Remove everything else in the layer + var child; + for (var i = this._object3D.children.length - 1; i >= 0; i--) { + child = this._object3D.children[i]; + + if (!child) { + continue; + } + + this.remove(child); + + if (child.geometry) { + // Dispose of mesh and materials + child.geometry.dispose(); + child.geometry = null; + } + + if (child.material) { + if (child.material.map) { + child.material.map.dispose(); + child.material.map = null; + } + + child.material.dispose(); + child.material = null; + } + } + } + + if (this._domObject3D && this._domObject3D.children) { + // Remove everything else in the layer + var child; + for (var i = this._domObject3D.children.length - 1; i >= 0; i--) { + child = this._domObject3D.children[i]; + + if (!child) { + continue; + } + + this.removeDOM3D(child); + } + } + + if (this._domObject2D && this._domObject2D.children) { + // Remove everything else in the layer + var child; + for (var i = this._domObject2D.children.length - 1; i >= 0; i--) { + child = this._domObject2D.children[i]; + + if (!child) { + continue; + } + + this.removeDOM2D(child); + } + } + + this._domObject3D = null; + this._domObject2D = null; + + this._world = null; + this._object3D = null; + } + }]); + + return Layer; + })(_eventemitter32['default']); + + exports['default'] = Layer; + + var noNew = function noNew(options) { + return new Layer(options); + }; + + exports.layer = noNew; + +/***/ }, +/* 35 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + module.exports = __webpack_require__(36); + + +/***/ }, +/* 36 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var alphabet = __webpack_require__(37); + var encode = __webpack_require__(39); + var decode = __webpack_require__(41); + var isValid = __webpack_require__(42); + + // Ignore all milliseconds before a certain time to reduce the size of the date entropy without sacrificing uniqueness. + // This number should be updated every year or so to keep the generated id short. + // To regenerate `new Date() - 0` and bump the version. Always bump the version! + var REDUCE_TIME = 1459707606518; + + // don't change unless we change the algos or REDUCE_TIME + // must be an integer and less than 16 + var version = 6; + + // if you are using cluster or multiple servers use this to make each instance + // has a unique value for worker + // Note: I don't know if this is automatically set when using third + // party cluster solutions such as pm2. + var clusterWorkerId = __webpack_require__(43) || 0; + + // Counter is used when shortid is called multiple times in one second. + var counter; + + // Remember the last time shortid was called in case counter is needed. + var previousSeconds; + + /** + * Generate unique id + * Returns string id + */ + function generate() { + + var str = ''; + + var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001); + + if (seconds === previousSeconds) { + counter++; + } else { + counter = 0; + previousSeconds = seconds; + } + + str = str + encode(alphabet.lookup, version); + str = str + encode(alphabet.lookup, clusterWorkerId); + if (counter > 0) { + str = str + encode(alphabet.lookup, counter); + } + str = str + encode(alphabet.lookup, seconds); + + return str; + } + + + /** + * Set the seed. + * Highly recommended if you don't want people to try to figure out your id schema. + * exposed as shortid.seed(int) + * @param seed Integer value to seed the random alphabet. ALWAYS USE THE SAME SEED or you might get overlaps. + */ + function seed(seedValue) { + alphabet.seed(seedValue); + return module.exports; + } + + /** + * Set the cluster worker or machine id + * exposed as shortid.worker(int) + * @param workerId worker must be positive integer. Number less than 16 is recommended. + * returns shortid module so it can be chained. + */ + function worker(workerId) { + clusterWorkerId = workerId; + return module.exports; + } + + /** + * + * sets new characters to use in the alphabet + * returns the shuffled alphabet + */ + function characters(newCharacters) { + if (newCharacters !== undefined) { + alphabet.characters(newCharacters); + } + + return alphabet.shuffled(); + } + + + // Export all other functions as properties of the generate function + module.exports = generate; + module.exports.generate = generate; + module.exports.seed = seed; + module.exports.worker = worker; + module.exports.characters = characters; + module.exports.decode = decode; + module.exports.isValid = isValid; + + +/***/ }, +/* 37 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var randomFromSeed = __webpack_require__(38); + + var ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-'; + var alphabet; + var previousSeed; + + var shuffled; + + function reset() { + shuffled = false; + } + + function setCharacters(_alphabet_) { + if (!_alphabet_) { + if (alphabet !== ORIGINAL) { + alphabet = ORIGINAL; + reset(); + } + return; + } + + if (_alphabet_ === alphabet) { + return; + } + + if (_alphabet_.length !== ORIGINAL.length) { + throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_); + } + + var unique = _alphabet_.split('').filter(function(item, ind, arr){ + return ind !== arr.lastIndexOf(item); + }); + + if (unique.length) { + throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', ')); + } + + alphabet = _alphabet_; + reset(); + } + + function characters(_alphabet_) { + setCharacters(_alphabet_); + return alphabet; + } + + function setSeed(seed) { + randomFromSeed.seed(seed); + if (previousSeed !== seed) { + reset(); + previousSeed = seed; + } + } + + function shuffle() { + if (!alphabet) { + setCharacters(ORIGINAL); + } + + var sourceArray = alphabet.split(''); + var targetArray = []; + var r = randomFromSeed.nextValue(); + var characterIndex; + + while (sourceArray.length > 0) { + r = randomFromSeed.nextValue(); + characterIndex = Math.floor(r * sourceArray.length); + targetArray.push(sourceArray.splice(characterIndex, 1)[0]); + } + return targetArray.join(''); + } + + function getShuffled() { + if (shuffled) { + return shuffled; + } + shuffled = shuffle(); + return shuffled; + } + + /** + * lookup shuffled letter + * @param index + * @returns {string} + */ + function lookup(index) { + var alphabetShuffled = getShuffled(); + return alphabetShuffled[index]; + } + + module.exports = { + characters: characters, + seed: setSeed, + lookup: lookup, + shuffled: getShuffled + }; + + +/***/ }, +/* 38 */ +/***/ function(module, exports) { + + 'use strict'; + + // Found this seed-based random generator somewhere + // Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu) + + var seed = 1; + + /** + * return a random number based on a seed + * @param seed + * @returns {number} + */ + function getNextValue() { + seed = (seed * 9301 + 49297) % 233280; + return seed/(233280.0); + } + + function setSeed(_seed_) { + seed = _seed_; + } + + module.exports = { + nextValue: getNextValue, + seed: setSeed + }; + + +/***/ }, +/* 39 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + + var randomByte = __webpack_require__(40); + + function encode(lookup, number) { + var loopCounter = 0; + var done; + + var str = ''; + + while (!done) { + str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() ); + done = number < (Math.pow(16, loopCounter + 1 ) ); + loopCounter++; + } + return str; + } + + module.exports = encode; + + +/***/ }, +/* 40 */ +/***/ function(module, exports) { + + 'use strict'; + + var crypto = typeof window === 'object' && (window.crypto || window.msCrypto); // IE 11 uses window.msCrypto + + function randomByte() { + if (!crypto || !crypto.getRandomValues) { + return Math.floor(Math.random() * 256) & 0x30; + } + var dest = new Uint8Array(1); + crypto.getRandomValues(dest); + return dest[0] & 0x30; + } + + module.exports = randomByte; + + +/***/ }, +/* 41 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + var alphabet = __webpack_require__(37); + + /** + * Decode the id to get the version and worker + * Mainly for debugging and testing. + * @param id - the shortid-generated id. + */ + function decode(id) { + var characters = alphabet.shuffled(); + return { + version: characters.indexOf(id.substr(0, 1)) & 0x0f, + worker: characters.indexOf(id.substr(1, 1)) & 0x0f + }; + } + + module.exports = decode; + + +/***/ }, +/* 42 */ +/***/ function(module, exports, __webpack_require__) { + + 'use strict'; + var alphabet = __webpack_require__(37); + + function isShortId(id) { + if (!id || typeof id !== 'string' || id.length < 6 ) { + return false; + } + + var characters = alphabet.characters(); + var len = id.length; + for(var i = 0; i < len;i++) { + if (characters.indexOf(id[i]) === -1) { + return false; + } + } + return true; + } + + module.exports = isShortId; + + +/***/ }, +/* 43 */ +/***/ function(module, exports) { + + 'use strict'; + + module.exports = 0; + + +/***/ }, +/* 44 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + var _Sky = __webpack_require__(45); + + var _Sky2 = _interopRequireDefault(_Sky); + + var _lodashThrottle = __webpack_require__(22); + + var _lodashThrottle2 = _interopRequireDefault(_lodashThrottle); + + // TODO: Make sure nothing is left behind in the heap after calling destroy() + + var cubemap = { + vertexShader: ['varying vec3 vPosition;', 'void main() {', 'vPosition = position;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'), + + fragmentShader: ['uniform samplerCube cubemap;', 'varying vec3 vPosition;', 'void main() {', 'gl_FragColor = textureCube(cubemap, normalize(vPosition));', '}'].join('\n') + }; + + var Skybox = (function () { + function Skybox(world, light) { + _classCallCheck(this, Skybox); + + this._world = world; + this._light = light; + + this._settings = { + distance: 38000, + turbidity: 10, + reileigh: 2, + mieCoefficient: 0.005, + mieDirectionalG: 0.8, + luminance: 1, + // 0.48 is a cracking dusk / sunset + // 0.4 is a beautiful early-morning / late-afternoon + // 0.2 is a nice day time + inclination: 0.48, // Elevation / inclination + azimuth: 0.25 }; + + // Facing front + this._initSkybox(); + this._updateUniforms(); + this._initEvents(); + } + + _createClass(Skybox, [{ + key: '_initEvents', + value: function _initEvents() { + // Throttled to 1 per 100ms + this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._update, 100); + this._world.on('preUpdate', this._throttledWorldUpdate, this); + } + }, { + key: '_initSkybox', + value: function _initSkybox() { + // Cube camera for skybox + this._cubeCamera = new _three2['default'].CubeCamera(1, 20000000, 128); + + // Cube material + var cubeTarget = this._cubeCamera.renderTarget; + + // Add Sky Mesh + this._sky = new _Sky2['default'](); + this._skyScene = new _three2['default'].Scene(); + this._skyScene.add(this._sky.mesh); + + // Add Sun Helper + this._sunSphere = new _three2['default'].Mesh(new _three2['default'].SphereBufferGeometry(2000, 16, 8), new _three2['default'].MeshBasicMaterial({ + color: 0xffffff + })); + + // TODO: This isn't actually visible because it's not added to the layer + // this._sunSphere.visible = true; + + var skyboxUniforms = { + cubemap: { type: 't', value: cubeTarget } + }; + + var skyboxMat = new _three2['default'].ShaderMaterial({ + uniforms: skyboxUniforms, + vertexShader: cubemap.vertexShader, + fragmentShader: cubemap.fragmentShader, + side: _three2['default'].BackSide + }); + + this._mesh = new _three2['default'].Mesh(new _three2['default'].BoxGeometry(1900000, 1900000, 1900000), skyboxMat); + + this._updateSkybox = true; + } + }, { + key: '_updateUniforms', + value: function _updateUniforms() { + var settings = this._settings; + var uniforms = this._sky.uniforms; + uniforms.turbidity.value = settings.turbidity; + uniforms.reileigh.value = settings.reileigh; + uniforms.luminance.value = settings.luminance; + uniforms.mieCoefficient.value = settings.mieCoefficient; + uniforms.mieDirectionalG.value = settings.mieDirectionalG; + + var theta = Math.PI * (settings.inclination - 0.5); + var phi = 2 * Math.PI * (settings.azimuth - 0.5); + + this._sunSphere.position.x = settings.distance * Math.cos(phi); + this._sunSphere.position.y = settings.distance * Math.sin(phi) * Math.sin(theta); + this._sunSphere.position.z = settings.distance * Math.sin(phi) * Math.cos(theta); + + // Move directional light to sun position + this._light.position.copy(this._sunSphere.position); + + this._sky.uniforms.sunPosition.value.copy(this._sunSphere.position); + } + }, { + key: '_update', + value: function _update(delta) { + if (this._updateSkybox) { + this._updateSkybox = false; + } else { + return; + } + + // if (!this._angle) { + // this._angle = 0; + // } + // + // // Animate inclination + // this._angle += Math.PI * delta; + // this._settings.inclination = 0.5 * (Math.sin(this._angle) / 2 + 0.5); + + // Update light intensity depending on elevation of sun (day to night) + this._light.intensity = 1 - 0.95 * (this._settings.inclination / 0.5); + + // // console.log(delta, this._angle, this._settings.inclination); + // + // TODO: Only do this when the uniforms have been changed + this._updateUniforms(); + + // TODO: Only do this when the cubemap has actually changed + this._cubeCamera.updateCubeMap(this._world._engine._renderer, this._skyScene); + } + }, { + key: 'getRenderTarget', + value: function getRenderTarget() { + return this._cubeCamera.renderTarget; + } + }, { + key: 'setInclination', + value: function setInclination(inclination) { + this._settings.inclination = inclination; + this._updateSkybox = true; + } + + // Destroy the skybox and remove it from memory + }, { + key: 'destroy', + value: function destroy() { + this._world.off('preUpdate', this._throttledWorldUpdate); + this._throttledWorldUpdate = null; + + this._world = null; + this._light = null; + + this._cubeCamera = null; + + this._sky.mesh.geometry.dispose(); + this._sky.mesh.geometry = null; + + if (this._sky.mesh.material.map) { + this._sky.mesh.material.map.dispose(); + this._sky.mesh.material.map = null; + } + + this._sky.mesh.material.dispose(); + this._sky.mesh.material = null; + + this._sky.mesh = null; + this._sky = null; + + this._skyScene = null; + + this._sunSphere.geometry.dispose(); + this._sunSphere.geometry = null; + + if (this._sunSphere.material.map) { + this._sunSphere.material.map.dispose(); + this._sunSphere.material.map = null; + } + + this._sunSphere.material.dispose(); + this._sunSphere.material = null; + + this._sunSphere = null; + + this._mesh.geometry.dispose(); + this._mesh.geometry = null; + + if (this._mesh.material.map) { + this._mesh.material.map.dispose(); + this._mesh.material.map = null; + } + + this._mesh.material.dispose(); + this._mesh.material = null; + } + }]); + + return Skybox; + })(); + + exports['default'] = Skybox; + + var noNew = function noNew(world, light) { + return new Skybox(world, light); + }; + + // Initialise without requiring new keyword + exports.skybox = noNew; + +/***/ }, +/* 45 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + // jscs:disable + /*eslint eqeqeq:0*/ + + /** + * @author zz85 / https://github.com/zz85 + * + * Based on 'A Practical Analytic Model for Daylight' + * aka The Preetham Model, the de facto standard analytic skydome model + * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf + * + * First implemented by Simon Wallner + * http://www.simonwallner.at/projects/atmospheric-scattering + * + * Improved by Martin Upitis + * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR + * + * Three.js integration by zz85 http://twitter.com/blurspline + */ + + var _three = __webpack_require__(10); + + var _three2 = _interopRequireDefault(_three); + + _three2['default'].ShaderLib['sky'] = { + + uniforms: { + + luminance: { type: 'f', value: 1 }, + turbidity: { type: 'f', value: 2 }, + reileigh: { type: 'f', value: 1 }, + mieCoefficient: { type: 'f', value: 0.005 }, + mieDirectionalG: { type: 'f', value: 0.8 }, + sunPosition: { type: 'v3', value: new _three2['default'].Vector3() } + + }, + + vertexShader: ['varying vec3 vWorldPosition;', 'void main() {', 'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', 'vWorldPosition = worldPosition.xyz;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\n'), + + fragmentShader: ['uniform sampler2D skySampler;', 'uniform vec3 sunPosition;', 'varying vec3 vWorldPosition;', 'vec3 cameraPos = vec3(0., 0., 0.);', '// uniform sampler2D sDiffuse;', '// const float turbidity = 10.0; //', '// const float reileigh = 2.; //', '// const float luminance = 1.0; //', '// const float mieCoefficient = 0.005;', '// const float mieDirectionalG = 0.8;', 'uniform float luminance;', 'uniform float turbidity;', 'uniform float reileigh;', 'uniform float mieCoefficient;', 'uniform float mieDirectionalG;', '// constants for atmospheric scattering', 'const float e = 2.71828182845904523536028747135266249775724709369995957;', 'const float pi = 3.141592653589793238462643383279502884197169;', 'const float n = 1.0003; // refractive index of air', 'const float N = 2.545E25; // number of molecules per unit volume for air at', '// 288.15K and 1013mb (sea level -45 celsius)', 'const float pn = 0.035; // depolatization factor for standard air', '// wavelength of used primaries, according to preetham', 'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);', '// mie stuff', '// K coefficient for the primaries', 'const vec3 K = vec3(0.686, 0.678, 0.666);', 'const float v = 4.0;', '// optical length at zenith for molecules', 'const float rayleighZenithLength = 8.4E3;', 'const float mieZenithLength = 1.25E3;', 'const vec3 up = vec3(0.0, 1.0, 0.0);', 'const float EE = 1000.0;', 'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;', '// 66 arc seconds -> degrees, and the cosine of that', '// earth shadow hack', 'const float cutoffAngle = pi/1.95;', 'const float steepness = 1.5;', 'vec3 totalRayleigh(vec3 lambda)', '{', 'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));', '}', + + // see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness + '// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE', 'vec3 simplifiedRayleigh()', '{', 'return 0.0005 / vec3(94, 40, 18);', + // return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245); + '}', 'float rayleighPhase(float cosTheta)', '{ ', 'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '// return (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '// return (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));', '}', 'vec3 totalMie(vec3 lambda, vec3 K, float T)', '{', 'float c = (0.2 * T ) * 10E-18;', 'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;', '}', 'float hgPhase(float cosTheta, float g)', '{', 'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));', '}', 'float sunIntensity(float zenithAngleCos)', '{', 'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));', '}', '// float logLuminance(vec3 c)', '// {', '// return log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);', '// }', '// Filmic ToneMapping http://filmicgames.com/archives/75', 'float A = 0.15;', 'float B = 0.50;', 'float C = 0.10;', 'float D = 0.20;', 'float E = 0.02;', 'float F = 0.30;', 'float W = 1000.0;', 'vec3 Uncharted2Tonemap(vec3 x)', '{', 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;', '}', 'void main() ', '{', 'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);', '// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;', '// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);', 'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));', 'vec3 sunDirection = normalize(sunPosition);', 'float sunE = sunIntensity(dot(sunDirection, up));', '// extinction (absorbtion + out scattering) ', '// rayleigh coefficients', + + // 'vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;', + 'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;', '// mie coefficients', 'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;', '// optical length', '// cutoff angle at 90 to avoid singularity in next formula.', 'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));', 'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', 'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', '// combined extinction factor ', 'vec3 Fex = exp(-(betaR * sR + betaM * sM));', '// in scattering', 'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);', 'float rPhase = rayleighPhase(cosTheta*0.5+0.5);', 'vec3 betaRTheta = betaR * rPhase;', 'float mPhase = hgPhase(cosTheta, mieDirectionalG);', 'vec3 betaMTheta = betaM * mPhase;', 'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));', 'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));', '//nightsky', 'vec3 direction = normalize(vWorldPosition - cameraPos);', 'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]', 'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]', 'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);', '// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;', 'vec3 L0 = vec3(0.1) * Fex;', '// composition + solar disc', '//if (cosTheta > sunAngularDiameterCos)', 'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);', '// if (normalize(vWorldPosition - cameraPos).y>0.0)', 'L0 += (sunE * 19000.0 * Fex)*sundisk;', 'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));', 'vec3 texColor = (Lin+L0); ', 'texColor *= 0.04 ;', 'texColor += vec3(0.0,0.001,0.0025)*0.3;', 'float g_fMaxLuminance = 1.0;', 'float fLumScaled = 0.1 / luminance; ', 'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ', 'float ExposureBias = fLumCompressed;', 'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);', 'vec3 color = curr*whiteScale;', 'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));', 'gl_FragColor.rgb = retColor;', 'gl_FragColor.a = 1.0;', '}'].join('\n') + + }; + + var Sky = function Sky() { + + var skyShader = _three2['default'].ShaderLib['sky']; + var skyUniforms = _three2['default'].UniformsUtils.clone(skyShader.uniforms); + + var skyMat = new _three2['default'].ShaderMaterial({ + fragmentShader: skyShader.fragmentShader, + vertexShader: skyShader.vertexShader, + uniforms: skyUniforms, + side: _three2['default'].BackSide + }); + + var skyGeo = new _three2['default'].SphereBufferGeometry(450000, 32, 15); + var skyMesh = new _three2['default'].Mesh(skyGeo, skyMat); + + // Expose variables + this.mesh = skyMesh; + this.uniforms = skyUniforms; + }; + + exports['default'] = Sky; + module.exports = exports['default']; + +/***/ }, +/* 46 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _WorkerPool = __webpack_require__(47); + + var _WorkerPool2 = _interopRequireDefault(_WorkerPool); + + var Worker = (function () { + var _maxWorkers = 2; + var pool; + + var createWorkers = function createWorkers(maxWorkers, workerScript) { + pool = new _WorkerPool2['default']({ + numThreads: maxWorkers ? maxWorkers : _maxWorkers, + workerScript: workerScript ? workerScript : 'vizicities-worker.js' + }); + + return pool.createWorkers(); + }; + + var exec = function exec(method, args, transferrables) { + return pool.exec(method, args, transferrables); + }; + + return { + createWorkers: createWorkers, + exec: exec + }; + })(); + + exports['default'] = Worker; + module.exports = exports['default']; + +/***/ }, +/* 47 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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 _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + var _WorkerPoolWorker = __webpack_require__(48); + + var _WorkerPoolWorker2 = _interopRequireDefault(_WorkerPoolWorker); + + var DEBUG = false; + + var WorkerPool = (function () { + function WorkerPool(options) { + _classCallCheck(this, WorkerPool); + + this.numThreads = options.numThreads || 2; + this.workerScript = options.workerScript; + + this.workers = []; + this.tasks = []; + } + + _createClass(WorkerPool, [{ + key: 'createWorkers', + value: function createWorkers() { + var _this = this; + + return new Promise(function (resolve, reject) { + var workerPromises = []; + + for (var i = 0; i < _this.numThreads; i++) { + workerPromises.push(_this.createWorker()); + } + + Promise.all(workerPromises).then(function () { + if (DEBUG) { + console.log('All workers ready', performance.now()); + } + resolve(); + })['catch'](reject); + }); + } + }, { + key: 'createWorker', + value: function createWorker() { + var _this2 = this; + + return new Promise(function (resolve, reject) { + // Initialise worker + var worker = new _WorkerPoolWorker2['default']({ + workerScript: _this2.workerScript + }); + + // Start worker and wait for it to be ready + return worker.start().then(function () { + if (DEBUG) { + console.log('Worker ready', performance.now()); + } + + // Add worker to pool + _this2.workers.push(worker); + + resolve(); + })['catch'](reject); + }); + } + }, { + key: 'getFreeWorker', + value: function getFreeWorker() { + return this.workers.find(function (worker) { + return !worker.busy; + }); + } + + // Execute task on a worker + }, { + key: 'exec', + value: function exec(method, args, transferrables) { + var deferred = Promise.deferred(); + + // Create task + var task = { + method: method, + args: args, + transferrables: transferrables, + deferred: deferred + }; + + // Add task to queue + this.tasks.push(task); + + // Trigger task processing + this.processTasks(); + + // Return task promise + return task.deferred.promise; + } + }, { + key: 'processTasks', + value: function processTasks() { + var _this3 = this; + + if (DEBUG) { + console.log('Processing tasks'); + } + + if (this.tasks.length === 0) { + return; + } + + // Find free worker + var worker = this.getFreeWorker(); + + if (!worker) { + if (DEBUG) { + console.log('No workers free'); + } + return; + } + + // Get oldest task + var task = this.tasks.shift(); + + // Execute task on worker + worker.exec(task.method, task.args, task.transferrables).then(function (result) { + // Trigger task processing + _this3.processTasks(); + + // Return result in deferred task promise + task.deferred.resolve(result); + }); + } + }]); + + return WorkerPool; + })(); + + exports['default'] = WorkerPool; + + // Quick shim to create deferred native promises + Promise.deferred = function () { + var result = {}; + + result.promise = new Promise(function (resolve, reject) { + result.resolve = resolve; + result.reject = reject; + }); + + return result; + }; + module.exports = exports['default']; + +/***/ }, +/* 48 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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 DEBUG = false; + + var WorkerPoolWorker = (function () { + function WorkerPoolWorker(options) { + _classCallCheck(this, WorkerPoolWorker); + + this.workerScript = options.workerScript; + + this.ready = false; + this.busy = false; + this.deferred = null; + } + + _createClass(WorkerPoolWorker, [{ + key: 'start', + value: function start() { + var _this = this; + + return new Promise(function (resolve, reject) { + _this.worker = new Worker(_this.workerScript); + + var onStartup = function onStartup(event) { + if (!event.data || event.data.type !== 'startup') { + reject(); + return; + } + + _this.ready = true; + + // Remove temporary message handler + _this.worker.removeEventListener('message', onStartup); + + // Set up listener to respond to normal events now + _this.worker.addEventListener('message', function (event) { + _this.onMessage(event); + }); + + // Resolve once worker is ready + resolve(); + }; + + // Set up temporary event listener for warmup + _this.worker.addEventListener('message', onStartup); + }); + } + }, { + key: 'exec', + value: function exec(method, args, transferrables) { + if (DEBUG) { + console.log('Execute', method, args, transferrables); + } + + var deferred = Promise.deferred(); + + this.busy = true; + this.deferred = deferred; + + this.worker.postMessage({ + method: method, + args: args + }, transferrables); + + return deferred.promise; + } + }, { + key: 'onMessage', + value: function onMessage(event) { + console.log('Message received from worker', performance.now()); + + this.busy = false; + + if (!event.data || event.data.type === 'error' || event.data.type !== 'result') { + this.deferred.reject(event.data.payload); + return; + } + + this.deferred.resolve(event.data.payload); + } + }]); + + return WorkerPoolWorker; + })(); + + exports['default'] = WorkerPoolWorker; + + // Quick shim to create deferred native promises + Promise.deferred = function () { + var result = {}; + + result.promise = new Promise(function (resolve, reject) { + result.resolve = resolve; + result.reject = reject; + }); + + return result; + }; + module.exports = exports['default']; + +/***/ }, +/* 49 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + var _ControlsOrbit = __webpack_require__(50); var _ControlsOrbit2 = _interopRequireDefault(_ControlsOrbit); @@ -5608,7 +6402,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 38 */ +/* 50 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -5633,11 +6427,11 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); - var _vendorOrbitControls = __webpack_require__(39); + var _vendorOrbitControls = __webpack_require__(51); var _vendorOrbitControls2 = _interopRequireDefault(_vendorOrbitControls); - var _TweenLite = __webpack_require__(41); + var _TweenLite = __webpack_require__(53); var _TweenLite2 = _interopRequireDefault(_TweenLite); @@ -5871,8 +6665,7 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: 'addTo', value: function addTo(world) { - world.addControls(this); - return Promise.resolve(this); + return world.addControls(this); } // Internal method called by World.addControls to actually add the controls @@ -5928,7 +6721,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.orbit = noNew; /***/ }, -/* 39 */ +/* 51 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -5944,7 +6737,7 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); - var _hammerjs = __webpack_require__(40); + var _hammerjs = __webpack_require__(52); var _hammerjs2 = _interopRequireDefault(_hammerjs); @@ -7116,7 +7909,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 40 */ +/* 52 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_RESULT__;/*! Hammer.JS - v2.0.7 - 2016-04-22 @@ -9765,13 +10558,13 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 41 */ +/* 53 */ /***/ function(module, exports) { - module.exports = __WEBPACK_EXTERNAL_MODULE_41__; + module.exports = __WEBPACK_EXTERNAL_MODULE_53__; /***/ }, -/* 42 */ +/* 54 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -9788,19 +10581,114 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _TileLayer2 = __webpack_require__(43); + var _Layer2 = __webpack_require__(34); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(3); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var LayerGroup = (function (_Layer) { + _inherits(LayerGroup, _Layer); + + function LayerGroup(options) { + _classCallCheck(this, LayerGroup); + + var defaults = { + output: false + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + _get(Object.getPrototypeOf(LayerGroup.prototype), 'constructor', this).call(this, _options); + + this._layers = []; + } + + _createClass(LayerGroup, [{ + key: 'addLayer', + value: function addLayer(layer) { + this._layers.push(layer); + return this._world.addLayer(layer); + } + }, { + key: 'removeLayer', + value: function removeLayer(layer) { + var layerIndex = this._layers.indexOf(layer); + + if (layerIndex > -1) { + // Remove from this._layers + this._layers.splice(layerIndex, 1); + }; + + this._world.removeLayer(layer); + } + }, { + key: '_onAdd', + value: function _onAdd(world) { + return Promise.resolve(this); + } + + // Destroy the layers and remove them from the scene and memory + }, { + key: 'destroy', + value: function destroy() { + // TODO: Sometimes this is already null, find out why + if (this._layers) { + for (var i = 0; i < this._layers.length; i++) { + this._layers[i].destroy(); + } + + this._layers = null; + } + + _get(Object.getPrototypeOf(LayerGroup.prototype), 'destroy', this).call(this); + } + }]); + + return LayerGroup; + })(_Layer3['default']); + + exports['default'] = LayerGroup; + + var noNew = function noNew(options) { + return new LayerGroup(options); + }; + + exports.layerGroup = noNew; + +/***/ }, +/* 55 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _TileLayer2 = __webpack_require__(56); var _TileLayer3 = _interopRequireDefault(_TileLayer2); - var _ImageTile = __webpack_require__(53); + var _ImageTile = __webpack_require__(66); var _ImageTile2 = _interopRequireDefault(_ImageTile); - var _ImageTileLayerBaseMaterial = __webpack_require__(56); + var _ImageTileLayerBaseMaterial = __webpack_require__(69); var _ImageTileLayerBaseMaterial2 = _interopRequireDefault(_ImageTileLayerBaseMaterial); - var _lodashThrottle = __webpack_require__(35); + var _lodashThrottle = __webpack_require__(22); var _lodashThrottle2 = _interopRequireDefault(_lodashThrottle); @@ -9887,26 +10775,33 @@ return /******/ (function(modules) { // webpackBootstrap return new Promise(function (resolve, reject) { _get(Object.getPrototypeOf(ImageTileLayer.prototype), '_onAdd', _this).call(_this, world).then(function () { + // TODO: Removed because it causes depth buffer intersection issues + // with layer on top for some reason. Need to work out why and fix. + // // Add base layer - var geom = new _three2['default'].PlaneBufferGeometry(2000000, 2000000, 1); + // var geom = new THREE.PlaneBufferGeometry(2000000, 2000000, 1); - var baseMaterial; - if (_this._world._environment._skybox) { - baseMaterial = (0, _ImageTileLayerBaseMaterial2['default'])('#f5f5f3', _this._world._environment._skybox.getRenderTarget()); - } else { - baseMaterial = (0, _ImageTileLayerBaseMaterial2['default'])('#f5f5f3'); - } + // var baseMaterial; + // if (this._world._environment._skybox) { + // baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3', this._world._environment._skybox.getRenderTarget()); + // } else { + // baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3'); + // } - var mesh = new _three2['default'].Mesh(geom, baseMaterial); - mesh.renderOrder = 0; - mesh.rotation.x = -90 * Math.PI / 180; + // var mesh = new THREE.Mesh(geom, baseMaterial); - // TODO: It might be overkill to receive a shadow on the base layer as it's - // rarely seen (good to have if performance difference is negligible) - mesh.receiveShadow = true; + // // Setting this causes a depth-buffer intersection issue on the + // // all-the-things example + // // mesh.renderOrder = -1; - _this._baseLayer = mesh; - _this.add(mesh); + // mesh.rotation.x = -90 * Math.PI / 180; + + // // TODO: It might be overkill to receive a shadow on the base layer as it's + // // rarely seen (good to have if performance difference is negligible) + // mesh.receiveShadow = true; + + // this._baseLayer = mesh; + // this.add(mesh); // Trigger initial quadtree calculation on the next frame // @@ -9930,7 +10825,7 @@ return /******/ (function(modules) { // webpackBootstrap this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._onWorldUpdate, 100); this._world.on('preUpdate', this._throttledWorldUpdate, this); - this._world.on('move', this._onWorldMove, this); + // this._world.on('move', this._onWorldMove, this); } }, { key: '_onWorldUpdate', @@ -9996,7 +10891,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.imageTileLayer = noNew; /***/ }, -/* 43 */ +/* 56 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -10013,7 +10908,7 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _Layer2 = __webpack_require__(32); + var _Layer2 = __webpack_require__(34); var _Layer3 = _interopRequireDefault(_Layer2); @@ -10021,7 +10916,7 @@ return /******/ (function(modules) { // webpackBootstrap var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - var _TileCache = __webpack_require__(44); + var _TileCache = __webpack_require__(57); var _TileCache2 = _interopRequireDefault(_TileCache); @@ -10095,6 +10990,8 @@ return /******/ (function(modules) { // webpackBootstrap _get(Object.getPrototypeOf(TileLayer.prototype), 'constructor', this).call(this, _options); + this._destroy = false; + this._tileCache = new _TileCache2['default'](this._options.maxCache, function (tile) { _this._destroyTile(tile); }); @@ -10142,7 +11039,7 @@ return /******/ (function(modules) { // webpackBootstrap value: function _outputTiles() { var _this2 = this; - if (!this._tiles) { + if (!this._tiles || this._destroy) { return; } @@ -10166,6 +11063,11 @@ return /******/ (function(modules) { // webpackBootstrap _this2._tilesPicking.add(tile.getPickingMesh()); } }); + + // Emit event notifying of new tiles + this.emit('tilesList', this._tileList.map(function (tile) { + return tile; + })); } // Works out tiles in the view frustum and stores them in an array @@ -10176,7 +11078,7 @@ return /******/ (function(modules) { // webpackBootstrap value: function _calculateLOD() { var _this3 = this; - if (this._stop || !this._world) { + if (this._stop || !this._world || this._destroy) { return; } @@ -10209,7 +11111,7 @@ return /******/ (function(modules) { // webpackBootstrap }); // 5. Filter the tiles remaining in the check list - this._tileList = checkList.filter(function (tile, index) { + var tileList = checkList.filter(function (tile, index) { // Skip tile if it's not in the current view frustum if (!_this3._tileInFrustum(tile)) { return false; @@ -10230,7 +11132,7 @@ return /******/ (function(modules) { // webpackBootstrap // // If yes, continue // If no, generate tile mesh, request texture and skip - if (!tile.getMesh()) { + if (!tile.getMesh() || tile.isAborted()) { tile.requestTileAsync(); } @@ -10248,6 +11150,19 @@ return /******/ (function(modules) { // webpackBootstrap // this._tiles.add(tile.getMesh()); }); + // Get list of tiles that were in the previous update but not the + // current one (for aborting requests, etc) + var missingTiles = this._tileList.filter(function (item) { + return !tileList.includes(item); + }); + + // Abort tiles that are no longer in view + missingTiles.forEach(function (tile) { + return tile._abortRequest(); + }); + + this._tileList = tileList; + // console.log(performance.now() - start); } }, { @@ -10384,11 +11299,36 @@ return /******/ (function(modules) { // webpackBootstrap // Call destory on tile instance tile.destroy(); } + }, { + key: 'show', + value: function show() { + this._stop = false; + + if (this._tilesPicking) { + this._tilesPicking.visible = true; + } + + this._calculateLOD(); + _get(Object.getPrototypeOf(TileLayer.prototype), 'show', this).call(this); + } + }, { + key: 'hide', + value: function hide() { + this._stop = true; + + if (this._tilesPicking) { + this._tilesPicking.visible = false; + } + + _get(Object.getPrototypeOf(TileLayer.prototype), 'hide', this).call(this); + } // Destroys the layer and removes it from the scene and memory }, { key: 'destroy', value: function destroy() { + this._destroy = true; + if (this._tiles.children) { // Remove all tiles for (var i = this._tiles.children.length - 1; i >= 0; i--) { @@ -10424,7 +11364,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 44 */ +/* 57 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -10437,7 +11377,7 @@ return /******/ (function(modules) { // webpackBootstrap function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - var _lruCache = __webpack_require__(45); + var _lruCache = __webpack_require__(58); var _lruCache2 = _interopRequireDefault(_lruCache); @@ -10505,18 +11445,18 @@ return /******/ (function(modules) { // webpackBootstrap exports.tileCache = noNew; /***/ }, -/* 45 */ +/* 58 */ /***/ function(module, exports, __webpack_require__) { module.exports = LRUCache // This will be a proper iterable 'Map' in engines that support it, // or a fakey-fake PseudoMap in older versions. - var Map = __webpack_require__(46) - var util = __webpack_require__(49) + var Map = __webpack_require__(59) + var util = __webpack_require__(62) // A linked list to keep track of recently-used-ness - var Yallist = __webpack_require__(52) + var Yallist = __webpack_require__(65) // use symbols if possible, otherwise just _props var symbols = {} @@ -10980,7 +11920,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 46 */ +/* 59 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(process) {if (process.env.npm_package_name === 'pseudomap' && @@ -10990,13 +11930,13 @@ return /******/ (function(modules) { // webpackBootstrap if (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) { module.exports = Map } else { - module.exports = __webpack_require__(48) + module.exports = __webpack_require__(61) } - /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(47))) + /* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(60))) /***/ }, -/* 47 */ +/* 60 */ /***/ function(module, exports) { // shim for using process in browser @@ -11121,7 +12061,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 48 */ +/* 61 */ /***/ function(module, exports) { var hasOwnProperty = Object.prototype.hasOwnProperty @@ -11240,7 +12180,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 49 */ +/* 62 */ /***/ function(module, exports, __webpack_require__) { /* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors. @@ -11768,7 +12708,7 @@ return /******/ (function(modules) { // webpackBootstrap } exports.isPrimitive = isPrimitive; - exports.isBuffer = __webpack_require__(50); + exports.isBuffer = __webpack_require__(63); function objectToString(o) { return Object.prototype.toString.call(o); @@ -11812,7 +12752,7 @@ return /******/ (function(modules) { // webpackBootstrap * prototype. * @param {function} superCtor Constructor function to inherit prototype from. */ - exports.inherits = __webpack_require__(51); + exports.inherits = __webpack_require__(64); exports._extend = function(origin, add) { // Don't do anything if add isn't an object @@ -11830,10 +12770,10 @@ return /******/ (function(modules) { // webpackBootstrap return Object.prototype.hasOwnProperty.call(obj, prop); } - /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(47))) + /* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(60))) /***/ }, -/* 50 */ +/* 63 */ /***/ function(module, exports) { module.exports = function isBuffer(arg) { @@ -11844,7 +12784,7 @@ return /******/ (function(modules) { // webpackBootstrap } /***/ }, -/* 51 */ +/* 64 */ /***/ function(module, exports) { if (typeof Object.create === 'function') { @@ -11873,7 +12813,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 52 */ +/* 65 */ /***/ function(module, exports) { module.exports = Yallist @@ -12239,7 +13179,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 53 */ +/* 66 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -12256,11 +13196,11 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _Tile2 = __webpack_require__(54); + var _Tile2 = __webpack_require__(67); var _Tile3 = _interopRequireDefault(_Tile2); - var _vendorBoxHelper = __webpack_require__(55); + var _vendorBoxHelper = __webpack_require__(68); var _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper); @@ -12290,8 +13230,9 @@ return /******/ (function(modules) { // webpackBootstrap setTimeout(function () { if (!_this._mesh) { _this._mesh = _this._createMesh(); - _this._requestTile(); } + + _this._requestTile(); }, 0); } }, { @@ -12346,8 +13287,15 @@ return /******/ (function(modules) { // webpackBootstrap localMesh.receiveShadow = true; + // Setting this causes a depth-buffer intersection issue on the + // all-the-things example + // localMesh.renderOrder = 2; + mesh.add(localMesh); - mesh.renderOrder = 0.1; + + // Setting this causes a depth-buffer intersection issue on the + // all-the-things example + // mesh.renderOrder = 2; mesh.position.x = this._center[0]; mesh.position.z = this._center[1]; @@ -12412,7 +13360,13 @@ return /******/ (function(modules) { // webpackBootstrap var image = document.createElement('img'); + this._aborted = false; + image.addEventListener('load', function (event) { + if (_this2.isAborted()) { + return; + } + var texture = new _three2['default'].Texture(); texture.image = image; @@ -12454,10 +13408,12 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_abortRequest', value: function _abortRequest() { - if (!this._image) { + if (!this._image || this._ready) { return; } + this._aborted = true; + this._image.src = ''; } }]); @@ -12475,7 +13431,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.imageTile = noNew; /***/ }, -/* 54 */ +/* 67 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -12514,6 +13470,7 @@ return /******/ (function(modules) { // webpackBootstrap this._path = path; this._ready = false; + this._aborted = false; this._tile = this._quadcodeToTile(quadcode); @@ -12544,6 +13501,11 @@ return /******/ (function(modules) { // webpackBootstrap value: function isReady() { return this._ready; } + }, { + key: 'isAborted', + value: function isAborted() { + return this._aborted; + } // Request data for the tile }, { @@ -12587,6 +13549,8 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: 'destroy', value: function destroy() { + // console.log('Destroying tile', this._quadcode); + // Delete reference to layer and world this._layer = null; this._world = null; @@ -12597,35 +13561,47 @@ return /******/ (function(modules) { // webpackBootstrap this._center = null; // Done if no mesh - if (!this._mesh) { + if (!this._mesh && !this._pickingMesh) { return; } - if (this._mesh.children) { - // Dispose of mesh and materials - this._mesh.children.forEach(function (child) { - child.geometry.dispose(); - child.geometry = null; + this.destroyMesh(this._mesh); + this.destroyMesh(this._pickingMesh); - if (child.material.map) { - child.material.map.dispose(); - child.material.map = null; - } + this._mesh = null; + this._pickingMesh = null; + } + }, { + key: 'destroyMesh', + value: function destroyMesh(mesh) { + var _this = this; - child.material.dispose(); - child.material = null; - }); - } else { - this._mesh.geometry.dispose(); - this._mesh.geometry = null; + var dispose = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1]; - if (this._mesh.material.map) { - this._mesh.material.map.dispose(); - this._mesh.material.map = null; + if (mesh) { + if (mesh.children) { + mesh.children.forEach(function (child) { + mesh.remove(child); + _this.destroyMesh(child); + }); } - this._mesh.material.dispose(); - this._mesh.material = null; + if (dispose) { + if (mesh.geometry) { + mesh.geometry.dispose(); + mesh.geometry = null; + } + + if (mesh.material) { + if (mesh.material.map) { + mesh.material.map.dispose(); + mesh.material.map = null; + } + + mesh.material.dispose(); + mesh.material = null; + } + } } } }, { @@ -12728,7 +13704,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 55 */ +/* 68 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -12818,7 +13794,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 56 */ +/* 69 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -12881,7 +13857,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 57 */ +/* 70 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -12898,7 +13874,7 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _TileLayer2 = __webpack_require__(43); + var _TileLayer2 = __webpack_require__(56); var _TileLayer3 = _interopRequireDefault(_TileLayer2); @@ -12906,11 +13882,11 @@ return /******/ (function(modules) { // webpackBootstrap var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - var _GeoJSONTile = __webpack_require__(58); + var _GeoJSONTile = __webpack_require__(71); var _GeoJSONTile2 = _interopRequireDefault(_GeoJSONTile); - var _lodashThrottle = __webpack_require__(35); + var _lodashThrottle = __webpack_require__(22); var _lodashThrottle2 = _interopRequireDefault(_lodashThrottle); @@ -12956,13 +13932,16 @@ return /******/ (function(modules) { // webpackBootstrap var defaults = { maxLOD: 14, - distance: 30000 + distance: 30000, + workers: false }; options = (0, _lodashAssign2['default'])({}, defaults, options); _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'constructor', this).call(this, options); + this.defaults = defaults; + this._path = path; } @@ -13003,7 +13982,7 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_onWorldUpdate', value: function _onWorldUpdate() { - if (this._pauseOutput) { + if (this._pauseOutput || this._disableOutput) { return; } @@ -13014,6 +13993,10 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_onWorldMove', value: function _onWorldMove(latlon, point) { + if (this._disableOutput) { + return; + } + this._pauseOutput = false; this._calculateLOD(); } @@ -13022,34 +14005,34 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_onControlsMove', value: function _onControlsMove() { + if (this._disableOutput) { + return; + } + this._pauseOutput = true; } }, { key: '_createTile', value: function _createTile(quadcode, layer) { - var options = {}; + var newOptions = (0, _lodashAssign2['default'])({}, this.defaults, this._options, { + outputToScene: false + }); - // if (this._options.filter) { - // options.filter = this._options.filter; - // } - // - // if (this._options.style) { - // options.style = this._options.style; - // } - // - // if (this._options.topojson) { - // options.topojson = true; - // } - // - // if (this._options.interactive) { - // options.interactive = true; - // } - // - // if (this._options.onClick) { - // options.onClick = this._options.onClick; - // } + delete newOptions.attribution; - return new _GeoJSONTile2['default'](quadcode, this._path, layer, this._options); + return new _GeoJSONTile2['default'](quadcode, this._path, layer, newOptions); + } + }, { + key: 'hide', + value: function hide() { + this._pauseOutput = true; + _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'hide', this).call(this); + } + }, { + key: 'show', + value: function show() { + this._pauseOutput = false; + _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'show', this).call(this); } // Destroys the layer and removes it from the scene and memory @@ -13079,7 +14062,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.geoJSONTileLayer = noNew; /***/ }, -/* 58 */ +/* 71 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -13096,13 +14079,15 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _Tile2 = __webpack_require__(54); + var _Tile2 = __webpack_require__(67); var _Tile3 = _interopRequireDefault(_Tile2); - var _GeoJSONLayer = __webpack_require__(59); + var _GeoJSONLayer = __webpack_require__(72); - var _vendorBoxHelper = __webpack_require__(55); + var _GeoJSONWorkerLayer = __webpack_require__(87); + + var _vendorBoxHelper = __webpack_require__(68); var _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper); @@ -13110,7 +14095,7 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); - var _reqwest = __webpack_require__(61); + var _reqwest = __webpack_require__(73); var _reqwest2 = _interopRequireDefault(_reqwest); @@ -13124,15 +14109,15 @@ return /******/ (function(modules) { // webpackBootstrap // import Offset from 'polygon-offset'; - var _utilGeoJSON = __webpack_require__(63); + var _utilGeoJSON = __webpack_require__(75); var _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON); - var _utilBuffer = __webpack_require__(69); + var _utilBuffer = __webpack_require__(81); var _utilBuffer2 = _interopRequireDefault(_utilBuffer); - var _enginePickingMaterial = __webpack_require__(70); + var _enginePickingMaterial = __webpack_require__(82); var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); @@ -13180,6 +14165,7 @@ return /******/ (function(modules) { // webpackBootstrap this._defaultStyle = _utilGeoJSON2['default'].defaultStyle; var defaults = { + workers: false, output: true, outputToScene: false, interactive: false, @@ -13221,11 +14207,10 @@ return /******/ (function(modules) { // webpackBootstrap setTimeout(function () { if (!_this._mesh) { _this._mesh = _this._createMesh(); - // this._shadowCanvas = this._createShadowCanvas(); - - _this._requestTile(); } + + _this._requestTile(); }, 0); } @@ -13373,38 +14358,71 @@ return /******/ (function(modules) { // webpackBootstrap var url = this._getTileURL(urlParams); - this._request = (0, _reqwest2['default'])({ - url: url, - type: 'json', - crossOrigin: true - }).then(function (res) { - // Clear request reference - _this2._request = null; - _this2._processTileData(res); - })['catch'](function (err) { - console.error(err); + this._aborted = false; - // Clear request reference - _this2._request = null; - }); + if (!this._options.workers) { + this._request = (0, _reqwest2['default'])({ + url: url, + type: 'json', + crossOrigin: true, + headers: this._options.headers + }).then(function (res) { + // Clear request reference + _this2._request = null; + _this2._processTileData(res); + })['catch'](function (err) { + // Clear request reference + _this2._request = null; + }); + } else { + this._processTileData(url); + } } }, { key: '_processTileData', value: function _processTileData(data) { var _this3 = this; - console.time(this._tile); + // console.time(this._tile); + + var GeoJSONClass = !this._options.workers ? _GeoJSONLayer.geoJSONLayer : _GeoJSONWorkerLayer.geoJSONWorkerLayer; // Using this creates a huge amount of memory due to the quantity of tiles - this._geojsonLayer = (0, _GeoJSONLayer.geoJSONLayer)(data, this._options); + this._geojsonLayer = GeoJSONClass(data, this._options); this._geojsonLayer.addTo(this._world).then(function () { - _this3._mesh = _this3._geojsonLayer._object3D; + // TODO: This never seems to be called on worker layers. Find out why. + if (_this3.isAborted()) { + // this._geojsonLayer._aborted = true; + // this._geojsonLayer = null; + return; + } + + // TODO: This is a hack to stop old tile meshes hanging around. Fix or + // move to somewhere more robust. + // + // Could potentially just overwrite mesh on first index each time + // + // This makes some worker tiles to not appear properly – showing the + // points mesh but not the polygon mesh, etc. + // + // Only do this for non-worker layers for now as it seems to cause issues + // with worker tiles showing for a moment and then disappearing forever + if (!_this3._options.workers) { + _this3.destroyMesh(_this3._mesh); + } + + // TOSO: Work out if the picking mesh needs destroying here + // this.destroyMesh(this._pickingMesh); + + _this3._mesh.add(_this3._geojsonLayer._object3D); _this3._pickingMesh = _this3._geojsonLayer._pickingMesh; // Free the GeoJSON memory as we don't need it // // TODO: This should probably be a method within GeoJSONLayer - _this3._geojsonLayer._geojson = null; + if (_this3._geojsonLayer._geojson) { + _this3._geojsonLayer._geojson = null; + } // TODO: Fix or store shadow canvas stuff and get rid of this code // Draw footprint on shadow canvas @@ -13459,17 +14477,21 @@ return /******/ (function(modules) { // webpackBootstrap // this._mesh.add(mesh); _this3._ready = true; - console.timeEnd(_this3._tile); - }); + // console.timeEnd(this._tile); + })['catch'](function () {}); } }, { key: '_abortRequest', value: function _abortRequest() { - if (!this._request) { + if (!this._request && !this._options.workers || this._ready) { return; } - this._request.abort(); + this._aborted = true; + + if (this._request) { + this._request.abort(); + } } }]); @@ -13486,7 +14508,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.geoJSONTile = noNew; /***/ }, -/* 59 */ +/* 72 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -13511,7 +14533,7 @@ return /******/ (function(modules) { // webpackBootstrap // For example, only allow polygons to be interactive via a polygonInteractive // option - var _LayerGroup2 = __webpack_require__(60); + var _LayerGroup2 = __webpack_require__(54); var _LayerGroup3 = _interopRequireDefault(_LayerGroup2); @@ -13519,31 +14541,31 @@ return /******/ (function(modules) { // webpackBootstrap var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - var _reqwest = __webpack_require__(61); + var _reqwest = __webpack_require__(73); var _reqwest2 = _interopRequireDefault(_reqwest); - var _utilGeoJSON = __webpack_require__(63); + var _utilGeoJSON = __webpack_require__(75); var _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON); - var _utilBuffer = __webpack_require__(69); + var _utilBuffer = __webpack_require__(81); var _utilBuffer2 = _interopRequireDefault(_utilBuffer); - var _enginePickingMaterial = __webpack_require__(70); + var _enginePickingMaterial = __webpack_require__(82); var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); - var _geometryPolygonLayer = __webpack_require__(72); + var _geometryPolygonLayer = __webpack_require__(84); var _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer); - var _geometryPolylineLayer = __webpack_require__(73); + var _geometryPolylineLayer = __webpack_require__(85); var _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer); - var _geometryPointLayer = __webpack_require__(74); + var _geometryPointLayer = __webpack_require__(86); var _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer); @@ -13626,6 +14648,8 @@ return /******/ (function(modules) { // webpackBootstrap // Clear request reference _this._request = null; + + reject(err); }); }); } @@ -13640,325 +14664,245 @@ return /******/ (function(modules) { // webpackBootstrap value: function _processData(data) { var _this2 = this; - // Collects features into a single FeatureCollection - // - // Also converts TopoJSON to GeoJSON if instructed - this._geojson = _utilGeoJSON2['default'].collectFeatures(data, this._options.topojson); + return new Promise(function (resolve) { + // Collects features into a single FeatureCollection + // + // Also converts TopoJSON to GeoJSON if instructed + _this2._geojson = _utilGeoJSON2['default'].collectFeatures(data, _this2._options.topojson); - // TODO: Check that GeoJSON is valid / usable + // TODO: Check that GeoJSON is valid / usable - var features = this._geojson.features; + var features = _this2._geojson.features; - // Run filter, if provided - if (this._options.filter) { - features = this._geojson.features.filter(this._options.filter); - } - - var defaults = {}; - - // Assume that a style won't be set per feature - var style = this._options.style; - - var options; - features.forEach(function (feature) { - // Get per-feature style object, if provided - if (typeof _this2._options.style === 'function') { - style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _this2._options.style(feature)); + // Run filter, if provided + if (_this2._options.filter) { + features = _this2._geojson.features.filter(_this2._options.filter); } - options = (0, _lodashAssign2['default'])({}, defaults, { - // If merging feature layers, stop them outputting themselves - // If not, let feature layers output themselves to the world - output: !_this2.isOutput(), - interactive: _this2._options.interactive, - style: style + var defaults = {}; + + // Assume that a style won't be set per feature + var style = _this2._options.style; + + var layerPromises = []; + + var options; + features.forEach(function (feature) { + // Get per-feature style object, if provided + if (typeof _this2._options.style === 'function') { + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _this2._options.style(feature)); + } + + options = (0, _lodashAssign2['default'])({}, defaults, { + // If merging feature layers, stop them outputting themselves + // If not, let feature layers output themselves to the world + output: !_this2.isOutput(), + interactive: _this2._options.interactive, + style: style + }); + + var layer = _this2._featureToLayer(feature, options); + + if (!layer) { + return; + } + + // Sometimes you don't want to store a reference to the feature + // + // For example, to save memory when being used by tile layers + if (_this2._options.keepFeatures) { + layer.feature = feature; + } + + // If defined, call a function for each feature + // + // This is commonly used for adding event listeners from the user script + if (_this2._options.onEachFeature) { + _this2._options.onEachFeature(feature, layer); + } + + // TODO: Make this a promise array and only continue on completion + layerPromises.push(_this2.addLayer(layer)); }); - var layer = _this2._featureToLayer(feature, options); - - if (!layer) { - return; - } - - // Sometimes you don't want to store a reference to the feature - // - // For example, to save memory when being used by tile layers - if (_this2._options.keepFeatures) { - layer.feature = feature; - } - - // If defined, call a function for each feature - // - // This is commonly used for adding event listeners from the user script - if (_this2._options.onEachFeature) { - _this2._options.onEachFeature(feature, layer); - } - - // TODO: Make this a promise array and only continue on completion - _this2.addLayer(layer); - }); - - // If merging layers do that now, otherwise skip as the geometry layers - // should have already outputted themselves - if (!this.isOutput()) { - return; - } - - // From here on we can assume that we want to merge the layers - - var polygonAttributes = []; - var polygonFlat = true; - - var polylineAttributes = []; - var pointAttributes = []; - - this._layers.forEach(function (layer) { - if (layer instanceof _geometryPolygonLayer2['default']) { - polygonAttributes.push(layer.getBufferAttributes()); - - if (polygonFlat && !layer.isFlat()) { - polygonFlat = false; + Promise.all(layerPromises).then(function (results) { + // If merging layers do that now, otherwise skip as the geometry layers + // should have already outputted themselves + if (!_this2.isOutput()) { + resolve(); + return; } - } else if (layer instanceof _geometryPolylineLayer2['default']) { - polylineAttributes.push(layer.getBufferAttributes()); - } else if (layer instanceof _geometryPointLayer2['default']) { - pointAttributes.push(layer.getBufferAttributes()); - } + + // From here on we can assume that we want to merge the layers + + var polygonAttributes = []; + var polygonOutlineAttributes = []; + var polygonAttributeLengths = { + positions: 3, + normals: 3, + colors: 3 + }; + var polygonFlat = true; + + var polylineAttributes = []; + var polylineAttributeLengths = { + positions: 3, + colors: 3 + }; + var polylineFlat = true; + + var pointAttributes = []; + var pointAttributeLengths = { + positions: 3, + normals: 3, + colors: 3 + }; + var pointFlat = true; + + _this2._layers.forEach(function (layer) { + if (layer instanceof _geometryPolygonLayer2['default']) { + polygonAttributes.push(layer.getBufferAttributes()); + + var outlineBufferAttributes = layer.getOutlineBufferAttributes(); + if (outlineBufferAttributes) { + polygonOutlineAttributes.push(outlineBufferAttributes); + } + + if (polygonFlat && !layer.isFlat()) { + polygonFlat = false; + } + + if (_this2._options.interactive) { + polygonAttributeLengths.pickingIds = 1; + } + } else if (layer instanceof _geometryPolylineLayer2['default']) { + polylineAttributes.push(layer.getBufferAttributes()); + + if (polylineFlat && !layer.isFlat()) { + polylineFlat = false; + } + + if (_this2._options.interactive) { + polylineAttributeLengths.pickingIds = 1; + } + } else if (layer instanceof _geometryPointLayer2['default']) { + pointAttributes.push(layer.getBufferAttributes()); + + if (pointFlat && !layer.isFlat()) { + pointFlat = false; + } + + if (_this2._options.interactive) { + pointAttributeLengths.pickingIds = 1; + } + } + }); + + var style; + + if (polygonAttributes.length > 0) { + var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes); + + var mergedPolygonOutlineAttributes; + if (polygonOutlineAttributes.length > 0) { + mergedPolygonOutlineAttributes = _utilBuffer2['default'].mergeAttributes(polygonOutlineAttributes); + } + + style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this2._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat).then(function (result) { + _this2._polygonMesh = result.mesh; + _this2.add(_this2._polygonMesh); + + if (mergedPolygonOutlineAttributes) { + style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + if (style.outlineRenderOrder !== undefined) { + style.lineRenderOrder = style.outlineRenderOrder; + } else { + style.lineRenderOrder = style.renderOrder ? style.renderOrder + 1 : 4; + } + + if (style.outlineWidth) { + style.lineWidth = style.outlineWidth; + } + + _this2._setPolylineMesh(mergedPolygonOutlineAttributes, polylineAttributeLengths, style, true).then(function (result) { + _this2.add(result.mesh); + }); + } + + if (result.pickingMesh) { + _this2._pickingMesh.add(result.pickingMesh); + } + }); + } + + if (polylineAttributes.length > 0) { + var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes); + + style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this2._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then(function (result) { + _this2._polylineMesh = result.mesh; + _this2.add(_this2._polylineMesh); + + if (result.pickingMesh) { + _this2._pickingMesh.add(result.pickingMesh); + } + }); + } + + if (pointAttributes.length > 0) { + var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes); + + style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this2._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then(function (result) { + _this2._pointMesh = result.mesh; + _this2.add(_this2._pointMesh); + + if (result.pickingMesh) { + _this2._pickingMesh.add(result.pickingMesh); + } + }); + } + + // Clean up layers + // + // TODO: Are there ever situations where the unmerged buffer attributes + // and coordinates would still be required? + _this2._layers.forEach(function (layer) { + layer.clearBufferAttributes(); + layer.clearCoordinates(); + }); + + resolve(); + }); }); - - if (polygonAttributes.length > 0) { - var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes); - this._setPolygonMesh(mergedPolygonAttributes, polygonFlat); - this.add(this._polygonMesh); - } - - if (polylineAttributes.length > 0) { - var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes); - this._setPolylineMesh(mergedPolylineAttributes); - this.add(this._polylineMesh); - } - - if (pointAttributes.length > 0) { - var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes); - this._setPointMesh(mergedPointAttributes); - this.add(this._pointMesh); - } - - // Clean up layers - // - // TODO: Are there ever situations where the unmerged buffer attributes - // and coordinates would still be required? - this._layers.forEach(function (layer) { - layer.clearBufferAttributes(); - layer.clearCoordinates(); - }); - - return Promise.resolve(); } // Create and store mesh from buffer attributes // - // TODO: De-dupe this from the individual mesh creation logic within each - // geometry layer (materials, settings, etc) - // - // Could make this an abstract method for each geometry layer + // TODO: Probably remove this and call static method directly as it's just a proxy }, { key: '_setPolygonMesh', - value: function _setPolygonMesh(attributes, flat) { - var geometry = new THREE.BufferGeometry(); - - // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3)); - geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3)); - geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3)); - - if (attributes.pickingIds) { - geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1)); - } - - geometry.computeBoundingBox(); - - // TODO: Make this work when style is a function per feature - var style = typeof this._options.style === 'function' ? this._options.style(this._geojson.features[0]) : this._options.style; - style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); - - var material; - if (this._options.polygonMaterial && this._options.polygonMaterial instanceof THREE.Material) { - material = this._options.polygonMaterial; - } else if (!this._world._environment._skybox) { - material = new THREE.MeshPhongMaterial({ - vertexColors: THREE.VertexColors, - side: THREE.BackSide, - transparent: style.transparent, - opacity: style.opacity, - blending: style.blending - }); - } else { - material = new THREE.MeshStandardMaterial({ - vertexColors: THREE.VertexColors, - side: THREE.BackSide, - transparent: style.transparent, - opacity: style.opacity, - blending: style.blending - }); - material.roughness = 1; - material.metalness = 0.1; - material.envMapIntensity = 3; - material.envMap = this._world._environment._skybox.getRenderTarget(); - } - - var mesh; - - // Pass mesh through callback, if defined - if (typeof this._options.onPolygonMesh === 'function') { - mesh = this._options.onPolygonMesh(geometry, material); - } else { - mesh = new THREE.Mesh(geometry, material); - - mesh.castShadow = true; - mesh.receiveShadow = true; - } - - if (flat) { - material.depthWrite = false; - mesh.renderOrder = 1; - } - - if (this._options.interactive && this._pickingMesh) { - material = new _enginePickingMaterial2['default'](); - material.side = THREE.BackSide; - - var pickingMesh = new THREE.Mesh(geometry, material); - this._pickingMesh.add(pickingMesh); - } - - this._polygonMesh = mesh; + value: function _setPolygonMesh(attributes, attributeLengths, style, flat) { + return _geometryPolygonLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox); } }, { key: '_setPolylineMesh', - value: function _setPolylineMesh(attributes) { - var geometry = new THREE.BufferGeometry(); - - // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3)); - - if (attributes.normals) { - geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3)); - } - - geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3)); - - if (attributes.pickingIds) { - geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1)); - } - - geometry.computeBoundingBox(); - - // TODO: Make this work when style is a function per feature - var style = typeof this._options.style === 'function' ? this._options.style(this._geojson.features[0]) : this._options.style; - style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); - - var material; - if (this._options.polylineMaterial && this._options.polylineMaterial instanceof THREE.Material) { - material = this._options.polylineMaterial; - } else { - material = new THREE.LineBasicMaterial({ - vertexColors: THREE.VertexColors, - linewidth: style.lineWidth, - transparent: style.lineTransparent, - opacity: style.lineOpacity, - blending: style.lineBlending - }); - } - - var mesh; - - // Pass mesh through callback, if defined - if (typeof this._options.onPolylineMesh === 'function') { - mesh = this._options.onPolylineMesh(geometry, material); - } else { - mesh = new THREE.LineSegments(geometry, material); - - if (style.lineRenderOrder !== undefined) { - material.depthWrite = false; - mesh.renderOrder = style.lineRenderOrder; - } - - mesh.castShadow = true; - // mesh.receiveShadow = true; - } - - // TODO: Allow this to be overridden, or copy mesh instead of creating a new - // one just for picking - if (this._options.interactive && this._pickingMesh) { - material = new _enginePickingMaterial2['default'](); - // material.side = THREE.BackSide; - - // Make the line wider / easier to pick - material.linewidth = style.lineWidth + material.linePadding; - - var pickingMesh = new THREE.LineSegments(geometry, material); - this._pickingMesh.add(pickingMesh); - } - - this._polylineMesh = mesh; + value: function _setPolylineMesh(attributes, attributeLengths, style, flat) { + return _geometryPolylineLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options); } }, { key: '_setPointMesh', - value: function _setPointMesh(attributes) { - var geometry = new THREE.BufferGeometry(); - - // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3)); - geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3)); - geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3)); - - if (attributes.pickingIds) { - geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1)); - } - - geometry.computeBoundingBox(); - - var material; - if (this._options.pointMaterial && this._options.pointMaterial instanceof THREE.Material) { - material = this._options.pointMaterial; - } else if (!this._world._environment._skybox) { - material = new THREE.MeshPhongMaterial({ - vertexColors: THREE.VertexColors - // side: THREE.BackSide - }); - } else { - material = new THREE.MeshStandardMaterial({ - vertexColors: THREE.VertexColors - // side: THREE.BackSide - }); - material.roughness = 1; - material.metalness = 0.1; - material.envMapIntensity = 3; - material.envMap = this._world._environment._skybox.getRenderTarget(); - } - - var mesh; - - // Pass mesh callback, if defined - if (typeof this._options.onPointMesh === 'function') { - mesh = this._options.onPointMesh(geometry, material); - } else { - mesh = new THREE.Mesh(geometry, material); - - mesh.castShadow = true; - // mesh.receiveShadow = true; - } - - if (this._options.interactive && this._pickingMesh) { - material = new _enginePickingMaterial2['default'](); - // material.side = THREE.BackSide; - - var pickingMesh = new THREE.Mesh(geometry, material); - this._pickingMesh.add(pickingMesh); - } - - this._pointMesh = mesh; + value: function _setPointMesh(attributes, attributeLengths, style, flat) { + return _geometryPointLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options); } // TODO: Support all GeoJSON geometry types @@ -13975,11 +14919,11 @@ return /******/ (function(modules) { // webpackBootstrap if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') { // Get material instance to use for polygon, if provided if (typeof this._options.polygonMaterial === 'function') { - options.geometry = this._options.polygonMaterial(feature); + options.polygonMaterial = this._options.polygonMaterial(feature); } if (typeof this._options.onPolygonMesh === 'function') { - options.onMesh = this._options.onPolygonMesh; + options.onPolygonMesh = this._options.onPolygonMesh; } // Pass onBufferAttributes callback, if defined @@ -13993,11 +14937,11 @@ return /******/ (function(modules) { // webpackBootstrap if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') { // Get material instance to use for line, if provided if (typeof this._options.lineMaterial === 'function') { - options.geometry = this._options.lineMaterial(feature); + options.lineMaterial = this._options.lineMaterial(feature); } if (typeof this._options.onPolylineMesh === 'function') { - options.onMesh = this._options.onPolylineMesh; + options.onPolylineMesh = this._options.onPolylineMesh; } // Pass onBufferAttributes callback, if defined @@ -14011,16 +14955,16 @@ return /******/ (function(modules) { // webpackBootstrap if (geometry.type === 'Point' || geometry.type === 'MultiPoint') { // Get geometry object to use for point, if provided if (typeof this._options.pointGeometry === 'function') { - options.geometry = this._options.pointGeometry(feature); + options.pointGeometry = this._options.pointGeometry(feature); } // Get material instance to use for point, if provided if (typeof this._options.pointMaterial === 'function') { - options.geometry = this._options.pointMaterial(feature); + options.pointMaterial = this._options.pointMaterial(feature); } if (typeof this._options.onPointMesh === 'function') { - options.onMesh = this._options.onPointMesh; + options.onPointMesh = this._options.onPointMesh; } return new _geometryPointLayer2['default'](coordinates, options); @@ -14082,100 +15026,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.geoJSONLayer = noNew; /***/ }, -/* 60 */ -/***/ function(module, exports, __webpack_require__) { - - Object.defineProperty(exports, '__esModule', { - value: true - }); - - 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; }; })(); - - var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; - - function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } - - function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } - - function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - - var _Layer2 = __webpack_require__(32); - - var _Layer3 = _interopRequireDefault(_Layer2); - - var _lodashAssign = __webpack_require__(3); - - var _lodashAssign2 = _interopRequireDefault(_lodashAssign); - - var LayerGroup = (function (_Layer) { - _inherits(LayerGroup, _Layer); - - function LayerGroup(options) { - _classCallCheck(this, LayerGroup); - - var defaults = { - output: false - }; - - var _options = (0, _lodashAssign2['default'])({}, defaults, options); - - _get(Object.getPrototypeOf(LayerGroup.prototype), 'constructor', this).call(this, _options); - - this._layers = []; - } - - _createClass(LayerGroup, [{ - key: 'addLayer', - value: function addLayer(layer) { - this._layers.push(layer); - return this._world.addLayer(layer); - } - }, { - key: 'removeLayer', - value: function removeLayer(layer) { - var layerIndex = this._layers.indexOf(layer); - - if (layerIndex > -1) { - // Remove from this._layers - this._layers.splice(layerIndex, 1); - }; - - this._world.removeLayer(layer); - } - }, { - key: '_onAdd', - value: function _onAdd(world) {} - - // Destroy the layers and remove them from the scene and memory - }, { - key: 'destroy', - value: function destroy() { - // TODO: Sometimes this is already null, find out why - if (this._layers) { - for (var i = 0; i < this._layers.length; i++) { - this._layers[i].destroy(); - } - - this._layers = null; - } - - _get(Object.getPrototypeOf(LayerGroup.prototype), 'destroy', this).call(this); - } - }]); - - return LayerGroup; - })(_Layer3['default']); - - exports['default'] = LayerGroup; - - var noNew = function noNew(options) { - return new LayerGroup(options); - }; - - exports.layerGroup = noNew; - -/***/ }, -/* 61 */ +/* 73 */ /***/ function(module, exports, __webpack_require__) { var __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*! @@ -14199,7 +15050,7 @@ return /******/ (function(modules) { // webpackBootstrap } else { var XHR2 try { - XHR2 = __webpack_require__(62) + XHR2 = __webpack_require__(74) } catch (ex) { throw new Error('Peer dependency `xhr2` required! Please npm install xhr2') } @@ -14811,19 +15662,21 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 62 */ +/* 74 */ /***/ function(module, exports) { /* (ignored) */ /***/ }, -/* 63 */ +/* 75 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { value: true }); + function _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } } + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } /* @@ -14834,19 +15687,19 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); - var _topojson2 = __webpack_require__(64); + var _topojson2 = __webpack_require__(76); - var _topojson3 = _interopRequireDefault(_topojson2); + var topojson = _interopRequireWildcard(_topojson2); - var _geojsonMerge = __webpack_require__(65); + var _geojsonMerge = __webpack_require__(77); var _geojsonMerge2 = _interopRequireDefault(_geojsonMerge); - var _earcut = __webpack_require__(67); + var _earcut = __webpack_require__(79); var _earcut2 = _interopRequireDefault(_earcut); - var _extrudePolygon = __webpack_require__(68); + var _extrudePolygon = __webpack_require__(80); var _extrudePolygon2 = _interopRequireDefault(_extrudePolygon); @@ -14865,6 +15718,8 @@ return /******/ (function(modules) { // webpackBootstrap var GeoJSON = (function () { var defaultStyle = { color: '#ffffff', + outline: false, + outlineColor: '#000000', transparent: false, opacity: 1, blending: _three2['default'].NormalBlending, @@ -14886,7 +15741,7 @@ return /******/ (function(modules) { // webpackBootstrap // If not overridden, merge all features from all objects for (var tk in data.objects) { - collections.push(_topojson3['default'].feature(data, data.objects[tk])); + collections.push(topojson.feature(data, data.objects[tk])); } return (0, _geojsonMerge2['default'])(collections); @@ -15095,560 +15950,562 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 64 */ +/* 76 */ /***/ function(module, exports, __webpack_require__) { (function (global, factory) { true ? factory(exports) : typeof define === 'function' && define.amd ? define(['exports'], factory) : (factory((global.topojson = global.topojson || {}))); - }(this, function (exports) { 'use strict'; + }(this, (function (exports) { 'use strict'; - function noop() {} + function noop() {} - function transformAbsolute(transform) { - if (!transform) return noop; - var x0, - y0, - kx = transform.scale[0], - ky = transform.scale[1], - dx = transform.translate[0], - dy = transform.translate[1]; - return function(point, i) { - if (!i) x0 = y0 = 0; - point[0] = (x0 += point[0]) * kx + dx; - point[1] = (y0 += point[1]) * ky + dy; - }; + function transformAbsolute(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + point[0] = (x0 += point[0]) * kx + dx; + point[1] = (y0 += point[1]) * ky + dy; + }; + } + + function transformRelative(transform) { + if (!transform) return noop; + var x0, + y0, + kx = transform.scale[0], + ky = transform.scale[1], + dx = transform.translate[0], + dy = transform.translate[1]; + return function(point, i) { + if (!i) x0 = y0 = 0; + var x1 = Math.round((point[0] - dx) / kx), + y1 = Math.round((point[1] - dy) / ky); + point[0] = x1 - x0; + point[1] = y1 - y0; + x0 = x1; + y0 = y1; + }; + } + + function reverse(array, n) { + var t, j = array.length, i = j - n; + while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + } + + function bisect(a, x) { + var lo = 0, hi = a.length; + while (lo < hi) { + var mid = lo + hi >>> 1; + if (a[mid] < x) lo = mid + 1; + else hi = mid; + } + return lo; + } + + function feature(topology, o) { + return o.type === "GeometryCollection" ? { + type: "FeatureCollection", + features: o.geometries.map(function(o) { return feature$1(topology, o); }) + } : feature$1(topology, o); + } + + function feature$1(topology, o) { + var f = { + type: "Feature", + id: o.id, + properties: o.properties || {}, + geometry: object(topology, o) + }; + if (o.id == null) delete f.id; + return f; + } + + function object(topology, o) { + var absolute = transformAbsolute(topology.transform), + arcs = topology.arcs; + + function arc(i, points) { + if (points.length) points.pop(); + for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { + points.push(p = a[k].slice()); + absolute(p, k); + } + if (i < 0) reverse(points, n); } - function transformRelative(transform) { - if (!transform) return noop; - var x0, - y0, - kx = transform.scale[0], - ky = transform.scale[1], - dx = transform.translate[0], - dy = transform.translate[1]; - return function(point, i) { - if (!i) x0 = y0 = 0; - var x1 = Math.round((point[0] - dx) / kx), - y1 = Math.round((point[1] - dy) / ky); - point[0] = x1 - x0; - point[1] = y1 - y0; - x0 = x1; - y0 = y1; - }; + function point(p) { + p = p.slice(); + absolute(p, 0); + return p; } - function reverse(array, n) { - var t, j = array.length, i = j - n; - while (i < --j) t = array[i], array[i++] = array[j], array[j] = t; + function line(arcs) { + var points = []; + for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); + if (points.length < 2) points.push(points[0].slice()); + return points; } - function bisect(a, x) { - var lo = 0, hi = a.length; - while (lo < hi) { - var mid = lo + hi >>> 1; - if (a[mid] < x) lo = mid + 1; - else hi = mid; - } - return lo; + function ring(arcs) { + var points = line(arcs); + while (points.length < 4) points.push(points[0].slice()); + return points; } - function feature(topology, o) { - return o.type === "GeometryCollection" ? { - type: "FeatureCollection", - features: o.geometries.map(function(o) { return feature$1(topology, o); }) - } : feature$1(topology, o); + function polygon(arcs) { + return arcs.map(ring); } - function feature$1(topology, o) { - var f = { - type: "Feature", - id: o.id, - properties: o.properties || {}, - geometry: object(topology, o) - }; - if (o.id == null) delete f.id; - return f; + function geometry(o) { + var t = o.type; + return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} + : t in geometryType ? {type: t, coordinates: geometryType[t](o)} + : null; } - function object(topology, o) { - var absolute = transformAbsolute(topology.transform), - arcs = topology.arcs; + var geometryType = { + Point: function(o) { return point(o.coordinates); }, + MultiPoint: function(o) { return o.coordinates.map(point); }, + LineString: function(o) { return line(o.arcs); }, + MultiLineString: function(o) { return o.arcs.map(line); }, + Polygon: function(o) { return polygon(o.arcs); }, + MultiPolygon: function(o) { return o.arcs.map(polygon); } + }; - function arc(i, points) { - if (points.length) points.pop(); - for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) { - points.push(p = a[k].slice()); - absolute(p, k); - } - if (i < 0) reverse(points, n); + return geometry(o); + } + + function stitchArcs(topology, arcs) { + var stitchedArcs = {}, + fragmentByStart = {}, + fragmentByEnd = {}, + fragments = [], + emptyIndex = -1; + + // Stitch empty arcs first, since they may be subsumed by other arcs. + arcs.forEach(function(i, j) { + var arc = topology.arcs[i < 0 ? ~i : i], t; + if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { + t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; } + }); - function point(p) { - p = p.slice(); - absolute(p, 0); - return p; - } + arcs.forEach(function(i) { + var e = ends(i), + start = e[0], + end = e[1], + f, g; - function line(arcs) { - var points = []; - for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points); - if (points.length < 2) points.push(points[0].slice()); - return points; - } - - function ring(arcs) { - var points = line(arcs); - while (points.length < 4) points.push(points[0].slice()); - return points; - } - - function polygon(arcs) { - return arcs.map(ring); - } - - function geometry(o) { - var t = o.type; - return t === "GeometryCollection" ? {type: t, geometries: o.geometries.map(geometry)} - : t in geometryType ? {type: t, coordinates: geometryType[t](o)} - : null; - } - - var geometryType = { - Point: function(o) { return point(o.coordinates); }, - MultiPoint: function(o) { return o.coordinates.map(point); }, - LineString: function(o) { return line(o.arcs); }, - MultiLineString: function(o) { return o.arcs.map(line); }, - Polygon: function(o) { return polygon(o.arcs); }, - MultiPolygon: function(o) { return o.arcs.map(polygon); } - }; - - return geometry(o); - } - - function stitchArcs(topology, arcs) { - var stitchedArcs = {}, - fragmentByStart = {}, - fragmentByEnd = {}, - fragments = [], - emptyIndex = -1; - - // Stitch empty arcs first, since they may be subsumed by other arcs. - arcs.forEach(function(i, j) { - var arc = topology.arcs[i < 0 ? ~i : i], t; - if (arc.length < 3 && !arc[1][0] && !arc[1][1]) { - t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t; - } - }); - - arcs.forEach(function(i) { - var e = ends(i), - start = e[0], - end = e[1], - f, g; - - if (f = fragmentByEnd[start]) { - delete fragmentByEnd[f.end]; - f.push(i); - f.end = end; - if (g = fragmentByStart[end]) { - delete fragmentByStart[g.start]; - var fg = g === f ? f : f.concat(g); - fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; - } else { - fragmentByStart[f.start] = fragmentByEnd[f.end] = f; - } - } else if (f = fragmentByStart[end]) { - delete fragmentByStart[f.start]; - f.unshift(i); - f.start = start; - if (g = fragmentByEnd[start]) { - delete fragmentByEnd[g.end]; - var gf = g === f ? f : g.concat(f); - fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; - } else { - fragmentByStart[f.start] = fragmentByEnd[f.end] = f; - } + if (f = fragmentByEnd[start]) { + delete fragmentByEnd[f.end]; + f.push(i); + f.end = end; + if (g = fragmentByStart[end]) { + delete fragmentByStart[g.start]; + var fg = g === f ? f : f.concat(g); + fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg; } else { - f = [i]; - fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; + fragmentByStart[f.start] = fragmentByEnd[f.end] = f; } - }); - - function ends(i) { - var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; - if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); - else p1 = arc[arc.length - 1]; - return i < 0 ? [p1, p0] : [p0, p1]; - } - - function flush(fragmentByEnd, fragmentByStart) { - for (var k in fragmentByEnd) { - var f = fragmentByEnd[k]; - delete fragmentByStart[f.start]; - delete f.start; - delete f.end; - f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); - fragments.push(f); + } else if (f = fragmentByStart[end]) { + delete fragmentByStart[f.start]; + f.unshift(i); + f.start = start; + if (g = fragmentByEnd[start]) { + delete fragmentByEnd[g.end]; + var gf = g === f ? f : g.concat(f); + fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf; + } else { + fragmentByStart[f.start] = fragmentByEnd[f.end] = f; } - } - - flush(fragmentByEnd, fragmentByStart); - flush(fragmentByStart, fragmentByEnd); - arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); - - return fragments; - } - - function mesh(topology) { - return object(topology, meshArcs.apply(this, arguments)); - } - - function meshArcs(topology, o, filter) { - var arcs = []; - - function arc(i) { - var j = i < 0 ? ~i : i; - (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); - } - - function line(arcs) { - arcs.forEach(arc); - } - - function polygon(arcs) { - arcs.forEach(line); - } - - function geometry(o) { - if (o.type === "GeometryCollection") o.geometries.forEach(geometry); - else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); - } - - if (arguments.length > 1) { - var geomsByArc = [], - geom; - - var geometryType = { - LineString: line, - MultiLineString: polygon, - Polygon: polygon, - MultiPolygon: function(arcs) { arcs.forEach(polygon); } - }; - - geometry(o); - - geomsByArc.forEach(arguments.length < 3 - ? function(geoms) { arcs.push(geoms[0].i); } - : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); } else { - for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); + f = [i]; + fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f; } + }); - return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + function ends(i) { + var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1; + if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; }); + else p1 = arc[arc.length - 1]; + return i < 0 ? [p1, p0] : [p0, p1]; } - function cartesianTriangleArea(triangle) { - var a = triangle[0], b = triangle[1], c = triangle[2]; - return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + function flush(fragmentByEnd, fragmentByStart) { + for (var k in fragmentByEnd) { + var f = fragmentByEnd[k]; + delete fragmentByStart[f.start]; + delete f.start; + delete f.end; + f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; }); + fragments.push(f); + } } - function ring(ring) { - var i = -1, - n = ring.length, - a, - b = ring[n - 1], - area = 0; + flush(fragmentByEnd, fragmentByStart); + flush(fragmentByStart, fragmentByEnd); + arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); }); - while (++i < n) { - a = b; - b = ring[i]; - area += a[0] * b[1] - a[1] * b[0]; - } + return fragments; + } - return area / 2; + function mesh(topology) { + return object(topology, meshArcs.apply(this, arguments)); + } + + function meshArcs(topology, o, filter) { + var arcs = []; + + function arc(i) { + var j = i < 0 ? ~i : i; + (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom}); } - function merge(topology) { - return object(topology, mergeArcs.apply(this, arguments)); + function line(arcs) { + arcs.forEach(arc); } - function mergeArcs(topology, objects) { - var polygonsByArc = {}, - polygons = [], - components = []; - - objects.forEach(function(o) { - if (o.type === "Polygon") register(o.arcs); - else if (o.type === "MultiPolygon") o.arcs.forEach(register); - }); - - function register(polygon) { - polygon.forEach(function(ring$$) { - ring$$.forEach(function(arc) { - (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); - }); - }); - polygons.push(polygon); - } - - function area(ring$$) { - return Math.abs(ring(object(topology, {type: "Polygon", arcs: [ring$$]}).coordinates[0])); - } - - polygons.forEach(function(polygon) { - if (!polygon._) { - var component = [], - neighbors = [polygon]; - polygon._ = 1; - components.push(component); - while (polygon = neighbors.pop()) { - component.push(polygon); - polygon.forEach(function(ring$$) { - ring$$.forEach(function(arc) { - polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { - if (!polygon._) { - polygon._ = 1; - neighbors.push(polygon); - } - }); - }); - }); - } - } - }); - - polygons.forEach(function(polygon) { - delete polygon._; - }); - - return { - type: "MultiPolygon", - arcs: components.map(function(polygons) { - var arcs = [], n; - - // Extract the exterior (unique) arcs. - polygons.forEach(function(polygon) { - polygon.forEach(function(ring$$) { - ring$$.forEach(function(arc) { - if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { - arcs.push(arc); - } - }); - }); - }); - - // Stitch the arcs into one or more rings. - arcs = stitchArcs(topology, arcs); - - // If more than one ring is returned, - // at most one of these rings can be the exterior; - // choose the one with the greatest absolute area. - if ((n = arcs.length) > 1) { - for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) { - if ((ki = area(arcs[i])) > k) { - t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki; - } - } - } - - return arcs; - }) - }; + function polygon(arcs) { + arcs.forEach(line); } - function neighbors(objects) { - var indexesByArc = {}, // arc index -> array of object indexes - neighbors = objects.map(function() { return []; }); + function geometry(o) { + if (o.type === "GeometryCollection") o.geometries.forEach(geometry); + else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs); + } - function line(arcs, i) { - arcs.forEach(function(a) { - if (a < 0) a = ~a; - var o = indexesByArc[a]; - if (o) o.push(i); - else indexesByArc[a] = [i]; - }); - } - - function polygon(arcs, i) { - arcs.forEach(function(arc) { line(arc, i); }); - } - - function geometry(o, i) { - if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); - else if (o.type in geometryType) geometryType[o.type](o.arcs, i); - } + if (arguments.length > 1) { + var geomsByArc = [], + geom; var geometryType = { LineString: line, MultiLineString: polygon, Polygon: polygon, - MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + MultiPolygon: function(arcs) { arcs.forEach(polygon); } }; - objects.forEach(geometry); + geometry(o); - for (var i in indexesByArc) { - for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { - for (var k = j + 1; k < m; ++k) { - var ij = indexes[j], ik = indexes[k], n; - if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); - if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); - } - } - } - - return neighbors; + geomsByArc.forEach(arguments.length < 3 + ? function(geoms) { arcs.push(geoms[0].i); } + : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); }); + } else { + for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i); } - function compareArea(a, b) { - return a[1][2] - b[1][2]; + return {type: "MultiLineString", arcs: stitchArcs(topology, arcs)}; + } + + function cartesianTriangleArea(triangle) { + var a = triangle[0], b = triangle[1], c = triangle[2]; + return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1])); + } + + function ring(ring) { + var i = -1, + n = ring.length, + a, + b = ring[n - 1], + area = 0; + + while (++i < n) { + a = b; + b = ring[i]; + area += a[0] * b[1] - a[1] * b[0]; } - function minAreaHeap() { - var heap = {}, - array = [], - size = 0; + return area / 2; + } - heap.push = function(object) { - up(array[object._ = size] = object, size++); - return size; - }; + function merge(topology) { + return object(topology, mergeArcs.apply(this, arguments)); + } - heap.pop = function() { - if (size <= 0) return; - var removed = array[0], object; - if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); - return removed; - }; + function mergeArcs(topology, objects) { + var polygonsByArc = {}, + polygons = [], + components = []; - heap.remove = function(removed) { - var i = removed._, object; - if (array[i] !== removed) return; // invalid request - if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); - return i; - }; + objects.forEach(function(o) { + if (o.type === "Polygon") register(o.arcs); + else if (o.type === "MultiPolygon") o.arcs.forEach(register); + }); - function up(object, i) { - while (i > 0) { - var j = ((i + 1) >> 1) - 1, - parent = array[j]; - if (compareArea(object, parent) >= 0) break; - array[parent._ = i] = parent; - array[object._ = i = j] = object; - } - } - - function down(object, i) { - while (true) { - var r = (i + 1) << 1, - l = r - 1, - j = i, - child = array[j]; - if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; - if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; - if (j === i) break; - array[child._ = i] = child; - array[object._ = i = j] = object; - } - } - - return heap; - } - - function presimplify(topology, triangleArea) { - var absolute = transformAbsolute(topology.transform), - relative = transformRelative(topology.transform), - heap = minAreaHeap(); - - if (!triangleArea) triangleArea = cartesianTriangleArea; - - topology.arcs.forEach(function(arc) { - var triangles = [], - maxArea = 0, - triangle, - i, - n, - p; - - // To store each point’s effective area, we create a new array rather than - // extending the passed-in point to workaround a Chrome/V8 bug (getting - // stuck in smi mode). For midpoints, the initial effective area of - // Infinity will be computed in the next step. - for (i = 0, n = arc.length; i < n; ++i) { - p = arc[i]; - absolute(arc[i] = [p[0], p[1], Infinity], i); - } - - for (i = 1, n = arc.length - 1; i < n; ++i) { - triangle = arc.slice(i - 1, i + 2); - triangle[1][2] = triangleArea(triangle); - triangles.push(triangle); - heap.push(triangle); - } - - for (i = 0, n = triangles.length; i < n; ++i) { - triangle = triangles[i]; - triangle.previous = triangles[i - 1]; - triangle.next = triangles[i + 1]; - } - - while (triangle = heap.pop()) { - var previous = triangle.previous, - next = triangle.next; - - // If the area of the current point is less than that of the previous point - // to be eliminated, use the latter's area instead. This ensures that the - // current point cannot be eliminated without eliminating previously- - // eliminated points. - if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; - else maxArea = triangle[1][2]; - - if (previous) { - previous.next = next; - previous[2] = triangle[2]; - update(previous); - } - - if (next) { - next.previous = previous; - next[0] = triangle[0]; - update(next); - } - } - - arc.forEach(relative); + function register(polygon) { + polygon.forEach(function(ring$$) { + ring$$.forEach(function(arc) { + (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon); + }); }); + polygons.push(polygon); + } - function update(triangle) { - heap.remove(triangle); + function area(ring$$) { + return Math.abs(ring(object(topology, {type: "Polygon", arcs: [ring$$]}).coordinates[0])); + } + + polygons.forEach(function(polygon) { + if (!polygon._) { + var component = [], + neighbors = [polygon]; + polygon._ = 1; + components.push(component); + while (polygon = neighbors.pop()) { + component.push(polygon); + polygon.forEach(function(ring$$) { + ring$$.forEach(function(arc) { + polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) { + if (!polygon._) { + polygon._ = 1; + neighbors.push(polygon); + } + }); + }); + }); + } + } + }); + + polygons.forEach(function(polygon) { + delete polygon._; + }); + + return { + type: "MultiPolygon", + arcs: components.map(function(polygons) { + var arcs = [], n; + + // Extract the exterior (unique) arcs. + polygons.forEach(function(polygon) { + polygon.forEach(function(ring$$) { + ring$$.forEach(function(arc) { + if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) { + arcs.push(arc); + } + }); + }); + }); + + // Stitch the arcs into one or more rings. + arcs = stitchArcs(topology, arcs); + + // If more than one ring is returned, + // at most one of these rings can be the exterior; + // choose the one with the greatest absolute area. + if ((n = arcs.length) > 1) { + for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) { + if ((ki = area(arcs[i])) > k) { + t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki; + } + } + } + + return arcs; + }) + }; + } + + function neighbors(objects) { + var indexesByArc = {}, // arc index -> array of object indexes + neighbors = objects.map(function() { return []; }); + + function line(arcs, i) { + arcs.forEach(function(a) { + if (a < 0) a = ~a; + var o = indexesByArc[a]; + if (o) o.push(i); + else indexesByArc[a] = [i]; + }); + } + + function polygon(arcs, i) { + arcs.forEach(function(arc) { line(arc, i); }); + } + + function geometry(o, i) { + if (o.type === "GeometryCollection") o.geometries.forEach(function(o) { geometry(o, i); }); + else if (o.type in geometryType) geometryType[o.type](o.arcs, i); + } + + var geometryType = { + LineString: line, + MultiLineString: polygon, + Polygon: polygon, + MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); } + }; + + objects.forEach(geometry); + + for (var i in indexesByArc) { + for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) { + for (var k = j + 1; k < m; ++k) { + var ij = indexes[j], ik = indexes[k], n; + if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik); + if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij); + } + } + } + + return neighbors; + } + + function compareArea(a, b) { + return a[1][2] - b[1][2]; + } + + function minAreaHeap() { + var heap = {}, + array = [], + size = 0; + + heap.push = function(object) { + up(array[object._ = size] = object, size++); + return size; + }; + + heap.pop = function() { + if (size <= 0) return; + var removed = array[0], object; + if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0); + return removed; + }; + + heap.remove = function(removed) { + var i = removed._, object; + if (array[i] !== removed) return; // invalid request + if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i); + return i; + }; + + function up(object, i) { + while (i > 0) { + var j = ((i + 1) >> 1) - 1, + parent = array[j]; + if (compareArea(object, parent) >= 0) break; + array[parent._ = i] = parent; + array[object._ = i = j] = object; + } + } + + function down(object, i) { + while (true) { + var r = (i + 1) << 1, + l = r - 1, + j = i, + child = array[j]; + if (l < size && compareArea(array[l], child) < 0) child = array[j = l]; + if (r < size && compareArea(array[r], child) < 0) child = array[j = r]; + if (j === i) break; + array[child._ = i] = child; + array[object._ = i = j] = object; + } + } + + return heap; + } + + function presimplify(topology, triangleArea) { + var absolute = transformAbsolute(topology.transform), + relative = transformRelative(topology.transform), + heap = minAreaHeap(); + + if (!triangleArea) triangleArea = cartesianTriangleArea; + + topology.arcs.forEach(function(arc) { + var triangles = [], + maxArea = 0, + triangle, + i, + n, + p; + + // To store each point’s effective area, we create a new array rather than + // extending the passed-in point to workaround a Chrome/V8 bug (getting + // stuck in smi mode). For midpoints, the initial effective area of + // Infinity will be computed in the next step. + for (i = 0, n = arc.length; i < n; ++i) { + p = arc[i]; + absolute(arc[i] = [p[0], p[1], Infinity], i); + } + + for (i = 1, n = arc.length - 1; i < n; ++i) { + triangle = arc.slice(i - 1, i + 2); triangle[1][2] = triangleArea(triangle); + triangles.push(triangle); heap.push(triangle); } - return topology; + for (i = 0, n = triangles.length; i < n; ++i) { + triangle = triangles[i]; + triangle.previous = triangles[i - 1]; + triangle.next = triangles[i + 1]; + } + + while (triangle = heap.pop()) { + var previous = triangle.previous, + next = triangle.next; + + // If the area of the current point is less than that of the previous point + // to be eliminated, use the latter's area instead. This ensures that the + // current point cannot be eliminated without eliminating previously- + // eliminated points. + if (triangle[1][2] < maxArea) triangle[1][2] = maxArea; + else maxArea = triangle[1][2]; + + if (previous) { + previous.next = next; + previous[2] = triangle[2]; + update(previous); + } + + if (next) { + next.previous = previous; + next[0] = triangle[0]; + update(next); + } + } + + arc.forEach(relative); + }); + + function update(triangle) { + heap.remove(triangle); + triangle[1][2] = triangleArea(triangle); + heap.push(triangle); } - var version = "1.6.26"; + return topology; + } - exports.version = version; - exports.mesh = mesh; - exports.meshArcs = meshArcs; - exports.merge = merge; - exports.mergeArcs = mergeArcs; - exports.feature = feature; - exports.neighbors = neighbors; - exports.presimplify = presimplify; + var version = "1.6.27"; - })); + exports.version = version; + exports.mesh = mesh; + exports.meshArcs = meshArcs; + exports.merge = merge; + exports.mergeArcs = mergeArcs; + exports.feature = feature; + exports.neighbors = neighbors; + exports.presimplify = presimplify; + + Object.defineProperty(exports, '__esModule', { value: true }); + + }))); /***/ }, -/* 65 */ +/* 77 */ /***/ function(module, exports, __webpack_require__) { - var normalize = __webpack_require__(66); + var normalize = __webpack_require__(78); module.exports = function(inputs) { return { @@ -15661,7 +16518,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 66 */ +/* 78 */ /***/ function(module, exports) { module.exports = normalize; @@ -15710,7 +16567,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 67 */ +/* 79 */ /***/ function(module, exports) { 'use strict'; @@ -16360,7 +17217,7 @@ return /******/ (function(modules) { // webpackBootstrap /***/ }, -/* 68 */ +/* 80 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -16459,7 +17316,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 69 */ +/* 81 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -16477,6 +17334,94 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); var Buffer = (function () { + // Merge TypedArrays of the same type + // Returns merged array as well as indexes for splitting the array + var mergeFloat32Arrays = function mergeFloat32Arrays(arrays) { + var size = 0; + var map = new Int32Array(arrays.length * 2); + + var lastIndex = 0; + var length; + + // Find size of each array + arrays.forEach(function (_array, index) { + length = _array.length; + size += length; + map.set([lastIndex, lastIndex + length], index * 2); + lastIndex += length; + }); + + // Create a new array of total size + var mergedArray = new Float32Array(size); + + // Add each array to the new array + arrays.forEach(function (_array, index) { + mergedArray.set(_array, map[index * 2]); + }); + + return [mergedArray, map]; + }; + + var splitFloat32Array = function splitFloat32Array(data) { + var arr = data[0]; + var map = data[1]; + + var start; + var arrays = []; + + // Iterate over map + for (var i = 0; i < map.length / 2; i++) { + start = i * 2; + arrays.push(arr.subarray(map[start], map[start + 1])); + } + + return arrays; + }; + + // TODO: Create a generic method that can work for any typed array + var mergeUint8Arrays = function mergeUint8Arrays(arrays) { + var size = 0; + var map = new Int32Array(arrays.length * 2); + + var lastIndex = 0; + var length; + + // Find size of each array + arrays.forEach(function (_array, index) { + length = _array.length; + size += length; + map.set([lastIndex, lastIndex + length], index * 2); + lastIndex += length; + }); + + // Create a new array of total size + var mergedArray = new Uint8Array(size); + + // Add each array to the new array + arrays.forEach(function (_array, index) { + mergedArray.set(_array, map[index * 2]); + }); + + return [mergedArray, map]; + }; + + // TODO: Dedupe with splitFloat32Array + var splitUint8Array = function splitUint8Array(data) { + var arr = data[0]; + var map = data[1]; + + var start; + var arrays = []; + + // Iterate over map + for (var i = 0; i < map.length / 2; i++) { + start = i * 2; + arrays.push(arr.subarray(map[start], map[start + 1])); + } + + return arrays; + }; + // Merge multiple attribute objects into a single attribute object // // Attribute objects must all use the same attribute keys @@ -16719,10 +17664,27 @@ return /******/ (function(modules) { // webpackBootstrap return geometry; }; + var textEncoder = new TextEncoder('utf-8'); + var textDecoder = new TextDecoder('utf-8'); + + var stringToUint8Array = function stringToUint8Array(str) { + return textEncoder.encode(str); + }; + + var uint8ArrayToString = function uint8ArrayToString(ab) { + return textDecoder.decode(ab); + }; + return { + mergeFloat32Arrays: mergeFloat32Arrays, + splitFloat32Array: splitFloat32Array, + mergeUint8Arrays: mergeUint8Arrays, + splitUint8Array: splitUint8Array, mergeAttributes: mergeAttributes, createLineGeometry: createLineGeometry, - createGeometry: createGeometry + createGeometry: createGeometry, + stringToUint8Array: stringToUint8Array, + uint8ArrayToString: uint8ArrayToString }; })(); @@ -16730,7 +17692,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 70 */ +/* 82 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -16743,7 +17705,7 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); - var _PickingShader = __webpack_require__(71); + var _PickingShader = __webpack_require__(83); var _PickingShader2 = _interopRequireDefault(_PickingShader); @@ -16785,7 +17747,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 71 */ +/* 83 */ /***/ function(module, exports) { Object.defineProperty(exports, '__esModule', { @@ -16809,7 +17771,7 @@ return /******/ (function(modules) { // webpackBootstrap module.exports = exports['default']; /***/ }, -/* 72 */ +/* 84 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -16842,7 +17804,7 @@ return /******/ (function(modules) { // webpackBootstrap // TODO: Allow _setBufferAttributes to use a custom function passed in to // generate a custom mesh - var _Layer2 = __webpack_require__(32); + var _Layer2 = __webpack_require__(34); var _Layer3 = _interopRequireDefault(_Layer2); @@ -16854,23 +17816,27 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); + var _geoGeo = __webpack_require__(6); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + var _geoLatLon = __webpack_require__(7); var _geoPoint = __webpack_require__(8); - var _earcut2 = __webpack_require__(67); + var _earcut2 = __webpack_require__(79); var _earcut3 = _interopRequireDefault(_earcut2); - var _utilExtrudePolygon = __webpack_require__(68); + var _utilExtrudePolygon = __webpack_require__(80); var _utilExtrudePolygon2 = _interopRequireDefault(_utilExtrudePolygon); - var _enginePickingMaterial = __webpack_require__(70); + var _enginePickingMaterial = __webpack_require__(82); var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); - var _utilBuffer = __webpack_require__(69); + var _utilBuffer = __webpack_require__(81); var _utilBuffer2 = _interopRequireDefault(_utilBuffer); @@ -16886,8 +17852,8 @@ return /******/ (function(modules) { // webpackBootstrap // Custom material override // // TODO: Should this be in the style object? - material: null, - onMesh: null, + polygonMaterial: null, + onPolygonMesh: null, onBufferAttributes: null, // This default style is separate to Util.GeoJSON.defaultStyle style: { @@ -16912,34 +17878,66 @@ return /******/ (function(modules) { // webpackBootstrap _createClass(PolygonLayer, [{ key: '_onAdd', value: function _onAdd(world) { - this._setCoordinates(); + var _this = this; - if (this._options.interactive) { - // Only add to picking mesh if this layer is controlling output - // - // Otherwise, assume another component will eventually add a mesh to - // the picking scene - if (this.isOutput()) { - this._pickingMesh = new _three2['default'].Object3D(); - this.addToPicking(this._pickingMesh); + return new Promise(function (resolve, reject) { + _this._setCoordinates(); + + if (_this._options.interactive) { + // Only add to picking mesh if this layer is controlling output + // + // Otherwise, assume another component will eventually add a mesh to + // the picking scene + if (_this.isOutput()) { + _this._pickingMesh = new _three2['default'].Object3D(); + _this.addToPicking(_this._pickingMesh); + } + + _this._setPickingId(); + _this._addPickingEvents(); } - this._setPickingId(); - this._addPickingEvents(); - } + PolygonLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) { + _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes); - // Store geometry representation as instances of THREE.BufferAttribute - this._setBufferAttributes(); + if (result.outlineAttributes.length > 0) { + _this._outlineBufferAttributes = _utilBuffer2['default'].mergeAttributes(result.outlineAttributes); + } - if (this.isOutput()) { - // Set mesh if not merging elsewhere - this._setMesh(this._bufferAttributes); + _this._flat = result.flat; - // Output mesh - this.add(this._mesh); - } + if (_this.isOutput()) { + var attributeLengths = { + positions: 3, + normals: 3, + colors: 3, + tops: 1 + }; - return Promise.resolve(this); + if (_this._options.interactive) { + attributeLengths.pickingIds = 1; + } + + var style = _this._options.style; + + // Set mesh if not merging elsewhere + PolygonLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) { + // Output mesh + _this.add(result.mesh); + + if (result.pickingMesh) { + _this._pickingMesh.add(result.pickingMesh); + } + }); + } + + result.attributes = null; + result.outlineAttributes = null; + result = null; + + resolve(_this); + })['catch'](reject); + }); } // Return center of polygon as a LatLon @@ -16972,137 +17970,26 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_addPickingEvents', value: function _addPickingEvents() { - var _this = this; + var _this2 = this; // TODO: Find a way to properly remove this listener on destroy this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) { // Re-emit click event from the layer - _this.emit('click', _this, point2d, point3d, intersects); + _this2.emit('click', _this2, point2d, point3d, intersects); }); } // Create and store reference to THREE.BufferAttribute data for this layer - }, { - key: '_setBufferAttributes', - value: function _setBufferAttributes() { - var _this2 = this; - - var attributes; - - // Only use this if you know what you're doing - if (typeof this._options.onBufferAttributes === 'function') { - // TODO: Probably want to pass something less general as arguments, - // though passing the instance will do for now (it's everything) - attributes = this._options.onBufferAttributes(this); - } else { - var height = 0; - - // Convert height into world units - if (this._options.style.height && this._options.style.height !== 0) { - height = this._world.metresToWorld(this._options.style.height, this._pointScale); - } - - var colour = new _three2['default'].Color(); - colour.set(this._options.style.color); - - // Light and dark colours used for poor-mans AO gradient on object sides - var light = new _three2['default'].Color(0xffffff); - var shadow = new _three2['default'].Color(0x666666); - - // For each polygon - attributes = this._projectedCoordinates.map(function (_projectedCoordinates) { - // Convert coordinates to earcut format - var _earcut = _this2._toEarcut(_projectedCoordinates); - - // Triangulate faces using earcut - var faces = _this2._triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions); - - var groupedVertices = []; - for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) { - groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions)); - } - - var extruded = (0, _utilExtrudePolygon2['default'])(groupedVertices, faces, { - bottom: 0, - top: height - }); - - var topColor = colour.clone().multiply(light); - var bottomColor = colour.clone().multiply(shadow); - - var _vertices = extruded.positions; - var _faces = []; - var _colours = []; - - var _colour; - extruded.top.forEach(function (face, fi) { - _colour = []; - - _colour.push([colour.r, colour.g, colour.b]); - _colour.push([colour.r, colour.g, colour.b]); - _colour.push([colour.r, colour.g, colour.b]); - - _faces.push(face); - _colours.push(_colour); - }); - - _this2._flat = true; - - if (extruded.sides) { - _this2._flat = false; - - // Set up colours for every vertex with poor-mans AO on the sides - extruded.sides.forEach(function (face, fi) { - _colour = []; - - // First face is always bottom-bottom-top - if (fi % 2 === 0) { - _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); - _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); - _colour.push([topColor.r, topColor.g, topColor.b]); - // Reverse winding for the second face - // top-top-bottom - } else { - _colour.push([topColor.r, topColor.g, topColor.b]); - _colour.push([topColor.r, topColor.g, topColor.b]); - _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); - } - - _faces.push(face); - _colours.push(_colour); - }); - } - - // Skip bottom as there's no point rendering it - // allFaces.push(extruded.faces); - - var polygon = { - vertices: _vertices, - faces: _faces, - colours: _colours, - facesCount: _faces.length - }; - - if (_this2._options.interactive && _this2._pickingId) { - // Inject picking ID - polygon.pickingId = _this2._pickingId; - } - - // Convert polygon representation to proper attribute arrays - return _this2._toAttributes(polygon); - }); - } - - this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes); - - // Original attributes are no longer required so free the memory - attributes = null; - } }, { key: 'getBufferAttributes', value: function getBufferAttributes() { return this._bufferAttributes; } + }, { + key: 'getOutlineBufferAttributes', + value: function getOutlineBufferAttributes() { + return this._outlineBufferAttributes; + } // Used by external components to clear some memory when the attributes // are no longer required to be stored in this layer @@ -17113,97 +18000,28 @@ return /******/ (function(modules) { // webpackBootstrap key: 'clearBufferAttributes', value: function clearBufferAttributes() { this._bufferAttributes = null; + this._outlineBufferAttributes = null; } + // Threshold angle is currently in rads + }, { + key: 'clearCoordinates', + // Used by external components to clear some memory when the coordinates // are no longer required to be stored in this layer // // For example, you would want to clear the coordinates here after this // layer is merged in something like the GeoJSONLayer - }, { - key: 'clearCoordinates', value: function clearCoordinates() { this._coordinates = null; this._projectedCoordinates = null; } - - // Create and store mesh from buffer attributes - // - // This is only called if the layer is controlling its own output }, { - key: '_setMesh', - value: function _setMesh(attributes) { - var geometry = new _three2['default'].BufferGeometry(); - - // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3)); - geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3)); - geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3)); - - if (attributes.pickingIds) { - geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1)); - } - - geometry.computeBoundingBox(); - - var material; - if (this._options.material && this._options.material instanceof _three2['default'].Material) { - material = this._options.material; - } else if (!this._world._environment._skybox) { - material = new _three2['default'].MeshPhongMaterial({ - vertexColors: _three2['default'].VertexColors, - side: _three2['default'].BackSide, - transparent: this._options.style.transparent, - opacity: this._options.style.opacity, - blending: this._options.style.blending - }); - } else { - material = new _three2['default'].MeshStandardMaterial({ - vertexColors: _three2['default'].VertexColors, - side: _three2['default'].BackSide, - transparent: this._options.style.transparent, - opacity: this._options.style.opacity, - blending: this._options.style.blending - }); - material.roughness = 1; - material.metalness = 0.1; - material.envMapIntensity = 3; - material.envMap = this._world._environment._skybox.getRenderTarget(); - } - - var mesh; - - // Pass mesh through callback, if defined - if (typeof this._options.onMesh === 'function') { - mesh = this._options.onMesh(geometry, material); - } else { - mesh = new _three2['default'].Mesh(geometry, material); - - mesh.castShadow = true; - mesh.receiveShadow = true; - } - - if (this.isFlat()) { - material.depthWrite = false; - mesh.renderOrder = 1; - } - - if (this._options.interactive && this._pickingMesh) { - material = new _enginePickingMaterial2['default'](); - material.side = _three2['default'].BackSide; - - var pickingMesh = new _three2['default'].Mesh(geometry, material); - this._pickingMesh.add(pickingMesh); - } - - this._mesh = mesh; - } + key: '_setCoordinates', // Convert and project coordinates // // TODO: Calculate bounds - }, { - key: '_setCoordinates', value: function _setCoordinates() { this._bounds = []; this._coordinates = this._convertCoordinates(this._coordinates); @@ -17253,7 +18071,7 @@ return /******/ (function(modules) { // webpackBootstrap _this3._offset.x = -1 * point.x; _this3._offset.y = -1 * point.y; - _this3._pointScale = _this3._world.pointScale(latlon); + _this3._options.pointScale = _this3._world.pointScale(latlon); } return point; @@ -17264,187 +18082,9 @@ return /******/ (function(modules) { // webpackBootstrap // Convert coordinates array to something earcut can understand }, { - key: '_toEarcut', - value: function _toEarcut(coordinates) { - var dim = 2; - var result = { vertices: [], holes: [], dimensions: dim }; - var holeIndex = 0; - - for (var i = 0; i < coordinates.length; i++) { - for (var j = 0; j < coordinates[i].length; j++) { - // for (var d = 0; d < dim; d++) { - result.vertices.push(coordinates[i][j].x); - result.vertices.push(coordinates[i][j].y); - // } - } - if (i > 0) { - holeIndex += coordinates[i - 1].length; - result.holes.push(holeIndex); - } - } - - return result; - } - - // Triangulate earcut-based input using earcut - }, { - key: '_triangulate', - value: function _triangulate(contour, holes, dim) { - // console.time('earcut'); - - var faces = (0, _earcut3['default'])(contour, holes, dim); - var result = []; - - for (i = 0, il = faces.length; i < il; i += 3) { - result.push(faces.slice(i, i + 3)); - } - - // console.timeEnd('earcut'); - - return result; - } - - // Transform polygon representation into attribute arrays that can be used by - // THREE.BufferGeometry - // - // TODO: Can this be simplified? It's messy and huge - }, { - key: '_toAttributes', - value: function _toAttributes(polygon) { - // Three components per vertex per face (3 x 3 = 9) - var vertices = new Float32Array(polygon.facesCount * 9); - var normals = new Float32Array(polygon.facesCount * 9); - var colours = new Float32Array(polygon.facesCount * 9); - - var pickingIds; - if (polygon.pickingId) { - // One component per vertex per face (1 x 3 = 3) - pickingIds = new Float32Array(polygon.facesCount * 3); - } - - var pA = new _three2['default'].Vector3(); - var pB = new _three2['default'].Vector3(); - var pC = new _three2['default'].Vector3(); - - var cb = new _three2['default'].Vector3(); - var ab = new _three2['default'].Vector3(); - - var index; - - var _faces = polygon.faces; - var _vertices = polygon.vertices; - var _colour = polygon.colours; - - var _pickingId; - if (pickingIds) { - _pickingId = polygon.pickingId; - } - - var lastIndex = 0; - - for (var i = 0; i < _faces.length; i++) { - // Array of vertex indexes for the face - index = _faces[i][0]; - - var ax = _vertices[index][0]; - var ay = _vertices[index][1]; - var az = _vertices[index][2]; - - var c1 = _colour[i][0]; - - index = _faces[i][1]; - - var bx = _vertices[index][0]; - var by = _vertices[index][1]; - var bz = _vertices[index][2]; - - var c2 = _colour[i][1]; - - index = _faces[i][2]; - - var cx = _vertices[index][0]; - var cy = _vertices[index][1]; - var cz = _vertices[index][2]; - - var c3 = _colour[i][2]; - - // Flat face normals - // From: http://threejs.org/examples/webgl_buffergeometry.html - pA.set(ax, ay, az); - pB.set(bx, by, bz); - pC.set(cx, cy, cz); - - cb.subVectors(pC, pB); - ab.subVectors(pA, pB); - cb.cross(ab); - - cb.normalize(); - - var nx = cb.x; - var ny = cb.y; - var nz = cb.z; - - vertices[lastIndex * 9 + 0] = ax; - vertices[lastIndex * 9 + 1] = ay; - vertices[lastIndex * 9 + 2] = az; - - normals[lastIndex * 9 + 0] = nx; - normals[lastIndex * 9 + 1] = ny; - normals[lastIndex * 9 + 2] = nz; - - colours[lastIndex * 9 + 0] = c1[0]; - colours[lastIndex * 9 + 1] = c1[1]; - colours[lastIndex * 9 + 2] = c1[2]; - - vertices[lastIndex * 9 + 3] = bx; - vertices[lastIndex * 9 + 4] = by; - vertices[lastIndex * 9 + 5] = bz; - - normals[lastIndex * 9 + 3] = nx; - normals[lastIndex * 9 + 4] = ny; - normals[lastIndex * 9 + 5] = nz; - - colours[lastIndex * 9 + 3] = c2[0]; - colours[lastIndex * 9 + 4] = c2[1]; - colours[lastIndex * 9 + 5] = c2[2]; - - vertices[lastIndex * 9 + 6] = cx; - vertices[lastIndex * 9 + 7] = cy; - vertices[lastIndex * 9 + 8] = cz; - - normals[lastIndex * 9 + 6] = nx; - normals[lastIndex * 9 + 7] = ny; - normals[lastIndex * 9 + 8] = nz; - - colours[lastIndex * 9 + 6] = c3[0]; - colours[lastIndex * 9 + 7] = c3[1]; - colours[lastIndex * 9 + 8] = c3[2]; - - if (pickingIds) { - pickingIds[lastIndex * 3 + 0] = _pickingId; - pickingIds[lastIndex * 3 + 1] = _pickingId; - pickingIds[lastIndex * 3 + 2] = _pickingId; - } - - lastIndex++; - } - - var attributes = { - vertices: vertices, - normals: normals, - colours: colours - }; - - if (pickingIds) { - attributes.pickingIds = pickingIds; - } - - return attributes; - } + key: 'isFlat', // Returns true if the polygon is flat (has no height) - }, { - key: 'isFlat', value: function isFlat() { return this._flat; } @@ -17469,6 +18109,445 @@ return /******/ (function(modules) { // webpackBootstrap _get(Object.getPrototypeOf(PolygonLayer.prototype), 'destroy', this).call(this); } }], [{ + key: 'SetBufferAttributes', + value: function SetBufferAttributes(coordinates, options) { + return new Promise(function (resolve) { + var height = 0; + + // Convert height into world units + if (options.style.height && options.style.height !== 0) { + height = _geoGeo2['default'].metresToWorld(options.style.height, options.pointScale); + } + + var colour = new _three2['default'].Color(); + colour.set(options.style.color); + + // Light and dark colours used for poor-mans AO gradient on object sides + var light = new _three2['default'].Color(0xffffff); + var shadow = new _three2['default'].Color(0x666666); + + var flat = true; + + var outlineAttributes = []; + + // For each polygon + var attributes = coordinates.map(function (_coordinates) { + // Convert coordinates to earcut format + var _earcut = PolygonLayer.ToEarcut(_coordinates); + + // Triangulate faces using earcut + var faces = PolygonLayer.Triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions); + + var groupedVertices = []; + for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) { + groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions)); + } + + var extruded = (0, _utilExtrudePolygon2['default'])(groupedVertices, faces, { + bottom: 0, + top: height + }); + + var topColor = colour.clone().multiply(light); + var bottomColor = colour.clone().multiply(shadow); + + var _vertices = extruded.positions; + var _faces = []; + var _colours = []; + var _tops = []; + + var _colour; + extruded.top.forEach(function (face, fi) { + _colour = []; + + _colour.push([colour.r, colour.g, colour.b]); + _colour.push([colour.r, colour.g, colour.b]); + _colour.push([colour.r, colour.g, colour.b]); + + _tops.push([true, true, true]); + + _faces.push(face); + _colours.push(_colour); + }); + + if (extruded.sides) { + flat = false; + + // Set up colours for every vertex with poor-mans AO on the sides + extruded.sides.forEach(function (face, fi) { + _colour = []; + + // First face is always bottom-bottom-top + if (fi % 2 === 0) { + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + _colour.push([topColor.r, topColor.g, topColor.b]); + + _tops.push([false, false, true]); + // Reverse winding for the second face + // top-top-bottom + } else { + _colour.push([topColor.r, topColor.g, topColor.b]); + _colour.push([topColor.r, topColor.g, topColor.b]); + _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]); + + _tops.push([true, true, false]); + } + + _faces.push(face); + _colours.push(_colour); + }); + } + + // Skip bottom as there's no point rendering it + // allFaces.push(extruded.faces); + + var polygon = { + vertices: _vertices, + faces: _faces, + colours: _colours, + tops: _tops, + facesCount: _faces.length + }; + + if (options.style.outline) { + var outlineColour = new _three2['default'].Color(); + outlineColour.set(options.style.outlineColor || 0x000000); + + outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour)); + } + + if (options.interactive && options.pickingId) { + // Inject picking ID + polygon.pickingId = options.pickingId; + } + + // Convert polygon representation to proper attribute arrays + return PolygonLayer.ToAttributes(polygon); + }); + + resolve({ + attributes: attributes, + outlineAttributes: outlineAttributes, + flat: flat + }); + }); + } + }, { + key: 'Set2DOutline', + value: function Set2DOutline(coordinates, colour) { + var _vertices = []; + + coordinates.forEach(function (ring) { + var _ring = ring.map(function (coordinate) { + return [coordinate.x, 0, coordinate.y]; + }); + + // Add in duplicate vertices for line segments to work + var verticeCount = _ring.length; + var first = true; + while (--verticeCount) { + if (first || verticeCount === 0) { + first = false; + continue; + } + + _ring.splice(verticeCount + 1, 0, _ring[verticeCount]); + } + + _vertices = _vertices.concat(_ring); + }); + + _colour = [colour.r, colour.g, colour.b]; + + var vertices = new Float32Array(_vertices.length * 3); + var colours = new Float32Array(_vertices.length * 3); + + var lastIndex = 0; + + for (var i = 0; i < _vertices.length; i++) { + var ax = _vertices[i][0]; + var ay = _vertices[i][1]; + var az = _vertices[i][2]; + + var c1 = _colour; + + vertices[lastIndex * 3 + 0] = ax; + vertices[lastIndex * 3 + 1] = ay; + vertices[lastIndex * 3 + 2] = az; + + colours[lastIndex * 3 + 0] = c1[0]; + colours[lastIndex * 3 + 1] = c1[1]; + colours[lastIndex * 3 + 2] = c1[2]; + + lastIndex++; + } + + var attributes = { + positions: vertices, + colors: colours + }; + + return attributes; + } + }, { + key: 'SetMesh', + value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) { + var geometry = new _three2['default'].BufferGeometry(); + + for (var key in attributes) { + geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key])); + } + + geometry.computeBoundingBox(); + + var material; + if (options.polygonMaterial && options.polygonMaterial instanceof _three2['default'].Material) { + material = options.polygonMaterial; + } else if (!skybox) { + material = new _three2['default'].MeshPhongMaterial({ + vertexColors: _three2['default'].VertexColors, + side: _three2['default'].BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + } else { + material = new _three2['default'].MeshStandardMaterial({ + vertexColors: _three2['default'].VertexColors, + side: _three2['default'].BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + material.roughness = 1; + material.metalness = 0.1; + material.envMapIntensity = 3; + material.envMap = skybox.getRenderTarget(); + } + + var mesh; + + // Pass mesh through callback, if defined + if (typeof options.onPolygonMesh === 'function') { + mesh = options.onPolygonMesh(geometry, material); + } else { + mesh = new _three2['default'].Mesh(geometry, material); + + mesh.castShadow = true; + mesh.receiveShadow = true; + } + + if (flat) { + material.depthWrite = false; + + var renderOrder = style.renderOrder !== undefined ? style.renderOrder : 3; + mesh.renderOrder = renderOrder; + } + + if (options.interactive) { + material = new _enginePickingMaterial2['default'](); + material.side = _three2['default'].BackSide; + + var pickingMesh = new _three2['default'].Mesh(geometry, material); + } + + return Promise.resolve({ + mesh: mesh, + pickingMesh: pickingMesh + }); + } + }, { + key: 'ToEarcut', + value: function ToEarcut(coordinates) { + var dim = 2; + var result = { vertices: [], holes: [], dimensions: dim }; + var holeIndex = 0; + + for (var i = 0; i < coordinates.length; i++) { + for (var j = 0; j < coordinates[i].length; j++) { + // for (var d = 0; d < dim; d++) { + result.vertices.push(coordinates[i][j].x); + result.vertices.push(coordinates[i][j].y); + // } + } + if (i > 0) { + holeIndex += coordinates[i - 1].length; + result.holes.push(holeIndex); + } + } + + return result; + } + + // Triangulate earcut-based input using earcut + }, { + key: 'Triangulate', + value: function Triangulate(contour, holes, dim) { + // console.time('earcut'); + + var faces = (0, _earcut3['default'])(contour, holes, dim); + var result = []; + + for (i = 0, il = faces.length; i < il; i += 3) { + result.push(faces.slice(i, i + 3)); + } + + // console.timeEnd('earcut'); + + return result; + } + + // Transform polygon representation into attribute arrays that can be used by + // THREE.BufferGeometry + // + // TODO: Can this be simplified? It's messy and huge + }, { + key: 'ToAttributes', + value: function ToAttributes(polygon) { + // Three components per vertex per face (3 x 3 = 9) + var positions = new Float32Array(polygon.facesCount * 9); + var normals = new Float32Array(polygon.facesCount * 9); + var colours = new Float32Array(polygon.facesCount * 9); + + // One component per vertex per face (1 x 3 = 3) + var tops = new Float32Array(polygon.facesCount * 3); + + var pickingIds; + if (polygon.pickingId) { + // One component per vertex per face (1 x 3 = 3) + pickingIds = new Float32Array(polygon.facesCount * 3); + } + + var pA = new _three2['default'].Vector3(); + var pB = new _three2['default'].Vector3(); + var pC = new _three2['default'].Vector3(); + + var cb = new _three2['default'].Vector3(); + var ab = new _three2['default'].Vector3(); + + var index; + + var _faces = polygon.faces; + var _vertices = polygon.vertices; + var _colour = polygon.colours; + var _tops = polygon.tops; + + var _pickingId; + if (pickingIds) { + _pickingId = polygon.pickingId; + } + + var lastIndex = 0; + + for (var i = 0; i < _faces.length; i++) { + // Array of vertex indexes for the face + index = _faces[i][0]; + + var ax = _vertices[index][0]; + var ay = _vertices[index][1]; + var az = _vertices[index][2]; + + var c1 = _colour[i][0]; + var t1 = _tops[i][0]; + + index = _faces[i][1]; + + var bx = _vertices[index][0]; + var by = _vertices[index][1]; + var bz = _vertices[index][2]; + + var c2 = _colour[i][1]; + var t2 = _tops[i][1]; + + index = _faces[i][2]; + + var cx = _vertices[index][0]; + var cy = _vertices[index][1]; + var cz = _vertices[index][2]; + + var c3 = _colour[i][2]; + var t3 = _tops[i][2]; + + // Flat face normals + // From: http://threejs.org/examples/webgl_buffergeometry.html + pA.set(ax, ay, az); + pB.set(bx, by, bz); + pC.set(cx, cy, cz); + + cb.subVectors(pC, pB); + ab.subVectors(pA, pB); + cb.cross(ab); + + cb.normalize(); + + var nx = cb.x; + var ny = cb.y; + var nz = cb.z; + + positions[lastIndex * 9 + 0] = ax; + positions[lastIndex * 9 + 1] = ay; + positions[lastIndex * 9 + 2] = az; + + normals[lastIndex * 9 + 0] = nx; + normals[lastIndex * 9 + 1] = ny; + normals[lastIndex * 9 + 2] = nz; + + colours[lastIndex * 9 + 0] = c1[0]; + colours[lastIndex * 9 + 1] = c1[1]; + colours[lastIndex * 9 + 2] = c1[2]; + + positions[lastIndex * 9 + 3] = bx; + positions[lastIndex * 9 + 4] = by; + positions[lastIndex * 9 + 5] = bz; + + normals[lastIndex * 9 + 3] = nx; + normals[lastIndex * 9 + 4] = ny; + normals[lastIndex * 9 + 5] = nz; + + colours[lastIndex * 9 + 3] = c2[0]; + colours[lastIndex * 9 + 4] = c2[1]; + colours[lastIndex * 9 + 5] = c2[2]; + + positions[lastIndex * 9 + 6] = cx; + positions[lastIndex * 9 + 7] = cy; + positions[lastIndex * 9 + 8] = cz; + + normals[lastIndex * 9 + 6] = nx; + normals[lastIndex * 9 + 7] = ny; + normals[lastIndex * 9 + 8] = nz; + + colours[lastIndex * 9 + 6] = c3[0]; + colours[lastIndex * 9 + 7] = c3[1]; + colours[lastIndex * 9 + 8] = c3[2]; + + tops[lastIndex * 3 + 0] = t1; + tops[lastIndex * 3 + 1] = t2; + tops[lastIndex * 3 + 2] = t3; + + if (pickingIds) { + pickingIds[lastIndex * 3 + 0] = _pickingId; + pickingIds[lastIndex * 3 + 1] = _pickingId; + pickingIds[lastIndex * 3 + 2] = _pickingId; + } + + lastIndex++; + } + + var attributes = { + positions: positions, + normals: normals, + colors: colours, + tops: tops + }; + + if (pickingIds) { + attributes.pickingIds = pickingIds; + } + + return attributes; + } + }, { key: 'isSingle', value: function isSingle(coordinates) { return !Array.isArray(coordinates[0][0][0]); @@ -17487,7 +18566,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.polygonLayer = noNew; /***/ }, -/* 73 */ +/* 85 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -17522,7 +18601,7 @@ return /******/ (function(modules) { // webpackBootstrap // TODO: Allow _setBufferAttributes to use a custom function passed in to // generate a custom mesh - var _Layer2 = __webpack_require__(32); + var _Layer2 = __webpack_require__(34); var _Layer3 = _interopRequireDefault(_Layer2); @@ -17534,15 +18613,19 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); + var _geoGeo = __webpack_require__(6); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + var _geoLatLon = __webpack_require__(7); var _geoPoint = __webpack_require__(8); - var _enginePickingMaterial = __webpack_require__(70); + var _enginePickingMaterial = __webpack_require__(82); var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); - var _utilBuffer = __webpack_require__(69); + var _utilBuffer = __webpack_require__(81); var _utilBuffer2 = _interopRequireDefault(_utilBuffer); @@ -17558,8 +18641,8 @@ return /******/ (function(modules) { // webpackBootstrap // Custom material override // // TODO: Should this be in the style object? - material: null, - onMesh: null, + polylineMaterial: null, + onPolylineMesh: null, onBufferAttributes: null, // This default style is separate to Util.GeoJSON.defaultStyle style: { @@ -17587,34 +18670,59 @@ return /******/ (function(modules) { // webpackBootstrap _createClass(PolylineLayer, [{ key: '_onAdd', value: function _onAdd(world) { - this._setCoordinates(); + var _this = this; - if (this._options.interactive) { - // Only add to picking mesh if this layer is controlling output - // - // Otherwise, assume another component will eventually add a mesh to - // the picking scene - if (this.isOutput()) { - this._pickingMesh = new _three2['default'].Object3D(); - this.addToPicking(this._pickingMesh); + return new Promise(function (resolve, reject) { + _this._setCoordinates(); + + if (_this._options.interactive) { + // Only add to picking mesh if this layer is controlling output + // + // Otherwise, assume another component will eventually add a mesh to + // the picking scene + if (_this.isOutput()) { + _this._pickingMesh = new _three2['default'].Object3D(); + _this.addToPicking(_this._pickingMesh); + } + + _this._setPickingId(); + _this._addPickingEvents(); } - this._setPickingId(); - this._addPickingEvents(); - } + // Store geometry representation as instances of THREE.BufferAttribute + PolylineLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) { + _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes); + _this._flat = result.flat; - // Store geometry representation as instances of THREE.BufferAttribute - this._setBufferAttributes(); + var attributeLengths = { + positions: 3, + colors: 3 + }; - if (this.isOutput()) { - // Set mesh if not merging elsewhere - this._setMesh(this._bufferAttributes); + if (_this._options.interactive) { + attributeLengths.pickingIds = 1; + } - // Output mesh - this.add(this._mesh); - } + if (_this.isOutput()) { + var style = _this._options.style; - return Promise.resolve(this); + // Set mesh if not merging elsewhere + PolylineLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options).then(function (result) { + // Output mesh + _this.add(result.mesh); + + if (result.pickingMesh) { + _this._pickingMesh.add(result.pickingMesh); + } + }); + } + + result.attributes = null; + result = null; + + resolve(_this); + }); + }); } // Return center of polyline as a LatLon @@ -17647,80 +18755,14 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_addPickingEvents', value: function _addPickingEvents() { - var _this = this; + var _this2 = this; // TODO: Find a way to properly remove this listener on destroy this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) { // Re-emit click event from the layer - _this.emit('click', _this, point2d, point3d, intersects); + _this2.emit('click', _this2, point2d, point3d, intersects); }); } - - // Create and store reference to THREE.BufferAttribute data for this layer - }, { - key: '_setBufferAttributes', - value: function _setBufferAttributes() { - var _this2 = this; - - var attributes; - - // Only use this if you know what you're doing - if (typeof this._options.onBufferAttributes === 'function') { - // TODO: Probably want to pass something less general as arguments, - // though passing the instance will do for now (it's everything) - attributes = this._options.onBufferAttributes(this); - } else { - var height = 0; - - // Convert height into world units - if (this._options.style.lineHeight) { - height = this._world.metresToWorld(this._options.style.lineHeight, this._pointScale); - } - - var colour = new _three2['default'].Color(); - colour.set(this._options.style.lineColor); - - // For each line - attributes = this._projectedCoordinates.map(function (_projectedCoordinates) { - var _vertices = []; - var _colours = []; - - // Connect coordinate with the next to make a pair - // - // LineSegments requires pairs of vertices so repeat the last point if - // there's an odd number of vertices - var nextCoord; - _projectedCoordinates.forEach(function (coordinate, index) { - _colours.push([colour.r, colour.g, colour.b]); - _vertices.push([coordinate.x, height, coordinate.y]); - - nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate; - - _colours.push([colour.r, colour.g, colour.b]); - _vertices.push([nextCoord.x, height, nextCoord.y]); - }); - - var line = { - vertices: _vertices, - colours: _colours, - verticesCount: _vertices.length - }; - - if (_this2._options.interactive && _this2._pickingId) { - // Inject picking ID - line.pickingId = _this2._pickingId; - } - - // Convert line representation to proper attribute arrays - return _this2._toAttributes(line); - }); - } - - this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes); - - // Original attributes are no longer required so free the memory - attributes = null; - } }, { key: 'getBufferAttributes', value: function getBufferAttributes() { @@ -17749,83 +18791,12 @@ return /******/ (function(modules) { // webpackBootstrap this._coordinates = null; this._projectedCoordinates = null; } - - // Create and store mesh from buffer attributes - // - // This is only called if the layer is controlling its own output }, { - key: '_setMesh', - value: function _setMesh(attributes) { - var geometry = new _three2['default'].BufferGeometry(); - - // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3)); - - if (attributes.normals) { - geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3)); - } - - geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3)); - - if (attributes.pickingIds) { - geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1)); - } - - geometry.computeBoundingBox(); - - var style = this._options.style; - var material; - - if (this._options.material && this._options.material instanceof _three2['default'].Material) { - material = this._options.material; - } else { - material = new _three2['default'].LineBasicMaterial({ - vertexColors: _three2['default'].VertexColors, - linewidth: style.lineWidth, - transparent: style.lineTransparent, - opacity: style.lineOpacity, - blending: style.lineBlending - }); - } - - var mesh; - - // Pass mesh through callback, if defined - if (typeof this._options.onMesh === 'function') { - mesh = this._options.onMesh(geometry, material); - } else { - mesh = new _three2['default'].LineSegments(geometry, material); - - if (style.lineRenderOrder !== undefined) { - material.depthWrite = false; - mesh.renderOrder = style.lineRenderOrder; - } - - mesh.castShadow = true; - // mesh.receiveShadow = true; - } - - // TODO: Allow this to be overridden, or copy mesh instead of creating a new - // one just for picking - if (this._options.interactive && this._pickingMesh) { - material = new _enginePickingMaterial2['default'](); - // material.side = THREE.BackSide; - - // Make the line wider / easier to pick - material.linewidth = style.lineWidth + material.linePadding; - - var pickingMesh = new _three2['default'].LineSegments(geometry, material); - this._pickingMesh.add(pickingMesh); - } - - this._mesh = mesh; - } + key: '_setCoordinates', // Convert and project coordinates // // TODO: Calculate bounds - }, { - key: '_setCoordinates', value: function _setCoordinates() { this._bounds = []; this._coordinates = this._convertCoordinates(this._coordinates); @@ -17872,104 +18843,17 @@ return /******/ (function(modules) { // webpackBootstrap _this3._offset.x = -1 * point.x; _this3._offset.y = -1 * point.y; - _this3._pointScale = _this3._world.pointScale(latlon); + _this3._options.pointScale = _this3._world.pointScale(latlon); } return point; }); }); } - - // Transform line representation into attribute arrays that can be used by - // THREE.BufferGeometry - // - // TODO: Can this be simplified? It's messy and huge - }, { - key: '_toAttributes', - value: function _toAttributes(line) { - // Three components per vertex - var vertices = new Float32Array(line.verticesCount * 3); - var colours = new Float32Array(line.verticesCount * 3); - - var pickingIds; - if (line.pickingId) { - // One component per vertex - pickingIds = new Float32Array(line.verticesCount); - } - - var _vertices = line.vertices; - var _colour = line.colours; - - var normals; - var _normals; - if (line.normals) { - normals = new Float32Array(line.verticesCount * 3); - _normals = line.normals; - } - - var _pickingId; - if (pickingIds) { - _pickingId = line.pickingId; - } - - var lastIndex = 0; - - for (var i = 0; i < _vertices.length; i++) { - var ax = _vertices[i][0]; - var ay = _vertices[i][1]; - var az = _vertices[i][2]; - - var nx; - var ny; - var nz; - if (_normals) { - nx = _normals[i][0]; - ny = _normals[i][1]; - nz = _normals[i][2]; - } - - var c1 = _colour[i]; - - vertices[lastIndex * 3 + 0] = ax; - vertices[lastIndex * 3 + 1] = ay; - vertices[lastIndex * 3 + 2] = az; - - if (normals) { - normals[lastIndex * 3 + 0] = nx; - normals[lastIndex * 3 + 1] = ny; - normals[lastIndex * 3 + 2] = nz; - } - - colours[lastIndex * 3 + 0] = c1[0]; - colours[lastIndex * 3 + 1] = c1[1]; - colours[lastIndex * 3 + 2] = c1[2]; - - if (pickingIds) { - pickingIds[lastIndex] = _pickingId; - } - - lastIndex++; - } - - var attributes = { - vertices: vertices, - colours: colours - }; - - if (normals) { - attributes.normals = normals; - } - - if (pickingIds) { - attributes.pickingIds = pickingIds; - } - - return attributes; - } - - // Returns true if the line is flat (has no height) }, { key: 'isFlat', + + // Returns true if the line is flat (has no height) value: function isFlat() { return this._flat; } @@ -17992,6 +18876,175 @@ return /******/ (function(modules) { // webpackBootstrap _get(Object.getPrototypeOf(PolylineLayer.prototype), 'destroy', this).call(this); } }], [{ + key: 'SetBufferAttributes', + value: function SetBufferAttributes(coordinates, options) { + return new Promise(function (resolve) { + var height = 0; + + // Convert height into world units + if (options.style.lineHeight) { + height = _geoGeo2['default'].metresToWorld(options.style.lineHeight, options.pointScale); + } + + var colour = new _three2['default'].Color(); + colour.set(options.style.lineColor); + + var flat = true; + + // For each line + var attributes = coordinates.map(function (_projectedCoordinates) { + var _vertices = []; + var _colours = []; + + // Connect coordinate with the next to make a pair + // + // LineSegments requires pairs of vertices so repeat the last point if + // there's an odd number of vertices + var nextCoord; + _projectedCoordinates.forEach(function (coordinate, index) { + _colours.push([colour.r, colour.g, colour.b]); + _vertices.push([coordinate.x, height, coordinate.y]); + + nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate; + + _colours.push([colour.r, colour.g, colour.b]); + _vertices.push([nextCoord.x, height, nextCoord.y]); + }); + + var line = { + vertices: _vertices, + colours: _colours, + verticesCount: _vertices.length + }; + + if (options.interactive && options.pickingId) { + // Inject picking ID + line.pickingId = options.pickingId; + } + + // Convert line representation to proper attribute arrays + return PolylineLayer.ToAttributes(line); + }); + + resolve({ + attributes: attributes, + flat: flat + }); + }); + } + }, { + key: 'SetMesh', + value: function SetMesh(attributes, attributeLengths, flat, style, options) { + var geometry = new _three2['default'].BufferGeometry(); + + for (var key in attributes) { + geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key])); + } + + geometry.computeBoundingBox(); + + var material; + if (options.polylineMaterial && options.polylineMaterial instanceof _three2['default'].Material) { + material = options.polylineMaterial; + } else { + material = new _three2['default'].LineBasicMaterial({ + vertexColors: _three2['default'].VertexColors, + linewidth: style.lineWidth, + transparent: style.lineTransparent, + opacity: style.lineOpacity, + blending: style.lineBlending + }); + } + + var mesh; + + // Pass mesh through callback, if defined + if (typeof options.onPolylineMesh === 'function') { + mesh = options.onPolylineMesh(geometry, material); + } else { + mesh = new _three2['default'].LineSegments(geometry, material); + + if (style.lineRenderOrder !== undefined) { + material.depthWrite = false; + mesh.renderOrder = style.lineRenderOrder; + } + + mesh.castShadow = true; + // mesh.receiveShadow = true; + } + + if (options.interactive) { + material = new _enginePickingMaterial2['default'](); + // material.side = THREE.BackSide; + + // Make the line wider / easier to pick + material.linewidth = style.lineWidth + material.linePadding; + + var pickingMesh = new _three2['default'].LineSegments(geometry, material); + } + + return Promise.resolve({ + mesh: mesh, + pickingMesh: pickingMesh + }); + } + }, { + key: 'ToAttributes', + value: function ToAttributes(line) { + // Three components per vertex + var vertices = new Float32Array(line.verticesCount * 3); + var colours = new Float32Array(line.verticesCount * 3); + + var pickingIds; + if (line.pickingId) { + // One component per vertex + pickingIds = new Float32Array(line.verticesCount); + } + + var _vertices = line.vertices; + var _colour = line.colours; + + var _pickingId; + if (pickingIds) { + _pickingId = line.pickingId; + } + + var lastIndex = 0; + + for (var i = 0; i < _vertices.length; i++) { + var ax = _vertices[i][0]; + var ay = _vertices[i][1]; + var az = _vertices[i][2]; + + var c1 = _colour[i]; + + vertices[lastIndex * 3 + 0] = ax; + vertices[lastIndex * 3 + 1] = ay; + vertices[lastIndex * 3 + 2] = az; + + colours[lastIndex * 3 + 0] = c1[0]; + colours[lastIndex * 3 + 1] = c1[1]; + colours[lastIndex * 3 + 2] = c1[2]; + + if (pickingIds) { + pickingIds[lastIndex] = _pickingId; + } + + lastIndex++; + } + + var attributes = { + positions: vertices, + colors: colours + }; + + if (pickingIds) { + attributes.pickingIds = pickingIds; + } + + return attributes; + } + }, { key: 'isSingle', value: function isSingle(coordinates) { return !Array.isArray(coordinates[0][0]); @@ -18010,7 +19063,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.polylineLayer = noNew; /***/ }, -/* 74 */ +/* 86 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -18051,7 +19104,7 @@ return /******/ (function(modules) { // webpackBootstrap // How much control should this layer support? Perhaps a different or custom // layer would be better suited for animation, for example. - var _Layer2 = __webpack_require__(32); + var _Layer2 = __webpack_require__(34); var _Layer3 = _interopRequireDefault(_Layer2); @@ -18063,18 +19116,26 @@ return /******/ (function(modules) { // webpackBootstrap var _three2 = _interopRequireDefault(_three); + var _geoGeo = __webpack_require__(6); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + var _geoLatLon = __webpack_require__(7); var _geoPoint = __webpack_require__(8); - var _enginePickingMaterial = __webpack_require__(70); + var _enginePickingMaterial = __webpack_require__(82); var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); - var _utilBuffer = __webpack_require__(69); + var _utilBuffer = __webpack_require__(81); var _utilBuffer2 = _interopRequireDefault(_utilBuffer); + var _PolygonLayer = __webpack_require__(84); + + var _PolygonLayer2 = _interopRequireDefault(_PolygonLayer); + var PointLayer = (function (_Layer) { _inherits(PointLayer, _Layer); @@ -18085,12 +19146,12 @@ return /******/ (function(modules) { // webpackBootstrap output: true, interactive: false, // THREE.Geometry or THREE.BufferGeometry to use for point output - geometry: null, + pointGeometry: null, // Custom material override // // TODO: Should this be in the style object? - material: null, - onMesh: null, + pointMaterial: null, + onPointMesh: null, // This default style is separate to Util.GeoJSON.defaultStyle style: { pointColor: '#ff0000' @@ -18106,44 +19167,67 @@ return /******/ (function(modules) { // webpackBootstrap // single point in the array) this._coordinates = PointLayer.isSingle(coordinates) ? [coordinates] : coordinates; - // Point features are always flat (for now at least) - // - // This won't always be the case once custom point objects / meshes are - // added - this._flat = true; + this._flat = false; } _createClass(PointLayer, [{ key: '_onAdd', value: function _onAdd(world) { - this._setCoordinates(); + var _this = this; - if (this._options.interactive) { - // Only add to picking mesh if this layer is controlling output - // - // Otherwise, assume another component will eventually add a mesh to - // the picking scene - if (this.isOutput()) { - this._pickingMesh = new _three2['default'].Object3D(); - this.addToPicking(this._pickingMesh); + return new Promise(function (resolve, reject) { + _this._setCoordinates(); + + if (_this._options.interactive) { + // Only add to picking mesh if this layer is controlling output + // + // Otherwise, assume another component will eventually add a mesh to + // the picking scene + if (_this.isOutput()) { + _this._pickingMesh = new _three2['default'].Object3D(); + _this.addToPicking(_this._pickingMesh); + } + + _this._setPickingId(); + _this._addPickingEvents(); } - this._setPickingId(); - this._addPickingEvents(); - } + // Store geometry representation as instances of THREE.BufferAttribute + PointLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) { + _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes); + _this._flat = result.flat; - // Store geometry representation as instances of THREE.BufferAttribute - this._setBufferAttributes(); + var attributeLengths = { + positions: 3, + normals: 3, + colors: 3 + }; - if (this.isOutput()) { - // Set mesh if not merging elsewhere - this._setMesh(this._bufferAttributes); + if (_this._options.interactive) { + attributeLengths.pickingIds = 1; + } - // Output mesh - this.add(this._mesh); - } + if (_this.isOutput()) { + var style = _this._options.style; - return Promise.resolve(this); + // Set mesh if not merging elsewhere + // TODO: Dedupe with PolygonLayer as they are identical + PointLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) { + // Output mesh + _this.add(result.mesh); + + if (result.pickingMesh) { + _this._pickingMesh.add(result.pickingMesh); + } + }); + } + + result.attributes = null; + result = null; + + resolve(_this); + })['catch'](reject); + }); } // Return center of point as a LatLon @@ -18175,101 +19259,14 @@ return /******/ (function(modules) { // webpackBootstrap }, { key: '_addPickingEvents', value: function _addPickingEvents() { - var _this = this; + var _this2 = this; // TODO: Find a way to properly remove this listener on destroy this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) { // Re-emit click event from the layer - _this.emit('click', _this, point2d, point3d, intersects); + _this2.emit('click', _this2, point2d, point3d, intersects); }); } - - // Create and store reference to THREE.BufferAttribute data for this layer - }, { - key: '_setBufferAttributes', - value: function _setBufferAttributes() { - var _this2 = this; - - var height = 0; - - // Convert height into world units - if (this._options.style.pointHeight) { - height = this._world.metresToWorld(this._options.style.pointHeight, this._pointScale); - } - - var colour = new _three2['default'].Color(); - colour.set(this._options.style.pointColor); - - var geometry; - - // Use default geometry if none has been provided or the provided geometry - // isn't valid - if (!this._options.geometry || !this._options.geometry instanceof _three2['default'].Geometry || !this._options.geometry instanceof _three2['default'].BufferGeometry) { - // Debug geometry for points is a thin bar - // - // TODO: Allow point geometry to be customised / overridden - var geometryWidth = this._world.metresToWorld(25, this._pointScale); - var geometryHeight = this._world.metresToWorld(200, this._pointScale); - var _geometry = new _three2['default'].BoxGeometry(geometryWidth, geometryHeight, geometryWidth); - - // Shift geometry up so it sits on the ground - _geometry.translate(0, geometryHeight * 0.5, 0); - - // Pull attributes out of debug geometry - geometry = new _three2['default'].BufferGeometry().fromGeometry(_geometry); - } else { - if (this._options.geometry instanceof _three2['default'].BufferGeometry) { - geometry = this._options.geometry; - } else { - geometry = new _three2['default'].BufferGeometry().fromGeometry(this._options.geometry); - } - } - - // For each point - var attributes = this._projectedCoordinates.map(function (coordinate) { - var _vertices = []; - var _normals = []; - var _colours = []; - - var _geometry = geometry.clone(); - - _geometry.translate(coordinate.x, height, coordinate.y); - - var _vertices = _geometry.attributes.position.clone().array; - var _normals = _geometry.attributes.normal.clone().array; - var _colours = _geometry.attributes.color.clone().array; - - for (var i = 0; i < _colours.length; i += 3) { - _colours[i] = colour.r; - _colours[i + 1] = colour.g; - _colours[i + 2] = colour.b; - } - - var _point = { - vertices: _vertices, - normals: _normals, - colours: _colours - }; - - if (_this2._options.interactive && _this2._pickingId) { - // Inject picking ID - // point.pickingId = this._pickingId; - _point.pickingIds = new Float32Array(_vertices.length / 3); - for (var i = 0; i < _point.pickingIds.length; i++) { - _point.pickingIds[i] = _this2._pickingId; - } - } - - // Convert point representation to proper attribute arrays - // return this._toAttributes(_point); - return _point; - }); - - this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes); - - // Original attributes are no longer required so free the memory - attributes = null; - } }, { key: 'getBufferAttributes', value: function getBufferAttributes() { @@ -18298,74 +19295,12 @@ return /******/ (function(modules) { // webpackBootstrap this._coordinates = null; this._projectedCoordinates = null; } - - // Create and store mesh from buffer attributes - // - // This is only called if the layer is controlling its own output }, { - key: '_setMesh', - value: function _setMesh(attributes) { - var geometry = new _three2['default'].BufferGeometry(); - - // itemSize = 3 because there are 3 values (components) per vertex - geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3)); - geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3)); - geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3)); - - if (attributes.pickingIds) { - geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1)); - } - - geometry.computeBoundingBox(); - - var material; - - if (this._options.material && this._options.material instanceof _three2['default'].Material) { - material = this._options.material; - } else if (!this._world._environment._skybox) { - material = new _three2['default'].MeshBasicMaterial({ - vertexColors: _three2['default'].VertexColors - // side: THREE.BackSide - }); - } else { - material = new _three2['default'].MeshStandardMaterial({ - vertexColors: _three2['default'].VertexColors - // side: THREE.BackSide - }); - material.roughness = 1; - material.metalness = 0.1; - material.envMapIntensity = 3; - material.envMap = this._world._environment._skybox.getRenderTarget(); - } - - var mesh; - - // Pass mesh through callback, if defined - if (typeof this._options.onMesh === 'function') { - mesh = this._options.onMesh(geometry, material); - } else { - mesh = new _three2['default'].Mesh(geometry, material); - - mesh.castShadow = true; - // mesh.receiveShadow = true; - } - - if (this._options.interactive && this._pickingMesh) { - material = new _enginePickingMaterial2['default'](); - // material.side = THREE.BackSide; - - var pickingMesh = new _three2['default'].Mesh(geometry, material); - this._pickingMesh.add(pickingMesh); - } - - this._mesh = mesh; - } + key: '_setCoordinates', // Convert and project coordinates // // TODO: Calculate bounds - }, { - key: '_setCoordinates', value: function _setCoordinates() { this._bounds = []; this._coordinates = this._convertCoordinates(this._coordinates); @@ -18409,74 +19344,13 @@ return /******/ (function(modules) { // webpackBootstrap _this3._offset.x = -1 * _point.x; _this3._offset.y = -1 * _point.y; - _this3._pointScale = _this3._world.pointScale(latlon); + _this3._options.pointScale = _this3._world.pointScale(latlon); } return _point; }); } - // Transform line representation into attribute arrays that can be used by - // THREE.BufferGeometry - // - // TODO: Can this be simplified? It's messy and huge - }, { - key: '_toAttributes', - value: function _toAttributes(line) { - // Three components per vertex - var vertices = new Float32Array(line.verticesCount * 3); - var colours = new Float32Array(line.verticesCount * 3); - - var pickingIds; - if (line.pickingId) { - // One component per vertex - pickingIds = new Float32Array(line.verticesCount); - } - - var _vertices = line.vertices; - var _colour = line.colours; - - var _pickingId; - if (pickingIds) { - _pickingId = line.pickingId; - } - - var lastIndex = 0; - - for (var i = 0; i < _vertices.length; i++) { - var ax = _vertices[i][0]; - var ay = _vertices[i][1]; - var az = _vertices[i][2]; - - var c1 = _colour[i]; - - vertices[lastIndex * 3 + 0] = ax; - vertices[lastIndex * 3 + 1] = ay; - vertices[lastIndex * 3 + 2] = az; - - colours[lastIndex * 3 + 0] = c1[0]; - colours[lastIndex * 3 + 1] = c1[1]; - colours[lastIndex * 3 + 2] = c1[2]; - - if (pickingIds) { - pickingIds[lastIndex] = _pickingId; - } - - lastIndex++; - } - - var attributes = { - vertices: vertices, - colours: colours - }; - - if (pickingIds) { - attributes.pickingIds = pickingIds; - } - - return attributes; - } - // Returns true if the line is flat (has no height) }, { key: 'isFlat', @@ -18502,6 +19376,146 @@ return /******/ (function(modules) { // webpackBootstrap _get(Object.getPrototypeOf(PointLayer.prototype), 'destroy', this).call(this); } }], [{ + key: 'SetBufferAttributes', + value: function SetBufferAttributes(coordinates, options) { + return new Promise(function (resolve) { + var height = 0; + + // Convert height into world units + if (options.style.pointHeight) { + height = _geoGeo2['default'].metresToWorld(options.style.pointHeight, options.pointScale); + } + + var colour = new _three2['default'].Color(); + colour.set(options.style.pointColor); + + // Use default geometry if none has been provided or the provided geometry + // isn't valid + if (!options.pointGeometry || !options.pointGeometry instanceof _three2['default'].Geometry || !options.pointGeometry instanceof _three2['default'].BufferGeometry) { + // Debug geometry for points is a thin bar + // + // TODO: Allow point geometry to be customised / overridden + var geometryWidth = _geoGeo2['default'].metresToWorld(25, options.pointScale); + var geometryHeight = _geoGeo2['default'].metresToWorld(200, options.pointScale); + var _geometry = new _three2['default'].BoxGeometry(geometryWidth, geometryHeight, geometryWidth); + + // Shift geometry up so it sits on the ground + _geometry.translate(0, geometryHeight * 0.5, 0); + + // Pull attributes out of debug geometry + geometry = new _three2['default'].BufferGeometry().fromGeometry(_geometry); + } else { + if (options.geometry instanceof _three2['default'].BufferGeometry) { + geometry = options.pointGeometry; + } else { + geometry = new _three2['default'].BufferGeometry().fromGeometry(options.pointGeometry); + } + } + + var attributes = coordinates.map(function (coordinate) { + var _vertices = []; + var _normals = []; + var _colours = []; + + var _geometry = geometry.clone(); + _geometry.translate(coordinate.x, height, coordinate.y); + + var _vertices = _geometry.attributes.position.clone().array; + var _normals = _geometry.attributes.normal.clone().array; + var _colours = _geometry.attributes.color.clone().array; + + for (var i = 0; i < _colours.length; i += 3) { + _colours[i] = colour.r; + _colours[i + 1] = colour.g; + _colours[i + 2] = colour.b; + } + + var _point = { + positions: _vertices, + normals: _normals, + colors: _colours + }; + + if (options.interactive && options.pickingId) { + // Inject picking ID + _point.pickingId = options.pickingId; + } + + return _point; + }); + + resolve({ + attributes: attributes, + flat: false + }); + }); + } + }, { + key: 'SetMesh', + value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) { + var geometry = new _three2['default'].BufferGeometry(); + + for (var key in attributes) { + geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key])); + } + + geometry.computeBoundingBox(); + + var material; + if (options.pointMaterial && options.pointMaterial instanceof _three2['default'].Material) { + material = options.pointMaterial; + } else if (!skybox) { + material = new _three2['default'].MeshPhongMaterial({ + vertexColors: _three2['default'].VertexColors, + // side: THREE.BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + } else { + material = new _three2['default'].MeshStandardMaterial({ + vertexColors: _three2['default'].VertexColors, + // side: THREE.BackSide, + transparent: style.transparent, + opacity: style.opacity, + blending: style.blending + }); + material.roughness = 1; + material.metalness = 0.1; + material.envMapIntensity = 3; + material.envMap = skybox.getRenderTarget(); + } + + var mesh; + + // Pass mesh through callback, if defined + if (typeof options.onPolygonMesh === 'function') { + mesh = options.onPolygonMesh(geometry, material); + } else { + mesh = new _three2['default'].Mesh(geometry, material); + + mesh.castShadow = true; + mesh.receiveShadow = true; + } + + if (flat) { + material.depthWrite = false; + mesh.renderOrder = 4; + } + + if (options.interactive) { + material = new _enginePickingMaterial2['default'](); + material.side = _three2['default'].BackSide; + + var pickingMesh = new _three2['default'].Mesh(geometry, material); + } + + return Promise.resolve({ + mesh: mesh, + pickingMesh: pickingMesh + }); + } + }, { key: 'isSingle', value: function isSingle(coordinates) { return !Array.isArray(coordinates[0]); @@ -18520,7 +19534,1277 @@ return /******/ (function(modules) { // webpackBootstrap exports.pointLayer = noNew; /***/ }, -/* 75 */ +/* 87 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })(); + + 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; }; })(); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _Layer2 = __webpack_require__(34); + + var _Layer3 = _interopRequireDefault(_Layer2); + + var _lodashAssign = __webpack_require__(3); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var _reqwest = __webpack_require__(73); + + var _reqwest2 = _interopRequireDefault(_reqwest); + + var _utilGeoJSON = __webpack_require__(75); + + var _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON); + + var _utilWorker = __webpack_require__(46); + + var _utilWorker2 = _interopRequireDefault(_utilWorker); + + var _utilBuffer = __webpack_require__(81); + + var _utilBuffer2 = _interopRequireDefault(_utilBuffer); + + var _utilStringify = __webpack_require__(88); + + var _utilStringify2 = _interopRequireDefault(_utilStringify); + + var _geometryPolygonLayer = __webpack_require__(84); + + var _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer); + + var _geometryPolylineLayer = __webpack_require__(85); + + var _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer); + + var _geometryPointLayer = __webpack_require__(86); + + var _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer); + + var _geoLatLon = __webpack_require__(7); + + var _geoPoint = __webpack_require__(8); + + var _geoGeo = __webpack_require__(6); + + var _geoGeo2 = _interopRequireDefault(_geoGeo); + + var _enginePickingMaterial = __webpack_require__(82); + + var _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial); + + // TODO: Allow filter method to be run inside a worker to improve performance + // TODO: Allow onEachFeature method to be run inside a worker to improve performance + + var GeoJSONWorkerLayer = (function (_Layer) { + _inherits(GeoJSONWorkerLayer, _Layer); + + function GeoJSONWorkerLayer(geojson, options) { + _classCallCheck(this, GeoJSONWorkerLayer); + + var defaults = { + topojson: false, + style: _utilGeoJSON2['default'].defaultStyle, + onEachFeature: null, + onEachFeatureWorker: null, + onAddAttributes: null, + interactive: false, + pointGeometry: null, + onClick: null, + headers: {} + }; + + var _options = (0, _lodashAssign2['default'])({}, defaults, options); + + if (typeof options.style === 'object') { + _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style); + } + + _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'constructor', this).call(this, _options); + + this._aborted = false; + this._geojson = geojson; + } + + _createClass(GeoJSONWorkerLayer, [{ + key: '_onAdd', + value: function _onAdd(world) { + if (this._options.interactive) { + // Worker layer always controls output to add a picking mesh + this._pickingMesh = new THREE.Object3D(); + } + + // Process GeoJSON + return this._process(this._geojson); + } + + // Use workers to request and process GeoJSON, returning data structure + // containing geometry and any supplementary data for output + }, { + key: '_process', + value: function _process(_geojson) { + var _this = this; + + return new Promise(function (resolve, reject) { + var style = _this._options.style; + + // TODO: Convert to buffer and use transferrable objects + if (typeof _this._options.style === 'function') { + style = _utilStringify2['default'].functionToString(_this._options.style); + } + + var pointGeometry = _this._options.pointGeometry; + + // TODO: Convert to buffer and use transferrable objects + if (typeof _this._options.pointGeometry === 'function') { + pointGeometry = _utilStringify2['default'].functionToString(_this._options.pointGeometry); + } + + var geojson = _geojson; + var transferrables = []; + + if (typeof geojson !== 'string') { + _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(geojson)); + transferrables.push(geojson.buffer); + _this._execWorker(geojson, _this._options.topojson, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () { + resolve(); + })['catch'](reject); + } else if (typeof _this._options.filter === 'function' || typeof _this._options.onEachFeature === 'function') { + GeoJSONWorkerLayer.RequestGeoJSON(geojson).then(function (res) { + // if (this._aborted) { + // resolve(); + // return; + // } + + var fc = _utilGeoJSON2['default'].collectFeatures(res, _this._options.topojson); + var features = fc.features; + + // Run filter, if provided + if (_this._options.filter) { + fc.features = features.filter(_this._options.filter); + } + + if (_this._options.onEachFeature) { + var feature; + for (var i = 0; i < features.length; i++) { + feature = features[i]; + _this._options.onEachFeature(feature); + }; + } + + _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(fc)); + transferrables.push(geojson.buffer); + + _this._execWorker(geojson, false, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () { + resolve(); + })['catch'](reject); + }); + } else { + _this._execWorker(geojson, _this._options.topojson, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () { + resolve(); + })['catch'](reject); + } + }); + } + }, { + key: '_execWorker', + value: function _execWorker(geojson, topojson, headers, originPoint, style, interactive, pointGeometry, transferrables) { + var _this2 = this; + + return new Promise(function (resolve, reject) { + console.time('Worker round trip'); + + _utilWorker2['default'].exec('GeoJSONWorkerLayer.Process', [geojson, topojson, headers, originPoint, style, interactive, pointGeometry], transferrables).then(function (results) { + console.timeEnd('Worker round trip'); + + // if (this._aborted) { + // resolve(); + // return; + // } + + var processPromises = []; + + if (results.polygons) { + processPromises.push(_this2._processPolygonResults(results.polygons)); + } + + if (results.polylines) { + processPromises.push(_this2._processPolylineResults(results.polylines)); + } + + if (results.points) { + processPromises.push(_this2._processPointResults(results.points)); + } + + if (processPromises.length > 0) { + Promise.all(processPromises).then(function () { + resolve(); + })['catch'](reject); + } else { + resolve(); + } + }); + }); + } + + // TODO: Dedupe with polyline method + }, { + key: '_processPolygonResults', + value: function _processPolygonResults(results) { + var _this3 = this; + + return new Promise(function (resolve, reject) { + var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions); + var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals); + var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors); + var splitTops = _utilBuffer2['default'].splitFloat32Array(results.attributes.tops); + + var splitOutlinePositions; + var splitOutlineColors; + + if (results.outlineAttributes) { + splitOutlinePositions = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.positions); + splitOutlineColors = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.colors); + } + + var splitProperties; + if (results.properties) { + splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties); + } + + var flats = results.flats; + + var objects = []; + var outlineObjects = []; + + var obj; + var pickingId; + var pickingIds; + var properties; + + var polygonAttributeLengths = { + positions: 3, + normals: 3, + colors: 3, + tops: 1 + }; + + var polygonOutlineAttributeLengths = { + positions: 3, + colors: 3 + }; + + for (var i = 0; i < splitPositions.length; i++) { + if (splitProperties && splitProperties[i]) { + properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i])); + } else { + properties = {}; + } + + // WORKERS: obj.attributes should actually an array of polygons for + // the feature, though the current logic isn't aware of that + obj = { + attributes: [{ + positions: splitPositions[i], + normals: splitNormals[i], + colors: splitColors[i], + tops: splitTops[i] + }], + properties: properties, + flat: flats[i] + }; + + // WORKERS: If interactive, generate unique ID for each feature, create + // the buffer attributes and set up event listeners + if (_this3._options.interactive) { + pickingId = _this3.getPickingId(); + + pickingIds = new Float32Array(splitPositions[i].length / 3); + pickingIds.fill(pickingId); + + obj.attributes[0].pickingIds = pickingIds; + + polygonAttributeLengths.pickingIds = 1; + + _this3._addPicking(pickingId, properties); + } + + // TODO: Make this specific to polygon attributes + if (typeof _this3._options.onAddAttributes === 'function') { + var customAttributes = _this3._options.onAddAttributes(obj.attributes[0], properties); + var customAttribute; + for (var key in customAttributes) { + customAttribute = customAttributes[key]; + obj.attributes[0][key] = customAttribute.value; + polygonAttributeLengths[key] = customAttribute.length; + } + } + + objects.push(obj); + } + + for (var i = 0; i < splitOutlinePositions.length; i++) { + obj = { + attributes: [{ + positions: splitOutlinePositions[i], + colors: splitOutlineColors[i] + }], + flat: true + }; + + outlineObjects.push(obj); + } + + var polygonAttributes = []; + var polygonOutlineAttributes = []; + + var polygonFlat = true; + + for (var i = 0; i < objects.length; i++) { + obj = objects[i]; + + // TODO: Work out why obj.flat is rarely set to something other than + // true or false. Potentially undefined. + if (polygonFlat && obj.flat === false) { + polygonFlat = false; + } + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + polygonAttributes.push(bufferAttributes); + }; + + for (var i = 0; i < outlineObjects.length; i++) { + obj = outlineObjects[i]; + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + polygonOutlineAttributes.push(bufferAttributes); + }; + + var outputPromises = []; + + var style; + + if (polygonAttributes.length > 0) { + var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes); + + // TODO: Make this work when style is a function per feature + style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + outputPromises.push(_this3._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat)); + } + + if (polygonOutlineAttributes.length > 0) { + var mergedPolygonOutlineAttributes = _utilBuffer2['default'].mergeAttributes(polygonOutlineAttributes); + + style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + if (style.outlineRenderOrder !== undefined) { + style.lineRenderOrder = style.outlineRenderOrder; + } else { + style.lineRenderOrder = style.renderOrder ? style.renderOrder + 1 : 4; + } + + if (style.outlineWidth) { + style.lineWidth = style.outlineWidth; + } + + outputPromises.push(_this3._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true)); + } + + Promise.all(outputPromises).then(function (results) { + var _results = _slicedToArray(results, 2); + + var polygonResult = _results[0]; + var outlineResult = _results[1]; + + if (polygonResult) { + _this3._polygonMesh = polygonResult.mesh; + _this3.add(_this3._polygonMesh); + + if (polygonResult.pickingMesh) { + _this3._pickingMesh.add(polygonResult.pickingMesh); + } + } + + if (outlineResult) { + _this3.add(outlineResult.mesh); + } + + resolve(); + })['catch'](reject); + }); + } + + // TODO: Dedupe with polygon method + }, { + key: '_processPolylineResults', + value: function _processPolylineResults(results) { + var _this4 = this; + + return new Promise(function (resolve, reject) { + var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions); + var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors); + + var splitProperties; + if (results.properties) { + splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties); + } + + var flats = results.flats; + + var objects = []; + var obj; + var pickingId; + var pickingIds; + var properties; + + var polylineAttributeLengths = { + positions: 3, + colors: 3 + }; + + for (var i = 0; i < splitPositions.length; i++) { + if (splitProperties && splitProperties[i]) { + properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i])); + } else { + properties = {}; + } + + // WORKERS: obj.attributes should actually an array of polygons for + // the feature, though the current logic isn't aware of that + obj = { + attributes: [{ + positions: splitPositions[i], + colors: splitColors[i] + }], + properties: properties, + flat: flats[i] + }; + + // WORKERS: If interactive, generate unique ID for each feature, create + // the buffer attributes and set up event listeners + if (_this4._options.interactive) { + pickingId = _this4.getPickingId(); + + pickingIds = new Float32Array(splitPositions[i].length / 3); + pickingIds.fill(pickingId); + + obj.attributes[0].pickingIds = pickingIds; + + polylineAttributeLengths.pickingIds = 1; + + _this4._addPicking(pickingId, properties); + } + + // TODO: Make this specific to polyline attributes + if (typeof _this4._options.onAddAttributes === 'function') { + var customAttributes = _this4._options.onAddAttributes(obj.attributes[0], properties); + var customAttribute; + for (var key in customAttributes) { + customAttribute = customAttributes[key]; + obj.attributes[0][key] = customAttribute.value; + polylineAttributeLengths[key] = customAttribute.length; + } + } + + objects.push(obj); + } + + var polylineAttributes = []; + + var polylineFlat = true; + + for (var i = 0; i < objects.length; i++) { + obj = objects[i]; + + if (polylineFlat && !obj.flat) { + polylineFlat = false; + } + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + polylineAttributes.push(bufferAttributes); + }; + + if (polylineAttributes.length > 0) { + var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes); + + // TODO: Make this work when style is a function per feature + var style = typeof _this4._options.style === 'function' ? _this4._options.style(objects[0]) : _this4._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this4._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then(function (result) { + _this4._polylineMesh = result.mesh; + _this4.add(_this4._polylineMesh); + + if (result.pickingMesh) { + _this4._pickingMesh.add(result.pickingMesh); + } + + resolve(); + })['catch'](reject); + } else { + resolve(); + } + }); + } + }, { + key: '_processPointResults', + value: function _processPointResults(results) { + var _this5 = this; + + return new Promise(function (resolve, reject) { + var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions); + var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals); + var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors); + + var splitProperties; + if (results.properties) { + splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties); + } + + var flats = results.flats; + + var objects = []; + var obj; + var pickingId; + var pickingIds; + var properties; + + var pointAttributeLengths = { + positions: 3, + normals: 3, + colors: 3 + }; + + for (var i = 0; i < splitPositions.length; i++) { + if (splitProperties && splitProperties[i]) { + properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i])); + } else { + properties = {}; + } + + // WORKERS: obj.attributes should actually an array of polygons for + // the feature, though the current logic isn't aware of that + obj = { + attributes: [{ + positions: splitPositions[i], + normals: splitNormals[i], + colors: splitColors[i] + }], + properties: properties, + flat: flats[i] + }; + + // WORKERS: If interactive, generate unique ID for each feature, create + // the buffer attributes and set up event listeners + if (_this5._options.interactive) { + pickingId = _this5.getPickingId(); + + pickingIds = new Float32Array(splitPositions[i].length / 3); + pickingIds.fill(pickingId); + + obj.attributes[0].pickingIds = pickingIds; + + pointAttributeLengths.pickingIds = 1; + + _this5._addPicking(pickingId, properties); + } + + // TODO: Make this specific to polygon attributes + if (typeof _this5._options.onAddAttributes === 'function') { + var customAttributes = _this5._options.onAddAttributes(obj.attributes[0], properties); + var customAttribute; + for (var key in customAttributes) { + customAttribute = customAttributes[key]; + obj.attributes[0][key] = customAttribute.value; + pointAttributeLengths[key] = customAttribute.length; + } + } + + objects.push(obj); + } + + var pointAttributes = []; + + var pointFlat = true; + + for (var i = 0; i < objects.length; i++) { + obj = objects[i]; + + if (pointFlat && !obj.flat) { + pointFlat = false; + } + + var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes); + pointAttributes.push(bufferAttributes); + }; + + if (pointAttributes.length > 0) { + var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes); + + // TODO: Make this work when style is a function per feature + var style = typeof _this5._options.style === 'function' ? _this5._options.style(objects[0]) : _this5._options.style; + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style); + + _this5._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then(function (result) { + _this5._pointMesh = result.mesh; + _this5.add(_this5._pointMesh); + + if (result.pickingMesh) { + _this5._pickingMesh.add(result.pickingMesh); + } + + resolve(); + })['catch'](reject); + } else { + resolve(); + } + }); + } + + // TODO: At some point this needs to return all the features to the main thread + // so it can generate meshes and output to the scene, as well as perhaps creating + // individual layers / components for each feature to track things like picking + // and properties + // + // TODO: Find a way so the origin point isn't needed to be passed in as it + // feels a bit messy and against the idea of a static Geo class + // + // TODO: Support passing custom geometry for point layers + }, { + key: '_setPolygonMesh', + + // Create and store mesh from buffer attributes + // + // Could make this an abstract method for each geometry layer + value: function _setPolygonMesh(attributes, attributeLengths, style, flat) { + if (!this._world) { + return Promise.reject(); + } + + return _geometryPolygonLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox); + } + }, { + key: '_setPolylineMesh', + value: function _setPolylineMesh(attributes, attributeLengths, style, flat) { + if (!this._world) { + return Promise.reject(); + } + + return _geometryPolylineLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options); + } + }, { + key: '_setPointMesh', + value: function _setPointMesh(attributes, attributeLengths, style, flat) { + if (!this._world) { + return Promise.reject(); + } + + return _geometryPointLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox); + } + + // Set up and re-emit interaction events + }, { + key: '_addPicking', + value: function _addPicking(pickingId, properties) { + var _this6 = this; + + this._world.on('pick-click-' + pickingId, function (pickingId, point2d, point3d, intersects) { + _this6._world.emit('click', _this6, properties, point2d, point3d); + }); + + this._world.on('pick-hover-' + pickingId, function (pickingId, point2d, point3d, intersects) { + _this6._world.emit('hover', _this6, properties, point2d, point3d); + }); + } + + // TODO: Finish cleanup + }, { + key: 'destroy', + value: function destroy() { + // Run common destruction logic from parent + _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'destroy', this).call(this); + } + }], [{ + key: 'Process', + value: function Process(geojson, topojson, headers, originPoint, _style, _properties, _pointGeometry) { + return new Promise(function (resolve, reject) { + GeoJSONWorkerLayer.ProcessGeoJSON(geojson, headers).then(function (res) { + // Collects features into a single FeatureCollection + // + // Also converts TopoJSON to GeoJSON if instructed + var geojson = _utilGeoJSON2['default'].collectFeatures(res, topojson); + + // TODO: Check that GeoJSON is valid / usable + + var features = geojson.features; + + // TODO: Run filter, if provided (must be static) + + var pointScale; + var polygons = []; + var polylines = []; + var points = []; + + // Deserialise style function if provided + if (typeof _style === 'string') { + _style = _utilStringify2['default'].stringToFunction(_style); + } + + // Assume that a style won't be set per feature + var style = _style; + + var pointGeometry; + // Deserialise pointGeometry function if provided + if (typeof _pointGeometry === 'string') { + pointGeometry = _utilStringify2['default'].stringToFunction(_pointGeometry); + } + + var feature; + for (var i = 0; i < features.length; i++) { + feature = features[i]; + + var geometry = feature.geometry; + var coordinates = geometry.coordinates ? geometry.coordinates : null; + + if (!coordinates || !geometry) { + return; + } + + // Get per-feature style object, if provided + if (typeof _style === 'function') { + style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _style(feature)); + // console.log(feature, style); + } + + if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') { + coordinates = _geometryPolygonLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates; + + var converted = coordinates.map(function (_coordinates) { + return _coordinates.map(function (ring) { + return ring.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + }); + }); + + var point; + var projected = converted.map(function (_coordinates) { + return _coordinates.map(function (ring) { + return ring.map(function (latlon) { + point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint); + + if (!pointScale) { + pointScale = _geoGeo2['default'].pointScale(latlon); + } + + return point; + }); + }); + }); + + var polygon = { + projected: projected, + options: { + pointScale: pointScale, + style: style + } + }; + + if (_properties) { + polygon.properties = feature.properties; + } + + polygons.push(polygon); + } + + if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') { + coordinates = _geometryPolylineLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates; + + var converted = coordinates.map(function (_coordinates) { + return _coordinates.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + }); + + var point; + var projected = converted.map(function (_coordinates) { + return _coordinates.map(function (latlon) { + point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint); + + if (!pointScale) { + pointScale = _geoGeo2['default'].pointScale(latlon); + } + + return point; + }); + }); + + var polyline = { + projected: projected, + options: { + pointScale: pointScale, + style: style + } + }; + + if (_properties) { + polyline.properties = feature.properties; + } + + polylines.push(polyline); + } + + if (geometry.type === 'Point' || geometry.type === 'MultiPoint') { + coordinates = _geometryPointLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates; + + var converted = coordinates.map(function (coordinate) { + return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]); + }); + + var point; + var projected = converted.map(function (latlon) { + point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint); + + if (!pointScale) { + pointScale = _geoGeo2['default'].pointScale(latlon); + } + + return point; + }); + + var point = { + projected: projected, + options: { + pointGeometry: pointGeometry(feature), + pointScale: pointScale, + style: style + } + }; + + if (_properties) { + point.properties = feature.properties; + } + + points.push(point); + } + }; + + var polygonBufferPromises = []; + var polylineBufferPromises = []; + var pointBufferPromises = []; + + var polygon; + for (var i = 0; i < polygons.length; i++) { + polygon = polygons[i]; + polygonBufferPromises.push(_geometryPolygonLayer2['default'].SetBufferAttributes(polygon.projected, polygon.options)); + }; + + var polyline; + for (var i = 0; i < polylines.length; i++) { + polyline = polylines[i]; + polylineBufferPromises.push(_geometryPolylineLayer2['default'].SetBufferAttributes(polyline.projected, polyline.options)); + }; + + var point; + for (var i = 0; i < points.length; i++) { + point = points[i]; + pointBufferPromises.push(_geometryPointLayer2['default'].SetBufferAttributes(point.projected, point.options)); + }; + + var data = {}; + var transferrables = []; + + // TODO: Make this work with polylines too + // TODO: Make this so it's not a nest of promises + GeoJSONWorkerLayer.ProcessPolygons(polygonBufferPromises, polygons, _properties).then(function (result) { + data.polygons = result.data; + transferrables = transferrables.concat(result.transferrables); + + GeoJSONWorkerLayer.ProcessPolylines(polylineBufferPromises, polylines, _properties).then(function (result) { + data.polylines = result.data; + transferrables = transferrables.concat(result.transferrables); + + GeoJSONWorkerLayer.ProcessPoints(pointBufferPromises, points, _properties).then(function (result) { + data.points = result.data; + transferrables = transferrables.concat(result.transferrables); + + resolve({ + data: data, + transferrables: transferrables + }); + }); + }); + }); + }); + }); + } + }, { + key: 'ProcessPolygons', + value: function ProcessPolygons(polygonPromises, polygons, _properties) { + return new Promise(function (resolve, reject) { + Promise.all(polygonPromises).then(function (results) { + var transferrables = []; + + var positions = []; + var normals = []; + var colors = []; + var tops = []; + + var outlinePositions = []; + var outlineColors = []; + + var properties = []; + + var flats = []; + var polygon; + + var result; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + polygon = polygons[i]; + + // WORKERS: Making this a typed array will speed up transfer time + // As things stand this adds on a few milliseconds + flats.push(result.flat); + + // WORKERS: result.attributes is actually an array of polygons for each + // feature, though the current logic isn't keeping these all together + + var attributes; + for (var j = 0; j < result.attributes.length; j++) { + attributes = result.attributes[j]; + + positions.push(attributes.positions); + normals.push(attributes.normals); + colors.push(attributes.colors); + tops.push(attributes.tops); + + if (_properties) { + properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties))); + } + }; + + var outlineAttributes; + for (var j = 0; j < result.outlineAttributes.length; j++) { + outlineAttributes = result.outlineAttributes[j]; + + outlinePositions.push(outlineAttributes.positions); + outlineColors.push(outlineAttributes.colors); + }; + }; + + var mergedAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(positions), + normals: _utilBuffer2['default'].mergeFloat32Arrays(normals), + colors: _utilBuffer2['default'].mergeFloat32Arrays(colors), + tops: _utilBuffer2['default'].mergeFloat32Arrays(tops) + }; + + var mergedOutlineAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(outlinePositions), + colors: _utilBuffer2['default'].mergeFloat32Arrays(outlineColors) + }; + + transferrables.push(mergedAttributes.positions[0].buffer); + transferrables.push(mergedAttributes.positions[1].buffer); + + transferrables.push(mergedAttributes.normals[0].buffer); + transferrables.push(mergedAttributes.normals[1].buffer); + + transferrables.push(mergedAttributes.colors[0].buffer); + transferrables.push(mergedAttributes.colors[1].buffer); + + transferrables.push(mergedAttributes.tops[0].buffer); + transferrables.push(mergedAttributes.tops[1].buffer); + + transferrables.push(mergedOutlineAttributes.positions[0].buffer); + transferrables.push(mergedOutlineAttributes.positions[1].buffer); + + transferrables.push(mergedOutlineAttributes.colors[0].buffer); + transferrables.push(mergedOutlineAttributes.colors[1].buffer); + + var mergedProperties; + if (_properties) { + mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties); + + transferrables.push(mergedProperties[0].buffer); + transferrables.push(mergedProperties[1].buffer); + } + + var output = { + attributes: mergedAttributes, + outlineAttributes: mergedOutlineAttributes, + flats: flats + }; + + if (_properties) { + output.properties = mergedProperties; + } + + // TODO: Also return GeoJSON features that can be mapped to objects on + // the main thread. Allow user to provide filter / toggles to only return + // properties from the GeoJSON that they need (eg. don't return geometry, + // or don't return properties.height) + resolve({ + data: output, + transferrables: transferrables + }); + })['catch'](reject); + }); + } + }, { + key: 'ProcessPolylines', + value: function ProcessPolylines(polylinePromises, polylines, _properties) { + return new Promise(function (resolve, reject) { + Promise.all(polylinePromises).then(function (results) { + var transferrables = []; + + var positions = []; + var colors = []; + + var properties = []; + + var flats = []; + var polyline; + + var result; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + polyline = polylines[i]; + + // WORKERS: Making this a typed array will speed up transfer time + // As things stand this adds on a few milliseconds + flats.push(result.flat); + + // WORKERS: result.attributes is actually an array of polygons for each + // feature, though the current logic isn't keeping these all together + + var attributes; + for (var j = 0; j < result.attributes.length; j++) { + attributes = result.attributes[j]; + + positions.push(attributes.positions); + colors.push(attributes.colors); + + if (_properties) { + properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polyline.properties))); + } + }; + }; + + var mergedAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(positions), + colors: _utilBuffer2['default'].mergeFloat32Arrays(colors) + }; + + transferrables.push(mergedAttributes.positions[0].buffer); + transferrables.push(mergedAttributes.positions[1].buffer); + + transferrables.push(mergedAttributes.colors[0].buffer); + transferrables.push(mergedAttributes.colors[1].buffer); + + var mergedProperties; + if (_properties) { + mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties); + + transferrables.push(mergedProperties[0].buffer); + transferrables.push(mergedProperties[1].buffer); + } + + var output = { + attributes: mergedAttributes, + flats: flats + }; + + if (_properties) { + output.properties = mergedProperties; + } + + // TODO: Also return GeoJSON features that can be mapped to objects on + // the main thread. Allow user to provide filter / toggles to only return + // properties from the GeoJSON that they need (eg. don't return geometry, + // or don't return properties.height) + resolve({ + data: output, + transferrables: transferrables + }); + })['catch'](reject); + }); + } + + // TODO: Dedupe with ProcessPolygons as they are identical + }, { + key: 'ProcessPoints', + value: function ProcessPoints(pointPromises, points, _properties) { + return new Promise(function (resolve, reject) { + Promise.all(pointPromises).then(function (results) { + var transferrables = []; + + var positions = []; + var normals = []; + var colors = []; + + var properties = []; + + var flats = []; + var point; + + var result; + for (var i = 0; i < results.length; i++) { + result = results[i]; + + point = points[i]; + + // WORKERS: Making this a typed array will speed up transfer time + // As things stand this adds on a few milliseconds + flats.push(result.flat); + + // WORKERS: result.attributes is actually an array of polygons for each + // feature, though the current logic isn't keeping these all together + + var attributes; + for (var j = 0; j < result.attributes.length; j++) { + attributes = result.attributes[j]; + + positions.push(attributes.positions); + normals.push(attributes.normals); + colors.push(attributes.colors); + + if (_properties) { + properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties))); + } + }; + }; + + var mergedAttributes = { + positions: _utilBuffer2['default'].mergeFloat32Arrays(positions), + normals: _utilBuffer2['default'].mergeFloat32Arrays(normals), + colors: _utilBuffer2['default'].mergeFloat32Arrays(colors) + }; + + transferrables.push(mergedAttributes.positions[0].buffer); + transferrables.push(mergedAttributes.positions[1].buffer); + + transferrables.push(mergedAttributes.normals[0].buffer); + transferrables.push(mergedAttributes.normals[1].buffer); + + transferrables.push(mergedAttributes.colors[0].buffer); + transferrables.push(mergedAttributes.colors[1].buffer); + + var mergedProperties; + if (_properties) { + mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties); + + transferrables.push(mergedProperties[0].buffer); + transferrables.push(mergedProperties[1].buffer); + } + + var output = { + attributes: mergedAttributes, + flats: flats + }; + + if (_properties) { + output.properties = mergedProperties; + } + + // TODO: Also return GeoJSON features that can be mapped to objects on + // the main thread. Allow user to provide filter / toggles to only return + // properties from the GeoJSON that they need (eg. don't return geometry, + // or don't return properties.height) + resolve({ + data: output, + transferrables: transferrables + }); + })['catch'](reject); + }); + } + }, { + key: 'ProcessGeoJSON', + value: function ProcessGeoJSON(geojson, headers) { + if (typeof geojson === 'string') { + return GeoJSONWorkerLayer.RequestGeoJSON(geojson, headers); + } else { + return Promise.resolve(JSON.parse(_utilBuffer2['default'].uint8ArrayToString(geojson))); + } + } + }, { + key: 'RequestGeoJSON', + value: function RequestGeoJSON(path, headers) { + return (0, _reqwest2['default'])({ + url: path, + type: 'json', + crossOrigin: true, + headers: headers + }); + } + }]); + + return GeoJSONWorkerLayer; + })(_Layer3['default']); + + exports['default'] = GeoJSONWorkerLayer; + + var noNew = function noNew(geojson, options) { + return new GeoJSONWorkerLayer(geojson, options); + }; + + exports.geoJSONWorkerLayer = noNew; + +/***/ }, +/* 88 */ +/***/ function(module, exports) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + var Stringify = (function () { + var functionToString = function functionToString(f) { + return f.toString(); + }; + + // Based on https://github.com/tangrams/tangram/blob/2a31893c814cf15d5077f87ffa10af20160716b9/src/utils/utils.js#L245 + var stringToFunction = function stringToFunction(str) { + if (typeof str === 'string' && str.match(/^\s*function\s*\w*\s*\([\s\S]*\)\s*\{[\s\S]*\}/m) != null) { + var f; + + try { + eval('f = ' + str); + return f; + } catch (err) { + return str; + } + } + }; + + return { + functionToString: functionToString, + stringToFunction: stringToFunction + }; + })(); + + exports['default'] = Stringify; + module.exports = exports['default']; + +/***/ }, +/* 89 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -18535,7 +20819,7 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _GeoJSONTileLayer2 = __webpack_require__(57); + var _GeoJSONTileLayer2 = __webpack_require__(70); var _GeoJSONTileLayer3 = _interopRequireDefault(_GeoJSONTileLayer2); @@ -18570,7 +20854,7 @@ return /******/ (function(modules) { // webpackBootstrap exports.topoJSONTileLayer = noNew; /***/ }, -/* 76 */ +/* 90 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -18585,7 +20869,7 @@ return /******/ (function(modules) { // webpackBootstrap function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } - var _GeoJSONLayer2 = __webpack_require__(59); + var _GeoJSONLayer2 = __webpack_require__(72); var _GeoJSONLayer3 = _interopRequireDefault(_GeoJSONLayer2); @@ -18621,7 +20905,58 @@ return /******/ (function(modules) { // webpackBootstrap exports.topoJSONLayer = noNew; /***/ }, -/* 77 */ +/* 91 */ +/***/ function(module, exports, __webpack_require__) { + + Object.defineProperty(exports, '__esModule', { + value: true + }); + + var _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } }; + + function _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; } + + function _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } } + + function _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; } + + var _GeoJSONWorkerLayer2 = __webpack_require__(87); + + var _GeoJSONWorkerLayer3 = _interopRequireDefault(_GeoJSONWorkerLayer2); + + var _lodashAssign = __webpack_require__(3); + + var _lodashAssign2 = _interopRequireDefault(_lodashAssign); + + var TopoJSONWorkerLayer = (function (_GeoJSONWorkerLayer) { + _inherits(TopoJSONWorkerLayer, _GeoJSONWorkerLayer); + + function TopoJSONWorkerLayer(topojson, options) { + _classCallCheck(this, TopoJSONWorkerLayer); + + var defaults = { + topojson: true + }; + + options = (0, _lodashAssign2['default'])({}, defaults, options); + + _get(Object.getPrototypeOf(TopoJSONWorkerLayer.prototype), 'constructor', this).call(this, topojson, options); + } + + return TopoJSONWorkerLayer; + })(_GeoJSONWorkerLayer3['default']); + + exports['default'] = TopoJSONWorkerLayer; + + var noNew = function noNew(topojson, options) { + return new TopoJSONWorkerLayer(topojson, options); + }; + + // Initialise without requiring new keyword + exports.topoJSONWorkerLayer = noNew; + +/***/ }, +/* 92 */ /***/ function(module, exports, __webpack_require__) { Object.defineProperty(exports, '__esModule', { @@ -18632,34 +20967,44 @@ return /******/ (function(modules) { // webpackBootstrap // TODO: A lot of these utils don't need to be in separate, tiny files - var _wrapNum = __webpack_require__(78); + var _wrapNum = __webpack_require__(93); var _wrapNum2 = _interopRequireDefault(_wrapNum); - var _extrudePolygon = __webpack_require__(68); + var _extrudePolygon = __webpack_require__(80); var _extrudePolygon2 = _interopRequireDefault(_extrudePolygon); - var _GeoJSON = __webpack_require__(63); + var _GeoJSON = __webpack_require__(75); var _GeoJSON2 = _interopRequireDefault(_GeoJSON); - var _Buffer = __webpack_require__(69); + var _Buffer = __webpack_require__(81); var _Buffer2 = _interopRequireDefault(_Buffer); + var _Worker = __webpack_require__(46); + + var _Worker2 = _interopRequireDefault(_Worker); + + var _Stringify = __webpack_require__(88); + + var _Stringify2 = _interopRequireDefault(_Stringify); + var Util = {}; Util.wrapNum = _wrapNum2['default']; Util.extrudePolygon = _extrudePolygon2['default']; Util.GeoJSON = _GeoJSON2['default']; Util.Buffer = _Buffer2['default']; + Util.Worker = _Worker2['default']; + Util.Stringify = _Stringify2['default']; exports['default'] = Util; module.exports = exports['default']; /***/ }, -/* 78 */ +/* 93 */ /***/ function(module, exports) { Object.defineProperty(exports, "__esModule", { diff --git a/dist/vizicities.min.js b/dist/vizicities.min.js index 7273f7f..b9a518f 100644 --- a/dist/vizicities.min.js +++ b/dist/vizicities.min.js @@ -1,8 +1,9 @@ -!function(e,t){"object"==typeof exports&&"object"==typeof module?module.exports=t(require("THREE"),require("TweenLite")):"function"==typeof define&&define.amd?define(["THREE","TweenLite"],t):"object"==typeof exports?exports.VIZI=t(require("THREE"),require("TweenLite")):e.VIZI=t(e.THREE,e.TweenLite)}(this,function(__WEBPACK_EXTERNAL_MODULE_10__,__WEBPACK_EXTERNAL_MODULE_41__){return function(e){function t(r){if(n[r])return n[r].exports;var i=n[r]={exports:{},id:r,loaded:!1};return e[r].call(i.exports,i,i.exports,t),i.loaded=!0,i.exports}var n={};return t.m=e,t.c=n,t.p="",t(0)}([function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(1),o=r(i),a=n(37),s=r(a),u=n(6),l=r(u),c=n(32),f=r(c),h=n(31),p=r(h),d=n(42),v=r(d),y=n(57),m=r(y),_=n(75),g=r(_),b=n(59),x=r(b),w=n(76),M=r(w),E=n(72),O=r(E),k=n(73),P=r(k),T=n(74),j=r(T),S=n(8),A=r(S),C=n(7),L=r(C),D=n(70),R=r(D),B=n(77),I=r(B),F={version:"0.3",World:o["default"],world:i.world,Controls:s["default"],Geo:l["default"],Layer:f["default"],layer:c.layer,EnvironmentLayer:p["default"],environmentLayer:h.environmentLayer,ImageTileLayer:v["default"],imageTileLayer:d.imageTileLayer,GeoJSONTileLayer:m["default"],geoJSONTileLayer:y.geoJSONTileLayer,TopoJSONTileLayer:g["default"],topoJSONTileLayer:_.topoJSONTileLayer,GeoJSONLayer:x["default"],geoJSONLayer:b.geoJSONLayer,TopoJSONLayer:M["default"],topoJSONLayer:w.topoJSONLayer,PolygonLayer:O["default"],polygonLayer:E.polygonLayer,PolylineLayer:P["default"],polylineLayer:k.polylineLayer,PointLayer:j["default"],pointLayer:T.pointLayer,Point:A["default"],point:S.point,LatLon:L["default"],latLon:C.latLon,PickingMaterial:R["default"],Util:I["default"]};t["default"]=F,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n-1&&this._layers.splice(t,1),e.isOutput()&&e.isOutputToScene()&&(this._engine._scene.remove(e._object3D),this._engine._domScene3D.remove(e._domObject3D),this._engine._domScene2D.remove(e._domObject2D)),this.emit("layerRemoved"),Promise.resolve(this)}},{key:"addControls",value:function(e){return e._addToWorld(this),this._controls.push(e),this.emit("controlsAdded",e),Promise.resolve(this)}},{key:"removeControls",value:function(e){var t=this._controls.indexOf(t);return t>-1&&this._controls.splice(t,1),this.emit("controlsRemoved",e),Promise.resolve(this)}},{key:"stop",value:function(){this._pause=!0}},{key:"start",value:function(){this._pause=!1,this._update()}},{key:"destroy",value:function(){this.stop(),this.off("controlsMoveEnd",this._onControlsMoveEnd);var e,t;for(e=this._controls.length-1;e>=0;e--)t=this._controls[0],this.removeControls(t),t.destroy();var n;for(e=this._layers.length-1;e>=0;e--)n=this._layers[0],this.removeLayer(n),n.destroy();for(this._environment=null,this._engine.destroy(),this._engine=null;this._container.firstChild;)this._container.removeChild(this._container.firstChild);this._container=null}}]),t}(l["default"]);t["default"]=b;var x=function(e,t){return new b(e,t)};t.world=x},function(e,t,n){"use strict";function r(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function i(){}var o=Object.prototype.hasOwnProperty,a="function"!=typeof Object.create?"~":!1;i.prototype._events=void 0,i.prototype.eventNames=function(){var e,t=this._events,n=[];if(!t)return n;for(e in t)o.call(t,e)&&n.push(a?e.slice(1):e);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(t)):n},i.prototype.listeners=function(e,t){var n=a?a+e:e,r=this._events&&this._events[n];if(t)return!!r;if(!r)return[];if(r.fn)return[r.fn];for(var i=0,o=r.length,s=new Array(o);o>i;i++)s[i]=r[i].fn;return s},i.prototype.emit=function(e,t,n,r,i,o){var s=a?a+e:e;if(!this._events||!this._events[s])return!1;var u,l,c=this._events[s],f=arguments.length;if("function"==typeof c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),f){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,r),!0;case 5:return c.fn.call(c.context,t,n,r,i),!0;case 6:return c.fn.call(c.context,t,n,r,i,o),!0}for(l=1,u=new Array(f-1);f>l;l++)u[l-1]=arguments[l];c.fn.apply(c.context,u)}else{var h,p=c.length;for(l=0;p>l;l++)switch(c[l].once&&this.removeListener(e,c[l].fn,void 0,!0),f){case 1:c[l].fn.call(c[l].context);break;case 2:c[l].fn.call(c[l].context,t);break;case 3:c[l].fn.call(c[l].context,t,n);break;default:if(!u)for(h=1,u=new Array(f-1);f>h;h++)u[h-1]=arguments[h];c[l].fn.apply(c[l].context,u)}}return!0},i.prototype.on=function(e,t,n){var i=new r(t,n||this),o=a?a+e:e;return this._events||(this._events=a?{}:Object.create(null)),this._events[o]?this._events[o].fn?this._events[o]=[this._events[o],i]:this._events[o].push(i):this._events[o]=i,this},i.prototype.once=function(e,t,n){var i=new r(t,n||this,!0),o=a?a+e:e;return this._events||(this._events=a?{}:Object.create(null)),this._events[o]?this._events[o].fn?this._events[o]=[this._events[o],i]:this._events[o].push(i):this._events[o]=i,this},i.prototype.removeListener=function(e,t,n,r){var i=a?a+e:e;if(!this._events||!this._events[i])return this;var o=this._events[i],s=[];if(t)if(o.fn)(o.fn!==t||r&&!o.once||n&&o.context!==n)&&s.push(o);else for(var u=0,l=o.length;l>u;u++)(o[u].fn!==t||r&&!o[u].once||n&&o[u].context!==n)&&s.push(o[u]);return s.length?this._events[i]=1===s.length?s[0]:s:delete this._events[i],this},i.prototype.removeAllListeners=function(e){return this._events?(e?delete this._events[a?a+e:e]:this._events=a?{}:Object.create(null),this):this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prototype.setMaxListeners=function(){return this},i.prefixed=a,e.exports=i},function(e,t,n){function r(e,t,n){var r=e[t];w.call(e,t)&&c(r,n)&&(void 0!==n||t in e)||(e[t]=n)}function i(e){return function(t){return null==t?void 0:t[e]}}function o(e,t,n,i){n||(n={});for(var o=-1,a=t.length;++o1?n[i-1]:void 0,a=i>2?n[2]:void 0;for(o=e.length>3&&"function"==typeof o?(i--,o):void 0,a&&u(n[0],n[1],a)&&(o=3>i?void 0:o,i=1),t=Object(t);++r-1&&e%1==0&&t>e}function u(e,t,n){if(!d(n))return!1;var r=typeof t;return("number"==r?f(n)&&s(t,n.length):"string"==r&&t in n)?c(n[t],e):!1}function l(e){var t=e&&e.constructor,n="function"==typeof t&&t.prototype||x;return e===n}function c(e,t){return e===t||e!==e&&t!==t}function f(e){return null!=e&&p(k(e))&&!h(e)}function h(e){var t=d(e)?M.call(e):"";return t==_||t==g}function p(e){return"number"==typeof e&&e>-1&&e%1==0&&m>=e}function d(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var v=n(4),y=n(5),m=9007199254740991,_="[object Function]",g="[object GeneratorFunction]",b=/^(?:0|[1-9]\d*)$/,x=Object.prototype,w=x.hasOwnProperty,M=x.toString,E=x.propertyIsEnumerable,O=!E.call({valueOf:1},"valueOf"),k=i("length"),P=a(function(e,t){if(O||l(t)||f(t))return void o(t,v(t),e);for(var n in t)w.call(t,n)&&r(e,n,t[n])});e.exports=P},function(e,t){function n(e,t){for(var n=-1,r=Array(e);++n-1&&e%1==0&&t>e}function l(e){var t=e&&e.constructor,n="function"==typeof t&&t.prototype||O;return e===n}function c(e){return h(e)&&k.call(e,"callee")&&(!T.call(e,"callee")||P.call(e)==b)}function f(e){return null!=e&&d(A(e))&&!p(e)}function h(e){return y(e)&&f(e)}function p(e){var t=v(e)?P.call(e):"";return t==x||t==w}function d(e){return"number"==typeof e&&e>-1&&e%1==0&&g>=e}function v(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function y(e){return!!e&&"object"==typeof e}function m(e){return"string"==typeof e||!C(e)&&y(e)&&P.call(e)==M}function _(e){var t=l(e);if(!t&&!f(e))return i(e);var n=s(e),o=!!n,a=n||[],c=a.length;for(var h in e)!r(e,h)||o&&("length"==h||u(h,c))||t&&"constructor"==h||a.push(h);return a}var g=9007199254740991,b="[object Arguments]",x="[object Function]",w="[object GeneratorFunction]",M="[object String]",E=/^(?:0|[1-9]\d*)$/,O=Object.prototype,k=O.hasOwnProperty,P=O.toString,T=O.propertyIsEnumerable,j=Object.getPrototypeOf,S=Object.keys,A=o("length"),C=Array.isArray;e.exports=_},function(e,t){function n(e,t,n){var r=n.length;switch(r){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function r(e,t){if("function"!=typeof e)throw new TypeError(f);return t=O(void 0===t?e.length-1:l(t),0),function(){for(var r=arguments,i=-1,o=O(r.length-t,0),a=Array(o);++ie?-1:1;return t*p}return e===e?e:0}function l(e){var t=u(e),n=t%1;return t===t?n?t-n:t:0}function c(e){if("number"==typeof e)return e;if(s(e))return d;if(o(e)){var t=i(e.valueOf)?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(_,"");var n=b.test(e);return n||x.test(e)?w(e.slice(2),n?2:8):g.test(e)?d:+e}var f="Expected a function",h=1/0,p=1.7976931348623157e308,d=NaN,v="[object Function]",y="[object GeneratorFunction]",m="[object Symbol]",_=/^\s+|\s+$/g,g=/^[-+]0x[0-9a-f]+$/i,b=/^0b[01]+$/i,x=/^0o[0-7]+$/i,w=parseInt,M=Object.prototype,E=M.toString,O=Math.max;e.exports=r},function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0});var r=n(7),i=n(8),o={};o.R=6378137,o.MAX_LATITUDE=85.0511287798,o.ECC=.081819191,o.ECC2=.006694380015894481,o.project=function(e){var t=Math.PI/180,n=o.MAX_LATITUDE,r=Math.max(Math.min(n,e.lat),-n),a=Math.sin(r*t);return(0,i.point)(o.R*e.lon*t,o.R*Math.log((1+a)/(1-a))/2)},o.unproject=function(e){var t=180/Math.PI;return(0,r.latLon)((2*Math.atan(Math.exp(e.y/o.R))-Math.PI/2)*t,e.x*t/o.R)},o.latLonToPoint=function(e){var t=o.project(e);return t.y*=-1,t},o.pointToLatLon=function(e){var t=(0,i.point)(e.x,-1*e.y);return o.unproject(t)},o.pointScale=function(e,t){var n,r=Math.PI/180;if(t){var i=e.lat*r,a=(e.lon*r,o.R),s=Math.sin(i),u=s*s,l=Math.cos(i),c=a*(1-o.ECC2)/Math.pow(1-o.ECC2*u,1.5),f=a/Math.sqrt(1-o.ECC2*u),h=a/c/l;return n=a/f/l,[n,h]}return n=1/Math.cos(e.lat*r),[n,n]},o.metresToProjected=function(e,t){return e*t[1]},o.projectedToMetres=function(e,t){return e/t[1]},o.metresToWorld=function(e,t){var n=o.metresToProjected(e,t),r=o.scale(),i=r*n;return i},o.worldToMetres=function(e,t){var n=o.scale(),r=e/n,i=o.projectedToMetres(r,t);return i},o.scale=function(e){return e>=0?256*Math.pow(2,e):1},o.zoom=function(e){return Math.log(e/256)/Math.LN2},o.distance=function(e,t,n){var r,i,a,s=Math.PI/180;if(n){r=e.lat*s,i=t.lat*s;var u=e.lon*s,l=t.lon*s,c=i-r,f=l-u,h=c/2,p=f/2;a=Math.sin(h)*Math.sin(h)+Math.cos(r)*Math.cos(i)*Math.sin(p)*Math.sin(p);var d=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));return o.R*d}return r=e.lat*s,i=t.lat*s,a=Math.sin(r)*Math.sin(i)+Math.cos(r)*Math.cos(i)*Math.cos((t.lon-e.lon)*s),o.R*Math.acos(Math.min(a,1))},o.bounds=function(){var e=o.R*Math.PI;return[[-e,-e],[e,e]]}(),t["default"]=o,e.exports=t["default"]},function(e,t){function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=0;t--)e=this._scene.children[t],e&&(this._scene.remove(e),e.geometry&&(e.geometry.dispose(),e.geometry=null),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));for(var t=this._domScene3D.children.length-1;t>=0;t--)e=this._domScene3D.children[t],e&&this._domScene3D.remove(e);for(var t=this._domScene2D.children.length-1;t>=0;t--)e=this._domScene2D.children[t],e&&this._domScene2D.remove(e);this._picking.destroy(),this._picking=null,this._world=null,this._scene=null,this._domScene3D=null,this._domScene2D=null,this._composer=null,this._renderer=null,this._domRenderer3D=null,this._domRenderer2D=null,this._camera=null,this._clock=null,this._frustum=null}}]),t}(l["default"]);t["default"]=H,e.exports=t["default"]},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE_10__},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=n(11);r(a);t["default"]=function(e,t){var n=new o["default"].WebGLRenderer({antialias:t});n.setClearColor(16777215,1);var r=1;n.setPixelRatio(r),n.gammaInput=!0,n.gammaOutput=!0,n.shadowMap.enabled=!0,e.appendChild(n.domElement);var i=function(){n.setSize(e.clientWidth,e.clientHeight)};return window.addEventListener("resize",i,!1),i(),n},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=(r(i),n(16)),a=n(12);r(a);t["default"]=function(e){var t=new o.CSS3DRenderer;t.domElement.style.position="absolute",t.domElement.style.top=0,e.appendChild(t.domElement);var n=function(){t.setSize(e.clientWidth,e.clientHeight)};return window.addEventListener("resize",n,!1),n(),t},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e){o["default"].Object3D.call(this),this.element=e,this.element.style.position="absolute",this.addEventListener("removed",function(e){null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element)})};a.prototype=Object.create(o["default"].Object3D.prototype),a.prototype.constructor=a;var s=function(e){a.call(this,e)};s.prototype=Object.create(a.prototype),s.prototype.constructor=s;var u=function(){console.log("THREE.CSS3DRenderer",o["default"].REVISION);var e,t,n,r,i=new o["default"].Matrix4,u={camera:{fov:0,style:""},objects:{}},l=document.createElement("div");l.style.overflow="hidden",l.style.WebkitTransformStyle="preserve-3d",l.style.MozTransformStyle="preserve-3d",l.style.oTransformStyle="preserve-3d",l.style.transformStyle="preserve-3d",this.domElement=l;var c=document.createElement("div");c.style.WebkitTransformStyle="preserve-3d",c.style.MozTransformStyle="preserve-3d",c.style.oTransformStyle="preserve-3d",c.style.transformStyle="preserve-3d",l.appendChild(c),this.setClearColor=function(){},this.getSize=function(){return{width:e,height:t}},this.setSize=function(i,o){e=i,t=o,n=e/2,r=t/2,l.style.width=i+"px",l.style.height=o+"px",c.style.width=i+"px",c.style.height=o+"px"};var f=function(e){return Math.abs(e)l;l++)v(e.children[l],t)};this.render=function(e,i){var a=.5/Math.tan(o["default"].Math.degToRad(.5*i.fov))*t;u.camera.fov!==a&&(l.style.WebkitPerspective=a+"px",l.style.MozPerspective=a+"px",l.style.oPerspective=a+"px",l.style.perspective=a+"px",u.camera.fov=a),e.updateMatrixWorld(),null===i.parent&&i.updateMatrixWorld(),i.matrixWorldInverse.getInverse(i.matrixWorld);var s="translate3d(0,0,"+a+"px)"+h(i.matrixWorldInverse)+" translate3d("+n+"px,"+r+"px, 0)";u.camera.style!==s&&(c.style.WebkitTransform=s,c.style.MozTransform=s,c.style.oTransform=s,c.style.transform=s,u.camera.style=s),d(e,i)}};t.CSS3DObject=a,t.CSS3DSprite=s,t.CSS3DRenderer=u,o["default"].CSS3DObject=a,o["default"].CSS3DSprite=s,o["default"].CSS3DRenderer=u},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=(r(i),n(18)),a=n(13);r(a);t["default"]=function(e){var t=new o.CSS2DRenderer;t.domElement.style.position="absolute",t.domElement.style.top=0,e.appendChild(t.domElement);var n=function(){t.setSize(e.clientWidth,e.clientHeight)};return window.addEventListener("resize",n,!1),n(),t},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e){o["default"].Object3D.call(this),this.element=e,this.element.style.position="absolute",this.addEventListener("removed",function(e){null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element)})};a.prototype=Object.create(o["default"].Object3D.prototype),a.prototype.constructor=a;var s=function(){console.log("THREE.CSS2DRenderer",o["default"].REVISION);var e,t,n,r,i=new o["default"].Vector3,s=new o["default"].Matrix4,u=new o["default"].Matrix4,l=new o["default"].Frustum,c=document.createElement("div");c.style.overflow="hidden",this.domElement=c,this.setSize=function(i,o){e=i,t=o,n=e/2,r=t/2,c.style.width=i+"px",c.style.height=o+"px"};var f=function h(e,t){if(e instanceof a){i.setFromMatrixPosition(e.matrixWorld),i.applyProjection(u);var o=e.element,s="translate(-50%,-50%) translate("+(i.x*n+n)+"px,"+(-i.y*r+r)+"px)";o.style.WebkitTransform=s,o.style.MozTransform=s,o.style.oTransform=s,o.style.transform=s,o.parentNode!==c&&c.appendChild(o),l.containsPoint(e.position)?o.style.display="block":o.style.display="none"}for(var f=0,p=e.children.length;p>f;f++)h(e.children[f],t)};this.render=function(e,t){e.updateMatrixWorld(),null===t.parent&&t.updateMatrixWorld(),t.matrixWorldInverse.getInverse(t.matrixWorld),s.copy(t.matrixWorldInverse.getInverse(t.matrixWorld)),u.multiplyMatrices(t.projectionMatrix,s),l.setFromMatrix((new o["default"].Matrix4).multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse)),f(e,t)}};t.CSS2DObject=a,t.CSS2DRenderer=s,o["default"].CSS2DObject=a,o["default"].CSS2DRenderer=s},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(e){var t=new o["default"].PerspectiveCamera(45,1,1,2e6);t.position.y=4e3,t.position.z=4e3;var n=function(){t.aspect=e.clientWidth/e.clientHeight,t.updateProjectionMatrix()};return window.addEventListener("resize",n,!1),n(),t},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n0&&(i=o[0].point.clone()),this._world.emit("pick",r,a,i,o),this._world.emit("pick-"+r,a,i,o)}}},{key:"add",value:function(e){this._pickingScene.add(e),this._needUpdate=!0}},{key:"remove",value:function(e){this._pickingScene.remove(e),this._needUpdate=!0}},{key:"getNextId",value:function(){return f++}},{key:"destroy",value:function(){if(window.removeEventListener("resize",this._resizeHandler,!1), -this._world._container.removeEventListener("mouseup",this._mouseUpHandler,!1),this._world.off("move",this._onWorldMove),this._pickingScene.children)for(var e,t=this._pickingScene.children.length-1;t>=0;t--)e=this._pickingScene.children[t],e&&(this._pickingScene.remove(e),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));this._pickingScene=null,this._pickingTexture=null,this._pixelBuffer=null,this._world=null,this._renderer=null,this._camera=null}}]),e}();t["default"]=function(e,t,n){return new h(e,t,n)},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=(r(i),n(23)),a=r(o);t["default"]=function(e,t){var n=new a["default"](e),r=function(){var e=1;n.setSize(t.clientWidth*e,t.clientHeight*e)};return window.addEventListener("resize",r,!1),r(),n},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=n(24),s=r(a),u=n(25),l=r(u),c=n(26),f=r(c),h=function(e,t){if(this.renderer=e,void 0===t){var n=e.getPixelRatio(),r=Math.floor(e.context.canvas.width/n)||1,i=Math.floor(e.context.canvas.height/n)||1,a={minFilter:o["default"].LinearFilter,magFilter:o["default"].LinearFilter,format:o["default"].RGBAFormat,stencilBuffer:!1};t=new o["default"].WebGLRenderTarget(r,i,a)}this.renderTarget1=t,this.renderTarget2=t.clone(),this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2,this.passes=[],void 0===s["default"]&&console.error("EffectComposer relies on THREE.CopyShader"),this.copyPass=new l["default"](s["default"])};h.prototype={swapBuffers:function(){var e=this.readBuffer;this.readBuffer=this.writeBuffer,this.writeBuffer=e},addPass:function(e){this.passes.push(e)},insertPass:function(e,t){this.passes.splice(t,0,e)},render:function(e){this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2;var t,n,r=!1,i=this.passes.length;for(n=0;i>n;n++)if(t=this.passes[n],t.enabled){if(t.render(this.renderer,this.writeBuffer,this.readBuffer,e,r),t.needsSwap){if(r){var o=this.renderer.context;o.stencilFunc(o.NOTEQUAL,1,4294967295),this.copyPass.render(this.renderer,this.writeBuffer,this.readBuffer,e),o.stencilFunc(o.EQUAL,1,4294967295)}this.swapBuffers()}t instanceof f["default"]?r=!0:t instanceof c.ClearMaskPass&&(r=!1)}},reset:function(e){if(void 0===e){e=this.renderTarget1.clone();var t=this.renderer.getPixelRatio();e.setSize(Math.floor(this.renderer.context.canvas.width/t),Math.floor(this.renderer.context.canvas.height/t))}this.renderTarget1.dispose(),this.renderTarget1=e,this.renderTarget2.dispose(),this.renderTarget2=e.clone(),this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2},setSize:function(e,t){this.renderTarget1.setSize(e,t),this.renderTarget2.setSize(e,t)}},t["default"]=h,o["default"].EffectComposer=h,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},opacity:{type:"f",value:1}},vertexShader:["varying vec2 vUv;","void main() {","vUv = uv;","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform float opacity;","uniform sampler2D tDiffuse;","varying vec2 vUv;","void main() {","vec4 texel = texture2D( tDiffuse, vUv );","gl_FragColor = opacity * texel;","}"].join("\n")};t["default"]=a,o["default"].CopyShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e,t){this.textureID=void 0!==t?t:"tDiffuse",e instanceof o["default"].ShaderMaterial?(this.uniforms=e.uniforms,this.material=e):e&&(this.uniforms=o["default"].UniformsUtils.clone(e.uniforms),this.material=new o["default"].ShaderMaterial({defines:e.defines||{},uniforms:this.uniforms,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader})),this.renderToScreen=!1,this.enabled=!0,this.needsSwap=!0,this.clear=!1,this.camera=new o["default"].OrthographicCamera(-1,1,1,-1,0,1),this.scene=new o["default"].Scene,this.quad=new o["default"].Mesh(new o["default"].PlaneBufferGeometry(2,2),null),this.scene.add(this.quad)};a.prototype={render:function(e,t,n,r){this.uniforms[this.textureID]&&(this.uniforms[this.textureID].value=n),this.quad.material=this.material,this.renderToScreen?e.render(this.scene,this.camera):e.render(this.scene,this.camera,t,this.clear)}},t["default"]=a,o["default"].ShaderPass=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e,t){this.scene=e,this.camera=t,this.enabled=!0,this.clear=!0,this.needsSwap=!1,this.inverse=!1};a.prototype={render:function(e,t,n,r){var i=e.context;i.colorMask(!1,!1,!1,!1),i.depthMask(!1);var o,a;this.inverse?(o=0,a=1):(o=1,a=0),i.enable(i.STENCIL_TEST),i.stencilOp(i.REPLACE,i.REPLACE,i.REPLACE),i.stencilFunc(i.ALWAYS,o,4294967295),i.clearStencil(a),e.render(this.scene,this.camera,n,this.clear),e.render(this.scene,this.camera,t,this.clear),i.colorMask(!0,!0,!0,!0),i.depthMask(!0),i.stencilFunc(i.EQUAL,1,4294967295),i.stencilOp(i.KEEP,i.KEEP,i.KEEP)}};var s=function(){this.enabled=!0};s.prototype={render:function(e,t,n,r){var i=e.context;i.disable(i.STENCIL_TEST)}},t["default"]=a,t.ClearMaskPass=s,o["default"].MaskPass=a,o["default"].ClearMaskPass=s},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e,t,n,r,i){this.scene=e,this.camera=t,this.overrideMaterial=n,this.clearColor=r,this.clearAlpha=void 0!==i?i:1,this.oldClearColor=new o["default"].Color,this.oldClearAlpha=1,this.enabled=!0,this.clear=!0,this.needsSwap=!1};a.prototype={render:function(e,t,n,r){this.scene.overrideMaterial=this.overrideMaterial,this.clearColor&&(this.oldClearColor.copy(e.getClearColor()),this.oldClearAlpha=e.getClearAlpha(),e.setClearColor(this.clearColor,this.clearAlpha)),e.render(this.scene,this.camera,n,this.clear),this.clearColor&&e.setClearColor(this.oldClearColor,this.oldClearAlpha),this.scene.overrideMaterial=null}},t["default"]=a,o["default"].RenderPass=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},h:{type:"f",value:1/512},r:{type:"f",value:.35}},vertexShader:["varying vec2 vUv;","void main() {","vUv = uv;","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform sampler2D tDiffuse;","uniform float h;","uniform float r;","varying vec2 vUv;","void main() {","vec4 sum = vec4( 0.0 );","float hh = h * abs( r - vUv.y );","sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;","sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;","sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;","gl_FragColor = sum;","}"].join("\n")};t["default"]=a,o["default"].HorizontalTiltShiftShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},v:{type:"f",value:1/512},r:{type:"f",value:.35}},vertexShader:["varying vec2 vUv;","void main() {","vUv = uv;","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform sampler2D tDiffuse;","uniform float v;","uniform float r;","varying vec2 vUv;","void main() {","vec4 sum = vec4( 0.0 );","float vv = v * abs( r - vUv.y );","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;","gl_FragColor = sum;","}"].join("\n")};t["default"]=a,o["default"].VerticalTiltShiftShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},resolution:{type:"v2",value:new o["default"].Vector2(1/1024,1/512)}},vertexShader:["void main() {","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform sampler2D tDiffuse;","uniform vec2 resolution;","#define FXAA_REDUCE_MIN (1.0/128.0)","#define FXAA_REDUCE_MUL (1.0/8.0)","#define FXAA_SPAN_MAX 8.0","void main() {","vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;","vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;","vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;","vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;","vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );","vec3 rgbM = rgbaM.xyz;","vec3 luma = vec3( 0.299, 0.587, 0.114 );","float lumaNW = dot( rgbNW, luma );","float lumaNE = dot( rgbNE, luma );","float lumaSW = dot( rgbSW, luma );","float lumaSE = dot( rgbSE, luma );","float lumaM = dot( rgbM, luma );","float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );","float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );","vec2 dir;","dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));","dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));","float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );","float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );","dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),","max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),","dir * rcpDirMin)) * resolution;","vec4 rgbA = (1.0/2.0) * (","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));","vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));","float lumaB = dot(rgbB, vec4(luma, 0.0));","if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {","gl_FragColor = rgbA;","} else {","gl_FragColor = rgbB;","}","}"].join("\n")};t["default"]=a,o["default"].FXAAShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n=0;t--)e=this._object3D.children[t],e&&(this.remove(e),e.geometry&&(e.geometry.dispose(),e.geometry=null),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));if(this._domObject3D&&this._domObject3D.children)for(var e,t=this._domObject3D.children.length-1;t>=0;t--)e=this._domObject3D.children[t],e&&this.removeDOM3D(e);if(this._domObject2D&&this._domObject2D.children)for(var e,t=this._domObject2D.children.length-1;t>=0;t--)e=this._domObject2D.children[t],e&&this.removeDOM2D(e);this._domObject3D=null,this._domObject2D=null,this._world=null,this._object3D=null}}]),t}(l["default"]);t["default"]=m;var _=function(e){return new m(e)};t.layer=_},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n degrees, and the cosine of that","// earth shadow hack","const float cutoffAngle = pi/1.95;","const float steepness = 1.5;","vec3 totalRayleigh(vec3 lambda)","{","return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));","}","// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE","vec3 simplifiedRayleigh()","{","return 0.0005 / vec3(94, 40, 18);","}","float rayleighPhase(float cosTheta)","{ ","return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));","// return (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));","// return (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));","}","vec3 totalMie(vec3 lambda, vec3 K, float T)","{","float c = (0.2 * T ) * 10E-18;","return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;","}","float hgPhase(float cosTheta, float g)","{","return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));","}","float sunIntensity(float zenithAngleCos)","{","return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));","}","// float logLuminance(vec3 c)","// {","// return log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);","// }","// Filmic ToneMapping http://filmicgames.com/archives/75","float A = 0.15;","float B = 0.50;","float C = 0.10;","float D = 0.20;","float E = 0.02;","float F = 0.30;","float W = 1000.0;","vec3 Uncharted2Tonemap(vec3 x)","{","return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;","}","void main() ","{","float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);","// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;","// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);","float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));","vec3 sunDirection = normalize(sunPosition);","float sunE = sunIntensity(dot(sunDirection, up));","// extinction (absorbtion + out scattering) ","// rayleigh coefficients","vec3 betaR = simplifiedRayleigh() * reileighCoefficient;","// mie coefficients","vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;","// optical length","// cutoff angle at 90 to avoid singularity in next formula.","float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));","float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));","float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));","// combined extinction factor ","vec3 Fex = exp(-(betaR * sR + betaM * sM));","// in scattering","float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);","float rPhase = rayleighPhase(cosTheta*0.5+0.5);","vec3 betaRTheta = betaR * rPhase;","float mPhase = hgPhase(cosTheta, mieDirectionalG);","vec3 betaMTheta = betaM * mPhase;","vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));","Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));","//nightsky","vec3 direction = normalize(vWorldPosition - cameraPos);","float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]","float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]","vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);","// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;","vec3 L0 = vec3(0.1) * Fex;","// composition + solar disc","//if (cosTheta > sunAngularDiameterCos)","float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);","// if (normalize(vWorldPosition - cameraPos).y>0.0)","L0 += (sunE * 19000.0 * Fex)*sundisk;","vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));","vec3 texColor = (Lin+L0); ","texColor *= 0.04 ;","texColor += vec3(0.0,0.001,0.0025)*0.3;","float g_fMaxLuminance = 1.0;","float fLumScaled = 0.1 / luminance; ","float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ","float ExposureBias = fLumCompressed;","vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);","vec3 color = curr*whiteScale;","vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));","gl_FragColor.rgb = retColor;","gl_FragColor.a = 1.0;","}"].join("\n")};var a=function(){var e=o["default"].ShaderLib.sky,t=o["default"].UniformsUtils.clone(e.uniforms),n=new o["default"].ShaderMaterial({fragmentShader:e.fragmentShader,vertexShader:e.vertexShader,uniforms:t,side:o["default"].BackSide}),r=new o["default"].SphereBufferGeometry(45e4,32,15),i=new o["default"].Mesh(r,n);this.mesh=i,this.uniforms=t};t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e,t,n){var r=!0,s=!0;if("function"!=typeof e)throw new TypeError(a);return i(n)&&(r="leading"in n?!!n.leading:r,s="trailing"in n?!!n.trailing:s),o(e,t,{leading:r,maxWait:t,trailing:s})}function i(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var o=n(36),a="Expected a function";e.exports=r},function(e,t){function n(e,t,n){function r(t){var n=v,r=y;return v=y=void 0,E=t,_=e.apply(r,n)}function o(e){return E=e,g=setTimeout(c,t),O?r(e):_}function a(e){var n=e-M,r=e-E,i=t-n;return k?x(i,m-r):i}function l(e){var n=e-M,r=e-E;return!M||n>=t||0>n||k&&r>=m}function c(){var e=w();return l(e)?f(e):void(g=setTimeout(c,a(e)))}function f(e){return clearTimeout(g),g=void 0,P&&v?r(e):(v=y=void 0,_)}function h(){void 0!==g&&clearTimeout(g),M=E=0,v=y=g=void 0}function p(){return void 0===g?_:f(w())}function d(){var e=w(),n=l(e);if(v=arguments,y=this,M=e,n){if(void 0===g)return o(M);if(k)return clearTimeout(g),g=setTimeout(c,t),r(M)}return void 0===g&&(g=setTimeout(c,t)),_}var v,y,m,_,g,M=0,E=0,O=!1,k=!1,P=!0;if("function"!=typeof e)throw new TypeError(u);return t=s(t)||0,i(n)&&(O=!!n.leading,k="maxWait"in n,m=k?b(s(n.maxWait)||0,t):m,P="trailing"in n?!!n.trailing:P),d.cancel=h,d.flush=p,d}function r(e){var t=i(e)?g.call(e):"";return t==c||t==f}function i(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function o(e){return!!e&&"object"==typeof e}function a(e){return"symbol"==typeof e||o(e)&&g.call(e)==h}function s(e){if("number"==typeof e)return e;if(a(e))return l;if(i(e)){var t=r(e.valueOf)?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(p,"");var n=v.test(e);return n||y.test(e)?m(e.slice(2),n?2:8):d.test(e)?l:+e}var u="Expected a function",l=NaN,c="[object Function]",f="[object GeneratorFunction]",h="[object Symbol]",p=/^\s+|\s+$/g,d=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,y=/^0o[0-7]+$/i,m=parseInt,_=Object.prototype,g=_.toString,b=Math.max,x=Math.min,w=Date.now;e.exports=n},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(38),o=r(i),a={Orbit:o["default"],orbit:i.orbit,orbit:i.orbit};t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n0?u(r()):re.y<0&&l(r()),te.copy(ne),I.update()}function v(e){Q.set(e.clientX,e.clientY),ee.subVectors(Q,$),ae(ee.x,ee.y),$.copy(Q),I.update()}function y(e){}function m(e){var t=0;void 0!==e.wheelDelta?t=e.wheelDelta:void 0!==e.detail&&(t=-e.detail),t>0?l(r()):0>t&&u(r()),I.update()}function _(e){switch(e.keyCode){case I.keys.UP:ae(0,I.keyPanSpeed),I.update();break;case I.keys.BOTTOM:ae(0,-I.keyPanSpeed),I.update();break;case I.keys.LEFT:ae(I.keyPanSpeed,0),I.update();break;case I.keys.RIGHT:ae(-I.keyPanSpeed,0),I.update()}}function g(e){Y.set(e.pointers[0].pageX,e.pointers[0].pageY)}function b(e){var t=e.pointers[0].pageX-e.pointers[1].pageX,n=e.pointers[0].pageY-e.pointers[1].pageY,r=Math.sqrt(t*t+n*n);te.set(0,r)}function x(e){$.set(e.deltaX,e.deltaY)}function w(e){K.set(e.pointers[0].pageX,e.pointers[0].pageY),J.subVectors(K,Y);var t=I.domElement===document?I.domElement.body:I.domElement;i(2*Math.PI*J.x/t.clientWidth*I.rotateSpeed),a(2*Math.PI*J.y/t.clientHeight*I.rotateSpeed),Y.copy(K),I.update()}function M(e){var t=e.pointers[0].pageX-e.pointers[1].pageX,n=e.pointers[0].pageY-e.pointers[1].pageY,i=Math.sqrt(t*t+n*n);ne.set(0,i),re.subVectors(ne,te),re.y>0?l(r()):re.y<0&&u(r()),te.copy(ne),I.update()}function E(e){Q.set(e.deltaX,e.deltaY),ee.subVectors(Q,$),ae(ee.x,ee.y),$.copy(Q),I.update()}function O(e){}function k(e){if(I.enabled!==!1){if(e.preventDefault(),e.button===I.mouseButtons.ORBIT){if(I.enableRotate===!1)return;c(e),H=N.ROTATE}else if(e.button===I.mouseButtons.ZOOM){if(I.enableZoom===!1)return;f(e),H=N.DOLLY}else if(e.button===I.mouseButtons.PAN){if(I.enablePan===!1)return;h(e),H=N.PAN}H!==N.NONE&&(document.addEventListener("mousemove",P,!1),document.addEventListener("mouseup",T,!1),document.addEventListener("mouseout",T,!1),I.dispatchEvent(z))}}function P(e){if(I.enabled!==!1)if(e.preventDefault(),H===N.ROTATE){if(I.enableRotate===!1)return;p(e)}else if(H===N.DOLLY){if(I.enableZoom===!1)return;d(e)}else if(H===N.PAN){if(I.enablePan===!1)return;v(e)}}function T(e){I.enabled!==!1&&(y(e),document.removeEventListener("mousemove",P,!1),document.removeEventListener("mouseup",T,!1),document.removeEventListener("mouseout",T,!1),I.dispatchEvent(U),H=N.NONE)}function j(e){I.enabled!==!1&&I.enableZoom!==!1&&H===N.NONE&&(e.preventDefault(),e.stopPropagation(),m(e),I.dispatchEvent(z),I.dispatchEvent(U))}function S(e){I.enabled!==!1&&I.enableKeys!==!1&&I.enablePan!==!1&&_(e)}function A(e){if(I.enabled!==!1){switch(e.touches.length){case 1:if(I.enableRotate===!1)return;g(e),H=N.TOUCH_ROTATE;break;case 2:if(I.enableZoom===!1)return;b(e),H=N.TOUCH_DOLLY;break;case 3:if(I.enablePan===!1)return;x(e),H=N.TOUCH_PAN;break;default:H=N.NONE}H!==N.NONE&&I.dispatchEvent(z)}}function C(e){if(I.enabled!==!1)switch(e.preventDefault(),e.stopPropagation(),e.touches.length){case 1:if(I.enableRotate===!1)return;if(H!==N.TOUCH_ROTATE)return;w(e);break;case 2:if(I.enableZoom===!1)return;if(H!==N.TOUCH_DOLLY)return;M(e);break;case 3:if(I.enablePan===!1)return;if(H!==N.TOUCH_PAN)return;E(e);break;default:H=N.NONE}}function L(e){I.enabled!==!1&&(O(e),I.dispatchEvent(U),H=N.NONE)}function D(e){e.preventDefault()}this.object=e,this.domElement=void 0!==t?t:document,this.enabled=!0,this.target=new o["default"].Vector3,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-(1/0),this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.25,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.enablePan=!0,this.keyPanSpeed=7,this.autoRotate=!1,this.autoRotateSpeed=2,this.enableKeys=!0,this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40},this.mouseButtons={ORBIT:o["default"].MOUSE.LEFT,ZOOM:o["default"].MOUSE.MIDDLE,PAN:o["default"].MOUSE.RIGHT},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this.getPolarAngle=function(){return B},this.getAzimuthalAngle=function(){return R},this.reset=function(){I.target.copy(I.target0),I.object.position.copy(I.position0),I.object.zoom=I.zoom0,I.object.updateProjectionMatrix(),I.dispatchEvent(F),I.update(),H=N.NONE},this.update=function(){var t=new o["default"].Vector3,r=(new o["default"].Quaternion).setFromUnitVectors(e.up,new o["default"].Vector3(0,1,0)),a=r.clone().inverse(),s=new o["default"].Vector3,u=new o["default"].Quaternion;return function(){var e=I.object.position;t.copy(e).sub(I.target),t.applyQuaternion(r),R=Math.atan2(t.x,t.z),B=Math.atan2(Math.sqrt(t.x*t.x+t.z*t.z),t.y),I.autoRotate&&H===N.NONE&&i(n()),R+=V,B+=q,R=Math.max(I.minAzimuthAngle,Math.min(I.maxAzimuthAngle,R)),B=Math.max(I.minPolarAngle,Math.min(I.maxPolarAngle,B)),B=Math.max(W,Math.min(Math.PI-W,B));var o=t.length()*G;return o=Math.max(I.minDistance,Math.min(I.maxDistance,o)),I.target.add(X),t.x=o*Math.sin(B)*Math.sin(R),t.y=o*Math.cos(B),t.z=o*Math.sin(B)*Math.cos(R),t.applyQuaternion(a),e.copy(I.target).add(t),I.object.lookAt(I.target),I.enableDamping===!0?(V*=1-I.dampingFactor,q*=1-I.dampingFactor):(V=0,q=0),G=1,X.set(0,0,0),Z||s.distanceToSquared(I.object.position)>W||8*(1-u.dot(I.object.quaternion))>W?(I.dispatchEvent(F),s.copy(I.object.position),u.copy(I.object.quaternion),Z=!1,!0):!1}}(),this.dispose=function(){I.domElement.removeEventListener("contextmenu",D,!1),I.domElement.removeEventListener("mousedown",k,!1),I.domElement.removeEventListener("mousewheel",j,!1),I.domElement.removeEventListener("MozMousePixelScroll",j,!1),I.domElement.removeEventListener("touchstart",A,!1),I.domElement.removeEventListener("touchend",L,!1),I.domElement.removeEventListener("touchmove",C,!1),document.removeEventListener("mousemove",P,!1),document.removeEventListener("mouseup",T,!1),document.removeEventListener("mouseout",T,!1),window.removeEventListener("keydown",S,!1)};var R,B,I=this,F={type:"change"},z={type:"start"},U={type:"end"},N={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},H=N.NONE,W=1e-6,q=0,V=0,G=1,X=new o["default"].Vector3,Z=!1,Y=new o["default"].Vector2,K=new o["default"].Vector2,J=new o["default"].Vector2,$=new o["default"].Vector2,Q=new o["default"].Vector2,ee=new o["default"].Vector2,te=new o["default"].Vector2,ne=new o["default"].Vector2,re=new o["default"].Vector2,ie=function(){var e=new o["default"].Vector3;return function(t,n){var r=n.elements;e.set(r[0],0,r[2]),e.multiplyScalar(-t),X.add(e)}}(),oe=function(){var e=new o["default"].Vector3;return function(t,n){var r=n.elements,i=t/Math.cos(B);e.set(r[4],0,r[6]),e.multiplyScalar(i),X.add(e)}}(),ae=function(){var e=new o["default"].Vector3;return function(t,n){var r=I.domElement===document?I.domElement.body:I.domElement;if(I.object instanceof o["default"].PerspectiveCamera){var i=I.object.position;e.copy(i).sub(I.target);var a=e.length();a*=Math.tan(I.object.fov/2*Math.PI/180),ie(2*t*a/r.clientHeight,I.object.matrix),oe(2*n*a/r.clientHeight,I.object.matrix)}else I.object instanceof o["default"].OrthographicCamera?(ie(t*(I.object.right-I.object.left)/r.clientWidth,I.object.matrix),oe(n*(I.object.top-I.object.bottom)/r.clientHeight,I.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),I.enablePan=!1)}}();I.domElement.addEventListener("contextmenu",D,!1),I.domElement.addEventListener("mousedown",k,!1),I.domElement.addEventListener("mousewheel",j,!1),I.domElement.addEventListener("MozMousePixelScroll",j,!1),I.hammer=new s["default"](I.domElement),I.hammer.get("pan").set({pointers:0,direction:s["default"].DIRECTION_ALL}),I.hammer.get("pinch").set({enable:!0,threshold:.1}),I.hammer.on("panstart",function(e){if(I.enabled!==!1&&"mouse"!==e.pointerType){if(1===e.pointers.length){if(I.enablePan===!1)return;x(e),H=N.TOUCH_PAN}else if(2===e.pointers.length){if(I.enableRotate===!1)return;g(e),H=N.TOUCH_ROTATE}H!==N.NONE&&I.dispatchEvent(z)}}),I.hammer.on("panend",function(e){"mouse"!==e.pointerType&&L(e)}),I.hammer.on("panmove",function(e){if(I.enabled!==!1&&"mouse"!==e.pointerType)if(1===e.pointers.length){if(I.enablePan===!1)return;if(H!==N.TOUCH_PAN)return;E(e)}else if(2===e.pointers.length){if(I.enableRotate===!1)return;if(H!==N.TOUCH_ROTATE)return;w(e)}}),I.hammer.on("pinchstart",function(e){I.enabled!==!1&&"mouse"!==e.pointerType&&I.enableZoom!==!1&&(b(e),H=N.TOUCH_DOLLY,H!==N.NONE&&I.dispatchEvent(z))}),I.hammer.on("pinchend",function(e){"mouse"!==e.pointerType&&L(e)}),I.hammer.on("pinchmove",function(e){I.enabled!==!1&&"mouse"!==e.pointerType&&I.enableZoom!==!1&&H===N.TOUCH_DOLLY&&M(e)}),window.addEventListener("keydown",S,!1),this.panLeft=ie,this.panUp=oe,this.pan=ae,this.dollyIn=u,this.dollyOut=l,this.getZoomScale=r,this.rotateLeft=i,this.rotateUp=a,this.update()};u.prototype=Object.create(o["default"].EventDispatcher.prototype),u.prototype.constructor=o["default"].OrbitControls,Object.defineProperties(u.prototype,{center:{get:function(){return console.warn("THREE.OrbitControls: .center has been renamed to .target"),this.target}},noZoom:{get:function(){return console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead."),!this.enableZoom},set:function(e){console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead."),this.enableZoom=!e}},noRotate:{get:function(){return console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead."),!this.enableRotate},set:function(e){console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead."),this.enableRotate=!e}},noPan:{get:function(){return console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead."),!this.enablePan},set:function(e){console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead."),this.enablePan=!e}},noKeys:{get:function(){return console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead."),!this.enableKeys},set:function(e){console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead."),this.enableKeys=!e}},staticMoving:{get:function(){return console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead."),!this.constraint.enableDamping},set:function(e){console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead."),this.constraint.enableDamping=!e}},dynamicDampingFactor:{get:function(){return console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead."),this.constraint.dampingFactor},set:function(e){console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead."),this.constraint.dampingFactor=e}}}),t["default"]=u,e.exports=t["default"]},function(e,t,n){var r;!function(i,o,a,s){"use strict";function u(e,t,n){return setTimeout(p(e,n),t)}function l(e,t,n){return Array.isArray(e)?(c(e,n[t],n),!0):!1}function c(e,t,n){var r;if(e)if(e.forEach)e.forEach(t,n);else if(e.length!==s)for(r=0;r\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",o=i.console&&(i.console.warn||i.console.log);return o&&o.call(i.console,r,n),e.apply(this,arguments)}}function h(e,t,n){var r,i=t.prototype;r=e.prototype=Object.create(i),r.constructor=e,r._super=i,n&&ve(r,n)}function p(e,t){return function(){return e.apply(t,arguments)}}function d(e,t){return typeof e==_e?e.apply(t?t[0]||s:s,t):e}function v(e,t){return e===s?t:e}function y(e,t,n){c(b(t),function(t){e.addEventListener(t,n,!1)})}function m(e,t,n){c(b(t),function(t){e.removeEventListener(t,n,!1)})}function _(e,t){for(;e;){if(e==t)return!0;e=e.parentNode}return!1}function g(e,t){return e.indexOf(t)>-1}function b(e){return e.trim().split(/\s+/g)}function x(e,t,n){if(e.indexOf&&!n)return e.indexOf(t);for(var r=0;rn[t]}):r.sort()),r}function E(e,t){for(var n,r,i=t[0].toUpperCase()+t.slice(1),o=0;o1&&!n.firstMultiple?n.firstMultiple=L(t):1===i&&(n.firstMultiple=!1);var o=n.firstInput,a=n.firstMultiple,s=a?a.center:o.center,u=t.center=D(r);t.timeStamp=xe(),t.deltaTime=t.timeStamp-o.timeStamp,t.angle=F(s,u),t.distance=I(s,u),A(n,t),t.offsetDirection=B(t.deltaX,t.deltaY);var l=R(t.deltaTime,t.deltaX,t.deltaY);t.overallVelocityX=l.x,t.overallVelocityY=l.y,t.overallVelocity=be(l.x)>be(l.y)?l.x:l.y,t.scale=a?U(a.pointers,r):1,t.rotation=a?z(a.pointers,r):0,t.maxPointers=n.prevInput?t.pointers.length>n.prevInput.maxPointers?t.pointers.length:n.prevInput.maxPointers:t.pointers.length,C(n,t);var c=e.element;_(t.srcEvent.target,c)&&(c=t.srcEvent.target),t.target=c}function A(e,t){var n=t.center,r=e.offsetDelta||{},i=e.prevDelta||{},o=e.prevInput||{};t.eventType!==De&&o.eventType!==Be||(i=e.prevDelta={x:o.deltaX||0,y:o.deltaY||0},r=e.offsetDelta={x:n.x,y:n.y}),t.deltaX=i.x+(n.x-r.x),t.deltaY=i.y+(n.y-r.y)}function C(e,t){var n,r,i,o,a=e.lastInterval||t,u=t.timeStamp-a.timeStamp;if(t.eventType!=Ie&&(u>Le||a.velocity===s)){var l=t.deltaX-a.deltaX,c=t.deltaY-a.deltaY,f=R(u,l,c);r=f.x,i=f.y,n=be(f.x)>be(f.y)?f.x:f.y,o=B(l,c),e.lastInterval=t}else n=a.velocity,r=a.velocityX,i=a.velocityY,o=a.direction;t.velocity=n,t.velocityX=r,t.velocityY=i,t.direction=o}function L(e){for(var t=[],n=0;ni;)n+=e[i].clientX,r+=e[i].clientY,i++;return{x:ge(n/t),y:ge(r/t)}}function R(e,t,n){return{x:t/e||0,y:n/e||0}}function B(e,t){return e===t?Fe:be(e)>=be(t)?0>e?ze:Ue:0>t?Ne:He}function I(e,t,n){n||(n=Ge);var r=t[n[0]]-e[n[0]],i=t[n[1]]-e[n[1]];return Math.sqrt(r*r+i*i)}function F(e,t,n){n||(n=Ge);var r=t[n[0]]-e[n[0]],i=t[n[1]]-e[n[1]];return 180*Math.atan2(i,r)/Math.PI}function z(e,t){return F(t[1],t[0],Xe)+F(e[1],e[0],Xe)}function U(e,t){return I(t[0],t[1],Xe)/I(e[0],e[1],Xe)}function N(){this.evEl=Ye,this.evWin=Ke,this.pressed=!1,P.apply(this,arguments)}function H(){this.evEl=Qe,this.evWin=et,P.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function W(){this.evTarget=nt,this.evWin=rt,this.started=!1,P.apply(this,arguments)}function q(e,t){var n=w(e.touches),r=w(e.changedTouches);return t&(Be|Ie)&&(n=M(n.concat(r),"identifier",!0)),[n,r]}function V(){this.evTarget=ot,this.targetIds={},P.apply(this,arguments)}function G(e,t){var n=w(e.touches),r=this.targetIds;if(t&(De|Re)&&1===n.length)return r[n[0].identifier]=!0,[n,n];var i,o,a=w(e.changedTouches),s=[],u=this.target;if(o=n.filter(function(e){return _(e.target,u)}),t===De)for(i=0;i-1&&r.splice(e,1)};setTimeout(i,at)}}function K(e){for(var t=e.srcEvent.clientX,n=e.srcEvent.clientY,r=0;r=o&&st>=a)return!0}return!1}function J(e,t){this.manager=e,this.set(t)}function $(e){if(g(e,pt))return pt;var t=g(e,dt),n=g(e,vt);return t&&n?pt:t||n?t?dt:vt:g(e,ht)?ht:ft}function Q(){if(!lt)return!1;var e={},t=i.CSS&&i.CSS.supports;return["auto","manipulation","pan-y","pan-x","pan-x pan-y","none"].forEach(function(n){e[n]=t?i.CSS.supports("touch-action",n):!0}),e}function ee(e){this.options=ve({},this.defaults,e||{}),this.id=O(),this.manager=null,this.options.enable=v(this.options.enable,!0),this.state=mt,this.simultaneous={},this.requireFail=[]}function te(e){return e&wt?"cancel":e&bt?"end":e>?"move":e&_t?"start":""}function ne(e){return e==He?"down":e==Ne?"up":e==ze?"left":e==Ue?"right":""}function re(e,t){var n=t.manager;return n?n.get(e):e}function ie(){ee.apply(this,arguments)}function oe(){ie.apply(this,arguments),this.pX=null,this.pY=null}function ae(){ie.apply(this,arguments)}function se(){ee.apply(this,arguments),this._timer=null,this._input=null}function ue(){ie.apply(this,arguments)}function le(){ie.apply(this,arguments)}function ce(){ee.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function fe(e,t){return t=t||{},t.recognizers=v(t.recognizers,fe.defaults.preset),new he(e,t)}function he(e,t){this.options=ve({},fe.defaults,t||{}),this.options.inputTarget=this.options.inputTarget||e,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=e,this.input=T(this),this.touchAction=new J(this,this.options.touchAction),pe(this,!0),c(this.options.recognizers,function(e){var t=this.add(new e[0](e[1]));e[2]&&t.recognizeWith(e[2]),e[3]&&t.requireFailure(e[3])},this)}function pe(e,t){var n=e.element;if(n.style){var r;c(e.options.cssProps,function(i,o){r=E(n.style,o),t?(e.oldCssProps[r]=n.style[r],n.style[r]=i):n.style[r]=e.oldCssProps[r]||""}),t||(e.oldCssProps={})}}function de(e,t){var n=o.createEvent("Event");n.initEvent(e,!0,!0),n.gesture=t,t.target.dispatchEvent(n)}var ve,ye=["","webkit","Moz","MS","ms","o"],me=o.createElement("div"),_e="function",ge=Math.round,be=Math.abs,xe=Date.now;ve="function"!=typeof Object.assign?function(e){if(e===s||null===e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=1;ns&&(t.push(e),s=t.length-1):i&(Be|Ie)&&(n=!0),0>s||(t[s]=e,this.callback(this.manager,i,{pointers:t,changedPointers:[e],pointerType:o,srcEvent:e}),n&&t.splice(s,1))}});var tt={touchstart:De,touchmove:Re,touchend:Be,touchcancel:Ie},nt="touchstart",rt="touchstart touchmove touchend touchcancel";h(W,P,{handler:function(e){var t=tt[e.type];if(t===De&&(this.started=!0),this.started){var n=q.call(this,e,t);t&(Be|Ie)&&n[0].length-n[1].length===0&&(this.started=!1),this.callback(this.manager,t,{pointers:n[0],changedPointers:n[1],pointerType:je,srcEvent:e})}}});var it={touchstart:De,touchmove:Re,touchend:Be,touchcancel:Ie},ot="touchstart touchmove touchend touchcancel";h(V,P,{handler:function(e){var t=it[e.type],n=G.call(this,e,t);n&&this.callback(this.manager,t,{pointers:n[0],changedPointers:n[1],pointerType:je,srcEvent:e})}});var at=2500,st=25;h(X,P,{handler:function(e,t,n){var r=n.pointerType==je,i=n.pointerType==Ae;if(!(i&&n.sourceCapabilities&&n.sourceCapabilities.firesTouchEvents)){if(r)Z.call(this,t,n);else if(i&&K.call(this,n))return;this.callback(e,t,n)}},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var ut=E(me.style,"touchAction"),lt=ut!==s,ct="compute",ft="auto",ht="manipulation",pt="none",dt="pan-x",vt="pan-y",yt=Q();J.prototype={set:function(e){e==ct&&(e=this.compute()),lt&&this.manager.element.style&&yt[e]&&(this.manager.element.style[ut]=e),this.actions=e.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction)},compute:function(){var e=[];return c(this.manager.recognizers,function(t){d(t.options.enable,[t])&&(e=e.concat(t.getTouchAction()))}),$(e.join(" "))},preventDefaults:function(e){var t=e.srcEvent,n=e.offsetDirection;if(this.manager.session.prevented)return void t.preventDefault();var r=this.actions,i=g(r,pt)&&!yt[pt],o=g(r,vt)&&!yt[vt],a=g(r,dt)&&!yt[dt];if(i){var s=1===e.pointers.length,u=e.distance<2,l=e.deltaTime<250;if(s&&u&&l)return}return a&&o?void 0:i||o&&n&We||a&&n&qe?this.preventSrc(t):void 0},preventSrc:function(e){this.manager.session.prevented=!0,e.preventDefault()}};var mt=1,_t=2,gt=4,bt=8,xt=bt,wt=16,Mt=32;ee.prototype={defaults:{},set:function(e){return ve(this.options,e),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(e){if(l(e,"recognizeWith",this))return this;var t=this.simultaneous;return e=re(e,this),t[e.id]||(t[e.id]=e,e.recognizeWith(this)),this},dropRecognizeWith:function(e){return l(e,"dropRecognizeWith",this)?this:(e=re(e,this),delete this.simultaneous[e.id],this)},requireFailure:function(e){if(l(e,"requireFailure",this))return this;var t=this.requireFail;return e=re(e,this),-1===x(t,e)&&(t.push(e),e.requireFailure(this)),this},dropRequireFailure:function(e){if(l(e,"dropRequireFailure",this))return this;e=re(e,this);var t=x(this.requireFail,e);return t>-1&&this.requireFail.splice(t,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(e){return!!this.simultaneous[e.id]},emit:function(e){function t(t){n.manager.emit(t,e)}var n=this,r=this.state;bt>r&&t(n.options.event+te(r)),t(n.options.event),e.additionalEvent&&t(e.additionalEvent),r>=bt&&t(n.options.event+te(r))},tryEmit:function(e){return this.canEmit()?this.emit(e):void(this.state=Mt)},canEmit:function(){for(var e=0;eo?ze:Ue,n=o!=this.pX,r=Math.abs(e.deltaX)):(i=0===a?Fe:0>a?Ne:He,n=a!=this.pY,r=Math.abs(e.deltaY))),e.direction=i,n&&r>t.threshold&&i&t.direction},attrTest:function(e){return ie.prototype.attrTest.call(this,e)&&(this.state&_t||!(this.state&_t)&&this.directionTest(e))},emit:function(e){this.pX=e.deltaX,this.pY=e.deltaY;var t=ne(e.direction);t&&(e.additionalEvent=this.options.event+t),this._super.emit.call(this,e)}}),h(ae,ie,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[pt]},attrTest:function(e){return this._super.attrTest.call(this,e)&&(Math.abs(e.scale-1)>this.options.threshold||this.state&_t)},emit:function(e){if(1!==e.scale){var t=e.scale<1?"in":"out";e.additionalEvent=this.options.event+t}this._super.emit.call(this,e)}}),h(se,ee,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return[ft]},process:function(e){var t=this.options,n=e.pointers.length===t.pointers,r=e.distancet.time;if(this._input=e,!r||!n||e.eventType&(Be|Ie)&&!i)this.reset();else if(e.eventType&De)this.reset(),this._timer=u(function(){this.state=xt,this.tryEmit()},t.time,this);else if(e.eventType&Be)return xt;return Mt},reset:function(){clearTimeout(this._timer)},emit:function(e){this.state===xt&&(e&&e.eventType&Be?this.manager.emit(this.options.event+"up",e):(this._input.timeStamp=xe(),this.manager.emit(this.options.event,this._input)))}}),h(ue,ie,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[pt]},attrTest:function(e){return this._super.attrTest.call(this,e)&&(Math.abs(e.rotation)>this.options.threshold||this.state&_t)}}),h(le,ie,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:We|qe,pointers:1},getTouchAction:function(){return oe.prototype.getTouchAction.call(this)},attrTest:function(e){var t,n=this.options.direction;return n&(We|qe)?t=e.overallVelocity:n&We?t=e.overallVelocityX:n&qe&&(t=e.overallVelocityY),this._super.attrTest.call(this,e)&&n&e.offsetDirection&&e.distance>this.options.threshold&&e.maxPointers==this.options.pointers&&be(t)>this.options.velocity&&e.eventType&Be},emit:function(e){var t=ne(e.offsetDirection);t&&this.manager.emit(this.options.event+t,e),this.manager.emit(this.options.event,e)}}),h(ce,ee,{defaults:{event:"tap",pointers:1,taps:1, -interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[ht]},process:function(e){var t=this.options,n=e.pointers.length===t.pointers,r=e.distance0){var i=n.getCenter(),o=new v["default"].Vector3(i[0],0,i[1]).sub(t.position).length();if(o>e._options.distance)return!1}return n.getMesh()||n.requestTileAsync(),!0})}}},{key:"_divide",value:function(e){for(var t,n,r=0;r!=e.length;)t=e[r],n=t.getQuadcode(),t.length!==this._maxLOD&&this._screenSpaceError(t)?(e.splice(r,1),e.push(this._requestTile(n+"0",this)),e.push(this._requestTile(n+"1",this)),e.push(this._requestTile(n+"2",this)),e.push(this._requestTile(n+"3",this))):r++}},{key:"_screenSpaceError",value:function(e){var t=this._minLOD,n=this._maxLOD,r=e.getQuadcode(),i=this._world.getCamera(),o=3;if(r.length===n)return!1;if(r.length1}},{key:"_removeTiles",value:function(){if(this._tiles&&this._tiles.children){for(var e=this._tiles.children.length-1;e>=0;e--)this._tiles.remove(this._tiles.children[e]);if(this._tilesPicking&&this._tilesPicking.children)for(var e=this._tilesPicking.children.length-1;e>=0;e--)this._tilesPicking.remove(this._tilesPicking.children[e])}}},{key:"_createTile",value:function(e,t){}},{key:"_requestTile",value:function(e,t){var n=this._tileCache.getTile(e);return n||(n=this._createTile(e,t),this._tileCache.setTile(e,n)),n}},{key:"_destroyTile",value:function(e){this._tiles.remove(e.getMesh()),e.destroy()}},{key:"destroy",value:function(){if(this._tiles.children)for(var e=this._tiles.children.length-1;e>=0;e--)this._tiles.remove(this._tiles.children[e]);if(this.removeFromPicking(this._tilesPicking),this._tilesPicking.children)for(var e=this._tilesPicking.children.length-1;e>=0;e--)this._tilesPicking.remove(this._tilesPicking.children[e]);this._tileCache.destroy(),this._tileCache=null,this._tiles=null,this._tilesPicking=null,this._frustum=null,s(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}]),t}(l["default"]);t["default"]=y,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n=t)&&r(this,"max",1/0);var n=e.length||i;"function"!=typeof n&&(n=i),r(this,"lengthCalculator",n),r(this,"allowStale",e.stale||!1),r(this,"maxAge",e.maxAge||0),r(this,"dispose",e.dispose),this.reset()}function a(e,t,n,i){var o=n.value;u(e,o)&&(c(e,n),r(e,"allowStale")||(o=void 0)),o&&t.call(i,o.value,o.key,e)}function s(e,t,n){var i=r(e,"cache").get(t);if(i){var o=i.value;u(e,o)?(c(e,i),r(e,"allowStale")||(o=void 0)):n&&r(e,"lruList").unshiftNode(i),o&&(o=o.value)}return o}function u(e,t){if(!t||!t.maxAge&&!r(e,"maxAge"))return!1;var n=!1,i=Date.now()-t.now;return n=t.maxAge?i>t.maxAge:r(e,"maxAge")&&i>r(e,"maxAge")}function l(e){if(r(e,"length")>r(e,"max"))for(var t=r(e,"lruList").tail;r(e,"length")>r(e,"max")&&null!==t;){var n=t.prev;c(e,t),t=n}}function c(e,t){if(t){var n=t.value;r(e,"dispose")&&r(e,"dispose").call(this,n.key,n.value),r(e,"length",r(e,"length")-n.length),r(e,"cache")["delete"](n.key),r(e,"lruList").removeNode(t)}}function f(e,t,n,r,i){this.key=e,this.value=t,this.length=n,this.now=r,this.maxAge=i||0}e.exports=o;var h,p=n(46),d=n(49),v=n(52),y={},m="function"==typeof Symbol;h=m?function(e){return Symbol["for"](e)}:function(e){return"_"+e},Object.defineProperty(o.prototype,"max",{set:function(e){(!e||"number"!=typeof e||0>=e)&&(e=1/0),r(this,"max",e),l(this)},get:function(){return r(this,"max")},enumerable:!0}),Object.defineProperty(o.prototype,"allowStale",{set:function(e){r(this,"allowStale",!!e)},get:function(){return r(this,"allowStale")},enumerable:!0}),Object.defineProperty(o.prototype,"maxAge",{set:function(e){(!e||"number"!=typeof e||0>e)&&(e=0),r(this,"maxAge",e),l(this)},get:function(){return r(this,"maxAge")},enumerable:!0}),Object.defineProperty(o.prototype,"lengthCalculator",{set:function(e){"function"!=typeof e&&(e=i),e!==r(this,"lengthCalculator")&&(r(this,"lengthCalculator",e),r(this,"length",0),r(this,"lruList").forEach(function(e){e.length=r(this,"lengthCalculator").call(this,e.value,e.key),r(this,"length",r(this,"length")+e.length)},this)),l(this)},get:function(){return r(this,"lengthCalculator")},enumerable:!0}),Object.defineProperty(o.prototype,"length",{get:function(){return r(this,"length")},enumerable:!0}),Object.defineProperty(o.prototype,"itemCount",{get:function(){return r(this,"lruList").length},enumerable:!0}),o.prototype.rforEach=function(e,t){t=t||this;for(var n=r(this,"lruList").tail;null!==n;){var i=n.prev;a(this,e,n,t),n=i}},o.prototype.forEach=function(e,t){t=t||this;for(var n=r(this,"lruList").head;null!==n;){var i=n.next;a(this,e,n,t),n=i}},o.prototype.keys=function(){return r(this,"lruList").toArray().map(function(e){return e.key},this)},o.prototype.values=function(){return r(this,"lruList").toArray().map(function(e){return e.value},this)},o.prototype.reset=function(){r(this,"dispose")&&r(this,"lruList")&&r(this,"lruList").length&&r(this,"lruList").forEach(function(e){r(this,"dispose").call(this,e.key,e.value)},this),r(this,"cache",new p),r(this,"lruList",new v),r(this,"length",0)},o.prototype.dump=function(){return r(this,"lruList").map(function(e){return u(this,e)?void 0:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}},this).toArray().filter(function(e){return e})},o.prototype.dumpLru=function(){return r(this,"lruList")},o.prototype.inspect=function(e,t){var n="LRUCache {",o=!1,a=r(this,"allowStale");a&&(n+="\n allowStale: true",o=!0);var s=r(this,"max");s&&s!==1/0&&(o&&(n+=","),n+="\n max: "+d.inspect(s,t),o=!0);var l=r(this,"maxAge");l&&(o&&(n+=","),n+="\n maxAge: "+d.inspect(l,t),o=!0);var c=r(this,"lengthCalculator");c&&c!==i&&(o&&(n+=","),n+="\n length: "+d.inspect(r(this,"length"),t),o=!0);var f=!1;return r(this,"lruList").forEach(function(e){f?n+=",\n ":(o&&(n+=",\n"),f=!0,n+="\n ");var r=d.inspect(e.key).split("\n").join("\n "),a={value:e.value};e.maxAge!==l&&(a.maxAge=e.maxAge),c!==i&&(a.length=e.length),u(this,e)&&(a.stale=!0),a=d.inspect(a,t).split("\n").join("\n "),n+=r+" => "+a}),(f||o)&&(n+="\n"),n+="}"},o.prototype.set=function(e,t,n){n=n||r(this,"maxAge");var i=n?Date.now():0,o=r(this,"lengthCalculator").call(this,t,e);if(r(this,"cache").has(e)){if(o>r(this,"max"))return c(this,r(this,"cache").get(e)),!1;var a=r(this,"cache").get(e),s=a.value;return r(this,"dispose")&&r(this,"dispose").call(this,e,s.value),s.now=i,s.maxAge=n,s.value=t,r(this,"length",r(this,"length")+(o-s.length)),s.length=o,this.get(e),l(this),!0}var u=new f(e,t,o,i,n);return u.length>r(this,"max")?(r(this,"dispose")&&r(this,"dispose").call(this,e,t),!1):(r(this,"length",r(this,"length")+u.length),r(this,"lruList").unshift(u),r(this,"cache").set(e,r(this,"lruList").head),l(this),!0)},o.prototype.has=function(e){if(!r(this,"cache").has(e))return!1;var t=r(this,"cache").get(e).value;return!u(this,t)},o.prototype.get=function(e){return s(this,e,!0)},o.prototype.peek=function(e){return s(this,e,!1)},o.prototype.pop=function(){var e=r(this,"lruList").tail;return e?(c(this,e),e.value):null},o.prototype.del=function(e){c(this,r(this,"cache").get(e))},o.prototype.load=function(e){this.reset();for(var t=Date.now(),n=e.length-1;n>=0;n--){var r=e[n],i=r.e||0;if(0===i)this.set(r.k,r.v);else{var o=i-t;o>0&&this.set(r.k,r.v,o)}}},o.prototype.prune=function(){var e=this;r(this,"cache").forEach(function(t,n){s(e,n,!1)})}},function(e,t,n){(function(t){"pseudomap"===t.env.npm_package_name&&"test"===t.env.npm_lifecycle_script&&(t.env.TEST_PSEUDOMAP="true"),"function"!=typeof Map||t.env.TEST_PSEUDOMAP?e.exports=n(48):e.exports=Map}).call(t,n(47))},function(e,t){function n(){f&&l&&(f=!1,l.length?c=l.concat(c):h=-1,c.length&&r())}function r(){if(!f){var e=a(n);f=!0;for(var t=c.length;t;){for(l=c,c=[];++h1)for(var n=1;n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),v(n)?r.showHidden=n:n&&t._extend(r,n),x(r.showHidden)&&(r.showHidden=!1),x(r.depth)&&(r.depth=2),x(r.colors)&&(r.colors=!1),x(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),u(r,e,r.depth)}function o(e,t){var n=i.styles[t];return n?"["+i.colors[n][0]+"m"+e+"["+i.colors[n][1]+"m":e}function a(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function u(e,n,r){if(e.customInspect&&n&&k(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var i=n.inspect(r,e);return g(i)||(i=u(e,i,r)),i}var o=l(e,n);if(o)return o;var a=Object.keys(n),v=s(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),O(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return c(n);if(0===a.length){if(k(n)){var y=n.name?": "+n.name:"";return e.stylize("[Function"+y+"]","special")}if(w(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(E(n))return e.stylize(Date.prototype.toString.call(n),"date");if(O(n))return c(n)}var m="",_=!1,b=["{","}"];if(d(n)&&(_=!0,b=["[","]"]),k(n)){var x=n.name?": "+n.name:"";m=" [Function"+x+"]"}if(w(n)&&(m=" "+RegExp.prototype.toString.call(n)),E(n)&&(m=" "+Date.prototype.toUTCString.call(n)),O(n)&&(m=" "+c(n)),0===a.length&&(!_||0==n.length))return b[0]+m+b[1];if(0>r)return w(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special");e.seen.push(n);var M;return M=_?f(e,n,r,v,a):a.map(function(t){return h(e,n,r,v,t,_)}),e.seen.pop(),p(M,m,b)}function l(e,t){if(x(t))return e.stylize("undefined","undefined");if(g(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return _(t)?e.stylize(""+t,"number"):v(t)?e.stylize(""+t,"boolean"):y(t)?e.stylize("null","null"):void 0}function c(e){return"["+Error.prototype.toString.call(e)+"]"}function f(e,t,n,r,i){for(var o=[],a=0,s=t.length;s>a;++a)A(t,String(a))?o.push(h(e,t,n,r,String(a),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(h(e,t,n,r,i,!0))}),o}function h(e,t,n,r,i,o){var a,s,l;if(l=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},l.get?s=l.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):l.set&&(s=e.stylize("[Setter]","special")),A(r,i)||(a="["+i+"]"),s||(e.seen.indexOf(l.value)<0?(s=y(n)?u(e,l.value,null):u(e,l.value,n-1),s.indexOf("\n")>-1&&(s=o?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n"))):s=e.stylize("[Circular]","special")),x(a)){if(o&&i.match(/^\d+$/))return s;a=JSON.stringify(""+i),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function d(e){return Array.isArray(e)}function v(e){return"boolean"==typeof e}function y(e){return null===e}function m(e){return null==e}function _(e){return"number"==typeof e}function g(e){return"string"==typeof e}function b(e){return"symbol"==typeof e}function x(e){return void 0===e}function w(e){return M(e)&&"[object RegExp]"===T(e)}function M(e){return"object"==typeof e&&null!==e}function E(e){return M(e)&&"[object Date]"===T(e)}function O(e){return M(e)&&("[object Error]"===T(e)||e instanceof Error)}function k(e){return"function"==typeof e}function P(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function T(e){return Object.prototype.toString.call(e)}function j(e){return 10>e?"0"+e.toString(10):e.toString(10)}function S(){var e=new Date,t=[j(e.getHours()),j(e.getMinutes()),j(e.getSeconds())].join(":");return[e.getDate(),R[e.getMonth()],t].join(" ")}function A(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var C=/%[sdj%]/g;t.format=function(e){if(!g(e)){for(var t=[],n=0;n=o)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return e}}),s=r[n];o>n;s=r[++n])a+=y(s)||!M(s)?" "+s:" "+i(s);return a},t.deprecate=function(n,i){function o(){if(!a){if(r.throwDeprecation)throw new Error(i);r.traceDeprecation?console.trace(i):console.error(i),a=!0}return n.apply(this,arguments)}if(x(e.process))return function(){return t.deprecate(n,i).apply(this,arguments)};if(r.noDeprecation===!0)return n;var a=!1;return o};var L,D={};t.debuglog=function(e){if(x(L)&&(L=r.env.NODE_DEBUG||""),e=e.toUpperCase(),!D[e])if(new RegExp("\\b"+e+"\\b","i").test(L)){var n=r.pid;D[e]=function(){var r=t.format.apply(t,arguments);console.error("%s %d: %s",e,n,r)}}else D[e]=function(){};return D[e]},t.inspect=i,i.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},i.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=d,t.isBoolean=v,t.isNull=y,t.isNullOrUndefined=m,t.isNumber=_,t.isString=g,t.isSymbol=b,t.isUndefined=x,t.isRegExp=w,t.isObject=M,t.isDate=E,t.isError=O,t.isFunction=k,t.isPrimitive=P,t.isBuffer=n(50);var R=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];t.log=function(){console.log("%s - %s",S(),t.format.apply(t,arguments))},t.inherits=n(51),t._extend=function(e,t){if(!t||!M(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(t,function(){return this}(),n(47))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t){function n(e){var t=this;if(t instanceof n||(t=new n),t.tail=null,t.head=null,t.length=0,e&&"function"==typeof e.forEach)e.forEach(function(e){t.push(e)});else if(arguments.length>0)for(var r=0,i=arguments.length;i>r;r++)t.push(arguments[r]);return t}function r(e,t){e.tail=new o(t,e.tail,null,e),e.head||(e.head=e.tail),e.length++}function i(e,t){e.head=new o(t,null,e.head,e),e.tail||(e.tail=e.head),e.length++}function o(e,t,n,r){return this instanceof o?(this.list=r,this.value=e,t?(t.next=this,this.prev=t):this.prev=null,void(n?(n.prev=this,this.next=n):this.next=null)):new o(e,t,n,r)}e.exports=n,n.Node=o,n.create=n,n.prototype.removeNode=function(e){if(e.list!==this)throw new Error("removing node which does not belong to this list");var t=e.next,n=e.prev;t&&(t.prev=n),n&&(n.next=t),e===this.head&&(this.head=t),e===this.tail&&(this.tail=n),e.list.length--,e.next=null,e.prev=null,e.list=null},n.prototype.unshiftNode=function(e){if(e!==this.head){e.list&&e.list.removeNode(e);var t=this.head;e.list=this,e.next=t,t&&(t.prev=e),this.head=e,this.tail||(this.tail=e),this.length++}},n.prototype.pushNode=function(e){if(e!==this.tail){e.list&&e.list.removeNode(e);var t=this.tail;e.list=this,e.prev=t,t&&(t.next=e),this.tail=e,this.head||(this.head=e),this.length++}},n.prototype.push=function(){for(var e=0,t=arguments.length;t>e;e++)r(this,arguments[e]);return this.length},n.prototype.unshift=function(){for(var e=0,t=arguments.length;t>e;e++)i(this,arguments[e]);return this.length},n.prototype.pop=function(){if(this.tail){var e=this.tail.value;return this.tail=this.tail.prev,this.tail.next=null,this.length--,e}},n.prototype.shift=function(){if(this.head){var e=this.head.value;return this.head=this.head.next,this.head.prev=null,this.length--,e}},n.prototype.forEach=function(e,t){t=t||this;for(var n=this.head,r=0;null!==n;r++)e.call(t,n.value,r,this),n=n.next},n.prototype.forEachReverse=function(e,t){t=t||this;for(var n=this.tail,r=this.length-1;null!==n;r--)e.call(t,n.value,r,this),n=n.prev},n.prototype.get=function(e){for(var t=0,n=this.head;null!==n&&e>t;t++)n=n.next;return t===e&&null!==n?n.value:void 0},n.prototype.getReverse=function(e){for(var t=0,n=this.tail;null!==n&&e>t;t++)n=n.prev;return t===e&&null!==n?n.value:void 0},n.prototype.map=function(e,t){t=t||this;for(var r=new n,i=this.head;null!==i;)r.push(e.call(t,i.value,this)),i=i.next;return r},n.prototype.mapReverse=function(e,t){t=t||this;for(var r=new n,i=this.tail;null!==i;)r.push(e.call(t,i.value,this)),i=i.prev;return r},n.prototype.reduce=function(e,t){var n,r=this.head;if(arguments.length>1)n=t;else{if(!this.head)throw new TypeError("Reduce of empty list with no initial value");r=this.head.next,n=this.head.value}for(var i=0;null!==r;i++)n=e(n,r.value,i),r=r.next;return n},n.prototype.reduceReverse=function(e,t){var n,r=this.tail;if(arguments.length>1)n=t;else{if(!this.tail)throw new TypeError("Reduce of empty list with no initial value");r=this.tail.prev,n=this.tail.value}for(var i=this.length-1;null!==r;i--)n=e(n,r.value,i),r=r.prev;return n},n.prototype.toArray=function(){for(var e=new Array(this.length),t=0,n=this.head;null!==n;t++)e[t]=n.value,n=n.next;return e},n.prototype.toArrayReverse=function(){for(var e=new Array(this.length),t=0,n=this.tail;null!==n;t++)e[t]=n.value,n=n.prev;return e},n.prototype.slice=function(e,t){t=t||this.length,0>t&&(t+=this.length),e=e||0,0>e&&(e+=this.length);var r=new n;if(e>t||0>t)return r;0>e&&(e=0),t>this.length&&(t=this.length);for(var i=0,o=this.head;null!==o&&e>i;i++)o=o.next;for(;null!==o&&t>i;i++,o=o.next)r.push(o.value);return r},n.prototype.sliceReverse=function(e,t){t=t||this.length,0>t&&(t+=this.length),e=e||0,0>e&&(e+=this.length);var r=new n;if(e>t||0>t)return r;0>e&&(e=0),t>this.length&&(t=this.length);for(var i=this.length,o=this.tail;null!==o&&i>t;i--)o=o.prev;for(;null!==o&&i>e;i--,o=o.prev)r.push(o.value);return r},n.prototype.reverse=function(){for(var e=this.head,t=this.tail,n=e;null!==n;n=n.prev){var r=n.prev;n.prev=n.next,n.next=r}return this.head=t,this.tail=e,this}},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function"); -}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n0;i--){var o=1<0){var c=m["default"].mergeAttributes(a);this._setPolygonMesh(c,s),this.add(this._polygonMesh)}if(u.length>0){var h=m["default"].mergeAttributes(u);this._setPolylineMesh(h),this.add(this._polylineMesh)}if(l.length>0){var p=m["default"].mergeAttributes(l);this._setPointMesh(p),this.add(this._pointMesh)}return this._layers.forEach(function(e){e.clearBufferAttributes(),e.clearCoordinates()}),Promise.resolve()}}},{key:"_setPolygonMesh",value:function(e,t){var n=new THREE.BufferGeometry;n.addAttribute("position",new THREE.BufferAttribute(e.vertices,3)),n.addAttribute("normal",new THREE.BufferAttribute(e.normals,3)),n.addAttribute("color",new THREE.BufferAttribute(e.colours,3)),e.pickingIds&&n.addAttribute("pickingId",new THREE.BufferAttribute(e.pickingIds,1)),n.computeBoundingBox();var r="function"==typeof this._options.style?this._options.style(this._geojson.features[0]):this._options.style;r=(0,f["default"])({},v["default"].defaultStyle,r);var i;this._options.polygonMaterial&&this._options.polygonMaterial instanceof THREE.Material?i=this._options.polygonMaterial:this._world._environment._skybox?(i=new THREE.MeshStandardMaterial({vertexColors:THREE.VertexColors,side:THREE.BackSide,transparent:r.transparent,opacity:r.opacity,blending:r.blending}),i.roughness=1,i.metalness=.1,i.envMapIntensity=3,i.envMap=this._world._environment._skybox.getRenderTarget()):i=new THREE.MeshPhongMaterial({vertexColors:THREE.VertexColors,side:THREE.BackSide,transparent:r.transparent,opacity:r.opacity,blending:r.blending});var o;if("function"==typeof this._options.onPolygonMesh?o=this._options.onPolygonMesh(n,i):(o=new THREE.Mesh(n,i),o.castShadow=!0,o.receiveShadow=!0),t&&(i.depthWrite=!1,o.renderOrder=1),this._options.interactive&&this._pickingMesh){i=new g["default"],i.side=THREE.BackSide;var a=new THREE.Mesh(n,i);this._pickingMesh.add(a)}this._polygonMesh=o}},{key:"_setPolylineMesh",value:function(e){var t=new THREE.BufferGeometry;t.addAttribute("position",new THREE.BufferAttribute(e.vertices,3)),e.normals&&t.addAttribute("normal",new THREE.BufferAttribute(e.normals,3)),t.addAttribute("color",new THREE.BufferAttribute(e.colours,3)),e.pickingIds&&t.addAttribute("pickingId",new THREE.BufferAttribute(e.pickingIds,1)),t.computeBoundingBox();var n="function"==typeof this._options.style?this._options.style(this._geojson.features[0]):this._options.style;n=(0,f["default"])({},v["default"].defaultStyle,n);var r;r=this._options.polylineMaterial&&this._options.polylineMaterial instanceof THREE.Material?this._options.polylineMaterial:new THREE.LineBasicMaterial({vertexColors:THREE.VertexColors,linewidth:n.lineWidth,transparent:n.lineTransparent,opacity:n.lineOpacity,blending:n.lineBlending});var i;if("function"==typeof this._options.onPolylineMesh?i=this._options.onPolylineMesh(t,r):(i=new THREE.LineSegments(t,r),void 0!==n.lineRenderOrder&&(r.depthWrite=!1,i.renderOrder=n.lineRenderOrder),i.castShadow=!0),this._options.interactive&&this._pickingMesh){r=new g["default"],r.linewidth=n.lineWidth+r.linePadding;var o=new THREE.LineSegments(t,r);this._pickingMesh.add(o)}this._polylineMesh=i}},{key:"_setPointMesh",value:function(e){var t=new THREE.BufferGeometry;t.addAttribute("position",new THREE.BufferAttribute(e.vertices,3)),t.addAttribute("normal",new THREE.BufferAttribute(e.normals,3)),t.addAttribute("color",new THREE.BufferAttribute(e.colours,3)),e.pickingIds&&t.addAttribute("pickingId",new THREE.BufferAttribute(e.pickingIds,1)),t.computeBoundingBox();var n;this._options.pointMaterial&&this._options.pointMaterial instanceof THREE.Material?n=this._options.pointMaterial:this._world._environment._skybox?(n=new THREE.MeshStandardMaterial({vertexColors:THREE.VertexColors}),n.roughness=1,n.metalness=.1,n.envMapIntensity=3,n.envMap=this._world._environment._skybox.getRenderTarget()):n=new THREE.MeshPhongMaterial({vertexColors:THREE.VertexColors});var r;if("function"==typeof this._options.onPointMesh?r=this._options.onPointMesh(t,n):(r=new THREE.Mesh(t,n),r.castShadow=!0),this._options.interactive&&this._pickingMesh){n=new g["default"];var i=new THREE.Mesh(t,n);this._pickingMesh.add(i)}this._pointMesh=r}},{key:"_featureToLayer",value:function(e,t){var n=e.geometry,r=n.coordinates?n.coordinates:null;return r&&n?"Polygon"===n.type||"MultiPolygon"===n.type?("function"==typeof this._options.polygonMaterial&&(t.geometry=this._options.polygonMaterial(e)),"function"==typeof this._options.onPolygonMesh&&(t.onMesh=this._options.onPolygonMesh),"function"==typeof this._options.onPolygonBufferAttributes&&(t.onBufferAttributes=this._options.onPolygonBufferAttributes),new x["default"](r,t)):"LineString"===n.type||"MultiLineString"===n.type?("function"==typeof this._options.lineMaterial&&(t.geometry=this._options.lineMaterial(e)),"function"==typeof this._options.onPolylineMesh&&(t.onMesh=this._options.onPolylineMesh),"function"==typeof this._options.onPolylineBufferAttributes&&(t.onBufferAttributes=this._options.onPolylineBufferAttributes),new M["default"](r,t)):"Point"===n.type||"MultiPoint"===n.type?("function"==typeof this._options.pointGeometry&&(t.geometry=this._options.pointGeometry(e)),"function"==typeof this._options.pointMaterial&&(t.geometry=this._options.pointMaterial(e)),"function"==typeof this._options.onPointMesh&&(t.onMesh=this._options.onPointMesh),new O["default"](r,t)):void 0:void 0}},{key:"_abortRequest",value:function(){this._request&&this._request.abort()}},{key:"destroy",value:function(){this._abortRequest(),this._request=null,this._geojson=null,this._pickingMesh&&(this._pickingMesh=null),this._polygonMesh&&(this._polygonMesh=null),this._polylineMesh&&(this._polylineMesh=null),this._pointMesh&&(this._pointMesh=null),s(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}]),t}(l["default"]);t["default"]=k;var P=function(e,t){return new k(e,t)};t.geoJSONLayer=P},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n-1&&this._layers.splice(t,1),this._world.removeLayer(e)}},{key:"_onAdd",value:function(e){}},{key:"destroy",value:function(){if(this._layers){for(var e=0;e0;)self._completeHandlers.shift()(e)}function success(resp){var type=o.type||resp&&setType(resp.getResponseHeader("Content-Type"));resp="jsonp"!==type?self.request:resp;var filteredResponse=globalSetupOptions.dataFilter(resp.responseText,type),r=filteredResponse;try{resp.responseText=r}catch(e){}if(r)switch(type){case"json":try{resp=context.JSON?context.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r;break;case"xml":resp=resp.responseXML&&resp.responseXML.parseError&&resp.responseXML.parseError.errorCode&&resp.responseXML.parseError.reason?null:resp.responseXML}for(self._responseArgs.resp=resp,self._fulfilled=!0,fn(resp),self._successHandler(resp);self._fulfillmentHandlers.length>0;)resp=self._fulfillmentHandlers.shift()(resp);complete(resp)}function timedOut(){self._timedOut=!0,self.request.abort()}function error(e,t,n){for(e=self.request,self._responseArgs.resp=e,self._responseArgs.msg=t,self._responseArgs.t=n,self._erred=!0;self._errorHandlers.length>0;)self._errorHandlers.shift()(e,t,n);complete(e)}this.url="string"==typeof o?o:o.url,this.timeout=null,this._fulfilled=!1,this._successHandler=function(){},this._fulfillmentHandlers=[],this._errorHandlers=[],this._completeHandlers=[],this._erred=!1,this._responseArgs={};var self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){timedOut()},o.timeout)),o.success&&(this._successHandler=function(){o.success.apply(o,arguments)}),o.error&&this._errorHandlers.push(function(){o.error.apply(o,arguments)}),o.complete&&this._completeHandlers.push(function(){o.complete.apply(o,arguments)}),this.request=getRequest.call(this,success,error)}function reqwest(e,t){return new Reqwest(e,t)}function normalize(e){return e?e.replace(/\r?\n/g,"\r\n"):""}function serial(e,t){var n,r,i,o,a=e.name,s=e.tagName.toLowerCase(),u=function(e){e&&!e.disabled&&t(a,normalize(e.attributes.value&&e.attributes.value.specified?e.value:e.text))};if(!e.disabled&&a)switch(s){case"input":/reset|button|image|file/i.test(e.type)||(n=/checkbox/i.test(e.type),r=/radio/i.test(e.type),i=e.value,(!(n||r)||e.checked)&&t(a,normalize(n&&""===i?"on":i)));break;case"textarea":t(a,normalize(e.value));break;case"select":if("select-one"===e.type.toLowerCase())u(e.selectedIndex>=0?e.options[e.selectedIndex]:null);else for(o=0;e.length&&oa;a++)n.vertices.push(e[i][o][a]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},l=function(e,t,n){var r=(0,h["default"])(e,t,n),o=[];for(i=0,il=r.length;in;){var i=n+r>>>1;e[i]e?~e:e],o=0,a=r.length;a>o;++o)t.push(n=r[o].slice()),c(n,o);0>e&&i(t,a)}function o(e){return e=e.slice(),c(e,0),e}function a(e){for(var t=[],n=0,i=e.length;i>n;++n)r(e[n],t);return t.length<2&&t.push(t[0].slice()),t}function s(e){for(var t=a(e);t.length<4;)t.push(t[0].slice());return t}function u(e){return e.map(s)}function l(e){var t=e.type;return"GeometryCollection"===t?{type:t,geometries:e.geometries.map(l)}:t in h?{type:t,coordinates:h[t](e)}:null}var c=n(e.transform),f=e.arcs,h={Point:function(e){return o(e.coordinates)},MultiPoint:function(e){return e.coordinates.map(o)},LineString:function(e){return a(e.arcs)},MultiLineString:function(e){return e.arcs.map(a)},Polygon:function(e){return u(e.arcs)},MultiPolygon:function(e){return e.arcs.map(u)}};return l(t)}function l(e,t){function n(t){var n,r=e.arcs[0>t?~t:t],i=r[0];return e.transform?(n=[0,0],r.forEach(function(e){n[0]+=e[0],n[1]+=e[1]})):n=r[r.length-1],0>t?[n,i]:[i,n]}function r(e,t){for(var n in e){var r=e[n];delete t[r.start],delete r.start,delete r.end,r.forEach(function(e){i[0>e?~e:e]=1}),s.push(r)}}var i={},o={},a={},s=[],u=-1;return t.forEach(function(n,r){var i,o=e.arcs[0>n?~n:n];o.length<3&&!o[1][0]&&!o[1][1]&&(i=t[++u],t[u]=n,t[r]=i)}),t.forEach(function(e){var t,r,i=n(e),s=i[0],u=i[1];if(t=a[s])if(delete a[t.end],t.push(e),t.end=u,r=o[u]){delete o[r.start];var l=r===t?t:t.concat(r);o[l.start=t.start]=a[l.end=r.end]=l}else o[t.start]=a[t.end]=t;else if(t=o[u])if(delete o[t.start],t.unshift(e),t.start=s,r=a[s]){delete a[r.end];var c=r===t?t:r.concat(t);o[c.start=r.start]=a[c.end=t.end]=c}else o[t.start]=a[t.end]=t;else t=[e],o[t.start=s]=a[t.end=u]=t}),r(a,o),r(o,a),t.forEach(function(e){i[0>e?~e:e]||s.push([e])}),s}function c(e){return u(e,f.apply(this,arguments))}function f(e,t,n){function r(e){var t=0>e?~e:e;(c[t]||(c[t]=[])).push({i:e,g:u})}function i(e){e.forEach(r)}function o(e){e.forEach(i)}function a(e){"GeometryCollection"===e.type?e.geometries.forEach(a):e.type in f&&(u=e,f[e.type](e.arcs))}var s=[];if(arguments.length>1){var u,c=[],f={LineString:i,MultiLineString:o,Polygon:o,MultiPolygon:function(e){e.forEach(o)}};a(t),c.forEach(arguments.length<3?function(e){s.push(e[0].i)}:function(e){n(e[0].g,e[e.length-1].g)&&s.push(e[0].i)})}else for(var h=0,p=e.arcs.length;p>h;++h)s.push(h);return{type:"MultiLineString",arcs:l(e,s)}}function h(e){var t=e[0],n=e[1],r=e[2];return Math.abs((t[0]-r[0])*(n[1]-t[1])-(t[0]-n[0])*(r[1]-t[1]))}function p(e){for(var t,n=-1,r=e.length,i=e[r-1],o=0;++nt?~t:t]||(i[t]=[])).push(e)})}),o.push(e)}function r(t){return Math.abs(p(u(e,{type:"Polygon",arcs:[t]}).coordinates[0]))}var i={},o=[],a=[];return t.forEach(function(e){"Polygon"===e.type?n(e.arcs):"MultiPolygon"===e.type&&e.arcs.forEach(n)}),o.forEach(function(e){if(!e._){var t=[],n=[e];for(e._=1,a.push(t);e=n.pop();)t.push(e),e.forEach(function(e){e.forEach(function(e){i[0>e?~e:e].forEach(function(e){e._||(e._=1,n.push(e))})})})}}),o.forEach(function(e){delete e._}),{type:"MultiPolygon",arcs:a.map(function(t){var n,o=[];if(t.forEach(function(e){e.forEach(function(e){e.forEach(function(e){i[0>e?~e:e].length<2&&o.push(e)})})}),o=l(e,o),(n=o.length)>1)for(var a,s,u=1,c=r(o[0]);n>u;++u)(a=r(o[u]))>c&&(s=o[0],o[0]=o[u],o[u]=s,c=a);return o})}}function y(e){function t(e,t){e.forEach(function(e){0>e&&(e=~e);var n=i[e];n?n.push(t):i[e]=[t]})}function n(e,n){e.forEach(function(e){t(e,n)})}function r(e,t){"GeometryCollection"===e.type?e.geometries.forEach(function(e){r(e,t)}):e.type in s&&s[e.type](e.arcs,t)}var i={},a=e.map(function(){return[]}),s={LineString:t,MultiLineString:n,Polygon:n,MultiPolygon:function(e,t){e.forEach(function(e){n(e,t)})}};e.forEach(r);for(var u in i)for(var l=i[u],c=l.length,f=0;c>f;++f)for(var h=f+1;c>h;++h){var p,d=l[f],v=l[h];(p=a[d])[u=o(p,v)]!==v&&p.splice(u,0,v),(p=a[v])[u=o(p,d)]!==d&&p.splice(u,0,d)}return a}function m(e,t){return e[1][2]-t[1][2]}function _(){function e(e,t){for(;t>0;){var n=(t+1>>1)-1,i=r[n];if(m(e,i)>=0)break;r[i._=t]=i,r[e._=t=n]=e}}function t(e,t){for(;;){var n=t+1<<1,o=n-1,a=t,s=r[a];if(i>o&&m(r[o],s)<0&&(s=r[a=o]),i>n&&m(r[n],s)<0&&(s=r[a=n]),a===t)break;r[s._=t]=s,r[e._=t=a]=e}}var n={},r=[],i=0;return n.push=function(t){return e(r[t._=i]=t,i++),i},n.pop=function(){if(!(0>=i)){var e,n=r[0];return--i>0&&(e=r[i],t(r[e._=0]=e,0)),n}},n.remove=function(n){var o,a=n._;if(r[a]===n)return a!==--i&&(o=r[i],(m(o,n)<0?e:t)(r[o._=a]=o,a)),a},n}function g(e,t){function i(e){s.remove(e),e[1][2]=t(e),s.push(e)}var o=n(e.transform),a=r(e.transform),s=_();return t||(t=h),e.arcs.forEach(function(e){var n,r,u,l,c=[],f=0;for(r=0,u=e.length;u>r;++r)l=e[r],o(e[r]=[l[0],l[1],1/0],r);for(r=1,u=e.length-1;u>r;++r)n=e.slice(r-1,r+2),n[1][2]=t(n),c.push(n),s.push(n);for(r=0,u=c.length;u>r;++r)n=c[r],n.previous=c[r-1],n.next=c[r+1];for(;n=s.pop();){var h=n.previous,p=n.next;n[1][2]80*n){l=h=e[0],f=p=e[1];for(var m=n;a>m;m+=n)d=e[m],v=e[m+1],l>d&&(l=d),f>v&&(f=v),d>h&&(h=d),v>p&&(p=v);y=Math.max(h-l,p-f)}return o(s,u,n,l,f,y),u}function r(e,t,n,r,i){var o,a;if(i===S(e,t,n,r)>0)for(o=t;n>o;o+=r)a=P(o,e[o],e[o+1],a);else for(o=n-r;o>=t;o-=r)a=P(o,e[o],e[o+1],a);return a&&x(a,a.next)&&(T(a),a=a.next),a}function i(e,t){if(!e)return e;t||(t=e);var n,r=e;do if(n=!1,r.steiner||!x(r,r.next)&&0!==b(r.prev,r,r.next))r=r.next;else{if(T(r),r=t=r.prev,r===r.next)return null;n=!0}while(n||r!==t);return t}function o(e,t,n,r,c,f,h){if(e){!h&&f&&d(e,r,c,f);for(var p,v,y=e;e.prev!==e.next;)if(p=e.prev,v=e.next,f?s(e,r,c,f):a(e))t.push(p.i/n),t.push(e.i/n),t.push(v.i/n),T(e),e=v.next,y=v.next;else if(e=v,e===y){h?1===h?(e=u(e,t,n),o(e,t,n,r,c,f,2)):2===h&&l(e,t,n,r,c,f):o(i(e),t,n,r,c,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(b(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(_(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&b(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function s(e,t,n,r){var i=e.prev,o=e,a=e.next;if(b(i,o,a)>=0)return!1;for(var s=i.xo.x?i.x>a.x?i.x:a.x:o.x>a.x?o.x:a.x,c=i.y>o.y?i.y>a.y?i.y:a.y:o.y>a.y?o.y:a.y,f=y(s,u,t,n,r),h=y(l,c,t,n,r),p=e.nextZ;p&&p.z<=h;){if(p!==e.prev&&p!==e.next&&_(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&b(p.prev,p,p.next)>=0)return!1;p=p.nextZ}for(p=e.prevZ;p&&p.z>=f;){if(p!==e.prev&&p!==e.next&&_(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&b(p.prev,p,p.next)>=0)return!1;p=p.prevZ}return!0}function u(e,t,n){var r=e;do{var i=r.prev,o=r.next.next;!x(i,o)&&w(i,r,r.next,o)&&E(i,o)&&E(o,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(o.i/n),T(r),T(r.next),r=e=o),r=r.next}while(r!==e);return r}function l(e,t,n,r,a,s){var u=e;do{for(var l=u.next.next;l!==u.prev;){if(u.i!==l.i&&g(u,l)){var c=k(u,l);return u=i(u,u.next),c=i(c,c.next),o(u,t,n,r,a,s),void o(c,t,n,r,a,s)}l=l.next}u=u.next}while(u!==e)}function c(e,t,n,o){var a,s,u,l,c,p=[];for(a=0,s=t.length;s>a;a++)u=t[a]*o,l=s-1>a?t[a+1]*o:e.length,c=r(e,u,l,o,!1),c===c.next&&(c.steiner=!0),p.push(m(c));for(p.sort(f),a=0;a=r.next.y){var s=r.x+(o-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(i>=s&&s>a){if(a=s,s===i){if(o===r.y)return r;if(o===r.next.y)return r.next}n=r.x=r.x&&r.x>=c&&_(f>o?i:a,o,c,f,f>o?a:i,o,r.x,r.y)&&(u=Math.abs(o-r.y)/(i-r.x),(h>u||u===h&&r.x>n.x)&&E(r,e)&&(n=r,h=u)),r=r.next;return n}function d(e,t,n,r){var i=e;do null===i.z&&(i.z=y(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next;while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,v(i)}function v(e){var t,n,r,i,o,a,s,u,l=1;do{for(n=e,e=null,o=null,a=0;n;){for(a++,r=n,s=0,t=0;l>t&&(s++,r=r.nextZ,r);t++);for(u=l;s>0||u>0&&r;)0===s?(i=r,r=r.nextZ,u--):0!==u&&r?n.z<=r.z?(i=n,n=n.nextZ,s--):(i=r,r=r.nextZ,u--):(i=n,n=n.nextZ,s--),o?o.nextZ=i:e=i,i.prevZ=o,o=i;n=r}o.nextZ=null,l*=2}while(a>1);return e}function y(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do t.x=0&&(e-a)*(r-s)-(n-a)*(t-s)>=0&&(n-a)*(o-s)-(i-a)*(r-s)>=0}function g(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!M(e,t)&&E(e,t)&&E(t,e)&&O(e,t)}function b(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function x(e,t){return e.x===t.x&&e.y===t.y}function w(e,t,n,r){return x(e,t)&&x(n,r)||x(e,r)&&x(n,t)?!0:b(e,t,n)>0!=b(e,t,r)>0&&b(n,r,e)>0!=b(n,r,t)>0}function M(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&w(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function E(e,t){return b(e.prev,e,e.next)<0?b(e,t,e.next)>=0&&b(e,e.prev,t)>=0:b(e,t,e.prev)<0||b(e,e.next,t)<0}function O(e,t){var n=e,r=!1,i=(e.x+t.x)/2,o=(e.y+t.y)/2;do n.y>o!=n.next.y>o&&i<(n.next.x-n.x)*(o-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next;while(n!==e);return r}function k(e,t){var n=new j(e.i,e.x,e.y),r=new j(t.i,t.x,t.y),i=e.next,o=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,o.next=r,r.prev=o,r}function P(e,t,n,r){var i=new j(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function T(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function j(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function S(e,t,n,r){for(var i=0,o=t,a=n-r;n>o;o+=r)i+=(e[a]-e[o])*(e[o+1]+e[a+1]),a=o;return i}e.exports=n,n.deviation=function(e,t,n,r){var i=t&&t.length,o=i?t[0]*n:e.length,a=Math.abs(S(e,0,o,n));if(i)for(var s=0,u=t.length;u>s;s++){var l=t[s]*n,c=u-1>s?t[s+1]*n:e.length;a-=Math.abs(S(e,l,c,n))}var f=0;for(s=0;sa;a++)n.vertices.push(e[i][o][a]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n}},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(3),o=r(i),a=function(e,t,n){function r(){a=e.map(function(e){return[e[0],h.top,e[1]]}),s=t,u=t}function i(){a=[],e.forEach(function(e){a.push([e[0],h.top,e[1]])}),e.forEach(function(e){a.push([e[0],h.bottom,e[1]])}),s=[];for(var n=0;p>n;n++)n===p-1?(s.push([n+p,p,n]),s.push([0,n,p])):(s.push([n+p,n+p+1,n]),s.push([n+1,n,n+p+1]));if(c=[].concat(s),h.closed){var r=t,i=r.map(function(e){return e.map(function(e){return e+p})});i=i.map(function(e){return[e[0],e[2],e[1]]}),s=s.concat(r).concat(i),u=r,l=i}}var a,s,u,l,c,f={top:1,bottom:0,closed:!0},h=(0,o["default"])({},f,n),p=e.length;return h.top===h.bottom?r():i(),{positions:a,faces:s,top:u,bottom:l,sides:c}};t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(){var e=function(e){var t={};e.forEach(function(e){for(var n in e)t[n]||(t[n]=0),t[n]+=e[n].length});var n={};for(var r in t)n[r]=new Float32Array(t[r]);var i={};return e.forEach(function(e){for(var t in e)i[t]||(i[t]=0),n[t].set(e[t],i[t]),i[t]+=e[t].length}),n},t=function(e,t){var n,r=new o["default"].BufferGeometry,i=new Float32Array(3*e.verticesCount),a=new Float32Array(3*e.verticesCount);e.pickingIds&&(n=new Float32Array(e.verticesCount));for(var s,u,l,c=0,f=0;f0&&(r+=e[i-1].length,n.holes.push(r))}return n}},{key:"_triangulate",value:function(e,t,n){var r=(0,_["default"])(e,t,n),o=[];for(i=0,il=r.length;i-1&&this._layers.splice(t,1),e.isOutput()&&e.isOutputToScene()&&(this._engine._scene.remove(e._object3D),this._engine._domScene3D.remove(e._domObject3D),this._engine._domScene2D.remove(e._domObject2D)),this.emit("layerRemoved"),Promise.resolve(this)}},{key:"addControls",value:function(e){return e._addToWorld(this),this._controls.push(e),this.emit("controlsAdded",e),Promise.resolve(this)}},{key:"removeControls",value:function(e){var t=this._controls.indexOf(t);return t>-1&&this._controls.splice(t,1),this.emit("controlsRemoved",e),Promise.resolve(this)}},{key:"stop",value:function(){this._pause=!0}},{key:"start",value:function(){this._pause=!1,this._update()}},{key:"destroy",value:function(){this.stop(),this.off("controlsMoveEnd",this._onControlsMoveEnd);var e,t;for(e=this._controls.length-1;e>=0;e--)t=this._controls[0],this.removeControls(t),t.destroy();var n;for(e=this._layers.length-1;e>=0;e--)n=this._layers[0],this.removeLayer(n),n.destroy();for(this._environment=null,this._engine.destroy(),this._engine=null;this._container.firstChild;)this._container.removeChild(this._container.firstChild);this._container=null}}]),t}(l["default"]);t["default"]=x;var k=function(e,t){return new x(e,t)};t.world=k},function(e,t,n){"use strict";function r(e,t,n){this.fn=e,this.context=t,this.once=n||!1}function i(){}var o=Object.prototype.hasOwnProperty,a="function"!=typeof Object.create?"~":!1;i.prototype._events=void 0,i.prototype.eventNames=function(){var e,t=this._events,n=[];if(!t)return n;for(e in t)o.call(t,e)&&n.push(a?e.slice(1):e);return Object.getOwnPropertySymbols?n.concat(Object.getOwnPropertySymbols(t)):n},i.prototype.listeners=function(e,t){var n=a?a+e:e,r=this._events&&this._events[n];if(t)return!!r;if(!r)return[];if(r.fn)return[r.fn];for(var i=0,o=r.length,s=new Array(o);o>i;i++)s[i]=r[i].fn;return s},i.prototype.emit=function(e,t,n,r,i,o){var s=a?a+e:e;if(!this._events||!this._events[s])return!1;var u,l,c=this._events[s],f=arguments.length;if("function"==typeof c.fn){switch(c.once&&this.removeListener(e,c.fn,void 0,!0),f){case 1:return c.fn.call(c.context),!0;case 2:return c.fn.call(c.context,t),!0;case 3:return c.fn.call(c.context,t,n),!0;case 4:return c.fn.call(c.context,t,n,r),!0;case 5:return c.fn.call(c.context,t,n,r,i),!0;case 6:return c.fn.call(c.context,t,n,r,i,o),!0}for(l=1,u=new Array(f-1);f>l;l++)u[l-1]=arguments[l];c.fn.apply(c.context,u)}else{var h,p=c.length;for(l=0;p>l;l++)switch(c[l].once&&this.removeListener(e,c[l].fn,void 0,!0),f){case 1:c[l].fn.call(c[l].context);break;case 2:c[l].fn.call(c[l].context,t);break;case 3:c[l].fn.call(c[l].context,t,n);break;default:if(!u)for(h=1,u=new Array(f-1);f>h;h++)u[h-1]=arguments[h];c[l].fn.apply(c[l].context,u)}}return!0},i.prototype.on=function(e,t,n){var i=new r(t,n||this),o=a?a+e:e;return this._events||(this._events=a?{}:Object.create(null)),this._events[o]?this._events[o].fn?this._events[o]=[this._events[o],i]:this._events[o].push(i):this._events[o]=i,this},i.prototype.once=function(e,t,n){var i=new r(t,n||this,!0),o=a?a+e:e;return this._events||(this._events=a?{}:Object.create(null)),this._events[o]?this._events[o].fn?this._events[o]=[this._events[o],i]:this._events[o].push(i):this._events[o]=i,this},i.prototype.removeListener=function(e,t,n,r){var i=a?a+e:e;if(!this._events||!this._events[i])return this;var o=this._events[i],s=[];if(t)if(o.fn)(o.fn!==t||r&&!o.once||n&&o.context!==n)&&s.push(o);else for(var u=0,l=o.length;l>u;u++)(o[u].fn!==t||r&&!o[u].once||n&&o[u].context!==n)&&s.push(o[u]);return s.length?this._events[i]=1===s.length?s[0]:s:delete this._events[i],this},i.prototype.removeAllListeners=function(e){return this._events?(e?delete this._events[a?a+e:e]:this._events=a?{}:Object.create(null),this):this},i.prototype.off=i.prototype.removeListener,i.prototype.addListener=i.prototype.on,i.prototype.setMaxListeners=function(){return this},i.prefixed=a,e.exports=i},function(e,t,n){function r(e,t,n){var r=e[t];x.call(e,t)&&c(r,n)&&(void 0!==n||t in e)||(e[t]=n)}function i(e){return function(t){return null==t?void 0:t[e]}}function o(e,t,n,i){n||(n={});for(var o=-1,a=t.length;++o1?n[i-1]:void 0,a=i>2?n[2]:void 0;for(o=e.length>3&&"function"==typeof o?(i--,o):void 0,a&&u(n[0],n[1],a)&&(o=3>i?void 0:o,i=1),t=Object(t);++r-1&&e%1==0&&t>e}function u(e,t,n){if(!d(n))return!1;var r=typeof t;return("number"==r?f(n)&&s(t,n.length):"string"==r&&t in n)?c(n[t],e):!1}function l(e){var t=e&&e.constructor,n="function"==typeof t&&t.prototype||w;return e===n}function c(e,t){return e===t||e!==e&&t!==t}function f(e){return null!=e&&p(P(e))&&!h(e)}function h(e){var t=d(e)?k.call(e):"";return t==_||t==g}function p(e){return"number"==typeof e&&e>-1&&e%1==0&&m>=e}function d(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var v=n(4),y=n(5),m=9007199254740991,_="[object Function]",g="[object GeneratorFunction]",b=/^(?:0|[1-9]\d*)$/,w=Object.prototype,x=w.hasOwnProperty,k=w.toString,O=w.propertyIsEnumerable,M=!O.call({valueOf:1},"valueOf"),P=i("length"),E=a(function(e,t){if(M||l(t)||f(t))return void o(t,v(t),e);for(var n in t)x.call(t,n)&&r(e,n,t[n])});e.exports=E},function(e,t){function n(e,t){for(var n=-1,r=Array(e);++n-1&&e%1==0&&t>e}function l(e){var t=e&&e.constructor,n="function"==typeof t&&t.prototype||M;return e===n}function c(e){return h(e)&&P.call(e,"callee")&&(!T.call(e,"callee")||E.call(e)==b)}function f(e){return null!=e&&d(A(e))&&!p(e)}function h(e){return y(e)&&f(e)}function p(e){var t=v(e)?E.call(e):"";return t==w||t==x}function d(e){return"number"==typeof e&&e>-1&&e%1==0&&g>=e}function v(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function y(e){return!!e&&"object"==typeof e}function m(e){return"string"==typeof e||!C(e)&&y(e)&&E.call(e)==k}function _(e){var t=l(e);if(!t&&!f(e))return i(e);var n=s(e),o=!!n,a=n||[],c=a.length;for(var h in e)!r(e,h)||o&&("length"==h||u(h,c))||t&&"constructor"==h||a.push(h);return a}var g=9007199254740991,b="[object Arguments]",w="[object Function]",x="[object GeneratorFunction]",k="[object String]",O=/^(?:0|[1-9]\d*)$/,M=Object.prototype,P=M.hasOwnProperty,E=M.toString,T=M.propertyIsEnumerable,S=Object.getPrototypeOf,j=Object.keys,A=o("length"),C=Array.isArray;e.exports=_},function(e,t){function n(e,t,n){var r=n.length;switch(r){case 0:return e.call(t);case 1:return e.call(t,n[0]);case 2:return e.call(t,n[0],n[1]);case 3:return e.call(t,n[0],n[1],n[2])}return e.apply(t,n)}function r(e,t){if("function"!=typeof e)throw new TypeError(f);return t=M(void 0===t?e.length-1:l(t),0),function(){for(var r=arguments,i=-1,o=M(r.length-t,0),a=Array(o);++ie?-1:1;return t*p}return e===e?e:0}function l(e){var t=u(e),n=t%1;return t===t?n?t-n:t:0}function c(e){if("number"==typeof e)return e;if(s(e))return d;if(o(e)){var t=i(e.valueOf)?e.valueOf():e;e=o(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(_,"");var n=b.test(e);return n||w.test(e)?x(e.slice(2),n?2:8):g.test(e)?d:+e}var f="Expected a function",h=1/0,p=1.7976931348623157e308,d=NaN,v="[object Function]",y="[object GeneratorFunction]",m="[object Symbol]",_=/^\s+|\s+$/g,g=/^[-+]0x[0-9a-f]+$/i,b=/^0b[01]+$/i,w=/^0o[0-7]+$/i,x=parseInt,k=Object.prototype,O=k.toString,M=Math.max;e.exports=r},function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0});var r=n(7),i=n(8),o={};o.R=6378137,o.MAX_LATITUDE=85.0511287798,o.ECC=.081819191,o.ECC2=.006694380015894481,o.project=function(e){var t=Math.PI/180,n=o.MAX_LATITUDE,r=Math.max(Math.min(n,e.lat),-n),a=Math.sin(r*t);return(0,i.point)(o.R*e.lon*t,o.R*Math.log((1+a)/(1-a))/2)},o.unproject=function(e){var t=180/Math.PI;return(0,r.latLon)((2*Math.atan(Math.exp(e.y/o.R))-Math.PI/2)*t,e.x*t/o.R)},o.latLonToPoint=function(e){var t=o.project(e);return t.y*=-1,t},o.pointToLatLon=function(e){var t=(0,i.point)(e.x,-1*e.y);return o.unproject(t)},o.pointScale=function(e,t){var n,r=Math.PI/180;if(t){var i=e.lat*r,a=(e.lon*r,o.R),s=Math.sin(i),u=s*s,l=Math.cos(i),c=a*(1-o.ECC2)/Math.pow(1-o.ECC2*u,1.5),f=a/Math.sqrt(1-o.ECC2*u),h=a/c/l;return n=a/f/l,[n,h]}return n=1/Math.cos(e.lat*r),[n,n]},o.metresToProjected=function(e,t){return e*t[1]},o.projectedToMetres=function(e,t){return e/t[1]},o.metresToWorld=function(e,t){var n=o.metresToProjected(e,t),r=o.scale(),i=r*n;return i},o.worldToMetres=function(e,t){var n=o.scale(),r=e/n,i=o.projectedToMetres(r,t);return i},o.scale=function(e){return e>=0?256*Math.pow(2,e):1},o.zoom=function(e){return Math.log(e/256)/Math.LN2},o.distance=function(e,t,n){var r,i,a,s=Math.PI/180;if(n){r=e.lat*s,i=t.lat*s;var u=e.lon*s,l=t.lon*s,c=i-r,f=l-u,h=c/2,p=f/2;a=Math.sin(h)*Math.sin(h)+Math.cos(r)*Math.cos(i)*Math.sin(p)*Math.sin(p);var d=2*Math.atan2(Math.sqrt(a),Math.sqrt(1-a));return o.R*d}return r=e.lat*s,i=t.lat*s,a=Math.sin(r)*Math.sin(i)+Math.cos(r)*Math.cos(i)*Math.cos((t.lon-e.lon)*s),o.R*Math.acos(Math.min(a,1))},o.bounds=function(){var e=o.R*Math.PI;return[[-e,-e],[e,e]]}(),t["default"]=o,e.exports=t["default"]},function(e,t){function n(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var r=function(){function e(e,t){for(var n=0;n=0;t--)e=this._scene.children[t],e&&(this._scene.remove(e),e.geometry&&(e.geometry.dispose(),e.geometry=null),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));for(var t=this._domScene3D.children.length-1;t>=0;t--)e=this._domScene3D.children[t],e&&this._domScene3D.remove(e);for(var t=this._domScene2D.children.length-1;t>=0;t--)e=this._domScene2D.children[t],e&&this._domScene2D.remove(e);this._picking.destroy(),this._picking=null,this._world=null,this._scene=null,this._domScene3D=null,this._domScene2D=null,this._composer=null,this._renderer=null,this._domRenderer3D=null,this._domRenderer2D=null,this._camera=null,this._clock=null,this._frustum=null}}]),t}(l["default"]);t["default"]=B,e.exports=t["default"]},function(e,t){e.exports=__WEBPACK_EXTERNAL_MODULE_10__},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=n(11);r(a);t["default"]=function(e,t){var n=new o["default"].WebGLRenderer({antialias:t});n.setClearColor(16777215,1);var r=1;n.setPixelRatio(r),n.gammaInput=!0,n.gammaOutput=!0,n.shadowMap.enabled=!0,e.appendChild(n.domElement);var i=function(){n.setSize(e.clientWidth,e.clientHeight)};return window.addEventListener("resize",i,!1),i(),n},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=(r(i),n(16)),a=n(12);r(a);t["default"]=function(e){var t=new o.CSS3DRenderer;t.domElement.style.position="absolute",t.domElement.style.top=0,e.appendChild(t.domElement);var n=function(){t.setSize(e.clientWidth,e.clientHeight)};return window.addEventListener("resize",n,!1),n(),t},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e){o["default"].Object3D.call(this),this.element=e,this.element.style.position="absolute",this.addEventListener("removed",function(e){null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element)})};a.prototype=Object.create(o["default"].Object3D.prototype),a.prototype.constructor=a;var s=function(e){a.call(this,e)};s.prototype=Object.create(a.prototype),s.prototype.constructor=s;var u=function(){console.log("THREE.CSS3DRenderer",o["default"].REVISION);var e,t,n,r,i=new o["default"].Matrix4,u={camera:{fov:0,style:""},objects:{}},l=document.createElement("div");l.style.overflow="hidden",l.style.WebkitTransformStyle="preserve-3d",l.style.MozTransformStyle="preserve-3d",l.style.oTransformStyle="preserve-3d",l.style.transformStyle="preserve-3d",this.domElement=l;var c=document.createElement("div");c.style.WebkitTransformStyle="preserve-3d",c.style.MozTransformStyle="preserve-3d",c.style.oTransformStyle="preserve-3d",c.style.transformStyle="preserve-3d",l.appendChild(c),this.setClearColor=function(){},this.getSize=function(){return{width:e,height:t}},this.setSize=function(i,o){e=i,t=o,n=e/2,r=t/2,l.style.width=i+"px",l.style.height=o+"px",c.style.width=i+"px",c.style.height=o+"px"};var f=function(e){return Math.abs(e)l;l++)v(e.children[l],t)};this.render=function(e,i){var a=.5/Math.tan(o["default"].Math.degToRad(.5*i.fov))*t;u.camera.fov!==a&&(l.style.WebkitPerspective=a+"px",l.style.MozPerspective=a+"px",l.style.oPerspective=a+"px",l.style.perspective=a+"px",u.camera.fov=a),e.updateMatrixWorld(),null===i.parent&&i.updateMatrixWorld(),i.matrixWorldInverse.getInverse(i.matrixWorld);var s="translate3d(0,0,"+a+"px)"+h(i.matrixWorldInverse)+" translate3d("+n+"px,"+r+"px, 0)";u.camera.style!==s&&(c.style.WebkitTransform=s,c.style.MozTransform=s,c.style.oTransform=s,c.style.transform=s,u.camera.style=s),d(e,i)}};t.CSS3DObject=a,t.CSS3DSprite=s,t.CSS3DRenderer=u,o["default"].CSS3DObject=a,o["default"].CSS3DSprite=s,o["default"].CSS3DRenderer=u},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=(r(i),n(18)),a=n(13);r(a);t["default"]=function(e){var t=new o.CSS2DRenderer;t.domElement.style.position="absolute",t.domElement.style.top=0,e.appendChild(t.domElement);var n=function(){t.setSize(e.clientWidth,e.clientHeight)};return window.addEventListener("resize",n,!1),n(),t},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e){o["default"].Object3D.call(this),this.element=e,this.element.style.position="absolute",this.addEventListener("removed",function(e){null!==this.element.parentNode&&this.element.parentNode.removeChild(this.element)})};a.prototype=Object.create(o["default"].Object3D.prototype),a.prototype.constructor=a;var s=function(){console.log("THREE.CSS2DRenderer",o["default"].REVISION);var e,t,n,r,i=new o["default"].Vector3,s=new o["default"].Matrix4,u=new o["default"].Matrix4,l=new o["default"].Frustum,c=document.createElement("div");c.style.overflow="hidden",this.domElement=c,this.setSize=function(i,o){e=i,t=o,n=e/2,r=t/2,c.style.width=i+"px",c.style.height=o+"px"};var f=function h(e,t){if(e instanceof a){i.setFromMatrixPosition(e.matrixWorld),i.applyProjection(u);var o=e.element,s="translate(-50%,-50%) translate("+(i.x*n+n)+"px,"+(-i.y*r+r)+"px)";o.style.WebkitTransform=s,o.style.MozTransform=s,o.style.oTransform=s,o.style.transform=s,o.parentNode!==c&&c.appendChild(o),l.containsPoint(e.position)?o.style.display="block":o.style.display="none"}for(var f=0,p=e.children.length;p>f;f++)h(e.children[f],t)};this.render=function(e,t){e.updateMatrixWorld(),null===t.parent&&t.updateMatrixWorld(),t.matrixWorldInverse.getInverse(t.matrixWorld),s.copy(t.matrixWorldInverse.getInverse(t.matrixWorld)),u.multiplyMatrices(t.projectionMatrix,s),l.setFromMatrix((new o["default"].Matrix4).multiplyMatrices(t.projectionMatrix,t.matrixWorldInverse)),f(e,t)}};t.CSS2DObject=a,t.CSS2DRenderer=s,o["default"].CSS2DObject=a,o["default"].CSS2DRenderer=s},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(e){var t=new o["default"].PerspectiveCamera(45,1,1,2e6);t.position.y=4e3,t.position.z=4e3;var n=function(){t.aspect=e.clientWidth/e.clientHeight,t.updateProjectionMatrix()};return window.addEventListener("resize",n,!1),n(),t},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n0&&(o=a[0].point.clone()),n?(this._world.emit("pick-hover",i,s,o,a),this._world.emit("pick-hover-"+i,s,o,a)):(this._world.emit("pick-click",i,s,o,a),this._world.emit("pick-click-"+i,s,o,a))}},{key:"add",value:function(e){this._pickingScene.add(e),this._needUpdate=!0}},{key:"remove",value:function(e){this._pickingScene.remove(e),this._needUpdate=!0}},{key:"getNextId",value:function(){return p++}},{key:"destroy",value:function(){if(window.removeEventListener("resize",this._resizeHandler,!1),this._world._container.removeEventListener("mouseup",this._mouseUpHandler,!1),this._world._container.removeEventListener("mousemove",this._throttledMouseMoveHandler,!1),this._world.off("move",this._onWorldMove),this._pickingScene.children)for(var e,t=this._pickingScene.children.length-1;t>=0;t--)e=this._pickingScene.children[t],e&&(this._pickingScene.remove(e),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));this._pickingScene=null,this._pickingTexture=null,this._pixelBuffer=null,this._world=null,this._renderer=null,this._camera=null}}]),e}();t["default"]=function(e,t,n){return new d(e,t,n)},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i);t["default"]=function(){var e=new o["default"].Scene;return e}(),e.exports=t["default"]},function(e,t,n){function r(e,t,n){var r=!0,s=!0;if("function"!=typeof e)throw new TypeError(a);return i(n)&&(r="leading"in n?!!n.leading:r,s="trailing"in n?!!n.trailing:s),o(e,t,{leading:r,maxWait:t,trailing:s})}function i(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}var o=n(23),a="Expected a function";e.exports=r},function(e,t){function n(e,t,n){function r(t){var n=v,r=y;return v=y=void 0,O=t,_=e.apply(r,n)}function o(e){return O=e,g=setTimeout(c,t),M?r(e):_}function a(e){var n=e-k,r=e-O,i=t-n;return P?w(i,m-r):i}function l(e){var n=e-k,r=e-O;return!k||n>=t||0>n||P&&r>=m}function c(){var e=x();return l(e)?f(e):void(g=setTimeout(c,a(e)))}function f(e){return clearTimeout(g),g=void 0,E&&v?r(e):(v=y=void 0,_)}function h(){void 0!==g&&clearTimeout(g),k=O=0,v=y=g=void 0}function p(){return void 0===g?_:f(x())}function d(){var e=x(),n=l(e);if(v=arguments,y=this,k=e,n){if(void 0===g)return o(k);if(P)return clearTimeout(g),g=setTimeout(c,t),r(k)}return void 0===g&&(g=setTimeout(c,t)),_}var v,y,m,_,g,k=0,O=0,M=!1,P=!1,E=!0;if("function"!=typeof e)throw new TypeError(u);return t=s(t)||0,i(n)&&(M=!!n.leading,P="maxWait"in n,m=P?b(s(n.maxWait)||0,t):m,E="trailing"in n?!!n.trailing:E),d.cancel=h,d.flush=p,d}function r(e){var t=i(e)?g.call(e):"";return t==c||t==f}function i(e){var t=typeof e;return!!e&&("object"==t||"function"==t)}function o(e){return!!e&&"object"==typeof e}function a(e){return"symbol"==typeof e||o(e)&&g.call(e)==h}function s(e){if("number"==typeof e)return e;if(a(e))return l;if(i(e)){var t=r(e.valueOf)?e.valueOf():e;e=i(t)?t+"":t}if("string"!=typeof e)return 0===e?e:+e;e=e.replace(p,"");var n=v.test(e);return n||y.test(e)?m(e.slice(2),n?2:8):d.test(e)?l:+e}var u="Expected a function",l=NaN,c="[object Function]",f="[object GeneratorFunction]",h="[object Symbol]",p=/^\s+|\s+$/g,d=/^[-+]0x[0-9a-f]+$/i,v=/^0b[01]+$/i,y=/^0o[0-7]+$/i,m=parseInt,_=Object.prototype,g=_.toString,b=Math.max,w=Math.min,x=Date.now;e.exports=n},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=(r(i),n(25)),a=r(o);t["default"]=function(e,t){var n=new a["default"](e),r=function(){var e=1;n.setSize(t.clientWidth*e,t.clientHeight*e)};return window.addEventListener("resize",r,!1),r(),n},e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=n(26),s=r(a),u=n(27),l=r(u),c=n(28),f=r(c),h=function(e,t){if(this.renderer=e,void 0===t){var n=e.getPixelRatio(),r=Math.floor(e.context.canvas.width/n)||1,i=Math.floor(e.context.canvas.height/n)||1,a={minFilter:o["default"].LinearFilter,magFilter:o["default"].LinearFilter,format:o["default"].RGBAFormat,stencilBuffer:!1};t=new o["default"].WebGLRenderTarget(r,i,a)}this.renderTarget1=t,this.renderTarget2=t.clone(),this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2,this.passes=[],void 0===s["default"]&&console.error("EffectComposer relies on THREE.CopyShader"),this.copyPass=new l["default"](s["default"])};h.prototype={swapBuffers:function(){var e=this.readBuffer;this.readBuffer=this.writeBuffer,this.writeBuffer=e},addPass:function(e){this.passes.push(e)},insertPass:function(e,t){this.passes.splice(t,0,e)},render:function(e){this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2;var t,n,r=!1,i=this.passes.length;for(n=0;i>n;n++)if(t=this.passes[n],t.enabled){if(t.render(this.renderer,this.writeBuffer,this.readBuffer,e,r),t.needsSwap){if(r){var o=this.renderer.context;o.stencilFunc(o.NOTEQUAL,1,4294967295),this.copyPass.render(this.renderer,this.writeBuffer,this.readBuffer,e),o.stencilFunc(o.EQUAL,1,4294967295)}this.swapBuffers()}t instanceof f["default"]?r=!0:t instanceof c.ClearMaskPass&&(r=!1)}},reset:function(e){if(void 0===e){e=this.renderTarget1.clone();var t=this.renderer.getPixelRatio();e.setSize(Math.floor(this.renderer.context.canvas.width/t),Math.floor(this.renderer.context.canvas.height/t))}this.renderTarget1.dispose(),this.renderTarget1=e,this.renderTarget2.dispose(),this.renderTarget2=e.clone(),this.writeBuffer=this.renderTarget1,this.readBuffer=this.renderTarget2},setSize:function(e,t){this.renderTarget1.setSize(e,t),this.renderTarget2.setSize(e,t)}},t["default"]=h,o["default"].EffectComposer=h,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},opacity:{type:"f",value:1}},vertexShader:["varying vec2 vUv;","void main() {","vUv = uv;","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform float opacity;","uniform sampler2D tDiffuse;","varying vec2 vUv;","void main() {","vec4 texel = texture2D( tDiffuse, vUv );","gl_FragColor = opacity * texel;","}"].join("\n")};t["default"]=a,o["default"].CopyShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e,t){this.textureID=void 0!==t?t:"tDiffuse",e instanceof o["default"].ShaderMaterial?(this.uniforms=e.uniforms,this.material=e):e&&(this.uniforms=o["default"].UniformsUtils.clone(e.uniforms),this.material=new o["default"].ShaderMaterial({defines:e.defines||{},uniforms:this.uniforms,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader})),this.renderToScreen=!1,this.enabled=!0,this.needsSwap=!0,this.clear=!1,this.camera=new o["default"].OrthographicCamera(-1,1,1,-1,0,1),this.scene=new o["default"].Scene,this.quad=new o["default"].Mesh(new o["default"].PlaneBufferGeometry(2,2),null),this.scene.add(this.quad)};a.prototype={render:function(e,t,n,r){this.uniforms[this.textureID]&&(this.uniforms[this.textureID].value=n),this.quad.material=this.material,this.renderToScreen?e.render(this.scene,this.camera):e.render(this.scene,this.camera,t,this.clear)}},t["default"]=a,o["default"].ShaderPass=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e,t){this.scene=e,this.camera=t,this.enabled=!0,this.clear=!0,this.needsSwap=!1,this.inverse=!1};a.prototype={render:function(e,t,n,r){var i=e.context;i.colorMask(!1,!1,!1,!1),i.depthMask(!1);var o,a;this.inverse?(o=0,a=1):(o=1,a=0),i.enable(i.STENCIL_TEST),i.stencilOp(i.REPLACE,i.REPLACE,i.REPLACE),i.stencilFunc(i.ALWAYS,o,4294967295),i.clearStencil(a),e.render(this.scene,this.camera,n,this.clear),e.render(this.scene,this.camera,t,this.clear),i.colorMask(!0,!0,!0,!0),i.depthMask(!0),i.stencilFunc(i.EQUAL,1,4294967295),i.stencilOp(i.KEEP,i.KEEP,i.KEEP)}};var s=function(){this.enabled=!0};s.prototype={render:function(e,t,n,r){var i=e.context;i.disable(i.STENCIL_TEST)}},t["default"]=a,t.ClearMaskPass=s,o["default"].MaskPass=a,o["default"].ClearMaskPass=s},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(e,t,n,r,i){this.scene=e,this.camera=t,this.overrideMaterial=n,this.clearColor=r,this.clearAlpha=void 0!==i?i:1,this.oldClearColor=new o["default"].Color,this.oldClearAlpha=1,this.enabled=!0,this.clear=!0,this.needsSwap=!1};a.prototype={render:function(e,t,n,r){this.scene.overrideMaterial=this.overrideMaterial,this.clearColor&&(this.oldClearColor.copy(e.getClearColor()),this.oldClearAlpha=e.getClearAlpha(),e.setClearColor(this.clearColor,this.clearAlpha)),e.render(this.scene,this.camera,n,this.clear),this.clearColor&&e.setClearColor(this.oldClearColor,this.oldClearAlpha),this.scene.overrideMaterial=null}},t["default"]=a,o["default"].RenderPass=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},h:{type:"f",value:1/512},r:{type:"f",value:.35}},vertexShader:["varying vec2 vUv;","void main() {","vUv = uv;","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform sampler2D tDiffuse;","uniform float h;","uniform float r;","varying vec2 vUv;","void main() {","vec4 sum = vec4( 0.0 );","float hh = h * abs( r - vUv.y );","sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;","sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;","sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;","gl_FragColor = sum;","}"].join("\n")};t["default"]=a,o["default"].HorizontalTiltShiftShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},v:{type:"f",value:1/512},r:{type:"f",value:.35}},vertexShader:["varying vec2 vUv;","void main() {","vUv = uv;","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform sampler2D tDiffuse;","uniform float v;","uniform float r;","varying vec2 vUv;","void main() {","vec4 sum = vec4( 0.0 );","float vv = v * abs( r - vUv.y );","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;","sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;","gl_FragColor = sum;","}"].join("\n")};t["default"]=a,o["default"].VerticalTiltShiftShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a={uniforms:{tDiffuse:{type:"t",value:null},resolution:{type:"v2",value:new o["default"].Vector2(1/1024,1/512)}},vertexShader:["void main() {","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["uniform sampler2D tDiffuse;","uniform vec2 resolution;","#define FXAA_REDUCE_MIN (1.0/128.0)","#define FXAA_REDUCE_MUL (1.0/8.0)","#define FXAA_SPAN_MAX 8.0","void main() {","vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;","vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;","vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;","vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;","vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );","vec3 rgbM = rgbaM.xyz;","vec3 luma = vec3( 0.299, 0.587, 0.114 );","float lumaNW = dot( rgbNW, luma );","float lumaNE = dot( rgbNE, luma );","float lumaSW = dot( rgbSW, luma );","float lumaSE = dot( rgbSE, luma );","float lumaM = dot( rgbM, luma );","float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );","float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );","vec2 dir;","dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));","dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));","float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );","float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );","dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),","max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),","dir * rcpDirMin)) * resolution;","vec4 rgbA = (1.0/2.0) * (","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));","vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +","texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));","float lumaB = dot(rgbB, vec4(luma, 0.0));","if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {","gl_FragColor = rgbA;","} else {","gl_FragColor = rgbB;","}","}"].join("\n")};t["default"]=a,o["default"].FXAAShader=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n=0;t--)e=this._object3D.children[t],e&&(this.remove(e),e.geometry&&(e.geometry.dispose(),e.geometry=null),e.material&&(e.material.map&&(e.material.map.dispose(),e.material.map=null),e.material.dispose(),e.material=null));if(this._domObject3D&&this._domObject3D.children)for(var e,t=this._domObject3D.children.length-1;t>=0;t--)e=this._domObject3D.children[t],e&&this.removeDOM3D(e);if(this._domObject2D&&this._domObject2D.children)for(var e,t=this._domObject2D.children.length-1;t>=0;t--)e=this._domObject2D.children[t],e&&this.removeDOM2D(e);this._domObject3D=null,this._domObject2D=null,this._world=null,this._object3D=null}}]),t}(l["default"]);t["default"]=g;var b=function(e){return new g(e)};t.layer=b},function(e,t,n){"use strict";e.exports=n(36)},function(e,t,n){"use strict";function r(){var e="",t=Math.floor(.001*(Date.now()-p));return t===u?s++:(s=0,u=t),e+=c(l.lookup,d),e+=c(l.lookup,v),s>0&&(e+=c(l.lookup,s)),e+=c(l.lookup,t)}function i(t){return l.seed(t),e.exports}function o(t){return v=t,e.exports}function a(e){return void 0!==e&&l.characters(e),l.shuffled()}var s,u,l=n(37),c=n(39),f=n(41),h=n(42),p=1459707606518,d=6,v=n(43)||0;e.exports=r,e.exports.generate=r,e.exports.seed=i,e.exports.worker=o,e.exports.characters=a,e.exports.decode=f,e.exports.isValid=h},function(e,t,n){"use strict";function r(){h=!1}function i(e){if(!e)return void(c!==d&&(c=d,r()));if(e!==c){if(e.length!==d.length)throw new Error("Custom alphabet for shortid must be "+d.length+" unique characters. You submitted "+e.length+" characters: "+e);var t=e.split("").filter(function(e,t,n){return t!==n.lastIndexOf(e)});if(t.length)throw new Error("Custom alphabet for shortid must be "+d.length+" unique characters. These characters were not unique: "+t.join(", "));c=e,r()}}function o(e){return i(e),c}function a(e){p.seed(e),f!==e&&(r(),f=e)}function s(){c||i(d);for(var e,t=c.split(""),n=[],r=p.nextValue();t.length>0;)r=p.nextValue(),e=Math.floor(r*t.length),n.push(t.splice(e,1)[0]);return n.join("")}function u(){return h?h:h=s()}function l(e){var t=u();return t[e]}var c,f,h,p=n(38),d="0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-";e.exports={characters:o,seed:a,lookup:l,shuffled:u}},function(e,t){"use strict";function n(){return i=(9301*i+49297)%233280,i/233280}function r(e){i=e}var i=1;e.exports={nextValue:n,seed:r}},function(e,t,n){"use strict";function r(e,t){for(var n,r=0,o="";!n;)o+=e(t>>4*r&15|i()),n=tr;r++)if(-1===t.indexOf(e[r]))return!1;return!0}var i=n(37);e.exports=r},function(e,t){"use strict";e.exports=0},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n degrees, and the cosine of that","// earth shadow hack","const float cutoffAngle = pi/1.95;","const float steepness = 1.5;","vec3 totalRayleigh(vec3 lambda)","{","return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));","}","// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE","vec3 simplifiedRayleigh()","{","return 0.0005 / vec3(94, 40, 18);","}","float rayleighPhase(float cosTheta)","{ ","return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));","// return (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));","// return (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));","}","vec3 totalMie(vec3 lambda, vec3 K, float T)","{","float c = (0.2 * T ) * 10E-18;","return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;","}","float hgPhase(float cosTheta, float g)","{","return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));","}","float sunIntensity(float zenithAngleCos)","{","return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));","}","// float logLuminance(vec3 c)","// {","// return log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);","// }","// Filmic ToneMapping http://filmicgames.com/archives/75","float A = 0.15;","float B = 0.50;","float C = 0.10;","float D = 0.20;","float E = 0.02;","float F = 0.30;","float W = 1000.0;","vec3 Uncharted2Tonemap(vec3 x)","{","return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;","}","void main() ","{","float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);","// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;","// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);","float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));","vec3 sunDirection = normalize(sunPosition);","float sunE = sunIntensity(dot(sunDirection, up));","// extinction (absorbtion + out scattering) ","// rayleigh coefficients","vec3 betaR = simplifiedRayleigh() * reileighCoefficient;","// mie coefficients","vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;","// optical length","// cutoff angle at 90 to avoid singularity in next formula.","float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));","float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));","float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));","// combined extinction factor ","vec3 Fex = exp(-(betaR * sR + betaM * sM));","// in scattering","float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);","float rPhase = rayleighPhase(cosTheta*0.5+0.5);","vec3 betaRTheta = betaR * rPhase;","float mPhase = hgPhase(cosTheta, mieDirectionalG);","vec3 betaMTheta = betaM * mPhase;","vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));","Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));","//nightsky","vec3 direction = normalize(vWorldPosition - cameraPos);","float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]","float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]","vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);","// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;","vec3 L0 = vec3(0.1) * Fex;","// composition + solar disc","//if (cosTheta > sunAngularDiameterCos)","float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);","// if (normalize(vWorldPosition - cameraPos).y>0.0)","L0 += (sunE * 19000.0 * Fex)*sundisk;","vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));","vec3 texColor = (Lin+L0); ","texColor *= 0.04 ;","texColor += vec3(0.0,0.001,0.0025)*0.3;","float g_fMaxLuminance = 1.0;","float fLumScaled = 0.1 / luminance; ","float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ","float ExposureBias = fLumCompressed;","vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);","vec3 color = curr*whiteScale;","vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));","gl_FragColor.rgb = retColor;","gl_FragColor.a = 1.0;","}"].join("\n") +};var a=function(){var e=o["default"].ShaderLib.sky,t=o["default"].UniformsUtils.clone(e.uniforms),n=new o["default"].ShaderMaterial({fragmentShader:e.fragmentShader,vertexShader:e.vertexShader,uniforms:t,side:o["default"].BackSide}),r=new o["default"].SphereBufferGeometry(45e4,32,15),i=new o["default"].Mesh(r,n);this.mesh=i,this.uniforms=t};t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(47),o=r(i),a=function(){var e,t=2,n=function(n,r){return e=new o["default"]({numThreads:n?n:t,workerScript:r?r:"vizicities-worker.js"}),e.createWorkers()},r=function(t,n,r){return e.exec(t,n,r)};return{createWorkers:n,exec:r}}();t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n0?u(r()):re.y<0&&l(r()),te.copy(ne),I.update()}function v(e){Q.set(e.clientX,e.clientY),ee.subVectors(Q,$),ae(ee.x,ee.y),$.copy(Q),I.update()}function y(e){}function m(e){var t=0;void 0!==e.wheelDelta?t=e.wheelDelta:void 0!==e.detail&&(t=-e.detail),t>0?l(r()):0>t&&u(r()),I.update()}function _(e){switch(e.keyCode){case I.keys.UP:ae(0,I.keyPanSpeed),I.update();break;case I.keys.BOTTOM:ae(0,-I.keyPanSpeed),I.update();break;case I.keys.LEFT:ae(I.keyPanSpeed,0),I.update();break;case I.keys.RIGHT:ae(-I.keyPanSpeed,0),I.update()}}function g(e){J.set(e.pointers[0].pageX,e.pointers[0].pageY)}function b(e){var t=e.pointers[0].pageX-e.pointers[1].pageX,n=e.pointers[0].pageY-e.pointers[1].pageY,r=Math.sqrt(t*t+n*n);te.set(0,r)}function w(e){$.set(e.deltaX,e.deltaY)}function x(e){Y.set(e.pointers[0].pageX,e.pointers[0].pageY),K.subVectors(Y,J);var t=I.domElement===document?I.domElement.body:I.domElement;i(2*Math.PI*K.x/t.clientWidth*I.rotateSpeed),a(2*Math.PI*K.y/t.clientHeight*I.rotateSpeed),J.copy(Y),I.update()}function k(e){var t=e.pointers[0].pageX-e.pointers[1].pageX,n=e.pointers[0].pageY-e.pointers[1].pageY,i=Math.sqrt(t*t+n*n);ne.set(0,i),re.subVectors(ne,te),re.y>0?l(r()):re.y<0&&u(r()),te.copy(ne),I.update()}function O(e){Q.set(e.deltaX,e.deltaY),ee.subVectors(Q,$),ae(ee.x,ee.y),$.copy(Q),I.update()}function M(e){}function P(e){if(I.enabled!==!1){if(e.preventDefault(),e.button===I.mouseButtons.ORBIT){if(I.enableRotate===!1)return;c(e),B=W.ROTATE}else if(e.button===I.mouseButtons.ZOOM){if(I.enableZoom===!1)return;f(e),B=W.DOLLY}else if(e.button===I.mouseButtons.PAN){if(I.enablePan===!1)return;h(e),B=W.PAN}B!==W.NONE&&(document.addEventListener("mousemove",E,!1),document.addEventListener("mouseup",T,!1),document.addEventListener("mouseout",T,!1),I.dispatchEvent(z))}}function E(e){if(I.enabled!==!1)if(e.preventDefault(),B===W.ROTATE){if(I.enableRotate===!1)return;p(e)}else if(B===W.DOLLY){if(I.enableZoom===!1)return;d(e)}else if(B===W.PAN){if(I.enablePan===!1)return;v(e)}}function T(e){I.enabled!==!1&&(y(e),document.removeEventListener("mousemove",E,!1),document.removeEventListener("mouseup",T,!1),document.removeEventListener("mouseout",T,!1),I.dispatchEvent(U),B=W.NONE)}function S(e){I.enabled!==!1&&I.enableZoom!==!1&&B===W.NONE&&(e.preventDefault(),e.stopPropagation(),m(e),I.dispatchEvent(z),I.dispatchEvent(U))}function j(e){I.enabled!==!1&&I.enableKeys!==!1&&I.enablePan!==!1&&_(e)}function A(e){if(I.enabled!==!1){switch(e.touches.length){case 1:if(I.enableRotate===!1)return;g(e),B=W.TOUCH_ROTATE;break;case 2:if(I.enableZoom===!1)return;b(e),B=W.TOUCH_DOLLY;break;case 3:if(I.enablePan===!1)return;w(e),B=W.TOUCH_PAN;break;default:B=W.NONE}B!==W.NONE&&I.dispatchEvent(z)}}function C(e){if(I.enabled!==!1)switch(e.preventDefault(),e.stopPropagation(),e.touches.length){case 1:if(I.enableRotate===!1)return;if(B!==W.TOUCH_ROTATE)return;x(e);break;case 2:if(I.enableZoom===!1)return;if(B!==W.TOUCH_DOLLY)return;k(e);break;case 3:if(I.enablePan===!1)return;if(B!==W.TOUCH_PAN)return;O(e);break;default:B=W.NONE}}function L(e){I.enabled!==!1&&(M(e),I.dispatchEvent(U),B=W.NONE)}function D(e){e.preventDefault()}this.object=e,this.domElement=void 0!==t?t:document,this.enabled=!0,this.target=new o["default"].Vector3,this.minDistance=0,this.maxDistance=1/0,this.minZoom=0,this.maxZoom=1/0,this.minPolarAngle=0,this.maxPolarAngle=Math.PI,this.minAzimuthAngle=-(1/0),this.maxAzimuthAngle=1/0,this.enableDamping=!1,this.dampingFactor=.25,this.enableZoom=!0,this.zoomSpeed=1,this.enableRotate=!0,this.rotateSpeed=1,this.enablePan=!0,this.keyPanSpeed=7,this.autoRotate=!1,this.autoRotateSpeed=2,this.enableKeys=!0,this.keys={LEFT:37,UP:38,RIGHT:39,BOTTOM:40},this.mouseButtons={ORBIT:o["default"].MOUSE.LEFT,ZOOM:o["default"].MOUSE.MIDDLE,PAN:o["default"].MOUSE.RIGHT},this.target0=this.target.clone(),this.position0=this.object.position.clone(),this.zoom0=this.object.zoom,this.getPolarAngle=function(){return F},this.getAzimuthalAngle=function(){return R},this.reset=function(){I.target.copy(I.target0),I.object.position.copy(I.position0),I.object.zoom=I.zoom0,I.object.updateProjectionMatrix(),I.dispatchEvent(N),I.update(),B=W.NONE},this.update=function(){var t=new o["default"].Vector3,r=(new o["default"].Quaternion).setFromUnitVectors(e.up,new o["default"].Vector3(0,1,0)),a=r.clone().inverse(),s=new o["default"].Vector3,u=new o["default"].Quaternion;return function(){var e=I.object.position;t.copy(e).sub(I.target),t.applyQuaternion(r),R=Math.atan2(t.x,t.z),F=Math.atan2(Math.sqrt(t.x*t.x+t.z*t.z),t.y),I.autoRotate&&B===W.NONE&&i(n()),R+=V,F+=H,R=Math.max(I.minAzimuthAngle,Math.min(I.maxAzimuthAngle,R)),F=Math.max(I.minPolarAngle,Math.min(I.maxPolarAngle,F)),F=Math.max(q,Math.min(Math.PI-q,F));var o=t.length()*G;return o=Math.max(I.minDistance,Math.min(I.maxDistance,o)),I.target.add(X),t.x=o*Math.sin(F)*Math.sin(R),t.y=o*Math.cos(F),t.z=o*Math.sin(F)*Math.cos(R),t.applyQuaternion(a),e.copy(I.target).add(t),I.object.lookAt(I.target),I.enableDamping===!0?(V*=1-I.dampingFactor,H*=1-I.dampingFactor):(V=0,H=0),G=1,X.set(0,0,0),Z||s.distanceToSquared(I.object.position)>q||8*(1-u.dot(I.object.quaternion))>q?(I.dispatchEvent(N),s.copy(I.object.position),u.copy(I.object.quaternion),Z=!1,!0):!1}}(),this.dispose=function(){I.domElement.removeEventListener("contextmenu",D,!1),I.domElement.removeEventListener("mousedown",P,!1),I.domElement.removeEventListener("mousewheel",S,!1),I.domElement.removeEventListener("MozMousePixelScroll",S,!1),I.domElement.removeEventListener("touchstart",A,!1),I.domElement.removeEventListener("touchend",L,!1),I.domElement.removeEventListener("touchmove",C,!1),document.removeEventListener("mousemove",E,!1),document.removeEventListener("mouseup",T,!1),document.removeEventListener("mouseout",T,!1),window.removeEventListener("keydown",j,!1)};var R,F,I=this,N={type:"change"},z={type:"start"},U={type:"end"},W={NONE:-1,ROTATE:0,DOLLY:1,PAN:2,TOUCH_ROTATE:3,TOUCH_DOLLY:4,TOUCH_PAN:5},B=W.NONE,q=1e-6,H=0,V=0,G=1,X=new o["default"].Vector3,Z=!1,J=new o["default"].Vector2,Y=new o["default"].Vector2,K=new o["default"].Vector2,$=new o["default"].Vector2,Q=new o["default"].Vector2,ee=new o["default"].Vector2,te=new o["default"].Vector2,ne=new o["default"].Vector2,re=new o["default"].Vector2,ie=function(){var e=new o["default"].Vector3;return function(t,n){var r=n.elements;e.set(r[0],0,r[2]),e.multiplyScalar(-t),X.add(e)}}(),oe=function(){var e=new o["default"].Vector3;return function(t,n){var r=n.elements,i=t/Math.cos(F);e.set(r[4],0,r[6]),e.multiplyScalar(i),X.add(e)}}(),ae=function(){var e=new o["default"].Vector3;return function(t,n){var r=I.domElement===document?I.domElement.body:I.domElement;if(I.object instanceof o["default"].PerspectiveCamera){var i=I.object.position;e.copy(i).sub(I.target);var a=e.length();a*=Math.tan(I.object.fov/2*Math.PI/180),ie(2*t*a/r.clientHeight,I.object.matrix),oe(2*n*a/r.clientHeight,I.object.matrix)}else I.object instanceof o["default"].OrthographicCamera?(ie(t*(I.object.right-I.object.left)/r.clientWidth,I.object.matrix),oe(n*(I.object.top-I.object.bottom)/r.clientHeight,I.object.matrix)):(console.warn("WARNING: OrbitControls.js encountered an unknown camera type - pan disabled."),I.enablePan=!1)}}();I.domElement.addEventListener("contextmenu",D,!1),I.domElement.addEventListener("mousedown",P,!1),I.domElement.addEventListener("mousewheel",S,!1),I.domElement.addEventListener("MozMousePixelScroll",S,!1),I.hammer=new s["default"](I.domElement),I.hammer.get("pan").set({pointers:0,direction:s["default"].DIRECTION_ALL}),I.hammer.get("pinch").set({enable:!0,threshold:.1}),I.hammer.on("panstart",function(e){if(I.enabled!==!1&&"mouse"!==e.pointerType){if(1===e.pointers.length){if(I.enablePan===!1)return;w(e),B=W.TOUCH_PAN}else if(2===e.pointers.length){if(I.enableRotate===!1)return;g(e),B=W.TOUCH_ROTATE}B!==W.NONE&&I.dispatchEvent(z)}}),I.hammer.on("panend",function(e){"mouse"!==e.pointerType&&L(e)}),I.hammer.on("panmove",function(e){if(I.enabled!==!1&&"mouse"!==e.pointerType)if(1===e.pointers.length){if(I.enablePan===!1)return;if(B!==W.TOUCH_PAN)return;O(e)}else if(2===e.pointers.length){if(I.enableRotate===!1)return;if(B!==W.TOUCH_ROTATE)return;x(e)}}),I.hammer.on("pinchstart",function(e){I.enabled!==!1&&"mouse"!==e.pointerType&&I.enableZoom!==!1&&(b(e),B=W.TOUCH_DOLLY,B!==W.NONE&&I.dispatchEvent(z))}),I.hammer.on("pinchend",function(e){"mouse"!==e.pointerType&&L(e)}),I.hammer.on("pinchmove",function(e){I.enabled!==!1&&"mouse"!==e.pointerType&&I.enableZoom!==!1&&B===W.TOUCH_DOLLY&&k(e)}),window.addEventListener("keydown",j,!1),this.panLeft=ie,this.panUp=oe,this.pan=ae,this.dollyIn=u,this.dollyOut=l,this.getZoomScale=r,this.rotateLeft=i,this.rotateUp=a,this.update()};u.prototype=Object.create(o["default"].EventDispatcher.prototype),u.prototype.constructor=o["default"].OrbitControls,Object.defineProperties(u.prototype,{center:{get:function(){return console.warn("THREE.OrbitControls: .center has been renamed to .target"),this.target}},noZoom:{get:function(){return console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead."),!this.enableZoom},set:function(e){console.warn("THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead."),this.enableZoom=!e}},noRotate:{get:function(){return console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead."),!this.enableRotate},set:function(e){console.warn("THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead."),this.enableRotate=!e}},noPan:{get:function(){return console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead."),!this.enablePan},set:function(e){console.warn("THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead."),this.enablePan=!e}},noKeys:{get:function(){return console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead."),!this.enableKeys},set:function(e){console.warn("THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead."),this.enableKeys=!e}},staticMoving:{get:function(){return console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead."),!this.constraint.enableDamping},set:function(e){console.warn("THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead."),this.constraint.enableDamping=!e}},dynamicDampingFactor:{get:function(){return console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead."),this.constraint.dampingFactor},set:function(e){console.warn("THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead."),this.constraint.dampingFactor=e}}}),t["default"]=u,e.exports=t["default"]},function(e,t,n){var r;!function(i,o,a,s){"use strict";function u(e,t,n){return setTimeout(p(e,n),t)}function l(e,t,n){return Array.isArray(e)?(c(e,n[t],n),!0):!1}function c(e,t,n){var r;if(e)if(e.forEach)e.forEach(t,n);else if(e.length!==s)for(r=0;r\s*\(/gm,"{anonymous}()@"):"Unknown Stack Trace",o=i.console&&(i.console.warn||i.console.log);return o&&o.call(i.console,r,n),e.apply(this,arguments)}}function h(e,t,n){var r,i=t.prototype;r=e.prototype=Object.create(i),r.constructor=e,r._super=i,n&&ve(r,n)}function p(e,t){return function(){return e.apply(t,arguments)}}function d(e,t){return typeof e==_e?e.apply(t?t[0]||s:s,t):e}function v(e,t){return e===s?t:e}function y(e,t,n){c(b(t),function(t){e.addEventListener(t,n,!1)})}function m(e,t,n){c(b(t),function(t){e.removeEventListener(t,n,!1)})}function _(e,t){for(;e;){if(e==t)return!0;e=e.parentNode}return!1}function g(e,t){return e.indexOf(t)>-1}function b(e){return e.trim().split(/\s+/g)}function w(e,t,n){if(e.indexOf&&!n)return e.indexOf(t);for(var r=0;rn[t]}):r.sort()),r}function O(e,t){for(var n,r,i=t[0].toUpperCase()+t.slice(1),o=0;o1&&!n.firstMultiple?n.firstMultiple=L(t):1===i&&(n.firstMultiple=!1);var o=n.firstInput,a=n.firstMultiple,s=a?a.center:o.center,u=t.center=D(r);t.timeStamp=we(),t.deltaTime=t.timeStamp-o.timeStamp,t.angle=N(s,u),t.distance=I(s,u),A(n,t),t.offsetDirection=F(t.deltaX,t.deltaY);var l=R(t.deltaTime,t.deltaX,t.deltaY);t.overallVelocityX=l.x,t.overallVelocityY=l.y,t.overallVelocity=be(l.x)>be(l.y)?l.x:l.y,t.scale=a?U(a.pointers,r):1,t.rotation=a?z(a.pointers,r):0,t.maxPointers=n.prevInput?t.pointers.length>n.prevInput.maxPointers?t.pointers.length:n.prevInput.maxPointers:t.pointers.length,C(n,t);var c=e.element;_(t.srcEvent.target,c)&&(c=t.srcEvent.target),t.target=c}function A(e,t){var n=t.center,r=e.offsetDelta||{},i=e.prevDelta||{},o=e.prevInput||{};t.eventType!==De&&o.eventType!==Fe||(i=e.prevDelta={x:o.deltaX||0,y:o.deltaY||0},r=e.offsetDelta={x:n.x,y:n.y}),t.deltaX=i.x+(n.x-r.x),t.deltaY=i.y+(n.y-r.y)}function C(e,t){var n,r,i,o,a=e.lastInterval||t,u=t.timeStamp-a.timeStamp;if(t.eventType!=Ie&&(u>Le||a.velocity===s)){var l=t.deltaX-a.deltaX,c=t.deltaY-a.deltaY,f=R(u,l,c);r=f.x,i=f.y,n=be(f.x)>be(f.y)?f.x:f.y,o=F(l,c),e.lastInterval=t}else n=a.velocity,r=a.velocityX,i=a.velocityY,o=a.direction;t.velocity=n,t.velocityX=r,t.velocityY=i,t.direction=o}function L(e){for(var t=[],n=0;ni;)n+=e[i].clientX,r+=e[i].clientY,i++;return{x:ge(n/t),y:ge(r/t)}}function R(e,t,n){return{x:t/e||0,y:n/e||0}}function F(e,t){return e===t?Ne:be(e)>=be(t)?0>e?ze:Ue:0>t?We:Be}function I(e,t,n){n||(n=Ge);var r=t[n[0]]-e[n[0]],i=t[n[1]]-e[n[1]];return Math.sqrt(r*r+i*i)}function N(e,t,n){n||(n=Ge);var r=t[n[0]]-e[n[0]],i=t[n[1]]-e[n[1]];return 180*Math.atan2(i,r)/Math.PI}function z(e,t){return N(t[1],t[0],Xe)+N(e[1],e[0],Xe)}function U(e,t){return I(t[0],t[1],Xe)/I(e[0],e[1],Xe)}function W(){this.evEl=Je,this.evWin=Ye,this.pressed=!1,E.apply(this,arguments)}function B(){this.evEl=Qe,this.evWin=et,E.apply(this,arguments),this.store=this.manager.session.pointerEvents=[]}function q(){this.evTarget=nt,this.evWin=rt,this.started=!1,E.apply(this,arguments)}function H(e,t){var n=x(e.touches),r=x(e.changedTouches);return t&(Fe|Ie)&&(n=k(n.concat(r),"identifier",!0)),[n,r]}function V(){this.evTarget=ot,this.targetIds={},E.apply(this,arguments)}function G(e,t){var n=x(e.touches),r=this.targetIds;if(t&(De|Re)&&1===n.length)return r[n[0].identifier]=!0,[n,n];var i,o,a=x(e.changedTouches),s=[],u=this.target;if(o=n.filter(function(e){return _(e.target,u)}),t===De)for(i=0;i-1&&r.splice(e,1)};setTimeout(i,at)}}function Y(e){for(var t=e.srcEvent.clientX,n=e.srcEvent.clientY,r=0;r=o&&st>=a)return!0}return!1}function K(e,t){this.manager=e,this.set(t)}function $(e){if(g(e,pt))return pt;var t=g(e,dt),n=g(e,vt);return t&&n?pt:t||n?t?dt:vt:g(e,ht)?ht:ft}function Q(){if(!lt)return!1;var e={},t=i.CSS&&i.CSS.supports;return["auto","manipulation","pan-y","pan-x","pan-x pan-y","none"].forEach(function(n){e[n]=t?i.CSS.supports("touch-action",n):!0}),e}function ee(e){this.options=ve({},this.defaults,e||{}),this.id=M(),this.manager=null,this.options.enable=v(this.options.enable,!0),this.state=mt,this.simultaneous={},this.requireFail=[]}function te(e){return e&xt?"cancel":e&bt?"end":e>?"move":e&_t?"start":""}function ne(e){return e==Be?"down":e==We?"up":e==ze?"left":e==Ue?"right":""}function re(e,t){var n=t.manager;return n?n.get(e):e}function ie(){ee.apply(this,arguments)}function oe(){ie.apply(this,arguments),this.pX=null,this.pY=null}function ae(){ie.apply(this,arguments)}function se(){ee.apply(this,arguments),this._timer=null,this._input=null}function ue(){ie.apply(this,arguments)}function le(){ie.apply(this,arguments)}function ce(){ee.apply(this,arguments),this.pTime=!1,this.pCenter=!1,this._timer=null,this._input=null,this.count=0}function fe(e,t){return t=t||{},t.recognizers=v(t.recognizers,fe.defaults.preset),new he(e,t)}function he(e,t){this.options=ve({},fe.defaults,t||{}),this.options.inputTarget=this.options.inputTarget||e,this.handlers={},this.session={},this.recognizers=[],this.oldCssProps={},this.element=e,this.input=T(this),this.touchAction=new K(this,this.options.touchAction),pe(this,!0),c(this.options.recognizers,function(e){var t=this.add(new e[0](e[1]));e[2]&&t.recognizeWith(e[2]),e[3]&&t.requireFailure(e[3])},this)}function pe(e,t){var n=e.element;if(n.style){var r;c(e.options.cssProps,function(i,o){r=O(n.style,o),t?(e.oldCssProps[r]=n.style[r],n.style[r]=i):n.style[r]=e.oldCssProps[r]||""}),t||(e.oldCssProps={})}}function de(e,t){var n=o.createEvent("Event");n.initEvent(e,!0,!0),n.gesture=t,t.target.dispatchEvent(n)}var ve,ye=["","webkit","Moz","MS","ms","o"],me=o.createElement("div"),_e="function",ge=Math.round,be=Math.abs,we=Date.now;ve="function"!=typeof Object.assign?function(e){if(e===s||null===e)throw new TypeError("Cannot convert undefined or null to object");for(var t=Object(e),n=1;ns&&(t.push(e),s=t.length-1):i&(Fe|Ie)&&(n=!0),0>s||(t[s]=e,this.callback(this.manager,i,{pointers:t,changedPointers:[e],pointerType:o,srcEvent:e}),n&&t.splice(s,1))}});var tt={touchstart:De,touchmove:Re,touchend:Fe,touchcancel:Ie},nt="touchstart",rt="touchstart touchmove touchend touchcancel";h(q,E,{handler:function(e){var t=tt[e.type];if(t===De&&(this.started=!0),this.started){var n=H.call(this,e,t);t&(Fe|Ie)&&n[0].length-n[1].length===0&&(this.started=!1),this.callback(this.manager,t,{pointers:n[0],changedPointers:n[1],pointerType:Se,srcEvent:e})}}});var it={touchstart:De,touchmove:Re,touchend:Fe,touchcancel:Ie},ot="touchstart touchmove touchend touchcancel";h(V,E,{handler:function(e){var t=it[e.type],n=G.call(this,e,t);n&&this.callback(this.manager,t,{pointers:n[0],changedPointers:n[1],pointerType:Se,srcEvent:e})}});var at=2500,st=25;h(X,E,{handler:function(e,t,n){var r=n.pointerType==Se,i=n.pointerType==Ae;if(!(i&&n.sourceCapabilities&&n.sourceCapabilities.firesTouchEvents)){if(r)Z.call(this,t,n);else if(i&&Y.call(this,n))return;this.callback(e,t,n)}},destroy:function(){this.touch.destroy(),this.mouse.destroy()}});var ut=O(me.style,"touchAction"),lt=ut!==s,ct="compute",ft="auto",ht="manipulation",pt="none",dt="pan-x",vt="pan-y",yt=Q();K.prototype={set:function(e){e==ct&&(e=this.compute()),lt&&this.manager.element.style&&yt[e]&&(this.manager.element.style[ut]=e),this.actions=e.toLowerCase().trim()},update:function(){this.set(this.manager.options.touchAction); +},compute:function(){var e=[];return c(this.manager.recognizers,function(t){d(t.options.enable,[t])&&(e=e.concat(t.getTouchAction()))}),$(e.join(" "))},preventDefaults:function(e){var t=e.srcEvent,n=e.offsetDirection;if(this.manager.session.prevented)return void t.preventDefault();var r=this.actions,i=g(r,pt)&&!yt[pt],o=g(r,vt)&&!yt[vt],a=g(r,dt)&&!yt[dt];if(i){var s=1===e.pointers.length,u=e.distance<2,l=e.deltaTime<250;if(s&&u&&l)return}return a&&o?void 0:i||o&&n&qe||a&&n&He?this.preventSrc(t):void 0},preventSrc:function(e){this.manager.session.prevented=!0,e.preventDefault()}};var mt=1,_t=2,gt=4,bt=8,wt=bt,xt=16,kt=32;ee.prototype={defaults:{},set:function(e){return ve(this.options,e),this.manager&&this.manager.touchAction.update(),this},recognizeWith:function(e){if(l(e,"recognizeWith",this))return this;var t=this.simultaneous;return e=re(e,this),t[e.id]||(t[e.id]=e,e.recognizeWith(this)),this},dropRecognizeWith:function(e){return l(e,"dropRecognizeWith",this)?this:(e=re(e,this),delete this.simultaneous[e.id],this)},requireFailure:function(e){if(l(e,"requireFailure",this))return this;var t=this.requireFail;return e=re(e,this),-1===w(t,e)&&(t.push(e),e.requireFailure(this)),this},dropRequireFailure:function(e){if(l(e,"dropRequireFailure",this))return this;e=re(e,this);var t=w(this.requireFail,e);return t>-1&&this.requireFail.splice(t,1),this},hasRequireFailures:function(){return this.requireFail.length>0},canRecognizeWith:function(e){return!!this.simultaneous[e.id]},emit:function(e){function t(t){n.manager.emit(t,e)}var n=this,r=this.state;bt>r&&t(n.options.event+te(r)),t(n.options.event),e.additionalEvent&&t(e.additionalEvent),r>=bt&&t(n.options.event+te(r))},tryEmit:function(e){return this.canEmit()?this.emit(e):void(this.state=kt)},canEmit:function(){for(var e=0;eo?ze:Ue,n=o!=this.pX,r=Math.abs(e.deltaX)):(i=0===a?Ne:0>a?We:Be,n=a!=this.pY,r=Math.abs(e.deltaY))),e.direction=i,n&&r>t.threshold&&i&t.direction},attrTest:function(e){return ie.prototype.attrTest.call(this,e)&&(this.state&_t||!(this.state&_t)&&this.directionTest(e))},emit:function(e){this.pX=e.deltaX,this.pY=e.deltaY;var t=ne(e.direction);t&&(e.additionalEvent=this.options.event+t),this._super.emit.call(this,e)}}),h(ae,ie,{defaults:{event:"pinch",threshold:0,pointers:2},getTouchAction:function(){return[pt]},attrTest:function(e){return this._super.attrTest.call(this,e)&&(Math.abs(e.scale-1)>this.options.threshold||this.state&_t)},emit:function(e){if(1!==e.scale){var t=e.scale<1?"in":"out";e.additionalEvent=this.options.event+t}this._super.emit.call(this,e)}}),h(se,ee,{defaults:{event:"press",pointers:1,time:251,threshold:9},getTouchAction:function(){return[ft]},process:function(e){var t=this.options,n=e.pointers.length===t.pointers,r=e.distancet.time;if(this._input=e,!r||!n||e.eventType&(Fe|Ie)&&!i)this.reset();else if(e.eventType&De)this.reset(),this._timer=u(function(){this.state=wt,this.tryEmit()},t.time,this);else if(e.eventType&Fe)return wt;return kt},reset:function(){clearTimeout(this._timer)},emit:function(e){this.state===wt&&(e&&e.eventType&Fe?this.manager.emit(this.options.event+"up",e):(this._input.timeStamp=we(),this.manager.emit(this.options.event,this._input)))}}),h(ue,ie,{defaults:{event:"rotate",threshold:0,pointers:2},getTouchAction:function(){return[pt]},attrTest:function(e){return this._super.attrTest.call(this,e)&&(Math.abs(e.rotation)>this.options.threshold||this.state&_t)}}),h(le,ie,{defaults:{event:"swipe",threshold:10,velocity:.3,direction:qe|He,pointers:1},getTouchAction:function(){return oe.prototype.getTouchAction.call(this)},attrTest:function(e){var t,n=this.options.direction;return n&(qe|He)?t=e.overallVelocity:n&qe?t=e.overallVelocityX:n&He&&(t=e.overallVelocityY),this._super.attrTest.call(this,e)&&n&e.offsetDirection&&e.distance>this.options.threshold&&e.maxPointers==this.options.pointers&&be(t)>this.options.velocity&&e.eventType&Fe},emit:function(e){var t=ne(e.offsetDirection);t&&this.manager.emit(this.options.event+t,e),this.manager.emit(this.options.event,e)}}),h(ce,ee,{defaults:{event:"tap",pointers:1,taps:1,interval:300,time:250,threshold:9,posThreshold:10},getTouchAction:function(){return[ht]},process:function(e){var t=this.options,n=e.pointers.length===t.pointers,r=e.distance-1&&this._layers.splice(t,1),this._world.removeLayer(e)}},{key:"_onAdd",value:function(e){return Promise.resolve(this)}},{key:"destroy",value:function(){if(this._layers){for(var e=0;e0){var i=n.getCenter(),o=new v["default"].Vector3(i[0],0,i[1]).sub(t.position).length();if(o>e._options.distance)return!1}return n.getMesh()&&!n.isAborted()||n.requestTileAsync(),!0}),i=this._tileList.filter(function(e){return!r.includes(e)});i.forEach(function(e){return e._abortRequest()}),this._tileList=r}}},{key:"_divide",value:function(e){for(var t,n,r=0;r!=e.length;)t=e[r],n=t.getQuadcode(),t.length!==this._maxLOD&&this._screenSpaceError(t)?(e.splice(r,1),e.push(this._requestTile(n+"0",this)),e.push(this._requestTile(n+"1",this)),e.push(this._requestTile(n+"2",this)),e.push(this._requestTile(n+"3",this))):r++}},{key:"_screenSpaceError",value:function(e){var t=this._minLOD,n=this._maxLOD,r=e.getQuadcode(),i=this._world.getCamera(),o=3;if(r.length===n)return!1;if(r.length1}},{key:"_removeTiles",value:function(){if(this._tiles&&this._tiles.children){for(var e=this._tiles.children.length-1;e>=0;e--)this._tiles.remove(this._tiles.children[e]);if(this._tilesPicking&&this._tilesPicking.children)for(var e=this._tilesPicking.children.length-1;e>=0;e--)this._tilesPicking.remove(this._tilesPicking.children[e])}}},{key:"_createTile",value:function(e,t){}},{key:"_requestTile",value:function(e,t){var n=this._tileCache.getTile(e);return n||(n=this._createTile(e,t),this._tileCache.setTile(e,n)),n}},{key:"_destroyTile",value:function(e){this._tiles.remove(e.getMesh()),e.destroy()}},{key:"show",value:function(){this._stop=!1,this._tilesPicking&&(this._tilesPicking.visible=!0),this._calculateLOD(),s(Object.getPrototypeOf(t.prototype),"show",this).call(this)}},{key:"hide",value:function(){this._stop=!0,this._tilesPicking&&(this._tilesPicking.visible=!1),s(Object.getPrototypeOf(t.prototype),"hide",this).call(this)}},{key:"destroy",value:function(){if(this._destroy=!0,this._tiles.children)for(var e=this._tiles.children.length-1;e>=0;e--)this._tiles.remove(this._tiles.children[e]);if(this.removeFromPicking(this._tilesPicking),this._tilesPicking.children)for(var e=this._tilesPicking.children.length-1;e>=0;e--)this._tilesPicking.remove(this._tilesPicking.children[e]);this._tileCache.destroy(),this._tileCache=null,this._tiles=null,this._tilesPicking=null,this._frustum=null,s(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}]),t}(l["default"]);t["default"]=y,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}Object.defineProperty(t,"__esModule",{value:!0});var o=function(){function e(e,t){for(var n=0;n=t)&&r(this,"max",1/0);var n=e.length||i;"function"!=typeof n&&(n=i),r(this,"lengthCalculator",n),r(this,"allowStale",e.stale||!1),r(this,"maxAge",e.maxAge||0),r(this,"dispose",e.dispose),this.reset()}function a(e,t,n,i){var o=n.value;u(e,o)&&(c(e,n),r(e,"allowStale")||(o=void 0)),o&&t.call(i,o.value,o.key,e)}function s(e,t,n){var i=r(e,"cache").get(t);if(i){var o=i.value;u(e,o)?(c(e,i),r(e,"allowStale")||(o=void 0)):n&&r(e,"lruList").unshiftNode(i),o&&(o=o.value)}return o}function u(e,t){if(!t||!t.maxAge&&!r(e,"maxAge"))return!1;var n=!1,i=Date.now()-t.now;return n=t.maxAge?i>t.maxAge:r(e,"maxAge")&&i>r(e,"maxAge")}function l(e){if(r(e,"length")>r(e,"max"))for(var t=r(e,"lruList").tail;r(e,"length")>r(e,"max")&&null!==t;){var n=t.prev;c(e,t),t=n}}function c(e,t){if(t){var n=t.value;r(e,"dispose")&&r(e,"dispose").call(this,n.key,n.value),r(e,"length",r(e,"length")-n.length),r(e,"cache")["delete"](n.key),r(e,"lruList").removeNode(t)}}function f(e,t,n,r,i){this.key=e,this.value=t,this.length=n,this.now=r,this.maxAge=i||0}e.exports=o;var h,p=n(59),d=n(62),v=n(65),y={},m="function"==typeof Symbol;h=m?function(e){return Symbol["for"](e)}:function(e){return"_"+e},Object.defineProperty(o.prototype,"max",{set:function(e){(!e||"number"!=typeof e||0>=e)&&(e=1/0),r(this,"max",e),l(this)},get:function(){return r(this,"max")},enumerable:!0}),Object.defineProperty(o.prototype,"allowStale",{set:function(e){r(this,"allowStale",!!e)},get:function(){return r(this,"allowStale")},enumerable:!0}),Object.defineProperty(o.prototype,"maxAge",{set:function(e){(!e||"number"!=typeof e||0>e)&&(e=0),r(this,"maxAge",e),l(this)},get:function(){return r(this,"maxAge")},enumerable:!0}),Object.defineProperty(o.prototype,"lengthCalculator",{set:function(e){"function"!=typeof e&&(e=i),e!==r(this,"lengthCalculator")&&(r(this,"lengthCalculator",e),r(this,"length",0),r(this,"lruList").forEach(function(e){e.length=r(this,"lengthCalculator").call(this,e.value,e.key),r(this,"length",r(this,"length")+e.length)},this)),l(this)},get:function(){return r(this,"lengthCalculator")},enumerable:!0}),Object.defineProperty(o.prototype,"length",{get:function(){return r(this,"length")},enumerable:!0}),Object.defineProperty(o.prototype,"itemCount",{get:function(){return r(this,"lruList").length},enumerable:!0}),o.prototype.rforEach=function(e,t){t=t||this;for(var n=r(this,"lruList").tail;null!==n;){var i=n.prev;a(this,e,n,t),n=i}},o.prototype.forEach=function(e,t){t=t||this;for(var n=r(this,"lruList").head;null!==n;){var i=n.next;a(this,e,n,t),n=i}},o.prototype.keys=function(){return r(this,"lruList").toArray().map(function(e){return e.key},this)},o.prototype.values=function(){return r(this,"lruList").toArray().map(function(e){return e.value},this)},o.prototype.reset=function(){r(this,"dispose")&&r(this,"lruList")&&r(this,"lruList").length&&r(this,"lruList").forEach(function(e){r(this,"dispose").call(this,e.key,e.value)},this),r(this,"cache",new p),r(this,"lruList",new v),r(this,"length",0)},o.prototype.dump=function(){return r(this,"lruList").map(function(e){return u(this,e)?void 0:{k:e.key,v:e.value,e:e.now+(e.maxAge||0)}},this).toArray().filter(function(e){return e})},o.prototype.dumpLru=function(){return r(this,"lruList")},o.prototype.inspect=function(e,t){var n="LRUCache {",o=!1,a=r(this,"allowStale");a&&(n+="\n allowStale: true",o=!0);var s=r(this,"max");s&&s!==1/0&&(o&&(n+=","),n+="\n max: "+d.inspect(s,t),o=!0);var l=r(this,"maxAge");l&&(o&&(n+=","),n+="\n maxAge: "+d.inspect(l,t),o=!0);var c=r(this,"lengthCalculator");c&&c!==i&&(o&&(n+=","),n+="\n length: "+d.inspect(r(this,"length"),t),o=!0);var f=!1;return r(this,"lruList").forEach(function(e){f?n+=",\n ":(o&&(n+=",\n"),f=!0,n+="\n ");var r=d.inspect(e.key).split("\n").join("\n "),a={value:e.value};e.maxAge!==l&&(a.maxAge=e.maxAge),c!==i&&(a.length=e.length),u(this,e)&&(a.stale=!0),a=d.inspect(a,t).split("\n").join("\n "),n+=r+" => "+a}),(f||o)&&(n+="\n"),n+="}"},o.prototype.set=function(e,t,n){n=n||r(this,"maxAge");var i=n?Date.now():0,o=r(this,"lengthCalculator").call(this,t,e);if(r(this,"cache").has(e)){if(o>r(this,"max"))return c(this,r(this,"cache").get(e)),!1;var a=r(this,"cache").get(e),s=a.value;return r(this,"dispose")&&r(this,"dispose").call(this,e,s.value),s.now=i,s.maxAge=n,s.value=t,r(this,"length",r(this,"length")+(o-s.length)),s.length=o,this.get(e),l(this),!0}var u=new f(e,t,o,i,n);return u.length>r(this,"max")?(r(this,"dispose")&&r(this,"dispose").call(this,e,t),!1):(r(this,"length",r(this,"length")+u.length),r(this,"lruList").unshift(u),r(this,"cache").set(e,r(this,"lruList").head),l(this),!0)},o.prototype.has=function(e){if(!r(this,"cache").has(e))return!1;var t=r(this,"cache").get(e).value;return!u(this,t)},o.prototype.get=function(e){return s(this,e,!0)},o.prototype.peek=function(e){return s(this,e,!1)},o.prototype.pop=function(){var e=r(this,"lruList").tail;return e?(c(this,e),e.value):null},o.prototype.del=function(e){c(this,r(this,"cache").get(e))},o.prototype.load=function(e){this.reset();for(var t=Date.now(),n=e.length-1;n>=0;n--){var r=e[n],i=r.e||0;if(0===i)this.set(r.k,r.v);else{var o=i-t;o>0&&this.set(r.k,r.v,o)}}},o.prototype.prune=function(){var e=this;r(this,"cache").forEach(function(t,n){s(e,n,!1)})}},function(e,t,n){(function(t){"pseudomap"===t.env.npm_package_name&&"test"===t.env.npm_lifecycle_script&&(t.env.TEST_PSEUDOMAP="true"),"function"!=typeof Map||t.env.TEST_PSEUDOMAP?e.exports=n(61):e.exports=Map}).call(t,n(60))},function(e,t){function n(){f&&l&&(f=!1,l.length?c=l.concat(c):h=-1,c.length&&r())}function r(){if(!f){var e=a(n);f=!0;for(var t=c.length;t;){for(l=c,c=[];++h1)for(var n=1;n=3&&(r.depth=arguments[2]),arguments.length>=4&&(r.colors=arguments[3]),v(n)?r.showHidden=n:n&&t._extend(r,n),w(r.showHidden)&&(r.showHidden=!1),w(r.depth)&&(r.depth=2),w(r.colors)&&(r.colors=!1),w(r.customInspect)&&(r.customInspect=!0),r.colors&&(r.stylize=o),u(r,e,r.depth)}function o(e,t){var n=i.styles[t];return n?"["+i.colors[n][0]+"m"+e+"["+i.colors[n][1]+"m":e}function a(e,t){return e}function s(e){var t={};return e.forEach(function(e,n){t[e]=!0}),t}function u(e,n,r){if(e.customInspect&&n&&P(n.inspect)&&n.inspect!==t.inspect&&(!n.constructor||n.constructor.prototype!==n)){var i=n.inspect(r,e);return g(i)||(i=u(e,i,r)),i}var o=l(e,n);if(o)return o;var a=Object.keys(n),v=s(a);if(e.showHidden&&(a=Object.getOwnPropertyNames(n)),M(n)&&(a.indexOf("message")>=0||a.indexOf("description")>=0))return c(n);if(0===a.length){if(P(n)){var y=n.name?": "+n.name:"";return e.stylize("[Function"+y+"]","special")}if(x(n))return e.stylize(RegExp.prototype.toString.call(n),"regexp");if(O(n))return e.stylize(Date.prototype.toString.call(n),"date");if(M(n))return c(n)}var m="",_=!1,b=["{","}"];if(d(n)&&(_=!0,b=["[","]"]),P(n)){var w=n.name?": "+n.name:"";m=" [Function"+w+"]"}if(x(n)&&(m=" "+RegExp.prototype.toString.call(n)),O(n)&&(m=" "+Date.prototype.toUTCString.call(n)),M(n)&&(m=" "+c(n)),0===a.length&&(!_||0==n.length))return b[0]+m+b[1];if(0>r)return x(n)?e.stylize(RegExp.prototype.toString.call(n),"regexp"):e.stylize("[Object]","special");e.seen.push(n);var k;return k=_?f(e,n,r,v,a):a.map(function(t){return h(e,n,r,v,t,_)}),e.seen.pop(),p(k,m,b)}function l(e,t){if(w(t))return e.stylize("undefined","undefined");if(g(t)){var n="'"+JSON.stringify(t).replace(/^"|"$/g,"").replace(/'/g,"\\'").replace(/\\"/g,'"')+"'";return e.stylize(n,"string")}return _(t)?e.stylize(""+t,"number"):v(t)?e.stylize(""+t,"boolean"):y(t)?e.stylize("null","null"):void 0}function c(e){return"["+Error.prototype.toString.call(e)+"]"}function f(e,t,n,r,i){for(var o=[],a=0,s=t.length;s>a;++a)A(t,String(a))?o.push(h(e,t,n,r,String(a),!0)):o.push("");return i.forEach(function(i){i.match(/^\d+$/)||o.push(h(e,t,n,r,i,!0))}),o}function h(e,t,n,r,i,o){var a,s,l;if(l=Object.getOwnPropertyDescriptor(t,i)||{value:t[i]},l.get?s=l.set?e.stylize("[Getter/Setter]","special"):e.stylize("[Getter]","special"):l.set&&(s=e.stylize("[Setter]","special")),A(r,i)||(a="["+i+"]"),s||(e.seen.indexOf(l.value)<0?(s=y(n)?u(e,l.value,null):u(e,l.value,n-1),s.indexOf("\n")>-1&&(s=o?s.split("\n").map(function(e){return" "+e}).join("\n").substr(2):"\n"+s.split("\n").map(function(e){return" "+e}).join("\n"))):s=e.stylize("[Circular]","special")),w(a)){if(o&&i.match(/^\d+$/))return s;a=JSON.stringify(""+i),a.match(/^"([a-zA-Z_][a-zA-Z_0-9]*)"$/)?(a=a.substr(1,a.length-2),a=e.stylize(a,"name")):(a=a.replace(/'/g,"\\'").replace(/\\"/g,'"').replace(/(^"|"$)/g,"'"),a=e.stylize(a,"string"))}return a+": "+s}function p(e,t,n){var r=0,i=e.reduce(function(e,t){return r++,t.indexOf("\n")>=0&&r++,e+t.replace(/\u001b\[\d\d?m/g,"").length+1},0);return i>60?n[0]+(""===t?"":t+"\n ")+" "+e.join(",\n ")+" "+n[1]:n[0]+t+" "+e.join(", ")+" "+n[1]}function d(e){return Array.isArray(e)}function v(e){return"boolean"==typeof e}function y(e){return null===e}function m(e){return null==e}function _(e){return"number"==typeof e}function g(e){return"string"==typeof e}function b(e){return"symbol"==typeof e}function w(e){return void 0===e}function x(e){return k(e)&&"[object RegExp]"===T(e)}function k(e){return"object"==typeof e&&null!==e}function O(e){return k(e)&&"[object Date]"===T(e); +}function M(e){return k(e)&&("[object Error]"===T(e)||e instanceof Error)}function P(e){return"function"==typeof e}function E(e){return null===e||"boolean"==typeof e||"number"==typeof e||"string"==typeof e||"symbol"==typeof e||"undefined"==typeof e}function T(e){return Object.prototype.toString.call(e)}function S(e){return 10>e?"0"+e.toString(10):e.toString(10)}function j(){var e=new Date,t=[S(e.getHours()),S(e.getMinutes()),S(e.getSeconds())].join(":");return[e.getDate(),R[e.getMonth()],t].join(" ")}function A(e,t){return Object.prototype.hasOwnProperty.call(e,t)}var C=/%[sdj%]/g;t.format=function(e){if(!g(e)){for(var t=[],n=0;n=o)return e;switch(e){case"%s":return String(r[n++]);case"%d":return Number(r[n++]);case"%j":try{return JSON.stringify(r[n++])}catch(t){return"[Circular]"}default:return e}}),s=r[n];o>n;s=r[++n])a+=y(s)||!k(s)?" "+s:" "+i(s);return a},t.deprecate=function(n,i){function o(){if(!a){if(r.throwDeprecation)throw new Error(i);r.traceDeprecation?console.trace(i):console.error(i),a=!0}return n.apply(this,arguments)}if(w(e.process))return function(){return t.deprecate(n,i).apply(this,arguments)};if(r.noDeprecation===!0)return n;var a=!1;return o};var L,D={};t.debuglog=function(e){if(w(L)&&(L=r.env.NODE_DEBUG||""),e=e.toUpperCase(),!D[e])if(new RegExp("\\b"+e+"\\b","i").test(L)){var n=r.pid;D[e]=function(){var r=t.format.apply(t,arguments);console.error("%s %d: %s",e,n,r)}}else D[e]=function(){};return D[e]},t.inspect=i,i.colors={bold:[1,22],italic:[3,23],underline:[4,24],inverse:[7,27],white:[37,39],grey:[90,39],black:[30,39],blue:[34,39],cyan:[36,39],green:[32,39],magenta:[35,39],red:[31,39],yellow:[33,39]},i.styles={special:"cyan",number:"yellow","boolean":"yellow",undefined:"grey","null":"bold",string:"green",date:"magenta",regexp:"red"},t.isArray=d,t.isBoolean=v,t.isNull=y,t.isNullOrUndefined=m,t.isNumber=_,t.isString=g,t.isSymbol=b,t.isUndefined=w,t.isRegExp=x,t.isObject=k,t.isDate=O,t.isError=M,t.isFunction=P,t.isPrimitive=E,t.isBuffer=n(63);var R=["Jan","Feb","Mar","Apr","May","Jun","Jul","Aug","Sep","Oct","Nov","Dec"];t.log=function(){console.log("%s - %s",j(),t.format.apply(t,arguments))},t.inherits=n(64),t._extend=function(e,t){if(!t||!k(t))return e;for(var n=Object.keys(t),r=n.length;r--;)e[n[r]]=t[n[r]];return e}}).call(t,function(){return this}(),n(60))},function(e,t){e.exports=function(e){return e&&"object"==typeof e&&"function"==typeof e.copy&&"function"==typeof e.fill&&"function"==typeof e.readUInt8}},function(e,t){"function"==typeof Object.create?e.exports=function(e,t){e.super_=t,e.prototype=Object.create(t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}})}:e.exports=function(e,t){e.super_=t;var n=function(){};n.prototype=t.prototype,e.prototype=new n,e.prototype.constructor=e}},function(e,t){function n(e){var t=this;if(t instanceof n||(t=new n),t.tail=null,t.head=null,t.length=0,e&&"function"==typeof e.forEach)e.forEach(function(e){t.push(e)});else if(arguments.length>0)for(var r=0,i=arguments.length;i>r;r++)t.push(arguments[r]);return t}function r(e,t){e.tail=new o(t,e.tail,null,e),e.head||(e.head=e.tail),e.length++}function i(e,t){e.head=new o(t,null,e.head,e),e.tail||(e.tail=e.head),e.length++}function o(e,t,n,r){return this instanceof o?(this.list=r,this.value=e,t?(t.next=this,this.prev=t):this.prev=null,void(n?(n.prev=this,this.next=n):this.next=null)):new o(e,t,n,r)}e.exports=n,n.Node=o,n.create=n,n.prototype.removeNode=function(e){if(e.list!==this)throw new Error("removing node which does not belong to this list");var t=e.next,n=e.prev;t&&(t.prev=n),n&&(n.next=t),e===this.head&&(this.head=t),e===this.tail&&(this.tail=n),e.list.length--,e.next=null,e.prev=null,e.list=null},n.prototype.unshiftNode=function(e){if(e!==this.head){e.list&&e.list.removeNode(e);var t=this.head;e.list=this,e.next=t,t&&(t.prev=e),this.head=e,this.tail||(this.tail=e),this.length++}},n.prototype.pushNode=function(e){if(e!==this.tail){e.list&&e.list.removeNode(e);var t=this.tail;e.list=this,e.prev=t,t&&(t.next=e),this.tail=e,this.head||(this.head=e),this.length++}},n.prototype.push=function(){for(var e=0,t=arguments.length;t>e;e++)r(this,arguments[e]);return this.length},n.prototype.unshift=function(){for(var e=0,t=arguments.length;t>e;e++)i(this,arguments[e]);return this.length},n.prototype.pop=function(){if(this.tail){var e=this.tail.value;return this.tail=this.tail.prev,this.tail.next=null,this.length--,e}},n.prototype.shift=function(){if(this.head){var e=this.head.value;return this.head=this.head.next,this.head.prev=null,this.length--,e}},n.prototype.forEach=function(e,t){t=t||this;for(var n=this.head,r=0;null!==n;r++)e.call(t,n.value,r,this),n=n.next},n.prototype.forEachReverse=function(e,t){t=t||this;for(var n=this.tail,r=this.length-1;null!==n;r--)e.call(t,n.value,r,this),n=n.prev},n.prototype.get=function(e){for(var t=0,n=this.head;null!==n&&e>t;t++)n=n.next;return t===e&&null!==n?n.value:void 0},n.prototype.getReverse=function(e){for(var t=0,n=this.tail;null!==n&&e>t;t++)n=n.prev;return t===e&&null!==n?n.value:void 0},n.prototype.map=function(e,t){t=t||this;for(var r=new n,i=this.head;null!==i;)r.push(e.call(t,i.value,this)),i=i.next;return r},n.prototype.mapReverse=function(e,t){t=t||this;for(var r=new n,i=this.tail;null!==i;)r.push(e.call(t,i.value,this)),i=i.prev;return r},n.prototype.reduce=function(e,t){var n,r=this.head;if(arguments.length>1)n=t;else{if(!this.head)throw new TypeError("Reduce of empty list with no initial value");r=this.head.next,n=this.head.value}for(var i=0;null!==r;i++)n=e(n,r.value,i),r=r.next;return n},n.prototype.reduceReverse=function(e,t){var n,r=this.tail;if(arguments.length>1)n=t;else{if(!this.tail)throw new TypeError("Reduce of empty list with no initial value");r=this.tail.prev,n=this.tail.value}for(var i=this.length-1;null!==r;i--)n=e(n,r.value,i),r=r.prev;return n},n.prototype.toArray=function(){for(var e=new Array(this.length),t=0,n=this.head;null!==n;t++)e[t]=n.value,n=n.next;return e},n.prototype.toArrayReverse=function(){for(var e=new Array(this.length),t=0,n=this.tail;null!==n;t++)e[t]=n.value,n=n.prev;return e},n.prototype.slice=function(e,t){t=t||this.length,0>t&&(t+=this.length),e=e||0,0>e&&(e+=this.length);var r=new n;if(e>t||0>t)return r;0>e&&(e=0),t>this.length&&(t=this.length);for(var i=0,o=this.head;null!==o&&e>i;i++)o=o.next;for(;null!==o&&t>i;i++,o=o.next)r.push(o.value);return r},n.prototype.sliceReverse=function(e,t){t=t||this.length,0>t&&(t+=this.length),e=e||0,0>e&&(e+=this.length);var r=new n;if(e>t||0>t)return r;0>e&&(e=0),t>this.length&&(t=this.length);for(var i=this.length,o=this.tail;null!==o&&i>t;i--)o=o.prev;for(;null!==o&&i>e;i--,o=o.prev)r.push(o.value);return r},n.prototype.reverse=function(){for(var e=this.head,t=this.tail,n=e;null!==n;n=n.prev){var r=n.prev;n.prev=n.next,n.next=r}return this.head=t,this.tail=e,this}},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}function i(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}function o(e,t){if("function"!=typeof t&&null!==t)throw new TypeError("Super expression must either be null or a function, not "+typeof t);e.prototype=Object.create(t&&t.prototype,{constructor:{value:e,enumerable:!1,writable:!0,configurable:!0}}),t&&(Object.setPrototypeOf?Object.setPrototypeOf(e,t):e.__proto__=t)}Object.defineProperty(t,"__esModule",{value:!0});var a=function(){function e(e,t){for(var n=0;n0;i--){var o=1<0){var y,_=m["default"].mergeAttributes(r);i.length>0&&(y=m["default"].mergeAttributes(i)),d="function"==typeof t._options.style?t._options.style(t._geojson.features[0]):t._options.style,d=(0,f["default"])({},v["default"].defaultStyle,d),t._setPolygonMesh(_,o,d,a).then(function(e){t._polygonMesh=e.mesh,t.add(t._polygonMesh),y&&(d="function"==typeof t._options.style?t._options.style(t._geojson.features[0]):t._options.style,d=(0,f["default"])({},v["default"].defaultStyle,d),void 0!==d.outlineRenderOrder?d.lineRenderOrder=d.outlineRenderOrder:d.lineRenderOrder=d.renderOrder?d.renderOrder+1:4,d.outlineWidth&&(d.lineWidth=d.outlineWidth),t._setPolylineMesh(y,u,d,!0).then(function(e){t.add(e.mesh)})),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh)})}if(s.length>0){var g=m["default"].mergeAttributes(s);d="function"==typeof t._options.style?t._options.style(t._geojson.features[0]):t._options.style,d=(0,f["default"])({},v["default"].defaultStyle,d),t._setPolylineMesh(g,u,d,l).then(function(e){t._polylineMesh=e.mesh,t.add(t._polylineMesh),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh)})}if(c.length>0){var w=m["default"].mergeAttributes(c);d="function"==typeof t._options.style?t._options.style(t._geojson.features[0]):t._options.style,d=(0,f["default"])({},v["default"].defaultStyle,d),t._setPointMesh(w,h,d,p).then(function(e){t._pointMesh=e.mesh,t.add(t._pointMesh),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh)})}t._layers.forEach(function(e){e.clearBufferAttributes(),e.clearCoordinates()}),n()})})}},{key:"_setPolygonMesh",value:function(e,t,n,r){return b["default"].SetMesh(e,t,r,n,this._options,this._world._environment._skybox)}},{key:"_setPolylineMesh",value:function(e,t,n,r){return x["default"].SetMesh(e,t,r,n,this._options)}},{key:"_setPointMesh",value:function(e,t,n,r){return O["default"].SetMesh(e,t,r,n,this._options)}},{key:"_featureToLayer",value:function(e,t){var n=e.geometry,r=n.coordinates?n.coordinates:null;return r&&n?"Polygon"===n.type||"MultiPolygon"===n.type?("function"==typeof this._options.polygonMaterial&&(t.polygonMaterial=this._options.polygonMaterial(e)),"function"==typeof this._options.onPolygonMesh&&(t.onPolygonMesh=this._options.onPolygonMesh),"function"==typeof this._options.onPolygonBufferAttributes&&(t.onBufferAttributes=this._options.onPolygonBufferAttributes),new b["default"](r,t)):"LineString"===n.type||"MultiLineString"===n.type?("function"==typeof this._options.lineMaterial&&(t.lineMaterial=this._options.lineMaterial(e)),"function"==typeof this._options.onPolylineMesh&&(t.onPolylineMesh=this._options.onPolylineMesh),"function"==typeof this._options.onPolylineBufferAttributes&&(t.onBufferAttributes=this._options.onPolylineBufferAttributes),new x["default"](r,t)):"Point"===n.type||"MultiPoint"===n.type?("function"==typeof this._options.pointGeometry&&(t.pointGeometry=this._options.pointGeometry(e)),"function"==typeof this._options.pointMaterial&&(t.pointMaterial=this._options.pointMaterial(e)),"function"==typeof this._options.onPointMesh&&(t.onPointMesh=this._options.onPointMesh),new O["default"](r,t)):void 0:void 0}},{key:"_abortRequest",value:function(){this._request&&this._request.abort()}},{key:"destroy",value:function(){this._abortRequest(),this._request=null,this._geojson=null,this._pickingMesh&&(this._pickingMesh=null),this._polygonMesh&&(this._polygonMesh=null),this._polylineMesh&&(this._polylineMesh=null),this._pointMesh&&(this._pointMesh=null),s(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}]),t}(l["default"]);t["default"]=M;var P=function(e,t){return new M(e,t)};t.geoJSONLayer=P},function(module,exports,__webpack_require__){var __WEBPACK_AMD_DEFINE_FACTORY__,__WEBPACK_AMD_DEFINE_RESULT__;!function(e,t,n){"undefined"!=typeof module&&module.exports?module.exports=n():(__WEBPACK_AMD_DEFINE_FACTORY__=n,__WEBPACK_AMD_DEFINE_RESULT__="function"==typeof __WEBPACK_AMD_DEFINE_FACTORY__?__WEBPACK_AMD_DEFINE_FACTORY__.call(exports,__webpack_require__,exports,module):__WEBPACK_AMD_DEFINE_FACTORY__,!(void 0!==__WEBPACK_AMD_DEFINE_RESULT__&&(module.exports=__WEBPACK_AMD_DEFINE_RESULT__)))}("reqwest",this,function(){function succeed(e){var t=protocolRe.exec(e.url);return t=t&&t[1]||context.location.protocol,httpsRe.test(t)?twoHundo.test(e.request.status):!!e.request.response}function handleReadyState(e,t,n){return function(){return e._aborted?n(e.request):e._timedOut?n(e.request,"Request is aborted: timeout"):void(e.request&&4==e.request[readyState]&&(e.request.onreadystatechange=noop,succeed(e)?t(e.request):n(e.request)))}}function setHeaders(e,t){var n,r=t.headers||{};r.Accept=r.Accept||defaultHeaders.accept[t.type]||defaultHeaders.accept["*"];var i="undefined"!=typeof FormData&&t.data instanceof FormData;t.crossOrigin||r[requestedWith]||(r[requestedWith]=defaultHeaders.requestedWith),r[contentType]||i||(r[contentType]=t.contentType||defaultHeaders.contentType);for(n in r)r.hasOwnProperty(n)&&"setRequestHeader"in e&&e.setRequestHeader(n,r[n])}function setCredentials(e,t){"undefined"!=typeof t.withCredentials&&"undefined"!=typeof e.withCredentials&&(e.withCredentials=!!t.withCredentials)}function generalCallback(e){lastValue=e}function urlappend(e,t){return e+(/\?/.test(e)?"&":"?")+t}function handleJsonp(e,t,n,r){var i=uniqid++,o=e.jsonpCallback||"callback",a=e.jsonpCallbackName||reqwest.getcallbackPrefix(i),s=new RegExp("((^|\\?|&)"+o+")=([^&]+)"),u=r.match(s),l=doc.createElement("script"),c=0,f=-1!==navigator.userAgent.indexOf("MSIE 10.0");return u?"?"===u[3]?r=r.replace(s,"$1="+a):a=u[3]:r=urlappend(r,o+"="+a), +context[a]=generalCallback,l.type="text/javascript",l.src=r,l.async=!0,"undefined"==typeof l.onreadystatechange||f||(l.htmlFor=l.id="_reqwest_"+i),l.onload=l.onreadystatechange=function(){return l[readyState]&&"complete"!==l[readyState]&&"loaded"!==l[readyState]||c?!1:(l.onload=l.onreadystatechange=null,l.onclick&&l.onclick(),t(lastValue),lastValue=void 0,head.removeChild(l),void(c=1))},head.appendChild(l),{abort:function(){l.onload=l.onreadystatechange=null,n({},"Request is aborted: timeout",{}),lastValue=void 0,head.removeChild(l),c=1}}}function getRequest(e,t){var n,r=this.o,i=(r.method||"GET").toUpperCase(),o="string"==typeof r?r:r.url,a=r.processData!==!1&&r.data&&"string"!=typeof r.data?reqwest.toQueryString(r.data):r.data||null,s=!1;return"jsonp"!=r.type&&"GET"!=i||!a||(o=urlappend(o,a),a=null),"jsonp"==r.type?handleJsonp(r,e,t,o):(n=r.xhr&&r.xhr(r)||xhr(r),n.open(i,o,r.async!==!1),setHeaders(n,r),setCredentials(n,r),context[xDomainRequest]&&n instanceof context[xDomainRequest]?(n.onload=e,n.onerror=t,n.onprogress=function(){},s=!0):n.onreadystatechange=handleReadyState(this,e,t),r.before&&r.before(n),s?setTimeout(function(){n.send(a)},200):n.send(a),n)}function Reqwest(e,t){this.o=e,this.fn=t,init.apply(this,arguments)}function setType(e){return null!==e?e.match("json")?"json":e.match("javascript")?"js":e.match("text")?"html":e.match("xml")?"xml":void 0:void 0}function init(o,fn){function complete(e){for(o.timeout&&clearTimeout(self.timeout),self.timeout=null;self._completeHandlers.length>0;)self._completeHandlers.shift()(e)}function success(resp){var type=o.type||resp&&setType(resp.getResponseHeader("Content-Type"));resp="jsonp"!==type?self.request:resp;var filteredResponse=globalSetupOptions.dataFilter(resp.responseText,type),r=filteredResponse;try{resp.responseText=r}catch(e){}if(r)switch(type){case"json":try{resp=context.JSON?context.JSON.parse(r):eval("("+r+")")}catch(err){return error(resp,"Could not parse JSON in response",err)}break;case"js":resp=eval(r);break;case"html":resp=r;break;case"xml":resp=resp.responseXML&&resp.responseXML.parseError&&resp.responseXML.parseError.errorCode&&resp.responseXML.parseError.reason?null:resp.responseXML}for(self._responseArgs.resp=resp,self._fulfilled=!0,fn(resp),self._successHandler(resp);self._fulfillmentHandlers.length>0;)resp=self._fulfillmentHandlers.shift()(resp);complete(resp)}function timedOut(){self._timedOut=!0,self.request.abort()}function error(e,t,n){for(e=self.request,self._responseArgs.resp=e,self._responseArgs.msg=t,self._responseArgs.t=n,self._erred=!0;self._errorHandlers.length>0;)self._errorHandlers.shift()(e,t,n);complete(e)}this.url="string"==typeof o?o:o.url,this.timeout=null,this._fulfilled=!1,this._successHandler=function(){},this._fulfillmentHandlers=[],this._errorHandlers=[],this._completeHandlers=[],this._erred=!1,this._responseArgs={};var self=this;fn=fn||function(){},o.timeout&&(this.timeout=setTimeout(function(){timedOut()},o.timeout)),o.success&&(this._successHandler=function(){o.success.apply(o,arguments)}),o.error&&this._errorHandlers.push(function(){o.error.apply(o,arguments)}),o.complete&&this._completeHandlers.push(function(){o.complete.apply(o,arguments)}),this.request=getRequest.call(this,success,error)}function reqwest(e,t){return new Reqwest(e,t)}function normalize(e){return e?e.replace(/\r?\n/g,"\r\n"):""}function serial(e,t){var n,r,i,o,a=e.name,s=e.tagName.toLowerCase(),u=function(e){e&&!e.disabled&&t(a,normalize(e.attributes.value&&e.attributes.value.specified?e.value:e.text))};if(!e.disabled&&a)switch(s){case"input":/reset|button|image|file/i.test(e.type)||(n=/checkbox/i.test(e.type),r=/radio/i.test(e.type),i=e.value,(!(n||r)||e.checked)&&t(a,normalize(n&&""===i?"on":i)));break;case"textarea":t(a,normalize(e.value));break;case"select":if("select-one"===e.type.toLowerCase())u(e.selectedIndex>=0?e.options[e.selectedIndex]:null);else for(o=0;e.length&&oa;a++)n.vertices.push(e[i][o][a]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n},u=function(e,t,n){var r=(0,p["default"])(e,t,n),o=[];for(i=0,il=r.length;in;){var i=n+r>>>1;e[i]e?~e:e],o=0,a=r.length;a>o;++o)t.push(n=r[o].slice()),c(n,o);0>e&&i(t,a)}function o(e){return e=e.slice(),c(e,0),e}function a(e){for(var t=[],n=0,i=e.length;i>n;++n)r(e[n],t);return t.length<2&&t.push(t[0].slice()),t}function s(e){for(var t=a(e);t.length<4;)t.push(t[0].slice());return t}function u(e){return e.map(s)}function l(e){var t=e.type;return"GeometryCollection"===t?{type:t,geometries:e.geometries.map(l)}:t in h?{type:t,coordinates:h[t](e)}:null}var c=n(e.transform),f=e.arcs,h={Point:function(e){return o(e.coordinates)},MultiPoint:function(e){return e.coordinates.map(o)},LineString:function(e){return a(e.arcs)},MultiLineString:function(e){return e.arcs.map(a)},Polygon:function(e){return u(e.arcs)},MultiPolygon:function(e){return e.arcs.map(u)}};return l(t)}function l(e,t){function n(t){var n,r=e.arcs[0>t?~t:t],i=r[0];return e.transform?(n=[0,0],r.forEach(function(e){n[0]+=e[0],n[1]+=e[1]})):n=r[r.length-1],0>t?[n,i]:[i,n]}function r(e,t){for(var n in e){var r=e[n];delete t[r.start],delete r.start,delete r.end,r.forEach(function(e){i[0>e?~e:e]=1}),s.push(r)}}var i={},o={},a={},s=[],u=-1;return t.forEach(function(n,r){var i,o=e.arcs[0>n?~n:n];o.length<3&&!o[1][0]&&!o[1][1]&&(i=t[++u],t[u]=n,t[r]=i)}),t.forEach(function(e){var t,r,i=n(e),s=i[0],u=i[1];if(t=a[s])if(delete a[t.end],t.push(e),t.end=u,r=o[u]){delete o[r.start];var l=r===t?t:t.concat(r);o[l.start=t.start]=a[l.end=r.end]=l}else o[t.start]=a[t.end]=t;else if(t=o[u])if(delete o[t.start],t.unshift(e),t.start=s,r=a[s]){delete a[r.end];var c=r===t?t:r.concat(t);o[c.start=r.start]=a[c.end=t.end]=c}else o[t.start]=a[t.end]=t;else t=[e],o[t.start=s]=a[t.end=u]=t}),r(a,o),r(o,a),t.forEach(function(e){i[0>e?~e:e]||s.push([e])}),s}function c(e){return u(e,f.apply(this,arguments))}function f(e,t,n){function r(e){var t=0>e?~e:e;(c[t]||(c[t]=[])).push({i:e,g:u})}function i(e){e.forEach(r)}function o(e){e.forEach(i)}function a(e){"GeometryCollection"===e.type?e.geometries.forEach(a):e.type in f&&(u=e,f[e.type](e.arcs))}var s=[];if(arguments.length>1){var u,c=[],f={LineString:i,MultiLineString:o,Polygon:o,MultiPolygon:function(e){e.forEach(o)}};a(t),c.forEach(arguments.length<3?function(e){s.push(e[0].i)}:function(e){n(e[0].g,e[e.length-1].g)&&s.push(e[0].i)})}else for(var h=0,p=e.arcs.length;p>h;++h)s.push(h);return{type:"MultiLineString",arcs:l(e,s)}}function h(e){var t=e[0],n=e[1],r=e[2];return Math.abs((t[0]-r[0])*(n[1]-t[1])-(t[0]-n[0])*(r[1]-t[1]))}function p(e){for(var t,n=-1,r=e.length,i=e[r-1],o=0;++nt?~t:t]||(i[t]=[])).push(e)})}),o.push(e)}function r(t){return Math.abs(p(u(e,{type:"Polygon",arcs:[t]}).coordinates[0]))}var i={},o=[],a=[];return t.forEach(function(e){"Polygon"===e.type?n(e.arcs):"MultiPolygon"===e.type&&e.arcs.forEach(n)}),o.forEach(function(e){if(!e._){var t=[],n=[e];for(e._=1,a.push(t);e=n.pop();)t.push(e),e.forEach(function(e){e.forEach(function(e){i[0>e?~e:e].forEach(function(e){e._||(e._=1,n.push(e))})})})}}),o.forEach(function(e){delete e._}),{type:"MultiPolygon",arcs:a.map(function(t){var n,o=[];if(t.forEach(function(e){e.forEach(function(e){e.forEach(function(e){i[0>e?~e:e].length<2&&o.push(e)})})}),o=l(e,o),(n=o.length)>1)for(var a,s,u=1,c=r(o[0]);n>u;++u)(a=r(o[u]))>c&&(s=o[0],o[0]=o[u],o[u]=s,c=a);return o})}}function y(e){function t(e,t){e.forEach(function(e){0>e&&(e=~e);var n=i[e];n?n.push(t):i[e]=[t]})}function n(e,n){e.forEach(function(e){t(e,n)})}function r(e,t){"GeometryCollection"===e.type?e.geometries.forEach(function(e){r(e,t)}):e.type in s&&s[e.type](e.arcs,t)}var i={},a=e.map(function(){return[]}),s={LineString:t,MultiLineString:n,Polygon:n,MultiPolygon:function(e,t){e.forEach(function(e){n(e,t)})}};e.forEach(r);for(var u in i)for(var l=i[u],c=l.length,f=0;c>f;++f)for(var h=f+1;c>h;++h){var p,d=l[f],v=l[h];(p=a[d])[u=o(p,v)]!==v&&p.splice(u,0,v),(p=a[v])[u=o(p,d)]!==d&&p.splice(u,0,d)}return a}function m(e,t){return e[1][2]-t[1][2]}function _(){function e(e,t){for(;t>0;){var n=(t+1>>1)-1,i=r[n];if(m(e,i)>=0)break;r[i._=t]=i,r[e._=t=n]=e}}function t(e,t){for(;;){var n=t+1<<1,o=n-1,a=t,s=r[a];if(i>o&&m(r[o],s)<0&&(s=r[a=o]),i>n&&m(r[n],s)<0&&(s=r[a=n]),a===t)break;r[s._=t]=s,r[e._=t=a]=e}}var n={},r=[],i=0;return n.push=function(t){return e(r[t._=i]=t,i++),i},n.pop=function(){if(!(0>=i)){var e,n=r[0];return--i>0&&(e=r[i],t(r[e._=0]=e,0)),n}},n.remove=function(n){var o,a=n._;if(r[a]===n)return a!==--i&&(o=r[i],(m(o,n)<0?e:t)(r[o._=a]=o,a)),a},n}function g(e,t){function i(e){s.remove(e),e[1][2]=t(e),s.push(e)}var o=n(e.transform),a=r(e.transform),s=_();return t||(t=h),e.arcs.forEach(function(e){var n,r,u,l,c=[],f=0;for(r=0,u=e.length;u>r;++r)l=e[r],o(e[r]=[l[0],l[1],1/0],r);for(r=1,u=e.length-1;u>r;++r)n=e.slice(r-1,r+2),n[1][2]=t(n),c.push(n),s.push(n);for(r=0,u=c.length;u>r;++r)n=c[r],n.previous=c[r-1],n.next=c[r+1];for(;n=s.pop();){var h=n.previous,p=n.next;n[1][2]80*n){l=h=e[0],f=p=e[1];for(var m=n;a>m;m+=n)d=e[m],v=e[m+1],l>d&&(l=d),f>v&&(f=v),d>h&&(h=d),v>p&&(p=v);y=Math.max(h-l,p-f)}return o(s,u,n,l,f,y),u}function r(e,t,n,r,i){var o,a;if(i===j(e,t,n,r)>0)for(o=t;n>o;o+=r)a=E(o,e[o],e[o+1],a);else for(o=n-r;o>=t;o-=r)a=E(o,e[o],e[o+1],a);return a&&w(a,a.next)&&(T(a),a=a.next),a}function i(e,t){if(!e)return e;t||(t=e);var n,r=e;do if(n=!1,r.steiner||!w(r,r.next)&&0!==b(r.prev,r,r.next))r=r.next;else{if(T(r),r=t=r.prev,r===r.next)return null;n=!0}while(n||r!==t);return t}function o(e,t,n,r,c,f,h){if(e){!h&&f&&d(e,r,c,f);for(var p,v,y=e;e.prev!==e.next;)if(p=e.prev,v=e.next,f?s(e,r,c,f):a(e))t.push(p.i/n),t.push(e.i/n),t.push(v.i/n),T(e),e=v.next,y=v.next;else if(e=v,e===y){h?1===h?(e=u(e,t,n),o(e,t,n,r,c,f,2)):2===h&&l(e,t,n,r,c,f):o(i(e),t,n,r,c,f,1);break}}}function a(e){var t=e.prev,n=e,r=e.next;if(b(t,n,r)>=0)return!1;for(var i=e.next.next;i!==e.prev;){if(_(t.x,t.y,n.x,n.y,r.x,r.y,i.x,i.y)&&b(i.prev,i,i.next)>=0)return!1;i=i.next}return!0}function s(e,t,n,r){var i=e.prev,o=e,a=e.next;if(b(i,o,a)>=0)return!1;for(var s=i.xo.x?i.x>a.x?i.x:a.x:o.x>a.x?o.x:a.x,c=i.y>o.y?i.y>a.y?i.y:a.y:o.y>a.y?o.y:a.y,f=y(s,u,t,n,r),h=y(l,c,t,n,r),p=e.nextZ;p&&p.z<=h;){if(p!==e.prev&&p!==e.next&&_(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&b(p.prev,p,p.next)>=0)return!1;p=p.nextZ}for(p=e.prevZ;p&&p.z>=f;){if(p!==e.prev&&p!==e.next&&_(i.x,i.y,o.x,o.y,a.x,a.y,p.x,p.y)&&b(p.prev,p,p.next)>=0)return!1;p=p.prevZ}return!0}function u(e,t,n){var r=e;do{var i=r.prev,o=r.next.next;!w(i,o)&&x(i,r,r.next,o)&&O(i,o)&&O(o,i)&&(t.push(i.i/n),t.push(r.i/n),t.push(o.i/n),T(r),T(r.next),r=e=o),r=r.next}while(r!==e);return r}function l(e,t,n,r,a,s){var u=e;do{for(var l=u.next.next;l!==u.prev;){if(u.i!==l.i&&g(u,l)){var c=P(u,l);return u=i(u,u.next),c=i(c,c.next),o(u,t,n,r,a,s),void o(c,t,n,r,a,s)}l=l.next}u=u.next}while(u!==e)}function c(e,t,n,o){var a,s,u,l,c,p=[];for(a=0,s=t.length;s>a;a++)u=t[a]*o,l=s-1>a?t[a+1]*o:e.length,c=r(e,u,l,o,!1),c===c.next&&(c.steiner=!0),p.push(m(c));for(p.sort(f),a=0;a=r.next.y){var s=r.x+(o-r.y)*(r.next.x-r.x)/(r.next.y-r.y);if(i>=s&&s>a){if(a=s,s===i){if(o===r.y)return r;if(o===r.next.y)return r.next}n=r.x=r.x&&r.x>=c&&_(f>o?i:a,o,c,f,f>o?a:i,o,r.x,r.y)&&(u=Math.abs(o-r.y)/(i-r.x),(h>u||u===h&&r.x>n.x)&&O(r,e)&&(n=r,h=u)),r=r.next;return n}function d(e,t,n,r){var i=e;do null===i.z&&(i.z=y(i.x,i.y,t,n,r)),i.prevZ=i.prev,i.nextZ=i.next,i=i.next;while(i!==e);i.prevZ.nextZ=null,i.prevZ=null,v(i)}function v(e){var t,n,r,i,o,a,s,u,l=1;do{for(n=e,e=null,o=null,a=0;n;){for(a++,r=n,s=0,t=0;l>t&&(s++,r=r.nextZ,r);t++);for(u=l;s>0||u>0&&r;)0===s?(i=r,r=r.nextZ,u--):0!==u&&r?n.z<=r.z?(i=n,n=n.nextZ,s--):(i=r,r=r.nextZ,u--):(i=n,n=n.nextZ,s--),o?o.nextZ=i:e=i,i.prevZ=o,o=i;n=r}o.nextZ=null,l*=2}while(a>1);return e}function y(e,t,n,r,i){return e=32767*(e-n)/i,t=32767*(t-r)/i,e=16711935&(e|e<<8),e=252645135&(e|e<<4),e=858993459&(e|e<<2),e=1431655765&(e|e<<1),t=16711935&(t|t<<8),t=252645135&(t|t<<4),t=858993459&(t|t<<2),t=1431655765&(t|t<<1),e|t<<1}function m(e){var t=e,n=e;do t.x=0&&(e-a)*(r-s)-(n-a)*(t-s)>=0&&(n-a)*(o-s)-(i-a)*(r-s)>=0}function g(e,t){return e.next.i!==t.i&&e.prev.i!==t.i&&!k(e,t)&&O(e,t)&&O(t,e)&&M(e,t)}function b(e,t,n){return(t.y-e.y)*(n.x-t.x)-(t.x-e.x)*(n.y-t.y)}function w(e,t){return e.x===t.x&&e.y===t.y}function x(e,t,n,r){return w(e,t)&&w(n,r)||w(e,r)&&w(n,t)?!0:b(e,t,n)>0!=b(e,t,r)>0&&b(n,r,e)>0!=b(n,r,t)>0}function k(e,t){var n=e;do{if(n.i!==e.i&&n.next.i!==e.i&&n.i!==t.i&&n.next.i!==t.i&&x(n,n.next,e,t))return!0;n=n.next}while(n!==e);return!1}function O(e,t){return b(e.prev,e,e.next)<0?b(e,t,e.next)>=0&&b(e,e.prev,t)>=0:b(e,t,e.prev)<0||b(e,e.next,t)<0}function M(e,t){var n=e,r=!1,i=(e.x+t.x)/2,o=(e.y+t.y)/2;do n.y>o!=n.next.y>o&&i<(n.next.x-n.x)*(o-n.y)/(n.next.y-n.y)+n.x&&(r=!r),n=n.next;while(n!==e);return r}function P(e,t){var n=new S(e.i,e.x,e.y),r=new S(t.i,t.x,t.y),i=e.next,o=t.prev;return e.next=t,t.prev=e,n.next=i,i.prev=n,r.next=n,n.prev=r,o.next=r,r.prev=o,r}function E(e,t,n,r){var i=new S(e,t,n);return r?(i.next=r.next,i.prev=r,r.next.prev=i,r.next=i):(i.prev=i,i.next=i),i}function T(e){e.next.prev=e.prev,e.prev.next=e.next,e.prevZ&&(e.prevZ.nextZ=e.nextZ),e.nextZ&&(e.nextZ.prevZ=e.prevZ)}function S(e,t,n){this.i=e,this.x=t,this.y=n,this.prev=null,this.next=null,this.z=null,this.prevZ=null,this.nextZ=null,this.steiner=!1}function j(e,t,n,r){for(var i=0,o=t,a=n-r;n>o;o+=r)i+=(e[a]-e[o])*(e[o+1]+e[a+1]),a=o;return i}e.exports=n,n.deviation=function(e,t,n,r){var i=t&&t.length,o=i?t[0]*n:e.length,a=Math.abs(j(e,0,o,n));if(i)for(var s=0,u=t.length;u>s;s++){var l=t[s]*n,c=u-1>s?t[s+1]*n:e.length;a-=Math.abs(j(e,l,c,n))}var f=0;for(s=0;sa;a++)n.vertices.push(e[i][o][a]);i>0&&(r+=e[i-1].length,n.holes.push(r))}return n}},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(3),o=r(i),a=function(e,t,n){function r(){a=e.map(function(e){return[e[0],h.top,e[1]]}),s=t,u=t}function i(){a=[],e.forEach(function(e){a.push([e[0],h.top,e[1]])}),e.forEach(function(e){a.push([e[0],h.bottom,e[1]])}),s=[];for(var n=0;p>n;n++)n===p-1?(s.push([n+p,p,n]),s.push([0,n,p])):(s.push([n+p,n+p+1,n]),s.push([n+1,n,n+p+1]));if(c=[].concat(s),h.closed){var r=t,i=r.map(function(e){return e.map(function(e){return e+p})});i=i.map(function(e){return[e[0],e[2],e[1]]}),s=s.concat(r).concat(i),u=r,l=i}}var a,s,u,l,c,f={top:1,bottom:0,closed:!0},h=(0,o["default"])({},f,n),p=e.length;return h.top===h.bottom?r():i(),{positions:a,faces:s,top:u,bottom:l,sides:c}};t["default"]=a,e.exports=t["default"]},function(e,t,n){function r(e){return e&&e.__esModule?e:{"default":e}}Object.defineProperty(t,"__esModule",{value:!0});var i=n(10),o=r(i),a=function(){var e=function(e){var t,n=0,r=new Int32Array(2*e.length),i=0;e.forEach(function(e,o){t=e.length,n+=t,r.set([i,i+t],2*o),i+=t});var o=new Float32Array(n);return e.forEach(function(e,t){o.set(e,r[2*t])}),[o,r]},t=function(e){for(var t,n=e[0],r=e[1],i=[],o=0;o0&&(n._outlineBufferAttributes=P["default"].mergeAttributes(r.outlineAttributes)),n._flat=r.flat,n.isOutput()){var i={positions:3,normals:3,colors:3,tops:1};n._options.interactive&&(i.pickingIds=1);var o=n._options.style;t.SetMesh(n._bufferAttributes,i,n._flat,o,n._options,n._world._environment._skybox).then(function(e){n.add(e.mesh),e.pickingMesh&&n._pickingMesh.add(e.pickingMesh)})}r.attributes=null,r.outlineAttributes=null,r=null,e(n)})["catch"](r)})}},{key:"getCenter",value:function(){return this._center}},{key:"getBounds",value:function(){}},{key:"_setPickingId",value:function(){this._pickingId=this.getPickingId()}},{key:"_addPickingEvents",value:function(){var e=this;this._world.on("pick-"+this._pickingId,function(t,n,r){e.emit("click",e,t,n,r)})}},{key:"getBufferAttributes",value:function(){return this._bufferAttributes}},{key:"getOutlineBufferAttributes",value:function(){return this._outlineBufferAttributes}},{key:"clearBufferAttributes",value:function(){this._bufferAttributes=null,this._outlineBufferAttributes=null}},{key:"clearCoordinates",value:function(){this._coordinates=null,this._projectedCoordinates=null}},{key:"_setCoordinates", +value:function(){this._bounds=[],this._coordinates=this._convertCoordinates(this._coordinates),this._projectedBounds=[],this._projectedCoordinates=this._projectCoordinates(),this._center=this._coordinates[0][0][0]}},{key:"_convertCoordinates",value:function(e){return e.map(function(e){return e.map(function(e){return e.map(function(e){return(0,m.latLon)(e[1],e[0])})})})}},{key:"_projectCoordinates",value:function(){var e,t=this;return this._coordinates.map(function(n){return n.map(function(n){return n.map(function(n){return e=t._world.latLonToPoint(n),t._offset||(t._offset=(0,_.point)(0,0),t._offset.x=-1*e.x,t._offset.y=-1*e.y,t._options.pointScale=t._world.pointScale(n)),e})})})}},{key:"isFlat",value:function(){return this._flat}},{key:"destroy",value:function(){this._pickingMesh&&(this._pickingMesh=null),this.clearCoordinates(),this.clearBufferAttributes(),u(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}],[{key:"SetBufferAttributes",value:function(e,n){return new Promise(function(r){var o=0;n.style.height&&0!==n.style.height&&(o=y["default"].metresToWorld(n.style.height,n.pointScale));var a=new d["default"].Color;a.set(n.style.color);var s=new d["default"].Color(16777215),u=new d["default"].Color(6710886),l=!0,c=[],f=e.map(function(e){var r=t.ToEarcut(e),f=t.Triangulate(r.vertices,r.holes,r.dimensions),h=[];for(i=0,il=r.vertices.length;i0&&(r+=e[i-1].length,n.holes.push(r))}return n}},{key:"Triangulate",value:function(e,t,n){var r=(0,b["default"])(e,t,n),o=[];for(i=0,il=r.length;i0?Promise.all(t).then(function(){l()})["catch"](c):l()})})}},{key:"_processPolygonResults",value:function(e){var t=this;return new Promise(function(n,r){var i,o,s=b["default"].splitFloat32Array(e.attributes.positions),u=b["default"].splitFloat32Array(e.attributes.normals),l=b["default"].splitFloat32Array(e.attributes.colors),c=b["default"].splitFloat32Array(e.attributes.tops);e.outlineAttributes&&(i=b["default"].splitFloat32Array(e.outlineAttributes.positions),o=b["default"].splitFloat32Array(e.outlineAttributes.colors));var f;e.properties&&(f=b["default"].splitUint8Array(e.properties));for(var p,d,v,m,_=e.flats,g=[],w=[],x={positions:3,normals:3,colors:3,tops:1},k={positions:3,colors:3},O=0;O0){var D=b["default"].mergeAttributes(T);C="function"==typeof t._options.style?t._options.style(g[0]):t._options.style,C=(0,h["default"])({},y["default"].defaultStyle,C),L.push(t._setPolygonMesh(D,x,C,j))}if(S.length>0){var R=b["default"].mergeAttributes(S);C="function"==typeof t._options.style?t._options.style(g[0]):t._options.style,C=(0,h["default"])({},y["default"].defaultStyle,C),void 0!==C.outlineRenderOrder?C.lineRenderOrder=C.outlineRenderOrder:C.lineRenderOrder=C.renderOrder?C.renderOrder+1:4,C.outlineWidth&&(C.lineWidth=C.outlineWidth),L.push(t._setPolylineMesh(R,k,C,!0))}Promise.all(L).then(function(e){var r=a(e,2),i=r[0],o=r[1];i&&(t._polygonMesh=i.mesh,t.add(t._polygonMesh),i.pickingMesh&&t._pickingMesh.add(i.pickingMesh)),o&&t.add(o.mesh),n()})["catch"](r)})}},{key:"_processPolylineResults",value:function(e){var t=this;return new Promise(function(n,r){var i,o=b["default"].splitFloat32Array(e.attributes.positions),a=b["default"].splitFloat32Array(e.attributes.colors);e.properties&&(i=b["default"].splitUint8Array(e.properties));for(var s,u,l,c,f=e.flats,p=[],d={positions:3,colors:3},v=0;v0){var O=b["default"].mergeAttributes(w),M="function"==typeof t._options.style?t._options.style(p[0]):t._options.style;M=(0,h["default"])({},y["default"].defaultStyle,M),t._setPolylineMesh(O,d,M,x).then(function(e){t._polylineMesh=e.mesh,t.add(t._polylineMesh),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh),n()})["catch"](r)}else n()})}},{key:"_processPointResults",value:function(e){var t=this;return new Promise(function(n,r){var i,o=b["default"].splitFloat32Array(e.attributes.positions),a=b["default"].splitFloat32Array(e.attributes.normals),s=b["default"].splitFloat32Array(e.attributes.colors);e.properties&&(i=b["default"].splitUint8Array(e.properties));for(var u,l,c,f,p=e.flats,d=[],v={positions:3,normals:3,colors:3},m=0;m0){var M=b["default"].mergeAttributes(x),P="function"==typeof t._options.style?t._options.style(d[0]):t._options.style;P=(0,h["default"])({},y["default"].defaultStyle,P),t._setPointMesh(M,v,P,k).then(function(e){t._pointMesh=e.mesh,t.add(t._pointMesh),e.pickingMesh&&t._pickingMesh.add(e.pickingMesh),n()})["catch"](r)}else n()})}},{key:"_setPolygonMesh",value:function(e,t,n,r){return this._world?O["default"].SetMesh(e,t,r,n,this._options,this._world._environment._skybox):Promise.reject()}},{key:"_setPolylineMesh",value:function(e,t,n,r){return this._world?P["default"].SetMesh(e,t,r,n,this._options):Promise.reject()}},{key:"_setPointMesh",value:function(e,t,n,r){return this._world?T["default"].SetMesh(e,t,r,n,this._options,this._world._environment._skybox):Promise.reject()}},{key:"_addPicking",value:function(e,t){var n=this;this._world.on("pick-click-"+e,function(e,r,i,o){n._world.emit("click",n,t,r,i)}),this._world.on("pick-hover-"+e,function(e,r,i,o){n._world.emit("hover",n,t,r,i)})}},{key:"destroy",value:function(){u(Object.getPrototypeOf(t.prototype),"destroy",this).call(this)}}],[{key:"Process",value:function(e,n,r,i,o,a,s){return new Promise(function(u,l){t.ProcessGeoJSON(e,r).then(function(e){var r,l=y["default"].collectFeatures(e,n),c=l.features,f=[],p=[],d=[];"string"==typeof o&&(o=x["default"].stringToFunction(o));var v,m=o;"string"==typeof s&&(v=x["default"].stringToFunction(s));for(var _,g=0;g {});\n\t // this._engine.on('postRender', () => {});\n\t }\n\t }, {\n\t key: '_initEnvironment',\n\t value: function _initEnvironment() {\n\t // Not sure if I want to keep this as a private API\n\t //\n\t // Makes sense to allow others to customise their environment so perhaps\n\t // add some method of disable / overriding the environment settings\n\t this._environment = new _layerEnvironmentEnvironmentLayer2['default']({\n\t skybox: this.options.skybox\n\t });\n\t\n\t return this._environment.addTo(this);\n\t }\n\t }, {\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t this.on('controlsMoveEnd', this._onControlsMoveEnd);\n\t }\n\t }, {\n\t key: '_onControlsMoveEnd',\n\t value: function _onControlsMoveEnd(point) {\n\t var _point = (0, _geoPoint.point)(point.x, point.z);\n\t this._resetView(this.pointToLatLon(_point), _point);\n\t }\n\t\n\t // Reset world view\n\t }, {\n\t key: '_resetView',\n\t value: function _resetView(latlon, point) {\n\t this.emit('preResetView');\n\t\n\t this._moveStart();\n\t this._move(latlon, point);\n\t this._moveEnd();\n\t\n\t this.emit('postResetView');\n\t }\n\t }, {\n\t key: '_moveStart',\n\t value: function _moveStart() {\n\t this.emit('moveStart');\n\t }\n\t }, {\n\t key: '_move',\n\t value: function _move(latlon, point) {\n\t this._lastPosition = latlon;\n\t this.emit('move', latlon, point);\n\t }\n\t }, {\n\t key: '_moveEnd',\n\t value: function _moveEnd() {\n\t this.emit('moveEnd');\n\t }\n\t }, {\n\t key: '_update',\n\t value: function _update() {\n\t if (this._pause) {\n\t return;\n\t }\n\t\n\t var delta = this._engine.clock.getDelta();\n\t\n\t // Once _update is called it will run forever, for now\n\t window.requestAnimationFrame(this._update.bind(this));\n\t\n\t // Update controls\n\t this._controls.forEach(function (controls) {\n\t controls.update(delta);\n\t });\n\t\n\t this.emit('preUpdate', delta);\n\t this._engine.update(delta);\n\t this.emit('postUpdate', delta);\n\t }\n\t\n\t // Set world view\n\t }, {\n\t key: 'setView',\n\t value: function setView(latlon) {\n\t // Store initial geographic coordinate for the [0,0,0] world position\n\t //\n\t // The origin point doesn't move in three.js / 3D space so only set it once\n\t // here instead of every time _resetView is called\n\t //\n\t // If it was updated every time then coorindates would shift over time and\n\t // would be out of place / context with previously-placed points (0,0 would\n\t // refer to a different point each time)\n\t this._originLatlon = latlon;\n\t this._originPoint = this.project(latlon);\n\t\n\t this._resetView(latlon);\n\t return this;\n\t }\n\t\n\t // Return world geographic position\n\t }, {\n\t key: 'getPosition',\n\t value: function getPosition() {\n\t return this._lastPosition;\n\t }\n\t\n\t // Transform geographic coordinate to world point\n\t //\n\t // This doesn't take into account the origin offset\n\t //\n\t // For example, this takes a geographic coordinate and returns a point\n\t // relative to the origin point of the projection (not the world)\n\t }, {\n\t key: 'project',\n\t value: function project(latlon) {\n\t return _geoGeo2['default'].latLonToPoint((0, _geoLatLon.latLon)(latlon));\n\t }\n\t\n\t // Transform world point to geographic coordinate\n\t //\n\t // This doesn't take into account the origin offset\n\t //\n\t // For example, this takes a point relative to the origin point of the\n\t // projection (not the world) and returns a geographic coordinate\n\t }, {\n\t key: 'unproject',\n\t value: function unproject(point) {\n\t return _geoGeo2['default'].pointToLatLon((0, _geoPoint.point)(point));\n\t }\n\t\n\t // Takes into account the origin offset\n\t //\n\t // For example, this takes a geographic coordinate and returns a point\n\t // relative to the three.js / 3D origin (0,0)\n\t }, {\n\t key: 'latLonToPoint',\n\t value: function latLonToPoint(latlon) {\n\t var projectedPoint = this.project((0, _geoLatLon.latLon)(latlon));\n\t return projectedPoint._subtract(this._originPoint);\n\t }\n\t\n\t // Takes into account the origin offset\n\t //\n\t // For example, this takes a point relative to the three.js / 3D origin (0,0)\n\t // and returns the exact geographic coordinate at that point\n\t }, {\n\t key: 'pointToLatLon',\n\t value: function pointToLatLon(point) {\n\t var projectedPoint = (0, _geoPoint.point)(point).add(this._originPoint);\n\t return this.unproject(projectedPoint);\n\t }\n\t\n\t // Return pointscale for a given geographic coordinate\n\t }, {\n\t key: 'pointScale',\n\t value: function pointScale(latlon, accurate) {\n\t return _geoGeo2['default'].pointScale(latlon, accurate);\n\t }\n\t\n\t // Convert from real meters to world units\n\t //\n\t // TODO: Would be nice not to have to pass in a pointscale here\n\t }, {\n\t key: 'metresToWorld',\n\t value: function metresToWorld(metres, pointScale, zoom) {\n\t return _geoGeo2['default'].metresToWorld(metres, pointScale, zoom);\n\t }\n\t\n\t // Convert from real meters to world units\n\t //\n\t // TODO: Would be nice not to have to pass in a pointscale here\n\t }, {\n\t key: 'worldToMetres',\n\t value: function worldToMetres(worldUnits, pointScale, zoom) {\n\t return _geoGeo2['default'].worldToMetres(worldUnits, pointScale, zoom);\n\t }\n\t\n\t // Unsure if it's a good idea to expose this here for components like\n\t // GridLayer to use (eg. to keep track of a frustum)\n\t }, {\n\t key: 'getCamera',\n\t value: function getCamera() {\n\t return this._engine._camera;\n\t }\n\t }, {\n\t key: 'addLayer',\n\t value: function addLayer(layer) {\n\t var _this2 = this;\n\t\n\t this._layers.push(layer);\n\t\n\t if (layer.isOutput() && layer.isOutputToScene()) {\n\t // Could move this into Layer but it'll do here for now\n\t this._engine._scene.add(layer._object3D);\n\t this._engine._domScene3D.add(layer._domObject3D);\n\t this._engine._domScene2D.add(layer._domObject2D);\n\t }\n\t\n\t return new Promise(function (resolve, reject) {\n\t layer._addToWorld(_this2).then(function () {\n\t _this2.emit('layerAdded', layer);\n\t resolve(_this2);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Remove layer from world and scene but don't destroy it entirely\n\t }, {\n\t key: 'removeLayer',\n\t value: function removeLayer(layer) {\n\t var layerIndex = this._layers.indexOf(layer);\n\t\n\t if (layerIndex > -1) {\n\t // Remove from this._layers\n\t this._layers.splice(layerIndex, 1);\n\t };\n\t\n\t if (layer.isOutput() && layer.isOutputToScene()) {\n\t this._engine._scene.remove(layer._object3D);\n\t this._engine._domScene3D.remove(layer._domObject3D);\n\t this._engine._domScene2D.remove(layer._domObject2D);\n\t }\n\t\n\t this.emit('layerRemoved');\n\t\n\t return Promise.resolve(this);\n\t }\n\t }, {\n\t key: 'addControls',\n\t value: function addControls(controls) {\n\t controls._addToWorld(this);\n\t\n\t this._controls.push(controls);\n\t\n\t this.emit('controlsAdded', controls);\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Remove controls from world but don't destroy them entirely\n\t }, {\n\t key: 'removeControls',\n\t value: function removeControls(controls) {\n\t var controlsIndex = this._controls.indexOf(controlsIndex);\n\t\n\t if (controlsIndex > -1) {\n\t this._controls.splice(controlsIndex, 1);\n\t };\n\t\n\t this.emit('controlsRemoved', controls);\n\t\n\t return Promise.resolve(this);\n\t }\n\t }, {\n\t key: 'stop',\n\t value: function stop() {\n\t this._pause = true;\n\t }\n\t }, {\n\t key: 'start',\n\t value: function start() {\n\t this._pause = false;\n\t this._update();\n\t }\n\t\n\t // Destroys the world(!) and removes it from the scene and memory\n\t //\n\t // TODO: World out why so much three.js stuff is left in the heap after this\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this.stop();\n\t\n\t // Remove listeners\n\t this.off('controlsMoveEnd', this._onControlsMoveEnd);\n\t\n\t var i;\n\t\n\t // Remove all controls\n\t var controls;\n\t for (i = this._controls.length - 1; i >= 0; i--) {\n\t controls = this._controls[0];\n\t this.removeControls(controls);\n\t controls.destroy();\n\t };\n\t\n\t // Remove all layers\n\t var layer;\n\t for (i = this._layers.length - 1; i >= 0; i--) {\n\t layer = this._layers[0];\n\t this.removeLayer(layer);\n\t layer.destroy();\n\t };\n\t\n\t // Environment layer is removed with the other layers\n\t this._environment = null;\n\t\n\t this._engine.destroy();\n\t this._engine = null;\n\t\n\t // Clean the container / remove the canvas\n\t while (this._container.firstChild) {\n\t this._container.removeChild(this._container.firstChild);\n\t }\n\t\n\t this._container = null;\n\t }\n\t }]);\n\t\n\t return World;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = World;\n\t\n\tvar noNew = function noNew(domId, options) {\n\t return new World(domId, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.world = noNew;\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar has = Object.prototype.hasOwnProperty;\n\t\n\t//\n\t// We store our EE objects in a plain object whose properties are event names.\n\t// If `Object.create(null)` is not supported we prefix the event names with a\n\t// `~` to make sure that the built-in object properties are not overridden or\n\t// used as an attack vector.\n\t// We also assume that `Object.create(null)` is available when the event name\n\t// is an ES6 Symbol.\n\t//\n\tvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\t\n\t/**\n\t * Representation of a single EventEmitter function.\n\t *\n\t * @param {Function} fn Event handler to be called.\n\t * @param {Mixed} context Context for function execution.\n\t * @param {Boolean} [once=false] Only emit once\n\t * @api private\n\t */\n\tfunction EE(fn, context, once) {\n\t this.fn = fn;\n\t this.context = context;\n\t this.once = once || false;\n\t}\n\t\n\t/**\n\t * Minimal EventEmitter interface that is molded against the Node.js\n\t * EventEmitter interface.\n\t *\n\t * @constructor\n\t * @api public\n\t */\n\tfunction EventEmitter() { /* Nothing to set */ }\n\t\n\t/**\n\t * Hold the assigned EventEmitters by name.\n\t *\n\t * @type {Object}\n\t * @private\n\t */\n\tEventEmitter.prototype._events = undefined;\n\t\n\t/**\n\t * Return an array listing the events for which the emitter has registered\n\t * listeners.\n\t *\n\t * @returns {Array}\n\t * @api public\n\t */\n\tEventEmitter.prototype.eventNames = function eventNames() {\n\t var events = this._events\n\t , names = []\n\t , name;\n\t\n\t if (!events) return names;\n\t\n\t for (name in events) {\n\t if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n\t }\n\t\n\t if (Object.getOwnPropertySymbols) {\n\t return names.concat(Object.getOwnPropertySymbols(events));\n\t }\n\t\n\t return names;\n\t};\n\t\n\t/**\n\t * Return a list of assigned event listeners.\n\t *\n\t * @param {String} event The events that should be listed.\n\t * @param {Boolean} exists We only need to know if there are listeners.\n\t * @returns {Array|Boolean}\n\t * @api public\n\t */\n\tEventEmitter.prototype.listeners = function listeners(event, exists) {\n\t var evt = prefix ? prefix + event : event\n\t , available = this._events && this._events[evt];\n\t\n\t if (exists) return !!available;\n\t if (!available) return [];\n\t if (available.fn) return [available.fn];\n\t\n\t for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n\t ee[i] = available[i].fn;\n\t }\n\t\n\t return ee;\n\t};\n\t\n\t/**\n\t * Emit an event to all registered event listeners.\n\t *\n\t * @param {String} event The name of the event.\n\t * @returns {Boolean} Indication if we've emitted an event.\n\t * @api public\n\t */\n\tEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n\t var evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events || !this._events[evt]) return false;\n\t\n\t var listeners = this._events[evt]\n\t , len = arguments.length\n\t , args\n\t , i;\n\t\n\t if ('function' === typeof listeners.fn) {\n\t if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\t\n\t switch (len) {\n\t case 1: return listeners.fn.call(listeners.context), true;\n\t case 2: return listeners.fn.call(listeners.context, a1), true;\n\t case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n\t case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n\t case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n\t case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n\t }\n\t\n\t for (i = 1, args = new Array(len -1); i < len; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t\n\t listeners.fn.apply(listeners.context, args);\n\t } else {\n\t var length = listeners.length\n\t , j;\n\t\n\t for (i = 0; i < length; i++) {\n\t if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\t\n\t switch (len) {\n\t case 1: listeners[i].fn.call(listeners[i].context); break;\n\t case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n\t case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n\t default:\n\t if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n\t args[j - 1] = arguments[j];\n\t }\n\t\n\t listeners[i].fn.apply(listeners[i].context, args);\n\t }\n\t }\n\t }\n\t\n\t return true;\n\t};\n\t\n\t/**\n\t * Register a new EventListener for the given event.\n\t *\n\t * @param {String} event Name of the event.\n\t * @param {Function} fn Callback function.\n\t * @param {Mixed} [context=this] The context of the function.\n\t * @api public\n\t */\n\tEventEmitter.prototype.on = function on(event, fn, context) {\n\t var listener = new EE(fn, context || this)\n\t , evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events) this._events = prefix ? {} : Object.create(null);\n\t if (!this._events[evt]) this._events[evt] = listener;\n\t else {\n\t if (!this._events[evt].fn) this._events[evt].push(listener);\n\t else this._events[evt] = [\n\t this._events[evt], listener\n\t ];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Add an EventListener that's only called once.\n\t *\n\t * @param {String} event Name of the event.\n\t * @param {Function} fn Callback function.\n\t * @param {Mixed} [context=this] The context of the function.\n\t * @api public\n\t */\n\tEventEmitter.prototype.once = function once(event, fn, context) {\n\t var listener = new EE(fn, context || this, true)\n\t , evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events) this._events = prefix ? {} : Object.create(null);\n\t if (!this._events[evt]) this._events[evt] = listener;\n\t else {\n\t if (!this._events[evt].fn) this._events[evt].push(listener);\n\t else this._events[evt] = [\n\t this._events[evt], listener\n\t ];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Remove event listeners.\n\t *\n\t * @param {String} event The event we want to remove.\n\t * @param {Function} fn The listener that we need to find.\n\t * @param {Mixed} context Only remove listeners matching this context.\n\t * @param {Boolean} once Only remove once listeners.\n\t * @api public\n\t */\n\tEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n\t var evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events || !this._events[evt]) return this;\n\t\n\t var listeners = this._events[evt]\n\t , events = [];\n\t\n\t if (fn) {\n\t if (listeners.fn) {\n\t if (\n\t listeners.fn !== fn\n\t || (once && !listeners.once)\n\t || (context && listeners.context !== context)\n\t ) {\n\t events.push(listeners);\n\t }\n\t } else {\n\t for (var i = 0, length = listeners.length; i < length; i++) {\n\t if (\n\t listeners[i].fn !== fn\n\t || (once && !listeners[i].once)\n\t || (context && listeners[i].context !== context)\n\t ) {\n\t events.push(listeners[i]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t //\n\t // Reset the array, or remove it completely if we have no more listeners.\n\t //\n\t if (events.length) {\n\t this._events[evt] = events.length === 1 ? events[0] : events;\n\t } else {\n\t delete this._events[evt];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Remove all listeners or only the listeners for the specified event.\n\t *\n\t * @param {String} event The event want to remove all listeners for.\n\t * @api public\n\t */\n\tEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n\t if (!this._events) return this;\n\t\n\t if (event) delete this._events[prefix ? prefix + event : event];\n\t else this._events = prefix ? {} : Object.create(null);\n\t\n\t return this;\n\t};\n\t\n\t//\n\t// Alias methods names because people roll like that.\n\t//\n\tEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\tEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\t\n\t//\n\t// This function doesn't apply anymore.\n\t//\n\tEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n\t return this;\n\t};\n\t\n\t//\n\t// Expose the prefix.\n\t//\n\tEventEmitter.prefixed = prefix;\n\t\n\t//\n\t// Expose the module.\n\t//\n\tif (true) {\n\t module.exports = EventEmitter;\n\t}\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\tvar keys = __webpack_require__(4),\n\t rest = __webpack_require__(5);\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]';\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\t\n\t/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\n\tvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\t\n\t/**\n\t * Assigns `value` to `key` of `object` if the existing value is not equivalent\n\t * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n\t * for equality comparisons.\n\t *\n\t * @private\n\t * @param {Object} object The object to modify.\n\t * @param {string} key The key of the property to assign.\n\t * @param {*} value The value to assign.\n\t */\n\tfunction assignValue(object, key, value) {\n\t var objValue = object[key];\n\t if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n\t (value === undefined && !(key in object))) {\n\t object[key] = value;\n\t }\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * Copies properties of `source` to `object`.\n\t *\n\t * @private\n\t * @param {Object} source The object to copy properties from.\n\t * @param {Array} props The property identifiers to copy.\n\t * @param {Object} [object={}] The object to copy properties to.\n\t * @param {Function} [customizer] The function to customize copied values.\n\t * @returns {Object} Returns `object`.\n\t */\n\tfunction copyObject(source, props, object, customizer) {\n\t object || (object = {});\n\t\n\t var index = -1,\n\t length = props.length;\n\t\n\t while (++index < length) {\n\t var key = props[index];\n\t\n\t var newValue = customizer\n\t ? customizer(object[key], source[key], key, object, source)\n\t : source[key];\n\t\n\t assignValue(object, key, newValue);\n\t }\n\t return object;\n\t}\n\t\n\t/**\n\t * Creates a function like `_.assign`.\n\t *\n\t * @private\n\t * @param {Function} assigner The function to assign values.\n\t * @returns {Function} Returns the new assigner function.\n\t */\n\tfunction createAssigner(assigner) {\n\t return rest(function(object, sources) {\n\t var index = -1,\n\t length = sources.length,\n\t customizer = length > 1 ? sources[length - 1] : undefined,\n\t guard = length > 2 ? sources[2] : undefined;\n\t\n\t customizer = (assigner.length > 3 && typeof customizer == 'function')\n\t ? (length--, customizer)\n\t : undefined;\n\t\n\t if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n\t customizer = length < 3 ? undefined : customizer;\n\t length = 1;\n\t }\n\t object = Object(object);\n\t while (++index < length) {\n\t var source = sources[index];\n\t if (source) {\n\t assigner(object, source, index, customizer);\n\t }\n\t }\n\t return object;\n\t });\n\t}\n\t\n\t/**\n\t * Gets the \"length\" property value of `object`.\n\t *\n\t * **Note:** This function is used to avoid a\n\t * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n\t * Safari on at least iOS 8.1-8.3 ARM64.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {*} Returns the \"length\" value.\n\t */\n\tvar getLength = baseProperty('length');\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if the given arguments are from an iteratee call.\n\t *\n\t * @private\n\t * @param {*} value The potential iteratee value argument.\n\t * @param {*} index The potential iteratee index or key argument.\n\t * @param {*} object The potential iteratee object argument.\n\t * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n\t * else `false`.\n\t */\n\tfunction isIterateeCall(value, index, object) {\n\t if (!isObject(object)) {\n\t return false;\n\t }\n\t var type = typeof index;\n\t if (type == 'number'\n\t ? (isArrayLike(object) && isIndex(index, object.length))\n\t : (type == 'string' && index in object)\n\t ) {\n\t return eq(object[index], value);\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Performs a\n\t * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n\t * comparison between two values to determine if they are equivalent.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'user': 'fred' };\n\t * var other = { 'user': 'fred' };\n\t *\n\t * _.eq(object, object);\n\t * // => true\n\t *\n\t * _.eq(object, other);\n\t * // => false\n\t *\n\t * _.eq('a', 'a');\n\t * // => true\n\t *\n\t * _.eq('a', Object('a'));\n\t * // => false\n\t *\n\t * _.eq(NaN, NaN);\n\t * // => true\n\t */\n\tfunction eq(value, other) {\n\t return value === other || (value !== value && other !== other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(getLength(value)) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Assigns own enumerable string keyed properties of source objects to the\n\t * destination object. Source objects are applied from left to right.\n\t * Subsequent sources overwrite property assignments of previous sources.\n\t *\n\t * **Note:** This method mutates `object` and is loosely based on\n\t * [`Object.assign`](https://mdn.io/Object/assign).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.10.0\n\t * @category Object\n\t * @param {Object} object The destination object.\n\t * @param {...Object} [sources] The source objects.\n\t * @returns {Object} Returns `object`.\n\t * @see _.assignIn\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.c = 3;\n\t * }\n\t *\n\t * function Bar() {\n\t * this.e = 5;\n\t * }\n\t *\n\t * Foo.prototype.d = 4;\n\t * Bar.prototype.f = 6;\n\t *\n\t * _.assign({ 'a': 1 }, new Foo, new Bar);\n\t * // => { 'a': 1, 'c': 3, 'e': 5 }\n\t */\n\tvar assign = createAssigner(function(object, source) {\n\t if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n\t copyObject(source, keys(source), object);\n\t return;\n\t }\n\t for (var key in source) {\n\t if (hasOwnProperty.call(source, key)) {\n\t assignValue(object, key, source[key]);\n\t }\n\t }\n\t});\n\t\n\tmodule.exports = assign;\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar argsTag = '[object Arguments]',\n\t funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t stringTag = '[object String]';\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/**\n\t * The base implementation of `_.times` without support for iteratee shorthands\n\t * or max array length checks.\n\t *\n\t * @private\n\t * @param {number} n The number of times to invoke `iteratee`.\n\t * @param {Function} iteratee The function invoked per iteration.\n\t * @returns {Array} Returns the array of results.\n\t */\n\tfunction baseTimes(n, iteratee) {\n\t var index = -1,\n\t result = Array(n);\n\t\n\t while (++index < n) {\n\t result[index] = iteratee(index);\n\t }\n\t return result;\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeGetPrototype = Object.getPrototypeOf,\n\t nativeKeys = Object.keys;\n\t\n\t/**\n\t * The base implementation of `_.has` without support for deep paths.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} key The key to check.\n\t * @returns {boolean} Returns `true` if `key` exists, else `false`.\n\t */\n\tfunction baseHas(object, key) {\n\t // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n\t // that are composed entirely of index properties, return `false` for\n\t // `hasOwnProperty` checks of them.\n\t return hasOwnProperty.call(object, key) ||\n\t (typeof object == 'object' && key in object && getPrototype(object) === null);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.keys` which doesn't skip the constructor\n\t * property of prototypes or treat sparse arrays as dense.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction baseKeys(object) {\n\t return nativeKeys(Object(object));\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * Gets the \"length\" property value of `object`.\n\t *\n\t * **Note:** This function is used to avoid a\n\t * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n\t * Safari on at least iOS 8.1-8.3 ARM64.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {*} Returns the \"length\" value.\n\t */\n\tvar getLength = baseProperty('length');\n\t\n\t/**\n\t * Gets the `[[Prototype]]` of `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {null|Object} Returns the `[[Prototype]]`.\n\t */\n\tfunction getPrototype(value) {\n\t return nativeGetPrototype(Object(value));\n\t}\n\t\n\t/**\n\t * Creates an array of index keys for `object` values of arrays,\n\t * `arguments` objects, and strings, otherwise `null` is returned.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array|null} Returns index keys, else `null`.\n\t */\n\tfunction indexKeys(object) {\n\t var length = object ? object.length : undefined;\n\t if (isLength(length) &&\n\t (isArray(object) || isString(object) || isArguments(object))) {\n\t return baseTimes(length, String);\n\t }\n\t return null;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely an `arguments` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArguments(function() { return arguments; }());\n\t * // => true\n\t *\n\t * _.isArguments([1, 2, 3]);\n\t * // => false\n\t */\n\tfunction isArguments(value) {\n\t // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n\t return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n\t (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as an `Array` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @type {Function}\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArray([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArray(document.body.children);\n\t * // => false\n\t *\n\t * _.isArray('abc');\n\t * // => false\n\t *\n\t * _.isArray(_.noop);\n\t * // => false\n\t */\n\tvar isArray = Array.isArray;\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(getLength(value)) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * This method is like `_.isArrayLike` except that it also checks if `value`\n\t * is an object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array-like object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArrayLikeObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject('abc');\n\t * // => false\n\t *\n\t * _.isArrayLikeObject(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLikeObject(value) {\n\t return isObjectLike(value) && isArrayLike(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `String` primitive or object.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isString('abc');\n\t * // => true\n\t *\n\t * _.isString(1);\n\t * // => false\n\t */\n\tfunction isString(value) {\n\t return typeof value == 'string' ||\n\t (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n\t}\n\t\n\t/**\n\t * Creates an array of the own enumerable property names of `object`.\n\t *\n\t * **Note:** Non-object values are coerced to objects. See the\n\t * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n\t * for more details.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.a = 1;\n\t * this.b = 2;\n\t * }\n\t *\n\t * Foo.prototype.c = 3;\n\t *\n\t * _.keys(new Foo);\n\t * // => ['a', 'b'] (iteration order is not guaranteed)\n\t *\n\t * _.keys('hi');\n\t * // => ['0', '1']\n\t */\n\tfunction keys(object) {\n\t var isProto = isPrototype(object);\n\t if (!(isProto || isArrayLike(object))) {\n\t return baseKeys(object);\n\t }\n\t var indexes = indexKeys(object),\n\t skipIndexes = !!indexes,\n\t result = indexes || [],\n\t length = result.length;\n\t\n\t for (var key in object) {\n\t if (baseHas(object, key) &&\n\t !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n\t !(isProto && key == 'constructor')) {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\tmodule.exports = keys;\n\n\n/***/ },\n/* 5 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar INFINITY = 1 / 0,\n\t MAX_INTEGER = 1.7976931348623157e+308,\n\t NAN = 0 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t symbolTag = '[object Symbol]';\n\t\n\t/** Used to match leading and trailing whitespace. */\n\tvar reTrim = /^\\s+|\\s+$/g;\n\t\n\t/** Used to detect bad signed hexadecimal string values. */\n\tvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\t\n\t/** Used to detect binary string values. */\n\tvar reIsBinary = /^0b[01]+$/i;\n\t\n\t/** Used to detect octal string values. */\n\tvar reIsOctal = /^0o[0-7]+$/i;\n\t\n\t/** Built-in method references without a dependency on `root`. */\n\tvar freeParseInt = parseInt;\n\t\n\t/**\n\t * A faster alternative to `Function#apply`, this function invokes `func`\n\t * with the `this` binding of `thisArg` and the arguments of `args`.\n\t *\n\t * @private\n\t * @param {Function} func The function to invoke.\n\t * @param {*} thisArg The `this` binding of `func`.\n\t * @param {Array} args The arguments to invoke `func` with.\n\t * @returns {*} Returns the result of `func`.\n\t */\n\tfunction apply(func, thisArg, args) {\n\t var length = args.length;\n\t switch (length) {\n\t case 0: return func.call(thisArg);\n\t case 1: return func.call(thisArg, args[0]);\n\t case 2: return func.call(thisArg, args[0], args[1]);\n\t case 3: return func.call(thisArg, args[0], args[1], args[2]);\n\t }\n\t return func.apply(thisArg, args);\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeMax = Math.max;\n\t\n\t/**\n\t * Creates a function that invokes `func` with the `this` binding of the\n\t * created function and arguments from `start` and beyond provided as\n\t * an array.\n\t *\n\t * **Note:** This method is based on the\n\t * [rest parameter](https://mdn.io/rest_parameters).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Function\n\t * @param {Function} func The function to apply a rest parameter to.\n\t * @param {number} [start=func.length-1] The start position of the rest parameter.\n\t * @returns {Function} Returns the new function.\n\t * @example\n\t *\n\t * var say = _.rest(function(what, names) {\n\t * return what + ' ' + _.initial(names).join(', ') +\n\t * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n\t * });\n\t *\n\t * say('hello', 'fred', 'barney', 'pebbles');\n\t * // => 'hello fred, barney, & pebbles'\n\t */\n\tfunction rest(func, start) {\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n\t return function() {\n\t var args = arguments,\n\t index = -1,\n\t length = nativeMax(args.length - start, 0),\n\t array = Array(length);\n\t\n\t while (++index < length) {\n\t array[index] = args[start + index];\n\t }\n\t switch (start) {\n\t case 0: return func.call(this, array);\n\t case 1: return func.call(this, args[0], array);\n\t case 2: return func.call(this, args[0], args[1], array);\n\t }\n\t var otherArgs = Array(start + 1);\n\t index = -1;\n\t while (++index < start) {\n\t otherArgs[index] = args[index];\n\t }\n\t otherArgs[start] = array;\n\t return apply(func, this, otherArgs);\n\t };\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a finite number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.12.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted number.\n\t * @example\n\t *\n\t * _.toFinite(3.2);\n\t * // => 3.2\n\t *\n\t * _.toFinite(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toFinite(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toFinite('3.2');\n\t * // => 3.2\n\t */\n\tfunction toFinite(value) {\n\t if (!value) {\n\t return value === 0 ? value : 0;\n\t }\n\t value = toNumber(value);\n\t if (value === INFINITY || value === -INFINITY) {\n\t var sign = (value < 0 ? -1 : 1);\n\t return sign * MAX_INTEGER;\n\t }\n\t return value === value ? value : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to an integer.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted integer.\n\t * @example\n\t *\n\t * _.toInteger(3.2);\n\t * // => 3\n\t *\n\t * _.toInteger(Number.MIN_VALUE);\n\t * // => 0\n\t *\n\t * _.toInteger(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toInteger('3.2');\n\t * // => 3\n\t */\n\tfunction toInteger(value) {\n\t var result = toFinite(value),\n\t remainder = result % 1;\n\t\n\t return result === result ? (remainder ? result - remainder : result) : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to a number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {number} Returns the number.\n\t * @example\n\t *\n\t * _.toNumber(3.2);\n\t * // => 3.2\n\t *\n\t * _.toNumber(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toNumber(Infinity);\n\t * // => Infinity\n\t *\n\t * _.toNumber('3.2');\n\t * // => 3.2\n\t */\n\tfunction toNumber(value) {\n\t if (typeof value == 'number') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return NAN;\n\t }\n\t if (isObject(value)) {\n\t var other = isFunction(value.valueOf) ? value.valueOf() : value;\n\t value = isObject(other) ? (other + '') : other;\n\t }\n\t if (typeof value != 'string') {\n\t return value === 0 ? value : +value;\n\t }\n\t value = value.replace(reTrim, '');\n\t var isBinary = reIsBinary.test(value);\n\t return (isBinary || reIsOctal.test(value))\n\t ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n\t : (reIsBadHex.test(value) ? NAN : +value);\n\t}\n\t\n\tmodule.exports = rest;\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _LatLon = __webpack_require__(7);\n\t\n\tvar _Point = __webpack_require__(8);\n\t\n\tvar Geo = {};\n\t\n\t// Radius / WGS84 semi-major axis\n\tGeo.R = 6378137;\n\tGeo.MAX_LATITUDE = 85.0511287798;\n\t\n\t// WGS84 eccentricity\n\tGeo.ECC = 0.081819191;\n\tGeo.ECC2 = 0.081819191 * 0.081819191;\n\t\n\tGeo.project = function (latlon) {\n\t var d = Math.PI / 180;\n\t var max = Geo.MAX_LATITUDE;\n\t var lat = Math.max(Math.min(max, latlon.lat), -max);\n\t var sin = Math.sin(lat * d);\n\t\n\t return (0, _Point.point)(Geo.R * latlon.lon * d, Geo.R * Math.log((1 + sin) / (1 - sin)) / 2);\n\t}, Geo.unproject = function (point) {\n\t var d = 180 / Math.PI;\n\t\n\t return (0, _LatLon.latLon)((2 * Math.atan(Math.exp(point.y / Geo.R)) - Math.PI / 2) * d, point.x * d / Geo.R);\n\t};\n\t\n\t// Converts geo coords to pixel / WebGL ones\n\t// This just reverses the Y axis to match WebGL\n\tGeo.latLonToPoint = function (latlon) {\n\t var projected = Geo.project(latlon);\n\t projected.y *= -1;\n\t\n\t return projected;\n\t};\n\t\n\t// Converts pixel / WebGL coords to geo coords\n\t// This just reverses the Y axis to match WebGL\n\tGeo.pointToLatLon = function (point) {\n\t var _point = (0, _Point.point)(point.x, point.y * -1);\n\t return Geo.unproject(_point);\n\t};\n\t\n\t// Scale factor for converting between real metres and projected metres\n\t//\n\t// projectedMetres = realMetres * pointScale\n\t// realMetres = projectedMetres / pointScale\n\t//\n\t// Accurate scale factor uses proper Web Mercator scaling\n\t// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf\n\t// See: http://jsfiddle.net/robhawkes/yws924cf/\n\tGeo.pointScale = function (latlon, accurate) {\n\t var rad = Math.PI / 180;\n\t\n\t var k;\n\t\n\t if (!accurate) {\n\t k = 1 / Math.cos(latlon.lat * rad);\n\t\n\t // [scaleX, scaleY]\n\t return [k, k];\n\t } else {\n\t var lat = latlon.lat * rad;\n\t var lon = latlon.lon * rad;\n\t\n\t var a = Geo.R;\n\t\n\t var sinLat = Math.sin(lat);\n\t var sinLat2 = sinLat * sinLat;\n\t\n\t var cosLat = Math.cos(lat);\n\t\n\t // Radius meridian\n\t var p = a * (1 - Geo.ECC2) / Math.pow(1 - Geo.ECC2 * sinLat2, 3 / 2);\n\t\n\t // Radius prime meridian\n\t var v = a / Math.sqrt(1 - Geo.ECC2 * sinLat2);\n\t\n\t // Scale N/S\n\t var h = a / p / cosLat;\n\t\n\t // Scale E/W\n\t k = a / v / cosLat;\n\t\n\t // [scaleX, scaleY]\n\t return [k, h];\n\t }\n\t};\n\t\n\t// Convert real metres to projected units\n\t//\n\t// Latitude scale is chosen because it fluctuates more than longitude\n\tGeo.metresToProjected = function (metres, pointScale) {\n\t return metres * pointScale[1];\n\t};\n\t\n\t// Convert projected units to real metres\n\t//\n\t// Latitude scale is chosen because it fluctuates more than longitude\n\tGeo.projectedToMetres = function (projectedUnits, pointScale) {\n\t return projectedUnits / pointScale[1];\n\t};\n\t\n\t// Convert real metres to a value in world (WebGL) units\n\tGeo.metresToWorld = function (metres, pointScale) {\n\t // Transform metres to projected metres using the latitude point scale\n\t //\n\t // Latitude scale is chosen because it fluctuates more than longitude\n\t var projectedMetres = Geo.metresToProjected(metres, pointScale);\n\t\n\t var scale = Geo.scale();\n\t\n\t // Scale projected metres\n\t var scaledMetres = scale * projectedMetres;\n\t\n\t return scaledMetres;\n\t};\n\t\n\t// Convert world (WebGL) units to a value in real metres\n\tGeo.worldToMetres = function (worldUnits, pointScale) {\n\t var scale = Geo.scale();\n\t\n\t var projectedUnits = worldUnits / scale;\n\t var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);\n\t\n\t return realMetres;\n\t};\n\t\n\t// If zoom is provided, returns the map width in pixels for a given zoom\n\t// Else, provides fixed scale value\n\tGeo.scale = function (zoom) {\n\t // If zoom is provided then return scale based on map tile zoom\n\t if (zoom >= 0) {\n\t return 256 * Math.pow(2, zoom);\n\t // Else, return fixed scale value to expand projected coordinates from\n\t // their 0 to 1 range into something more practical\n\t } else {\n\t return 1;\n\t }\n\t};\n\t\n\t// Returns zoom level for a given scale value\n\t// This only works with a scale value that is based on map pixel width\n\tGeo.zoom = function (scale) {\n\t return Math.log(scale / 256) / Math.LN2;\n\t};\n\t\n\t// Distance between two geographical points using spherical law of cosines\n\t// approximation or Haversine\n\t//\n\t// See: http://www.movable-type.co.uk/scripts/latlong.html\n\tGeo.distance = function (latlon1, latlon2, accurate) {\n\t var rad = Math.PI / 180;\n\t\n\t var lat1;\n\t var lat2;\n\t\n\t var a;\n\t\n\t if (!accurate) {\n\t lat1 = latlon1.lat * rad;\n\t lat2 = latlon2.lat * rad;\n\t\n\t a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);\n\t\n\t return Geo.R * Math.acos(Math.min(a, 1));\n\t } else {\n\t lat1 = latlon1.lat * rad;\n\t lat2 = latlon2.lat * rad;\n\t\n\t var lon1 = latlon1.lon * rad;\n\t var lon2 = latlon2.lon * rad;\n\t\n\t var deltaLat = lat2 - lat1;\n\t var deltaLon = lon2 - lon1;\n\t\n\t var halfDeltaLat = deltaLat / 2;\n\t var halfDeltaLon = deltaLon / 2;\n\t\n\t a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);\n\t\n\t var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\t\n\t return Geo.R * c;\n\t }\n\t};\n\t\n\tGeo.bounds = (function () {\n\t var d = Geo.R * Math.PI;\n\t return [[-d, -d], [d, d]];\n\t})();\n\t\n\texports['default'] = Geo;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\t/*\n\t * LatLon is a helper class for ensuring consistent geographic coordinates.\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js\n\t */\n\t\n\tvar LatLon = (function () {\n\t function LatLon(lat, lon, alt) {\n\t _classCallCheck(this, LatLon);\n\t\n\t if (isNaN(lat) || isNaN(lon)) {\n\t throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');\n\t }\n\t\n\t this.lat = +lat;\n\t this.lon = +lon;\n\t\n\t if (alt !== undefined) {\n\t this.alt = +alt;\n\t }\n\t }\n\t\n\t _createClass(LatLon, [{\n\t key: 'clone',\n\t value: function clone() {\n\t return new LatLon(this.lat, this.lon, this.alt);\n\t }\n\t }]);\n\t\n\t return LatLon;\n\t})();\n\t\n\texports['default'] = LatLon;\n\t\n\t// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)\n\t// Also converts between lng and lon\n\tvar noNew = function noNew(a, b, c) {\n\t if (a instanceof LatLon) {\n\t return a;\n\t }\n\t if (Array.isArray(a) && typeof a[0] !== 'object') {\n\t if (a.length === 3) {\n\t return new LatLon(a[0], a[1], a[2]);\n\t }\n\t if (a.length === 2) {\n\t return new LatLon(a[0], a[1]);\n\t }\n\t return null;\n\t }\n\t if (a === undefined || a === null) {\n\t return a;\n\t }\n\t if (typeof a === 'object' && 'lat' in a) {\n\t return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\n\t }\n\t if (b === undefined) {\n\t return null;\n\t }\n\t return new LatLon(a, b, c);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.latLon = noNew;\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/*\n\t * Point is a helper class for ensuring consistent world positions.\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js\n\t */\n\t\n\tvar Point = (function () {\n\t function Point(x, y, round) {\n\t _classCallCheck(this, Point);\n\t\n\t this.x = round ? Math.round(x) : x;\n\t this.y = round ? Math.round(y) : y;\n\t }\n\t\n\t _createClass(Point, [{\n\t key: \"clone\",\n\t value: function clone() {\n\t return new Point(this.x, this.y);\n\t }\n\t\n\t // Non-destructive\n\t }, {\n\t key: \"add\",\n\t value: function add(point) {\n\t return this.clone()._add(_point(point));\n\t }\n\t\n\t // Destructive\n\t }, {\n\t key: \"_add\",\n\t value: function _add(point) {\n\t this.x += point.x;\n\t this.y += point.y;\n\t return this;\n\t }\n\t\n\t // Non-destructive\n\t }, {\n\t key: \"subtract\",\n\t value: function subtract(point) {\n\t return this.clone()._subtract(_point(point));\n\t }\n\t\n\t // Destructive\n\t }, {\n\t key: \"_subtract\",\n\t value: function _subtract(point) {\n\t this.x -= point.x;\n\t this.y -= point.y;\n\t return this;\n\t }\n\t }]);\n\t\n\t return Point;\n\t})();\n\t\n\texports[\"default\"] = Point;\n\t\n\t// Accepts (point), ([x, y]) and (x, y, round)\n\tvar _point = function _point(x, y, round) {\n\t if (x instanceof Point) {\n\t return x;\n\t }\n\t if (Array.isArray(x)) {\n\t return new Point(x[0], x[1]);\n\t }\n\t if (x === undefined || x === null) {\n\t return x;\n\t }\n\t return new Point(x, y, round);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.point = _point;\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Scene = __webpack_require__(11);\n\t\n\tvar _Scene2 = _interopRequireDefault(_Scene);\n\t\n\tvar _DOMScene3D = __webpack_require__(12);\n\t\n\tvar _DOMScene3D2 = _interopRequireDefault(_DOMScene3D);\n\t\n\tvar _DOMScene2D = __webpack_require__(13);\n\t\n\tvar _DOMScene2D2 = _interopRequireDefault(_DOMScene2D);\n\t\n\tvar _Renderer = __webpack_require__(14);\n\t\n\tvar _Renderer2 = _interopRequireDefault(_Renderer);\n\t\n\tvar _DOMRenderer3D = __webpack_require__(15);\n\t\n\tvar _DOMRenderer3D2 = _interopRequireDefault(_DOMRenderer3D);\n\t\n\tvar _DOMRenderer2D = __webpack_require__(17);\n\t\n\tvar _DOMRenderer2D2 = _interopRequireDefault(_DOMRenderer2D);\n\t\n\tvar _Camera = __webpack_require__(19);\n\t\n\tvar _Camera2 = _interopRequireDefault(_Camera);\n\t\n\tvar _Picking = __webpack_require__(20);\n\t\n\tvar _Picking2 = _interopRequireDefault(_Picking);\n\t\n\tvar _EffectComposer = __webpack_require__(22);\n\t\n\tvar _EffectComposer2 = _interopRequireDefault(_EffectComposer);\n\t\n\tvar _vendorRenderPass = __webpack_require__(27);\n\t\n\tvar _vendorRenderPass2 = _interopRequireDefault(_vendorRenderPass);\n\t\n\tvar _vendorShaderPass = __webpack_require__(25);\n\t\n\tvar _vendorShaderPass2 = _interopRequireDefault(_vendorShaderPass);\n\t\n\tvar _vendorCopyShader = __webpack_require__(24);\n\t\n\tvar _vendorCopyShader2 = _interopRequireDefault(_vendorCopyShader);\n\t\n\tvar _vendorHorizontalTiltShiftShader = __webpack_require__(28);\n\t\n\tvar _vendorHorizontalTiltShiftShader2 = _interopRequireDefault(_vendorHorizontalTiltShiftShader);\n\t\n\tvar _vendorVerticalTiltShiftShader = __webpack_require__(29);\n\t\n\tvar _vendorVerticalTiltShiftShader2 = _interopRequireDefault(_vendorVerticalTiltShiftShader);\n\t\n\tvar _vendorFXAAShader = __webpack_require__(30);\n\t\n\tvar _vendorFXAAShader2 = _interopRequireDefault(_vendorFXAAShader);\n\t\n\tvar Engine = (function (_EventEmitter) {\n\t _inherits(Engine, _EventEmitter);\n\t\n\t function Engine(container, world) {\n\t _classCallCheck(this, Engine);\n\t\n\t console.log('Init Engine');\n\t\n\t _get(Object.getPrototypeOf(Engine.prototype), 'constructor', this).call(this);\n\t\n\t this._world = world;\n\t\n\t this._scene = _Scene2['default'];\n\t this._domScene3D = _DOMScene3D2['default'];\n\t this._domScene2D = _DOMScene2D2['default'];\n\t\n\t var antialias = this._world.options.postProcessing ? false : true;\n\t this._renderer = (0, _Renderer2['default'])(container, antialias);\n\t this._domRenderer3D = (0, _DOMRenderer3D2['default'])(container);\n\t this._domRenderer2D = (0, _DOMRenderer2D2['default'])(container);\n\t\n\t this._camera = (0, _Camera2['default'])(container);\n\t\n\t this._container = container;\n\t\n\t // TODO: Make this optional\n\t this._picking = (0, _Picking2['default'])(this._world, this._renderer, this._camera);\n\t\n\t this.clock = new _three2['default'].Clock();\n\t\n\t this._frustum = new _three2['default'].Frustum();\n\t\n\t if (this._world.options.postProcessing) {\n\t this._initPostProcessing();\n\t }\n\t }\n\t\n\t // TODO: Set up composer to automatically resize on viewport change\n\t // TODO: Update passes that rely on width / height on resize\n\t // TODO: Merge default passes into a single shader / pass for performance\n\t\n\t _createClass(Engine, [{\n\t key: '_initPostProcessing',\n\t value: function _initPostProcessing() {\n\t var renderPass = new _vendorRenderPass2['default'](this._scene, this._camera);\n\t\n\t // TODO: Look at using @mattdesl's optimised FXAA shader\n\t // https://github.com/mattdesl/three-shader-fxaa\n\t var fxaaPass = new _vendorShaderPass2['default'](_vendorFXAAShader2['default']);\n\t\n\t var hblurPass = new _vendorShaderPass2['default'](_vendorHorizontalTiltShiftShader2['default']);\n\t var vblurPass = new _vendorShaderPass2['default'](_vendorVerticalTiltShiftShader2['default']);\n\t var bluriness = 5;\n\t\n\t hblurPass.uniforms.r.value = vblurPass.uniforms.r.value = 0.6;\n\t\n\t var copyPass = new _vendorShaderPass2['default'](_vendorCopyShader2['default']);\n\t copyPass.renderToScreen = true;\n\t\n\t this._composer = (0, _EffectComposer2['default'])(this._renderer, this._container);\n\t\n\t this._composer.addPass(renderPass);\n\t this._composer.addPass(fxaaPass);\n\t this._composer.addPass(hblurPass);\n\t this._composer.addPass(vblurPass);\n\t this._composer.addPass(copyPass);\n\t\n\t var self = this;\n\t var updatePostProcessingSize = function updatePostProcessingSize() {\n\t var width = self._container.clientWidth;\n\t var height = self._container.clientHeight;\n\t\n\t // TODO: Re-enable this when perf issues can be solved\n\t //\n\t // Rendering double the resolution of the screen can be really slow\n\t // var pixelRatio = window.devicePixelRatio;\n\t var pixelRatio = 1;\n\t\n\t fxaaPass.uniforms.resolution.value.set(1 / (width * pixelRatio), 1 / (height * pixelRatio));\n\t\n\t hblurPass.uniforms.h.value = bluriness / (width * pixelRatio);\n\t vblurPass.uniforms.v.value = bluriness / (height * pixelRatio);\n\t };\n\t\n\t updatePostProcessingSize();\n\t window.addEventListener('resize', updatePostProcessingSize, false);\n\t }\n\t }, {\n\t key: 'update',\n\t value: function update(delta) {\n\t this.emit('preRender');\n\t\n\t if (this._world.options.postProcessing) {\n\t this._composer.render(delta);\n\t } else {\n\t this._renderer.render(this._scene, this._camera);\n\t }\n\t\n\t // Render picking scene\n\t // this._renderer.render(this._picking._pickingScene, this._camera);\n\t\n\t // Render DOM scenes\n\t this._domRenderer3D.render(this._domScene3D, this._camera);\n\t this._domRenderer2D.render(this._domScene2D, this._camera);\n\t\n\t this.emit('postRender');\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Remove any remaining objects from scene\n\t var child;\n\t for (var i = this._scene.children.length - 1; i >= 0; i--) {\n\t child = this._scene.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._scene.remove(child);\n\t\n\t if (child.geometry) {\n\t // Dispose of mesh and materials\n\t child.geometry.dispose();\n\t child.geometry = null;\n\t }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t };\n\t\n\t for (var i = this._domScene3D.children.length - 1; i >= 0; i--) {\n\t child = this._domScene3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._domScene3D.remove(child);\n\t };\n\t\n\t for (var i = this._domScene2D.children.length - 1; i >= 0; i--) {\n\t child = this._domScene2D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._domScene2D.remove(child);\n\t };\n\t\n\t this._picking.destroy();\n\t this._picking = null;\n\t\n\t this._world = null;\n\t this._scene = null;\n\t this._domScene3D = null;\n\t this._domScene2D = null;\n\t\n\t this._composer = null;\n\t this._renderer = null;\n\t\n\t this._domRenderer3D = null;\n\t this._domRenderer2D = null;\n\t this._camera = null;\n\t this._clock = null;\n\t this._frustum = null;\n\t }\n\t }]);\n\t\n\t return Engine;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Engine;\n\t\n\t// // Initialise without requiring new keyword\n\t// export default function(container, world) {\n\t// return new Engine(container, world);\n\t// };\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 10 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_10__;\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t\n\t // TODO: Re-enable when this works with the skybox\n\t // scene.fog = new THREE.Fog(0xffffff, 1, 15000);\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 13 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 14 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Scene = __webpack_require__(11);\n\t\n\tvar _Scene2 = _interopRequireDefault(_Scene);\n\t\n\t// This can only be accessed from Engine.renderer if you want to reference the\n\t// same scene in multiple places\n\t\n\texports['default'] = function (container, antialias) {\n\t var renderer = new _three2['default'].WebGLRenderer({\n\t antialias: antialias\n\t });\n\t\n\t // TODO: Re-enable when this works with the skybox\n\t // renderer.setClearColor(Scene.fog.color, 1);\n\t\n\t renderer.setClearColor(0xffffff, 1);\n\t\n\t // TODO: Re-enable this when perf issues can be solved\n\t //\n\t // Rendering double the resolution of the screen can be really slow\n\t // var pixelRatio = window.devicePixelRatio;\n\t var pixelRatio = 1;\n\t\n\t renderer.setPixelRatio(pixelRatio);\n\t\n\t // Gamma settings make things look nicer\n\t renderer.gammaInput = true;\n\t renderer.gammaOutput = true;\n\t\n\t renderer.shadowMap.enabled = true;\n\t\n\t // TODO: Work out which of the shadowmap types is best\n\t // https://github.com/mrdoob/three.js/blob/r56/src/Three.js#L107\n\t // renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n\t\n\t // TODO: Check that leaving this as default (CullFrontFace) is right\n\t // renderer.shadowMap.cullFace = THREE.CullFaceBack;\n\t\n\t container.appendChild(renderer.domElement);\n\t\n\t var updateSize = function updateSize() {\n\t renderer.setSize(container.clientWidth, container.clientHeight);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return renderer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorCSS3DRenderer = __webpack_require__(16);\n\t\n\tvar _DOMScene3D = __webpack_require__(12);\n\t\n\tvar _DOMScene3D2 = _interopRequireDefault(_DOMScene3D);\n\t\n\t// This can only be accessed from Engine.renderer if you want to reference the\n\t// same scene in multiple places\n\t\n\texports['default'] = function (container) {\n\t var renderer = new _vendorCSS3DRenderer.CSS3DRenderer();\n\t\n\t renderer.domElement.style.position = 'absolute';\n\t renderer.domElement.style.top = 0;\n\t\n\t container.appendChild(renderer.domElement);\n\t\n\t var updateSize = function updateSize() {\n\t renderer.setSize(container.clientWidth, container.clientHeight);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return renderer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\t/**\n\t * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar CSS3DObject = function CSS3DObject(element) {\n\t\n\t\t_three2['default'].Object3D.call(this);\n\t\n\t\tthis.element = element;\n\t\tthis.element.style.position = 'absolute';\n\t\n\t\tthis.addEventListener('removed', function (event) {\n\t\n\t\t\tif (this.element.parentNode !== null) {\n\t\n\t\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t\t}\n\t\t});\n\t};\n\t\n\tCSS3DObject.prototype = Object.create(_three2['default'].Object3D.prototype);\n\tCSS3DObject.prototype.constructor = CSS3DObject;\n\t\n\tvar CSS3DSprite = function CSS3DSprite(element) {\n\t\n\t\tCSS3DObject.call(this, element);\n\t};\n\t\n\tCSS3DSprite.prototype = Object.create(CSS3DObject.prototype);\n\tCSS3DSprite.prototype.constructor = CSS3DSprite;\n\t\n\t//\n\t\n\tvar CSS3DRenderer = function CSS3DRenderer() {\n\t\n\t\tconsole.log('THREE.CSS3DRenderer', _three2['default'].REVISION);\n\t\n\t\tvar _width, _height;\n\t\tvar _widthHalf, _heightHalf;\n\t\n\t\tvar matrix = new _three2['default'].Matrix4();\n\t\n\t\tvar cache = {\n\t\t\tcamera: { fov: 0, style: '' },\n\t\t\tobjects: {}\n\t\t};\n\t\n\t\tvar domElement = document.createElement('div');\n\t\tdomElement.style.overflow = 'hidden';\n\t\n\t\tdomElement.style.WebkitTransformStyle = 'preserve-3d';\n\t\tdomElement.style.MozTransformStyle = 'preserve-3d';\n\t\tdomElement.style.oTransformStyle = 'preserve-3d';\n\t\tdomElement.style.transformStyle = 'preserve-3d';\n\t\n\t\tthis.domElement = domElement;\n\t\n\t\tvar cameraElement = document.createElement('div');\n\t\n\t\tcameraElement.style.WebkitTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.MozTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.oTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.transformStyle = 'preserve-3d';\n\t\n\t\tdomElement.appendChild(cameraElement);\n\t\n\t\tthis.setClearColor = function () {};\n\t\n\t\tthis.getSize = function () {\n\t\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\t\t};\n\t\n\t\tthis.setSize = function (width, height) {\n\t\n\t\t\t_width = width;\n\t\t\t_height = height;\n\t\n\t\t\t_widthHalf = _width / 2;\n\t\t\t_heightHalf = _height / 2;\n\t\n\t\t\tdomElement.style.width = width + 'px';\n\t\t\tdomElement.style.height = height + 'px';\n\t\n\t\t\tcameraElement.style.width = width + 'px';\n\t\t\tcameraElement.style.height = height + 'px';\n\t\t};\n\t\n\t\tvar epsilon = function epsilon(value) {\n\t\n\t\t\treturn Math.abs(value) < Number.EPSILON ? 0 : value;\n\t\t};\n\t\n\t\tvar getCameraCSSMatrix = function getCameraCSSMatrix(matrix) {\n\t\n\t\t\tvar elements = matrix.elements;\n\t\n\t\t\treturn 'matrix3d(' + epsilon(elements[0]) + ',' + epsilon(-elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(elements[6]) + ',' + epsilon(elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(-elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(-elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')';\n\t\t};\n\t\n\t\tvar getObjectCSSMatrix = function getObjectCSSMatrix(matrix) {\n\t\n\t\t\tvar elements = matrix.elements;\n\t\n\t\t\treturn 'translate3d(-50%,-50%,0) matrix3d(' + epsilon(elements[0]) + ',' + epsilon(elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(-elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(-elements[6]) + ',' + epsilon(-elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')';\n\t\t};\n\t\n\t\tvar renderObject = function renderObject(object, camera) {\n\t\n\t\t\tif (object instanceof CSS3DObject) {\n\t\n\t\t\t\tvar style;\n\t\n\t\t\t\tif (object instanceof CSS3DSprite) {\n\t\n\t\t\t\t\t// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/\n\t\n\t\t\t\t\tmatrix.copy(camera.matrixWorldInverse);\n\t\t\t\t\tmatrix.transpose();\n\t\t\t\t\tmatrix.copyPosition(object.matrixWorld);\n\t\t\t\t\tmatrix.scale(object.scale);\n\t\n\t\t\t\t\tmatrix.elements[3] = 0;\n\t\t\t\t\tmatrix.elements[7] = 0;\n\t\t\t\t\tmatrix.elements[11] = 0;\n\t\t\t\t\tmatrix.elements[15] = 1;\n\t\n\t\t\t\t\tstyle = getObjectCSSMatrix(matrix);\n\t\t\t\t} else {\n\t\n\t\t\t\t\tstyle = getObjectCSSMatrix(object.matrixWorld);\n\t\t\t\t}\n\t\n\t\t\t\tvar element = object.element;\n\t\t\t\tvar cachedStyle = cache.objects[object.id];\n\t\n\t\t\t\tif (cachedStyle === undefined || cachedStyle !== style) {\n\t\n\t\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\t\telement.style.MozTransform = style;\n\t\t\t\t\telement.style.oTransform = style;\n\t\t\t\t\telement.style.transform = style;\n\t\n\t\t\t\t\tcache.objects[object.id] = style;\n\t\t\t\t}\n\t\n\t\t\t\tif (element.parentNode !== cameraElement) {\n\t\n\t\t\t\t\tcameraElement.appendChild(element);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (var i = 0, l = object.children.length; i < l; i++) {\n\t\n\t\t\t\trenderObject(object.children[i], camera);\n\t\t\t}\n\t\t};\n\t\n\t\tthis.render = function (scene, camera) {\n\t\n\t\t\tvar fov = 0.5 / Math.tan(_three2['default'].Math.degToRad(camera.fov * 0.5)) * _height;\n\t\n\t\t\tif (cache.camera.fov !== fov) {\n\t\n\t\t\t\tdomElement.style.WebkitPerspective = fov + 'px';\n\t\t\t\tdomElement.style.MozPerspective = fov + 'px';\n\t\t\t\tdomElement.style.oPerspective = fov + 'px';\n\t\t\t\tdomElement.style.perspective = fov + 'px';\n\t\n\t\t\t\tcache.camera.fov = fov;\n\t\t\t}\n\t\n\t\t\tscene.updateMatrixWorld();\n\t\n\t\t\tif (camera.parent === null) camera.updateMatrixWorld();\n\t\n\t\t\tcamera.matrixWorldInverse.getInverse(camera.matrixWorld);\n\t\n\t\t\tvar style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix(camera.matrixWorldInverse) + ' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)';\n\t\n\t\t\tif (cache.camera.style !== style) {\n\t\n\t\t\t\tcameraElement.style.WebkitTransform = style;\n\t\t\t\tcameraElement.style.MozTransform = style;\n\t\t\t\tcameraElement.style.oTransform = style;\n\t\t\t\tcameraElement.style.transform = style;\n\t\n\t\t\t\tcache.camera.style = style;\n\t\t\t}\n\t\n\t\t\trenderObject(scene, camera);\n\t\t};\n\t};\n\t\n\texports.CSS3DObject = CSS3DObject;\n\texports.CSS3DSprite = CSS3DSprite;\n\texports.CSS3DRenderer = CSS3DRenderer;\n\t\n\t_three2['default'].CSS3DObject = CSS3DObject;\n\t_three2['default'].CSS3DSprite = CSS3DSprite;\n\t_three2['default'].CSS3DRenderer = CSS3DRenderer;\n\n/***/ },\n/* 17 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorCSS2DRenderer = __webpack_require__(18);\n\t\n\tvar _DOMScene2D = __webpack_require__(13);\n\t\n\tvar _DOMScene2D2 = _interopRequireDefault(_DOMScene2D);\n\t\n\t// This can only be accessed from Engine.renderer if you want to reference the\n\t// same scene in multiple places\n\t\n\texports['default'] = function (container) {\n\t var renderer = new _vendorCSS2DRenderer.CSS2DRenderer();\n\t\n\t renderer.domElement.style.position = 'absolute';\n\t renderer.domElement.style.top = 0;\n\t\n\t container.appendChild(renderer.domElement);\n\t\n\t var updateSize = function updateSize() {\n\t renderer.setSize(container.clientWidth, container.clientHeight);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return renderer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 18 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar CSS2DObject = function CSS2DObject(element) {\n\t\n\t\t_three2['default'].Object3D.call(this);\n\t\n\t\tthis.element = element;\n\t\tthis.element.style.position = 'absolute';\n\t\n\t\tthis.addEventListener('removed', function (event) {\n\t\n\t\t\tif (this.element.parentNode !== null) {\n\t\n\t\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t\t}\n\t\t});\n\t};\n\t\n\tCSS2DObject.prototype = Object.create(_three2['default'].Object3D.prototype);\n\tCSS2DObject.prototype.constructor = CSS2DObject;\n\t\n\t//\n\t\n\tvar CSS2DRenderer = function CSS2DRenderer() {\n\t\n\t\tconsole.log('THREE.CSS2DRenderer', _three2['default'].REVISION);\n\t\n\t\tvar _width, _height;\n\t\tvar _widthHalf, _heightHalf;\n\t\n\t\tvar vector = new _three2['default'].Vector3();\n\t\tvar viewMatrix = new _three2['default'].Matrix4();\n\t\tvar viewProjectionMatrix = new _three2['default'].Matrix4();\n\t\n\t\tvar frustum = new _three2['default'].Frustum();\n\t\n\t\tvar domElement = document.createElement('div');\n\t\tdomElement.style.overflow = 'hidden';\n\t\n\t\tthis.domElement = domElement;\n\t\n\t\tthis.setSize = function (width, height) {\n\t\n\t\t\t_width = width;\n\t\t\t_height = height;\n\t\n\t\t\t_widthHalf = _width / 2;\n\t\t\t_heightHalf = _height / 2;\n\t\n\t\t\tdomElement.style.width = width + 'px';\n\t\t\tdomElement.style.height = height + 'px';\n\t\t};\n\t\n\t\tvar renderObject = function renderObject(object, camera) {\n\t\n\t\t\tif (object instanceof CSS2DObject) {\n\t\n\t\t\t\tvector.setFromMatrixPosition(object.matrixWorld);\n\t\t\t\tvector.applyProjection(viewProjectionMatrix);\n\t\n\t\t\t\tvar element = object.element;\n\t\t\t\tvar style = 'translate(-50%,-50%) translate(' + (vector.x * _widthHalf + _widthHalf) + 'px,' + (-vector.y * _heightHalf + _heightHalf) + 'px)';\n\t\n\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\telement.style.MozTransform = style;\n\t\t\t\telement.style.oTransform = style;\n\t\t\t\telement.style.transform = style;\n\t\n\t\t\t\tif (element.parentNode !== domElement) {\n\t\n\t\t\t\t\tdomElement.appendChild(element);\n\t\t\t\t}\n\t\n\t\t\t\t// Hide if outside view frustum\n\t\t\t\tif (!frustum.containsPoint(object.position)) {\n\t\t\t\t\telement.style.display = 'none';\n\t\t\t\t} else {\n\t\t\t\t\telement.style.display = 'block';\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (var i = 0, l = object.children.length; i < l; i++) {\n\t\n\t\t\t\trenderObject(object.children[i], camera);\n\t\t\t}\n\t\t};\n\t\n\t\tthis.render = function (scene, camera) {\n\t\n\t\t\tscene.updateMatrixWorld();\n\t\n\t\t\tif (camera.parent === null) camera.updateMatrixWorld();\n\t\n\t\t\tcamera.matrixWorldInverse.getInverse(camera.matrixWorld);\n\t\n\t\t\tviewMatrix.copy(camera.matrixWorldInverse.getInverse(camera.matrixWorld));\n\t\t\tviewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, viewMatrix);\n\t\n\t\t\tfrustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n\t\n\t\t\trenderObject(scene, camera);\n\t\t};\n\t};\n\t\n\texports.CSS2DObject = CSS2DObject;\n\texports.CSS2DRenderer = CSS2DRenderer;\n\t\n\t_three2['default'].CSS2DObject = CSS2DObject;\n\t_three2['default'].CSS2DRenderer = CSS2DRenderer;\n\n/***/ },\n/* 19 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can only be accessed from Engine.camera if you want to reference the\n\t// same scene in multiple places\n\t\n\t// TODO: Ensure that FOV looks natural on all aspect ratios\n\t// http://stackoverflow.com/q/26655930/997339\n\t\n\texports['default'] = function (container) {\n\t var camera = new _three2['default'].PerspectiveCamera(45, 1, 1, 2000000);\n\t camera.position.y = 4000;\n\t camera.position.z = 4000;\n\t\n\t var updateSize = function updateSize() {\n\t camera.aspect = container.clientWidth / container.clientHeight;\n\t camera.updateProjectionMatrix();\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return camera;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _PickingScene = __webpack_require__(21);\n\t\n\tvar _PickingScene2 = _interopRequireDefault(_PickingScene);\n\t\n\t// TODO: Look into a way of setting this up without passing in a renderer and\n\t// camera from the engine\n\t\n\t// TODO: Add a basic indicator on or around the mouse pointer when it is over\n\t// something pickable / clickable\n\t//\n\t// A simple transparent disc or ring at the mouse point should work to start, or\n\t// even just changing the cursor to the CSS 'pointer' style\n\t//\n\t// Probably want this on mousemove with a throttled update as not to spam the\n\t// picking method\n\t//\n\t// Relies upon the picking method not redrawing the scene every call due to\n\t// the way TileLayer invalidates the picking scene\n\t\n\tvar nextId = 1;\n\t\n\tvar Picking = (function () {\n\t function Picking(world, renderer, camera) {\n\t _classCallCheck(this, Picking);\n\t\n\t this._world = world;\n\t this._renderer = renderer;\n\t this._camera = camera;\n\t\n\t this._raycaster = new _three2['default'].Raycaster();\n\t\n\t // TODO: Match this with the line width used in the picking layers\n\t this._raycaster.linePrecision = 3;\n\t\n\t this._pickingScene = _PickingScene2['default'];\n\t this._pickingTexture = new _three2['default'].WebGLRenderTarget();\n\t this._pickingTexture.texture.minFilter = _three2['default'].LinearFilter;\n\t this._pickingTexture.texture.generateMipmaps = false;\n\t\n\t this._nextId = 1;\n\t\n\t this._resizeTexture();\n\t this._initEvents();\n\t }\n\t\n\t // Initialise without requiring new keyword\n\t\n\t _createClass(Picking, [{\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t this._resizeHandler = this._resizeTexture.bind(this);\n\t window.addEventListener('resize', this._resizeHandler, false);\n\t\n\t this._mouseUpHandler = this._onMouseUp.bind(this);\n\t this._world._container.addEventListener('mouseup', this._mouseUpHandler, false);\n\t\n\t this._world.on('move', this._onWorldMove, this);\n\t }\n\t }, {\n\t key: '_onMouseUp',\n\t value: function _onMouseUp(event) {\n\t // Only react to main button click\n\t if (event.button !== 0) {\n\t return;\n\t }\n\t\n\t var point = (0, _geoPoint.point)(event.clientX, event.clientY);\n\t\n\t var normalisedPoint = (0, _geoPoint.point)(0, 0);\n\t normalisedPoint.x = point.x / this._width * 2 - 1;\n\t normalisedPoint.y = -(point.y / this._height) * 2 + 1;\n\t\n\t this._pick(point, normalisedPoint);\n\t }\n\t }, {\n\t key: '_onWorldMove',\n\t value: function _onWorldMove() {\n\t this._needUpdate = true;\n\t }\n\t\n\t // TODO: Ensure this doesn't get out of sync issue with the renderer resize\n\t }, {\n\t key: '_resizeTexture',\n\t value: function _resizeTexture() {\n\t var size = this._renderer.getSize();\n\t\n\t this._width = size.width;\n\t this._height = size.height;\n\t\n\t this._pickingTexture.setSize(this._width, this._height);\n\t this._pixelBuffer = new Uint8Array(4 * this._width * this._height);\n\t\n\t this._needUpdate = true;\n\t }\n\t\n\t // TODO: Make this only re-draw the scene if both an update is needed and the\n\t // camera has moved since the last update\n\t //\n\t // Otherwise it re-draws the scene on every click due to the way LOD updates\n\t // work in TileLayer – spamming this.add() and this.remove()\n\t //\n\t // TODO: Pause updates during map move / orbit / zoom as this is unlikely to\n\t // be a point in time where the user cares for picking functionality\n\t }, {\n\t key: '_update',\n\t value: function _update() {\n\t if (this._needUpdate) {\n\t var texture = this._pickingTexture;\n\t\n\t this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);\n\t\n\t // Read the rendering texture\n\t this._renderer.readRenderTargetPixels(texture, 0, 0, texture.width, texture.height, this._pixelBuffer);\n\t\n\t this._needUpdate = false;\n\t }\n\t }\n\t }, {\n\t key: '_pick',\n\t value: function _pick(point, normalisedPoint) {\n\t this._update();\n\t\n\t var index = point.x + (this._pickingTexture.height - point.y) * this._pickingTexture.width;\n\t\n\t // Interpret the pixel as an ID\n\t var id = this._pixelBuffer[index * 4 + 2] * 255 * 255 + this._pixelBuffer[index * 4 + 1] * 255 + this._pixelBuffer[index * 4 + 0];\n\t\n\t // Skip if ID is 16646655 (white) as the background returns this\n\t if (id === 16646655) {\n\t return;\n\t }\n\t\n\t this._raycaster.setFromCamera(normalisedPoint, this._camera);\n\t\n\t // Perform ray intersection on picking scene\n\t //\n\t // TODO: Only perform intersection test on the relevant picking mesh\n\t var intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);\n\t\n\t var _point2d = point.clone();\n\t\n\t var _point3d;\n\t if (intersects.length > 0) {\n\t _point3d = intersects[0].point.clone();\n\t }\n\t\n\t // Pass along as much data as possible for now until we know more about how\n\t // people use the picking API and what the returned data should be\n\t //\n\t // TODO: Look into the leak potential for passing so much by reference here\n\t this._world.emit('pick', id, _point2d, _point3d, intersects);\n\t this._world.emit('pick-' + id, _point2d, _point3d, intersects);\n\t }\n\t\n\t // Add mesh to picking scene\n\t //\n\t // Picking ID should already be added as an attribute\n\t }, {\n\t key: 'add',\n\t value: function add(mesh) {\n\t this._pickingScene.add(mesh);\n\t this._needUpdate = true;\n\t }\n\t\n\t // Remove mesh from picking scene\n\t }, {\n\t key: 'remove',\n\t value: function remove(mesh) {\n\t this._pickingScene.remove(mesh);\n\t this._needUpdate = true;\n\t }\n\t\n\t // Returns next ID to use for picking\n\t }, {\n\t key: 'getNextId',\n\t value: function getNextId() {\n\t return nextId++;\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // TODO: Find a way to properly remove these listeners as they stay\n\t // active at the moment\n\t window.removeEventListener('resize', this._resizeHandler, false);\n\t this._world._container.removeEventListener('mouseup', this._mouseUpHandler, false);\n\t\n\t this._world.off('move', this._onWorldMove);\n\t\n\t if (this._pickingScene.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._pickingScene.children.length - 1; i >= 0; i--) {\n\t child = this._pickingScene.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._pickingScene.remove(child);\n\t\n\t // Probably not a good idea to dispose of geometry due to it being\n\t // shared with the non-picking scene\n\t // if (child.geometry) {\n\t // // Dispose of mesh and materials\n\t // child.geometry.dispose();\n\t // child.geometry = null;\n\t // }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t }\n\t }\n\t\n\t this._pickingScene = null;\n\t this._pickingTexture = null;\n\t this._pixelBuffer = null;\n\t\n\t this._world = null;\n\t this._renderer = null;\n\t this._camera = null;\n\t }\n\t }]);\n\t\n\t return Picking;\n\t})();\n\t\n\texports['default'] = function (world, renderer, camera) {\n\t return new Picking(world, renderer, camera);\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.pickingScene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 22 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorEffectComposer = __webpack_require__(23);\n\t\n\tvar _vendorEffectComposer2 = _interopRequireDefault(_vendorEffectComposer);\n\t\n\texports['default'] = function (renderer, container) {\n\t var composer = new _vendorEffectComposer2['default'](renderer);\n\t\n\t var updateSize = function updateSize() {\n\t // TODO: Re-enable this when perf issues can be solved\n\t //\n\t // Rendering double the resolution of the screen can be really slow\n\t // var pixelRatio = window.devicePixelRatio;\n\t var pixelRatio = 1;\n\t\n\t composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return composer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 23 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _CopyShader = __webpack_require__(24);\n\t\n\tvar _CopyShader2 = _interopRequireDefault(_CopyShader);\n\t\n\tvar _ShaderPass = __webpack_require__(25);\n\t\n\tvar _ShaderPass2 = _interopRequireDefault(_ShaderPass);\n\t\n\tvar _MaskPass = __webpack_require__(26);\n\t\n\tvar _MaskPass2 = _interopRequireDefault(_MaskPass);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar EffectComposer = function EffectComposer(renderer, renderTarget) {\n\t\n\t\tthis.renderer = renderer;\n\t\n\t\tif (renderTarget === undefined) {\n\t\n\t\t\tvar pixelRatio = renderer.getPixelRatio();\n\t\n\t\t\tvar width = Math.floor(renderer.context.canvas.width / pixelRatio) || 1;\n\t\t\tvar height = Math.floor(renderer.context.canvas.height / pixelRatio) || 1;\n\t\t\tvar parameters = { minFilter: _three2['default'].LinearFilter, magFilter: _three2['default'].LinearFilter, format: _three2['default'].RGBAFormat, stencilBuffer: false };\n\t\n\t\t\trenderTarget = new _three2['default'].WebGLRenderTarget(width, height, parameters);\n\t\t}\n\t\n\t\tthis.renderTarget1 = renderTarget;\n\t\tthis.renderTarget2 = renderTarget.clone();\n\t\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\t\n\t\tthis.passes = [];\n\t\n\t\tif (_CopyShader2['default'] === undefined) console.error(\"EffectComposer relies on THREE.CopyShader\");\n\t\n\t\tthis.copyPass = new _ShaderPass2['default'](_CopyShader2['default']);\n\t};\n\t\n\tEffectComposer.prototype = {\n\t\n\t\tswapBuffers: function swapBuffers() {\n\t\n\t\t\tvar tmp = this.readBuffer;\n\t\t\tthis.readBuffer = this.writeBuffer;\n\t\t\tthis.writeBuffer = tmp;\n\t\t},\n\t\n\t\taddPass: function addPass(pass) {\n\t\n\t\t\tthis.passes.push(pass);\n\t\t},\n\t\n\t\tinsertPass: function insertPass(pass, index) {\n\t\n\t\t\tthis.passes.splice(index, 0, pass);\n\t\t},\n\t\n\t\trender: function render(delta) {\n\t\n\t\t\tthis.writeBuffer = this.renderTarget1;\n\t\t\tthis.readBuffer = this.renderTarget2;\n\t\n\t\t\tvar maskActive = false;\n\t\n\t\t\tvar pass,\n\t\t\t i,\n\t\t\t il = this.passes.length;\n\t\n\t\t\tfor (i = 0; i < il; i++) {\n\t\n\t\t\t\tpass = this.passes[i];\n\t\n\t\t\t\tif (!pass.enabled) continue;\n\t\n\t\t\t\tpass.render(this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive);\n\t\n\t\t\t\tif (pass.needsSwap) {\n\t\n\t\t\t\t\tif (maskActive) {\n\t\n\t\t\t\t\t\tvar context = this.renderer.context;\n\t\n\t\t\t\t\t\tcontext.stencilFunc(context.NOTEQUAL, 1, 0xffffffff);\n\t\n\t\t\t\t\t\tthis.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, delta);\n\t\n\t\t\t\t\t\tcontext.stencilFunc(context.EQUAL, 1, 0xffffffff);\n\t\t\t\t\t}\n\t\n\t\t\t\t\tthis.swapBuffers();\n\t\t\t\t}\n\t\n\t\t\t\tif (pass instanceof _MaskPass2['default']) {\n\t\n\t\t\t\t\tmaskActive = true;\n\t\t\t\t} else if (pass instanceof _MaskPass.ClearMaskPass) {\n\t\n\t\t\t\t\tmaskActive = false;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\treset: function reset(renderTarget) {\n\t\n\t\t\tif (renderTarget === undefined) {\n\t\n\t\t\t\trenderTarget = this.renderTarget1.clone();\n\t\n\t\t\t\tvar pixelRatio = this.renderer.getPixelRatio();\n\t\n\t\t\t\trenderTarget.setSize(Math.floor(this.renderer.context.canvas.width / pixelRatio), Math.floor(this.renderer.context.canvas.height / pixelRatio));\n\t\t\t}\n\t\n\t\t\tthis.renderTarget1.dispose();\n\t\t\tthis.renderTarget1 = renderTarget;\n\t\t\tthis.renderTarget2.dispose();\n\t\t\tthis.renderTarget2 = renderTarget.clone();\n\t\n\t\t\tthis.writeBuffer = this.renderTarget1;\n\t\t\tthis.readBuffer = this.renderTarget2;\n\t\t},\n\t\n\t\tsetSize: function setSize(width, height) {\n\t\n\t\t\tthis.renderTarget1.setSize(width, height);\n\t\t\tthis.renderTarget2.setSize(width, height);\n\t\t}\n\t\n\t};\n\t\n\texports['default'] = EffectComposer;\n\t\n\t_three2['default'].EffectComposer = EffectComposer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 24 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Full-screen textured quad shader\n\t */\n\t\n\tvar CopyShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"opacity\": { type: \"f\", value: 1.0 }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"varying vec2 vUv;\", \"void main() {\", \"vUv = uv;\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform float opacity;\", \"uniform sampler2D tDiffuse;\", \"varying vec2 vUv;\", \"void main() {\", \"vec4 texel = texture2D( tDiffuse, vUv );\", \"gl_FragColor = opacity * texel;\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = CopyShader;\n\t\n\t_three2[\"default\"].CopyShader = CopyShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 25 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar ShaderPass = function ShaderPass(shader, textureID) {\n\t\n\t\tthis.textureID = textureID !== undefined ? textureID : \"tDiffuse\";\n\t\n\t\tif (shader instanceof _three2[\"default\"].ShaderMaterial) {\n\t\n\t\t\tthis.uniforms = shader.uniforms;\n\t\n\t\t\tthis.material = shader;\n\t\t} else if (shader) {\n\t\n\t\t\tthis.uniforms = _three2[\"default\"].UniformsUtils.clone(shader.uniforms);\n\t\n\t\t\tthis.material = new _three2[\"default\"].ShaderMaterial({\n\t\n\t\t\t\tdefines: shader.defines || {},\n\t\t\t\tuniforms: this.uniforms,\n\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\tfragmentShader: shader.fragmentShader\n\t\n\t\t\t});\n\t\t}\n\t\n\t\tthis.renderToScreen = false;\n\t\n\t\tthis.enabled = true;\n\t\tthis.needsSwap = true;\n\t\tthis.clear = false;\n\t\n\t\tthis.camera = new _three2[\"default\"].OrthographicCamera(-1, 1, 1, -1, 0, 1);\n\t\tthis.scene = new _three2[\"default\"].Scene();\n\t\n\t\tthis.quad = new _three2[\"default\"].Mesh(new _three2[\"default\"].PlaneBufferGeometry(2, 2), null);\n\t\tthis.scene.add(this.quad);\n\t};\n\t\n\tShaderPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tif (this.uniforms[this.textureID]) {\n\t\n\t\t\t\tthis.uniforms[this.textureID].value = readBuffer;\n\t\t\t}\n\t\n\t\t\tthis.quad.material = this.material;\n\t\n\t\t\tif (this.renderToScreen) {\n\t\n\t\t\t\trenderer.render(this.scene, this.camera);\n\t\t\t} else {\n\t\n\t\t\t\trenderer.render(this.scene, this.camera, writeBuffer, this.clear);\n\t\t\t}\n\t\t}\n\t\n\t};\n\t\n\texports[\"default\"] = ShaderPass;\n\t\n\t_three2[\"default\"].ShaderPass = ShaderPass;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 26 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar MaskPass = function MaskPass(scene, camera) {\n\t\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\t\n\t\tthis.enabled = true;\n\t\tthis.clear = true;\n\t\tthis.needsSwap = false;\n\t\n\t\tthis.inverse = false;\n\t};\n\t\n\tMaskPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tvar context = renderer.context;\n\t\n\t\t\t// don't update color or depth\n\t\n\t\t\tcontext.colorMask(false, false, false, false);\n\t\t\tcontext.depthMask(false);\n\t\n\t\t\t// set up stencil\n\t\n\t\t\tvar writeValue, clearValue;\n\t\n\t\t\tif (this.inverse) {\n\t\n\t\t\t\twriteValue = 0;\n\t\t\t\tclearValue = 1;\n\t\t\t} else {\n\t\n\t\t\t\twriteValue = 1;\n\t\t\t\tclearValue = 0;\n\t\t\t}\n\t\n\t\t\tcontext.enable(context.STENCIL_TEST);\n\t\t\tcontext.stencilOp(context.REPLACE, context.REPLACE, context.REPLACE);\n\t\t\tcontext.stencilFunc(context.ALWAYS, writeValue, 0xffffffff);\n\t\t\tcontext.clearStencil(clearValue);\n\t\n\t\t\t// draw into the stencil buffer\n\t\n\t\t\trenderer.render(this.scene, this.camera, readBuffer, this.clear);\n\t\t\trenderer.render(this.scene, this.camera, writeBuffer, this.clear);\n\t\n\t\t\t// re-enable update of color and depth\n\t\n\t\t\tcontext.colorMask(true, true, true, true);\n\t\t\tcontext.depthMask(true);\n\t\n\t\t\t// only render where stencil is set to 1\n\t\n\t\t\tcontext.stencilFunc(context.EQUAL, 1, 0xffffffff); // draw if == 1\n\t\t\tcontext.stencilOp(context.KEEP, context.KEEP, context.KEEP);\n\t\t}\n\t\n\t};\n\t\n\tvar ClearMaskPass = function ClearMaskPass() {\n\t\n\t\tthis.enabled = true;\n\t};\n\t\n\tClearMaskPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tvar context = renderer.context;\n\t\n\t\t\tcontext.disable(context.STENCIL_TEST);\n\t\t}\n\t\n\t};\n\t\n\texports['default'] = MaskPass;\n\texports.ClearMaskPass = ClearMaskPass;\n\t\n\t_three2['default'].MaskPass = MaskPass;\n\t_three2['default'].ClearMaskPass = ClearMaskPass;\n\n/***/ },\n/* 27 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar RenderPass = function RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha) {\n\t\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\t\n\t\tthis.overrideMaterial = overrideMaterial;\n\t\n\t\tthis.clearColor = clearColor;\n\t\tthis.clearAlpha = clearAlpha !== undefined ? clearAlpha : 1;\n\t\n\t\tthis.oldClearColor = new _three2['default'].Color();\n\t\tthis.oldClearAlpha = 1;\n\t\n\t\tthis.enabled = true;\n\t\tthis.clear = true;\n\t\tthis.needsSwap = false;\n\t};\n\t\n\tRenderPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tthis.scene.overrideMaterial = this.overrideMaterial;\n\t\n\t\t\tif (this.clearColor) {\n\t\n\t\t\t\tthis.oldClearColor.copy(renderer.getClearColor());\n\t\t\t\tthis.oldClearAlpha = renderer.getClearAlpha();\n\t\n\t\t\t\trenderer.setClearColor(this.clearColor, this.clearAlpha);\n\t\t\t}\n\t\n\t\t\trenderer.render(this.scene, this.camera, readBuffer, this.clear);\n\t\n\t\t\tif (this.clearColor) {\n\t\n\t\t\t\trenderer.setClearColor(this.oldClearColor, this.oldClearAlpha);\n\t\t\t}\n\t\n\t\t\tthis.scene.overrideMaterial = null;\n\t\t}\n\t\n\t};\n\t\n\texports['default'] = RenderPass;\n\t\n\t_three2['default'].RenderPass = RenderPass;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 28 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n\t *\n\t * - 9 samples per pass\n\t * - standard deviation 2.7\n\t * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n\t * - \"r\" parameter control where \"focused\" horizontal line lies\n\t */\n\t\n\tvar HorizontalTiltShiftShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"h\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\t\"r\": { type: \"f\", value: 0.35 }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"varying vec2 vUv;\", \"void main() {\", \"vUv = uv;\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform sampler2D tDiffuse;\", \"uniform float h;\", \"uniform float r;\", \"varying vec2 vUv;\", \"void main() {\", \"vec4 sum = vec4( 0.0 );\", \"float hh = h * abs( r - vUv.y );\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;\", \"gl_FragColor = sum;\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = HorizontalTiltShiftShader;\n\t\n\t_three2[\"default\"].HorizontalTiltShiftShader = HorizontalTiltShiftShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 29 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n\t *\n\t * - 9 samples per pass\n\t * - standard deviation 2.7\n\t * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n\t * - \"r\" parameter control where \"focused\" horizontal line lies\n\t */\n\t\n\tvar VerticalTiltShiftShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"v\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\t\"r\": { type: \"f\", value: 0.35 }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"varying vec2 vUv;\", \"void main() {\", \"vUv = uv;\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform sampler2D tDiffuse;\", \"uniform float v;\", \"uniform float r;\", \"varying vec2 vUv;\", \"void main() {\", \"vec4 sum = vec4( 0.0 );\", \"float vv = v * abs( r - vUv.y );\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;\", \"gl_FragColor = sum;\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = VerticalTiltShiftShader;\n\t\n\t_three2[\"default\"].VerticalTiltShiftShader = VerticalTiltShiftShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 30 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author davidedc / http://www.sketchpatch.net/\n\t *\n\t * NVIDIA FXAA by Timothy Lottes\n\t * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html\n\t * - WebGL port by @supereggbert\n\t * http://www.glge.org/demos/fxaa/\n\t */\n\t\n\tvar FXAAShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"resolution\": { type: \"v2\", value: new _three2[\"default\"].Vector2(1 / 1024, 1 / 512) }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"void main() {\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform sampler2D tDiffuse;\", \"uniform vec2 resolution;\", \"#define FXAA_REDUCE_MIN (1.0/128.0)\", \"#define FXAA_REDUCE_MUL (1.0/8.0)\", \"#define FXAA_SPAN_MAX 8.0\", \"void main() {\", \"vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;\", \"vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;\", \"vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;\", \"vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;\", \"vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );\", \"vec3 rgbM = rgbaM.xyz;\", \"vec3 luma = vec3( 0.299, 0.587, 0.114 );\", \"float lumaNW = dot( rgbNW, luma );\", \"float lumaNE = dot( rgbNE, luma );\", \"float lumaSW = dot( rgbSW, luma );\", \"float lumaSE = dot( rgbSE, luma );\", \"float lumaM = dot( rgbM, luma );\", \"float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\", \"float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\", \"vec2 dir;\", \"dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\", \"dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\", \"float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\", \"float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\", \"dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\", \"max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\", \"dir * rcpDirMin)) * resolution;\", \"vec4 rgbA = (1.0/2.0) * (\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));\", \"vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));\", \"float lumaB = dot(rgbB, vec4(luma, 0.0));\", \"if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {\", \"gl_FragColor = rgbA;\", \"} else {\", \"gl_FragColor = rgbB;\", \"}\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = FXAAShader;\n\t\n\t_three2[\"default\"].FXAAShader = FXAAShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 31 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(32);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Skybox = __webpack_require__(33);\n\t\n\tvar _Skybox2 = _interopRequireDefault(_Skybox);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\tvar EnvironmentLayer = (function (_Layer) {\n\t _inherits(EnvironmentLayer, _Layer);\n\t\n\t function EnvironmentLayer(options) {\n\t _classCallCheck(this, EnvironmentLayer);\n\t\n\t var defaults = {\n\t skybox: false\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'constructor', this).call(this, _options);\n\t }\n\t\n\t _createClass(EnvironmentLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd() {\n\t this._initLights();\n\t\n\t if (this._options.skybox) {\n\t this._initSkybox();\n\t }\n\t\n\t // this._initGrid();\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Not fleshed out or thought through yet\n\t //\n\t // Lights could potentially be put it their own 'layer' to keep this class\n\t // much simpler and less messy\n\t }, {\n\t key: '_initLights',\n\t value: function _initLights() {\n\t // Position doesn't really matter (the angle is important), however it's\n\t // used here so the helpers look more natural.\n\t\n\t if (!this._options.skybox) {\n\t var directionalLight = new _three2['default'].DirectionalLight(0xffffff, 1);\n\t directionalLight.position.x = 10000;\n\t directionalLight.position.y = 10000;\n\t directionalLight.position.z = 10000;\n\t\n\t // TODO: Get shadows working in non-PBR scenes\n\t\n\t // directionalLight.castShadow = true;\n\t //\n\t // var d = 100;\n\t // directionalLight.shadow.camera.left = -d;\n\t // directionalLight.shadow.camera.right = d;\n\t // directionalLight.shadow.camera.top = d;\n\t // directionalLight.shadow.camera.bottom = -d;\n\t //\n\t // directionalLight.shadow.camera.near = 10;\n\t // directionalLight.shadow.camera.far = 100;\n\t //\n\t // // TODO: Need to dial in on a good shadowmap size\n\t // directionalLight.shadow.mapSize.width = 2048;\n\t // directionalLight.shadow.mapSize.height = 2048;\n\t //\n\t // // directionalLight.shadowBias = -0.0010;\n\t // // directionalLight.shadow.darkness = 0.15;\n\t\n\t var directionalLight2 = new _three2['default'].DirectionalLight(0xffffff, 0.5);\n\t directionalLight2.position.x = -10000;\n\t directionalLight2.position.y = 10000;\n\t directionalLight2.position.z = 0;\n\t\n\t var directionalLight3 = new _three2['default'].DirectionalLight(0xffffff, 0.5);\n\t directionalLight3.position.x = 10000;\n\t directionalLight3.position.y = 10000;\n\t directionalLight3.position.z = -10000;\n\t\n\t this.add(directionalLight);\n\t this.add(directionalLight2);\n\t this.add(directionalLight3);\n\t\n\t // var helper = new THREE.DirectionalLightHelper(directionalLight, 10);\n\t // var helper2 = new THREE.DirectionalLightHelper(directionalLight2, 10);\n\t // var helper3 = new THREE.DirectionalLightHelper(directionalLight3, 10);\n\t //\n\t // this.add(helper);\n\t // this.add(helper2);\n\t // this.add(helper3);\n\t } else {\n\t // Directional light that will be projected from the sun\n\t this._skyboxLight = new _three2['default'].DirectionalLight(0xffffff, 1);\n\t\n\t this._skyboxLight.castShadow = true;\n\t\n\t var d = 10000;\n\t this._skyboxLight.shadow.camera.left = -d;\n\t this._skyboxLight.shadow.camera.right = d;\n\t this._skyboxLight.shadow.camera.top = d;\n\t this._skyboxLight.shadow.camera.bottom = -d;\n\t\n\t this._skyboxLight.shadow.camera.near = 10000;\n\t this._skyboxLight.shadow.camera.far = 70000;\n\t\n\t // TODO: Need to dial in on a good shadowmap size\n\t this._skyboxLight.shadow.mapSize.width = 2048;\n\t this._skyboxLight.shadow.mapSize.height = 2048;\n\t\n\t // this._skyboxLight.shadowBias = -0.0010;\n\t // this._skyboxLight.shadow.darkness = 0.15;\n\t\n\t // this._object3D.add(new THREE.CameraHelper(this._skyboxLight.shadow.camera));\n\t\n\t this.add(this._skyboxLight);\n\t }\n\t }\n\t }, {\n\t key: '_initSkybox',\n\t value: function _initSkybox() {\n\t this._skybox = new _Skybox2['default'](this._world, this._skyboxLight);\n\t this.add(this._skybox._mesh);\n\t }\n\t\n\t // Add grid helper for context during initial development\n\t }, {\n\t key: '_initGrid',\n\t value: function _initGrid() {\n\t var size = 4000;\n\t var step = 100;\n\t\n\t var gridHelper = new _three2['default'].GridHelper(size, step);\n\t this.add(gridHelper);\n\t }\n\t\n\t // Clean up environment\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._skyboxLight = null;\n\t\n\t this.remove(this._skybox._mesh);\n\t this._skybox.destroy();\n\t this._skybox = null;\n\t\n\t _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return EnvironmentLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = EnvironmentLayer;\n\t\n\tvar noNew = function noNew(options) {\n\t return new EnvironmentLayer(options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.environmentLayer = noNew;\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _engineScene = __webpack_require__(11);\n\t\n\tvar _engineScene2 = _interopRequireDefault(_engineScene);\n\t\n\tvar _vendorCSS3DRenderer = __webpack_require__(16);\n\t\n\tvar _vendorCSS2DRenderer = __webpack_require__(18);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Need a single move method that handles moving all the various object\n\t// layers so that the DOM layers stay in sync with the 3D layer\n\t\n\t// TODO: Double check that objects within the _object3D Object3D parent are frustum\n\t// culled even if the layer position stays at the default (0,0,0) and the child\n\t// objects are positioned much further away\n\t//\n\t// Or does the layer being at (0,0,0) prevent the child objects from being\n\t// culled because the layer parent is effectively always in view even if the\n\t// child is actually out of camera\n\t\n\tvar Layer = (function (_EventEmitter) {\n\t _inherits(Layer, _EventEmitter);\n\t\n\t function Layer(options) {\n\t _classCallCheck(this, Layer);\n\t\n\t _get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this);\n\t\n\t var defaults = {\n\t output: true,\n\t outputToScene: true\n\t };\n\t\n\t this._options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (this.isOutput()) {\n\t this._object3D = new _three2['default'].Object3D();\n\t\n\t this._dom3D = document.createElement('div');\n\t this._domObject3D = new _vendorCSS3DRenderer.CSS3DObject(this._dom3D);\n\t\n\t this._dom2D = document.createElement('div');\n\t this._domObject2D = new _vendorCSS2DRenderer.CSS2DObject(this._dom2D);\n\t }\n\t }\n\t\n\t // Add THREE object directly to layer\n\t\n\t _createClass(Layer, [{\n\t key: 'add',\n\t value: function add(object) {\n\t this._object3D.add(object);\n\t }\n\t\n\t // Remove THREE object from to layer\n\t }, {\n\t key: 'remove',\n\t value: function remove(object) {\n\t this._object3D.remove(object);\n\t }\n\t }, {\n\t key: 'addDOM3D',\n\t value: function addDOM3D(object) {\n\t this._domObject3D.add(object);\n\t }\n\t }, {\n\t key: 'removeDOM3D',\n\t value: function removeDOM3D(object) {\n\t this._domObject3D.remove(object);\n\t }\n\t }, {\n\t key: 'addDOM2D',\n\t value: function addDOM2D(object) {\n\t this._domObject2D.add(object);\n\t }\n\t }, {\n\t key: 'removeDOM2D',\n\t value: function removeDOM2D(object) {\n\t this._domObject2D.remove(object);\n\t }\n\t\n\t // Add layer to world instance and store world reference\n\t }, {\n\t key: 'addTo',\n\t value: function addTo(world) {\n\t return world.addLayer(this);\n\t }\n\t\n\t // Internal method called by World.addLayer to actually add the layer\n\t }, {\n\t key: '_addToWorld',\n\t value: function _addToWorld(world) {\n\t var _this = this;\n\t\n\t this._world = world;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._onAdd(world).then(function () {\n\t _this.emit('added');\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Must return a promise\n\t }, {\n\t key: '_onAdd',\n\t value: function _onAdd(world) {}\n\t }, {\n\t key: 'getPickingId',\n\t value: function getPickingId() {\n\t if (this._world._engine._picking) {\n\t return this._world._engine._picking.getNextId();\n\t }\n\t\n\t return false;\n\t }\n\t\n\t // TODO: Tidy this up and don't access so many private properties to work\n\t }, {\n\t key: 'addToPicking',\n\t value: function addToPicking(object) {\n\t if (!this._world._engine._picking) {\n\t return;\n\t }\n\t\n\t this._world._engine._picking.add(object);\n\t }\n\t }, {\n\t key: 'removeFromPicking',\n\t value: function removeFromPicking(object) {\n\t if (!this._world._engine._picking) {\n\t return;\n\t }\n\t\n\t this._world._engine._picking.remove(object);\n\t }\n\t }, {\n\t key: 'isOutput',\n\t value: function isOutput() {\n\t return this._options.output;\n\t }\n\t }, {\n\t key: 'isOutputToScene',\n\t value: function isOutputToScene() {\n\t return this._options.outputToScene;\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._object3D && this._object3D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._object3D.children.length - 1; i >= 0; i--) {\n\t child = this._object3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.remove(child);\n\t\n\t if (child.geometry) {\n\t // Dispose of mesh and materials\n\t child.geometry.dispose();\n\t child.geometry = null;\n\t }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t }\n\t }\n\t\n\t if (this._domObject3D && this._domObject3D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._domObject3D.children.length - 1; i >= 0; i--) {\n\t child = this._domObject3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.removeDOM3D(child);\n\t }\n\t }\n\t\n\t if (this._domObject2D && this._domObject2D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._domObject2D.children.length - 1; i >= 0; i--) {\n\t child = this._domObject2D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.removeDOM2D(child);\n\t }\n\t }\n\t\n\t this._domObject3D = null;\n\t this._domObject2D = null;\n\t\n\t this._world = null;\n\t this._object3D = null;\n\t }\n\t }]);\n\t\n\t return Layer;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Layer;\n\t\n\tvar noNew = function noNew(options) {\n\t return new Layer(options);\n\t};\n\t\n\texports.layer = noNew;\n\n/***/ },\n/* 33 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Sky = __webpack_require__(34);\n\t\n\tvar _Sky2 = _interopRequireDefault(_Sky);\n\t\n\tvar _lodashThrottle = __webpack_require__(35);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\tvar cubemap = {\n\t vertexShader: ['varying vec3 vPosition;', 'void main() {', 'vPosition = position;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t fragmentShader: ['uniform samplerCube cubemap;', 'varying vec3 vPosition;', 'void main() {', 'gl_FragColor = textureCube(cubemap, normalize(vPosition));', '}'].join('\\n')\n\t};\n\t\n\tvar Skybox = (function () {\n\t function Skybox(world, light) {\n\t _classCallCheck(this, Skybox);\n\t\n\t this._world = world;\n\t this._light = light;\n\t\n\t this._settings = {\n\t distance: 38000,\n\t turbidity: 10,\n\t reileigh: 2,\n\t mieCoefficient: 0.005,\n\t mieDirectionalG: 0.8,\n\t luminance: 1,\n\t // 0.48 is a cracking dusk / sunset\n\t // 0.4 is a beautiful early-morning / late-afternoon\n\t // 0.2 is a nice day time\n\t inclination: 0.48, // Elevation / inclination\n\t azimuth: 0.25 };\n\t\n\t // Facing front\n\t this._initSkybox();\n\t this._updateUniforms();\n\t this._initEvents();\n\t }\n\t\n\t _createClass(Skybox, [{\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t // Throttled to 1 per 100ms\n\t this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._update, 100);\n\t this._world.on('preUpdate', this._throttledWorldUpdate, this);\n\t }\n\t }, {\n\t key: '_initSkybox',\n\t value: function _initSkybox() {\n\t // Cube camera for skybox\n\t this._cubeCamera = new _three2['default'].CubeCamera(1, 20000000, 128);\n\t\n\t // Cube material\n\t var cubeTarget = this._cubeCamera.renderTarget;\n\t\n\t // Add Sky Mesh\n\t this._sky = new _Sky2['default']();\n\t this._skyScene = new _three2['default'].Scene();\n\t this._skyScene.add(this._sky.mesh);\n\t\n\t // Add Sun Helper\n\t this._sunSphere = new _three2['default'].Mesh(new _three2['default'].SphereBufferGeometry(2000, 16, 8), new _three2['default'].MeshBasicMaterial({\n\t color: 0xffffff\n\t }));\n\t\n\t // TODO: This isn't actually visible because it's not added to the layer\n\t // this._sunSphere.visible = true;\n\t\n\t var skyboxUniforms = {\n\t cubemap: { type: 't', value: cubeTarget }\n\t };\n\t\n\t var skyboxMat = new _three2['default'].ShaderMaterial({\n\t uniforms: skyboxUniforms,\n\t vertexShader: cubemap.vertexShader,\n\t fragmentShader: cubemap.fragmentShader,\n\t side: _three2['default'].BackSide\n\t });\n\t\n\t this._mesh = new _three2['default'].Mesh(new _three2['default'].BoxGeometry(1900000, 1900000, 1900000), skyboxMat);\n\t\n\t this._updateSkybox = true;\n\t }\n\t }, {\n\t key: '_updateUniforms',\n\t value: function _updateUniforms() {\n\t var settings = this._settings;\n\t var uniforms = this._sky.uniforms;\n\t uniforms.turbidity.value = settings.turbidity;\n\t uniforms.reileigh.value = settings.reileigh;\n\t uniforms.luminance.value = settings.luminance;\n\t uniforms.mieCoefficient.value = settings.mieCoefficient;\n\t uniforms.mieDirectionalG.value = settings.mieDirectionalG;\n\t\n\t var theta = Math.PI * (settings.inclination - 0.5);\n\t var phi = 2 * Math.PI * (settings.azimuth - 0.5);\n\t\n\t this._sunSphere.position.x = settings.distance * Math.cos(phi);\n\t this._sunSphere.position.y = settings.distance * Math.sin(phi) * Math.sin(theta);\n\t this._sunSphere.position.z = settings.distance * Math.sin(phi) * Math.cos(theta);\n\t\n\t // Move directional light to sun position\n\t this._light.position.copy(this._sunSphere.position);\n\t\n\t this._sky.uniforms.sunPosition.value.copy(this._sunSphere.position);\n\t }\n\t }, {\n\t key: '_update',\n\t value: function _update(delta) {\n\t if (this._updateSkybox) {\n\t this._updateSkybox = false;\n\t } else {\n\t return;\n\t }\n\t\n\t // if (!this._angle) {\n\t // this._angle = 0;\n\t // }\n\t //\n\t // // Animate inclination\n\t // this._angle += Math.PI * delta;\n\t // this._settings.inclination = 0.5 * (Math.sin(this._angle) / 2 + 0.5);\n\t\n\t // Update light intensity depending on elevation of sun (day to night)\n\t this._light.intensity = 1 - 0.95 * (this._settings.inclination / 0.5);\n\t\n\t // // console.log(delta, this._angle, this._settings.inclination);\n\t //\n\t // TODO: Only do this when the uniforms have been changed\n\t this._updateUniforms();\n\t\n\t // TODO: Only do this when the cubemap has actually changed\n\t this._cubeCamera.updateCubeMap(this._world._engine._renderer, this._skyScene);\n\t }\n\t }, {\n\t key: 'getRenderTarget',\n\t value: function getRenderTarget() {\n\t return this._cubeCamera.renderTarget;\n\t }\n\t }, {\n\t key: 'setInclination',\n\t value: function setInclination(inclination) {\n\t this._settings.inclination = inclination;\n\t this._updateSkybox = true;\n\t }\n\t\n\t // Destroy the skybox and remove it from memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._world.off('preUpdate', this._throttledWorldUpdate);\n\t this._throttledWorldUpdate = null;\n\t\n\t this._world = null;\n\t this._light = null;\n\t\n\t this._cubeCamera = null;\n\t\n\t this._sky.mesh.geometry.dispose();\n\t this._sky.mesh.geometry = null;\n\t\n\t if (this._sky.mesh.material.map) {\n\t this._sky.mesh.material.map.dispose();\n\t this._sky.mesh.material.map = null;\n\t }\n\t\n\t this._sky.mesh.material.dispose();\n\t this._sky.mesh.material = null;\n\t\n\t this._sky.mesh = null;\n\t this._sky = null;\n\t\n\t this._skyScene = null;\n\t\n\t this._sunSphere.geometry.dispose();\n\t this._sunSphere.geometry = null;\n\t\n\t if (this._sunSphere.material.map) {\n\t this._sunSphere.material.map.dispose();\n\t this._sunSphere.material.map = null;\n\t }\n\t\n\t this._sunSphere.material.dispose();\n\t this._sunSphere.material = null;\n\t\n\t this._sunSphere = null;\n\t\n\t this._mesh.geometry.dispose();\n\t this._mesh.geometry = null;\n\t\n\t if (this._mesh.material.map) {\n\t this._mesh.material.map.dispose();\n\t this._mesh.material.map = null;\n\t }\n\t\n\t this._mesh.material.dispose();\n\t this._mesh.material = null;\n\t }\n\t }]);\n\t\n\t return Skybox;\n\t})();\n\t\n\texports['default'] = Skybox;\n\t\n\tvar noNew = function noNew(world, light) {\n\t return new Skybox(world, light);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.skybox = noNew;\n\n/***/ },\n/* 34 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/*eslint eqeqeq:0*/\n\t\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Based on 'A Practical Analytic Model for Daylight'\n\t * aka The Preetham Model, the de facto standard analytic skydome model\n\t * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf\n\t *\n\t * First implemented by Simon Wallner\n\t * http://www.simonwallner.at/projects/atmospheric-scattering\n\t *\n\t * Improved by Martin Upitis\n\t * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR\n\t *\n\t * Three.js integration by zz85 http://twitter.com/blurspline\n\t*/\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t_three2['default'].ShaderLib['sky'] = {\n\t\n\t\tuniforms: {\n\t\n\t\t\tluminance: { type: 'f', value: 1 },\n\t\t\tturbidity: { type: 'f', value: 2 },\n\t\t\treileigh: { type: 'f', value: 1 },\n\t\t\tmieCoefficient: { type: 'f', value: 0.005 },\n\t\t\tmieDirectionalG: { type: 'f', value: 0.8 },\n\t\t\tsunPosition: { type: 'v3', value: new _three2['default'].Vector3() }\n\t\n\t\t},\n\t\n\t\tvertexShader: ['varying vec3 vWorldPosition;', 'void main() {', 'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', 'vWorldPosition = worldPosition.xyz;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t\tfragmentShader: ['uniform sampler2D skySampler;', 'uniform vec3 sunPosition;', 'varying vec3 vWorldPosition;', 'vec3 cameraPos = vec3(0., 0., 0.);', '// uniform sampler2D sDiffuse;', '// const float turbidity = 10.0; //', '// const float reileigh = 2.; //', '// const float luminance = 1.0; //', '// const float mieCoefficient = 0.005;', '// const float mieDirectionalG = 0.8;', 'uniform float luminance;', 'uniform float turbidity;', 'uniform float reileigh;', 'uniform float mieCoefficient;', 'uniform float mieDirectionalG;', '// constants for atmospheric scattering', 'const float e = 2.71828182845904523536028747135266249775724709369995957;', 'const float pi = 3.141592653589793238462643383279502884197169;', 'const float n = 1.0003; // refractive index of air', 'const float N = 2.545E25; // number of molecules per unit volume for air at', '// 288.15K and 1013mb (sea level -45 celsius)', 'const float pn = 0.035;\t// depolatization factor for standard air', '// wavelength of used primaries, according to preetham', 'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);', '// mie stuff', '// K coefficient for the primaries', 'const vec3 K = vec3(0.686, 0.678, 0.666);', 'const float v = 4.0;', '// optical length at zenith for molecules', 'const float rayleighZenithLength = 8.4E3;', 'const float mieZenithLength = 1.25E3;', 'const vec3 up = vec3(0.0, 1.0, 0.0);', 'const float EE = 1000.0;', 'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;', '// 66 arc seconds -> degrees, and the cosine of that', '// earth shadow hack', 'const float cutoffAngle = pi/1.95;', 'const float steepness = 1.5;', 'vec3 totalRayleigh(vec3 lambda)', '{', 'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));', '}',\n\t\n\t\t// see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness\n\t\t'// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE', 'vec3 simplifiedRayleigh()', '{', 'return 0.0005 / vec3(94, 40, 18);',\n\t\t// return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245);\n\t\t'}', 'float rayleighPhase(float cosTheta)', '{\t ', 'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '//\treturn (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '//\treturn (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));', '}', 'vec3 totalMie(vec3 lambda, vec3 K, float T)', '{', 'float c = (0.2 * T ) * 10E-18;', 'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;', '}', 'float hgPhase(float cosTheta, float g)', '{', 'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));', '}', 'float sunIntensity(float zenithAngleCos)', '{', 'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));', '}', '// float logLuminance(vec3 c)', '// {', '// \treturn log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);', '// }', '// Filmic ToneMapping http://filmicgames.com/archives/75', 'float A = 0.15;', 'float B = 0.50;', 'float C = 0.10;', 'float D = 0.20;', 'float E = 0.02;', 'float F = 0.30;', 'float W = 1000.0;', 'vec3 Uncharted2Tonemap(vec3 x)', '{', 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;', '}', 'void main() ', '{', 'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);', '// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;', '// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);', 'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));', 'vec3 sunDirection = normalize(sunPosition);', 'float sunE = sunIntensity(dot(sunDirection, up));', '// extinction (absorbtion + out scattering) ', '// rayleigh coefficients',\n\t\n\t\t// 'vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;',\n\t\t'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;', '// mie coefficients', 'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;', '// optical length', '// cutoff angle at 90 to avoid singularity in next formula.', 'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));', 'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', 'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', '// combined extinction factor\t', 'vec3 Fex = exp(-(betaR * sR + betaM * sM));', '// in scattering', 'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);', 'float rPhase = rayleighPhase(cosTheta*0.5+0.5);', 'vec3 betaRTheta = betaR * rPhase;', 'float mPhase = hgPhase(cosTheta, mieDirectionalG);', 'vec3 betaMTheta = betaM * mPhase;', 'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));', 'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));', '//nightsky', 'vec3 direction = normalize(vWorldPosition - cameraPos);', 'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]', 'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]', 'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);', '// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;', 'vec3 L0 = vec3(0.1) * Fex;', '// composition + solar disc', '//if (cosTheta > sunAngularDiameterCos)', 'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);', '// if (normalize(vWorldPosition - cameraPos).y>0.0)', 'L0 += (sunE * 19000.0 * Fex)*sundisk;', 'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));', 'vec3 texColor = (Lin+L0); ', 'texColor *= 0.04 ;', 'texColor += vec3(0.0,0.001,0.0025)*0.3;', 'float g_fMaxLuminance = 1.0;', 'float fLumScaled = 0.1 / luminance; ', 'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ', 'float ExposureBias = fLumCompressed;', 'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);', 'vec3 color = curr*whiteScale;', 'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));', 'gl_FragColor.rgb = retColor;', 'gl_FragColor.a = 1.0;', '}'].join('\\n')\n\t\n\t};\n\t\n\tvar Sky = function Sky() {\n\t\n\t\tvar skyShader = _three2['default'].ShaderLib['sky'];\n\t\tvar skyUniforms = _three2['default'].UniformsUtils.clone(skyShader.uniforms);\n\t\n\t\tvar skyMat = new _three2['default'].ShaderMaterial({\n\t\t\tfragmentShader: skyShader.fragmentShader,\n\t\t\tvertexShader: skyShader.vertexShader,\n\t\t\tuniforms: skyUniforms,\n\t\t\tside: _three2['default'].BackSide\n\t\t});\n\t\n\t\tvar skyGeo = new _three2['default'].SphereBufferGeometry(450000, 32, 15);\n\t\tvar skyMesh = new _three2['default'].Mesh(skyGeo, skyMat);\n\t\n\t\t// Expose variables\n\t\tthis.mesh = skyMesh;\n\t\tthis.uniforms = skyUniforms;\n\t};\n\t\n\texports['default'] = Sky;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 35 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * lodash 4.0.1 (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright 2012-2016 The Dojo Foundation \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t * Available under MIT license \n\t */\n\tvar debounce = __webpack_require__(36);\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/**\n\t * Creates a throttled function that only invokes `func` at most once per\n\t * every `wait` milliseconds. The throttled function comes with a `cancel`\n\t * method to cancel delayed `func` invocations and a `flush` method to\n\t * immediately invoke them. Provide an options object to indicate whether\n\t * `func` should be invoked on the leading and/or trailing edge of the `wait`\n\t * timeout. The `func` is invoked with the last arguments provided to the\n\t * throttled function. Subsequent calls to the throttled function return the\n\t * result of the last `func` invocation.\n\t *\n\t * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n\t * on the trailing edge of the timeout only if the throttled function is\n\t * invoked more than once during the `wait` timeout.\n\t *\n\t * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)\n\t * for details over the differences between `_.throttle` and `_.debounce`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @category Function\n\t * @param {Function} func The function to throttle.\n\t * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n\t * @param {Object} [options] The options object.\n\t * @param {boolean} [options.leading=true] Specify invoking on the leading\n\t * edge of the timeout.\n\t * @param {boolean} [options.trailing=true] Specify invoking on the trailing\n\t * edge of the timeout.\n\t * @returns {Function} Returns the new throttled function.\n\t * @example\n\t *\n\t * // Avoid excessively updating the position while scrolling.\n\t * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n\t *\n\t * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n\t * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n\t * jQuery(element).on('click', throttled);\n\t *\n\t * // Cancel the trailing throttled invocation.\n\t * jQuery(window).on('popstate', throttled.cancel);\n\t */\n\tfunction throttle(func, wait, options) {\n\t var leading = true,\n\t trailing = true;\n\t\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t if (isObject(options)) {\n\t leading = 'leading' in options ? !!options.leading : leading;\n\t trailing = 'trailing' in options ? !!options.trailing : trailing;\n\t }\n\t return debounce(func, wait, {\n\t 'leading': leading,\n\t 'maxWait': wait,\n\t 'trailing': trailing\n\t });\n\t}\n\t\n\t/**\n\t * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n\t * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\tmodule.exports = throttle;\n\n\n/***/ },\n/* 36 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash 4.0.6 (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar NAN = 0 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t symbolTag = '[object Symbol]';\n\t\n\t/** Used to match leading and trailing whitespace. */\n\tvar reTrim = /^\\s+|\\s+$/g;\n\t\n\t/** Used to detect bad signed hexadecimal string values. */\n\tvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\t\n\t/** Used to detect binary string values. */\n\tvar reIsBinary = /^0b[01]+$/i;\n\t\n\t/** Used to detect octal string values. */\n\tvar reIsOctal = /^0o[0-7]+$/i;\n\t\n\t/** Built-in method references without a dependency on `root`. */\n\tvar freeParseInt = parseInt;\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeMax = Math.max,\n\t nativeMin = Math.min;\n\t\n\t/**\n\t * Gets the timestamp of the number of milliseconds that have elapsed since\n\t * the Unix epoch (1 January 1970 00:00:00 UTC).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 2.4.0\n\t * @type {Function}\n\t * @category Date\n\t * @returns {number} Returns the timestamp.\n\t * @example\n\t *\n\t * _.defer(function(stamp) {\n\t * console.log(_.now() - stamp);\n\t * }, _.now());\n\t * // => Logs the number of milliseconds it took for the deferred function to be invoked.\n\t */\n\tvar now = Date.now;\n\t\n\t/**\n\t * Creates a debounced function that delays invoking `func` until after `wait`\n\t * milliseconds have elapsed since the last time the debounced function was\n\t * invoked. The debounced function comes with a `cancel` method to cancel\n\t * delayed `func` invocations and a `flush` method to immediately invoke them.\n\t * Provide an options object to indicate whether `func` should be invoked on\n\t * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n\t * with the last arguments provided to the debounced function. Subsequent calls\n\t * to the debounced function return the result of the last `func` invocation.\n\t *\n\t * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n\t * on the trailing edge of the timeout only if the debounced function is\n\t * invoked more than once during the `wait` timeout.\n\t *\n\t * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n\t * for details over the differences between `_.debounce` and `_.throttle`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Function\n\t * @param {Function} func The function to debounce.\n\t * @param {number} [wait=0] The number of milliseconds to delay.\n\t * @param {Object} [options={}] The options object.\n\t * @param {boolean} [options.leading=false]\n\t * Specify invoking on the leading edge of the timeout.\n\t * @param {number} [options.maxWait]\n\t * The maximum time `func` is allowed to be delayed before it's invoked.\n\t * @param {boolean} [options.trailing=true]\n\t * Specify invoking on the trailing edge of the timeout.\n\t * @returns {Function} Returns the new debounced function.\n\t * @example\n\t *\n\t * // Avoid costly calculations while the window size is in flux.\n\t * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n\t *\n\t * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n\t * jQuery(element).on('click', _.debounce(sendMail, 300, {\n\t * 'leading': true,\n\t * 'trailing': false\n\t * }));\n\t *\n\t * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n\t * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n\t * var source = new EventSource('/stream');\n\t * jQuery(source).on('message', debounced);\n\t *\n\t * // Cancel the trailing debounced invocation.\n\t * jQuery(window).on('popstate', debounced.cancel);\n\t */\n\tfunction debounce(func, wait, options) {\n\t var lastArgs,\n\t lastThis,\n\t maxWait,\n\t result,\n\t timerId,\n\t lastCallTime = 0,\n\t lastInvokeTime = 0,\n\t leading = false,\n\t maxing = false,\n\t trailing = true;\n\t\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t wait = toNumber(wait) || 0;\n\t if (isObject(options)) {\n\t leading = !!options.leading;\n\t maxing = 'maxWait' in options;\n\t maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n\t trailing = 'trailing' in options ? !!options.trailing : trailing;\n\t }\n\t\n\t function invokeFunc(time) {\n\t var args = lastArgs,\n\t thisArg = lastThis;\n\t\n\t lastArgs = lastThis = undefined;\n\t lastInvokeTime = time;\n\t result = func.apply(thisArg, args);\n\t return result;\n\t }\n\t\n\t function leadingEdge(time) {\n\t // Reset any `maxWait` timer.\n\t lastInvokeTime = time;\n\t // Start the timer for the trailing edge.\n\t timerId = setTimeout(timerExpired, wait);\n\t // Invoke the leading edge.\n\t return leading ? invokeFunc(time) : result;\n\t }\n\t\n\t function remainingWait(time) {\n\t var timeSinceLastCall = time - lastCallTime,\n\t timeSinceLastInvoke = time - lastInvokeTime,\n\t result = wait - timeSinceLastCall;\n\t\n\t return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n\t }\n\t\n\t function shouldInvoke(time) {\n\t var timeSinceLastCall = time - lastCallTime,\n\t timeSinceLastInvoke = time - lastInvokeTime;\n\t\n\t // Either this is the first call, activity has stopped and we're at the\n\t // trailing edge, the system time has gone backwards and we're treating\n\t // it as the trailing edge, or we've hit the `maxWait` limit.\n\t return (!lastCallTime || (timeSinceLastCall >= wait) ||\n\t (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n\t }\n\t\n\t function timerExpired() {\n\t var time = now();\n\t if (shouldInvoke(time)) {\n\t return trailingEdge(time);\n\t }\n\t // Restart the timer.\n\t timerId = setTimeout(timerExpired, remainingWait(time));\n\t }\n\t\n\t function trailingEdge(time) {\n\t clearTimeout(timerId);\n\t timerId = undefined;\n\t\n\t // Only invoke if we have `lastArgs` which means `func` has been\n\t // debounced at least once.\n\t if (trailing && lastArgs) {\n\t return invokeFunc(time);\n\t }\n\t lastArgs = lastThis = undefined;\n\t return result;\n\t }\n\t\n\t function cancel() {\n\t if (timerId !== undefined) {\n\t clearTimeout(timerId);\n\t }\n\t lastCallTime = lastInvokeTime = 0;\n\t lastArgs = lastThis = timerId = undefined;\n\t }\n\t\n\t function flush() {\n\t return timerId === undefined ? result : trailingEdge(now());\n\t }\n\t\n\t function debounced() {\n\t var time = now(),\n\t isInvoking = shouldInvoke(time);\n\t\n\t lastArgs = arguments;\n\t lastThis = this;\n\t lastCallTime = time;\n\t\n\t if (isInvoking) {\n\t if (timerId === undefined) {\n\t return leadingEdge(lastCallTime);\n\t }\n\t if (maxing) {\n\t // Handle invocations in a tight loop.\n\t clearTimeout(timerId);\n\t timerId = setTimeout(timerExpired, wait);\n\t return invokeFunc(lastCallTime);\n\t }\n\t }\n\t if (timerId === undefined) {\n\t timerId = setTimeout(timerExpired, wait);\n\t }\n\t return result;\n\t }\n\t debounced.cancel = cancel;\n\t debounced.flush = flush;\n\t return debounced;\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {number} Returns the number.\n\t * @example\n\t *\n\t * _.toNumber(3);\n\t * // => 3\n\t *\n\t * _.toNumber(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toNumber(Infinity);\n\t * // => Infinity\n\t *\n\t * _.toNumber('3');\n\t * // => 3\n\t */\n\tfunction toNumber(value) {\n\t if (typeof value == 'number') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return NAN;\n\t }\n\t if (isObject(value)) {\n\t var other = isFunction(value.valueOf) ? value.valueOf() : value;\n\t value = isObject(other) ? (other + '') : other;\n\t }\n\t if (typeof value != 'string') {\n\t return value === 0 ? value : +value;\n\t }\n\t value = value.replace(reTrim, '');\n\t var isBinary = reIsBinary.test(value);\n\t return (isBinary || reIsOctal.test(value))\n\t ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n\t : (reIsBadHex.test(value) ? NAN : +value);\n\t}\n\t\n\tmodule.exports = debounce;\n\n\n/***/ },\n/* 37 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _ControlsOrbit = __webpack_require__(38);\n\t\n\tvar _ControlsOrbit2 = _interopRequireDefault(_ControlsOrbit);\n\t\n\tvar Controls = {\n\t Orbit: _ControlsOrbit2['default'],\n\t orbit: _ControlsOrbit.orbit, orbit: _ControlsOrbit.orbit\n\t};\n\t\n\texports['default'] = Controls;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 38 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorOrbitControls = __webpack_require__(39);\n\t\n\tvar _vendorOrbitControls2 = _interopRequireDefault(_vendorOrbitControls);\n\t\n\tvar _TweenLite = __webpack_require__(41);\n\t\n\tvar _TweenLite2 = _interopRequireDefault(_TweenLite);\n\t\n\tvar Orbit = (function (_EventEmitter) {\n\t _inherits(Orbit, _EventEmitter);\n\t\n\t function Orbit() {\n\t _classCallCheck(this, Orbit);\n\t\n\t _get(Object.getPrototypeOf(Orbit.prototype), 'constructor', this).call(this);\n\t\n\t // Prevent animation from pausing when tab is inactive\n\t _TweenLite2['default'].lagSmoothing(0);\n\t }\n\t\n\t // Proxy control events\n\t //\n\t // There's currently no distinction between pan, orbit and zoom events\n\t\n\t _createClass(Orbit, [{\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t var _this = this;\n\t\n\t this._controls.addEventListener('start', function (event) {\n\t _this._world.emit('controlsMoveStart', event.target.target);\n\t });\n\t\n\t this._controls.addEventListener('change', function (event) {\n\t _this._world.emit('controlsMove', event.target.target);\n\t });\n\t\n\t this._controls.addEventListener('end', function (event) {\n\t _this._world.emit('controlsMoveEnd', event.target.target);\n\t });\n\t }\n\t\n\t // Moving the camera along the [x,y,z] axis based on a target position\n\t }, {\n\t key: 'panTo',\n\t value: function panTo(point, animate) {}\n\t }, {\n\t key: 'panBy',\n\t value: function panBy(pointDelta, animate) {}\n\t\n\t // Zooming the camera in and out\n\t }, {\n\t key: 'zoomTo',\n\t value: function zoomTo(metres, animate) {}\n\t }, {\n\t key: 'zoomBy',\n\t value: function zoomBy(metresDelta, animate) {}\n\t\n\t // Force camera to look at something other than the target\n\t }, {\n\t key: 'lookAt',\n\t value: function lookAt(point, animate) {}\n\t\n\t // Make camera look at the target\n\t }, {\n\t key: 'lookAtTarget',\n\t value: function lookAtTarget() {}\n\t\n\t // Tilt (up and down)\n\t }, {\n\t key: 'tiltTo',\n\t value: function tiltTo(angle, animate) {}\n\t }, {\n\t key: 'tiltBy',\n\t value: function tiltBy(angleDelta, animate) {}\n\t\n\t // Rotate (left and right)\n\t }, {\n\t key: 'rotateTo',\n\t value: function rotateTo(angle, animate) {}\n\t }, {\n\t key: 'rotateBy',\n\t value: function rotateBy(angleDelta, animate) {}\n\t\n\t // Fly to the given point, animating pan and tilt/rotation to final position\n\t // with nice zoom out and in\n\t //\n\t // TODO: Calling flyTo a second time before the previous animation has\n\t // completed should immediately start the new animation from wherever the\n\t // previous one has got to\n\t //\n\t // TODO: Long-distance pans should prevent the quadtree grid from trying to\n\t // update by not firing the control update events every frame until the\n\t // pan velocity calms down a bit\n\t //\n\t // TODO: Long-distance plans should zoom out further\n\t //\n\t // TODO: Return a promise?\n\t }, {\n\t key: 'flyToPoint',\n\t value: function flyToPoint(point, duration, zoom) {\n\t // Animation time in seconds\n\t var animationTime = duration || 2;\n\t\n\t this._flyTarget = new _three2['default'].Vector3(point.x, 0, point.y);\n\t\n\t // Calculate delta from current position to fly target\n\t var diff = new _three2['default'].Vector3().subVectors(this._controls.target, this._flyTarget);\n\t\n\t this._flyTween = new _TweenLite2['default']({\n\t x: 0,\n\t z: 0,\n\t // zoom: 0,\n\t prev: {\n\t x: 0,\n\t z: 0\n\t }\n\t }, animationTime, {\n\t x: diff.x,\n\t z: diff.z,\n\t // zoom: 1,\n\t onUpdate: function onUpdate(tween) {\n\t var controls = this._controls;\n\t\n\t // Work out difference since last frame\n\t var deltaX = tween.target.x - tween.target.prev.x;\n\t var deltaZ = tween.target.z - tween.target.prev.z;\n\t\n\t // Move some fraction toward the target point\n\t controls.panLeft(deltaX, controls.object.matrix);\n\t controls.panUp(deltaZ, controls.object.matrix);\n\t\n\t tween.target.prev.x = tween.target.x;\n\t tween.target.prev.z = tween.target.z;\n\t\n\t // console.log(Math.sin((tween.target.zoom - 0.5) * Math.PI));\n\t\n\t // TODO: Get zoom to dolly in and out on pan\n\t // controls.object.zoom -= Math.sin((tween.target.zoom - 0.5) * Math.PI);\n\t // controls.object.updateProjectionMatrix();\n\t },\n\t onComplete: function onComplete(tween) {\n\t // console.log(`Arrived at flyTarget`);\n\t this._flyTarget = null;\n\t },\n\t onUpdateParams: ['{self}'],\n\t onCompleteParams: ['{self}'],\n\t callbackScope: this,\n\t ease: Power1.easeInOut\n\t });\n\t\n\t if (!zoom) {\n\t return;\n\t }\n\t\n\t var zoomTime = animationTime / 2;\n\t\n\t this._zoomTweenIn = new _TweenLite2['default']({\n\t zoom: 0\n\t }, zoomTime, {\n\t zoom: 1,\n\t onUpdate: function onUpdate(tween) {\n\t var controls = this._controls;\n\t controls.dollyIn(1 - 0.01 * tween.target.zoom);\n\t },\n\t onComplete: function onComplete(tween) {},\n\t onUpdateParams: ['{self}'],\n\t onCompleteParams: ['{self}'],\n\t callbackScope: this,\n\t ease: Power1.easeInOut\n\t });\n\t\n\t this._zoomTweenOut = new _TweenLite2['default']({\n\t zoom: 0\n\t }, zoomTime, {\n\t zoom: 1,\n\t delay: zoomTime,\n\t onUpdate: function onUpdate(tween) {\n\t var controls = this._controls;\n\t controls.dollyOut(0.99 + 0.01 * tween.target.zoom);\n\t },\n\t onComplete: function onComplete(tween) {},\n\t onUpdateParams: ['{self}'],\n\t onCompleteParams: ['{self}'],\n\t callbackScope: this,\n\t ease: Power1.easeInOut\n\t });\n\t }\n\t\n\t // TODO: Return a promise?\n\t }, {\n\t key: 'flyToLatLon',\n\t value: function flyToLatLon(latlon, duration, noZoom) {\n\t var point = this._world.latLonToPoint(latlon);\n\t this.flyToPoint(point, duration, noZoom);\n\t }\n\t\n\t // TODO: Make this animate over a user-defined period of time\n\t //\n\t // Perhaps use TweenMax for now and implement as a more lightweight solution\n\t // later on once it all works\n\t // _animateFlyTo(delta) {\n\t // var controls = this._controls;\n\t //\n\t // // this._controls.panLeft(50, controls._controls.object.matrix);\n\t // // this._controls.panUp(50, controls._controls.object.matrix);\n\t // // this._controls.dollyIn(this._controls.getZoomScale());\n\t // // this._controls.dollyOut(this._controls.getZoomScale());\n\t //\n\t // // Calculate delta from current position to fly target\n\t // var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);\n\t //\n\t // // 1000 units per second\n\t // var speed = 1000 * (delta / 1000);\n\t //\n\t // // Remove fly target after arrival and snap to target\n\t // if (diff.length() < 0.01) {\n\t // console.log(`Arrived at flyTarget`);\n\t // this._flyTarget = null;\n\t // speed = 1;\n\t // }\n\t //\n\t // // Move some fraction toward the target point\n\t // controls.panLeft(diff.x * speed, controls.object.matrix);\n\t // controls.panUp(diff.z * speed, controls.object.matrix);\n\t // }\n\t\n\t // Proxy to OrbitControls.update()\n\t }, {\n\t key: 'update',\n\t value: function update(delta) {\n\t this._controls.update(delta);\n\t }\n\t\n\t // Add controls to world instance and store world reference\n\t }, {\n\t key: 'addTo',\n\t value: function addTo(world) {\n\t world.addControls(this);\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Internal method called by World.addControls to actually add the controls\n\t }, {\n\t key: '_addToWorld',\n\t value: function _addToWorld(world) {\n\t this._world = world;\n\t\n\t // TODO: Override panLeft and panUp methods to prevent panning on Y axis\n\t // See: http://stackoverflow.com/a/26188674/997339\n\t this._controls = new _vendorOrbitControls2['default'](world._engine._camera, world._container);\n\t\n\t // Disable keys for now as no events are fired for them anyway\n\t this._controls.keys = false;\n\t\n\t // 89 degrees\n\t this._controls.maxPolarAngle = 1.5533;\n\t\n\t // this._controls.enableDamping = true;\n\t // this._controls.dampingFactor = 0.25;\n\t\n\t this._initEvents();\n\t\n\t // TODO: Remove now that this is a promise?\n\t this.emit('added');\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Destroys the controls and removes them from memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // TODO: Remove event listeners\n\t\n\t this._controls.dispose();\n\t\n\t this._world = null;\n\t this._controls = null;\n\t }\n\t }]);\n\t\n\t return Orbit;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Orbit;\n\t\n\tvar noNew = function noNew() {\n\t return new Orbit();\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.orbit = noNew;\n\n/***/ },\n/* 39 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _hammerjs = __webpack_require__(40);\n\t\n\tvar _hammerjs2 = _interopRequireDefault(_hammerjs);\n\t\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\t\n\t// This set of controls performs orbiting, dollying (zooming), and panning.\n\t// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n\t//\n\t// Orbit - left mouse / touch: one finger move\n\t// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n\t// Pan - right mouse, or arrow keys / touch: three finter swipe\n\t\n\tvar OrbitControls = function OrbitControls(object, domElement) {\n\t\n\t\tthis.object = object;\n\t\n\t\tthis.domElement = domElement !== undefined ? domElement : document;\n\t\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\t\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new _three2['default'].Vector3();\n\t\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\t\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\t\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\t\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = -Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\t\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\t\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\t\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\t\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0; // pixels moved per arrow key push\n\t\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\t\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\t\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\t\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: _three2['default'].MOUSE.LEFT, ZOOM: _three2['default'].MOUSE.MIDDLE, PAN: _three2['default'].MOUSE.RIGHT };\n\t\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\t\n\t\t//\n\t\t// public methods\n\t\t//\n\t\n\t\tthis.getPolarAngle = function () {\n\t\n\t\t\treturn phi;\n\t\t};\n\t\n\t\tthis.getAzimuthalAngle = function () {\n\t\n\t\t\treturn theta;\n\t\t};\n\t\n\t\tthis.reset = function () {\n\t\n\t\t\tscope.target.copy(scope.target0);\n\t\t\tscope.object.position.copy(scope.position0);\n\t\t\tscope.object.zoom = scope.zoom0;\n\t\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent(changeEvent);\n\t\n\t\t\tscope.update();\n\t\n\t\t\tstate = STATE.NONE;\n\t\t};\n\t\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = (function () {\n\t\n\t\t\tvar offset = new _three2['default'].Vector3();\n\t\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new _three2['default'].Quaternion().setFromUnitVectors(object.up, new _three2['default'].Vector3(0, 1, 0));\n\t\t\tvar quatInverse = quat.clone().inverse();\n\t\n\t\t\tvar lastPosition = new _three2['default'].Vector3();\n\t\t\tvar lastQuaternion = new _three2['default'].Quaternion();\n\t\n\t\t\treturn function () {\n\t\n\t\t\t\tvar position = scope.object.position;\n\t\n\t\t\t\toffset.copy(position).sub(scope.target);\n\t\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion(quat);\n\t\n\t\t\t\t// angle from z-axis around y-axis\n\t\n\t\t\t\ttheta = Math.atan2(offset.x, offset.z);\n\t\n\t\t\t\t// angle from y-axis\n\t\n\t\t\t\tphi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y);\n\t\n\t\t\t\tif (scope.autoRotate && state === STATE.NONE) {\n\t\n\t\t\t\t\trotateLeft(getAutoRotationAngle());\n\t\t\t\t}\n\t\n\t\t\t\ttheta += thetaDelta;\n\t\t\t\tphi += phiDelta;\n\t\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\ttheta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, theta));\n\t\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tphi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, phi));\n\t\n\t\t\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\t\t\tphi = Math.max(EPS, Math.min(Math.PI - EPS, phi));\n\t\n\t\t\t\tvar radius = offset.length() * scale;\n\t\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tradius = Math.max(scope.minDistance, Math.min(scope.maxDistance, radius));\n\t\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add(panOffset);\n\t\n\t\t\t\toffset.x = radius * Math.sin(phi) * Math.sin(theta);\n\t\t\t\toffset.y = radius * Math.cos(phi);\n\t\t\t\toffset.z = radius * Math.sin(phi) * Math.cos(theta);\n\t\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion(quatInverse);\n\t\n\t\t\t\tposition.copy(scope.target).add(offset);\n\t\n\t\t\t\tscope.object.lookAt(scope.target);\n\t\n\t\t\t\tif (scope.enableDamping === true) {\n\t\n\t\t\t\t\tthetaDelta *= 1 - scope.dampingFactor;\n\t\t\t\t\tphiDelta *= 1 - scope.dampingFactor;\n\t\t\t\t} else {\n\t\n\t\t\t\t\tthetaDelta = 0;\n\t\t\t\t\tphiDelta = 0;\n\t\t\t\t}\n\t\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set(0, 0, 0);\n\t\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\t\n\t\t\t\tif (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {\n\t\n\t\t\t\t\tscope.dispatchEvent(changeEvent);\n\t\n\t\t\t\t\tlastPosition.copy(scope.object.position);\n\t\t\t\t\tlastQuaternion.copy(scope.object.quaternion);\n\t\t\t\t\tzoomChanged = false;\n\t\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})();\n\t\n\t\tthis.dispose = function () {\n\t\n\t\t\tscope.domElement.removeEventListener('contextmenu', onContextMenu, false);\n\t\t\tscope.domElement.removeEventListener('mousedown', onMouseDown, false);\n\t\t\tscope.domElement.removeEventListener('mousewheel', onMouseWheel, false);\n\t\t\tscope.domElement.removeEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox\n\t\n\t\t\tscope.domElement.removeEventListener('touchstart', onTouchStart, false);\n\t\t\tscope.domElement.removeEventListener('touchend', onTouchEnd, false);\n\t\t\tscope.domElement.removeEventListener('touchmove', onTouchMove, false);\n\t\n\t\t\tdocument.removeEventListener('mousemove', onMouseMove, false);\n\t\t\tdocument.removeEventListener('mouseup', onMouseUp, false);\n\t\t\tdocument.removeEventListener('mouseout', onMouseUp, false);\n\t\n\t\t\twindow.removeEventListener('keydown', onKeyDown, false);\n\t\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\t\t};\n\t\n\t\t//\n\t\t// internals\n\t\t//\n\t\n\t\tvar scope = this;\n\t\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\t\n\t\tvar STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };\n\t\n\t\tvar state = STATE.NONE;\n\t\n\t\tvar EPS = 0.000001;\n\t\n\t\t// current position in spherical coordinates\n\t\tvar theta;\n\t\tvar phi;\n\t\n\t\tvar phiDelta = 0;\n\t\tvar thetaDelta = 0;\n\t\tvar scale = 1;\n\t\tvar panOffset = new _three2['default'].Vector3();\n\t\tvar zoomChanged = false;\n\t\n\t\tvar rotateStart = new _three2['default'].Vector2();\n\t\tvar rotateEnd = new _three2['default'].Vector2();\n\t\tvar rotateDelta = new _three2['default'].Vector2();\n\t\n\t\tvar panStart = new _three2['default'].Vector2();\n\t\tvar panEnd = new _three2['default'].Vector2();\n\t\tvar panDelta = new _three2['default'].Vector2();\n\t\n\t\tvar dollyStart = new _three2['default'].Vector2();\n\t\tvar dollyEnd = new _three2['default'].Vector2();\n\t\tvar dollyDelta = new _three2['default'].Vector2();\n\t\n\t\tfunction getAutoRotationAngle() {\n\t\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\t\t}\n\t\n\t\tfunction getZoomScale() {\n\t\n\t\t\treturn Math.pow(0.95, scope.zoomSpeed);\n\t\t}\n\t\n\t\tfunction rotateLeft(angle) {\n\t\n\t\t\tthetaDelta -= angle;\n\t\t}\n\t\n\t\tfunction rotateUp(angle) {\n\t\n\t\t\tphiDelta -= angle;\n\t\t}\n\t\n\t\tvar panLeft = (function () {\n\t\n\t\t\tvar v = new _three2['default'].Vector3();\n\t\n\t\t\t// return function panLeft( distance, objectMatrix ) {\n\t\t\t//\n\t\t\t// \tvar te = objectMatrix.elements;\n\t\t\t//\n\t\t\t// \t// get X column of objectMatrix\n\t\t\t// \tv.set( te[ 0 ], te[ 1 ], te[ 2 ] );\n\t\t\t//\n\t\t\t// \tv.multiplyScalar( - distance );\n\t\t\t//\n\t\t\t// \tpanOffset.add( v );\n\t\t\t//\n\t\t\t// };\n\t\n\t\t\t// Fixed panning to x/y plane\n\t\t\treturn function panLeft(distance, objectMatrix) {\n\t\t\t\tvar te = objectMatrix.elements;\n\t\t\t\t// var adjDist = distance / Math.cos(phi);\n\t\n\t\t\t\tv.set(te[0], 0, te[2]);\n\t\t\t\tv.multiplyScalar(-distance);\n\t\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t})();\n\t\n\t\t// Fixed panning to x/y plane\n\t\tvar panUp = (function () {\n\t\n\t\t\tvar v = new _three2['default'].Vector3();\n\t\n\t\t\t// return function panUp( distance, objectMatrix ) {\n\t\t\t//\n\t\t\t// \tvar te = objectMatrix.elements;\n\t\t\t//\n\t\t\t// \t// get Y column of objectMatrix\n\t\t\t// \tv.set( te[ 4 ], te[ 5 ], te[ 6 ] );\n\t\t\t//\n\t\t\t// \tv.multiplyScalar( distance );\n\t\t\t//\n\t\t\t// \tpanOffset.add( v );\n\t\t\t//\n\t\t\t// };\n\t\n\t\t\treturn function panUp(distance, objectMatrix) {\n\t\t\t\tvar te = objectMatrix.elements;\n\t\t\t\tvar adjDist = distance / Math.cos(phi);\n\t\n\t\t\t\tv.set(te[4], 0, te[6]);\n\t\t\t\tv.multiplyScalar(adjDist);\n\t\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t})();\n\t\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = (function () {\n\t\n\t\t\tvar offset = new _three2['default'].Vector3();\n\t\n\t\t\treturn function (deltaX, deltaY) {\n\t\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\n\t\t\t\tif (scope.object instanceof _three2['default'].PerspectiveCamera) {\n\t\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy(position).sub(scope.target);\n\t\t\t\t\tvar targetDistance = offset.length();\n\t\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180.0);\n\t\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t\tpanUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t} else if (scope.object instanceof _three2['default'].OrthographicCamera) {\n\t\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft(deltaX * (scope.object.right - scope.object.left) / element.clientWidth, scope.object.matrix);\n\t\t\t\t\tpanUp(deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight, scope.object.matrix);\n\t\t\t\t} else {\n\t\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.');\n\t\t\t\t\tscope.enablePan = false;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\t\n\t\tfunction dollyIn(dollyScale) {\n\t\n\t\t\tif (scope.object instanceof _three2['default'].PerspectiveCamera) {\n\t\n\t\t\t\tscale /= dollyScale;\n\t\t\t} else if (scope.object instanceof _three2['default'].OrthographicCamera) {\n\t\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t} else {\n\t\n\t\t\t\tconsole.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\n\t\tfunction dollyOut(dollyScale) {\n\t\n\t\t\tif (scope.object instanceof _three2['default'].PerspectiveCamera) {\n\t\n\t\t\t\tscale *= dollyScale;\n\t\t\t} else if (scope.object instanceof _three2['default'].OrthographicCamera) {\n\t\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t} else {\n\t\n\t\t\t\tconsole.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\t\n\t\tfunction handleMouseDownRotate(event) {\n\t\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\t\n\t\t\trotateStart.set(event.clientX, event.clientY);\n\t\t}\n\t\n\t\tfunction handleMouseDownDolly(event) {\n\t\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\t\n\t\t\tdollyStart.set(event.clientX, event.clientY);\n\t\t}\n\t\n\t\tfunction handleMouseDownPan(event) {\n\t\n\t\t\t//console.log( 'handleMouseDownPan' );\n\t\n\t\t\tpanStart.set(event.clientX, event.clientY);\n\t\t}\n\t\n\t\tfunction handleMouseMoveRotate(event) {\n\t\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\t\n\t\t\trotateEnd.set(event.clientX, event.clientY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\n\t\t\trotateStart.copy(rotateEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleMouseMoveDolly(event) {\n\t\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\t\n\t\t\tdollyEnd.set(event.clientX, event.clientY);\n\t\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\n\t\t\tif (dollyDelta.y > 0) {\n\t\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t} else if (dollyDelta.y < 0) {\n\t\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\n\t\t\tdollyStart.copy(dollyEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleMouseMovePan(event) {\n\t\n\t\t\t//console.log( 'handleMouseMovePan' );\n\t\n\t\t\tpanEnd.set(event.clientX, event.clientY);\n\t\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\n\t\t\tpanStart.copy(panEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleMouseUp(event) {\n\t\n\t\t\t//console.log( 'handleMouseUp' );\n\t\n\t\t}\n\t\n\t\tfunction handleMouseWheel(event) {\n\t\n\t\t\t//console.log( 'handleMouseWheel' );\n\t\n\t\t\tvar delta = 0;\n\t\n\t\t\tif (event.wheelDelta !== undefined) {\n\t\n\t\t\t\t// WebKit / Opera / Explorer 9\n\t\n\t\t\t\tdelta = event.wheelDelta;\n\t\t\t} else if (event.detail !== undefined) {\n\t\n\t\t\t\t// Firefox\n\t\n\t\t\t\tdelta = -event.detail;\n\t\t\t}\n\t\n\t\t\tif (delta > 0) {\n\t\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t} else if (delta < 0) {\n\t\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleKeyDown(event) {\n\t\n\t\t\t//console.log( 'handleKeyDown' );\n\t\n\t\t\tswitch (event.keyCode) {\n\t\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan(0, scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan(0, -scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan(scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan(-scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t}\n\t\t}\n\t\n\t\tfunction handleTouchStartRotate(event) {\n\t\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\t\n\t\t\trotateStart.set(event.pointers[0].pageX, event.pointers[0].pageY);\n\t\t}\n\t\n\t\tfunction handleTouchStartDolly(event) {\n\t\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\t\n\t\t\tvar dx = event.pointers[0].pageX - event.pointers[1].pageX;\n\t\t\tvar dy = event.pointers[0].pageY - event.pointers[1].pageY;\n\t\n\t\t\tvar distance = Math.sqrt(dx * dx + dy * dy);\n\t\n\t\t\tdollyStart.set(0, distance);\n\t\t}\n\t\n\t\tfunction handleTouchStartPan(event) {\n\t\n\t\t\t//console.log( 'handleTouchStartPan' );\n\t\n\t\t\tpanStart.set(event.deltaX, event.deltaY);\n\t\t}\n\t\n\t\tfunction handleTouchMoveRotate(event) {\n\t\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\t\n\t\t\trotateEnd.set(event.pointers[0].pageX, event.pointers[0].pageY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\n\t\t\trotateStart.copy(rotateEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleTouchMoveDolly(event) {\n\t\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\t\n\t\t\tvar dx = event.pointers[0].pageX - event.pointers[1].pageX;\n\t\t\tvar dy = event.pointers[0].pageY - event.pointers[1].pageY;\n\t\n\t\t\tvar distance = Math.sqrt(dx * dx + dy * dy);\n\t\n\t\t\tdollyEnd.set(0, distance);\n\t\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\n\t\t\tif (dollyDelta.y > 0) {\n\t\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t} else if (dollyDelta.y < 0) {\n\t\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\n\t\t\tdollyStart.copy(dollyEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleTouchMovePan(event) {\n\t\n\t\t\t//console.log( 'handleTouchMovePan' );\n\t\n\t\t\tpanEnd.set(event.deltaX, event.deltaY);\n\t\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\n\t\t\tpanStart.copy(panEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleTouchEnd(event) {}\n\t\n\t\t//console.log( 'handleTouchEnd' );\n\t\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\t\n\t\tfunction onMouseDown(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tif (event.button === scope.mouseButtons.ORBIT) {\n\t\n\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\thandleMouseDownRotate(event);\n\t\n\t\t\t\tstate = STATE.ROTATE;\n\t\t\t} else if (event.button === scope.mouseButtons.ZOOM) {\n\t\n\t\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\t\thandleMouseDownDolly(event);\n\t\n\t\t\t\tstate = STATE.DOLLY;\n\t\t\t} else if (event.button === scope.mouseButtons.PAN) {\n\t\n\t\t\t\tif (scope.enablePan === false) return;\n\t\n\t\t\t\thandleMouseDownPan(event);\n\t\n\t\t\t\tstate = STATE.PAN;\n\t\t\t}\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\n\t\t\t\tdocument.addEventListener('mousemove', onMouseMove, false);\n\t\t\t\tdocument.addEventListener('mouseup', onMouseUp, false);\n\t\t\t\tdocument.addEventListener('mouseout', onMouseUp, false);\n\t\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onMouseMove(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tif (state === STATE.ROTATE) {\n\t\n\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\thandleMouseMoveRotate(event);\n\t\t\t} else if (state === STATE.DOLLY) {\n\t\n\t\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\t\thandleMouseMoveDolly(event);\n\t\t\t} else if (state === STATE.PAN) {\n\t\n\t\t\t\tif (scope.enablePan === false) return;\n\t\n\t\t\t\thandleMouseMovePan(event);\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onMouseUp(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\thandleMouseUp(event);\n\t\n\t\t\tdocument.removeEventListener('mousemove', onMouseMove, false);\n\t\t\tdocument.removeEventListener('mouseup', onMouseUp, false);\n\t\t\tdocument.removeEventListener('mouseout', onMouseUp, false);\n\t\n\t\t\tscope.dispatchEvent(endEvent);\n\t\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\n\t\tfunction onMouseWheel(event) {\n\t\n\t\t\tif (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;\n\t\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\n\t\t\thandleMouseWheel(event);\n\t\n\t\t\tscope.dispatchEvent(startEvent); // not sure why these are here...\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t}\n\t\n\t\tfunction onKeyDown(event) {\n\t\n\t\t\tif (scope.enabled === false || scope.enableKeys === false || scope.enablePan === false) return;\n\t\n\t\t\thandleKeyDown(event);\n\t\t}\n\t\n\t\tfunction onTouchStart(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tswitch (event.touches.length) {\n\t\n\t\t\t\tcase 1:\n\t\t\t\t\t// one-fingered touch: rotate\n\t\n\t\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\t\thandleTouchStartRotate(event);\n\t\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 2:\n\t\t\t\t\t// two-fingered touch: dolly\n\t\n\t\t\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\t\t\thandleTouchStartDolly(event);\n\t\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 3:\n\t\t\t\t\t// three-fingered touch: pan\n\t\n\t\t\t\t\tif (scope.enablePan === false) return;\n\t\n\t\t\t\t\thandleTouchStartPan(event);\n\t\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tdefault:\n\t\n\t\t\t\t\tstate = STATE.NONE;\n\t\n\t\t\t}\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onTouchMove(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\n\t\t\tswitch (event.touches.length) {\n\t\n\t\t\t\tcase 1:\n\t\t\t\t\t// one-fingered touch: rotate\n\t\n\t\t\t\t\tif (scope.enableRotate === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_ROTATE) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMoveRotate(event);\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 2:\n\t\t\t\t\t// two-fingered touch: dolly\n\t\n\t\t\t\t\tif (scope.enableZoom === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_DOLLY) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMoveDolly(event);\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 3:\n\t\t\t\t\t// three-fingered touch: pan\n\t\n\t\t\t\t\tif (scope.enablePan === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_PAN) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMovePan(event);\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tdefault:\n\t\n\t\t\t\t\tstate = STATE.NONE;\n\t\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onTouchEnd(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\thandleTouchEnd(event);\n\t\n\t\t\tscope.dispatchEvent(endEvent);\n\t\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\n\t\tfunction onContextMenu(event) {\n\t\n\t\t\tevent.preventDefault();\n\t\t}\n\t\n\t\t//\n\t\n\t\tscope.domElement.addEventListener('contextmenu', onContextMenu, false);\n\t\n\t\tscope.domElement.addEventListener('mousedown', onMouseDown, false);\n\t\tscope.domElement.addEventListener('mousewheel', onMouseWheel, false);\n\t\tscope.domElement.addEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox\n\t\n\t\t// scope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\t// scope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\t// scope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\t\n\t\tscope.hammer = new _hammerjs2['default'](scope.domElement);\n\t\n\t\tscope.hammer.get('pan').set({\n\t\t\tpointers: 0,\n\t\t\tdirection: _hammerjs2['default'].DIRECTION_ALL\n\t\t});\n\t\n\t\tscope.hammer.get('pinch').set({\n\t\t\tenable: true,\n\t\t\tthreshold: 0.1\n\t\t});\n\t\n\t\tscope.hammer.on('panstart', function (event) {\n\t\t\tif (scope.enabled === false) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif (event.pointers.length === 1) {\n\t\t\t\tif (scope.enablePan === false) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\thandleTouchStartPan(event);\n\t\t\t\t// panStart.set(event.deltaX, event.deltaY);\n\t\n\t\t\t\tstate = STATE.TOUCH_PAN;\n\t\t\t} else if (event.pointers.length === 2) {\n\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\thandleTouchStartRotate(event);\n\t\n\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\t\t}\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t});\n\t\n\t\tscope.hammer.on('panend', function (event) {\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tonTouchEnd(event);\n\t\t});\n\t\n\t\tscope.hammer.on('panmove', function (event) {\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// event.preventDefault();\n\t\t\t// event.stopPropagation();\n\t\n\t\t\tif (event.pointers.length === 1) {\n\t\t\t\tif (scope.enablePan === false) return;\n\t\t\t\tif (state !== STATE.TOUCH_PAN) return; // is this needed?...\n\t\n\t\t\t\thandleTouchMovePan(event);\n\t\n\t\t\t\t// panEnd.set( event.deltaX, event.deltaY );\n\t\t\t\t//\n\t\t\t\t// panDelta.subVectors( panEnd, panStart );\n\t\t\t\t//\n\t\t\t\t// pan( panDelta.x, panDelta.y );\n\t\t\t\t//\n\t\t\t\t// panStart.copy( panEnd );\n\t\t\t\t//\n\t\t\t\t// scope.update();\n\t\t\t} else if (event.pointers.length === 2) {\n\t\t\t\t\tif (scope.enableRotate === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_ROTATE) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMoveRotate(event);\n\t\t\t\t}\n\t\t});\n\t\n\t\tscope.hammer.on('pinchstart', function (event) {\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\thandleTouchStartDolly(event);\n\t\n\t\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t\t//\n\t\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t\t//\n\t\t\t// dollyStart.set( 0, distance );\n\t\t\t//\n\t\t\tstate = STATE.TOUCH_DOLLY;\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t});\n\t\n\t\tscope.hammer.on('pinchend', function (event) {\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tonTouchEnd(event);\n\t\t});\n\t\n\t\tscope.hammer.on('pinchmove', function (event) {\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// event.preventDefault();\n\t\t\t// event.stopPropagation();\n\t\n\t\t\tif (scope.enableZoom === false) return;\n\t\t\tif (state !== STATE.TOUCH_DOLLY) return; // is this needed?...\n\t\n\t\t\thandleTouchMoveDolly(event);\n\t\n\t\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t\t//\n\t\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t\t//\n\t\t\t// dollyEnd.set( 0, distance );\n\t\t\t//\n\t\t\t// dollyDelta.subVectors( dollyEnd, dollyStart );\n\t\t\t//\n\t\t\t// if ( dollyDelta.y > 0 ) {\n\t\t\t//\n\t\t\t// \tdollyOut( getZoomScale() );\n\t\t\t//\n\t\t\t// } else if ( dollyDelta.y < 0 ) {\n\t\t\t//\n\t\t\t// \tdollyIn( getZoomScale() );\n\t\t\t//\n\t\t\t// }\n\t\t\t//\n\t\t\t// dollyStart.copy( dollyEnd );\n\t\t\t//\n\t\t\t// scope.update();\n\t\t});\n\t\n\t\twindow.addEventListener('keydown', onKeyDown, false);\n\t\n\t\t// Expose controls methods for programmatic control\n\t\tthis.panLeft = panLeft;\n\t\tthis.panUp = panUp;\n\t\tthis.pan = pan;\n\t\tthis.dollyIn = dollyIn;\n\t\tthis.dollyOut = dollyOut;\n\t\tthis.getZoomScale = getZoomScale;\n\t\tthis.rotateLeft = rotateLeft;\n\t\tthis.rotateUp = rotateUp;\n\t\n\t\t// force an update at start\n\t\n\t\tthis.update();\n\t};\n\t\n\tOrbitControls.prototype = Object.create(_three2['default'].EventDispatcher.prototype);\n\tOrbitControls.prototype.constructor = _three2['default'].OrbitControls;\n\t\n\tObject.defineProperties(OrbitControls.prototype, {\n\t\n\t\tcenter: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .center has been renamed to .target');\n\t\t\t\treturn this.target;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t// backward compatibility\n\t\n\t\tnoZoom: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');\n\t\t\t\treturn !this.enableZoom;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');\n\t\t\t\tthis.enableZoom = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tnoRotate: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');\n\t\t\t\treturn !this.enableRotate;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');\n\t\t\t\tthis.enableRotate = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tnoPan: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');\n\t\t\t\treturn !this.enablePan;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');\n\t\t\t\tthis.enablePan = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tnoKeys: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');\n\t\t\t\treturn !this.enableKeys;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');\n\t\t\t\tthis.enableKeys = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tstaticMoving: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');\n\t\t\t\treturn !this.constraint.enableDamping;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');\n\t\t\t\tthis.constraint.enableDamping = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tdynamicDampingFactor: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');\n\t\t\t\treturn this.constraint.dampingFactor;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');\n\t\t\t\tthis.constraint.dampingFactor = value;\n\t\t\t}\n\t\n\t\t}\n\t\n\t});\n\t\n\texports['default'] = OrbitControls;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 40 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_RESULT__;/*! Hammer.JS - v2.0.7 - 2016-04-22\n\t * http://hammerjs.github.io/\n\t *\n\t * Copyright (c) 2016 Jorik Tangelder;\n\t * Licensed under the MIT license */\n\t(function(window, document, exportName, undefined) {\n\t 'use strict';\n\t\n\tvar VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];\n\tvar TEST_ELEMENT = document.createElement('div');\n\t\n\tvar TYPE_FUNCTION = 'function';\n\t\n\tvar round = Math.round;\n\tvar abs = Math.abs;\n\tvar now = Date.now;\n\t\n\t/**\n\t * set a timeout with a given scope\n\t * @param {Function} fn\n\t * @param {Number} timeout\n\t * @param {Object} context\n\t * @returns {number}\n\t */\n\tfunction setTimeoutContext(fn, timeout, context) {\n\t return setTimeout(bindFn(fn, context), timeout);\n\t}\n\t\n\t/**\n\t * if the argument is an array, we want to execute the fn on each entry\n\t * if it aint an array we don't want to do a thing.\n\t * this is used by all the methods that accept a single and array argument.\n\t * @param {*|Array} arg\n\t * @param {String} fn\n\t * @param {Object} [context]\n\t * @returns {Boolean}\n\t */\n\tfunction invokeArrayArg(arg, fn, context) {\n\t if (Array.isArray(arg)) {\n\t each(arg, context[fn], context);\n\t return true;\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * walk objects and arrays\n\t * @param {Object} obj\n\t * @param {Function} iterator\n\t * @param {Object} context\n\t */\n\tfunction each(obj, iterator, context) {\n\t var i;\n\t\n\t if (!obj) {\n\t return;\n\t }\n\t\n\t if (obj.forEach) {\n\t obj.forEach(iterator, context);\n\t } else if (obj.length !== undefined) {\n\t i = 0;\n\t while (i < obj.length) {\n\t iterator.call(context, obj[i], i, obj);\n\t i++;\n\t }\n\t } else {\n\t for (i in obj) {\n\t obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * wrap a method with a deprecation warning and stack trace\n\t * @param {Function} method\n\t * @param {String} name\n\t * @param {String} message\n\t * @returns {Function} A new function wrapping the supplied method.\n\t */\n\tfunction deprecate(method, name, message) {\n\t var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\\n' + message + ' AT \\n';\n\t return function() {\n\t var e = new Error('get-stack-trace');\n\t var stack = e && e.stack ? e.stack.replace(/^[^\\(]+?[\\n$]/gm, '')\n\t .replace(/^\\s+at\\s+/gm, '')\n\t .replace(/^Object.\\s*\\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';\n\t\n\t var log = window.console && (window.console.warn || window.console.log);\n\t if (log) {\n\t log.call(window.console, deprecationMessage, stack);\n\t }\n\t return method.apply(this, arguments);\n\t };\n\t}\n\t\n\t/**\n\t * extend object.\n\t * means that properties in dest will be overwritten by the ones in src.\n\t * @param {Object} target\n\t * @param {...Object} objects_to_assign\n\t * @returns {Object} target\n\t */\n\tvar assign;\n\tif (typeof Object.assign !== 'function') {\n\t assign = function assign(target) {\n\t if (target === undefined || target === null) {\n\t throw new TypeError('Cannot convert undefined or null to object');\n\t }\n\t\n\t var output = Object(target);\n\t for (var index = 1; index < arguments.length; index++) {\n\t var source = arguments[index];\n\t if (source !== undefined && source !== null) {\n\t for (var nextKey in source) {\n\t if (source.hasOwnProperty(nextKey)) {\n\t output[nextKey] = source[nextKey];\n\t }\n\t }\n\t }\n\t }\n\t return output;\n\t };\n\t} else {\n\t assign = Object.assign;\n\t}\n\t\n\t/**\n\t * extend object.\n\t * means that properties in dest will be overwritten by the ones in src.\n\t * @param {Object} dest\n\t * @param {Object} src\n\t * @param {Boolean} [merge=false]\n\t * @returns {Object} dest\n\t */\n\tvar extend = deprecate(function extend(dest, src, merge) {\n\t var keys = Object.keys(src);\n\t var i = 0;\n\t while (i < keys.length) {\n\t if (!merge || (merge && dest[keys[i]] === undefined)) {\n\t dest[keys[i]] = src[keys[i]];\n\t }\n\t i++;\n\t }\n\t return dest;\n\t}, 'extend', 'Use `assign`.');\n\t\n\t/**\n\t * merge the values from src in the dest.\n\t * means that properties that exist in dest will not be overwritten by src\n\t * @param {Object} dest\n\t * @param {Object} src\n\t * @returns {Object} dest\n\t */\n\tvar merge = deprecate(function merge(dest, src) {\n\t return extend(dest, src, true);\n\t}, 'merge', 'Use `assign`.');\n\t\n\t/**\n\t * simple class inheritance\n\t * @param {Function} child\n\t * @param {Function} base\n\t * @param {Object} [properties]\n\t */\n\tfunction inherit(child, base, properties) {\n\t var baseP = base.prototype,\n\t childP;\n\t\n\t childP = child.prototype = Object.create(baseP);\n\t childP.constructor = child;\n\t childP._super = baseP;\n\t\n\t if (properties) {\n\t assign(childP, properties);\n\t }\n\t}\n\t\n\t/**\n\t * simple function bind\n\t * @param {Function} fn\n\t * @param {Object} context\n\t * @returns {Function}\n\t */\n\tfunction bindFn(fn, context) {\n\t return function boundFn() {\n\t return fn.apply(context, arguments);\n\t };\n\t}\n\t\n\t/**\n\t * let a boolean value also be a function that must return a boolean\n\t * this first item in args will be used as the context\n\t * @param {Boolean|Function} val\n\t * @param {Array} [args]\n\t * @returns {Boolean}\n\t */\n\tfunction boolOrFn(val, args) {\n\t if (typeof val == TYPE_FUNCTION) {\n\t return val.apply(args ? args[0] || undefined : undefined, args);\n\t }\n\t return val;\n\t}\n\t\n\t/**\n\t * use the val2 when val1 is undefined\n\t * @param {*} val1\n\t * @param {*} val2\n\t * @returns {*}\n\t */\n\tfunction ifUndefined(val1, val2) {\n\t return (val1 === undefined) ? val2 : val1;\n\t}\n\t\n\t/**\n\t * addEventListener with multiple events at once\n\t * @param {EventTarget} target\n\t * @param {String} types\n\t * @param {Function} handler\n\t */\n\tfunction addEventListeners(target, types, handler) {\n\t each(splitStr(types), function(type) {\n\t target.addEventListener(type, handler, false);\n\t });\n\t}\n\t\n\t/**\n\t * removeEventListener with multiple events at once\n\t * @param {EventTarget} target\n\t * @param {String} types\n\t * @param {Function} handler\n\t */\n\tfunction removeEventListeners(target, types, handler) {\n\t each(splitStr(types), function(type) {\n\t target.removeEventListener(type, handler, false);\n\t });\n\t}\n\t\n\t/**\n\t * find if a node is in the given parent\n\t * @method hasParent\n\t * @param {HTMLElement} node\n\t * @param {HTMLElement} parent\n\t * @return {Boolean} found\n\t */\n\tfunction hasParent(node, parent) {\n\t while (node) {\n\t if (node == parent) {\n\t return true;\n\t }\n\t node = node.parentNode;\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * small indexOf wrapper\n\t * @param {String} str\n\t * @param {String} find\n\t * @returns {Boolean} found\n\t */\n\tfunction inStr(str, find) {\n\t return str.indexOf(find) > -1;\n\t}\n\t\n\t/**\n\t * split string on whitespace\n\t * @param {String} str\n\t * @returns {Array} words\n\t */\n\tfunction splitStr(str) {\n\t return str.trim().split(/\\s+/g);\n\t}\n\t\n\t/**\n\t * find if a array contains the object using indexOf or a simple polyFill\n\t * @param {Array} src\n\t * @param {String} find\n\t * @param {String} [findByKey]\n\t * @return {Boolean|Number} false when not found, or the index\n\t */\n\tfunction inArray(src, find, findByKey) {\n\t if (src.indexOf && !findByKey) {\n\t return src.indexOf(find);\n\t } else {\n\t var i = 0;\n\t while (i < src.length) {\n\t if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {\n\t return i;\n\t }\n\t i++;\n\t }\n\t return -1;\n\t }\n\t}\n\t\n\t/**\n\t * convert array-like objects to real arrays\n\t * @param {Object} obj\n\t * @returns {Array}\n\t */\n\tfunction toArray(obj) {\n\t return Array.prototype.slice.call(obj, 0);\n\t}\n\t\n\t/**\n\t * unique array with objects based on a key (like 'id') or just by the array's value\n\t * @param {Array} src [{id:1},{id:2},{id:1}]\n\t * @param {String} [key]\n\t * @param {Boolean} [sort=False]\n\t * @returns {Array} [{id:1},{id:2}]\n\t */\n\tfunction uniqueArray(src, key, sort) {\n\t var results = [];\n\t var values = [];\n\t var i = 0;\n\t\n\t while (i < src.length) {\n\t var val = key ? src[i][key] : src[i];\n\t if (inArray(values, val) < 0) {\n\t results.push(src[i]);\n\t }\n\t values[i] = val;\n\t i++;\n\t }\n\t\n\t if (sort) {\n\t if (!key) {\n\t results = results.sort();\n\t } else {\n\t results = results.sort(function sortUniqueArray(a, b) {\n\t return a[key] > b[key];\n\t });\n\t }\n\t }\n\t\n\t return results;\n\t}\n\t\n\t/**\n\t * get the prefixed property\n\t * @param {Object} obj\n\t * @param {String} property\n\t * @returns {String|Undefined} prefixed\n\t */\n\tfunction prefixed(obj, property) {\n\t var prefix, prop;\n\t var camelProp = property[0].toUpperCase() + property.slice(1);\n\t\n\t var i = 0;\n\t while (i < VENDOR_PREFIXES.length) {\n\t prefix = VENDOR_PREFIXES[i];\n\t prop = (prefix) ? prefix + camelProp : property;\n\t\n\t if (prop in obj) {\n\t return prop;\n\t }\n\t i++;\n\t }\n\t return undefined;\n\t}\n\t\n\t/**\n\t * get a unique id\n\t * @returns {number} uniqueId\n\t */\n\tvar _uniqueId = 1;\n\tfunction uniqueId() {\n\t return _uniqueId++;\n\t}\n\t\n\t/**\n\t * get the window object of an element\n\t * @param {HTMLElement} element\n\t * @returns {DocumentView|Window}\n\t */\n\tfunction getWindowForElement(element) {\n\t var doc = element.ownerDocument || element;\n\t return (doc.defaultView || doc.parentWindow || window);\n\t}\n\t\n\tvar MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;\n\t\n\tvar SUPPORT_TOUCH = ('ontouchstart' in window);\n\tvar SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;\n\tvar SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);\n\t\n\tvar INPUT_TYPE_TOUCH = 'touch';\n\tvar INPUT_TYPE_PEN = 'pen';\n\tvar INPUT_TYPE_MOUSE = 'mouse';\n\tvar INPUT_TYPE_KINECT = 'kinect';\n\t\n\tvar COMPUTE_INTERVAL = 25;\n\t\n\tvar INPUT_START = 1;\n\tvar INPUT_MOVE = 2;\n\tvar INPUT_END = 4;\n\tvar INPUT_CANCEL = 8;\n\t\n\tvar DIRECTION_NONE = 1;\n\tvar DIRECTION_LEFT = 2;\n\tvar DIRECTION_RIGHT = 4;\n\tvar DIRECTION_UP = 8;\n\tvar DIRECTION_DOWN = 16;\n\t\n\tvar DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;\n\tvar DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;\n\tvar DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;\n\t\n\tvar PROPS_XY = ['x', 'y'];\n\tvar PROPS_CLIENT_XY = ['clientX', 'clientY'];\n\t\n\t/**\n\t * create new input type manager\n\t * @param {Manager} manager\n\t * @param {Function} callback\n\t * @returns {Input}\n\t * @constructor\n\t */\n\tfunction Input(manager, callback) {\n\t var self = this;\n\t this.manager = manager;\n\t this.callback = callback;\n\t this.element = manager.element;\n\t this.target = manager.options.inputTarget;\n\t\n\t // smaller wrapper around the handler, for the scope and the enabled state of the manager,\n\t // so when disabled the input events are completely bypassed.\n\t this.domHandler = function(ev) {\n\t if (boolOrFn(manager.options.enable, [manager])) {\n\t self.handler(ev);\n\t }\n\t };\n\t\n\t this.init();\n\t\n\t}\n\t\n\tInput.prototype = {\n\t /**\n\t * should handle the inputEvent data and trigger the callback\n\t * @virtual\n\t */\n\t handler: function() { },\n\t\n\t /**\n\t * bind the events\n\t */\n\t init: function() {\n\t this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);\n\t this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);\n\t this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n\t },\n\t\n\t /**\n\t * unbind the events\n\t */\n\t destroy: function() {\n\t this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);\n\t this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);\n\t this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n\t }\n\t};\n\t\n\t/**\n\t * create new input type manager\n\t * called by the Manager constructor\n\t * @param {Hammer} manager\n\t * @returns {Input}\n\t */\n\tfunction createInputInstance(manager) {\n\t var Type;\n\t var inputClass = manager.options.inputClass;\n\t\n\t if (inputClass) {\n\t Type = inputClass;\n\t } else if (SUPPORT_POINTER_EVENTS) {\n\t Type = PointerEventInput;\n\t } else if (SUPPORT_ONLY_TOUCH) {\n\t Type = TouchInput;\n\t } else if (!SUPPORT_TOUCH) {\n\t Type = MouseInput;\n\t } else {\n\t Type = TouchMouseInput;\n\t }\n\t return new (Type)(manager, inputHandler);\n\t}\n\t\n\t/**\n\t * handle input events\n\t * @param {Manager} manager\n\t * @param {String} eventType\n\t * @param {Object} input\n\t */\n\tfunction inputHandler(manager, eventType, input) {\n\t var pointersLen = input.pointers.length;\n\t var changedPointersLen = input.changedPointers.length;\n\t var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));\n\t var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));\n\t\n\t input.isFirst = !!isFirst;\n\t input.isFinal = !!isFinal;\n\t\n\t if (isFirst) {\n\t manager.session = {};\n\t }\n\t\n\t // source event is the normalized value of the domEvents\n\t // like 'touchstart, mouseup, pointerdown'\n\t input.eventType = eventType;\n\t\n\t // compute scale, rotation etc\n\t computeInputData(manager, input);\n\t\n\t // emit secret event\n\t manager.emit('hammer.input', input);\n\t\n\t manager.recognize(input);\n\t manager.session.prevInput = input;\n\t}\n\t\n\t/**\n\t * extend the data with some usable properties like scale, rotate, velocity etc\n\t * @param {Object} manager\n\t * @param {Object} input\n\t */\n\tfunction computeInputData(manager, input) {\n\t var session = manager.session;\n\t var pointers = input.pointers;\n\t var pointersLength = pointers.length;\n\t\n\t // store the first input to calculate the distance and direction\n\t if (!session.firstInput) {\n\t session.firstInput = simpleCloneInputData(input);\n\t }\n\t\n\t // to compute scale and rotation we need to store the multiple touches\n\t if (pointersLength > 1 && !session.firstMultiple) {\n\t session.firstMultiple = simpleCloneInputData(input);\n\t } else if (pointersLength === 1) {\n\t session.firstMultiple = false;\n\t }\n\t\n\t var firstInput = session.firstInput;\n\t var firstMultiple = session.firstMultiple;\n\t var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;\n\t\n\t var center = input.center = getCenter(pointers);\n\t input.timeStamp = now();\n\t input.deltaTime = input.timeStamp - firstInput.timeStamp;\n\t\n\t input.angle = getAngle(offsetCenter, center);\n\t input.distance = getDistance(offsetCenter, center);\n\t\n\t computeDeltaXY(session, input);\n\t input.offsetDirection = getDirection(input.deltaX, input.deltaY);\n\t\n\t var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);\n\t input.overallVelocityX = overallVelocity.x;\n\t input.overallVelocityY = overallVelocity.y;\n\t input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;\n\t\n\t input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;\n\t input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;\n\t\n\t input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >\n\t session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);\n\t\n\t computeIntervalInputData(session, input);\n\t\n\t // find the correct target\n\t var target = manager.element;\n\t if (hasParent(input.srcEvent.target, target)) {\n\t target = input.srcEvent.target;\n\t }\n\t input.target = target;\n\t}\n\t\n\tfunction computeDeltaXY(session, input) {\n\t var center = input.center;\n\t var offset = session.offsetDelta || {};\n\t var prevDelta = session.prevDelta || {};\n\t var prevInput = session.prevInput || {};\n\t\n\t if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {\n\t prevDelta = session.prevDelta = {\n\t x: prevInput.deltaX || 0,\n\t y: prevInput.deltaY || 0\n\t };\n\t\n\t offset = session.offsetDelta = {\n\t x: center.x,\n\t y: center.y\n\t };\n\t }\n\t\n\t input.deltaX = prevDelta.x + (center.x - offset.x);\n\t input.deltaY = prevDelta.y + (center.y - offset.y);\n\t}\n\t\n\t/**\n\t * velocity is calculated every x ms\n\t * @param {Object} session\n\t * @param {Object} input\n\t */\n\tfunction computeIntervalInputData(session, input) {\n\t var last = session.lastInterval || input,\n\t deltaTime = input.timeStamp - last.timeStamp,\n\t velocity, velocityX, velocityY, direction;\n\t\n\t if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {\n\t var deltaX = input.deltaX - last.deltaX;\n\t var deltaY = input.deltaY - last.deltaY;\n\t\n\t var v = getVelocity(deltaTime, deltaX, deltaY);\n\t velocityX = v.x;\n\t velocityY = v.y;\n\t velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;\n\t direction = getDirection(deltaX, deltaY);\n\t\n\t session.lastInterval = input;\n\t } else {\n\t // use latest velocity info if it doesn't overtake a minimum period\n\t velocity = last.velocity;\n\t velocityX = last.velocityX;\n\t velocityY = last.velocityY;\n\t direction = last.direction;\n\t }\n\t\n\t input.velocity = velocity;\n\t input.velocityX = velocityX;\n\t input.velocityY = velocityY;\n\t input.direction = direction;\n\t}\n\t\n\t/**\n\t * create a simple clone from the input used for storage of firstInput and firstMultiple\n\t * @param {Object} input\n\t * @returns {Object} clonedInputData\n\t */\n\tfunction simpleCloneInputData(input) {\n\t // make a simple copy of the pointers because we will get a reference if we don't\n\t // we only need clientXY for the calculations\n\t var pointers = [];\n\t var i = 0;\n\t while (i < input.pointers.length) {\n\t pointers[i] = {\n\t clientX: round(input.pointers[i].clientX),\n\t clientY: round(input.pointers[i].clientY)\n\t };\n\t i++;\n\t }\n\t\n\t return {\n\t timeStamp: now(),\n\t pointers: pointers,\n\t center: getCenter(pointers),\n\t deltaX: input.deltaX,\n\t deltaY: input.deltaY\n\t };\n\t}\n\t\n\t/**\n\t * get the center of all the pointers\n\t * @param {Array} pointers\n\t * @return {Object} center contains `x` and `y` properties\n\t */\n\tfunction getCenter(pointers) {\n\t var pointersLength = pointers.length;\n\t\n\t // no need to loop when only one touch\n\t if (pointersLength === 1) {\n\t return {\n\t x: round(pointers[0].clientX),\n\t y: round(pointers[0].clientY)\n\t };\n\t }\n\t\n\t var x = 0, y = 0, i = 0;\n\t while (i < pointersLength) {\n\t x += pointers[i].clientX;\n\t y += pointers[i].clientY;\n\t i++;\n\t }\n\t\n\t return {\n\t x: round(x / pointersLength),\n\t y: round(y / pointersLength)\n\t };\n\t}\n\t\n\t/**\n\t * calculate the velocity between two points. unit is in px per ms.\n\t * @param {Number} deltaTime\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @return {Object} velocity `x` and `y`\n\t */\n\tfunction getVelocity(deltaTime, x, y) {\n\t return {\n\t x: x / deltaTime || 0,\n\t y: y / deltaTime || 0\n\t };\n\t}\n\t\n\t/**\n\t * get the direction between two points\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @return {Number} direction\n\t */\n\tfunction getDirection(x, y) {\n\t if (x === y) {\n\t return DIRECTION_NONE;\n\t }\n\t\n\t if (abs(x) >= abs(y)) {\n\t return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;\n\t }\n\t return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;\n\t}\n\t\n\t/**\n\t * calculate the absolute distance between two points\n\t * @param {Object} p1 {x, y}\n\t * @param {Object} p2 {x, y}\n\t * @param {Array} [props] containing x and y keys\n\t * @return {Number} distance\n\t */\n\tfunction getDistance(p1, p2, props) {\n\t if (!props) {\n\t props = PROPS_XY;\n\t }\n\t var x = p2[props[0]] - p1[props[0]],\n\t y = p2[props[1]] - p1[props[1]];\n\t\n\t return Math.sqrt((x * x) + (y * y));\n\t}\n\t\n\t/**\n\t * calculate the angle between two coordinates\n\t * @param {Object} p1\n\t * @param {Object} p2\n\t * @param {Array} [props] containing x and y keys\n\t * @return {Number} angle\n\t */\n\tfunction getAngle(p1, p2, props) {\n\t if (!props) {\n\t props = PROPS_XY;\n\t }\n\t var x = p2[props[0]] - p1[props[0]],\n\t y = p2[props[1]] - p1[props[1]];\n\t return Math.atan2(y, x) * 180 / Math.PI;\n\t}\n\t\n\t/**\n\t * calculate the rotation degrees between two pointersets\n\t * @param {Array} start array of pointers\n\t * @param {Array} end array of pointers\n\t * @return {Number} rotation\n\t */\n\tfunction getRotation(start, end) {\n\t return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);\n\t}\n\t\n\t/**\n\t * calculate the scale factor between two pointersets\n\t * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out\n\t * @param {Array} start array of pointers\n\t * @param {Array} end array of pointers\n\t * @return {Number} scale\n\t */\n\tfunction getScale(start, end) {\n\t return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);\n\t}\n\t\n\tvar MOUSE_INPUT_MAP = {\n\t mousedown: INPUT_START,\n\t mousemove: INPUT_MOVE,\n\t mouseup: INPUT_END\n\t};\n\t\n\tvar MOUSE_ELEMENT_EVENTS = 'mousedown';\n\tvar MOUSE_WINDOW_EVENTS = 'mousemove mouseup';\n\t\n\t/**\n\t * Mouse events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction MouseInput() {\n\t this.evEl = MOUSE_ELEMENT_EVENTS;\n\t this.evWin = MOUSE_WINDOW_EVENTS;\n\t\n\t this.pressed = false; // mousedown state\n\t\n\t Input.apply(this, arguments);\n\t}\n\t\n\tinherit(MouseInput, Input, {\n\t /**\n\t * handle mouse events\n\t * @param {Object} ev\n\t */\n\t handler: function MEhandler(ev) {\n\t var eventType = MOUSE_INPUT_MAP[ev.type];\n\t\n\t // on start we want to have the left mouse button down\n\t if (eventType & INPUT_START && ev.button === 0) {\n\t this.pressed = true;\n\t }\n\t\n\t if (eventType & INPUT_MOVE && ev.which !== 1) {\n\t eventType = INPUT_END;\n\t }\n\t\n\t // mouse must be down\n\t if (!this.pressed) {\n\t return;\n\t }\n\t\n\t if (eventType & INPUT_END) {\n\t this.pressed = false;\n\t }\n\t\n\t this.callback(this.manager, eventType, {\n\t pointers: [ev],\n\t changedPointers: [ev],\n\t pointerType: INPUT_TYPE_MOUSE,\n\t srcEvent: ev\n\t });\n\t }\n\t});\n\t\n\tvar POINTER_INPUT_MAP = {\n\t pointerdown: INPUT_START,\n\t pointermove: INPUT_MOVE,\n\t pointerup: INPUT_END,\n\t pointercancel: INPUT_CANCEL,\n\t pointerout: INPUT_CANCEL\n\t};\n\t\n\t// in IE10 the pointer types is defined as an enum\n\tvar IE10_POINTER_TYPE_ENUM = {\n\t 2: INPUT_TYPE_TOUCH,\n\t 3: INPUT_TYPE_PEN,\n\t 4: INPUT_TYPE_MOUSE,\n\t 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816\n\t};\n\t\n\tvar POINTER_ELEMENT_EVENTS = 'pointerdown';\n\tvar POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';\n\t\n\t// IE10 has prefixed support, and case-sensitive\n\tif (window.MSPointerEvent && !window.PointerEvent) {\n\t POINTER_ELEMENT_EVENTS = 'MSPointerDown';\n\t POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';\n\t}\n\t\n\t/**\n\t * Pointer events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction PointerEventInput() {\n\t this.evEl = POINTER_ELEMENT_EVENTS;\n\t this.evWin = POINTER_WINDOW_EVENTS;\n\t\n\t Input.apply(this, arguments);\n\t\n\t this.store = (this.manager.session.pointerEvents = []);\n\t}\n\t\n\tinherit(PointerEventInput, Input, {\n\t /**\n\t * handle mouse events\n\t * @param {Object} ev\n\t */\n\t handler: function PEhandler(ev) {\n\t var store = this.store;\n\t var removePointer = false;\n\t\n\t var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');\n\t var eventType = POINTER_INPUT_MAP[eventTypeNormalized];\n\t var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;\n\t\n\t var isTouch = (pointerType == INPUT_TYPE_TOUCH);\n\t\n\t // get index of the event in the store\n\t var storeIndex = inArray(store, ev.pointerId, 'pointerId');\n\t\n\t // start and mouse must be down\n\t if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {\n\t if (storeIndex < 0) {\n\t store.push(ev);\n\t storeIndex = store.length - 1;\n\t }\n\t } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n\t removePointer = true;\n\t }\n\t\n\t // it not found, so the pointer hasn't been down (so it's probably a hover)\n\t if (storeIndex < 0) {\n\t return;\n\t }\n\t\n\t // update the event in the store\n\t store[storeIndex] = ev;\n\t\n\t this.callback(this.manager, eventType, {\n\t pointers: store,\n\t changedPointers: [ev],\n\t pointerType: pointerType,\n\t srcEvent: ev\n\t });\n\t\n\t if (removePointer) {\n\t // remove from the store\n\t store.splice(storeIndex, 1);\n\t }\n\t }\n\t});\n\t\n\tvar SINGLE_TOUCH_INPUT_MAP = {\n\t touchstart: INPUT_START,\n\t touchmove: INPUT_MOVE,\n\t touchend: INPUT_END,\n\t touchcancel: INPUT_CANCEL\n\t};\n\t\n\tvar SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';\n\tvar SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';\n\t\n\t/**\n\t * Touch events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction SingleTouchInput() {\n\t this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;\n\t this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;\n\t this.started = false;\n\t\n\t Input.apply(this, arguments);\n\t}\n\t\n\tinherit(SingleTouchInput, Input, {\n\t handler: function TEhandler(ev) {\n\t var type = SINGLE_TOUCH_INPUT_MAP[ev.type];\n\t\n\t // should we handle the touch events?\n\t if (type === INPUT_START) {\n\t this.started = true;\n\t }\n\t\n\t if (!this.started) {\n\t return;\n\t }\n\t\n\t var touches = normalizeSingleTouches.call(this, ev, type);\n\t\n\t // when done, reset the started state\n\t if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {\n\t this.started = false;\n\t }\n\t\n\t this.callback(this.manager, type, {\n\t pointers: touches[0],\n\t changedPointers: touches[1],\n\t pointerType: INPUT_TYPE_TOUCH,\n\t srcEvent: ev\n\t });\n\t }\n\t});\n\t\n\t/**\n\t * @this {TouchInput}\n\t * @param {Object} ev\n\t * @param {Number} type flag\n\t * @returns {undefined|Array} [all, changed]\n\t */\n\tfunction normalizeSingleTouches(ev, type) {\n\t var all = toArray(ev.touches);\n\t var changed = toArray(ev.changedTouches);\n\t\n\t if (type & (INPUT_END | INPUT_CANCEL)) {\n\t all = uniqueArray(all.concat(changed), 'identifier', true);\n\t }\n\t\n\t return [all, changed];\n\t}\n\t\n\tvar TOUCH_INPUT_MAP = {\n\t touchstart: INPUT_START,\n\t touchmove: INPUT_MOVE,\n\t touchend: INPUT_END,\n\t touchcancel: INPUT_CANCEL\n\t};\n\t\n\tvar TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';\n\t\n\t/**\n\t * Multi-user touch events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction TouchInput() {\n\t this.evTarget = TOUCH_TARGET_EVENTS;\n\t this.targetIds = {};\n\t\n\t Input.apply(this, arguments);\n\t}\n\t\n\tinherit(TouchInput, Input, {\n\t handler: function MTEhandler(ev) {\n\t var type = TOUCH_INPUT_MAP[ev.type];\n\t var touches = getTouches.call(this, ev, type);\n\t if (!touches) {\n\t return;\n\t }\n\t\n\t this.callback(this.manager, type, {\n\t pointers: touches[0],\n\t changedPointers: touches[1],\n\t pointerType: INPUT_TYPE_TOUCH,\n\t srcEvent: ev\n\t });\n\t }\n\t});\n\t\n\t/**\n\t * @this {TouchInput}\n\t * @param {Object} ev\n\t * @param {Number} type flag\n\t * @returns {undefined|Array} [all, changed]\n\t */\n\tfunction getTouches(ev, type) {\n\t var allTouches = toArray(ev.touches);\n\t var targetIds = this.targetIds;\n\t\n\t // when there is only one touch, the process can be simplified\n\t if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {\n\t targetIds[allTouches[0].identifier] = true;\n\t return [allTouches, allTouches];\n\t }\n\t\n\t var i,\n\t targetTouches,\n\t changedTouches = toArray(ev.changedTouches),\n\t changedTargetTouches = [],\n\t target = this.target;\n\t\n\t // get target touches from touches\n\t targetTouches = allTouches.filter(function(touch) {\n\t return hasParent(touch.target, target);\n\t });\n\t\n\t // collect touches\n\t if (type === INPUT_START) {\n\t i = 0;\n\t while (i < targetTouches.length) {\n\t targetIds[targetTouches[i].identifier] = true;\n\t i++;\n\t }\n\t }\n\t\n\t // filter changed touches to only contain touches that exist in the collected target ids\n\t i = 0;\n\t while (i < changedTouches.length) {\n\t if (targetIds[changedTouches[i].identifier]) {\n\t changedTargetTouches.push(changedTouches[i]);\n\t }\n\t\n\t // cleanup removed touches\n\t if (type & (INPUT_END | INPUT_CANCEL)) {\n\t delete targetIds[changedTouches[i].identifier];\n\t }\n\t i++;\n\t }\n\t\n\t if (!changedTargetTouches.length) {\n\t return;\n\t }\n\t\n\t return [\n\t // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'\n\t uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),\n\t changedTargetTouches\n\t ];\n\t}\n\t\n\t/**\n\t * Combined touch and mouse input\n\t *\n\t * Touch has a higher priority then mouse, and while touching no mouse events are allowed.\n\t * This because touch devices also emit mouse events while doing a touch.\n\t *\n\t * @constructor\n\t * @extends Input\n\t */\n\t\n\tvar DEDUP_TIMEOUT = 2500;\n\tvar DEDUP_DISTANCE = 25;\n\t\n\tfunction TouchMouseInput() {\n\t Input.apply(this, arguments);\n\t\n\t var handler = bindFn(this.handler, this);\n\t this.touch = new TouchInput(this.manager, handler);\n\t this.mouse = new MouseInput(this.manager, handler);\n\t\n\t this.primaryTouch = null;\n\t this.lastTouches = [];\n\t}\n\t\n\tinherit(TouchMouseInput, Input, {\n\t /**\n\t * handle mouse and touch events\n\t * @param {Hammer} manager\n\t * @param {String} inputEvent\n\t * @param {Object} inputData\n\t */\n\t handler: function TMEhandler(manager, inputEvent, inputData) {\n\t var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),\n\t isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);\n\t\n\t if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {\n\t return;\n\t }\n\t\n\t // when we're in a touch event, record touches to de-dupe synthetic mouse event\n\t if (isTouch) {\n\t recordTouches.call(this, inputEvent, inputData);\n\t } else if (isMouse && isSyntheticEvent.call(this, inputData)) {\n\t return;\n\t }\n\t\n\t this.callback(manager, inputEvent, inputData);\n\t },\n\t\n\t /**\n\t * remove the event listeners\n\t */\n\t destroy: function destroy() {\n\t this.touch.destroy();\n\t this.mouse.destroy();\n\t }\n\t});\n\t\n\tfunction recordTouches(eventType, eventData) {\n\t if (eventType & INPUT_START) {\n\t this.primaryTouch = eventData.changedPointers[0].identifier;\n\t setLastTouch.call(this, eventData);\n\t } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n\t setLastTouch.call(this, eventData);\n\t }\n\t}\n\t\n\tfunction setLastTouch(eventData) {\n\t var touch = eventData.changedPointers[0];\n\t\n\t if (touch.identifier === this.primaryTouch) {\n\t var lastTouch = {x: touch.clientX, y: touch.clientY};\n\t this.lastTouches.push(lastTouch);\n\t var lts = this.lastTouches;\n\t var removeLastTouch = function() {\n\t var i = lts.indexOf(lastTouch);\n\t if (i > -1) {\n\t lts.splice(i, 1);\n\t }\n\t };\n\t setTimeout(removeLastTouch, DEDUP_TIMEOUT);\n\t }\n\t}\n\t\n\tfunction isSyntheticEvent(eventData) {\n\t var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;\n\t for (var i = 0; i < this.lastTouches.length; i++) {\n\t var t = this.lastTouches[i];\n\t var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n\t if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t}\n\t\n\tvar PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');\n\tvar NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;\n\t\n\t// magical touchAction value\n\tvar TOUCH_ACTION_COMPUTE = 'compute';\n\tvar TOUCH_ACTION_AUTO = 'auto';\n\tvar TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented\n\tvar TOUCH_ACTION_NONE = 'none';\n\tvar TOUCH_ACTION_PAN_X = 'pan-x';\n\tvar TOUCH_ACTION_PAN_Y = 'pan-y';\n\tvar TOUCH_ACTION_MAP = getTouchActionProps();\n\t\n\t/**\n\t * Touch Action\n\t * sets the touchAction property or uses the js alternative\n\t * @param {Manager} manager\n\t * @param {String} value\n\t * @constructor\n\t */\n\tfunction TouchAction(manager, value) {\n\t this.manager = manager;\n\t this.set(value);\n\t}\n\t\n\tTouchAction.prototype = {\n\t /**\n\t * set the touchAction value on the element or enable the polyfill\n\t * @param {String} value\n\t */\n\t set: function(value) {\n\t // find out the touch-action by the event handlers\n\t if (value == TOUCH_ACTION_COMPUTE) {\n\t value = this.compute();\n\t }\n\t\n\t if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {\n\t this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;\n\t }\n\t this.actions = value.toLowerCase().trim();\n\t },\n\t\n\t /**\n\t * just re-set the touchAction value\n\t */\n\t update: function() {\n\t this.set(this.manager.options.touchAction);\n\t },\n\t\n\t /**\n\t * compute the value for the touchAction property based on the recognizer's settings\n\t * @returns {String} value\n\t */\n\t compute: function() {\n\t var actions = [];\n\t each(this.manager.recognizers, function(recognizer) {\n\t if (boolOrFn(recognizer.options.enable, [recognizer])) {\n\t actions = actions.concat(recognizer.getTouchAction());\n\t }\n\t });\n\t return cleanTouchActions(actions.join(' '));\n\t },\n\t\n\t /**\n\t * this method is called on each input cycle and provides the preventing of the browser behavior\n\t * @param {Object} input\n\t */\n\t preventDefaults: function(input) {\n\t var srcEvent = input.srcEvent;\n\t var direction = input.offsetDirection;\n\t\n\t // if the touch action did prevented once this session\n\t if (this.manager.session.prevented) {\n\t srcEvent.preventDefault();\n\t return;\n\t }\n\t\n\t var actions = this.actions;\n\t var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];\n\t var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];\n\t var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];\n\t\n\t if (hasNone) {\n\t //do not prevent defaults if this is a tap gesture\n\t\n\t var isTapPointer = input.pointers.length === 1;\n\t var isTapMovement = input.distance < 2;\n\t var isTapTouchTime = input.deltaTime < 250;\n\t\n\t if (isTapPointer && isTapMovement && isTapTouchTime) {\n\t return;\n\t }\n\t }\n\t\n\t if (hasPanX && hasPanY) {\n\t // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent\n\t return;\n\t }\n\t\n\t if (hasNone ||\n\t (hasPanY && direction & DIRECTION_HORIZONTAL) ||\n\t (hasPanX && direction & DIRECTION_VERTICAL)) {\n\t return this.preventSrc(srcEvent);\n\t }\n\t },\n\t\n\t /**\n\t * call preventDefault to prevent the browser's default behavior (scrolling in most cases)\n\t * @param {Object} srcEvent\n\t */\n\t preventSrc: function(srcEvent) {\n\t this.manager.session.prevented = true;\n\t srcEvent.preventDefault();\n\t }\n\t};\n\t\n\t/**\n\t * when the touchActions are collected they are not a valid value, so we need to clean things up. *\n\t * @param {String} actions\n\t * @returns {*}\n\t */\n\tfunction cleanTouchActions(actions) {\n\t // none\n\t if (inStr(actions, TOUCH_ACTION_NONE)) {\n\t return TOUCH_ACTION_NONE;\n\t }\n\t\n\t var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);\n\t var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);\n\t\n\t // if both pan-x and pan-y are set (different recognizers\n\t // for different directions, e.g. horizontal pan but vertical swipe?)\n\t // we need none (as otherwise with pan-x pan-y combined none of these\n\t // recognizers will work, since the browser would handle all panning\n\t if (hasPanX && hasPanY) {\n\t return TOUCH_ACTION_NONE;\n\t }\n\t\n\t // pan-x OR pan-y\n\t if (hasPanX || hasPanY) {\n\t return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;\n\t }\n\t\n\t // manipulation\n\t if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {\n\t return TOUCH_ACTION_MANIPULATION;\n\t }\n\t\n\t return TOUCH_ACTION_AUTO;\n\t}\n\t\n\tfunction getTouchActionProps() {\n\t if (!NATIVE_TOUCH_ACTION) {\n\t return false;\n\t }\n\t var touchMap = {};\n\t var cssSupports = window.CSS && window.CSS.supports;\n\t ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {\n\t\n\t // If css.supports is not supported but there is native touch-action assume it supports\n\t // all values. This is the case for IE 10 and 11.\n\t touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;\n\t });\n\t return touchMap;\n\t}\n\t\n\t/**\n\t * Recognizer flow explained; *\n\t * All recognizers have the initial state of POSSIBLE when a input session starts.\n\t * The definition of a input session is from the first input until the last input, with all it's movement in it. *\n\t * Example session for mouse-input: mousedown -> mousemove -> mouseup\n\t *\n\t * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed\n\t * which determines with state it should be.\n\t *\n\t * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to\n\t * POSSIBLE to give it another change on the next cycle.\n\t *\n\t * Possible\n\t * |\n\t * +-----+---------------+\n\t * | |\n\t * +-----+-----+ |\n\t * | | |\n\t * Failed Cancelled |\n\t * +-------+------+\n\t * | |\n\t * Recognized Began\n\t * |\n\t * Changed\n\t * |\n\t * Ended/Recognized\n\t */\n\tvar STATE_POSSIBLE = 1;\n\tvar STATE_BEGAN = 2;\n\tvar STATE_CHANGED = 4;\n\tvar STATE_ENDED = 8;\n\tvar STATE_RECOGNIZED = STATE_ENDED;\n\tvar STATE_CANCELLED = 16;\n\tvar STATE_FAILED = 32;\n\t\n\t/**\n\t * Recognizer\n\t * Every recognizer needs to extend from this class.\n\t * @constructor\n\t * @param {Object} options\n\t */\n\tfunction Recognizer(options) {\n\t this.options = assign({}, this.defaults, options || {});\n\t\n\t this.id = uniqueId();\n\t\n\t this.manager = null;\n\t\n\t // default is enable true\n\t this.options.enable = ifUndefined(this.options.enable, true);\n\t\n\t this.state = STATE_POSSIBLE;\n\t\n\t this.simultaneous = {};\n\t this.requireFail = [];\n\t}\n\t\n\tRecognizer.prototype = {\n\t /**\n\t * @virtual\n\t * @type {Object}\n\t */\n\t defaults: {},\n\t\n\t /**\n\t * set options\n\t * @param {Object} options\n\t * @return {Recognizer}\n\t */\n\t set: function(options) {\n\t assign(this.options, options);\n\t\n\t // also update the touchAction, in case something changed about the directions/enabled state\n\t this.manager && this.manager.touchAction.update();\n\t return this;\n\t },\n\t\n\t /**\n\t * recognize simultaneous with an other recognizer.\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t recognizeWith: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {\n\t return this;\n\t }\n\t\n\t var simultaneous = this.simultaneous;\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t if (!simultaneous[otherRecognizer.id]) {\n\t simultaneous[otherRecognizer.id] = otherRecognizer;\n\t otherRecognizer.recognizeWith(this);\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * drop the simultaneous link. it doesnt remove the link on the other recognizer.\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t dropRecognizeWith: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {\n\t return this;\n\t }\n\t\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t delete this.simultaneous[otherRecognizer.id];\n\t return this;\n\t },\n\t\n\t /**\n\t * recognizer can only run when an other is failing\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t requireFailure: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {\n\t return this;\n\t }\n\t\n\t var requireFail = this.requireFail;\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t if (inArray(requireFail, otherRecognizer) === -1) {\n\t requireFail.push(otherRecognizer);\n\t otherRecognizer.requireFailure(this);\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * drop the requireFailure link. it does not remove the link on the other recognizer.\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t dropRequireFailure: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {\n\t return this;\n\t }\n\t\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t var index = inArray(this.requireFail, otherRecognizer);\n\t if (index > -1) {\n\t this.requireFail.splice(index, 1);\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * has require failures boolean\n\t * @returns {boolean}\n\t */\n\t hasRequireFailures: function() {\n\t return this.requireFail.length > 0;\n\t },\n\t\n\t /**\n\t * if the recognizer can recognize simultaneous with an other recognizer\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Boolean}\n\t */\n\t canRecognizeWith: function(otherRecognizer) {\n\t return !!this.simultaneous[otherRecognizer.id];\n\t },\n\t\n\t /**\n\t * You should use `tryEmit` instead of `emit` directly to check\n\t * that all the needed recognizers has failed before emitting.\n\t * @param {Object} input\n\t */\n\t emit: function(input) {\n\t var self = this;\n\t var state = this.state;\n\t\n\t function emit(event) {\n\t self.manager.emit(event, input);\n\t }\n\t\n\t // 'panstart' and 'panmove'\n\t if (state < STATE_ENDED) {\n\t emit(self.options.event + stateStr(state));\n\t }\n\t\n\t emit(self.options.event); // simple 'eventName' events\n\t\n\t if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)\n\t emit(input.additionalEvent);\n\t }\n\t\n\t // panend and pancancel\n\t if (state >= STATE_ENDED) {\n\t emit(self.options.event + stateStr(state));\n\t }\n\t },\n\t\n\t /**\n\t * Check that all the require failure recognizers has failed,\n\t * if true, it emits a gesture event,\n\t * otherwise, setup the state to FAILED.\n\t * @param {Object} input\n\t */\n\t tryEmit: function(input) {\n\t if (this.canEmit()) {\n\t return this.emit(input);\n\t }\n\t // it's failing anyway\n\t this.state = STATE_FAILED;\n\t },\n\t\n\t /**\n\t * can we emit?\n\t * @returns {boolean}\n\t */\n\t canEmit: function() {\n\t var i = 0;\n\t while (i < this.requireFail.length) {\n\t if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {\n\t return false;\n\t }\n\t i++;\n\t }\n\t return true;\n\t },\n\t\n\t /**\n\t * update the recognizer\n\t * @param {Object} inputData\n\t */\n\t recognize: function(inputData) {\n\t // make a new copy of the inputData\n\t // so we can change the inputData without messing up the other recognizers\n\t var inputDataClone = assign({}, inputData);\n\t\n\t // is is enabled and allow recognizing?\n\t if (!boolOrFn(this.options.enable, [this, inputDataClone])) {\n\t this.reset();\n\t this.state = STATE_FAILED;\n\t return;\n\t }\n\t\n\t // reset when we've reached the end\n\t if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {\n\t this.state = STATE_POSSIBLE;\n\t }\n\t\n\t this.state = this.process(inputDataClone);\n\t\n\t // the recognizer has recognized a gesture\n\t // so trigger an event\n\t if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {\n\t this.tryEmit(inputDataClone);\n\t }\n\t },\n\t\n\t /**\n\t * return the state of the recognizer\n\t * the actual recognizing happens in this method\n\t * @virtual\n\t * @param {Object} inputData\n\t * @returns {Const} STATE\n\t */\n\t process: function(inputData) { }, // jshint ignore:line\n\t\n\t /**\n\t * return the preferred touch-action\n\t * @virtual\n\t * @returns {Array}\n\t */\n\t getTouchAction: function() { },\n\t\n\t /**\n\t * called when the gesture isn't allowed to recognize\n\t * like when another is being recognized or it is disabled\n\t * @virtual\n\t */\n\t reset: function() { }\n\t};\n\t\n\t/**\n\t * get a usable string, used as event postfix\n\t * @param {Const} state\n\t * @returns {String} state\n\t */\n\tfunction stateStr(state) {\n\t if (state & STATE_CANCELLED) {\n\t return 'cancel';\n\t } else if (state & STATE_ENDED) {\n\t return 'end';\n\t } else if (state & STATE_CHANGED) {\n\t return 'move';\n\t } else if (state & STATE_BEGAN) {\n\t return 'start';\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * direction cons to string\n\t * @param {Const} direction\n\t * @returns {String}\n\t */\n\tfunction directionStr(direction) {\n\t if (direction == DIRECTION_DOWN) {\n\t return 'down';\n\t } else if (direction == DIRECTION_UP) {\n\t return 'up';\n\t } else if (direction == DIRECTION_LEFT) {\n\t return 'left';\n\t } else if (direction == DIRECTION_RIGHT) {\n\t return 'right';\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * get a recognizer by name if it is bound to a manager\n\t * @param {Recognizer|String} otherRecognizer\n\t * @param {Recognizer} recognizer\n\t * @returns {Recognizer}\n\t */\n\tfunction getRecognizerByNameIfManager(otherRecognizer, recognizer) {\n\t var manager = recognizer.manager;\n\t if (manager) {\n\t return manager.get(otherRecognizer);\n\t }\n\t return otherRecognizer;\n\t}\n\t\n\t/**\n\t * This recognizer is just used as a base for the simple attribute recognizers.\n\t * @constructor\n\t * @extends Recognizer\n\t */\n\tfunction AttrRecognizer() {\n\t Recognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(AttrRecognizer, Recognizer, {\n\t /**\n\t * @namespace\n\t * @memberof AttrRecognizer\n\t */\n\t defaults: {\n\t /**\n\t * @type {Number}\n\t * @default 1\n\t */\n\t pointers: 1\n\t },\n\t\n\t /**\n\t * Used to check if it the recognizer receives valid input, like input.distance > 10.\n\t * @memberof AttrRecognizer\n\t * @param {Object} input\n\t * @returns {Boolean} recognized\n\t */\n\t attrTest: function(input) {\n\t var optionPointers = this.options.pointers;\n\t return optionPointers === 0 || input.pointers.length === optionPointers;\n\t },\n\t\n\t /**\n\t * Process the input and return the state for the recognizer\n\t * @memberof AttrRecognizer\n\t * @param {Object} input\n\t * @returns {*} State\n\t */\n\t process: function(input) {\n\t var state = this.state;\n\t var eventType = input.eventType;\n\t\n\t var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);\n\t var isValid = this.attrTest(input);\n\t\n\t // on cancel input and we've recognized before, return STATE_CANCELLED\n\t if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {\n\t return state | STATE_CANCELLED;\n\t } else if (isRecognized || isValid) {\n\t if (eventType & INPUT_END) {\n\t return state | STATE_ENDED;\n\t } else if (!(state & STATE_BEGAN)) {\n\t return STATE_BEGAN;\n\t }\n\t return state | STATE_CHANGED;\n\t }\n\t return STATE_FAILED;\n\t }\n\t});\n\t\n\t/**\n\t * Pan\n\t * Recognized when the pointer is down and moved in the allowed direction.\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction PanRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t\n\t this.pX = null;\n\t this.pY = null;\n\t}\n\t\n\tinherit(PanRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PanRecognizer\n\t */\n\t defaults: {\n\t event: 'pan',\n\t threshold: 10,\n\t pointers: 1,\n\t direction: DIRECTION_ALL\n\t },\n\t\n\t getTouchAction: function() {\n\t var direction = this.options.direction;\n\t var actions = [];\n\t if (direction & DIRECTION_HORIZONTAL) {\n\t actions.push(TOUCH_ACTION_PAN_Y);\n\t }\n\t if (direction & DIRECTION_VERTICAL) {\n\t actions.push(TOUCH_ACTION_PAN_X);\n\t }\n\t return actions;\n\t },\n\t\n\t directionTest: function(input) {\n\t var options = this.options;\n\t var hasMoved = true;\n\t var distance = input.distance;\n\t var direction = input.direction;\n\t var x = input.deltaX;\n\t var y = input.deltaY;\n\t\n\t // lock to axis?\n\t if (!(direction & options.direction)) {\n\t if (options.direction & DIRECTION_HORIZONTAL) {\n\t direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;\n\t hasMoved = x != this.pX;\n\t distance = Math.abs(input.deltaX);\n\t } else {\n\t direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;\n\t hasMoved = y != this.pY;\n\t distance = Math.abs(input.deltaY);\n\t }\n\t }\n\t input.direction = direction;\n\t return hasMoved && distance > options.threshold && direction & options.direction;\n\t },\n\t\n\t attrTest: function(input) {\n\t return AttrRecognizer.prototype.attrTest.call(this, input) &&\n\t (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));\n\t },\n\t\n\t emit: function(input) {\n\t\n\t this.pX = input.deltaX;\n\t this.pY = input.deltaY;\n\t\n\t var direction = directionStr(input.direction);\n\t\n\t if (direction) {\n\t input.additionalEvent = this.options.event + direction;\n\t }\n\t this._super.emit.call(this, input);\n\t }\n\t});\n\t\n\t/**\n\t * Pinch\n\t * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction PinchRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(PinchRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PinchRecognizer\n\t */\n\t defaults: {\n\t event: 'pinch',\n\t threshold: 0,\n\t pointers: 2\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_NONE];\n\t },\n\t\n\t attrTest: function(input) {\n\t return this._super.attrTest.call(this, input) &&\n\t (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);\n\t },\n\t\n\t emit: function(input) {\n\t if (input.scale !== 1) {\n\t var inOut = input.scale < 1 ? 'in' : 'out';\n\t input.additionalEvent = this.options.event + inOut;\n\t }\n\t this._super.emit.call(this, input);\n\t }\n\t});\n\t\n\t/**\n\t * Press\n\t * Recognized when the pointer is down for x ms without any movement.\n\t * @constructor\n\t * @extends Recognizer\n\t */\n\tfunction PressRecognizer() {\n\t Recognizer.apply(this, arguments);\n\t\n\t this._timer = null;\n\t this._input = null;\n\t}\n\t\n\tinherit(PressRecognizer, Recognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PressRecognizer\n\t */\n\t defaults: {\n\t event: 'press',\n\t pointers: 1,\n\t time: 251, // minimal time of the pointer to be pressed\n\t threshold: 9 // a minimal movement is ok, but keep it low\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_AUTO];\n\t },\n\t\n\t process: function(input) {\n\t var options = this.options;\n\t var validPointers = input.pointers.length === options.pointers;\n\t var validMovement = input.distance < options.threshold;\n\t var validTime = input.deltaTime > options.time;\n\t\n\t this._input = input;\n\t\n\t // we only allow little movement\n\t // and we've reached an end event, so a tap is possible\n\t if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {\n\t this.reset();\n\t } else if (input.eventType & INPUT_START) {\n\t this.reset();\n\t this._timer = setTimeoutContext(function() {\n\t this.state = STATE_RECOGNIZED;\n\t this.tryEmit();\n\t }, options.time, this);\n\t } else if (input.eventType & INPUT_END) {\n\t return STATE_RECOGNIZED;\n\t }\n\t return STATE_FAILED;\n\t },\n\t\n\t reset: function() {\n\t clearTimeout(this._timer);\n\t },\n\t\n\t emit: function(input) {\n\t if (this.state !== STATE_RECOGNIZED) {\n\t return;\n\t }\n\t\n\t if (input && (input.eventType & INPUT_END)) {\n\t this.manager.emit(this.options.event + 'up', input);\n\t } else {\n\t this._input.timeStamp = now();\n\t this.manager.emit(this.options.event, this._input);\n\t }\n\t }\n\t});\n\t\n\t/**\n\t * Rotate\n\t * Recognized when two or more pointer are moving in a circular motion.\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction RotateRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(RotateRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof RotateRecognizer\n\t */\n\t defaults: {\n\t event: 'rotate',\n\t threshold: 0,\n\t pointers: 2\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_NONE];\n\t },\n\t\n\t attrTest: function(input) {\n\t return this._super.attrTest.call(this, input) &&\n\t (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);\n\t }\n\t});\n\t\n\t/**\n\t * Swipe\n\t * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction SwipeRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(SwipeRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof SwipeRecognizer\n\t */\n\t defaults: {\n\t event: 'swipe',\n\t threshold: 10,\n\t velocity: 0.3,\n\t direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,\n\t pointers: 1\n\t },\n\t\n\t getTouchAction: function() {\n\t return PanRecognizer.prototype.getTouchAction.call(this);\n\t },\n\t\n\t attrTest: function(input) {\n\t var direction = this.options.direction;\n\t var velocity;\n\t\n\t if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {\n\t velocity = input.overallVelocity;\n\t } else if (direction & DIRECTION_HORIZONTAL) {\n\t velocity = input.overallVelocityX;\n\t } else if (direction & DIRECTION_VERTICAL) {\n\t velocity = input.overallVelocityY;\n\t }\n\t\n\t return this._super.attrTest.call(this, input) &&\n\t direction & input.offsetDirection &&\n\t input.distance > this.options.threshold &&\n\t input.maxPointers == this.options.pointers &&\n\t abs(velocity) > this.options.velocity && input.eventType & INPUT_END;\n\t },\n\t\n\t emit: function(input) {\n\t var direction = directionStr(input.offsetDirection);\n\t if (direction) {\n\t this.manager.emit(this.options.event + direction, input);\n\t }\n\t\n\t this.manager.emit(this.options.event, input);\n\t }\n\t});\n\t\n\t/**\n\t * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur\n\t * between the given interval and position. The delay option can be used to recognize multi-taps without firing\n\t * a single tap.\n\t *\n\t * The eventData from the emitted event contains the property `tapCount`, which contains the amount of\n\t * multi-taps being recognized.\n\t * @constructor\n\t * @extends Recognizer\n\t */\n\tfunction TapRecognizer() {\n\t Recognizer.apply(this, arguments);\n\t\n\t // previous time and center,\n\t // used for tap counting\n\t this.pTime = false;\n\t this.pCenter = false;\n\t\n\t this._timer = null;\n\t this._input = null;\n\t this.count = 0;\n\t}\n\t\n\tinherit(TapRecognizer, Recognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PinchRecognizer\n\t */\n\t defaults: {\n\t event: 'tap',\n\t pointers: 1,\n\t taps: 1,\n\t interval: 300, // max time between the multi-tap taps\n\t time: 250, // max time of the pointer to be down (like finger on the screen)\n\t threshold: 9, // a minimal movement is ok, but keep it low\n\t posThreshold: 10 // a multi-tap can be a bit off the initial position\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_MANIPULATION];\n\t },\n\t\n\t process: function(input) {\n\t var options = this.options;\n\t\n\t var validPointers = input.pointers.length === options.pointers;\n\t var validMovement = input.distance < options.threshold;\n\t var validTouchTime = input.deltaTime < options.time;\n\t\n\t this.reset();\n\t\n\t if ((input.eventType & INPUT_START) && (this.count === 0)) {\n\t return this.failTimeout();\n\t }\n\t\n\t // we only allow little movement\n\t // and we've reached an end event, so a tap is possible\n\t if (validMovement && validTouchTime && validPointers) {\n\t if (input.eventType != INPUT_END) {\n\t return this.failTimeout();\n\t }\n\t\n\t var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;\n\t var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;\n\t\n\t this.pTime = input.timeStamp;\n\t this.pCenter = input.center;\n\t\n\t if (!validMultiTap || !validInterval) {\n\t this.count = 1;\n\t } else {\n\t this.count += 1;\n\t }\n\t\n\t this._input = input;\n\t\n\t // if tap count matches we have recognized it,\n\t // else it has began recognizing...\n\t var tapCount = this.count % options.taps;\n\t if (tapCount === 0) {\n\t // no failing requirements, immediately trigger the tap event\n\t // or wait as long as the multitap interval to trigger\n\t if (!this.hasRequireFailures()) {\n\t return STATE_RECOGNIZED;\n\t } else {\n\t this._timer = setTimeoutContext(function() {\n\t this.state = STATE_RECOGNIZED;\n\t this.tryEmit();\n\t }, options.interval, this);\n\t return STATE_BEGAN;\n\t }\n\t }\n\t }\n\t return STATE_FAILED;\n\t },\n\t\n\t failTimeout: function() {\n\t this._timer = setTimeoutContext(function() {\n\t this.state = STATE_FAILED;\n\t }, this.options.interval, this);\n\t return STATE_FAILED;\n\t },\n\t\n\t reset: function() {\n\t clearTimeout(this._timer);\n\t },\n\t\n\t emit: function() {\n\t if (this.state == STATE_RECOGNIZED) {\n\t this._input.tapCount = this.count;\n\t this.manager.emit(this.options.event, this._input);\n\t }\n\t }\n\t});\n\t\n\t/**\n\t * Simple way to create a manager with a default set of recognizers.\n\t * @param {HTMLElement} element\n\t * @param {Object} [options]\n\t * @constructor\n\t */\n\tfunction Hammer(element, options) {\n\t options = options || {};\n\t options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);\n\t return new Manager(element, options);\n\t}\n\t\n\t/**\n\t * @const {string}\n\t */\n\tHammer.VERSION = '2.0.7';\n\t\n\t/**\n\t * default settings\n\t * @namespace\n\t */\n\tHammer.defaults = {\n\t /**\n\t * set if DOM events are being triggered.\n\t * But this is slower and unused by simple implementations, so disabled by default.\n\t * @type {Boolean}\n\t * @default false\n\t */\n\t domEvents: false,\n\t\n\t /**\n\t * The value for the touchAction property/fallback.\n\t * When set to `compute` it will magically set the correct value based on the added recognizers.\n\t * @type {String}\n\t * @default compute\n\t */\n\t touchAction: TOUCH_ACTION_COMPUTE,\n\t\n\t /**\n\t * @type {Boolean}\n\t * @default true\n\t */\n\t enable: true,\n\t\n\t /**\n\t * EXPERIMENTAL FEATURE -- can be removed/changed\n\t * Change the parent input target element.\n\t * If Null, then it is being set the to main element.\n\t * @type {Null|EventTarget}\n\t * @default null\n\t */\n\t inputTarget: null,\n\t\n\t /**\n\t * force an input class\n\t * @type {Null|Function}\n\t * @default null\n\t */\n\t inputClass: null,\n\t\n\t /**\n\t * Default recognizer setup when calling `Hammer()`\n\t * When creating a new Manager these will be skipped.\n\t * @type {Array}\n\t */\n\t preset: [\n\t // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]\n\t [RotateRecognizer, {enable: false}],\n\t [PinchRecognizer, {enable: false}, ['rotate']],\n\t [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],\n\t [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],\n\t [TapRecognizer],\n\t [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],\n\t [PressRecognizer]\n\t ],\n\t\n\t /**\n\t * Some CSS properties can be used to improve the working of Hammer.\n\t * Add them to this method and they will be set when creating a new Manager.\n\t * @namespace\n\t */\n\t cssProps: {\n\t /**\n\t * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t userSelect: 'none',\n\t\n\t /**\n\t * Disable the Windows Phone grippers when pressing an element.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t touchSelect: 'none',\n\t\n\t /**\n\t * Disables the default callout shown when you touch and hold a touch target.\n\t * On iOS, when you touch and hold a touch target such as a link, Safari displays\n\t * a callout containing information about the link. This property allows you to disable that callout.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t touchCallout: 'none',\n\t\n\t /**\n\t * Specifies whether zooming is enabled. Used by IE10>\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t contentZooming: 'none',\n\t\n\t /**\n\t * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t userDrag: 'none',\n\t\n\t /**\n\t * Overrides the highlight color shown when the user taps a link or a JavaScript\n\t * clickable element in iOS. This property obeys the alpha value, if specified.\n\t * @type {String}\n\t * @default 'rgba(0,0,0,0)'\n\t */\n\t tapHighlightColor: 'rgba(0,0,0,0)'\n\t }\n\t};\n\t\n\tvar STOP = 1;\n\tvar FORCED_STOP = 2;\n\t\n\t/**\n\t * Manager\n\t * @param {HTMLElement} element\n\t * @param {Object} [options]\n\t * @constructor\n\t */\n\tfunction Manager(element, options) {\n\t this.options = assign({}, Hammer.defaults, options || {});\n\t\n\t this.options.inputTarget = this.options.inputTarget || element;\n\t\n\t this.handlers = {};\n\t this.session = {};\n\t this.recognizers = [];\n\t this.oldCssProps = {};\n\t\n\t this.element = element;\n\t this.input = createInputInstance(this);\n\t this.touchAction = new TouchAction(this, this.options.touchAction);\n\t\n\t toggleCssProps(this, true);\n\t\n\t each(this.options.recognizers, function(item) {\n\t var recognizer = this.add(new (item[0])(item[1]));\n\t item[2] && recognizer.recognizeWith(item[2]);\n\t item[3] && recognizer.requireFailure(item[3]);\n\t }, this);\n\t}\n\t\n\tManager.prototype = {\n\t /**\n\t * set options\n\t * @param {Object} options\n\t * @returns {Manager}\n\t */\n\t set: function(options) {\n\t assign(this.options, options);\n\t\n\t // Options that need a little more setup\n\t if (options.touchAction) {\n\t this.touchAction.update();\n\t }\n\t if (options.inputTarget) {\n\t // Clean up existing event listeners and reinitialize\n\t this.input.destroy();\n\t this.input.target = options.inputTarget;\n\t this.input.init();\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * stop recognizing for this session.\n\t * This session will be discarded, when a new [input]start event is fired.\n\t * When forced, the recognizer cycle is stopped immediately.\n\t * @param {Boolean} [force]\n\t */\n\t stop: function(force) {\n\t this.session.stopped = force ? FORCED_STOP : STOP;\n\t },\n\t\n\t /**\n\t * run the recognizers!\n\t * called by the inputHandler function on every movement of the pointers (touches)\n\t * it walks through all the recognizers and tries to detect the gesture that is being made\n\t * @param {Object} inputData\n\t */\n\t recognize: function(inputData) {\n\t var session = this.session;\n\t if (session.stopped) {\n\t return;\n\t }\n\t\n\t // run the touch-action polyfill\n\t this.touchAction.preventDefaults(inputData);\n\t\n\t var recognizer;\n\t var recognizers = this.recognizers;\n\t\n\t // this holds the recognizer that is being recognized.\n\t // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED\n\t // if no recognizer is detecting a thing, it is set to `null`\n\t var curRecognizer = session.curRecognizer;\n\t\n\t // reset when the last recognizer is recognized\n\t // or when we're in a new session\n\t if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {\n\t curRecognizer = session.curRecognizer = null;\n\t }\n\t\n\t var i = 0;\n\t while (i < recognizers.length) {\n\t recognizer = recognizers[i];\n\t\n\t // find out if we are allowed try to recognize the input for this one.\n\t // 1. allow if the session is NOT forced stopped (see the .stop() method)\n\t // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one\n\t // that is being recognized.\n\t // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.\n\t // this can be setup with the `recognizeWith()` method on the recognizer.\n\t if (session.stopped !== FORCED_STOP && ( // 1\n\t !curRecognizer || recognizer == curRecognizer || // 2\n\t recognizer.canRecognizeWith(curRecognizer))) { // 3\n\t recognizer.recognize(inputData);\n\t } else {\n\t recognizer.reset();\n\t }\n\t\n\t // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the\n\t // current active recognizer. but only if we don't already have an active recognizer\n\t if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {\n\t curRecognizer = session.curRecognizer = recognizer;\n\t }\n\t i++;\n\t }\n\t },\n\t\n\t /**\n\t * get a recognizer by its event name.\n\t * @param {Recognizer|String} recognizer\n\t * @returns {Recognizer|Null}\n\t */\n\t get: function(recognizer) {\n\t if (recognizer instanceof Recognizer) {\n\t return recognizer;\n\t }\n\t\n\t var recognizers = this.recognizers;\n\t for (var i = 0; i < recognizers.length; i++) {\n\t if (recognizers[i].options.event == recognizer) {\n\t return recognizers[i];\n\t }\n\t }\n\t return null;\n\t },\n\t\n\t /**\n\t * add a recognizer to the manager\n\t * existing recognizers with the same event name will be removed\n\t * @param {Recognizer} recognizer\n\t * @returns {Recognizer|Manager}\n\t */\n\t add: function(recognizer) {\n\t if (invokeArrayArg(recognizer, 'add', this)) {\n\t return this;\n\t }\n\t\n\t // remove existing\n\t var existing = this.get(recognizer.options.event);\n\t if (existing) {\n\t this.remove(existing);\n\t }\n\t\n\t this.recognizers.push(recognizer);\n\t recognizer.manager = this;\n\t\n\t this.touchAction.update();\n\t return recognizer;\n\t },\n\t\n\t /**\n\t * remove a recognizer by name or instance\n\t * @param {Recognizer|String} recognizer\n\t * @returns {Manager}\n\t */\n\t remove: function(recognizer) {\n\t if (invokeArrayArg(recognizer, 'remove', this)) {\n\t return this;\n\t }\n\t\n\t recognizer = this.get(recognizer);\n\t\n\t // let's make sure this recognizer exists\n\t if (recognizer) {\n\t var recognizers = this.recognizers;\n\t var index = inArray(recognizers, recognizer);\n\t\n\t if (index !== -1) {\n\t recognizers.splice(index, 1);\n\t this.touchAction.update();\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /**\n\t * bind event\n\t * @param {String} events\n\t * @param {Function} handler\n\t * @returns {EventEmitter} this\n\t */\n\t on: function(events, handler) {\n\t if (events === undefined) {\n\t return;\n\t }\n\t if (handler === undefined) {\n\t return;\n\t }\n\t\n\t var handlers = this.handlers;\n\t each(splitStr(events), function(event) {\n\t handlers[event] = handlers[event] || [];\n\t handlers[event].push(handler);\n\t });\n\t return this;\n\t },\n\t\n\t /**\n\t * unbind event, leave emit blank to remove all handlers\n\t * @param {String} events\n\t * @param {Function} [handler]\n\t * @returns {EventEmitter} this\n\t */\n\t off: function(events, handler) {\n\t if (events === undefined) {\n\t return;\n\t }\n\t\n\t var handlers = this.handlers;\n\t each(splitStr(events), function(event) {\n\t if (!handler) {\n\t delete handlers[event];\n\t } else {\n\t handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);\n\t }\n\t });\n\t return this;\n\t },\n\t\n\t /**\n\t * emit event to the listeners\n\t * @param {String} event\n\t * @param {Object} data\n\t */\n\t emit: function(event, data) {\n\t // we also want to trigger dom events\n\t if (this.options.domEvents) {\n\t triggerDomEvent(event, data);\n\t }\n\t\n\t // no handlers, so skip it all\n\t var handlers = this.handlers[event] && this.handlers[event].slice();\n\t if (!handlers || !handlers.length) {\n\t return;\n\t }\n\t\n\t data.type = event;\n\t data.preventDefault = function() {\n\t data.srcEvent.preventDefault();\n\t };\n\t\n\t var i = 0;\n\t while (i < handlers.length) {\n\t handlers[i](data);\n\t i++;\n\t }\n\t },\n\t\n\t /**\n\t * destroy the manager and unbinds all events\n\t * it doesn't unbind dom events, that is the user own responsibility\n\t */\n\t destroy: function() {\n\t this.element && toggleCssProps(this, false);\n\t\n\t this.handlers = {};\n\t this.session = {};\n\t this.input.destroy();\n\t this.element = null;\n\t }\n\t};\n\t\n\t/**\n\t * add/remove the css properties as defined in manager.options.cssProps\n\t * @param {Manager} manager\n\t * @param {Boolean} add\n\t */\n\tfunction toggleCssProps(manager, add) {\n\t var element = manager.element;\n\t if (!element.style) {\n\t return;\n\t }\n\t var prop;\n\t each(manager.options.cssProps, function(value, name) {\n\t prop = prefixed(element.style, name);\n\t if (add) {\n\t manager.oldCssProps[prop] = element.style[prop];\n\t element.style[prop] = value;\n\t } else {\n\t element.style[prop] = manager.oldCssProps[prop] || '';\n\t }\n\t });\n\t if (!add) {\n\t manager.oldCssProps = {};\n\t }\n\t}\n\t\n\t/**\n\t * trigger dom event\n\t * @param {String} event\n\t * @param {Object} data\n\t */\n\tfunction triggerDomEvent(event, data) {\n\t var gestureEvent = document.createEvent('Event');\n\t gestureEvent.initEvent(event, true, true);\n\t gestureEvent.gesture = data;\n\t data.target.dispatchEvent(gestureEvent);\n\t}\n\t\n\tassign(Hammer, {\n\t INPUT_START: INPUT_START,\n\t INPUT_MOVE: INPUT_MOVE,\n\t INPUT_END: INPUT_END,\n\t INPUT_CANCEL: INPUT_CANCEL,\n\t\n\t STATE_POSSIBLE: STATE_POSSIBLE,\n\t STATE_BEGAN: STATE_BEGAN,\n\t STATE_CHANGED: STATE_CHANGED,\n\t STATE_ENDED: STATE_ENDED,\n\t STATE_RECOGNIZED: STATE_RECOGNIZED,\n\t STATE_CANCELLED: STATE_CANCELLED,\n\t STATE_FAILED: STATE_FAILED,\n\t\n\t DIRECTION_NONE: DIRECTION_NONE,\n\t DIRECTION_LEFT: DIRECTION_LEFT,\n\t DIRECTION_RIGHT: DIRECTION_RIGHT,\n\t DIRECTION_UP: DIRECTION_UP,\n\t DIRECTION_DOWN: DIRECTION_DOWN,\n\t DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,\n\t DIRECTION_VERTICAL: DIRECTION_VERTICAL,\n\t DIRECTION_ALL: DIRECTION_ALL,\n\t\n\t Manager: Manager,\n\t Input: Input,\n\t TouchAction: TouchAction,\n\t\n\t TouchInput: TouchInput,\n\t MouseInput: MouseInput,\n\t PointerEventInput: PointerEventInput,\n\t TouchMouseInput: TouchMouseInput,\n\t SingleTouchInput: SingleTouchInput,\n\t\n\t Recognizer: Recognizer,\n\t AttrRecognizer: AttrRecognizer,\n\t Tap: TapRecognizer,\n\t Pan: PanRecognizer,\n\t Swipe: SwipeRecognizer,\n\t Pinch: PinchRecognizer,\n\t Rotate: RotateRecognizer,\n\t Press: PressRecognizer,\n\t\n\t on: addEventListeners,\n\t off: removeEventListeners,\n\t each: each,\n\t merge: merge,\n\t extend: extend,\n\t assign: assign,\n\t inherit: inherit,\n\t bindFn: bindFn,\n\t prefixed: prefixed\n\t});\n\t\n\t// this prevents errors when Hammer is loaded in the presence of an AMD\n\t// style loader but by script tag, not by the loader.\n\tvar freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line\n\tfreeGlobal.Hammer = Hammer;\n\t\n\tif (true) {\n\t !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {\n\t return Hammer;\n\t }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else if (typeof module != 'undefined' && module.exports) {\n\t module.exports = Hammer;\n\t} else {\n\t window[exportName] = Hammer;\n\t}\n\t\n\t})(window, document, 'Hammer');\n\n\n/***/ },\n/* 41 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_41__;\n\n/***/ },\n/* 42 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _TileLayer2 = __webpack_require__(43);\n\t\n\tvar _TileLayer3 = _interopRequireDefault(_TileLayer2);\n\t\n\tvar _ImageTile = __webpack_require__(53);\n\t\n\tvar _ImageTile2 = _interopRequireDefault(_ImageTile);\n\t\n\tvar _ImageTileLayerBaseMaterial = __webpack_require__(56);\n\t\n\tvar _ImageTileLayerBaseMaterial2 = _interopRequireDefault(_ImageTileLayerBaseMaterial);\n\t\n\tvar _lodashThrottle = __webpack_require__(35);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// DONE: Find a way to avoid the flashing caused by the gap between old tiles\n\t// being removed and the new tiles being ready for display\n\t//\n\t// DONE: Simplest first step for MVP would be to give each tile mesh the colour\n\t// of the basemap ground so it blends in a little more, or have a huge ground\n\t// plane underneath all the tiles that shows through between tile updates.\n\t//\n\t// Could keep the old tiles around until the new ones are ready, though they'd\n\t// probably need to be layered in a way so the old tiles don't overlap new ones,\n\t// which is similar to how Leaflet approaches this (it has 2 layers)\n\t//\n\t// Could keep the tile from the previous quadtree level visible until all 4\n\t// tiles at the new / current level have finished loading and are displayed.\n\t// Perhaps by keeping a map of tiles by quadcode and a boolean for each of the\n\t// child quadcodes showing whether they are loaded and in view. If all true then\n\t// remove the parent tile, otherwise keep it on a lower layer.\n\t\n\t// TODO: Load and display a base layer separate to the LOD grid that is at a low\n\t// resolution – used as a backup / background to fill in empty areas / distance\n\t\n\t// DONE: Fix the issue where some tiles just don't load, or at least the texture\n\t// never shows up – tends to happen if you quickly zoom in / out past it while\n\t// it's still loading, leaving a blank space\n\t\n\t// TODO: Optimise the request of many image tiles – look at how Leaflet and\n\t// OpenWebGlobe approach this (eg. batching, queues, etc)\n\t\n\t// TODO: Cancel pending tile requests if they get removed from view before they\n\t// reach a ready state (eg. cancel image requests, etc). Need to ensure that the\n\t// images are re-requested when the tile is next in scene (even if from cache)\n\t\n\t// TODO: Consider not performing an LOD calculation on every frame, instead only\n\t// on move end so panning, orbiting and zooming stays smooth. Otherwise it's\n\t// possible for performance to tank if you pan, orbit or zoom rapidly while all\n\t// the LOD calculations are being made and new tiles requested.\n\t//\n\t// Pending tiles should continue to be requested and output to the scene on each\n\t// frame, but no new LOD calculations should be made.\n\t\n\t// This tile layer both updates the quadtree and outputs tiles on every frame\n\t// (throttled to some amount)\n\t//\n\t// This is because the computational complexity of image tiles is generally low\n\t// and so there isn't much jank when running these calculations and outputs in\n\t// realtime\n\t//\n\t// The benefit to doing this is that the underlying map layer continues to\n\t// refresh and update during movement, which is an arguably better experience\n\t\n\tvar ImageTileLayer = (function (_TileLayer) {\n\t _inherits(ImageTileLayer, _TileLayer);\n\t\n\t function ImageTileLayer(path, options) {\n\t _classCallCheck(this, ImageTileLayer);\n\t\n\t var defaults = {\n\t distance: 300000\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(ImageTileLayer.prototype), 'constructor', this).call(this, options);\n\t\n\t this._path = path;\n\t }\n\t\n\t _createClass(ImageTileLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _get(Object.getPrototypeOf(ImageTileLayer.prototype), '_onAdd', _this).call(_this, world).then(function () {\n\t // Add base layer\n\t var geom = new _three2['default'].PlaneBufferGeometry(2000000, 2000000, 1);\n\t\n\t var baseMaterial;\n\t if (_this._world._environment._skybox) {\n\t baseMaterial = (0, _ImageTileLayerBaseMaterial2['default'])('#f5f5f3', _this._world._environment._skybox.getRenderTarget());\n\t } else {\n\t baseMaterial = (0, _ImageTileLayerBaseMaterial2['default'])('#f5f5f3');\n\t }\n\t\n\t var mesh = new _three2['default'].Mesh(geom, baseMaterial);\n\t mesh.renderOrder = 0;\n\t mesh.rotation.x = -90 * Math.PI / 180;\n\t\n\t // TODO: It might be overkill to receive a shadow on the base layer as it's\n\t // rarely seen (good to have if performance difference is negligible)\n\t mesh.receiveShadow = true;\n\t\n\t _this._baseLayer = mesh;\n\t _this.add(mesh);\n\t\n\t // Trigger initial quadtree calculation on the next frame\n\t //\n\t // TODO: This is a hack to ensure the camera is all set up - a better\n\t // solution should be found\n\t setTimeout(function () {\n\t _this._calculateLOD();\n\t _this._initEvents();\n\t }, 0);\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t // Run LOD calculations based on render calls\n\t //\n\t // Throttled to 1 LOD calculation per 100ms\n\t this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._onWorldUpdate, 100);\n\t\n\t this._world.on('preUpdate', this._throttledWorldUpdate, this);\n\t this._world.on('move', this._onWorldMove, this);\n\t }\n\t }, {\n\t key: '_onWorldUpdate',\n\t value: function _onWorldUpdate() {\n\t this._calculateLOD();\n\t this._outputTiles();\n\t }\n\t }, {\n\t key: '_onWorldMove',\n\t value: function _onWorldMove(latlon, point) {\n\t this._moveBaseLayer(point);\n\t }\n\t }, {\n\t key: '_moveBaseLayer',\n\t value: function _moveBaseLayer(point) {\n\t this._baseLayer.position.x = point.x;\n\t this._baseLayer.position.z = point.y;\n\t }\n\t }, {\n\t key: '_createTile',\n\t value: function _createTile(quadcode, layer) {\n\t return new _ImageTile2['default'](quadcode, this._path, layer);\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._world.off('preUpdate', this._throttledWorldUpdate);\n\t this._world.off('move', this._onWorldMove);\n\t\n\t this._throttledWorldUpdate = null;\n\t\n\t // Dispose of mesh and materials\n\t this._baseLayer.geometry.dispose();\n\t this._baseLayer.geometry = null;\n\t\n\t if (this._baseLayer.material.map) {\n\t this._baseLayer.material.map.dispose();\n\t this._baseLayer.material.map = null;\n\t }\n\t\n\t this._baseLayer.material.dispose();\n\t this._baseLayer.material = null;\n\t\n\t this._baseLayer = null;\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(ImageTileLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return ImageTileLayer;\n\t})(_TileLayer3['default']);\n\t\n\texports['default'] = ImageTileLayer;\n\t\n\tvar noNew = function noNew(path, options) {\n\t return new ImageTileLayer(path, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.imageTileLayer = noNew;\n\n/***/ },\n/* 43 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(32);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _TileCache = __webpack_require__(44);\n\t\n\tvar _TileCache2 = _interopRequireDefault(_TileCache);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Consider removing picking from TileLayer instances as there aren't\n\t// (m)any situations where it would be practical\n\t//\n\t// For example, how would you even know what picking IDs to listen to and what\n\t// to do with them?\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Consider keeping a single TileLayer / LOD instance running by default\n\t// that keeps a standard LOD grid for other layers to utilise, rather than\n\t// having to create their own, unique LOD grid and duplicate calculations when\n\t// they're going to use the same grid setup anyway\n\t//\n\t// It still makes sense to be able to have a custom LOD grid for some layers as\n\t// they may want to customise things, maybe not even using a quadtree at all!\n\t//\n\t// Perhaps it makes sense to split out the quadtree stuff into a singleton and\n\t// pass in the necessary parameters each time for the calculation step.\n\t//\n\t// Either way, it seems silly to force layers to have to create a new LOD grid\n\t// each time and create extra, duplicated processing every frame.\n\t\n\t// TODO: Allow passing in of options to define min/max LOD and a distance to use\n\t// for culling tiles beyond that distance.\n\t\n\t// DONE: Prevent tiles from being loaded if they are further than a certain\n\t// distance from the camera and are unlikely to be seen anyway\n\t\n\t// TODO: Avoid performing LOD calculation when it isn't required. For example,\n\t// when nothing has changed since the last frame and there are no tiles to be\n\t// loaded or in need of rendering\n\t\n\t// TODO: Only remove tiles from the layer that aren't to be rendered in the\n\t// current frame – it seems excessive to remove all tiles and re-add them on\n\t// every single frame, even if it's just array manipulation\n\t\n\t// TODO: Fix LOD calculation so min and max LOD can be changed without causing\n\t// problems (eg. making min above 5 causes all sorts of issues)\n\t\n\t// TODO: Reuse THREE objects where possible instead of creating new instances\n\t// on every LOD calculation\n\t\n\t// TODO: Consider not using THREE or LatLon / Point objects in LOD calculations\n\t// to avoid creating unnecessary memory for garbage collection\n\t\n\t// TODO: Prioritise loading of tiles at highest level in the quadtree (those\n\t// closest to the camera) so visual inconsistancies during loading are minimised\n\t\n\tvar TileLayer = (function (_Layer) {\n\t _inherits(TileLayer, _Layer);\n\t\n\t function TileLayer(options) {\n\t var _this = this;\n\t\n\t _classCallCheck(this, TileLayer);\n\t\n\t var defaults = {\n\t picking: false,\n\t maxCache: 1000,\n\t maxLOD: 18\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TileLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._tileCache = new _TileCache2['default'](this._options.maxCache, function (tile) {\n\t _this._destroyTile(tile);\n\t });\n\t\n\t // List of tiles from the previous LOD calculation\n\t this._tileList = [];\n\t\n\t // TODO: Work out why changing the minLOD causes loads of issues\n\t this._minLOD = 3;\n\t this._maxLOD = this._options.maxLOD;\n\t\n\t this._frustum = new _three2['default'].Frustum();\n\t this._tiles = new _three2['default'].Object3D();\n\t this._tilesPicking = new _three2['default'].Object3D();\n\t }\n\t\n\t _createClass(TileLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t this.addToPicking(this._tilesPicking);\n\t this.add(this._tiles);\n\t\n\t return Promise.resolve();\n\t }\n\t }, {\n\t key: '_updateFrustum',\n\t value: function _updateFrustum() {\n\t var camera = this._world.getCamera();\n\t var projScreenMatrix = new _three2['default'].Matrix4();\n\t projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n\t\n\t this._frustum.setFromMatrix(camera.projectionMatrix);\n\t this._frustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n\t }\n\t }, {\n\t key: '_tileInFrustum',\n\t value: function _tileInFrustum(tile) {\n\t var bounds = tile.getBounds();\n\t return this._frustum.intersectsBox(new _three2['default'].Box3(new _three2['default'].Vector3(bounds[0], 0, bounds[3]), new _three2['default'].Vector3(bounds[2], 0, bounds[1])));\n\t }\n\t\n\t // Update and output tiles from the previous LOD checklist\n\t }, {\n\t key: '_outputTiles',\n\t value: function _outputTiles() {\n\t var _this2 = this;\n\t\n\t if (!this._tiles) {\n\t return;\n\t }\n\t\n\t // Remove all tiles from layer\n\t this._removeTiles();\n\t\n\t // Add / re-add tiles\n\t this._tileList.forEach(function (tile) {\n\t // Are the mesh and texture ready?\n\t //\n\t // If yes, continue\n\t // If no, skip\n\t if (!tile.isReady()) {\n\t return;\n\t }\n\t\n\t // Add tile to layer (and to scene) if not already there\n\t _this2._tiles.add(tile.getMesh());\n\t\n\t if (tile.getPickingMesh()) {\n\t _this2._tilesPicking.add(tile.getPickingMesh());\n\t }\n\t });\n\t }\n\t\n\t // Works out tiles in the view frustum and stores them in an array\n\t //\n\t // Does not output the tiles, deferring this to _outputTiles()\n\t }, {\n\t key: '_calculateLOD',\n\t value: function _calculateLOD() {\n\t var _this3 = this;\n\t\n\t if (this._stop || !this._world) {\n\t return;\n\t }\n\t\n\t // var start = performance.now();\n\t\n\t var camera = this._world.getCamera();\n\t\n\t // 1. Update and retrieve camera frustum\n\t this._updateFrustum(this._frustum, camera);\n\t\n\t // 2. Add the four root items of the quadtree to a check list\n\t var checkList = this._checklist;\n\t checkList = [];\n\t checkList.push(this._requestTile('0', this));\n\t checkList.push(this._requestTile('1', this));\n\t checkList.push(this._requestTile('2', this));\n\t checkList.push(this._requestTile('3', this));\n\t\n\t // 3. Call Divide, passing in the check list\n\t this._divide(checkList);\n\t\n\t // // 4. Remove all tiles from layer\n\t //\n\t // Moved to _outputTiles() for now\n\t // this._removeTiles();\n\t\n\t // Order tile-list by zoom so nearest tiles are requested first\n\t checkList.sort(function (a, b) {\n\t return a._quadcode.length < b._quadcode.length;\n\t });\n\t\n\t // 5. Filter the tiles remaining in the check list\n\t this._tileList = checkList.filter(function (tile, index) {\n\t // Skip tile if it's not in the current view frustum\n\t if (!_this3._tileInFrustum(tile)) {\n\t return false;\n\t }\n\t\n\t if (_this3._options.distance && _this3._options.distance > 0) {\n\t // TODO: Can probably speed this up\n\t var center = tile.getCenter();\n\t var dist = new _three2['default'].Vector3(center[0], 0, center[1]).sub(camera.position).length();\n\t\n\t // Manual distance limit to cut down on tiles so far away\n\t if (dist > _this3._options.distance) {\n\t return false;\n\t }\n\t }\n\t\n\t // Does the tile have a mesh?\n\t //\n\t // If yes, continue\n\t // If no, generate tile mesh, request texture and skip\n\t if (!tile.getMesh()) {\n\t tile.requestTileAsync();\n\t }\n\t\n\t return true;\n\t\n\t // Are the mesh and texture ready?\n\t //\n\t // If yes, continue\n\t // If no, skip\n\t // if (!tile.isReady()) {\n\t // return;\n\t // }\n\t //\n\t // // Add tile to layer (and to scene)\n\t // this._tiles.add(tile.getMesh());\n\t });\n\t\n\t // console.log(performance.now() - start);\n\t }\n\t }, {\n\t key: '_divide',\n\t value: function _divide(checkList) {\n\t var count = 0;\n\t var currentItem;\n\t var quadcode;\n\t\n\t // 1. Loop until count equals check list length\n\t while (count != checkList.length) {\n\t currentItem = checkList[count];\n\t quadcode = currentItem.getQuadcode();\n\t\n\t // 2. Increase count and continue loop if quadcode equals max LOD / zoom\n\t if (currentItem.length === this._maxLOD) {\n\t count++;\n\t continue;\n\t }\n\t\n\t // 3. Else, calculate screen-space error metric for quadcode\n\t if (this._screenSpaceError(currentItem)) {\n\t // 4. If error is sufficient...\n\t\n\t // 4a. Remove parent item from the check list\n\t checkList.splice(count, 1);\n\t\n\t // 4b. Add 4 child items to the check list\n\t checkList.push(this._requestTile(quadcode + '0', this));\n\t checkList.push(this._requestTile(quadcode + '1', this));\n\t checkList.push(this._requestTile(quadcode + '2', this));\n\t checkList.push(this._requestTile(quadcode + '3', this));\n\t\n\t // 4d. Continue the loop without increasing count\n\t continue;\n\t } else {\n\t // 5. Else, increase count and continue loop\n\t count++;\n\t }\n\t }\n\t }\n\t }, {\n\t key: '_screenSpaceError',\n\t value: function _screenSpaceError(tile) {\n\t var minDepth = this._minLOD;\n\t var maxDepth = this._maxLOD;\n\t\n\t var quadcode = tile.getQuadcode();\n\t\n\t var camera = this._world.getCamera();\n\t\n\t // Tweak this value to refine specific point that each quad is subdivided\n\t //\n\t // It's used to multiple the dimensions of the tile sides before\n\t // comparing against the tile distance from camera\n\t var quality = 3.0;\n\t\n\t // 1. Return false if quadcode length equals maxDepth (stop dividing)\n\t if (quadcode.length === maxDepth) {\n\t return false;\n\t }\n\t\n\t // 2. Return true if quadcode length is less than minDepth\n\t if (quadcode.length < minDepth) {\n\t return true;\n\t }\n\t\n\t // 3. Return false if quadcode bounds are not in view frustum\n\t if (!this._tileInFrustum(tile)) {\n\t return false;\n\t }\n\t\n\t var center = tile.getCenter();\n\t\n\t // 4. Calculate screen-space error metric\n\t // TODO: Use closest distance to one of the 4 tile corners\n\t var dist = new _three2['default'].Vector3(center[0], 0, center[1]).sub(camera.position).length();\n\t\n\t var error = quality * tile.getSide() / dist;\n\t\n\t // 5. Return true if error is greater than 1.0, else return false\n\t return error > 1.0;\n\t }\n\t }, {\n\t key: '_removeTiles',\n\t value: function _removeTiles() {\n\t if (!this._tiles || !this._tiles.children) {\n\t return;\n\t }\n\t\n\t for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n\t this._tiles.remove(this._tiles.children[i]);\n\t }\n\t\n\t if (!this._tilesPicking || !this._tilesPicking.children) {\n\t return;\n\t }\n\t\n\t for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n\t this._tilesPicking.remove(this._tilesPicking.children[i]);\n\t }\n\t }\n\t\n\t // Return a new tile instance\n\t }, {\n\t key: '_createTile',\n\t value: function _createTile(quadcode, layer) {}\n\t\n\t // Get a cached tile or request a new one if not in cache\n\t }, {\n\t key: '_requestTile',\n\t value: function _requestTile(quadcode, layer) {\n\t var tile = this._tileCache.getTile(quadcode);\n\t\n\t if (!tile) {\n\t // Set up a brand new tile\n\t tile = this._createTile(quadcode, layer);\n\t\n\t // Add tile to cache, though it won't be ready yet as the data is being\n\t // requested from various places asynchronously\n\t this._tileCache.setTile(quadcode, tile);\n\t }\n\t\n\t return tile;\n\t }\n\t }, {\n\t key: '_destroyTile',\n\t value: function _destroyTile(tile) {\n\t // Remove tile from scene\n\t this._tiles.remove(tile.getMesh());\n\t\n\t // Delete any references to the tile within this component\n\t\n\t // Call destory on tile instance\n\t tile.destroy();\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._tiles.children) {\n\t // Remove all tiles\n\t for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n\t this._tiles.remove(this._tiles.children[i]);\n\t }\n\t }\n\t\n\t // Remove tile from picking scene\n\t this.removeFromPicking(this._tilesPicking);\n\t\n\t if (this._tilesPicking.children) {\n\t // Remove all tiles\n\t for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n\t this._tilesPicking.remove(this._tilesPicking.children[i]);\n\t }\n\t }\n\t\n\t this._tileCache.destroy();\n\t this._tileCache = null;\n\t\n\t this._tiles = null;\n\t this._tilesPicking = null;\n\t this._frustum = null;\n\t\n\t _get(Object.getPrototypeOf(TileLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return TileLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = TileLayer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 44 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _lruCache = __webpack_require__(45);\n\t\n\tvar _lruCache2 = _interopRequireDefault(_lruCache);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// This process is based on a similar approach taken by OpenWebGlobe\n\t// See: https://github.com/OpenWebGlobe/WebViewer/blob/master/source/core/globecache.js\n\t\n\tvar TileCache = (function () {\n\t function TileCache(cacheLimit, onDestroyTile) {\n\t _classCallCheck(this, TileCache);\n\t\n\t this._cache = (0, _lruCache2['default'])({\n\t max: cacheLimit,\n\t dispose: function dispose(key, tile) {\n\t onDestroyTile(tile);\n\t }\n\t });\n\t }\n\t\n\t // Returns true if all specified tile providers are ready to be used\n\t // Otherwise, returns false\n\t\n\t _createClass(TileCache, [{\n\t key: 'isReady',\n\t value: function isReady() {\n\t return false;\n\t }\n\t\n\t // Get a cached tile without requesting a new one\n\t }, {\n\t key: 'getTile',\n\t value: function getTile(quadcode) {\n\t return this._cache.get(quadcode);\n\t }\n\t\n\t // Add tile to cache\n\t }, {\n\t key: 'setTile',\n\t value: function setTile(quadcode, tile) {\n\t this._cache.set(quadcode, tile);\n\t }\n\t\n\t // Destroy the cache and remove it from memory\n\t //\n\t // TODO: Call destroy method on items in cache\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._cache.reset();\n\t this._cache = null;\n\t }\n\t }]);\n\t\n\t return TileCache;\n\t})();\n\t\n\texports['default'] = TileCache;\n\t\n\tvar noNew = function noNew(cacheLimit, onDestroyTile) {\n\t return new TileCache(cacheLimit, onDestroyTile);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.tileCache = noNew;\n\n/***/ },\n/* 45 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = LRUCache\n\t\n\t// This will be a proper iterable 'Map' in engines that support it,\n\t// or a fakey-fake PseudoMap in older versions.\n\tvar Map = __webpack_require__(46)\n\tvar util = __webpack_require__(49)\n\t\n\t// A linked list to keep track of recently-used-ness\n\tvar Yallist = __webpack_require__(52)\n\t\n\t// use symbols if possible, otherwise just _props\n\tvar symbols = {}\n\tvar hasSymbol = typeof Symbol === 'function'\n\tvar makeSymbol\n\t/* istanbul ignore if */\n\tif (hasSymbol) {\n\t makeSymbol = function (key) {\n\t return Symbol.for(key)\n\t }\n\t} else {\n\t makeSymbol = function (key) {\n\t return '_' + key\n\t }\n\t}\n\t\n\tfunction priv (obj, key, val) {\n\t var sym\n\t if (symbols[key]) {\n\t sym = symbols[key]\n\t } else {\n\t sym = makeSymbol(key)\n\t symbols[key] = sym\n\t }\n\t if (arguments.length === 2) {\n\t return obj[sym]\n\t } else {\n\t obj[sym] = val\n\t return val\n\t }\n\t}\n\t\n\tfunction naiveLength () { return 1 }\n\t\n\t// lruList is a yallist where the head is the youngest\n\t// item, and the tail is the oldest. the list contains the Hit\n\t// objects as the entries.\n\t// Each Hit object has a reference to its Yallist.Node. This\n\t// never changes.\n\t//\n\t// cache is a Map (or PseudoMap) that matches the keys to\n\t// the Yallist.Node object.\n\tfunction LRUCache (options) {\n\t if (!(this instanceof LRUCache)) {\n\t return new LRUCache(options)\n\t }\n\t\n\t if (typeof options === 'number') {\n\t options = { max: options }\n\t }\n\t\n\t if (!options) {\n\t options = {}\n\t }\n\t\n\t var max = priv(this, 'max', options.max)\n\t // Kind of weird to have a default max of Infinity, but oh well.\n\t if (!max ||\n\t !(typeof max === 'number') ||\n\t max <= 0) {\n\t priv(this, 'max', Infinity)\n\t }\n\t\n\t var lc = options.length || naiveLength\n\t if (typeof lc !== 'function') {\n\t lc = naiveLength\n\t }\n\t priv(this, 'lengthCalculator', lc)\n\t\n\t priv(this, 'allowStale', options.stale || false)\n\t priv(this, 'maxAge', options.maxAge || 0)\n\t priv(this, 'dispose', options.dispose)\n\t this.reset()\n\t}\n\t\n\t// resize the cache when the max changes.\n\tObject.defineProperty(LRUCache.prototype, 'max', {\n\t set: function (mL) {\n\t if (!mL || !(typeof mL === 'number') || mL <= 0) {\n\t mL = Infinity\n\t }\n\t priv(this, 'max', mL)\n\t trim(this)\n\t },\n\t get: function () {\n\t return priv(this, 'max')\n\t },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'allowStale', {\n\t set: function (allowStale) {\n\t priv(this, 'allowStale', !!allowStale)\n\t },\n\t get: function () {\n\t return priv(this, 'allowStale')\n\t },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'maxAge', {\n\t set: function (mA) {\n\t if (!mA || !(typeof mA === 'number') || mA < 0) {\n\t mA = 0\n\t }\n\t priv(this, 'maxAge', mA)\n\t trim(this)\n\t },\n\t get: function () {\n\t return priv(this, 'maxAge')\n\t },\n\t enumerable: true\n\t})\n\t\n\t// resize the cache when the lengthCalculator changes.\n\tObject.defineProperty(LRUCache.prototype, 'lengthCalculator', {\n\t set: function (lC) {\n\t if (typeof lC !== 'function') {\n\t lC = naiveLength\n\t }\n\t if (lC !== priv(this, 'lengthCalculator')) {\n\t priv(this, 'lengthCalculator', lC)\n\t priv(this, 'length', 0)\n\t priv(this, 'lruList').forEach(function (hit) {\n\t hit.length = priv(this, 'lengthCalculator').call(this, hit.value, hit.key)\n\t priv(this, 'length', priv(this, 'length') + hit.length)\n\t }, this)\n\t }\n\t trim(this)\n\t },\n\t get: function () { return priv(this, 'lengthCalculator') },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'length', {\n\t get: function () { return priv(this, 'length') },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'itemCount', {\n\t get: function () { return priv(this, 'lruList').length },\n\t enumerable: true\n\t})\n\t\n\tLRUCache.prototype.rforEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = priv(this, 'lruList').tail; walker !== null;) {\n\t var prev = walker.prev\n\t forEachStep(this, fn, walker, thisp)\n\t walker = prev\n\t }\n\t}\n\t\n\tfunction forEachStep (self, fn, node, thisp) {\n\t var hit = node.value\n\t if (isStale(self, hit)) {\n\t del(self, node)\n\t if (!priv(self, 'allowStale')) {\n\t hit = undefined\n\t }\n\t }\n\t if (hit) {\n\t fn.call(thisp, hit.value, hit.key, self)\n\t }\n\t}\n\t\n\tLRUCache.prototype.forEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = priv(this, 'lruList').head; walker !== null;) {\n\t var next = walker.next\n\t forEachStep(this, fn, walker, thisp)\n\t walker = next\n\t }\n\t}\n\t\n\tLRUCache.prototype.keys = function () {\n\t return priv(this, 'lruList').toArray().map(function (k) {\n\t return k.key\n\t }, this)\n\t}\n\t\n\tLRUCache.prototype.values = function () {\n\t return priv(this, 'lruList').toArray().map(function (k) {\n\t return k.value\n\t }, this)\n\t}\n\t\n\tLRUCache.prototype.reset = function () {\n\t if (priv(this, 'dispose') &&\n\t priv(this, 'lruList') &&\n\t priv(this, 'lruList').length) {\n\t priv(this, 'lruList').forEach(function (hit) {\n\t priv(this, 'dispose').call(this, hit.key, hit.value)\n\t }, this)\n\t }\n\t\n\t priv(this, 'cache', new Map()) // hash of items by key\n\t priv(this, 'lruList', new Yallist()) // list of items in order of use recency\n\t priv(this, 'length', 0) // length of items in the list\n\t}\n\t\n\tLRUCache.prototype.dump = function () {\n\t return priv(this, 'lruList').map(function (hit) {\n\t if (!isStale(this, hit)) {\n\t return {\n\t k: hit.key,\n\t v: hit.value,\n\t e: hit.now + (hit.maxAge || 0)\n\t }\n\t }\n\t }, this).toArray().filter(function (h) {\n\t return h\n\t })\n\t}\n\t\n\tLRUCache.prototype.dumpLru = function () {\n\t return priv(this, 'lruList')\n\t}\n\t\n\tLRUCache.prototype.inspect = function (n, opts) {\n\t var str = 'LRUCache {'\n\t var extras = false\n\t\n\t var as = priv(this, 'allowStale')\n\t if (as) {\n\t str += '\\n allowStale: true'\n\t extras = true\n\t }\n\t\n\t var max = priv(this, 'max')\n\t if (max && max !== Infinity) {\n\t if (extras) {\n\t str += ','\n\t }\n\t str += '\\n max: ' + util.inspect(max, opts)\n\t extras = true\n\t }\n\t\n\t var maxAge = priv(this, 'maxAge')\n\t if (maxAge) {\n\t if (extras) {\n\t str += ','\n\t }\n\t str += '\\n maxAge: ' + util.inspect(maxAge, opts)\n\t extras = true\n\t }\n\t\n\t var lc = priv(this, 'lengthCalculator')\n\t if (lc && lc !== naiveLength) {\n\t if (extras) {\n\t str += ','\n\t }\n\t str += '\\n length: ' + util.inspect(priv(this, 'length'), opts)\n\t extras = true\n\t }\n\t\n\t var didFirst = false\n\t priv(this, 'lruList').forEach(function (item) {\n\t if (didFirst) {\n\t str += ',\\n '\n\t } else {\n\t if (extras) {\n\t str += ',\\n'\n\t }\n\t didFirst = true\n\t str += '\\n '\n\t }\n\t var key = util.inspect(item.key).split('\\n').join('\\n ')\n\t var val = { value: item.value }\n\t if (item.maxAge !== maxAge) {\n\t val.maxAge = item.maxAge\n\t }\n\t if (lc !== naiveLength) {\n\t val.length = item.length\n\t }\n\t if (isStale(this, item)) {\n\t val.stale = true\n\t }\n\t\n\t val = util.inspect(val, opts).split('\\n').join('\\n ')\n\t str += key + ' => ' + val\n\t })\n\t\n\t if (didFirst || extras) {\n\t str += '\\n'\n\t }\n\t str += '}'\n\t\n\t return str\n\t}\n\t\n\tLRUCache.prototype.set = function (key, value, maxAge) {\n\t maxAge = maxAge || priv(this, 'maxAge')\n\t\n\t var now = maxAge ? Date.now() : 0\n\t var len = priv(this, 'lengthCalculator').call(this, value, key)\n\t\n\t if (priv(this, 'cache').has(key)) {\n\t if (len > priv(this, 'max')) {\n\t del(this, priv(this, 'cache').get(key))\n\t return false\n\t }\n\t\n\t var node = priv(this, 'cache').get(key)\n\t var item = node.value\n\t\n\t // dispose of the old one before overwriting\n\t if (priv(this, 'dispose')) {\n\t priv(this, 'dispose').call(this, key, item.value)\n\t }\n\t\n\t item.now = now\n\t item.maxAge = maxAge\n\t item.value = value\n\t priv(this, 'length', priv(this, 'length') + (len - item.length))\n\t item.length = len\n\t this.get(key)\n\t trim(this)\n\t return true\n\t }\n\t\n\t var hit = new Entry(key, value, len, now, maxAge)\n\t\n\t // oversized objects fall out of cache automatically.\n\t if (hit.length > priv(this, 'max')) {\n\t if (priv(this, 'dispose')) {\n\t priv(this, 'dispose').call(this, key, value)\n\t }\n\t return false\n\t }\n\t\n\t priv(this, 'length', priv(this, 'length') + hit.length)\n\t priv(this, 'lruList').unshift(hit)\n\t priv(this, 'cache').set(key, priv(this, 'lruList').head)\n\t trim(this)\n\t return true\n\t}\n\t\n\tLRUCache.prototype.has = function (key) {\n\t if (!priv(this, 'cache').has(key)) return false\n\t var hit = priv(this, 'cache').get(key).value\n\t if (isStale(this, hit)) {\n\t return false\n\t }\n\t return true\n\t}\n\t\n\tLRUCache.prototype.get = function (key) {\n\t return get(this, key, true)\n\t}\n\t\n\tLRUCache.prototype.peek = function (key) {\n\t return get(this, key, false)\n\t}\n\t\n\tLRUCache.prototype.pop = function () {\n\t var node = priv(this, 'lruList').tail\n\t if (!node) return null\n\t del(this, node)\n\t return node.value\n\t}\n\t\n\tLRUCache.prototype.del = function (key) {\n\t del(this, priv(this, 'cache').get(key))\n\t}\n\t\n\tLRUCache.prototype.load = function (arr) {\n\t // reset the cache\n\t this.reset()\n\t\n\t var now = Date.now()\n\t // A previous serialized cache has the most recent items first\n\t for (var l = arr.length - 1; l >= 0; l--) {\n\t var hit = arr[l]\n\t var expiresAt = hit.e || 0\n\t if (expiresAt === 0) {\n\t // the item was created without expiration in a non aged cache\n\t this.set(hit.k, hit.v)\n\t } else {\n\t var maxAge = expiresAt - now\n\t // dont add already expired items\n\t if (maxAge > 0) {\n\t this.set(hit.k, hit.v, maxAge)\n\t }\n\t }\n\t }\n\t}\n\t\n\tLRUCache.prototype.prune = function () {\n\t var self = this\n\t priv(this, 'cache').forEach(function (value, key) {\n\t get(self, key, false)\n\t })\n\t}\n\t\n\tfunction get (self, key, doUse) {\n\t var node = priv(self, 'cache').get(key)\n\t if (node) {\n\t var hit = node.value\n\t if (isStale(self, hit)) {\n\t del(self, node)\n\t if (!priv(self, 'allowStale')) hit = undefined\n\t } else {\n\t if (doUse) {\n\t priv(self, 'lruList').unshiftNode(node)\n\t }\n\t }\n\t if (hit) hit = hit.value\n\t }\n\t return hit\n\t}\n\t\n\tfunction isStale (self, hit) {\n\t if (!hit || (!hit.maxAge && !priv(self, 'maxAge'))) {\n\t return false\n\t }\n\t var stale = false\n\t var diff = Date.now() - hit.now\n\t if (hit.maxAge) {\n\t stale = diff > hit.maxAge\n\t } else {\n\t stale = priv(self, 'maxAge') && (diff > priv(self, 'maxAge'))\n\t }\n\t return stale\n\t}\n\t\n\tfunction trim (self) {\n\t if (priv(self, 'length') > priv(self, 'max')) {\n\t for (var walker = priv(self, 'lruList').tail;\n\t priv(self, 'length') > priv(self, 'max') && walker !== null;) {\n\t // We know that we're about to delete this one, and also\n\t // what the next least recently used key will be, so just\n\t // go ahead and set it now.\n\t var prev = walker.prev\n\t del(self, walker)\n\t walker = prev\n\t }\n\t }\n\t}\n\t\n\tfunction del (self, node) {\n\t if (node) {\n\t var hit = node.value\n\t if (priv(self, 'dispose')) {\n\t priv(self, 'dispose').call(this, hit.key, hit.value)\n\t }\n\t priv(self, 'length', priv(self, 'length') - hit.length)\n\t priv(self, 'cache').delete(hit.key)\n\t priv(self, 'lruList').removeNode(node)\n\t }\n\t}\n\t\n\t// classy, since V8 prefers predictable objects.\n\tfunction Entry (key, value, length, now, maxAge) {\n\t this.key = key\n\t this.value = value\n\t this.length = length\n\t this.now = now\n\t this.maxAge = maxAge || 0\n\t}\n\n\n/***/ },\n/* 46 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(process) {if (process.env.npm_package_name === 'pseudomap' &&\n\t process.env.npm_lifecycle_script === 'test')\n\t process.env.TEST_PSEUDOMAP = 'true'\n\t\n\tif (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) {\n\t module.exports = Map\n\t} else {\n\t module.exports = __webpack_require__(48)\n\t}\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(47)))\n\n/***/ },\n/* 47 */\n/***/ function(module, exports) {\n\n\t// shim for using process in browser\n\t\n\tvar process = module.exports = {};\n\t\n\t// cached from whatever global is present so that test runners that stub it\n\t// don't break things. But we need to wrap it in a try catch in case it is\n\t// wrapped in strict mode code which doesn't define any globals. It's inside a\n\t// function because try/catches deoptimize in certain engines.\n\t\n\tvar cachedSetTimeout;\n\tvar cachedClearTimeout;\n\t\n\t(function () {\n\t try {\n\t cachedSetTimeout = setTimeout;\n\t } catch (e) {\n\t cachedSetTimeout = function () {\n\t throw new Error('setTimeout is not defined');\n\t }\n\t }\n\t try {\n\t cachedClearTimeout = clearTimeout;\n\t } catch (e) {\n\t cachedClearTimeout = function () {\n\t throw new Error('clearTimeout is not defined');\n\t }\n\t }\n\t} ())\n\tvar queue = [];\n\tvar draining = false;\n\tvar currentQueue;\n\tvar queueIndex = -1;\n\t\n\tfunction cleanUpNextTick() {\n\t if (!draining || !currentQueue) {\n\t return;\n\t }\n\t draining = false;\n\t if (currentQueue.length) {\n\t queue = currentQueue.concat(queue);\n\t } else {\n\t queueIndex = -1;\n\t }\n\t if (queue.length) {\n\t drainQueue();\n\t }\n\t}\n\t\n\tfunction drainQueue() {\n\t if (draining) {\n\t return;\n\t }\n\t var timeout = cachedSetTimeout(cleanUpNextTick);\n\t draining = true;\n\t\n\t var len = queue.length;\n\t while(len) {\n\t currentQueue = queue;\n\t queue = [];\n\t while (++queueIndex < len) {\n\t if (currentQueue) {\n\t currentQueue[queueIndex].run();\n\t }\n\t }\n\t queueIndex = -1;\n\t len = queue.length;\n\t }\n\t currentQueue = null;\n\t draining = false;\n\t cachedClearTimeout(timeout);\n\t}\n\t\n\tprocess.nextTick = function (fun) {\n\t var args = new Array(arguments.length - 1);\n\t if (arguments.length > 1) {\n\t for (var i = 1; i < arguments.length; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t }\n\t queue.push(new Item(fun, args));\n\t if (queue.length === 1 && !draining) {\n\t cachedSetTimeout(drainQueue, 0);\n\t }\n\t};\n\t\n\t// v8 likes predictible objects\n\tfunction Item(fun, array) {\n\t this.fun = fun;\n\t this.array = array;\n\t}\n\tItem.prototype.run = function () {\n\t this.fun.apply(null, this.array);\n\t};\n\tprocess.title = 'browser';\n\tprocess.browser = true;\n\tprocess.env = {};\n\tprocess.argv = [];\n\tprocess.version = ''; // empty string to avoid regexp issues\n\tprocess.versions = {};\n\t\n\tfunction noop() {}\n\t\n\tprocess.on = noop;\n\tprocess.addListener = noop;\n\tprocess.once = noop;\n\tprocess.off = noop;\n\tprocess.removeListener = noop;\n\tprocess.removeAllListeners = noop;\n\tprocess.emit = noop;\n\t\n\tprocess.binding = function (name) {\n\t throw new Error('process.binding is not supported');\n\t};\n\t\n\tprocess.cwd = function () { return '/' };\n\tprocess.chdir = function (dir) {\n\t throw new Error('process.chdir is not supported');\n\t};\n\tprocess.umask = function() { return 0; };\n\n\n/***/ },\n/* 48 */\n/***/ function(module, exports) {\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty\n\t\n\tmodule.exports = PseudoMap\n\t\n\tfunction PseudoMap (set) {\n\t if (!(this instanceof PseudoMap)) // whyyyyyyy\n\t throw new TypeError(\"Constructor PseudoMap requires 'new'\")\n\t\n\t this.clear()\n\t\n\t if (set) {\n\t if ((set instanceof PseudoMap) ||\n\t (typeof Map === 'function' && set instanceof Map))\n\t set.forEach(function (value, key) {\n\t this.set(key, value)\n\t }, this)\n\t else if (Array.isArray(set))\n\t set.forEach(function (kv) {\n\t this.set(kv[0], kv[1])\n\t }, this)\n\t else\n\t throw new TypeError('invalid argument')\n\t }\n\t}\n\t\n\tPseudoMap.prototype.forEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t Object.keys(this._data).forEach(function (k) {\n\t if (k !== 'size')\n\t fn.call(thisp, this._data[k].value, this._data[k].key)\n\t }, this)\n\t}\n\t\n\tPseudoMap.prototype.has = function (k) {\n\t return !!find(this._data, k)\n\t}\n\t\n\tPseudoMap.prototype.get = function (k) {\n\t var res = find(this._data, k)\n\t return res && res.value\n\t}\n\t\n\tPseudoMap.prototype.set = function (k, v) {\n\t set(this._data, k, v)\n\t}\n\t\n\tPseudoMap.prototype.delete = function (k) {\n\t var res = find(this._data, k)\n\t if (res) {\n\t delete this._data[res._index]\n\t this._data.size--\n\t }\n\t}\n\t\n\tPseudoMap.prototype.clear = function () {\n\t var data = Object.create(null)\n\t data.size = 0\n\t\n\t Object.defineProperty(this, '_data', {\n\t value: data,\n\t enumerable: false,\n\t configurable: true,\n\t writable: false\n\t })\n\t}\n\t\n\tObject.defineProperty(PseudoMap.prototype, 'size', {\n\t get: function () {\n\t return this._data.size\n\t },\n\t set: function (n) {},\n\t enumerable: true,\n\t configurable: true\n\t})\n\t\n\tPseudoMap.prototype.values =\n\tPseudoMap.prototype.keys =\n\tPseudoMap.prototype.entries = function () {\n\t throw new Error('iterators are not implemented in this version')\n\t}\n\t\n\t// Either identical, or both NaN\n\tfunction same (a, b) {\n\t return a === b || a !== a && b !== b\n\t}\n\t\n\tfunction Entry (k, v, i) {\n\t this.key = k\n\t this.value = v\n\t this._index = i\n\t}\n\t\n\tfunction find (data, k) {\n\t for (var i = 0, s = '_' + k, key = s;\n\t hasOwnProperty.call(data, key);\n\t key = s + i++) {\n\t if (same(data[key].key, k))\n\t return data[key]\n\t }\n\t}\n\t\n\tfunction set (data, k, v) {\n\t for (var i = 0, s = '_' + k, key = s;\n\t hasOwnProperty.call(data, key);\n\t key = s + i++) {\n\t if (same(data[key].key, k)) {\n\t data[key].value = v\n\t return\n\t }\n\t }\n\t data.size++\n\t data[key] = new Entry(k, v, key)\n\t}\n\n\n/***/ },\n/* 49 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.\n\t//\n\t// Permission is hereby granted, free of charge, to any person obtaining a\n\t// copy of this software and associated documentation files (the\n\t// \"Software\"), to deal in the Software without restriction, including\n\t// without limitation the rights to use, copy, modify, merge, publish,\n\t// distribute, sublicense, and/or sell copies of the Software, and to permit\n\t// persons to whom the Software is furnished to do so, subject to the\n\t// following conditions:\n\t//\n\t// The above copyright notice and this permission notice shall be included\n\t// in all copies or substantial portions of the Software.\n\t//\n\t// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n\t// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\t// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n\t// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n\t// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n\t// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n\t// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\t\n\tvar formatRegExp = /%[sdj%]/g;\n\texports.format = function(f) {\n\t if (!isString(f)) {\n\t var objects = [];\n\t for (var i = 0; i < arguments.length; i++) {\n\t objects.push(inspect(arguments[i]));\n\t }\n\t return objects.join(' ');\n\t }\n\t\n\t var i = 1;\n\t var args = arguments;\n\t var len = args.length;\n\t var str = String(f).replace(formatRegExp, function(x) {\n\t if (x === '%%') return '%';\n\t if (i >= len) return x;\n\t switch (x) {\n\t case '%s': return String(args[i++]);\n\t case '%d': return Number(args[i++]);\n\t case '%j':\n\t try {\n\t return JSON.stringify(args[i++]);\n\t } catch (_) {\n\t return '[Circular]';\n\t }\n\t default:\n\t return x;\n\t }\n\t });\n\t for (var x = args[i]; i < len; x = args[++i]) {\n\t if (isNull(x) || !isObject(x)) {\n\t str += ' ' + x;\n\t } else {\n\t str += ' ' + inspect(x);\n\t }\n\t }\n\t return str;\n\t};\n\t\n\t\n\t// Mark that a method should not be used.\n\t// Returns a modified function which warns once by default.\n\t// If --no-deprecation is set, then it is a no-op.\n\texports.deprecate = function(fn, msg) {\n\t // Allow for deprecating things in the process of starting up.\n\t if (isUndefined(global.process)) {\n\t return function() {\n\t return exports.deprecate(fn, msg).apply(this, arguments);\n\t };\n\t }\n\t\n\t if (process.noDeprecation === true) {\n\t return fn;\n\t }\n\t\n\t var warned = false;\n\t function deprecated() {\n\t if (!warned) {\n\t if (process.throwDeprecation) {\n\t throw new Error(msg);\n\t } else if (process.traceDeprecation) {\n\t console.trace(msg);\n\t } else {\n\t console.error(msg);\n\t }\n\t warned = true;\n\t }\n\t return fn.apply(this, arguments);\n\t }\n\t\n\t return deprecated;\n\t};\n\t\n\t\n\tvar debugs = {};\n\tvar debugEnviron;\n\texports.debuglog = function(set) {\n\t if (isUndefined(debugEnviron))\n\t debugEnviron = process.env.NODE_DEBUG || '';\n\t set = set.toUpperCase();\n\t if (!debugs[set]) {\n\t if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n\t var pid = process.pid;\n\t debugs[set] = function() {\n\t var msg = exports.format.apply(exports, arguments);\n\t console.error('%s %d: %s', set, pid, msg);\n\t };\n\t } else {\n\t debugs[set] = function() {};\n\t }\n\t }\n\t return debugs[set];\n\t};\n\t\n\t\n\t/**\n\t * Echos the value of a value. Trys to print the value out\n\t * in the best way possible given the different types.\n\t *\n\t * @param {Object} obj The object to print out.\n\t * @param {Object} opts Optional options object that alters the output.\n\t */\n\t/* legacy: obj, showHidden, depth, colors*/\n\tfunction inspect(obj, opts) {\n\t // default options\n\t var ctx = {\n\t seen: [],\n\t stylize: stylizeNoColor\n\t };\n\t // legacy...\n\t if (arguments.length >= 3) ctx.depth = arguments[2];\n\t if (arguments.length >= 4) ctx.colors = arguments[3];\n\t if (isBoolean(opts)) {\n\t // legacy...\n\t ctx.showHidden = opts;\n\t } else if (opts) {\n\t // got an \"options\" object\n\t exports._extend(ctx, opts);\n\t }\n\t // set default options\n\t if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n\t if (isUndefined(ctx.depth)) ctx.depth = 2;\n\t if (isUndefined(ctx.colors)) ctx.colors = false;\n\t if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n\t if (ctx.colors) ctx.stylize = stylizeWithColor;\n\t return formatValue(ctx, obj, ctx.depth);\n\t}\n\texports.inspect = inspect;\n\t\n\t\n\t// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\n\tinspect.colors = {\n\t 'bold' : [1, 22],\n\t 'italic' : [3, 23],\n\t 'underline' : [4, 24],\n\t 'inverse' : [7, 27],\n\t 'white' : [37, 39],\n\t 'grey' : [90, 39],\n\t 'black' : [30, 39],\n\t 'blue' : [34, 39],\n\t 'cyan' : [36, 39],\n\t 'green' : [32, 39],\n\t 'magenta' : [35, 39],\n\t 'red' : [31, 39],\n\t 'yellow' : [33, 39]\n\t};\n\t\n\t// Don't use 'blue' not visible on cmd.exe\n\tinspect.styles = {\n\t 'special': 'cyan',\n\t 'number': 'yellow',\n\t 'boolean': 'yellow',\n\t 'undefined': 'grey',\n\t 'null': 'bold',\n\t 'string': 'green',\n\t 'date': 'magenta',\n\t // \"name\": intentionally not styling\n\t 'regexp': 'red'\n\t};\n\t\n\t\n\tfunction stylizeWithColor(str, styleType) {\n\t var style = inspect.styles[styleType];\n\t\n\t if (style) {\n\t return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n\t '\\u001b[' + inspect.colors[style][1] + 'm';\n\t } else {\n\t return str;\n\t }\n\t}\n\t\n\t\n\tfunction stylizeNoColor(str, styleType) {\n\t return str;\n\t}\n\t\n\t\n\tfunction arrayToHash(array) {\n\t var hash = {};\n\t\n\t array.forEach(function(val, idx) {\n\t hash[val] = true;\n\t });\n\t\n\t return hash;\n\t}\n\t\n\t\n\tfunction formatValue(ctx, value, recurseTimes) {\n\t // Provide a hook for user-specified inspect functions.\n\t // Check that value is an object with an inspect function on it\n\t if (ctx.customInspect &&\n\t value &&\n\t isFunction(value.inspect) &&\n\t // Filter out the util module, it's inspect function is special\n\t value.inspect !== exports.inspect &&\n\t // Also filter out any prototype objects using the circular check.\n\t !(value.constructor && value.constructor.prototype === value)) {\n\t var ret = value.inspect(recurseTimes, ctx);\n\t if (!isString(ret)) {\n\t ret = formatValue(ctx, ret, recurseTimes);\n\t }\n\t return ret;\n\t }\n\t\n\t // Primitive types cannot have properties\n\t var primitive = formatPrimitive(ctx, value);\n\t if (primitive) {\n\t return primitive;\n\t }\n\t\n\t // Look up the keys of the object.\n\t var keys = Object.keys(value);\n\t var visibleKeys = arrayToHash(keys);\n\t\n\t if (ctx.showHidden) {\n\t keys = Object.getOwnPropertyNames(value);\n\t }\n\t\n\t // IE doesn't make error fields non-enumerable\n\t // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n\t if (isError(value)\n\t && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n\t return formatError(value);\n\t }\n\t\n\t // Some type of object without properties can be shortcutted.\n\t if (keys.length === 0) {\n\t if (isFunction(value)) {\n\t var name = value.name ? ': ' + value.name : '';\n\t return ctx.stylize('[Function' + name + ']', 'special');\n\t }\n\t if (isRegExp(value)) {\n\t return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n\t }\n\t if (isDate(value)) {\n\t return ctx.stylize(Date.prototype.toString.call(value), 'date');\n\t }\n\t if (isError(value)) {\n\t return formatError(value);\n\t }\n\t }\n\t\n\t var base = '', array = false, braces = ['{', '}'];\n\t\n\t // Make Array say that they are Array\n\t if (isArray(value)) {\n\t array = true;\n\t braces = ['[', ']'];\n\t }\n\t\n\t // Make functions say that they are functions\n\t if (isFunction(value)) {\n\t var n = value.name ? ': ' + value.name : '';\n\t base = ' [Function' + n + ']';\n\t }\n\t\n\t // Make RegExps say that they are RegExps\n\t if (isRegExp(value)) {\n\t base = ' ' + RegExp.prototype.toString.call(value);\n\t }\n\t\n\t // Make dates with properties first say the date\n\t if (isDate(value)) {\n\t base = ' ' + Date.prototype.toUTCString.call(value);\n\t }\n\t\n\t // Make error with message first say the error\n\t if (isError(value)) {\n\t base = ' ' + formatError(value);\n\t }\n\t\n\t if (keys.length === 0 && (!array || value.length == 0)) {\n\t return braces[0] + base + braces[1];\n\t }\n\t\n\t if (recurseTimes < 0) {\n\t if (isRegExp(value)) {\n\t return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n\t } else {\n\t return ctx.stylize('[Object]', 'special');\n\t }\n\t }\n\t\n\t ctx.seen.push(value);\n\t\n\t var output;\n\t if (array) {\n\t output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n\t } else {\n\t output = keys.map(function(key) {\n\t return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n\t });\n\t }\n\t\n\t ctx.seen.pop();\n\t\n\t return reduceToSingleString(output, base, braces);\n\t}\n\t\n\t\n\tfunction formatPrimitive(ctx, value) {\n\t if (isUndefined(value))\n\t return ctx.stylize('undefined', 'undefined');\n\t if (isString(value)) {\n\t var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n\t .replace(/'/g, \"\\\\'\")\n\t .replace(/\\\\\"/g, '\"') + '\\'';\n\t return ctx.stylize(simple, 'string');\n\t }\n\t if (isNumber(value))\n\t return ctx.stylize('' + value, 'number');\n\t if (isBoolean(value))\n\t return ctx.stylize('' + value, 'boolean');\n\t // For some reason typeof null is \"object\", so special case here.\n\t if (isNull(value))\n\t return ctx.stylize('null', 'null');\n\t}\n\t\n\t\n\tfunction formatError(value) {\n\t return '[' + Error.prototype.toString.call(value) + ']';\n\t}\n\t\n\t\n\tfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n\t var output = [];\n\t for (var i = 0, l = value.length; i < l; ++i) {\n\t if (hasOwnProperty(value, String(i))) {\n\t output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n\t String(i), true));\n\t } else {\n\t output.push('');\n\t }\n\t }\n\t keys.forEach(function(key) {\n\t if (!key.match(/^\\d+$/)) {\n\t output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n\t key, true));\n\t }\n\t });\n\t return output;\n\t}\n\t\n\t\n\tfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n\t var name, str, desc;\n\t desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n\t if (desc.get) {\n\t if (desc.set) {\n\t str = ctx.stylize('[Getter/Setter]', 'special');\n\t } else {\n\t str = ctx.stylize('[Getter]', 'special');\n\t }\n\t } else {\n\t if (desc.set) {\n\t str = ctx.stylize('[Setter]', 'special');\n\t }\n\t }\n\t if (!hasOwnProperty(visibleKeys, key)) {\n\t name = '[' + key + ']';\n\t }\n\t if (!str) {\n\t if (ctx.seen.indexOf(desc.value) < 0) {\n\t if (isNull(recurseTimes)) {\n\t str = formatValue(ctx, desc.value, null);\n\t } else {\n\t str = formatValue(ctx, desc.value, recurseTimes - 1);\n\t }\n\t if (str.indexOf('\\n') > -1) {\n\t if (array) {\n\t str = str.split('\\n').map(function(line) {\n\t return ' ' + line;\n\t }).join('\\n').substr(2);\n\t } else {\n\t str = '\\n' + str.split('\\n').map(function(line) {\n\t return ' ' + line;\n\t }).join('\\n');\n\t }\n\t }\n\t } else {\n\t str = ctx.stylize('[Circular]', 'special');\n\t }\n\t }\n\t if (isUndefined(name)) {\n\t if (array && key.match(/^\\d+$/)) {\n\t return str;\n\t }\n\t name = JSON.stringify('' + key);\n\t if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n\t name = name.substr(1, name.length - 2);\n\t name = ctx.stylize(name, 'name');\n\t } else {\n\t name = name.replace(/'/g, \"\\\\'\")\n\t .replace(/\\\\\"/g, '\"')\n\t .replace(/(^\"|\"$)/g, \"'\");\n\t name = ctx.stylize(name, 'string');\n\t }\n\t }\n\t\n\t return name + ': ' + str;\n\t}\n\t\n\t\n\tfunction reduceToSingleString(output, base, braces) {\n\t var numLinesEst = 0;\n\t var length = output.reduce(function(prev, cur) {\n\t numLinesEst++;\n\t if (cur.indexOf('\\n') >= 0) numLinesEst++;\n\t return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n\t }, 0);\n\t\n\t if (length > 60) {\n\t return braces[0] +\n\t (base === '' ? '' : base + '\\n ') +\n\t ' ' +\n\t output.join(',\\n ') +\n\t ' ' +\n\t braces[1];\n\t }\n\t\n\t return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n\t}\n\t\n\t\n\t// NOTE: These type checking functions intentionally don't use `instanceof`\n\t// because it is fragile and can be easily faked with `Object.create()`.\n\tfunction isArray(ar) {\n\t return Array.isArray(ar);\n\t}\n\texports.isArray = isArray;\n\t\n\tfunction isBoolean(arg) {\n\t return typeof arg === 'boolean';\n\t}\n\texports.isBoolean = isBoolean;\n\t\n\tfunction isNull(arg) {\n\t return arg === null;\n\t}\n\texports.isNull = isNull;\n\t\n\tfunction isNullOrUndefined(arg) {\n\t return arg == null;\n\t}\n\texports.isNullOrUndefined = isNullOrUndefined;\n\t\n\tfunction isNumber(arg) {\n\t return typeof arg === 'number';\n\t}\n\texports.isNumber = isNumber;\n\t\n\tfunction isString(arg) {\n\t return typeof arg === 'string';\n\t}\n\texports.isString = isString;\n\t\n\tfunction isSymbol(arg) {\n\t return typeof arg === 'symbol';\n\t}\n\texports.isSymbol = isSymbol;\n\t\n\tfunction isUndefined(arg) {\n\t return arg === void 0;\n\t}\n\texports.isUndefined = isUndefined;\n\t\n\tfunction isRegExp(re) {\n\t return isObject(re) && objectToString(re) === '[object RegExp]';\n\t}\n\texports.isRegExp = isRegExp;\n\t\n\tfunction isObject(arg) {\n\t return typeof arg === 'object' && arg !== null;\n\t}\n\texports.isObject = isObject;\n\t\n\tfunction isDate(d) {\n\t return isObject(d) && objectToString(d) === '[object Date]';\n\t}\n\texports.isDate = isDate;\n\t\n\tfunction isError(e) {\n\t return isObject(e) &&\n\t (objectToString(e) === '[object Error]' || e instanceof Error);\n\t}\n\texports.isError = isError;\n\t\n\tfunction isFunction(arg) {\n\t return typeof arg === 'function';\n\t}\n\texports.isFunction = isFunction;\n\t\n\tfunction isPrimitive(arg) {\n\t return arg === null ||\n\t typeof arg === 'boolean' ||\n\t typeof arg === 'number' ||\n\t typeof arg === 'string' ||\n\t typeof arg === 'symbol' || // ES6 symbol\n\t typeof arg === 'undefined';\n\t}\n\texports.isPrimitive = isPrimitive;\n\t\n\texports.isBuffer = __webpack_require__(50);\n\t\n\tfunction objectToString(o) {\n\t return Object.prototype.toString.call(o);\n\t}\n\t\n\t\n\tfunction pad(n) {\n\t return n < 10 ? '0' + n.toString(10) : n.toString(10);\n\t}\n\t\n\t\n\tvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n\t 'Oct', 'Nov', 'Dec'];\n\t\n\t// 26 Feb 16:19:34\n\tfunction timestamp() {\n\t var d = new Date();\n\t var time = [pad(d.getHours()),\n\t pad(d.getMinutes()),\n\t pad(d.getSeconds())].join(':');\n\t return [d.getDate(), months[d.getMonth()], time].join(' ');\n\t}\n\t\n\t\n\t// log is just a thin wrapper to console.log that prepends a timestamp\n\texports.log = function() {\n\t console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n\t};\n\t\n\t\n\t/**\n\t * Inherit the prototype methods from one constructor into another.\n\t *\n\t * The Function.prototype.inherits from lang.js rewritten as a standalone\n\t * function (not on Function.prototype). NOTE: If this file is to be loaded\n\t * during bootstrapping this function needs to be rewritten using some native\n\t * functions as prototype setup using normal JavaScript does not work as\n\t * expected during bootstrapping (see mirror.js in r114903).\n\t *\n\t * @param {function} ctor Constructor function which needs to inherit the\n\t * prototype.\n\t * @param {function} superCtor Constructor function to inherit prototype from.\n\t */\n\texports.inherits = __webpack_require__(51);\n\t\n\texports._extend = function(origin, add) {\n\t // Don't do anything if add isn't an object\n\t if (!add || !isObject(add)) return origin;\n\t\n\t var keys = Object.keys(add);\n\t var i = keys.length;\n\t while (i--) {\n\t origin[keys[i]] = add[keys[i]];\n\t }\n\t return origin;\n\t};\n\t\n\tfunction hasOwnProperty(obj, prop) {\n\t return Object.prototype.hasOwnProperty.call(obj, prop);\n\t}\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(47)))\n\n/***/ },\n/* 50 */\n/***/ function(module, exports) {\n\n\tmodule.exports = function isBuffer(arg) {\n\t return arg && typeof arg === 'object'\n\t && typeof arg.copy === 'function'\n\t && typeof arg.fill === 'function'\n\t && typeof arg.readUInt8 === 'function';\n\t}\n\n/***/ },\n/* 51 */\n/***/ function(module, exports) {\n\n\tif (typeof Object.create === 'function') {\n\t // implementation from standard node.js 'util' module\n\t module.exports = function inherits(ctor, superCtor) {\n\t ctor.super_ = superCtor\n\t ctor.prototype = Object.create(superCtor.prototype, {\n\t constructor: {\n\t value: ctor,\n\t enumerable: false,\n\t writable: true,\n\t configurable: true\n\t }\n\t });\n\t };\n\t} else {\n\t // old school shim for old browsers\n\t module.exports = function inherits(ctor, superCtor) {\n\t ctor.super_ = superCtor\n\t var TempCtor = function () {}\n\t TempCtor.prototype = superCtor.prototype\n\t ctor.prototype = new TempCtor()\n\t ctor.prototype.constructor = ctor\n\t }\n\t}\n\n\n/***/ },\n/* 52 */\n/***/ function(module, exports) {\n\n\tmodule.exports = Yallist\n\t\n\tYallist.Node = Node\n\tYallist.create = Yallist\n\t\n\tfunction Yallist (list) {\n\t var self = this\n\t if (!(self instanceof Yallist)) {\n\t self = new Yallist()\n\t }\n\t\n\t self.tail = null\n\t self.head = null\n\t self.length = 0\n\t\n\t if (list && typeof list.forEach === 'function') {\n\t list.forEach(function (item) {\n\t self.push(item)\n\t })\n\t } else if (arguments.length > 0) {\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t self.push(arguments[i])\n\t }\n\t }\n\t\n\t return self\n\t}\n\t\n\tYallist.prototype.removeNode = function (node) {\n\t if (node.list !== this) {\n\t throw new Error('removing node which does not belong to this list')\n\t }\n\t\n\t var next = node.next\n\t var prev = node.prev\n\t\n\t if (next) {\n\t next.prev = prev\n\t }\n\t\n\t if (prev) {\n\t prev.next = next\n\t }\n\t\n\t if (node === this.head) {\n\t this.head = next\n\t }\n\t if (node === this.tail) {\n\t this.tail = prev\n\t }\n\t\n\t node.list.length --\n\t node.next = null\n\t node.prev = null\n\t node.list = null\n\t}\n\t\n\tYallist.prototype.unshiftNode = function (node) {\n\t if (node === this.head) {\n\t return\n\t }\n\t\n\t if (node.list) {\n\t node.list.removeNode(node)\n\t }\n\t\n\t var head = this.head\n\t node.list = this\n\t node.next = head\n\t if (head) {\n\t head.prev = node\n\t }\n\t\n\t this.head = node\n\t if (!this.tail) {\n\t this.tail = node\n\t }\n\t this.length ++\n\t}\n\t\n\tYallist.prototype.pushNode = function (node) {\n\t if (node === this.tail) {\n\t return\n\t }\n\t\n\t if (node.list) {\n\t node.list.removeNode(node)\n\t }\n\t\n\t var tail = this.tail\n\t node.list = this\n\t node.prev = tail\n\t if (tail) {\n\t tail.next = node\n\t }\n\t\n\t this.tail = node\n\t if (!this.head) {\n\t this.head = node\n\t }\n\t this.length ++\n\t}\n\t\n\tYallist.prototype.push = function () {\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t push(this, arguments[i])\n\t }\n\t return this.length\n\t}\n\t\n\tYallist.prototype.unshift = function () {\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t unshift(this, arguments[i])\n\t }\n\t return this.length\n\t}\n\t\n\tYallist.prototype.pop = function () {\n\t if (!this.tail)\n\t return undefined\n\t\n\t var res = this.tail.value\n\t this.tail = this.tail.prev\n\t this.tail.next = null\n\t this.length --\n\t return res\n\t}\n\t\n\tYallist.prototype.shift = function () {\n\t if (!this.head)\n\t return undefined\n\t\n\t var res = this.head.value\n\t this.head = this.head.next\n\t this.head.prev = null\n\t this.length --\n\t return res\n\t}\n\t\n\tYallist.prototype.forEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = this.head, i = 0; walker !== null; i++) {\n\t fn.call(thisp, walker.value, i, this)\n\t walker = walker.next\n\t }\n\t}\n\t\n\tYallist.prototype.forEachReverse = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {\n\t fn.call(thisp, walker.value, i, this)\n\t walker = walker.prev\n\t }\n\t}\n\t\n\tYallist.prototype.get = function (n) {\n\t for (var i = 0, walker = this.head; walker !== null && i < n; i++) {\n\t // abort out of the list early if we hit a cycle\n\t walker = walker.next\n\t }\n\t if (i === n && walker !== null) {\n\t return walker.value\n\t }\n\t}\n\t\n\tYallist.prototype.getReverse = function (n) {\n\t for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {\n\t // abort out of the list early if we hit a cycle\n\t walker = walker.prev\n\t }\n\t if (i === n && walker !== null) {\n\t return walker.value\n\t }\n\t}\n\t\n\tYallist.prototype.map = function (fn, thisp) {\n\t thisp = thisp || this\n\t var res = new Yallist()\n\t for (var walker = this.head; walker !== null; ) {\n\t res.push(fn.call(thisp, walker.value, this))\n\t walker = walker.next\n\t }\n\t return res\n\t}\n\t\n\tYallist.prototype.mapReverse = function (fn, thisp) {\n\t thisp = thisp || this\n\t var res = new Yallist()\n\t for (var walker = this.tail; walker !== null;) {\n\t res.push(fn.call(thisp, walker.value, this))\n\t walker = walker.prev\n\t }\n\t return res\n\t}\n\t\n\tYallist.prototype.reduce = function (fn, initial) {\n\t var acc\n\t var walker = this.head\n\t if (arguments.length > 1) {\n\t acc = initial\n\t } else if (this.head) {\n\t walker = this.head.next\n\t acc = this.head.value\n\t } else {\n\t throw new TypeError('Reduce of empty list with no initial value')\n\t }\n\t\n\t for (var i = 0; walker !== null; i++) {\n\t acc = fn(acc, walker.value, i)\n\t walker = walker.next\n\t }\n\t\n\t return acc\n\t}\n\t\n\tYallist.prototype.reduceReverse = function (fn, initial) {\n\t var acc\n\t var walker = this.tail\n\t if (arguments.length > 1) {\n\t acc = initial\n\t } else if (this.tail) {\n\t walker = this.tail.prev\n\t acc = this.tail.value\n\t } else {\n\t throw new TypeError('Reduce of empty list with no initial value')\n\t }\n\t\n\t for (var i = this.length - 1; walker !== null; i--) {\n\t acc = fn(acc, walker.value, i)\n\t walker = walker.prev\n\t }\n\t\n\t return acc\n\t}\n\t\n\tYallist.prototype.toArray = function () {\n\t var arr = new Array(this.length)\n\t for (var i = 0, walker = this.head; walker !== null; i++) {\n\t arr[i] = walker.value\n\t walker = walker.next\n\t }\n\t return arr\n\t}\n\t\n\tYallist.prototype.toArrayReverse = function () {\n\t var arr = new Array(this.length)\n\t for (var i = 0, walker = this.tail; walker !== null; i++) {\n\t arr[i] = walker.value\n\t walker = walker.prev\n\t }\n\t return arr\n\t}\n\t\n\tYallist.prototype.slice = function (from, to) {\n\t to = to || this.length\n\t if (to < 0) {\n\t to += this.length\n\t }\n\t from = from || 0\n\t if (from < 0) {\n\t from += this.length\n\t }\n\t var ret = new Yallist()\n\t if (to < from || to < 0) {\n\t return ret\n\t }\n\t if (from < 0) {\n\t from = 0\n\t }\n\t if (to > this.length) {\n\t to = this.length\n\t }\n\t for (var i = 0, walker = this.head; walker !== null && i < from; i++) {\n\t walker = walker.next\n\t }\n\t for (; walker !== null && i < to; i++, walker = walker.next) {\n\t ret.push(walker.value)\n\t }\n\t return ret\n\t}\n\t\n\tYallist.prototype.sliceReverse = function (from, to) {\n\t to = to || this.length\n\t if (to < 0) {\n\t to += this.length\n\t }\n\t from = from || 0\n\t if (from < 0) {\n\t from += this.length\n\t }\n\t var ret = new Yallist()\n\t if (to < from || to < 0) {\n\t return ret\n\t }\n\t if (from < 0) {\n\t from = 0\n\t }\n\t if (to > this.length) {\n\t to = this.length\n\t }\n\t for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {\n\t walker = walker.prev\n\t }\n\t for (; walker !== null && i > from; i--, walker = walker.prev) {\n\t ret.push(walker.value)\n\t }\n\t return ret\n\t}\n\t\n\tYallist.prototype.reverse = function () {\n\t var head = this.head\n\t var tail = this.tail\n\t for (var walker = head; walker !== null; walker = walker.prev) {\n\t var p = walker.prev\n\t walker.prev = walker.next\n\t walker.next = p\n\t }\n\t this.head = tail\n\t this.tail = head\n\t return this\n\t}\n\t\n\tfunction push (self, item) {\n\t self.tail = new Node(item, self.tail, null, self)\n\t if (!self.head) {\n\t self.head = self.tail\n\t }\n\t self.length ++\n\t}\n\t\n\tfunction unshift (self, item) {\n\t self.head = new Node(item, null, self.head, self)\n\t if (!self.tail) {\n\t self.tail = self.head\n\t }\n\t self.length ++\n\t}\n\t\n\tfunction Node (value, prev, next, list) {\n\t if (!(this instanceof Node)) {\n\t return new Node(value, prev, next, list)\n\t }\n\t\n\t this.list = list\n\t this.value = value\n\t\n\t if (prev) {\n\t prev.next = this\n\t this.prev = prev\n\t } else {\n\t this.prev = null\n\t }\n\t\n\t if (next) {\n\t next.prev = this\n\t this.next = next\n\t } else {\n\t this.next = null\n\t }\n\t}\n\n\n/***/ },\n/* 53 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Tile2 = __webpack_require__(54);\n\t\n\tvar _Tile3 = _interopRequireDefault(_Tile2);\n\t\n\tvar _vendorBoxHelper = __webpack_require__(55);\n\t\n\tvar _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\tvar ImageTile = (function (_Tile) {\n\t _inherits(ImageTile, _Tile);\n\t\n\t function ImageTile(quadcode, path, layer) {\n\t _classCallCheck(this, ImageTile);\n\t\n\t _get(Object.getPrototypeOf(ImageTile.prototype), 'constructor', this).call(this, quadcode, path, layer);\n\t }\n\t\n\t // Request data for the tile\n\t\n\t _createClass(ImageTile, [{\n\t key: 'requestTileAsync',\n\t value: function requestTileAsync() {\n\t var _this = this;\n\t\n\t // Making this asynchronous really speeds up the LOD framerate\n\t setTimeout(function () {\n\t if (!_this._mesh) {\n\t _this._mesh = _this._createMesh();\n\t _this._requestTile();\n\t }\n\t }, 0);\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Cancel any pending requests\n\t this._abortRequest();\n\t\n\t // Clear image reference\n\t this._image = null;\n\t\n\t _get(Object.getPrototypeOf(ImageTile.prototype), 'destroy', this).call(this);\n\t }\n\t }, {\n\t key: '_createMesh',\n\t value: function _createMesh() {\n\t // Something went wrong and the tile\n\t //\n\t // Possibly removed by the cache before loaded\n\t if (!this._center) {\n\t return;\n\t }\n\t\n\t var mesh = new _three2['default'].Object3D();\n\t var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);\n\t\n\t var material;\n\t if (!this._world._environment._skybox) {\n\t material = new _three2['default'].MeshBasicMaterial({\n\t depthWrite: false\n\t });\n\t\n\t // var material = new THREE.MeshPhongMaterial({\n\t // depthWrite: false\n\t // });\n\t } else {\n\t // Other MeshStandardMaterial settings\n\t //\n\t // material.envMapIntensity will change the amount of colour reflected(?)\n\t // from the environment map – can be greater than 1 for more intensity\n\t\n\t material = new _three2['default'].MeshStandardMaterial({\n\t depthWrite: false\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMap = this._world._environment._skybox.getRenderTarget();\n\t }\n\t\n\t var localMesh = new _three2['default'].Mesh(geom, material);\n\t localMesh.rotation.x = -90 * Math.PI / 180;\n\t\n\t localMesh.receiveShadow = true;\n\t\n\t mesh.add(localMesh);\n\t mesh.renderOrder = 0.1;\n\t\n\t mesh.position.x = this._center[0];\n\t mesh.position.z = this._center[1];\n\t\n\t // var box = new BoxHelper(localMesh);\n\t // mesh.add(box);\n\t //\n\t // mesh.add(this._createDebugMesh());\n\t\n\t return mesh;\n\t }\n\t }, {\n\t key: '_createDebugMesh',\n\t value: function _createDebugMesh() {\n\t var canvas = document.createElement('canvas');\n\t canvas.width = 256;\n\t canvas.height = 256;\n\t\n\t var context = canvas.getContext('2d');\n\t context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n\t context.fillStyle = '#ff0000';\n\t context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n\t context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\t\n\t var texture = new _three2['default'].Texture(canvas);\n\t\n\t // Silky smooth images when tilted\n\t texture.magFilter = _three2['default'].LinearFilter;\n\t texture.minFilter = _three2['default'].LinearMipMapLinearFilter;\n\t\n\t // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t texture.anisotropy = 4;\n\t\n\t texture.needsUpdate = true;\n\t\n\t var material = new _three2['default'].MeshBasicMaterial({\n\t map: texture,\n\t transparent: true,\n\t depthWrite: false\n\t });\n\t\n\t var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);\n\t var mesh = new _three2['default'].Mesh(geom, material);\n\t\n\t mesh.rotation.x = -90 * Math.PI / 180;\n\t mesh.position.y = 0.1;\n\t\n\t return mesh;\n\t }\n\t }, {\n\t key: '_requestTile',\n\t value: function _requestTile() {\n\t var _this2 = this;\n\t\n\t var urlParams = {\n\t x: this._tile[0],\n\t y: this._tile[1],\n\t z: this._tile[2]\n\t };\n\t\n\t var url = this._getTileURL(urlParams);\n\t\n\t var image = document.createElement('img');\n\t\n\t image.addEventListener('load', function (event) {\n\t var texture = new _three2['default'].Texture();\n\t\n\t texture.image = image;\n\t texture.needsUpdate = true;\n\t\n\t // Silky smooth images when tilted\n\t texture.magFilter = _three2['default'].LinearFilter;\n\t texture.minFilter = _three2['default'].LinearMipMapLinearFilter;\n\t\n\t // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t texture.anisotropy = 4;\n\t\n\t texture.needsUpdate = true;\n\t\n\t // Something went wrong and the tile or its material is missing\n\t //\n\t // Possibly removed by the cache before the image loaded\n\t if (!_this2._mesh || !_this2._mesh.children[0] || !_this2._mesh.children[0].material) {\n\t return;\n\t }\n\t\n\t _this2._mesh.children[0].material.map = texture;\n\t _this2._mesh.children[0].material.needsUpdate = true;\n\t\n\t _this2._texture = texture;\n\t _this2._ready = true;\n\t }, false);\n\t\n\t // image.addEventListener('progress', event => {}, false);\n\t // image.addEventListener('error', event => {}, false);\n\t\n\t image.crossOrigin = '';\n\t\n\t // Load image\n\t image.src = url;\n\t\n\t this._image = image;\n\t }\n\t }, {\n\t key: '_abortRequest',\n\t value: function _abortRequest() {\n\t if (!this._image) {\n\t return;\n\t }\n\t\n\t this._image.src = '';\n\t }\n\t }]);\n\t\n\t return ImageTile;\n\t})(_Tile3['default']);\n\t\n\texports['default'] = ImageTile;\n\t\n\tvar noNew = function noNew(quadcode, path, layer) {\n\t return new ImageTile(quadcode, path, layer);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.imageTile = noNew;\n\n/***/ },\n/* 54 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// Manages a single tile and its layers\n\t\n\tvar r2d = 180 / Math.PI;\n\t\n\tvar tileURLRegex = /\\{([szxy])\\}/g;\n\t\n\tvar Tile = (function () {\n\t function Tile(quadcode, path, layer) {\n\t _classCallCheck(this, Tile);\n\t\n\t this._layer = layer;\n\t this._world = layer._world;\n\t this._quadcode = quadcode;\n\t this._path = path;\n\t\n\t this._ready = false;\n\t\n\t this._tile = this._quadcodeToTile(quadcode);\n\t\n\t // Bottom-left and top-right bounds in WGS84 coordinates\n\t this._boundsLatLon = this._tileBoundsWGS84(this._tile);\n\t\n\t // Bottom-left and top-right bounds in world coordinates\n\t this._boundsWorld = this._tileBoundsFromWGS84(this._boundsLatLon);\n\t\n\t // Tile center in world coordinates\n\t this._center = this._boundsToCenter(this._boundsWorld);\n\t\n\t // Tile center in projected coordinates\n\t this._centerLatlon = this._world.pointToLatLon((0, _geoPoint.point)(this._center[0], this._center[1]));\n\t\n\t // Length of a tile side in world coorindates\n\t this._side = this._getSide(this._boundsWorld);\n\t\n\t // Point scale for tile (for unit conversion)\n\t this._pointScale = this._world.pointScale(this._centerLatlon);\n\t }\n\t\n\t // Returns true if the tile mesh and texture are ready to be used\n\t // Otherwise, returns false\n\t\n\t _createClass(Tile, [{\n\t key: 'isReady',\n\t value: function isReady() {\n\t return this._ready;\n\t }\n\t\n\t // Request data for the tile\n\t }, {\n\t key: 'requestTileAsync',\n\t value: function requestTileAsync() {}\n\t }, {\n\t key: 'getQuadcode',\n\t value: function getQuadcode() {\n\t return this._quadcode;\n\t }\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {\n\t return this._boundsWorld;\n\t }\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t }, {\n\t key: 'getSide',\n\t value: function getSide() {\n\t return this._side;\n\t }\n\t }, {\n\t key: 'getMesh',\n\t value: function getMesh() {\n\t return this._mesh;\n\t }\n\t }, {\n\t key: 'getPickingMesh',\n\t value: function getPickingMesh() {\n\t return this._pickingMesh;\n\t }\n\t\n\t // Destroys the tile and removes it from the layer and memory\n\t //\n\t // Ensure that this leaves no trace of the tile – no textures, no meshes,\n\t // nothing in memory or the GPU\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Delete reference to layer and world\n\t this._layer = null;\n\t this._world = null;\n\t\n\t // Delete location references\n\t this._boundsLatLon = null;\n\t this._boundsWorld = null;\n\t this._center = null;\n\t\n\t // Done if no mesh\n\t if (!this._mesh) {\n\t return;\n\t }\n\t\n\t if (this._mesh.children) {\n\t // Dispose of mesh and materials\n\t this._mesh.children.forEach(function (child) {\n\t child.geometry.dispose();\n\t child.geometry = null;\n\t\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t });\n\t } else {\n\t this._mesh.geometry.dispose();\n\t this._mesh.geometry = null;\n\t\n\t if (this._mesh.material.map) {\n\t this._mesh.material.map.dispose();\n\t this._mesh.material.map = null;\n\t }\n\t\n\t this._mesh.material.dispose();\n\t this._mesh.material = null;\n\t }\n\t }\n\t }, {\n\t key: '_createMesh',\n\t value: function _createMesh() {}\n\t }, {\n\t key: '_createDebugMesh',\n\t value: function _createDebugMesh() {}\n\t }, {\n\t key: '_getTileURL',\n\t value: function _getTileURL(urlParams) {\n\t if (!urlParams.s) {\n\t // Default to a random choice of a, b or c\n\t urlParams.s = String.fromCharCode(97 + Math.floor(Math.random() * 3));\n\t }\n\t\n\t tileURLRegex.lastIndex = 0;\n\t return this._path.replace(tileURLRegex, function (value, key) {\n\t // Replace with paramter, otherwise keep existing value\n\t return urlParams[key];\n\t });\n\t }\n\t\n\t // Convert from quadcode to TMS tile coordinates\n\t }, {\n\t key: '_quadcodeToTile',\n\t value: function _quadcodeToTile(quadcode) {\n\t var x = 0;\n\t var y = 0;\n\t var z = quadcode.length;\n\t\n\t for (var i = z; i > 0; i--) {\n\t var mask = 1 << i - 1;\n\t var q = +quadcode[z - i];\n\t if (q === 1) {\n\t x |= mask;\n\t }\n\t if (q === 2) {\n\t y |= mask;\n\t }\n\t if (q === 3) {\n\t x |= mask;\n\t y |= mask;\n\t }\n\t }\n\t\n\t return [x, y, z];\n\t }\n\t\n\t // Convert WGS84 tile bounds to world coordinates\n\t }, {\n\t key: '_tileBoundsFromWGS84',\n\t value: function _tileBoundsFromWGS84(boundsWGS84) {\n\t var sw = this._layer._world.latLonToPoint((0, _geoLatLon.latLon)(boundsWGS84[1], boundsWGS84[0]));\n\t var ne = this._layer._world.latLonToPoint((0, _geoLatLon.latLon)(boundsWGS84[3], boundsWGS84[2]));\n\t\n\t return [sw.x, sw.y, ne.x, ne.y];\n\t }\n\t\n\t // Get tile bounds in WGS84 coordinates\n\t }, {\n\t key: '_tileBoundsWGS84',\n\t value: function _tileBoundsWGS84(tile) {\n\t var e = this._tile2lon(tile[0] + 1, tile[2]);\n\t var w = this._tile2lon(tile[0], tile[2]);\n\t var s = this._tile2lat(tile[1] + 1, tile[2]);\n\t var n = this._tile2lat(tile[1], tile[2]);\n\t return [w, s, e, n];\n\t }\n\t }, {\n\t key: '_tile2lon',\n\t value: function _tile2lon(x, z) {\n\t return x / Math.pow(2, z) * 360 - 180;\n\t }\n\t }, {\n\t key: '_tile2lat',\n\t value: function _tile2lat(y, z) {\n\t var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);\n\t return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));\n\t }\n\t }, {\n\t key: '_boundsToCenter',\n\t value: function _boundsToCenter(bounds) {\n\t var x = bounds[0] + (bounds[2] - bounds[0]) / 2;\n\t var y = bounds[1] + (bounds[3] - bounds[1]) / 2;\n\t\n\t return [x, y];\n\t }\n\t }, {\n\t key: '_getSide',\n\t value: function _getSide(bounds) {\n\t return new _three2['default'].Vector3(bounds[0], 0, bounds[3]).sub(new _three2['default'].Vector3(bounds[0], 0, bounds[1])).length();\n\t }\n\t }]);\n\t\n\t return Tile;\n\t})();\n\t\n\texports['default'] = Tile;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 55 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tBoxHelper = function (object) {\n\t\n\t\tvar indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]);\n\t\tvar positions = new Float32Array(8 * 3);\n\t\n\t\tvar geometry = new _three2['default'].BufferGeometry();\n\t\tgeometry.setIndex(new _three2['default'].BufferAttribute(indices, 1));\n\t\tgeometry.addAttribute('position', new _three2['default'].BufferAttribute(positions, 3));\n\t\n\t\t_three2['default'].LineSegments.call(this, geometry, new _three2['default'].LineBasicMaterial({ linewidth: 2, color: 0xff0000 }));\n\t\n\t\tif (object !== undefined) {\n\t\n\t\t\tthis.update(object);\n\t\t}\n\t};\n\t\n\tBoxHelper.prototype = Object.create(_three2['default'].LineSegments.prototype);\n\tBoxHelper.prototype.constructor = BoxHelper;\n\t\n\tBoxHelper.prototype.update = (function () {\n\t\n\t\tvar box = new _three2['default'].Box3();\n\t\n\t\treturn function (object) {\n\t\n\t\t\tbox.setFromObject(object);\n\t\n\t\t\tif (box.isEmpty()) return;\n\t\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\t\n\t\t\t/*\n\t 5____4\n\t 1/___0/|\n\t | 6__|_7\n\t 2/___3/\n\t \t0: max.x, max.y, max.z\n\t 1: min.x, max.y, max.z\n\t 2: min.x, min.y, max.z\n\t 3: max.x, min.y, max.z\n\t 4: max.x, max.y, min.z\n\t 5: min.x, max.y, min.z\n\t 6: min.x, min.y, min.z\n\t 7: max.x, min.y, min.z\n\t */\n\t\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\t\n\t\t\tarray[0] = max.x;array[1] = max.y;array[2] = max.z;\n\t\t\tarray[3] = min.x;array[4] = max.y;array[5] = max.z;\n\t\t\tarray[6] = min.x;array[7] = min.y;array[8] = max.z;\n\t\t\tarray[9] = max.x;array[10] = min.y;array[11] = max.z;\n\t\t\tarray[12] = max.x;array[13] = max.y;array[14] = min.z;\n\t\t\tarray[15] = min.x;array[16] = max.y;array[17] = min.z;\n\t\t\tarray[18] = min.x;array[19] = min.y;array[20] = min.z;\n\t\t\tarray[21] = max.x;array[22] = min.y;array[23] = min.z;\n\t\n\t\t\tposition.needsUpdate = true;\n\t\n\t\t\tthis.geometry.computeBoundingSphere();\n\t\t};\n\t})();\n\t\n\texports['default'] = BoxHelper;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 56 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\texports['default'] = function (colour, skyboxTarget) {\n\t var canvas = document.createElement('canvas');\n\t canvas.width = 1;\n\t canvas.height = 1;\n\t\n\t var context = canvas.getContext('2d');\n\t context.fillStyle = colour;\n\t context.fillRect(0, 0, canvas.width, canvas.height);\n\t // context.strokeStyle = '#D0D0CF';\n\t // context.strokeRect(0, 0, canvas.width, canvas.height);\n\t\n\t var texture = new _three2['default'].Texture(canvas);\n\t\n\t // // Silky smooth images when tilted\n\t // texture.magFilter = THREE.LinearFilter;\n\t // texture.minFilter = THREE.LinearMipMapLinearFilter;\n\t // //\n\t // // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t // texture.anisotropy = 4;\n\t\n\t // texture.wrapS = THREE.RepeatWrapping;\n\t // texture.wrapT = THREE.RepeatWrapping;\n\t // texture.repeat.set(segments, segments);\n\t\n\t texture.needsUpdate = true;\n\t\n\t var material;\n\t\n\t if (!skyboxTarget) {\n\t material = new _three2['default'].MeshBasicMaterial({\n\t map: texture,\n\t depthWrite: false\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t map: texture,\n\t depthWrite: false\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMap = skyboxTarget;\n\t }\n\t\n\t return material;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 57 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _TileLayer2 = __webpack_require__(43);\n\t\n\tvar _TileLayer3 = _interopRequireDefault(_TileLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _GeoJSONTile = __webpack_require__(58);\n\t\n\tvar _GeoJSONTile2 = _interopRequireDefault(_GeoJSONTile);\n\t\n\tvar _lodashThrottle = __webpack_require__(35);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Offer on-the-fly slicing of static, non-tile-based GeoJSON files into a\n\t// tile grid using geojson-vt\n\t//\n\t// See: https://github.com/mapbox/geojson-vt\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Consider pausing per-frame output during movement so there's little to\n\t// no jank caused by previous tiles still processing\n\t\n\t// This tile layer only updates the quadtree after world movement has occurred\n\t//\n\t// Tiles from previous quadtree updates are updated and outputted every frame\n\t// (or at least every frame, throttled to some amount)\n\t//\n\t// This is because the complexity of TopoJSON tiles requires a lot of processing\n\t// and so makes movement janky if updates occur every frame – only updating\n\t// after movement means frame drops are less obvious due to heavy processing\n\t// occurring while the view is generally stationary\n\t//\n\t// The downside is that until new tiles are requested and outputted you will\n\t// see blank spaces as you orbit and move around\n\t//\n\t// An added benefit is that it dramatically reduces the number of tiles being\n\t// requested over a period of time and the time it takes to go from request to\n\t// screen output\n\t//\n\t// It may be possible to perform these updates per-frame once Web Worker\n\t// processing is added\n\t\n\tvar GeoJSONTileLayer = (function (_TileLayer) {\n\t _inherits(GeoJSONTileLayer, _TileLayer);\n\t\n\t function GeoJSONTileLayer(path, options) {\n\t _classCallCheck(this, GeoJSONTileLayer);\n\t\n\t var defaults = {\n\t maxLOD: 14,\n\t distance: 30000\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'constructor', this).call(this, options);\n\t\n\t this._path = path;\n\t }\n\t\n\t _createClass(GeoJSONTileLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), '_onAdd', _this).call(_this, world).then(function () {\n\t // Trigger initial quadtree calculation on the next frame\n\t //\n\t // TODO: This is a hack to ensure the camera is all set up - a better\n\t // solution should be found\n\t setTimeout(function () {\n\t _this._calculateLOD();\n\t _this._initEvents();\n\t }, 0);\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t // Run LOD calculations based on render calls\n\t //\n\t // Throttled to 1 LOD calculation per 100ms\n\t this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._onWorldUpdate, 100);\n\t\n\t this._world.on('preUpdate', this._throttledWorldUpdate, this);\n\t this._world.on('move', this._onWorldMove, this);\n\t this._world.on('controlsMove', this._onControlsMove, this);\n\t }\n\t\n\t // Update and output tiles each frame (throttled)\n\t }, {\n\t key: '_onWorldUpdate',\n\t value: function _onWorldUpdate() {\n\t if (this._pauseOutput) {\n\t return;\n\t }\n\t\n\t this._outputTiles();\n\t }\n\t\n\t // Update tiles grid after world move, but don't output them\n\t }, {\n\t key: '_onWorldMove',\n\t value: function _onWorldMove(latlon, point) {\n\t this._pauseOutput = false;\n\t this._calculateLOD();\n\t }\n\t\n\t // Pause updates during control movement for less visual jank\n\t }, {\n\t key: '_onControlsMove',\n\t value: function _onControlsMove() {\n\t this._pauseOutput = true;\n\t }\n\t }, {\n\t key: '_createTile',\n\t value: function _createTile(quadcode, layer) {\n\t var options = {};\n\t\n\t // if (this._options.filter) {\n\t // options.filter = this._options.filter;\n\t // }\n\t //\n\t // if (this._options.style) {\n\t // options.style = this._options.style;\n\t // }\n\t //\n\t // if (this._options.topojson) {\n\t // options.topojson = true;\n\t // }\n\t //\n\t // if (this._options.interactive) {\n\t // options.interactive = true;\n\t // }\n\t //\n\t // if (this._options.onClick) {\n\t // options.onClick = this._options.onClick;\n\t // }\n\t\n\t return new _GeoJSONTile2['default'](quadcode, this._path, layer, this._options);\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._world.off('preUpdate', this._throttledWorldUpdate);\n\t this._world.off('move', this._onWorldMove);\n\t\n\t this._throttledWorldUpdate = null;\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return GeoJSONTileLayer;\n\t})(_TileLayer3['default']);\n\t\n\texports['default'] = GeoJSONTileLayer;\n\t\n\tvar noNew = function noNew(path, options) {\n\t return new GeoJSONTileLayer(path, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.geoJSONTileLayer = noNew;\n\n/***/ },\n/* 58 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Tile2 = __webpack_require__(54);\n\t\n\tvar _Tile3 = _interopRequireDefault(_Tile2);\n\t\n\tvar _GeoJSONLayer = __webpack_require__(59);\n\t\n\tvar _vendorBoxHelper = __webpack_require__(55);\n\t\n\tvar _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _reqwest = __webpack_require__(61);\n\t\n\tvar _reqwest2 = _interopRequireDefault(_reqwest);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\t// import Offset from 'polygon-offset';\n\t\n\tvar _utilGeoJSON = __webpack_require__(63);\n\t\n\tvar _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON);\n\t\n\tvar _utilBuffer = __webpack_require__(69);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(70);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\t// TODO: Map picking IDs to some reference within the tile data / geometry so\n\t// that something useful can be done when an object is picked / clicked on\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Perform tile request and processing in a Web Worker\n\t//\n\t// Use Operative (https://github.com/padolsey/operative)\n\t//\n\t// Would it make sense to have the worker functionality defined in a static\n\t// method so it only gets initialised once and not on every tile instance?\n\t//\n\t// Otherwise, worker processing logic would have to go in the tile layer so not\n\t// to waste loads of time setting up a brand new worker with three.js for each\n\t// tile every single time.\n\t//\n\t// Unsure of the best way to get three.js and VIZI into the worker\n\t//\n\t// Would need to set up a CRS / projection identical to the world instance\n\t//\n\t// Is it possible to bypass requirements on external script by having multiple\n\t// simple worker methods that each take enough inputs to perform a single task\n\t// without requiring VIZI or three.js? So long as the heaviest logic is done in\n\t// the worker and transferrable objects are used then it should be better than\n\t// nothing. Would probably still need things like earcut...\n\t//\n\t// After all, the three.js logic and object creation will still need to be\n\t// done on the main thread regardless so the worker should try to do as much as\n\t// possible with as few dependencies as possible.\n\t//\n\t// Have a look at how this is done in Tangram before implementing anything as\n\t// the approach there is pretty similar and robust.\n\t\n\tvar GeoJSONTile = (function (_Tile) {\n\t _inherits(GeoJSONTile, _Tile);\n\t\n\t function GeoJSONTile(quadcode, path, layer, options) {\n\t _classCallCheck(this, GeoJSONTile);\n\t\n\t _get(Object.getPrototypeOf(GeoJSONTile.prototype), 'constructor', this).call(this, quadcode, path, layer);\n\t\n\t this._defaultStyle = _utilGeoJSON2['default'].defaultStyle;\n\t\n\t var defaults = {\n\t output: true,\n\t outputToScene: false,\n\t interactive: false,\n\t topojson: false,\n\t filter: null,\n\t onEachFeature: null,\n\t polygonMaterial: null,\n\t onPolygonMesh: null,\n\t onPolygonBufferAttributes: null,\n\t polylineMaterial: null,\n\t onPolylineMesh: null,\n\t onPolylineBufferAttributes: null,\n\t pointGeometry: null,\n\t pointMaterial: null,\n\t onPointMesh: null,\n\t style: _utilGeoJSON2['default'].defaultStyle,\n\t keepFeatures: false\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (typeof options.style === 'function') {\n\t _options.style = options.style;\n\t } else {\n\t _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);\n\t }\n\t\n\t this._options = _options;\n\t }\n\t\n\t // Request data for the tile\n\t\n\t _createClass(GeoJSONTile, [{\n\t key: 'requestTileAsync',\n\t value: function requestTileAsync() {\n\t var _this = this;\n\t\n\t // Making this asynchronous really speeds up the LOD framerate\n\t setTimeout(function () {\n\t if (!_this._mesh) {\n\t _this._mesh = _this._createMesh();\n\t\n\t // this._shadowCanvas = this._createShadowCanvas();\n\t\n\t _this._requestTile();\n\t }\n\t }, 0);\n\t }\n\t\n\t // TODO: Destroy GeoJSONLayer\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Cancel any pending requests\n\t this._abortRequest();\n\t\n\t // Clear request reference\n\t this._request = null;\n\t\n\t if (this._geojsonLayer) {\n\t this._geojsonLayer.destroy();\n\t this._geojsonLayer = null;\n\t }\n\t\n\t this._mesh = null;\n\t\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t\n\t _get(Object.getPrototypeOf(GeoJSONTile.prototype), 'destroy', this).call(this);\n\t }\n\t }, {\n\t key: '_createMesh',\n\t value: function _createMesh() {\n\t // Something went wrong and the tile\n\t //\n\t // Possibly removed by the cache before loaded\n\t if (!this._center) {\n\t return;\n\t }\n\t\n\t var mesh = new _three2['default'].Object3D();\n\t // mesh.add(this._createDebugMesh());\n\t\n\t return mesh;\n\t }\n\t }, {\n\t key: '_createDebugMesh',\n\t value: function _createDebugMesh() {\n\t var canvas = document.createElement('canvas');\n\t canvas.width = 256;\n\t canvas.height = 256;\n\t\n\t var context = canvas.getContext('2d');\n\t context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n\t context.fillStyle = '#ff0000';\n\t context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n\t context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\t\n\t var texture = new _three2['default'].Texture(canvas);\n\t\n\t // Silky smooth images when tilted\n\t texture.magFilter = _three2['default'].LinearFilter;\n\t texture.minFilter = _three2['default'].LinearMipMapLinearFilter;\n\t\n\t // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t texture.anisotropy = 4;\n\t\n\t texture.needsUpdate = true;\n\t\n\t var material = new _three2['default'].MeshBasicMaterial({\n\t map: texture,\n\t transparent: true,\n\t depthWrite: false\n\t });\n\t\n\t var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);\n\t var mesh = new _three2['default'].Mesh(geom, material);\n\t\n\t mesh.rotation.x = -90 * Math.PI / 180;\n\t mesh.position.y = 0.1;\n\t\n\t return mesh;\n\t }\n\t\n\t // _createShadowCanvas() {\n\t // var canvas = document.createElement('canvas');\n\t //\n\t // // Rendered at a low resolution and later scaled up for a low-quality blur\n\t // canvas.width = 512;\n\t // canvas.height = 512;\n\t //\n\t // return canvas;\n\t // }\n\t\n\t // _addShadow(coordinates) {\n\t // var ctx = this._shadowCanvas.getContext('2d');\n\t // var width = this._shadowCanvas.width;\n\t // var height = this._shadowCanvas.height;\n\t //\n\t // var _coords;\n\t // var _offset;\n\t // var offset = new Offset();\n\t //\n\t // // Transform coordinates to shadowCanvas space and draw on canvas\n\t // coordinates.forEach((ring, index) => {\n\t // ctx.beginPath();\n\t //\n\t // _coords = ring.map(coord => {\n\t // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n\t // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n\t // return [xFrac * width, yFrac * height];\n\t // });\n\t //\n\t // if (index > 0) {\n\t // _offset = _coords;\n\t // } else {\n\t // _offset = offset.data(_coords).padding(1.3);\n\t // }\n\t //\n\t // // TODO: This is super flaky and crashes the browser if run on anything\n\t // // put the outer ring (potentially due to winding)\n\t // _offset.forEach((coord, index) => {\n\t // // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n\t // // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n\t //\n\t // if (index === 0) {\n\t // ctx.moveTo(coord[0], coord[1]);\n\t // } else {\n\t // ctx.lineTo(coord[0], coord[1]);\n\t // }\n\t // });\n\t //\n\t // ctx.closePath();\n\t // });\n\t //\n\t // ctx.fillStyle = 'rgba(80, 80, 80, 0.7)';\n\t // ctx.fill();\n\t // }\n\t\n\t }, {\n\t key: '_requestTile',\n\t value: function _requestTile() {\n\t var _this2 = this;\n\t\n\t var urlParams = {\n\t x: this._tile[0],\n\t y: this._tile[1],\n\t z: this._tile[2]\n\t };\n\t\n\t var url = this._getTileURL(urlParams);\n\t\n\t this._request = (0, _reqwest2['default'])({\n\t url: url,\n\t type: 'json',\n\t crossOrigin: true\n\t }).then(function (res) {\n\t // Clear request reference\n\t _this2._request = null;\n\t _this2._processTileData(res);\n\t })['catch'](function (err) {\n\t console.error(err);\n\t\n\t // Clear request reference\n\t _this2._request = null;\n\t });\n\t }\n\t }, {\n\t key: '_processTileData',\n\t value: function _processTileData(data) {\n\t var _this3 = this;\n\t\n\t console.time(this._tile);\n\t\n\t // Using this creates a huge amount of memory due to the quantity of tiles\n\t this._geojsonLayer = (0, _GeoJSONLayer.geoJSONLayer)(data, this._options);\n\t this._geojsonLayer.addTo(this._world).then(function () {\n\t _this3._mesh = _this3._geojsonLayer._object3D;\n\t _this3._pickingMesh = _this3._geojsonLayer._pickingMesh;\n\t\n\t // Free the GeoJSON memory as we don't need it\n\t //\n\t // TODO: This should probably be a method within GeoJSONLayer\n\t _this3._geojsonLayer._geojson = null;\n\t\n\t // TODO: Fix or store shadow canvas stuff and get rid of this code\n\t // Draw footprint on shadow canvas\n\t //\n\t // TODO: Disabled for the time-being until it can be sped up / moved to\n\t // a worker\n\t // this._addShadow(coordinates);\n\t\n\t // Output shadow canvas\n\t\n\t // TODO: Disabled for the time-being until it can be sped up / moved to\n\t // a worker\n\t\n\t // var texture = new THREE.Texture(this._shadowCanvas);\n\t //\n\t // // Silky smooth images when tilted\n\t // texture.magFilter = THREE.LinearFilter;\n\t // texture.minFilter = THREE.LinearMipMapLinearFilter;\n\t //\n\t // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t // texture.anisotropy = 4;\n\t //\n\t // texture.needsUpdate = true;\n\t //\n\t // var material;\n\t // if (!this._world._environment._skybox) {\n\t // material = new THREE.MeshBasicMaterial({\n\t // map: texture,\n\t // transparent: true,\n\t // depthWrite: false\n\t // });\n\t // } else {\n\t // material = new THREE.MeshStandardMaterial({\n\t // map: texture,\n\t // transparent: true,\n\t // depthWrite: false\n\t // });\n\t // material.roughness = 1;\n\t // material.metalness = 0.1;\n\t // material.envMap = this._world._environment._skybox.getRenderTarget();\n\t // }\n\t //\n\t // var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n\t // var mesh = new THREE.Mesh(geom, material);\n\t //\n\t // mesh.castShadow = false;\n\t // mesh.receiveShadow = false;\n\t // mesh.renderOrder = 1;\n\t //\n\t // mesh.rotation.x = -90 * Math.PI / 180;\n\t //\n\t // this._mesh.add(mesh);\n\t\n\t _this3._ready = true;\n\t console.timeEnd(_this3._tile);\n\t });\n\t }\n\t }, {\n\t key: '_abortRequest',\n\t value: function _abortRequest() {\n\t if (!this._request) {\n\t return;\n\t }\n\t\n\t this._request.abort();\n\t }\n\t }]);\n\t\n\t return GeoJSONTile;\n\t})(_Tile3['default']);\n\t\n\texports['default'] = GeoJSONTile;\n\t\n\tvar noNew = function noNew(quadcode, path, layer, options) {\n\t return new GeoJSONTile(quadcode, path, layer, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.geoJSONTile = noNew;\n\n/***/ },\n/* 59 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Consider adopting GeoJSON CSS\n\t// http://wiki.openstreetmap.org/wiki/Geojson_CSS\n\t\n\t// TODO: Allow interaction to be defined per-layer to save on resources\n\t//\n\t// For example, only allow polygons to be interactive via a polygonInteractive\n\t// option\n\t\n\tvar _LayerGroup2 = __webpack_require__(60);\n\t\n\tvar _LayerGroup3 = _interopRequireDefault(_LayerGroup2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _reqwest = __webpack_require__(61);\n\t\n\tvar _reqwest2 = _interopRequireDefault(_reqwest);\n\t\n\tvar _utilGeoJSON = __webpack_require__(63);\n\t\n\tvar _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON);\n\t\n\tvar _utilBuffer = __webpack_require__(69);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(70);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _geometryPolygonLayer = __webpack_require__(72);\n\t\n\tvar _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer);\n\t\n\tvar _geometryPolylineLayer = __webpack_require__(73);\n\t\n\tvar _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer);\n\t\n\tvar _geometryPointLayer = __webpack_require__(74);\n\t\n\tvar _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer);\n\t\n\tvar GeoJSONLayer = (function (_LayerGroup) {\n\t _inherits(GeoJSONLayer, _LayerGroup);\n\t\n\t function GeoJSONLayer(geojson, options) {\n\t _classCallCheck(this, GeoJSONLayer);\n\t\n\t var defaults = {\n\t output: false,\n\t interactive: false,\n\t topojson: false,\n\t filter: null,\n\t onEachFeature: null,\n\t polygonMaterial: null,\n\t onPolygonMesh: null,\n\t onPolygonBufferAttributes: null,\n\t polylineMaterial: null,\n\t onPolylineMesh: null,\n\t onPolylineBufferAttributes: null,\n\t pointGeometry: null,\n\t pointMaterial: null,\n\t onPointMesh: null,\n\t style: _utilGeoJSON2['default'].defaultStyle,\n\t keepFeatures: true\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (typeof options.style === 'function') {\n\t _options.style = options.style;\n\t } else {\n\t _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);\n\t }\n\t\n\t _get(Object.getPrototypeOf(GeoJSONLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._geojson = geojson;\n\t }\n\t\n\t _createClass(GeoJSONLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (this.isOutput()) {\n\t this._pickingMesh = new THREE.Object3D();\n\t this.addToPicking(this._pickingMesh);\n\t }\n\t\n\t // Request data from URL if needed\n\t if (typeof this._geojson === 'string') {\n\t return this._requestData(this._geojson);\n\t } else {\n\t // Process and add GeoJSON to layer\n\t return this._processData(this._geojson);\n\t }\n\t }\n\t }, {\n\t key: '_requestData',\n\t value: function _requestData(url) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._request = (0, _reqwest2['default'])({\n\t url: url,\n\t type: 'json',\n\t crossOrigin: true\n\t }).then(function (res) {\n\t // Clear request reference\n\t _this._request = null;\n\t _this._processData(res).then(function () {\n\t resolve(_this);\n\t });\n\t })['catch'](function (err) {\n\t console.error(err);\n\t\n\t // Clear request reference\n\t _this._request = null;\n\t });\n\t });\n\t }\n\t\n\t // TODO: Wrap into a helper method so this isn't duplicated in the tiled\n\t // GeoJSON output layer\n\t //\n\t // Need to be careful as to not make it impossible to fork this off into a\n\t // worker script at a later stage\n\t }, {\n\t key: '_processData',\n\t value: function _processData(data) {\n\t var _this2 = this;\n\t\n\t // Collects features into a single FeatureCollection\n\t //\n\t // Also converts TopoJSON to GeoJSON if instructed\n\t this._geojson = _utilGeoJSON2['default'].collectFeatures(data, this._options.topojson);\n\t\n\t // TODO: Check that GeoJSON is valid / usable\n\t\n\t var features = this._geojson.features;\n\t\n\t // Run filter, if provided\n\t if (this._options.filter) {\n\t features = this._geojson.features.filter(this._options.filter);\n\t }\n\t\n\t var defaults = {};\n\t\n\t // Assume that a style won't be set per feature\n\t var style = this._options.style;\n\t\n\t var options;\n\t features.forEach(function (feature) {\n\t // Get per-feature style object, if provided\n\t if (typeof _this2._options.style === 'function') {\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _this2._options.style(feature));\n\t }\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, {\n\t // If merging feature layers, stop them outputting themselves\n\t // If not, let feature layers output themselves to the world\n\t output: !_this2.isOutput(),\n\t interactive: _this2._options.interactive,\n\t style: style\n\t });\n\t\n\t var layer = _this2._featureToLayer(feature, options);\n\t\n\t if (!layer) {\n\t return;\n\t }\n\t\n\t // Sometimes you don't want to store a reference to the feature\n\t //\n\t // For example, to save memory when being used by tile layers\n\t if (_this2._options.keepFeatures) {\n\t layer.feature = feature;\n\t }\n\t\n\t // If defined, call a function for each feature\n\t //\n\t // This is commonly used for adding event listeners from the user script\n\t if (_this2._options.onEachFeature) {\n\t _this2._options.onEachFeature(feature, layer);\n\t }\n\t\n\t // TODO: Make this a promise array and only continue on completion\n\t _this2.addLayer(layer);\n\t });\n\t\n\t // If merging layers do that now, otherwise skip as the geometry layers\n\t // should have already outputted themselves\n\t if (!this.isOutput()) {\n\t return;\n\t }\n\t\n\t // From here on we can assume that we want to merge the layers\n\t\n\t var polygonAttributes = [];\n\t var polygonFlat = true;\n\t\n\t var polylineAttributes = [];\n\t var pointAttributes = [];\n\t\n\t this._layers.forEach(function (layer) {\n\t if (layer instanceof _geometryPolygonLayer2['default']) {\n\t polygonAttributes.push(layer.getBufferAttributes());\n\t\n\t if (polygonFlat && !layer.isFlat()) {\n\t polygonFlat = false;\n\t }\n\t } else if (layer instanceof _geometryPolylineLayer2['default']) {\n\t polylineAttributes.push(layer.getBufferAttributes());\n\t } else if (layer instanceof _geometryPointLayer2['default']) {\n\t pointAttributes.push(layer.getBufferAttributes());\n\t }\n\t });\n\t\n\t if (polygonAttributes.length > 0) {\n\t var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes);\n\t this._setPolygonMesh(mergedPolygonAttributes, polygonFlat);\n\t this.add(this._polygonMesh);\n\t }\n\t\n\t if (polylineAttributes.length > 0) {\n\t var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes);\n\t this._setPolylineMesh(mergedPolylineAttributes);\n\t this.add(this._polylineMesh);\n\t }\n\t\n\t if (pointAttributes.length > 0) {\n\t var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes);\n\t this._setPointMesh(mergedPointAttributes);\n\t this.add(this._pointMesh);\n\t }\n\t\n\t // Clean up layers\n\t //\n\t // TODO: Are there ever situations where the unmerged buffer attributes\n\t // and coordinates would still be required?\n\t this._layers.forEach(function (layer) {\n\t layer.clearBufferAttributes();\n\t layer.clearCoordinates();\n\t });\n\t\n\t return Promise.resolve();\n\t }\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // TODO: De-dupe this from the individual mesh creation logic within each\n\t // geometry layer (materials, settings, etc)\n\t //\n\t // Could make this an abstract method for each geometry layer\n\t }, {\n\t key: '_setPolygonMesh',\n\t value: function _setPolygonMesh(attributes, flat) {\n\t var geometry = new THREE.BufferGeometry();\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n\t geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n\t geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\t\n\t if (attributes.pickingIds) {\n\t geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t // TODO: Make this work when style is a function per feature\n\t var style = typeof this._options.style === 'function' ? this._options.style(this._geojson.features[0]) : this._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t var material;\n\t if (this._options.polygonMaterial && this._options.polygonMaterial instanceof THREE.Material) {\n\t material = this._options.polygonMaterial;\n\t } else if (!this._world._environment._skybox) {\n\t material = new THREE.MeshPhongMaterial({\n\t vertexColors: THREE.VertexColors,\n\t side: THREE.BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t } else {\n\t material = new THREE.MeshStandardMaterial({\n\t vertexColors: THREE.VertexColors,\n\t side: THREE.BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = this._world._environment._skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof this._options.onPolygonMesh === 'function') {\n\t mesh = this._options.onPolygonMesh(geometry, material);\n\t } else {\n\t mesh = new THREE.Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t mesh.receiveShadow = true;\n\t }\n\t\n\t if (flat) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = 1;\n\t }\n\t\n\t if (this._options.interactive && this._pickingMesh) {\n\t material = new _enginePickingMaterial2['default']();\n\t material.side = THREE.BackSide;\n\t\n\t var pickingMesh = new THREE.Mesh(geometry, material);\n\t this._pickingMesh.add(pickingMesh);\n\t }\n\t\n\t this._polygonMesh = mesh;\n\t }\n\t }, {\n\t key: '_setPolylineMesh',\n\t value: function _setPolylineMesh(attributes) {\n\t var geometry = new THREE.BufferGeometry();\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n\t\n\t if (attributes.normals) {\n\t geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n\t }\n\t\n\t geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\t\n\t if (attributes.pickingIds) {\n\t geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t // TODO: Make this work when style is a function per feature\n\t var style = typeof this._options.style === 'function' ? this._options.style(this._geojson.features[0]) : this._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t var material;\n\t if (this._options.polylineMaterial && this._options.polylineMaterial instanceof THREE.Material) {\n\t material = this._options.polylineMaterial;\n\t } else {\n\t material = new THREE.LineBasicMaterial({\n\t vertexColors: THREE.VertexColors,\n\t linewidth: style.lineWidth,\n\t transparent: style.lineTransparent,\n\t opacity: style.lineOpacity,\n\t blending: style.lineBlending\n\t });\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof this._options.onPolylineMesh === 'function') {\n\t mesh = this._options.onPolylineMesh(geometry, material);\n\t } else {\n\t mesh = new THREE.LineSegments(geometry, material);\n\t\n\t if (style.lineRenderOrder !== undefined) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = style.lineRenderOrder;\n\t }\n\t\n\t mesh.castShadow = true;\n\t // mesh.receiveShadow = true;\n\t }\n\t\n\t // TODO: Allow this to be overridden, or copy mesh instead of creating a new\n\t // one just for picking\n\t if (this._options.interactive && this._pickingMesh) {\n\t material = new _enginePickingMaterial2['default']();\n\t // material.side = THREE.BackSide;\n\t\n\t // Make the line wider / easier to pick\n\t material.linewidth = style.lineWidth + material.linePadding;\n\t\n\t var pickingMesh = new THREE.LineSegments(geometry, material);\n\t this._pickingMesh.add(pickingMesh);\n\t }\n\t\n\t this._polylineMesh = mesh;\n\t }\n\t }, {\n\t key: '_setPointMesh',\n\t value: function _setPointMesh(attributes) {\n\t var geometry = new THREE.BufferGeometry();\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n\t geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n\t geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\t\n\t if (attributes.pickingIds) {\n\t geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (this._options.pointMaterial && this._options.pointMaterial instanceof THREE.Material) {\n\t material = this._options.pointMaterial;\n\t } else if (!this._world._environment._skybox) {\n\t material = new THREE.MeshPhongMaterial({\n\t vertexColors: THREE.VertexColors\n\t // side: THREE.BackSide\n\t });\n\t } else {\n\t material = new THREE.MeshStandardMaterial({\n\t vertexColors: THREE.VertexColors\n\t // side: THREE.BackSide\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = this._world._environment._skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh callback, if defined\n\t if (typeof this._options.onPointMesh === 'function') {\n\t mesh = this._options.onPointMesh(geometry, material);\n\t } else {\n\t mesh = new THREE.Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t // mesh.receiveShadow = true;\n\t }\n\t\n\t if (this._options.interactive && this._pickingMesh) {\n\t material = new _enginePickingMaterial2['default']();\n\t // material.side = THREE.BackSide;\n\t\n\t var pickingMesh = new THREE.Mesh(geometry, material);\n\t this._pickingMesh.add(pickingMesh);\n\t }\n\t\n\t this._pointMesh = mesh;\n\t }\n\t\n\t // TODO: Support all GeoJSON geometry types\n\t }, {\n\t key: '_featureToLayer',\n\t value: function _featureToLayer(feature, options) {\n\t var geometry = feature.geometry;\n\t var coordinates = geometry.coordinates ? geometry.coordinates : null;\n\t\n\t if (!coordinates || !geometry) {\n\t return;\n\t }\n\t\n\t if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n\t // Get material instance to use for polygon, if provided\n\t if (typeof this._options.polygonMaterial === 'function') {\n\t options.geometry = this._options.polygonMaterial(feature);\n\t }\n\t\n\t if (typeof this._options.onPolygonMesh === 'function') {\n\t options.onMesh = this._options.onPolygonMesh;\n\t }\n\t\n\t // Pass onBufferAttributes callback, if defined\n\t if (typeof this._options.onPolygonBufferAttributes === 'function') {\n\t options.onBufferAttributes = this._options.onPolygonBufferAttributes;\n\t }\n\t\n\t return new _geometryPolygonLayer2['default'](coordinates, options);\n\t }\n\t\n\t if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n\t // Get material instance to use for line, if provided\n\t if (typeof this._options.lineMaterial === 'function') {\n\t options.geometry = this._options.lineMaterial(feature);\n\t }\n\t\n\t if (typeof this._options.onPolylineMesh === 'function') {\n\t options.onMesh = this._options.onPolylineMesh;\n\t }\n\t\n\t // Pass onBufferAttributes callback, if defined\n\t if (typeof this._options.onPolylineBufferAttributes === 'function') {\n\t options.onBufferAttributes = this._options.onPolylineBufferAttributes;\n\t }\n\t\n\t return new _geometryPolylineLayer2['default'](coordinates, options);\n\t }\n\t\n\t if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n\t // Get geometry object to use for point, if provided\n\t if (typeof this._options.pointGeometry === 'function') {\n\t options.geometry = this._options.pointGeometry(feature);\n\t }\n\t\n\t // Get material instance to use for point, if provided\n\t if (typeof this._options.pointMaterial === 'function') {\n\t options.geometry = this._options.pointMaterial(feature);\n\t }\n\t\n\t if (typeof this._options.onPointMesh === 'function') {\n\t options.onMesh = this._options.onPointMesh;\n\t }\n\t\n\t return new _geometryPointLayer2['default'](coordinates, options);\n\t }\n\t }\n\t }, {\n\t key: '_abortRequest',\n\t value: function _abortRequest() {\n\t if (!this._request) {\n\t return;\n\t }\n\t\n\t this._request.abort();\n\t }\n\t\n\t // Destroy the layers and remove them from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Cancel any pending requests\n\t this._abortRequest();\n\t\n\t // Clear request reference\n\t this._request = null;\n\t\n\t this._geojson = null;\n\t\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t if (this._polygonMesh) {\n\t this._polygonMesh = null;\n\t }\n\t\n\t if (this._polylineMesh) {\n\t this._polylineMesh = null;\n\t }\n\t\n\t if (this._pointMesh) {\n\t this._pointMesh = null;\n\t }\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(GeoJSONLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return GeoJSONLayer;\n\t})(_LayerGroup3['default']);\n\t\n\texports['default'] = GeoJSONLayer;\n\t\n\tvar noNew = function noNew(geojson, options) {\n\t return new GeoJSONLayer(geojson, options);\n\t};\n\t\n\texports.geoJSONLayer = noNew;\n\n/***/ },\n/* 60 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(32);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar LayerGroup = (function (_Layer) {\n\t _inherits(LayerGroup, _Layer);\n\t\n\t function LayerGroup(options) {\n\t _classCallCheck(this, LayerGroup);\n\t\n\t var defaults = {\n\t output: false\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(LayerGroup.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._layers = [];\n\t }\n\t\n\t _createClass(LayerGroup, [{\n\t key: 'addLayer',\n\t value: function addLayer(layer) {\n\t this._layers.push(layer);\n\t return this._world.addLayer(layer);\n\t }\n\t }, {\n\t key: 'removeLayer',\n\t value: function removeLayer(layer) {\n\t var layerIndex = this._layers.indexOf(layer);\n\t\n\t if (layerIndex > -1) {\n\t // Remove from this._layers\n\t this._layers.splice(layerIndex, 1);\n\t };\n\t\n\t this._world.removeLayer(layer);\n\t }\n\t }, {\n\t key: '_onAdd',\n\t value: function _onAdd(world) {}\n\t\n\t // Destroy the layers and remove them from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // TODO: Sometimes this is already null, find out why\n\t if (this._layers) {\n\t for (var i = 0; i < this._layers.length; i++) {\n\t this._layers[i].destroy();\n\t }\n\t\n\t this._layers = null;\n\t }\n\t\n\t _get(Object.getPrototypeOf(LayerGroup.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return LayerGroup;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = LayerGroup;\n\t\n\tvar noNew = function noNew(options) {\n\t return new LayerGroup(options);\n\t};\n\t\n\texports.layerGroup = noNew;\n\n/***/ },\n/* 61 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n\t * Reqwest! A general purpose XHR connection manager\n\t * license MIT (c) Dustin Diaz 2015\n\t * https://github.com/ded/reqwest\n\t */\n\t\n\t!function (name, context, definition) {\n\t if (typeof module != 'undefined' && module.exports) module.exports = definition()\n\t else if (true) !(__WEBPACK_AMD_DEFINE_FACTORY__ = (definition), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))\n\t else context[name] = definition()\n\t}('reqwest', this, function () {\n\t\n\t var context = this\n\t\n\t if ('window' in context) {\n\t var doc = document\n\t , byTag = 'getElementsByTagName'\n\t , head = doc[byTag]('head')[0]\n\t } else {\n\t var XHR2\n\t try {\n\t XHR2 = __webpack_require__(62)\n\t } catch (ex) {\n\t throw new Error('Peer dependency `xhr2` required! Please npm install xhr2')\n\t }\n\t }\n\t\n\t\n\t var httpsRe = /^http/\n\t , protocolRe = /(^\\w+):\\/\\//\n\t , twoHundo = /^(20\\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\n\t , readyState = 'readyState'\n\t , contentType = 'Content-Type'\n\t , requestedWith = 'X-Requested-With'\n\t , uniqid = 0\n\t , callbackPrefix = 'reqwest_' + (+new Date())\n\t , lastValue // data stored by the most recent JSONP callback\n\t , xmlHttpRequest = 'XMLHttpRequest'\n\t , xDomainRequest = 'XDomainRequest'\n\t , noop = function () {}\n\t\n\t , isArray = typeof Array.isArray == 'function'\n\t ? Array.isArray\n\t : function (a) {\n\t return a instanceof Array\n\t }\n\t\n\t , defaultHeaders = {\n\t 'contentType': 'application/x-www-form-urlencoded'\n\t , 'requestedWith': xmlHttpRequest\n\t , 'accept': {\n\t '*': 'text/javascript, text/html, application/xml, text/xml, */*'\n\t , 'xml': 'application/xml, text/xml'\n\t , 'html': 'text/html'\n\t , 'text': 'text/plain'\n\t , 'json': 'application/json, text/javascript'\n\t , 'js': 'application/javascript, text/javascript'\n\t }\n\t }\n\t\n\t , xhr = function(o) {\n\t // is it x-domain\n\t if (o['crossOrigin'] === true) {\n\t var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null\n\t if (xhr && 'withCredentials' in xhr) {\n\t return xhr\n\t } else if (context[xDomainRequest]) {\n\t return new XDomainRequest()\n\t } else {\n\t throw new Error('Browser does not support cross-origin requests')\n\t }\n\t } else if (context[xmlHttpRequest]) {\n\t return new XMLHttpRequest()\n\t } else if (XHR2) {\n\t return new XHR2()\n\t } else {\n\t return new ActiveXObject('Microsoft.XMLHTTP')\n\t }\n\t }\n\t , globalSetupOptions = {\n\t dataFilter: function (data) {\n\t return data\n\t }\n\t }\n\t\n\t function succeed(r) {\n\t var protocol = protocolRe.exec(r.url)\n\t protocol = (protocol && protocol[1]) || context.location.protocol\n\t return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response\n\t }\n\t\n\t function handleReadyState(r, success, error) {\n\t return function () {\n\t // use _aborted to mitigate against IE err c00c023f\n\t // (can't read props on aborted request objects)\n\t if (r._aborted) return error(r.request)\n\t if (r._timedOut) return error(r.request, 'Request is aborted: timeout')\n\t if (r.request && r.request[readyState] == 4) {\n\t r.request.onreadystatechange = noop\n\t if (succeed(r)) success(r.request)\n\t else\n\t error(r.request)\n\t }\n\t }\n\t }\n\t\n\t function setHeaders(http, o) {\n\t var headers = o['headers'] || {}\n\t , h\n\t\n\t headers['Accept'] = headers['Accept']\n\t || defaultHeaders['accept'][o['type']]\n\t || defaultHeaders['accept']['*']\n\t\n\t var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData);\n\t // breaks cross-origin requests with legacy browsers\n\t if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']\n\t if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']\n\t for (h in headers)\n\t headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])\n\t }\n\t\n\t function setCredentials(http, o) {\n\t if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n\t http.withCredentials = !!o['withCredentials']\n\t }\n\t }\n\t\n\t function generalCallback(data) {\n\t lastValue = data\n\t }\n\t\n\t function urlappend (url, s) {\n\t return url + (/\\?/.test(url) ? '&' : '?') + s\n\t }\n\t\n\t function handleJsonp(o, fn, err, url) {\n\t var reqId = uniqid++\n\t , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key\n\t , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)\n\t , cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)')\n\t , match = url.match(cbreg)\n\t , script = doc.createElement('script')\n\t , loaded = 0\n\t , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1\n\t\n\t if (match) {\n\t if (match[3] === '?') {\n\t url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name\n\t } else {\n\t cbval = match[3] // provided callback func name\n\t }\n\t } else {\n\t url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em\n\t }\n\t\n\t context[cbval] = generalCallback\n\t\n\t script.type = 'text/javascript'\n\t script.src = url\n\t script.async = true\n\t if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n\t // need this for IE due to out-of-order onreadystatechange(), binding script\n\t // execution to an event listener gives us control over when the script\n\t // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n\t script.htmlFor = script.id = '_reqwest_' + reqId\n\t }\n\t\n\t script.onload = script.onreadystatechange = function () {\n\t if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {\n\t return false\n\t }\n\t script.onload = script.onreadystatechange = null\n\t script.onclick && script.onclick()\n\t // Call the user callback with the last value stored and clean up values and scripts.\n\t fn(lastValue)\n\t lastValue = undefined\n\t head.removeChild(script)\n\t loaded = 1\n\t }\n\t\n\t // Add the script to the DOM head\n\t head.appendChild(script)\n\t\n\t // Enable JSONP timeout\n\t return {\n\t abort: function () {\n\t script.onload = script.onreadystatechange = null\n\t err({}, 'Request is aborted: timeout', {})\n\t lastValue = undefined\n\t head.removeChild(script)\n\t loaded = 1\n\t }\n\t }\n\t }\n\t\n\t function getRequest(fn, err) {\n\t var o = this.o\n\t , method = (o['method'] || 'GET').toUpperCase()\n\t , url = typeof o === 'string' ? o : o['url']\n\t // convert non-string objects to query-string form unless o['processData'] is false\n\t , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')\n\t ? reqwest.toQueryString(o['data'])\n\t : (o['data'] || null)\n\t , http\n\t , sendWait = false\n\t\n\t // if we're working on a GET request and we have data then we should append\n\t // query string to end of URL and not post data\n\t if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n\t url = urlappend(url, data)\n\t data = null\n\t }\n\t\n\t if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)\n\t\n\t // get the xhr from the factory if passed\n\t // if the factory returns null, fall-back to ours\n\t http = (o.xhr && o.xhr(o)) || xhr(o)\n\t\n\t http.open(method, url, o['async'] === false ? false : true)\n\t setHeaders(http, o)\n\t setCredentials(http, o)\n\t if (context[xDomainRequest] && http instanceof context[xDomainRequest]) {\n\t http.onload = fn\n\t http.onerror = err\n\t // NOTE: see\n\t // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e\n\t http.onprogress = function() {}\n\t sendWait = true\n\t } else {\n\t http.onreadystatechange = handleReadyState(this, fn, err)\n\t }\n\t o['before'] && o['before'](http)\n\t if (sendWait) {\n\t setTimeout(function () {\n\t http.send(data)\n\t }, 200)\n\t } else {\n\t http.send(data)\n\t }\n\t return http\n\t }\n\t\n\t function Reqwest(o, fn) {\n\t this.o = o\n\t this.fn = fn\n\t\n\t init.apply(this, arguments)\n\t }\n\t\n\t function setType(header) {\n\t // json, javascript, text/plain, text/html, xml\n\t if (header === null) return undefined; //In case of no content-type.\n\t if (header.match('json')) return 'json'\n\t if (header.match('javascript')) return 'js'\n\t if (header.match('text')) return 'html'\n\t if (header.match('xml')) return 'xml'\n\t }\n\t\n\t function init(o, fn) {\n\t\n\t this.url = typeof o == 'string' ? o : o['url']\n\t this.timeout = null\n\t\n\t // whether request has been fulfilled for purpose\n\t // of tracking the Promises\n\t this._fulfilled = false\n\t // success handlers\n\t this._successHandler = function(){}\n\t this._fulfillmentHandlers = []\n\t // error handlers\n\t this._errorHandlers = []\n\t // complete (both success and fail) handlers\n\t this._completeHandlers = []\n\t this._erred = false\n\t this._responseArgs = {}\n\t\n\t var self = this\n\t\n\t fn = fn || function () {}\n\t\n\t if (o['timeout']) {\n\t this.timeout = setTimeout(function () {\n\t timedOut()\n\t }, o['timeout'])\n\t }\n\t\n\t if (o['success']) {\n\t this._successHandler = function () {\n\t o['success'].apply(o, arguments)\n\t }\n\t }\n\t\n\t if (o['error']) {\n\t this._errorHandlers.push(function () {\n\t o['error'].apply(o, arguments)\n\t })\n\t }\n\t\n\t if (o['complete']) {\n\t this._completeHandlers.push(function () {\n\t o['complete'].apply(o, arguments)\n\t })\n\t }\n\t\n\t function complete (resp) {\n\t o['timeout'] && clearTimeout(self.timeout)\n\t self.timeout = null\n\t while (self._completeHandlers.length > 0) {\n\t self._completeHandlers.shift()(resp)\n\t }\n\t }\n\t\n\t function success (resp) {\n\t var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE\n\t resp = (type !== 'jsonp') ? self.request : resp\n\t // use global data filter on response text\n\t var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)\n\t , r = filteredResponse\n\t try {\n\t resp.responseText = r\n\t } catch (e) {\n\t // can't assign this in IE<=8, just ignore\n\t }\n\t if (r) {\n\t switch (type) {\n\t case 'json':\n\t try {\n\t resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')')\n\t } catch (err) {\n\t return error(resp, 'Could not parse JSON in response', err)\n\t }\n\t break\n\t case 'js':\n\t resp = eval(r)\n\t break\n\t case 'html':\n\t resp = r\n\t break\n\t case 'xml':\n\t resp = resp.responseXML\n\t && resp.responseXML.parseError // IE trololo\n\t && resp.responseXML.parseError.errorCode\n\t && resp.responseXML.parseError.reason\n\t ? null\n\t : resp.responseXML\n\t break\n\t }\n\t }\n\t\n\t self._responseArgs.resp = resp\n\t self._fulfilled = true\n\t fn(resp)\n\t self._successHandler(resp)\n\t while (self._fulfillmentHandlers.length > 0) {\n\t resp = self._fulfillmentHandlers.shift()(resp)\n\t }\n\t\n\t complete(resp)\n\t }\n\t\n\t function timedOut() {\n\t self._timedOut = true\n\t self.request.abort()\n\t }\n\t\n\t function error(resp, msg, t) {\n\t resp = self.request\n\t self._responseArgs.resp = resp\n\t self._responseArgs.msg = msg\n\t self._responseArgs.t = t\n\t self._erred = true\n\t while (self._errorHandlers.length > 0) {\n\t self._errorHandlers.shift()(resp, msg, t)\n\t }\n\t complete(resp)\n\t }\n\t\n\t this.request = getRequest.call(this, success, error)\n\t }\n\t\n\t Reqwest.prototype = {\n\t abort: function () {\n\t this._aborted = true\n\t this.request.abort()\n\t }\n\t\n\t , retry: function () {\n\t init.call(this, this.o, this.fn)\n\t }\n\t\n\t /**\n\t * Small deviation from the Promises A CommonJs specification\n\t * http://wiki.commonjs.org/wiki/Promises/A\n\t */\n\t\n\t /**\n\t * `then` will execute upon successful requests\n\t */\n\t , then: function (success, fail) {\n\t success = success || function () {}\n\t fail = fail || function () {}\n\t if (this._fulfilled) {\n\t this._responseArgs.resp = success(this._responseArgs.resp)\n\t } else if (this._erred) {\n\t fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n\t } else {\n\t this._fulfillmentHandlers.push(success)\n\t this._errorHandlers.push(fail)\n\t }\n\t return this\n\t }\n\t\n\t /**\n\t * `always` will execute whether the request succeeds or fails\n\t */\n\t , always: function (fn) {\n\t if (this._fulfilled || this._erred) {\n\t fn(this._responseArgs.resp)\n\t } else {\n\t this._completeHandlers.push(fn)\n\t }\n\t return this\n\t }\n\t\n\t /**\n\t * `fail` will execute when the request fails\n\t */\n\t , fail: function (fn) {\n\t if (this._erred) {\n\t fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n\t } else {\n\t this._errorHandlers.push(fn)\n\t }\n\t return this\n\t }\n\t , 'catch': function (fn) {\n\t return this.fail(fn)\n\t }\n\t }\n\t\n\t function reqwest(o, fn) {\n\t return new Reqwest(o, fn)\n\t }\n\t\n\t // normalize newline variants according to spec -> CRLF\n\t function normalize(s) {\n\t return s ? s.replace(/\\r?\\n/g, '\\r\\n') : ''\n\t }\n\t\n\t function serial(el, cb) {\n\t var n = el.name\n\t , t = el.tagName.toLowerCase()\n\t , optCb = function (o) {\n\t // IE gives value=\"\" even where there is no value attribute\n\t // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273\n\t if (o && !o['disabled'])\n\t cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))\n\t }\n\t , ch, ra, val, i\n\t\n\t // don't serialize elements that are disabled or without a name\n\t if (el.disabled || !n) return\n\t\n\t switch (t) {\n\t case 'input':\n\t if (!/reset|button|image|file/i.test(el.type)) {\n\t ch = /checkbox/i.test(el.type)\n\t ra = /radio/i.test(el.type)\n\t val = el.value\n\t // WebKit gives us \"\" instead of \"on\" if a checkbox has no value, so correct it here\n\t ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))\n\t }\n\t break\n\t case 'textarea':\n\t cb(n, normalize(el.value))\n\t break\n\t case 'select':\n\t if (el.type.toLowerCase() === 'select-one') {\n\t optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)\n\t } else {\n\t for (i = 0; el.length && i < el.length; i++) {\n\t el.options[i].selected && optCb(el.options[i])\n\t }\n\t }\n\t break\n\t }\n\t }\n\t\n\t // collect up all form elements found from the passed argument elements all\n\t // the way down to child elements; pass a '' or form fields.\n\t // called with 'this'=callback to use for serial() on each element\n\t function eachFormElement() {\n\t var cb = this\n\t , e, i\n\t , serializeSubtags = function (e, tags) {\n\t var i, j, fa\n\t for (i = 0; i < tags.length; i++) {\n\t fa = e[byTag](tags[i])\n\t for (j = 0; j < fa.length; j++) serial(fa[j], cb)\n\t }\n\t }\n\t\n\t for (i = 0; i < arguments.length; i++) {\n\t e = arguments[i]\n\t if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)\n\t serializeSubtags(e, [ 'input', 'select', 'textarea' ])\n\t }\n\t }\n\t\n\t // standard query string style serialization\n\t function serializeQueryString() {\n\t return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))\n\t }\n\t\n\t // { 'name': 'value', ... } style serialization\n\t function serializeHash() {\n\t var hash = {}\n\t eachFormElement.apply(function (name, value) {\n\t if (name in hash) {\n\t hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])\n\t hash[name].push(value)\n\t } else hash[name] = value\n\t }, arguments)\n\t return hash\n\t }\n\t\n\t // [ { name: 'name', value: 'value' }, ... ] style serialization\n\t reqwest.serializeArray = function () {\n\t var arr = []\n\t eachFormElement.apply(function (name, value) {\n\t arr.push({name: name, value: value})\n\t }, arguments)\n\t return arr\n\t }\n\t\n\t reqwest.serialize = function () {\n\t if (arguments.length === 0) return ''\n\t var opt, fn\n\t , args = Array.prototype.slice.call(arguments, 0)\n\t\n\t opt = args.pop()\n\t opt && opt.nodeType && args.push(opt) && (opt = null)\n\t opt && (opt = opt.type)\n\t\n\t if (opt == 'map') fn = serializeHash\n\t else if (opt == 'array') fn = reqwest.serializeArray\n\t else fn = serializeQueryString\n\t\n\t return fn.apply(null, args)\n\t }\n\t\n\t reqwest.toQueryString = function (o, trad) {\n\t var prefix, i\n\t , traditional = trad || false\n\t , s = []\n\t , enc = encodeURIComponent\n\t , add = function (key, value) {\n\t // If value is a function, invoke it and return its value\n\t value = ('function' === typeof value) ? value() : (value == null ? '' : value)\n\t s[s.length] = enc(key) + '=' + enc(value)\n\t }\n\t // If an array was passed in, assume that it is an array of form elements.\n\t if (isArray(o)) {\n\t for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])\n\t } else {\n\t // If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t // did it), otherwise encode params recursively.\n\t for (prefix in o) {\n\t if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)\n\t }\n\t }\n\t\n\t // spaces should be + according to spec\n\t return s.join('&').replace(/%20/g, '+')\n\t }\n\t\n\t function buildParams(prefix, obj, traditional, add) {\n\t var name, i, v\n\t , rbracket = /\\[\\]$/\n\t\n\t if (isArray(obj)) {\n\t // Serialize array item.\n\t for (i = 0; obj && i < obj.length; i++) {\n\t v = obj[i]\n\t if (traditional || rbracket.test(prefix)) {\n\t // Treat each array item as a scalar.\n\t add(prefix, v)\n\t } else {\n\t buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)\n\t }\n\t }\n\t } else if (obj && obj.toString() === '[object Object]') {\n\t // Serialize object item.\n\t for (name in obj) {\n\t buildParams(prefix + '[' + name + ']', obj[name], traditional, add)\n\t }\n\t\n\t } else {\n\t // Serialize scalar item.\n\t add(prefix, obj)\n\t }\n\t }\n\t\n\t reqwest.getcallbackPrefix = function () {\n\t return callbackPrefix\n\t }\n\t\n\t // jQuery and Zepto compatibility, differences can be remapped here so you can call\n\t // .ajax.compat(options, callback)\n\t reqwest.compat = function (o, fn) {\n\t if (o) {\n\t o['type'] && (o['method'] = o['type']) && delete o['type']\n\t o['dataType'] && (o['type'] = o['dataType'])\n\t o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']\n\t o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])\n\t }\n\t return new Reqwest(o, fn)\n\t }\n\t\n\t reqwest.ajaxSetup = function (options) {\n\t options = options || {}\n\t for (var k in options) {\n\t globalSetupOptions[k] = options[k]\n\t }\n\t }\n\t\n\t return reqwest\n\t});\n\n\n/***/ },\n/* 62 */\n/***/ function(module, exports) {\n\n\t/* (ignored) */\n\n/***/ },\n/* 63 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * GeoJSON helpers for handling data and generating objects\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _topojson2 = __webpack_require__(64);\n\t\n\tvar _topojson3 = _interopRequireDefault(_topojson2);\n\t\n\tvar _geojsonMerge = __webpack_require__(65);\n\t\n\tvar _geojsonMerge2 = _interopRequireDefault(_geojsonMerge);\n\t\n\tvar _earcut = __webpack_require__(67);\n\t\n\tvar _earcut2 = _interopRequireDefault(_earcut);\n\t\n\tvar _extrudePolygon = __webpack_require__(68);\n\t\n\tvar _extrudePolygon2 = _interopRequireDefault(_extrudePolygon);\n\t\n\t// TODO: Make it so height can be per-coordinate / point but connected together\n\t// as a linestring (eg. GPS points with an elevation at each point)\n\t//\n\t// This isn't really valid GeoJSON so perhaps something best left to an external\n\t// component for now, until a better approach can be considered\n\t//\n\t// See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html\n\t\n\t// Light and dark colours used for poor-mans AO gradient on object sides\n\tvar light = new _three2['default'].Color(0xffffff);\n\tvar shadow = new _three2['default'].Color(0x666666);\n\t\n\tvar GeoJSON = (function () {\n\t var defaultStyle = {\n\t color: '#ffffff',\n\t transparent: false,\n\t opacity: 1,\n\t blending: _three2['default'].NormalBlending,\n\t height: 0,\n\t lineOpacity: 1,\n\t lineTransparent: false,\n\t lineColor: '#ffffff',\n\t lineWidth: 1,\n\t lineBlending: _three2['default'].NormalBlending\n\t };\n\t\n\t // Attempts to merge together multiple GeoJSON Features or FeatureCollections\n\t // into a single FeatureCollection\n\t var collectFeatures = function collectFeatures(data, _topojson) {\n\t var collections = [];\n\t\n\t if (_topojson) {\n\t // TODO: Allow TopoJSON objects to be overridden as an option\n\t\n\t // If not overridden, merge all features from all objects\n\t for (var tk in data.objects) {\n\t collections.push(_topojson3['default'].feature(data, data.objects[tk]));\n\t }\n\t\n\t return (0, _geojsonMerge2['default'])(collections);\n\t } else {\n\t // If root doesn't have a type then let's see if there are features in the\n\t // next step down\n\t if (!data.type) {\n\t // TODO: Allow GeoJSON objects to be overridden as an option\n\t\n\t // If not overridden, merge all features from all objects\n\t for (var gk in data) {\n\t if (!data[gk].type) {\n\t continue;\n\t }\n\t\n\t collections.push(data[gk]);\n\t }\n\t\n\t return (0, _geojsonMerge2['default'])(collections);\n\t } else if (Array.isArray(data)) {\n\t return (0, _geojsonMerge2['default'])(data);\n\t } else {\n\t return data;\n\t }\n\t }\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var lineStringAttributes = function lineStringAttributes(coordinates, colour, height) {\n\t var _coords = [];\n\t var _colours = [];\n\t\n\t var nextCoord;\n\t\n\t // Connect coordinate with the next to make a pair\n\t //\n\t // LineSegments requires pairs of vertices so repeat the last point if\n\t // there's an odd number of vertices\n\t coordinates.forEach(function (coordinate, index) {\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _coords.push([coordinate[0], height, coordinate[1]]);\n\t\n\t nextCoord = coordinates[index + 1] ? coordinates[index + 1] : coordinate;\n\t\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _coords.push([nextCoord[0], height, nextCoord[1]]);\n\t });\n\t\n\t return {\n\t vertices: _coords,\n\t colours: _colours\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var multiLineStringAttributes = function multiLineStringAttributes(coordinates, colour, height) {\n\t var _coords = [];\n\t var _colours = [];\n\t\n\t var result;\n\t coordinates.forEach(function (coordinate) {\n\t result = lineStringAttributes(coordinate, colour, height);\n\t\n\t result.vertices.forEach(function (coord) {\n\t _coords.push(coord);\n\t });\n\t\n\t result.colours.forEach(function (colour) {\n\t _colours.push(colour);\n\t });\n\t });\n\t\n\t return {\n\t vertices: _coords,\n\t colours: _colours\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var polygonAttributes = function polygonAttributes(coordinates, colour, height) {\n\t var earcutData = _toEarcut(coordinates);\n\t\n\t var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions);\n\t\n\t var groupedVertices = [];\n\t for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) {\n\t groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions));\n\t }\n\t\n\t var extruded = (0, _extrudePolygon2['default'])(groupedVertices, faces, {\n\t bottom: 0,\n\t top: height\n\t });\n\t\n\t var topColor = colour.clone().multiply(light);\n\t var bottomColor = colour.clone().multiply(shadow);\n\t\n\t var _vertices = extruded.positions;\n\t var _faces = [];\n\t var _colours = [];\n\t\n\t var _colour;\n\t extruded.top.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t\n\t var allFlat = true;\n\t\n\t if (extruded.sides) {\n\t if (allFlat) {\n\t allFlat = false;\n\t }\n\t\n\t // Set up colours for every vertex with poor-mans AO on the sides\n\t extruded.sides.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t // First face is always bottom-bottom-top\n\t if (fi % 2 === 0) {\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t // Reverse winding for the second face\n\t // top-top-bottom\n\t } else {\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t }\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t }\n\t\n\t // Skip bottom as there's no point rendering it\n\t // allFaces.push(extruded.faces);\n\t\n\t return {\n\t vertices: _vertices,\n\t faces: _faces,\n\t colours: _colours,\n\t flat: allFlat\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var _toEarcut = function _toEarcut(data) {\n\t var dim = data[0][0].length;\n\t var result = { vertices: [], holes: [], dimensions: dim };\n\t var holeIndex = 0;\n\t\n\t for (var i = 0; i < data.length; i++) {\n\t for (var j = 0; j < data[i].length; j++) {\n\t for (var d = 0; d < dim; d++) {\n\t result.vertices.push(data[i][j][d]);\n\t }\n\t }\n\t if (i > 0) {\n\t holeIndex += data[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t\n\t return result;\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var _triangulate = function _triangulate(contour, holes, dim) {\n\t // console.time('earcut');\n\t\n\t var faces = (0, _earcut2['default'])(contour, holes, dim);\n\t var result = [];\n\t\n\t for (i = 0, il = faces.length; i < il; i += 3) {\n\t result.push(faces.slice(i, i + 3));\n\t }\n\t\n\t // console.timeEnd('earcut');\n\t\n\t return result;\n\t };\n\t\n\t return {\n\t defaultStyle: defaultStyle,\n\t collectFeatures: collectFeatures,\n\t lineStringAttributes: lineStringAttributes,\n\t multiLineStringAttributes: multiLineStringAttributes,\n\t polygonAttributes: polygonAttributes\n\t };\n\t})();\n\t\n\texports['default'] = GeoJSON;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 64 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t(function (global, factory) {\n\t true ? factory(exports) :\n\t typeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t (factory((global.topojson = global.topojson || {})));\n\t}(this, function (exports) { 'use strict';\n\t\n\t function noop() {}\n\t\n\t function transformAbsolute(transform) {\n\t if (!transform) return noop;\n\t var x0,\n\t y0,\n\t kx = transform.scale[0],\n\t ky = transform.scale[1],\n\t dx = transform.translate[0],\n\t dy = transform.translate[1];\n\t return function(point, i) {\n\t if (!i) x0 = y0 = 0;\n\t point[0] = (x0 += point[0]) * kx + dx;\n\t point[1] = (y0 += point[1]) * ky + dy;\n\t };\n\t }\n\t\n\t function transformRelative(transform) {\n\t if (!transform) return noop;\n\t var x0,\n\t y0,\n\t kx = transform.scale[0],\n\t ky = transform.scale[1],\n\t dx = transform.translate[0],\n\t dy = transform.translate[1];\n\t return function(point, i) {\n\t if (!i) x0 = y0 = 0;\n\t var x1 = Math.round((point[0] - dx) / kx),\n\t y1 = Math.round((point[1] - dy) / ky);\n\t point[0] = x1 - x0;\n\t point[1] = y1 - y0;\n\t x0 = x1;\n\t y0 = y1;\n\t };\n\t }\n\t\n\t function reverse(array, n) {\n\t var t, j = array.length, i = j - n;\n\t while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n\t }\n\t\n\t function bisect(a, x) {\n\t var lo = 0, hi = a.length;\n\t while (lo < hi) {\n\t var mid = lo + hi >>> 1;\n\t if (a[mid] < x) lo = mid + 1;\n\t else hi = mid;\n\t }\n\t return lo;\n\t }\n\t\n\t function feature(topology, o) {\n\t return o.type === \"GeometryCollection\" ? {\n\t type: \"FeatureCollection\",\n\t features: o.geometries.map(function(o) { return feature$1(topology, o); })\n\t } : feature$1(topology, o);\n\t }\n\t\n\t function feature$1(topology, o) {\n\t var f = {\n\t type: \"Feature\",\n\t id: o.id,\n\t properties: o.properties || {},\n\t geometry: object(topology, o)\n\t };\n\t if (o.id == null) delete f.id;\n\t return f;\n\t }\n\t\n\t function object(topology, o) {\n\t var absolute = transformAbsolute(topology.transform),\n\t arcs = topology.arcs;\n\t\n\t function arc(i, points) {\n\t if (points.length) points.pop();\n\t for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {\n\t points.push(p = a[k].slice());\n\t absolute(p, k);\n\t }\n\t if (i < 0) reverse(points, n);\n\t }\n\t\n\t function point(p) {\n\t p = p.slice();\n\t absolute(p, 0);\n\t return p;\n\t }\n\t\n\t function line(arcs) {\n\t var points = [];\n\t for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n\t if (points.length < 2) points.push(points[0].slice());\n\t return points;\n\t }\n\t\n\t function ring(arcs) {\n\t var points = line(arcs);\n\t while (points.length < 4) points.push(points[0].slice());\n\t return points;\n\t }\n\t\n\t function polygon(arcs) {\n\t return arcs.map(ring);\n\t }\n\t\n\t function geometry(o) {\n\t var t = o.type;\n\t return t === \"GeometryCollection\" ? {type: t, geometries: o.geometries.map(geometry)}\n\t : t in geometryType ? {type: t, coordinates: geometryType[t](o)}\n\t : null;\n\t }\n\t\n\t var geometryType = {\n\t Point: function(o) { return point(o.coordinates); },\n\t MultiPoint: function(o) { return o.coordinates.map(point); },\n\t LineString: function(o) { return line(o.arcs); },\n\t MultiLineString: function(o) { return o.arcs.map(line); },\n\t Polygon: function(o) { return polygon(o.arcs); },\n\t MultiPolygon: function(o) { return o.arcs.map(polygon); }\n\t };\n\t\n\t return geometry(o);\n\t }\n\t\n\t function stitchArcs(topology, arcs) {\n\t var stitchedArcs = {},\n\t fragmentByStart = {},\n\t fragmentByEnd = {},\n\t fragments = [],\n\t emptyIndex = -1;\n\t\n\t // Stitch empty arcs first, since they may be subsumed by other arcs.\n\t arcs.forEach(function(i, j) {\n\t var arc = topology.arcs[i < 0 ? ~i : i], t;\n\t if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n\t t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n\t }\n\t });\n\t\n\t arcs.forEach(function(i) {\n\t var e = ends(i),\n\t start = e[0],\n\t end = e[1],\n\t f, g;\n\t\n\t if (f = fragmentByEnd[start]) {\n\t delete fragmentByEnd[f.end];\n\t f.push(i);\n\t f.end = end;\n\t if (g = fragmentByStart[end]) {\n\t delete fragmentByStart[g.start];\n\t var fg = g === f ? f : f.concat(g);\n\t fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n\t } else {\n\t fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n\t }\n\t } else if (f = fragmentByStart[end]) {\n\t delete fragmentByStart[f.start];\n\t f.unshift(i);\n\t f.start = start;\n\t if (g = fragmentByEnd[start]) {\n\t delete fragmentByEnd[g.end];\n\t var gf = g === f ? f : g.concat(f);\n\t fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n\t } else {\n\t fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n\t }\n\t } else {\n\t f = [i];\n\t fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n\t }\n\t });\n\t\n\t function ends(i) {\n\t var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n\t if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n\t else p1 = arc[arc.length - 1];\n\t return i < 0 ? [p1, p0] : [p0, p1];\n\t }\n\t\n\t function flush(fragmentByEnd, fragmentByStart) {\n\t for (var k in fragmentByEnd) {\n\t var f = fragmentByEnd[k];\n\t delete fragmentByStart[f.start];\n\t delete f.start;\n\t delete f.end;\n\t f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n\t fragments.push(f);\n\t }\n\t }\n\t\n\t flush(fragmentByEnd, fragmentByStart);\n\t flush(fragmentByStart, fragmentByEnd);\n\t arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\t\n\t return fragments;\n\t }\n\t\n\t function mesh(topology) {\n\t return object(topology, meshArcs.apply(this, arguments));\n\t }\n\t\n\t function meshArcs(topology, o, filter) {\n\t var arcs = [];\n\t\n\t function arc(i) {\n\t var j = i < 0 ? ~i : i;\n\t (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n\t }\n\t\n\t function line(arcs) {\n\t arcs.forEach(arc);\n\t }\n\t\n\t function polygon(arcs) {\n\t arcs.forEach(line);\n\t }\n\t\n\t function geometry(o) {\n\t if (o.type === \"GeometryCollection\") o.geometries.forEach(geometry);\n\t else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);\n\t }\n\t\n\t if (arguments.length > 1) {\n\t var geomsByArc = [],\n\t geom;\n\t\n\t var geometryType = {\n\t LineString: line,\n\t MultiLineString: polygon,\n\t Polygon: polygon,\n\t MultiPolygon: function(arcs) { arcs.forEach(polygon); }\n\t };\n\t\n\t geometry(o);\n\t\n\t geomsByArc.forEach(arguments.length < 3\n\t ? function(geoms) { arcs.push(geoms[0].i); }\n\t : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n\t } else {\n\t for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);\n\t }\n\t\n\t return {type: \"MultiLineString\", arcs: stitchArcs(topology, arcs)};\n\t }\n\t\n\t function cartesianTriangleArea(triangle) {\n\t var a = triangle[0], b = triangle[1], c = triangle[2];\n\t return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));\n\t }\n\t\n\t function ring(ring) {\n\t var i = -1,\n\t n = ring.length,\n\t a,\n\t b = ring[n - 1],\n\t area = 0;\n\t\n\t while (++i < n) {\n\t a = b;\n\t b = ring[i];\n\t area += a[0] * b[1] - a[1] * b[0];\n\t }\n\t\n\t return area / 2;\n\t }\n\t\n\t function merge(topology) {\n\t return object(topology, mergeArcs.apply(this, arguments));\n\t }\n\t\n\t function mergeArcs(topology, objects) {\n\t var polygonsByArc = {},\n\t polygons = [],\n\t components = [];\n\t\n\t objects.forEach(function(o) {\n\t if (o.type === \"Polygon\") register(o.arcs);\n\t else if (o.type === \"MultiPolygon\") o.arcs.forEach(register);\n\t });\n\t\n\t function register(polygon) {\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n\t });\n\t });\n\t polygons.push(polygon);\n\t }\n\t\n\t function area(ring$$) {\n\t return Math.abs(ring(object(topology, {type: \"Polygon\", arcs: [ring$$]}).coordinates[0]));\n\t }\n\t\n\t polygons.forEach(function(polygon) {\n\t if (!polygon._) {\n\t var component = [],\n\t neighbors = [polygon];\n\t polygon._ = 1;\n\t components.push(component);\n\t while (polygon = neighbors.pop()) {\n\t component.push(polygon);\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n\t if (!polygon._) {\n\t polygon._ = 1;\n\t neighbors.push(polygon);\n\t }\n\t });\n\t });\n\t });\n\t }\n\t }\n\t });\n\t\n\t polygons.forEach(function(polygon) {\n\t delete polygon._;\n\t });\n\t\n\t return {\n\t type: \"MultiPolygon\",\n\t arcs: components.map(function(polygons) {\n\t var arcs = [], n;\n\t\n\t // Extract the exterior (unique) arcs.\n\t polygons.forEach(function(polygon) {\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n\t arcs.push(arc);\n\t }\n\t });\n\t });\n\t });\n\t\n\t // Stitch the arcs into one or more rings.\n\t arcs = stitchArcs(topology, arcs);\n\t\n\t // If more than one ring is returned,\n\t // at most one of these rings can be the exterior;\n\t // choose the one with the greatest absolute area.\n\t if ((n = arcs.length) > 1) {\n\t for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n\t if ((ki = area(arcs[i])) > k) {\n\t t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n\t }\n\t }\n\t }\n\t\n\t return arcs;\n\t })\n\t };\n\t }\n\t\n\t function neighbors(objects) {\n\t var indexesByArc = {}, // arc index -> array of object indexes\n\t neighbors = objects.map(function() { return []; });\n\t\n\t function line(arcs, i) {\n\t arcs.forEach(function(a) {\n\t if (a < 0) a = ~a;\n\t var o = indexesByArc[a];\n\t if (o) o.push(i);\n\t else indexesByArc[a] = [i];\n\t });\n\t }\n\t\n\t function polygon(arcs, i) {\n\t arcs.forEach(function(arc) { line(arc, i); });\n\t }\n\t\n\t function geometry(o, i) {\n\t if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n\t else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n\t }\n\t\n\t var geometryType = {\n\t LineString: line,\n\t MultiLineString: polygon,\n\t Polygon: polygon,\n\t MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n\t };\n\t\n\t objects.forEach(geometry);\n\t\n\t for (var i in indexesByArc) {\n\t for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n\t for (var k = j + 1; k < m; ++k) {\n\t var ij = indexes[j], ik = indexes[k], n;\n\t if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);\n\t if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);\n\t }\n\t }\n\t }\n\t\n\t return neighbors;\n\t }\n\t\n\t function compareArea(a, b) {\n\t return a[1][2] - b[1][2];\n\t }\n\t\n\t function minAreaHeap() {\n\t var heap = {},\n\t array = [],\n\t size = 0;\n\t\n\t heap.push = function(object) {\n\t up(array[object._ = size] = object, size++);\n\t return size;\n\t };\n\t\n\t heap.pop = function() {\n\t if (size <= 0) return;\n\t var removed = array[0], object;\n\t if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);\n\t return removed;\n\t };\n\t\n\t heap.remove = function(removed) {\n\t var i = removed._, object;\n\t if (array[i] !== removed) return; // invalid request\n\t if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);\n\t return i;\n\t };\n\t\n\t function up(object, i) {\n\t while (i > 0) {\n\t var j = ((i + 1) >> 1) - 1,\n\t parent = array[j];\n\t if (compareArea(object, parent) >= 0) break;\n\t array[parent._ = i] = parent;\n\t array[object._ = i = j] = object;\n\t }\n\t }\n\t\n\t function down(object, i) {\n\t while (true) {\n\t var r = (i + 1) << 1,\n\t l = r - 1,\n\t j = i,\n\t child = array[j];\n\t if (l < size && compareArea(array[l], child) < 0) child = array[j = l];\n\t if (r < size && compareArea(array[r], child) < 0) child = array[j = r];\n\t if (j === i) break;\n\t array[child._ = i] = child;\n\t array[object._ = i = j] = object;\n\t }\n\t }\n\t\n\t return heap;\n\t }\n\t\n\t function presimplify(topology, triangleArea) {\n\t var absolute = transformAbsolute(topology.transform),\n\t relative = transformRelative(topology.transform),\n\t heap = minAreaHeap();\n\t\n\t if (!triangleArea) triangleArea = cartesianTriangleArea;\n\t\n\t topology.arcs.forEach(function(arc) {\n\t var triangles = [],\n\t maxArea = 0,\n\t triangle,\n\t i,\n\t n,\n\t p;\n\t\n\t // To store each point’s effective area, we create a new array rather than\n\t // extending the passed-in point to workaround a Chrome/V8 bug (getting\n\t // stuck in smi mode). For midpoints, the initial effective area of\n\t // Infinity will be computed in the next step.\n\t for (i = 0, n = arc.length; i < n; ++i) {\n\t p = arc[i];\n\t absolute(arc[i] = [p[0], p[1], Infinity], i);\n\t }\n\t\n\t for (i = 1, n = arc.length - 1; i < n; ++i) {\n\t triangle = arc.slice(i - 1, i + 2);\n\t triangle[1][2] = triangleArea(triangle);\n\t triangles.push(triangle);\n\t heap.push(triangle);\n\t }\n\t\n\t for (i = 0, n = triangles.length; i < n; ++i) {\n\t triangle = triangles[i];\n\t triangle.previous = triangles[i - 1];\n\t triangle.next = triangles[i + 1];\n\t }\n\t\n\t while (triangle = heap.pop()) {\n\t var previous = triangle.previous,\n\t next = triangle.next;\n\t\n\t // If the area of the current point is less than that of the previous point\n\t // to be eliminated, use the latter's area instead. This ensures that the\n\t // current point cannot be eliminated without eliminating previously-\n\t // eliminated points.\n\t if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;\n\t else maxArea = triangle[1][2];\n\t\n\t if (previous) {\n\t previous.next = next;\n\t previous[2] = triangle[2];\n\t update(previous);\n\t }\n\t\n\t if (next) {\n\t next.previous = previous;\n\t next[0] = triangle[0];\n\t update(next);\n\t }\n\t }\n\t\n\t arc.forEach(relative);\n\t });\n\t\n\t function update(triangle) {\n\t heap.remove(triangle);\n\t triangle[1][2] = triangleArea(triangle);\n\t heap.push(triangle);\n\t }\n\t\n\t return topology;\n\t }\n\t\n\t var version = \"1.6.26\";\n\t\n\t exports.version = version;\n\t exports.mesh = mesh;\n\t exports.meshArcs = meshArcs;\n\t exports.merge = merge;\n\t exports.mergeArcs = mergeArcs;\n\t exports.feature = feature;\n\t exports.neighbors = neighbors;\n\t exports.presimplify = presimplify;\n\t\n\t}));\n\n/***/ },\n/* 65 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar normalize = __webpack_require__(66);\n\t\n\tmodule.exports = function(inputs) {\n\t return {\n\t type: 'FeatureCollection',\n\t features: inputs.reduce(function(memo, input) {\n\t return memo.concat(normalize(input).features);\n\t }, [])\n\t };\n\t};\n\n\n/***/ },\n/* 66 */\n/***/ function(module, exports) {\n\n\tmodule.exports = normalize;\n\t\n\tvar types = {\n\t Point: 'geometry',\n\t MultiPoint: 'geometry',\n\t LineString: 'geometry',\n\t MultiLineString: 'geometry',\n\t Polygon: 'geometry',\n\t MultiPolygon: 'geometry',\n\t GeometryCollection: 'geometry',\n\t Feature: 'feature',\n\t FeatureCollection: 'featurecollection'\n\t};\n\t\n\t/**\n\t * Normalize a GeoJSON feature into a FeatureCollection.\n\t *\n\t * @param {object} gj geojson data\n\t * @returns {object} normalized geojson data\n\t */\n\tfunction normalize(gj) {\n\t if (!gj || !gj.type) return null;\n\t var type = types[gj.type];\n\t if (!type) return null;\n\t\n\t if (type === 'geometry') {\n\t return {\n\t type: 'FeatureCollection',\n\t features: [{\n\t type: 'Feature',\n\t properties: {},\n\t geometry: gj\n\t }]\n\t };\n\t } else if (type === 'feature') {\n\t return {\n\t type: 'FeatureCollection',\n\t features: [gj]\n\t };\n\t } else if (type === 'featurecollection') {\n\t return gj;\n\t }\n\t}\n\n\n/***/ },\n/* 67 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = earcut;\n\t\n\tfunction earcut(data, holeIndices, dim) {\n\t\n\t dim = dim || 2;\n\t\n\t var hasHoles = holeIndices && holeIndices.length,\n\t outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n\t outerNode = linkedList(data, 0, outerLen, dim, true),\n\t triangles = [];\n\t\n\t if (!outerNode) return triangles;\n\t\n\t var minX, minY, maxX, maxY, x, y, size;\n\t\n\t if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\t\n\t // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n\t if (data.length > 80 * dim) {\n\t minX = maxX = data[0];\n\t minY = maxY = data[1];\n\t\n\t for (var i = dim; i < outerLen; i += dim) {\n\t x = data[i];\n\t y = data[i + 1];\n\t if (x < minX) minX = x;\n\t if (y < minY) minY = y;\n\t if (x > maxX) maxX = x;\n\t if (y > maxY) maxY = y;\n\t }\n\t\n\t // minX, minY and size are later used to transform coords into integers for z-order calculation\n\t size = Math.max(maxX - minX, maxY - minY);\n\t }\n\t\n\t earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\t\n\t return triangles;\n\t}\n\t\n\t// create a circular doubly linked list from polygon points in the specified winding order\n\tfunction linkedList(data, start, end, dim, clockwise) {\n\t var i, last;\n\t\n\t if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n\t for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n\t } else {\n\t for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n\t }\n\t\n\t if (last && equals(last, last.next)) {\n\t removeNode(last);\n\t last = last.next;\n\t }\n\t\n\t return last;\n\t}\n\t\n\t// eliminate colinear or duplicate points\n\tfunction filterPoints(start, end) {\n\t if (!start) return start;\n\t if (!end) end = start;\n\t\n\t var p = start,\n\t again;\n\t do {\n\t again = false;\n\t\n\t if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n\t removeNode(p);\n\t p = end = p.prev;\n\t if (p === p.next) return null;\n\t again = true;\n\t\n\t } else {\n\t p = p.next;\n\t }\n\t } while (again || p !== end);\n\t\n\t return end;\n\t}\n\t\n\t// main ear slicing loop which triangulates a polygon (given as a linked list)\n\tfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n\t if (!ear) return;\n\t\n\t // interlink polygon nodes in z-order\n\t if (!pass && size) indexCurve(ear, minX, minY, size);\n\t\n\t var stop = ear,\n\t prev, next;\n\t\n\t // iterate through ears, slicing them one by one\n\t while (ear.prev !== ear.next) {\n\t prev = ear.prev;\n\t next = ear.next;\n\t\n\t if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n\t // cut off the triangle\n\t triangles.push(prev.i / dim);\n\t triangles.push(ear.i / dim);\n\t triangles.push(next.i / dim);\n\t\n\t removeNode(ear);\n\t\n\t // skipping the next vertice leads to less sliver triangles\n\t ear = next.next;\n\t stop = next.next;\n\t\n\t continue;\n\t }\n\t\n\t ear = next;\n\t\n\t // if we looped through the whole remaining polygon and can't find any more ears\n\t if (ear === stop) {\n\t // try filtering points and slicing again\n\t if (!pass) {\n\t earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\t\n\t // if this didn't work, try curing all small self-intersections locally\n\t } else if (pass === 1) {\n\t ear = cureLocalIntersections(ear, triangles, dim);\n\t earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\t\n\t // as a last resort, try splitting the remaining polygon into two\n\t } else if (pass === 2) {\n\t splitEarcut(ear, triangles, dim, minX, minY, size);\n\t }\n\t\n\t break;\n\t }\n\t }\n\t}\n\t\n\t// check whether a polygon node forms a valid ear with adjacent nodes\n\tfunction isEar(ear) {\n\t var a = ear.prev,\n\t b = ear,\n\t c = ear.next;\n\t\n\t if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\t\n\t // now make sure we don't have other points inside the potential ear\n\t var p = ear.next.next;\n\t\n\t while (p !== ear.prev) {\n\t if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.next;\n\t }\n\t\n\t return true;\n\t}\n\t\n\tfunction isEarHashed(ear, minX, minY, size) {\n\t var a = ear.prev,\n\t b = ear,\n\t c = ear.next;\n\t\n\t if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\t\n\t // triangle bbox; min & max are calculated like this for speed\n\t var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n\t minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n\t maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n\t maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\t\n\t // z-order range for the current triangle bbox;\n\t var minZ = zOrder(minTX, minTY, minX, minY, size),\n\t maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\t\n\t // first look for points inside the triangle in increasing z-order\n\t var p = ear.nextZ;\n\t\n\t while (p && p.z <= maxZ) {\n\t if (p !== ear.prev && p !== ear.next &&\n\t pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.nextZ;\n\t }\n\t\n\t // then look for points in decreasing z-order\n\t p = ear.prevZ;\n\t\n\t while (p && p.z >= minZ) {\n\t if (p !== ear.prev && p !== ear.next &&\n\t pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.prevZ;\n\t }\n\t\n\t return true;\n\t}\n\t\n\t// go through all polygon nodes and cure small local self-intersections\n\tfunction cureLocalIntersections(start, triangles, dim) {\n\t var p = start;\n\t do {\n\t var a = p.prev,\n\t b = p.next.next;\n\t\n\t if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\t\n\t triangles.push(a.i / dim);\n\t triangles.push(p.i / dim);\n\t triangles.push(b.i / dim);\n\t\n\t // remove two nodes involved\n\t removeNode(p);\n\t removeNode(p.next);\n\t\n\t p = start = b;\n\t }\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t return p;\n\t}\n\t\n\t// try splitting polygon into two and triangulate them independently\n\tfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n\t // look for a valid diagonal that divides the polygon into two\n\t var a = start;\n\t do {\n\t var b = a.next.next;\n\t while (b !== a.prev) {\n\t if (a.i !== b.i && isValidDiagonal(a, b)) {\n\t // split the polygon in two by the diagonal\n\t var c = splitPolygon(a, b);\n\t\n\t // filter colinear points around the cuts\n\t a = filterPoints(a, a.next);\n\t c = filterPoints(c, c.next);\n\t\n\t // run earcut on each half\n\t earcutLinked(a, triangles, dim, minX, minY, size);\n\t earcutLinked(c, triangles, dim, minX, minY, size);\n\t return;\n\t }\n\t b = b.next;\n\t }\n\t a = a.next;\n\t } while (a !== start);\n\t}\n\t\n\t// link every hole into the outer loop, producing a single-ring polygon without holes\n\tfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n\t var queue = [],\n\t i, len, start, end, list;\n\t\n\t for (i = 0, len = holeIndices.length; i < len; i++) {\n\t start = holeIndices[i] * dim;\n\t end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n\t list = linkedList(data, start, end, dim, false);\n\t if (list === list.next) list.steiner = true;\n\t queue.push(getLeftmost(list));\n\t }\n\t\n\t queue.sort(compareX);\n\t\n\t // process holes from left to right\n\t for (i = 0; i < queue.length; i++) {\n\t eliminateHole(queue[i], outerNode);\n\t outerNode = filterPoints(outerNode, outerNode.next);\n\t }\n\t\n\t return outerNode;\n\t}\n\t\n\tfunction compareX(a, b) {\n\t return a.x - b.x;\n\t}\n\t\n\t// find a bridge between vertices that connects hole with an outer ring and and link it\n\tfunction eliminateHole(hole, outerNode) {\n\t outerNode = findHoleBridge(hole, outerNode);\n\t if (outerNode) {\n\t var b = splitPolygon(outerNode, hole);\n\t filterPoints(b, b.next);\n\t }\n\t}\n\t\n\t// David Eberly's algorithm for finding a bridge between hole and outer polygon\n\tfunction findHoleBridge(hole, outerNode) {\n\t var p = outerNode,\n\t hx = hole.x,\n\t hy = hole.y,\n\t qx = -Infinity,\n\t m;\n\t\n\t // find a segment intersected by a ray from the hole's leftmost point to the left;\n\t // segment's endpoint with lesser x will be potential connection point\n\t do {\n\t if (hy <= p.y && hy >= p.next.y) {\n\t var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n\t if (x <= hx && x > qx) {\n\t qx = x;\n\t if (x === hx) {\n\t if (hy === p.y) return p;\n\t if (hy === p.next.y) return p.next;\n\t }\n\t m = p.x < p.next.x ? p : p.next;\n\t }\n\t }\n\t p = p.next;\n\t } while (p !== outerNode);\n\t\n\t if (!m) return null;\n\t\n\t if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint\n\t\n\t // look for points inside the triangle of hole point, segment intersection and endpoint;\n\t // if there are no points found, we have a valid connection;\n\t // otherwise choose the point of the minimum angle with the ray as connection point\n\t\n\t var stop = m,\n\t mx = m.x,\n\t my = m.y,\n\t tanMin = Infinity,\n\t tan;\n\t\n\t p = m.next;\n\t\n\t while (p !== stop) {\n\t if (hx >= p.x && p.x >= mx &&\n\t pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\t\n\t tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\t\n\t if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n\t m = p;\n\t tanMin = tan;\n\t }\n\t }\n\t\n\t p = p.next;\n\t }\n\t\n\t return m;\n\t}\n\t\n\t// interlink polygon nodes in z-order\n\tfunction indexCurve(start, minX, minY, size) {\n\t var p = start;\n\t do {\n\t if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n\t p.prevZ = p.prev;\n\t p.nextZ = p.next;\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t p.prevZ.nextZ = null;\n\t p.prevZ = null;\n\t\n\t sortLinked(p);\n\t}\n\t\n\t// Simon Tatham's linked list merge sort algorithm\n\t// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\n\tfunction sortLinked(list) {\n\t var i, p, q, e, tail, numMerges, pSize, qSize,\n\t inSize = 1;\n\t\n\t do {\n\t p = list;\n\t list = null;\n\t tail = null;\n\t numMerges = 0;\n\t\n\t while (p) {\n\t numMerges++;\n\t q = p;\n\t pSize = 0;\n\t for (i = 0; i < inSize; i++) {\n\t pSize++;\n\t q = q.nextZ;\n\t if (!q) break;\n\t }\n\t\n\t qSize = inSize;\n\t\n\t while (pSize > 0 || (qSize > 0 && q)) {\n\t\n\t if (pSize === 0) {\n\t e = q;\n\t q = q.nextZ;\n\t qSize--;\n\t } else if (qSize === 0 || !q) {\n\t e = p;\n\t p = p.nextZ;\n\t pSize--;\n\t } else if (p.z <= q.z) {\n\t e = p;\n\t p = p.nextZ;\n\t pSize--;\n\t } else {\n\t e = q;\n\t q = q.nextZ;\n\t qSize--;\n\t }\n\t\n\t if (tail) tail.nextZ = e;\n\t else list = e;\n\t\n\t e.prevZ = tail;\n\t tail = e;\n\t }\n\t\n\t p = q;\n\t }\n\t\n\t tail.nextZ = null;\n\t inSize *= 2;\n\t\n\t } while (numMerges > 1);\n\t\n\t return list;\n\t}\n\t\n\t// z-order of a point given coords and size of the data bounding box\n\tfunction zOrder(x, y, minX, minY, size) {\n\t // coords are transformed into non-negative 15-bit integer range\n\t x = 32767 * (x - minX) / size;\n\t y = 32767 * (y - minY) / size;\n\t\n\t x = (x | (x << 8)) & 0x00FF00FF;\n\t x = (x | (x << 4)) & 0x0F0F0F0F;\n\t x = (x | (x << 2)) & 0x33333333;\n\t x = (x | (x << 1)) & 0x55555555;\n\t\n\t y = (y | (y << 8)) & 0x00FF00FF;\n\t y = (y | (y << 4)) & 0x0F0F0F0F;\n\t y = (y | (y << 2)) & 0x33333333;\n\t y = (y | (y << 1)) & 0x55555555;\n\t\n\t return x | (y << 1);\n\t}\n\t\n\t// find the leftmost node of a polygon ring\n\tfunction getLeftmost(start) {\n\t var p = start,\n\t leftmost = start;\n\t do {\n\t if (p.x < leftmost.x) leftmost = p;\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t return leftmost;\n\t}\n\t\n\t// check if a point lies within a convex triangle\n\tfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n\t return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n\t (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n\t (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n\t}\n\t\n\t// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\n\tfunction isValidDiagonal(a, b) {\n\t return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n\t locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n\t}\n\t\n\t// signed area of a triangle\n\tfunction area(p, q, r) {\n\t return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n\t}\n\t\n\t// check if two points are equal\n\tfunction equals(p1, p2) {\n\t return p1.x === p2.x && p1.y === p2.y;\n\t}\n\t\n\t// check if two segments intersect\n\tfunction intersects(p1, q1, p2, q2) {\n\t if ((equals(p1, q1) && equals(p2, q2)) ||\n\t (equals(p1, q2) && equals(p2, q1))) return true;\n\t return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n\t area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n\t}\n\t\n\t// check if a polygon diagonal intersects any polygon segments\n\tfunction intersectsPolygon(a, b) {\n\t var p = a;\n\t do {\n\t if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n\t intersects(p, p.next, a, b)) return true;\n\t p = p.next;\n\t } while (p !== a);\n\t\n\t return false;\n\t}\n\t\n\t// check if a polygon diagonal is locally inside the polygon\n\tfunction locallyInside(a, b) {\n\t return area(a.prev, a, a.next) < 0 ?\n\t area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n\t area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n\t}\n\t\n\t// check if the middle point of a polygon diagonal is inside the polygon\n\tfunction middleInside(a, b) {\n\t var p = a,\n\t inside = false,\n\t px = (a.x + b.x) / 2,\n\t py = (a.y + b.y) / 2;\n\t do {\n\t if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n\t inside = !inside;\n\t p = p.next;\n\t } while (p !== a);\n\t\n\t return inside;\n\t}\n\t\n\t// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n\t// if one belongs to the outer ring and another to a hole, it merges it into a single ring\n\tfunction splitPolygon(a, b) {\n\t var a2 = new Node(a.i, a.x, a.y),\n\t b2 = new Node(b.i, b.x, b.y),\n\t an = a.next,\n\t bp = b.prev;\n\t\n\t a.next = b;\n\t b.prev = a;\n\t\n\t a2.next = an;\n\t an.prev = a2;\n\t\n\t b2.next = a2;\n\t a2.prev = b2;\n\t\n\t bp.next = b2;\n\t b2.prev = bp;\n\t\n\t return b2;\n\t}\n\t\n\t// create a node and optionally link it with previous one (in a circular doubly linked list)\n\tfunction insertNode(i, x, y, last) {\n\t var p = new Node(i, x, y);\n\t\n\t if (!last) {\n\t p.prev = p;\n\t p.next = p;\n\t\n\t } else {\n\t p.next = last.next;\n\t p.prev = last;\n\t last.next.prev = p;\n\t last.next = p;\n\t }\n\t return p;\n\t}\n\t\n\tfunction removeNode(p) {\n\t p.next.prev = p.prev;\n\t p.prev.next = p.next;\n\t\n\t if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n\t if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n\t}\n\t\n\tfunction Node(i, x, y) {\n\t // vertice index in coordinates array\n\t this.i = i;\n\t\n\t // vertex coordinates\n\t this.x = x;\n\t this.y = y;\n\t\n\t // previous and next vertice nodes in a polygon ring\n\t this.prev = null;\n\t this.next = null;\n\t\n\t // z-order curve value\n\t this.z = null;\n\t\n\t // previous and next nodes in z-order\n\t this.prevZ = null;\n\t this.nextZ = null;\n\t\n\t // indicates whether this is a steiner point\n\t this.steiner = false;\n\t}\n\t\n\t// return a percentage difference between the polygon area and its triangulation area;\n\t// used to verify correctness of triangulation\n\tearcut.deviation = function (data, holeIndices, dim, triangles) {\n\t var hasHoles = holeIndices && holeIndices.length;\n\t var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\t\n\t var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n\t if (hasHoles) {\n\t for (var i = 0, len = holeIndices.length; i < len; i++) {\n\t var start = holeIndices[i] * dim;\n\t var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n\t polygonArea -= Math.abs(signedArea(data, start, end, dim));\n\t }\n\t }\n\t\n\t var trianglesArea = 0;\n\t for (i = 0; i < triangles.length; i += 3) {\n\t var a = triangles[i] * dim;\n\t var b = triangles[i + 1] * dim;\n\t var c = triangles[i + 2] * dim;\n\t trianglesArea += Math.abs(\n\t (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n\t (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n\t }\n\t\n\t return polygonArea === 0 && trianglesArea === 0 ? 0 :\n\t Math.abs((trianglesArea - polygonArea) / polygonArea);\n\t};\n\t\n\tfunction signedArea(data, start, end, dim) {\n\t var sum = 0;\n\t for (var i = start, j = end - dim; i < end; i += dim) {\n\t sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n\t j = i;\n\t }\n\t return sum;\n\t}\n\t\n\t// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\n\tearcut.flatten = function (data) {\n\t var dim = data[0][0].length,\n\t result = {vertices: [], holes: [], dimensions: dim},\n\t holeIndex = 0;\n\t\n\t for (var i = 0; i < data.length; i++) {\n\t for (var j = 0; j < data[i].length; j++) {\n\t for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n\t }\n\t if (i > 0) {\n\t holeIndex += data[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t return result;\n\t};\n\n\n/***/ },\n/* 68 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * Extrude a polygon given its vertices and triangulated faces\n\t *\n\t * Based on:\n\t * https://github.com/freeman-lab/extrude\n\t */\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar extrudePolygon = function extrudePolygon(points, faces, _options) {\n\t var defaults = {\n\t top: 1,\n\t bottom: 0,\n\t closed: true\n\t };\n\t\n\t var options = (0, _lodashAssign2['default'])({}, defaults, _options);\n\t\n\t var n = points.length;\n\t var positions;\n\t var cells;\n\t var topCells;\n\t var bottomCells;\n\t var sideCells;\n\t\n\t // If bottom and top values are identical then return the flat shape\n\t options.top === options.bottom ? flat() : full();\n\t\n\t function flat() {\n\t positions = points.map(function (p) {\n\t return [p[0], options.top, p[1]];\n\t });\n\t cells = faces;\n\t topCells = faces;\n\t }\n\t\n\t function full() {\n\t positions = [];\n\t points.forEach(function (p) {\n\t positions.push([p[0], options.top, p[1]]);\n\t });\n\t points.forEach(function (p) {\n\t positions.push([p[0], options.bottom, p[1]]);\n\t });\n\t\n\t cells = [];\n\t for (var i = 0; i < n; i++) {\n\t if (i === n - 1) {\n\t cells.push([i + n, n, i]);\n\t cells.push([0, i, n]);\n\t } else {\n\t cells.push([i + n, i + n + 1, i]);\n\t cells.push([i + 1, i, i + n + 1]);\n\t }\n\t }\n\t\n\t sideCells = [].concat(cells);\n\t\n\t if (options.closed) {\n\t var top = faces;\n\t var bottom = top.map(function (p) {\n\t return p.map(function (v) {\n\t return v + n;\n\t });\n\t });\n\t bottom = bottom.map(function (p) {\n\t return [p[0], p[2], p[1]];\n\t });\n\t cells = cells.concat(top).concat(bottom);\n\t\n\t topCells = top;\n\t bottomCells = bottom;\n\t }\n\t }\n\t\n\t return {\n\t positions: positions,\n\t faces: cells,\n\t top: topCells,\n\t bottom: bottomCells,\n\t sides: sideCells\n\t };\n\t};\n\t\n\texports['default'] = extrudePolygon;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 69 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * BufferGeometry helpers\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar Buffer = (function () {\n\t // Merge multiple attribute objects into a single attribute object\n\t //\n\t // Attribute objects must all use the same attribute keys\n\t var mergeAttributes = function mergeAttributes(attributes) {\n\t var lengths = {};\n\t\n\t // Find array lengths\n\t attributes.forEach(function (_attributes) {\n\t for (var k in _attributes) {\n\t if (!lengths[k]) {\n\t lengths[k] = 0;\n\t }\n\t\n\t lengths[k] += _attributes[k].length;\n\t }\n\t });\n\t\n\t var mergedAttributes = {};\n\t\n\t // Set up arrays to merge into\n\t for (var k in lengths) {\n\t mergedAttributes[k] = new Float32Array(lengths[k]);\n\t }\n\t\n\t var lastLengths = {};\n\t\n\t attributes.forEach(function (_attributes) {\n\t for (var k in _attributes) {\n\t if (!lastLengths[k]) {\n\t lastLengths[k] = 0;\n\t }\n\t\n\t mergedAttributes[k].set(_attributes[k], lastLengths[k]);\n\t\n\t lastLengths[k] += _attributes[k].length;\n\t }\n\t });\n\t\n\t return mergedAttributes;\n\t };\n\t\n\t var createLineGeometry = function createLineGeometry(lines, offset) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t var vertices = new Float32Array(lines.verticesCount * 3);\n\t var colours = new Float32Array(lines.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (lines.pickingIds) {\n\t // One component per vertex (1)\n\t pickingIds = new Float32Array(lines.verticesCount);\n\t }\n\t\n\t var _vertices;\n\t var _colour;\n\t var _pickingId;\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < lines.vertices.length; i++) {\n\t _vertices = lines.vertices[i];\n\t _colour = lines.colours[i];\n\t\n\t if (pickingIds) {\n\t _pickingId = lines.pickingIds[i];\n\t }\n\t\n\t for (var j = 0; j < _vertices.length; j++) {\n\t var ax = _vertices[j][0] + offset.x;\n\t var ay = _vertices[j][1];\n\t var az = _vertices[j][2] + offset.y;\n\t\n\t var c1 = _colour[j];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t }\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3));\n\t\n\t if (pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t return geometry;\n\t };\n\t\n\t // TODO: Make picking IDs optional\n\t var createGeometry = function createGeometry(attributes, offset) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t // Three components per vertex per face (3 x 3 = 9)\n\t var vertices = new Float32Array(attributes.facesCount * 9);\n\t var normals = new Float32Array(attributes.facesCount * 9);\n\t var colours = new Float32Array(attributes.facesCount * 9);\n\t\n\t var pickingIds;\n\t if (attributes.pickingIds) {\n\t // One component per vertex per face (1 x 3 = 3)\n\t pickingIds = new Float32Array(attributes.facesCount * 3);\n\t }\n\t\n\t var pA = new _three2['default'].Vector3();\n\t var pB = new _three2['default'].Vector3();\n\t var pC = new _three2['default'].Vector3();\n\t\n\t var cb = new _three2['default'].Vector3();\n\t var ab = new _three2['default'].Vector3();\n\t\n\t var index;\n\t var _faces;\n\t var _vertices;\n\t var _colour;\n\t var _pickingId;\n\t var lastIndex = 0;\n\t for (var i = 0; i < attributes.faces.length; i++) {\n\t _faces = attributes.faces[i];\n\t _vertices = attributes.vertices[i];\n\t _colour = attributes.colours[i];\n\t\n\t if (pickingIds) {\n\t _pickingId = attributes.pickingIds[i];\n\t }\n\t\n\t for (var j = 0; j < _faces.length; j++) {\n\t // Array of vertex indexes for the face\n\t index = _faces[j][0];\n\t\n\t var ax = _vertices[index][0] + offset.x;\n\t var ay = _vertices[index][1];\n\t var az = _vertices[index][2] + offset.y;\n\t\n\t var c1 = _colour[j][0];\n\t\n\t index = _faces[j][1];\n\t\n\t var bx = _vertices[index][0] + offset.x;\n\t var by = _vertices[index][1];\n\t var bz = _vertices[index][2] + offset.y;\n\t\n\t var c2 = _colour[j][1];\n\t\n\t index = _faces[j][2];\n\t\n\t var cx = _vertices[index][0] + offset.x;\n\t var cy = _vertices[index][1];\n\t var cz = _vertices[index][2] + offset.y;\n\t\n\t var c3 = _colour[j][2];\n\t\n\t // Flat face normals\n\t // From: http://threejs.org/examples/webgl_buffergeometry.html\n\t pA.set(ax, ay, az);\n\t pB.set(bx, by, bz);\n\t pC.set(cx, cy, cz);\n\t\n\t cb.subVectors(pC, pB);\n\t ab.subVectors(pA, pB);\n\t cb.cross(ab);\n\t\n\t cb.normalize();\n\t\n\t var nx = cb.x;\n\t var ny = cb.y;\n\t var nz = cb.z;\n\t\n\t vertices[lastIndex * 9 + 0] = ax;\n\t vertices[lastIndex * 9 + 1] = ay;\n\t vertices[lastIndex * 9 + 2] = az;\n\t\n\t normals[lastIndex * 9 + 0] = nx;\n\t normals[lastIndex * 9 + 1] = ny;\n\t normals[lastIndex * 9 + 2] = nz;\n\t\n\t colours[lastIndex * 9 + 0] = c1[0];\n\t colours[lastIndex * 9 + 1] = c1[1];\n\t colours[lastIndex * 9 + 2] = c1[2];\n\t\n\t vertices[lastIndex * 9 + 3] = bx;\n\t vertices[lastIndex * 9 + 4] = by;\n\t vertices[lastIndex * 9 + 5] = bz;\n\t\n\t normals[lastIndex * 9 + 3] = nx;\n\t normals[lastIndex * 9 + 4] = ny;\n\t normals[lastIndex * 9 + 5] = nz;\n\t\n\t colours[lastIndex * 9 + 3] = c2[0];\n\t colours[lastIndex * 9 + 4] = c2[1];\n\t colours[lastIndex * 9 + 5] = c2[2];\n\t\n\t vertices[lastIndex * 9 + 6] = cx;\n\t vertices[lastIndex * 9 + 7] = cy;\n\t vertices[lastIndex * 9 + 8] = cz;\n\t\n\t normals[lastIndex * 9 + 6] = nx;\n\t normals[lastIndex * 9 + 7] = ny;\n\t normals[lastIndex * 9 + 8] = nz;\n\t\n\t colours[lastIndex * 9 + 6] = c3[0];\n\t colours[lastIndex * 9 + 7] = c3[1];\n\t colours[lastIndex * 9 + 8] = c3[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex * 3 + 0] = _pickingId;\n\t pickingIds[lastIndex * 3 + 1] = _pickingId;\n\t pickingIds[lastIndex * 3 + 2] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t }\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3));\n\t geometry.addAttribute('normal', new _three2['default'].BufferAttribute(normals, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3));\n\t\n\t if (pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t return geometry;\n\t };\n\t\n\t return {\n\t mergeAttributes: mergeAttributes,\n\t createLineGeometry: createLineGeometry,\n\t createGeometry: createGeometry\n\t };\n\t})();\n\t\n\texports['default'] = Buffer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 70 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _PickingShader = __webpack_require__(71);\n\t\n\tvar _PickingShader2 = _interopRequireDefault(_PickingShader);\n\t\n\t// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\t\n\tvar PickingMaterial = function PickingMaterial() {\n\t _three2['default'].ShaderMaterial.call(this, {\n\t uniforms: {\n\t size: {\n\t type: 'f',\n\t value: 0.01\n\t },\n\t scale: {\n\t type: 'f',\n\t value: 400\n\t }\n\t },\n\t // attributes: ['position', 'id'],\n\t vertexShader: _PickingShader2['default'].vertexShader,\n\t fragmentShader: _PickingShader2['default'].fragmentShader\n\t });\n\t\n\t this.linePadding = 2;\n\t};\n\t\n\tPickingMaterial.prototype = Object.create(_three2['default'].ShaderMaterial.prototype);\n\t\n\tPickingMaterial.prototype.constructor = PickingMaterial;\n\t\n\tPickingMaterial.prototype.setPointSize = function (size) {\n\t this.uniforms.size.value = size;\n\t};\n\t\n\tPickingMaterial.prototype.setPointScale = function (scale) {\n\t this.uniforms.scale.value = scale;\n\t};\n\t\n\texports['default'] = PickingMaterial;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 71 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\t\n\tvar PickingShader = {\n\t\tvertexShader: ['attribute float pickingId;',\n\t\t// '',\n\t\t// 'uniform float size;',\n\t\t// 'uniform float scale;',\n\t\t'', 'varying vec4 worldId;', '', 'void main() {', ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',\n\t\t// ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );',\n\t\t' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);', ' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);', ' worldId = vec4(a,1);', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t\tfragmentShader: ['#ifdef GL_ES\\n', 'precision highp float;\\n', '#endif\\n', '', 'varying vec4 worldId;', '', 'void main() {', ' gl_FragColor = worldId;', '}'].join('\\n')\n\t};\n\t\n\texports['default'] = PickingShader;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 72 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\t// TODO: Allow _setBufferAttributes to use a custom function passed in to\n\t// generate a custom mesh\n\t\n\tvar _Layer2 = __webpack_require__(32);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _earcut2 = __webpack_require__(67);\n\t\n\tvar _earcut3 = _interopRequireDefault(_earcut2);\n\t\n\tvar _utilExtrudePolygon = __webpack_require__(68);\n\t\n\tvar _utilExtrudePolygon2 = _interopRequireDefault(_utilExtrudePolygon);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(70);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(69);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PolygonLayer = (function (_Layer) {\n\t _inherits(PolygonLayer, _Layer);\n\t\n\t function PolygonLayer(coordinates, options) {\n\t _classCallCheck(this, PolygonLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t material: null,\n\t onMesh: null,\n\t onBufferAttributes: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t color: '#ffffff',\n\t transparent: false,\n\t opacity: 1,\n\t blending: _three2['default'].NormalBlending,\n\t height: 0\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PolygonLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of polygons so it's easy to support\n\t // MultiPolygon features (a single polygon would be a MultiPolygon with a\n\t // single polygon in the array)\n\t this._coordinates = PolygonLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t }\n\t\n\t _createClass(PolygonLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t this._setCoordinates();\n\t\n\t if (this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (this.isOutput()) {\n\t this._pickingMesh = new _three2['default'].Object3D();\n\t this.addToPicking(this._pickingMesh);\n\t }\n\t\n\t this._setPickingId();\n\t this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t this._setBufferAttributes();\n\t\n\t if (this.isOutput()) {\n\t // Set mesh if not merging elsewhere\n\t this._setMesh(this._bufferAttributes);\n\t\n\t // Output mesh\n\t this.add(this._mesh);\n\t }\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Return center of polygon as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t //\n\t // TODO: Find proper center position instead of returning first coordinate\n\t // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return polygon bounds in geographic coordinates\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this.emit('click', _this, point2d, point3d, intersects);\n\t });\n\t }\n\t\n\t // Create and store reference to THREE.BufferAttribute data for this layer\n\t }, {\n\t key: '_setBufferAttributes',\n\t value: function _setBufferAttributes() {\n\t var _this2 = this;\n\t\n\t var attributes;\n\t\n\t // Only use this if you know what you're doing\n\t if (typeof this._options.onBufferAttributes === 'function') {\n\t // TODO: Probably want to pass something less general as arguments,\n\t // though passing the instance will do for now (it's everything)\n\t attributes = this._options.onBufferAttributes(this);\n\t } else {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (this._options.style.height && this._options.style.height !== 0) {\n\t height = this._world.metresToWorld(this._options.style.height, this._pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(this._options.style.color);\n\t\n\t // Light and dark colours used for poor-mans AO gradient on object sides\n\t var light = new _three2['default'].Color(0xffffff);\n\t var shadow = new _three2['default'].Color(0x666666);\n\t\n\t // For each polygon\n\t attributes = this._projectedCoordinates.map(function (_projectedCoordinates) {\n\t // Convert coordinates to earcut format\n\t var _earcut = _this2._toEarcut(_projectedCoordinates);\n\t\n\t // Triangulate faces using earcut\n\t var faces = _this2._triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions);\n\t\n\t var groupedVertices = [];\n\t for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) {\n\t groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions));\n\t }\n\t\n\t var extruded = (0, _utilExtrudePolygon2['default'])(groupedVertices, faces, {\n\t bottom: 0,\n\t top: height\n\t });\n\t\n\t var topColor = colour.clone().multiply(light);\n\t var bottomColor = colour.clone().multiply(shadow);\n\t\n\t var _vertices = extruded.positions;\n\t var _faces = [];\n\t var _colours = [];\n\t\n\t var _colour;\n\t extruded.top.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t\n\t _this2._flat = true;\n\t\n\t if (extruded.sides) {\n\t _this2._flat = false;\n\t\n\t // Set up colours for every vertex with poor-mans AO on the sides\n\t extruded.sides.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t // First face is always bottom-bottom-top\n\t if (fi % 2 === 0) {\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t // Reverse winding for the second face\n\t // top-top-bottom\n\t } else {\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t }\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t }\n\t\n\t // Skip bottom as there's no point rendering it\n\t // allFaces.push(extruded.faces);\n\t\n\t var polygon = {\n\t vertices: _vertices,\n\t faces: _faces,\n\t colours: _colours,\n\t facesCount: _faces.length\n\t };\n\t\n\t if (_this2._options.interactive && _this2._pickingId) {\n\t // Inject picking ID\n\t polygon.pickingId = _this2._pickingId;\n\t }\n\t\n\t // Convert polygon representation to proper attribute arrays\n\t return _this2._toAttributes(polygon);\n\t });\n\t }\n\t\n\t this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes);\n\t\n\t // Original attributes are no longer required so free the memory\n\t attributes = null;\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // This is only called if the layer is controlling its own output\n\t }, {\n\t key: '_setMesh',\n\t value: function _setMesh(attributes) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3));\n\t geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3));\n\t\n\t if (attributes.pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (this._options.material && this._options.material instanceof _three2['default'].Material) {\n\t material = this._options.material;\n\t } else if (!this._world._environment._skybox) {\n\t material = new _three2['default'].MeshPhongMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t side: _three2['default'].BackSide,\n\t transparent: this._options.style.transparent,\n\t opacity: this._options.style.opacity,\n\t blending: this._options.style.blending\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t side: _three2['default'].BackSide,\n\t transparent: this._options.style.transparent,\n\t opacity: this._options.style.opacity,\n\t blending: this._options.style.blending\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = this._world._environment._skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof this._options.onMesh === 'function') {\n\t mesh = this._options.onMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t mesh.receiveShadow = true;\n\t }\n\t\n\t if (this.isFlat()) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = 1;\n\t }\n\t\n\t if (this._options.interactive && this._pickingMesh) {\n\t material = new _enginePickingMaterial2['default']();\n\t material.side = _three2['default'].BackSide;\n\t\n\t var pickingMesh = new _three2['default'].Mesh(geometry, material);\n\t this._pickingMesh.add(pickingMesh);\n\t }\n\t\n\t this._mesh = mesh;\n\t }\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t }, {\n\t key: '_setCoordinates',\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates[0][0][0];\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var point;\n\t return this._coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (latlon) {\n\t point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * point.x;\n\t _this3._offset.y = -1 * point.y;\n\t\n\t _this3._pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t });\n\t }\n\t\n\t // Convert coordinates array to something earcut can understand\n\t }, {\n\t key: '_toEarcut',\n\t value: function _toEarcut(coordinates) {\n\t var dim = 2;\n\t var result = { vertices: [], holes: [], dimensions: dim };\n\t var holeIndex = 0;\n\t\n\t for (var i = 0; i < coordinates.length; i++) {\n\t for (var j = 0; j < coordinates[i].length; j++) {\n\t // for (var d = 0; d < dim; d++) {\n\t result.vertices.push(coordinates[i][j].x);\n\t result.vertices.push(coordinates[i][j].y);\n\t // }\n\t }\n\t if (i > 0) {\n\t holeIndex += coordinates[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t\n\t return result;\n\t }\n\t\n\t // Triangulate earcut-based input using earcut\n\t }, {\n\t key: '_triangulate',\n\t value: function _triangulate(contour, holes, dim) {\n\t // console.time('earcut');\n\t\n\t var faces = (0, _earcut3['default'])(contour, holes, dim);\n\t var result = [];\n\t\n\t for (i = 0, il = faces.length; i < il; i += 3) {\n\t result.push(faces.slice(i, i + 3));\n\t }\n\t\n\t // console.timeEnd('earcut');\n\t\n\t return result;\n\t }\n\t\n\t // Transform polygon representation into attribute arrays that can be used by\n\t // THREE.BufferGeometry\n\t //\n\t // TODO: Can this be simplified? It's messy and huge\n\t }, {\n\t key: '_toAttributes',\n\t value: function _toAttributes(polygon) {\n\t // Three components per vertex per face (3 x 3 = 9)\n\t var vertices = new Float32Array(polygon.facesCount * 9);\n\t var normals = new Float32Array(polygon.facesCount * 9);\n\t var colours = new Float32Array(polygon.facesCount * 9);\n\t\n\t var pickingIds;\n\t if (polygon.pickingId) {\n\t // One component per vertex per face (1 x 3 = 3)\n\t pickingIds = new Float32Array(polygon.facesCount * 3);\n\t }\n\t\n\t var pA = new _three2['default'].Vector3();\n\t var pB = new _three2['default'].Vector3();\n\t var pC = new _three2['default'].Vector3();\n\t\n\t var cb = new _three2['default'].Vector3();\n\t var ab = new _three2['default'].Vector3();\n\t\n\t var index;\n\t\n\t var _faces = polygon.faces;\n\t var _vertices = polygon.vertices;\n\t var _colour = polygon.colours;\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = polygon.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _faces.length; i++) {\n\t // Array of vertex indexes for the face\n\t index = _faces[i][0];\n\t\n\t var ax = _vertices[index][0];\n\t var ay = _vertices[index][1];\n\t var az = _vertices[index][2];\n\t\n\t var c1 = _colour[i][0];\n\t\n\t index = _faces[i][1];\n\t\n\t var bx = _vertices[index][0];\n\t var by = _vertices[index][1];\n\t var bz = _vertices[index][2];\n\t\n\t var c2 = _colour[i][1];\n\t\n\t index = _faces[i][2];\n\t\n\t var cx = _vertices[index][0];\n\t var cy = _vertices[index][1];\n\t var cz = _vertices[index][2];\n\t\n\t var c3 = _colour[i][2];\n\t\n\t // Flat face normals\n\t // From: http://threejs.org/examples/webgl_buffergeometry.html\n\t pA.set(ax, ay, az);\n\t pB.set(bx, by, bz);\n\t pC.set(cx, cy, cz);\n\t\n\t cb.subVectors(pC, pB);\n\t ab.subVectors(pA, pB);\n\t cb.cross(ab);\n\t\n\t cb.normalize();\n\t\n\t var nx = cb.x;\n\t var ny = cb.y;\n\t var nz = cb.z;\n\t\n\t vertices[lastIndex * 9 + 0] = ax;\n\t vertices[lastIndex * 9 + 1] = ay;\n\t vertices[lastIndex * 9 + 2] = az;\n\t\n\t normals[lastIndex * 9 + 0] = nx;\n\t normals[lastIndex * 9 + 1] = ny;\n\t normals[lastIndex * 9 + 2] = nz;\n\t\n\t colours[lastIndex * 9 + 0] = c1[0];\n\t colours[lastIndex * 9 + 1] = c1[1];\n\t colours[lastIndex * 9 + 2] = c1[2];\n\t\n\t vertices[lastIndex * 9 + 3] = bx;\n\t vertices[lastIndex * 9 + 4] = by;\n\t vertices[lastIndex * 9 + 5] = bz;\n\t\n\t normals[lastIndex * 9 + 3] = nx;\n\t normals[lastIndex * 9 + 4] = ny;\n\t normals[lastIndex * 9 + 5] = nz;\n\t\n\t colours[lastIndex * 9 + 3] = c2[0];\n\t colours[lastIndex * 9 + 4] = c2[1];\n\t colours[lastIndex * 9 + 5] = c2[2];\n\t\n\t vertices[lastIndex * 9 + 6] = cx;\n\t vertices[lastIndex * 9 + 7] = cy;\n\t vertices[lastIndex * 9 + 8] = cz;\n\t\n\t normals[lastIndex * 9 + 6] = nx;\n\t normals[lastIndex * 9 + 7] = ny;\n\t normals[lastIndex * 9 + 8] = nz;\n\t\n\t colours[lastIndex * 9 + 6] = c3[0];\n\t colours[lastIndex * 9 + 7] = c3[1];\n\t colours[lastIndex * 9 + 8] = c3[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex * 3 + 0] = _pickingId;\n\t pickingIds[lastIndex * 3 + 1] = _pickingId;\n\t pickingIds[lastIndex * 3 + 2] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t vertices: vertices,\n\t normals: normals,\n\t colours: colours\n\t };\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t\n\t // Returns true if the polygon is flat (has no height)\n\t }, {\n\t key: 'isFlat',\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiPolygon GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t\n\t // TODO: Make sure this is cleaning everything\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PolygonLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0][0][0]);\n\t }\n\t }]);\n\t\n\t return PolygonLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PolygonLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PolygonLayer(coordinates, options);\n\t};\n\t\n\texports.polygonLayer = noNew;\n\n/***/ },\n/* 73 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Provide alternative output using tubes and splines / curves\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\t// TODO: Allow _setBufferAttributes to use a custom function passed in to\n\t// generate a custom mesh\n\t\n\tvar _Layer2 = __webpack_require__(32);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(70);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(69);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PolylineLayer = (function (_Layer) {\n\t _inherits(PolylineLayer, _Layer);\n\t\n\t function PolylineLayer(coordinates, options) {\n\t _classCallCheck(this, PolylineLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t material: null,\n\t onMesh: null,\n\t onBufferAttributes: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t lineOpacity: 1,\n\t lineTransparent: false,\n\t lineColor: '#ffffff',\n\t lineWidth: 1,\n\t lineBlending: _three2['default'].NormalBlending\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PolylineLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of lines so it's easy to support\n\t // MultiLineString features (a single line would be a MultiLineString with a\n\t // single line in the array)\n\t this._coordinates = PolylineLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t // Polyline features are always flat (for now at least)\n\t this._flat = true;\n\t }\n\t\n\t _createClass(PolylineLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t this._setCoordinates();\n\t\n\t if (this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (this.isOutput()) {\n\t this._pickingMesh = new _three2['default'].Object3D();\n\t this.addToPicking(this._pickingMesh);\n\t }\n\t\n\t this._setPickingId();\n\t this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t this._setBufferAttributes();\n\t\n\t if (this.isOutput()) {\n\t // Set mesh if not merging elsewhere\n\t this._setMesh(this._bufferAttributes);\n\t\n\t // Output mesh\n\t this.add(this._mesh);\n\t }\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Return center of polyline as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t //\n\t // TODO: Find proper center position instead of returning first coordinate\n\t // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return line bounds in geographic coordinates\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this.emit('click', _this, point2d, point3d, intersects);\n\t });\n\t }\n\t\n\t // Create and store reference to THREE.BufferAttribute data for this layer\n\t }, {\n\t key: '_setBufferAttributes',\n\t value: function _setBufferAttributes() {\n\t var _this2 = this;\n\t\n\t var attributes;\n\t\n\t // Only use this if you know what you're doing\n\t if (typeof this._options.onBufferAttributes === 'function') {\n\t // TODO: Probably want to pass something less general as arguments,\n\t // though passing the instance will do for now (it's everything)\n\t attributes = this._options.onBufferAttributes(this);\n\t } else {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (this._options.style.lineHeight) {\n\t height = this._world.metresToWorld(this._options.style.lineHeight, this._pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(this._options.style.lineColor);\n\t\n\t // For each line\n\t attributes = this._projectedCoordinates.map(function (_projectedCoordinates) {\n\t var _vertices = [];\n\t var _colours = [];\n\t\n\t // Connect coordinate with the next to make a pair\n\t //\n\t // LineSegments requires pairs of vertices so repeat the last point if\n\t // there's an odd number of vertices\n\t var nextCoord;\n\t _projectedCoordinates.forEach(function (coordinate, index) {\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _vertices.push([coordinate.x, height, coordinate.y]);\n\t\n\t nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate;\n\t\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _vertices.push([nextCoord.x, height, nextCoord.y]);\n\t });\n\t\n\t var line = {\n\t vertices: _vertices,\n\t colours: _colours,\n\t verticesCount: _vertices.length\n\t };\n\t\n\t if (_this2._options.interactive && _this2._pickingId) {\n\t // Inject picking ID\n\t line.pickingId = _this2._pickingId;\n\t }\n\t\n\t // Convert line representation to proper attribute arrays\n\t return _this2._toAttributes(line);\n\t });\n\t }\n\t\n\t this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes);\n\t\n\t // Original attributes are no longer required so free the memory\n\t attributes = null;\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // This is only called if the layer is controlling its own output\n\t }, {\n\t key: '_setMesh',\n\t value: function _setMesh(attributes) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3));\n\t\n\t if (attributes.normals) {\n\t geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3));\n\t }\n\t\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3));\n\t\n\t if (attributes.pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var style = this._options.style;\n\t var material;\n\t\n\t if (this._options.material && this._options.material instanceof _three2['default'].Material) {\n\t material = this._options.material;\n\t } else {\n\t material = new _three2['default'].LineBasicMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t linewidth: style.lineWidth,\n\t transparent: style.lineTransparent,\n\t opacity: style.lineOpacity,\n\t blending: style.lineBlending\n\t });\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof this._options.onMesh === 'function') {\n\t mesh = this._options.onMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].LineSegments(geometry, material);\n\t\n\t if (style.lineRenderOrder !== undefined) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = style.lineRenderOrder;\n\t }\n\t\n\t mesh.castShadow = true;\n\t // mesh.receiveShadow = true;\n\t }\n\t\n\t // TODO: Allow this to be overridden, or copy mesh instead of creating a new\n\t // one just for picking\n\t if (this._options.interactive && this._pickingMesh) {\n\t material = new _enginePickingMaterial2['default']();\n\t // material.side = THREE.BackSide;\n\t\n\t // Make the line wider / easier to pick\n\t material.linewidth = style.lineWidth + material.linePadding;\n\t\n\t var pickingMesh = new _three2['default'].LineSegments(geometry, material);\n\t this._pickingMesh.add(pickingMesh);\n\t }\n\t\n\t this._mesh = mesh;\n\t }\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t }, {\n\t key: '_setCoordinates',\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates[0][0];\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var point;\n\t return this._coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (latlon) {\n\t point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * point.x;\n\t _this3._offset.y = -1 * point.y;\n\t\n\t _this3._pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t }\n\t\n\t // Transform line representation into attribute arrays that can be used by\n\t // THREE.BufferGeometry\n\t //\n\t // TODO: Can this be simplified? It's messy and huge\n\t }, {\n\t key: '_toAttributes',\n\t value: function _toAttributes(line) {\n\t // Three components per vertex\n\t var vertices = new Float32Array(line.verticesCount * 3);\n\t var colours = new Float32Array(line.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (line.pickingId) {\n\t // One component per vertex\n\t pickingIds = new Float32Array(line.verticesCount);\n\t }\n\t\n\t var _vertices = line.vertices;\n\t var _colour = line.colours;\n\t\n\t var normals;\n\t var _normals;\n\t if (line.normals) {\n\t normals = new Float32Array(line.verticesCount * 3);\n\t _normals = line.normals;\n\t }\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = line.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _vertices.length; i++) {\n\t var ax = _vertices[i][0];\n\t var ay = _vertices[i][1];\n\t var az = _vertices[i][2];\n\t\n\t var nx;\n\t var ny;\n\t var nz;\n\t if (_normals) {\n\t nx = _normals[i][0];\n\t ny = _normals[i][1];\n\t nz = _normals[i][2];\n\t }\n\t\n\t var c1 = _colour[i];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t if (normals) {\n\t normals[lastIndex * 3 + 0] = nx;\n\t normals[lastIndex * 3 + 1] = ny;\n\t normals[lastIndex * 3 + 2] = nz;\n\t }\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t vertices: vertices,\n\t colours: colours\n\t };\n\t\n\t if (normals) {\n\t attributes.normals = normals;\n\t }\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t\n\t // Returns true if the line is flat (has no height)\n\t }, {\n\t key: 'isFlat',\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiLineString GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PolylineLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0][0]);\n\t }\n\t }]);\n\t\n\t return PolylineLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PolylineLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PolylineLayer(coordinates, options);\n\t};\n\t\n\texports.polylineLayer = noNew;\n\n/***/ },\n/* 74 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Point features may be using custom models / meshes and so an approach\n\t// needs to be found to allow these to be brokwn down into buffer attributes for\n\t// merging\n\t//\n\t// Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry\n\t// and pull out the attributes\n\t\n\t// TODO: Support sprite objects using textures\n\t\n\t// TODO: Provide option to billboard geometry so it always faces the camera\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\tvar _Layer2 = __webpack_require__(32);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(70);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(69);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PointLayer = (function (_Layer) {\n\t _inherits(PointLayer, _Layer);\n\t\n\t function PointLayer(coordinates, options) {\n\t _classCallCheck(this, PointLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // THREE.Geometry or THREE.BufferGeometry to use for point output\n\t geometry: null,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t material: null,\n\t onMesh: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t pointColor: '#ff0000'\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PointLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of points so it's easy to support\n\t // MultiPoint features (a single point would be a MultiPoint with a\n\t // single point in the array)\n\t this._coordinates = PointLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t // Point features are always flat (for now at least)\n\t //\n\t // This won't always be the case once custom point objects / meshes are\n\t // added\n\t this._flat = true;\n\t }\n\t\n\t _createClass(PointLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t this._setCoordinates();\n\t\n\t if (this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (this.isOutput()) {\n\t this._pickingMesh = new _three2['default'].Object3D();\n\t this.addToPicking(this._pickingMesh);\n\t }\n\t\n\t this._setPickingId();\n\t this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t this._setBufferAttributes();\n\t\n\t if (this.isOutput()) {\n\t // Set mesh if not merging elsewhere\n\t this._setMesh(this._bufferAttributes);\n\t\n\t // Output mesh\n\t this.add(this._mesh);\n\t }\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Return center of point as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return point bounds in geographic coordinates\n\t //\n\t // While not useful for single points, it could be useful for MultiPoint\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this.emit('click', _this, point2d, point3d, intersects);\n\t });\n\t }\n\t\n\t // Create and store reference to THREE.BufferAttribute data for this layer\n\t }, {\n\t key: '_setBufferAttributes',\n\t value: function _setBufferAttributes() {\n\t var _this2 = this;\n\t\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (this._options.style.pointHeight) {\n\t height = this._world.metresToWorld(this._options.style.pointHeight, this._pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(this._options.style.pointColor);\n\t\n\t var geometry;\n\t\n\t // Use default geometry if none has been provided or the provided geometry\n\t // isn't valid\n\t if (!this._options.geometry || !this._options.geometry instanceof _three2['default'].Geometry || !this._options.geometry instanceof _three2['default'].BufferGeometry) {\n\t // Debug geometry for points is a thin bar\n\t //\n\t // TODO: Allow point geometry to be customised / overridden\n\t var geometryWidth = this._world.metresToWorld(25, this._pointScale);\n\t var geometryHeight = this._world.metresToWorld(200, this._pointScale);\n\t var _geometry = new _three2['default'].BoxGeometry(geometryWidth, geometryHeight, geometryWidth);\n\t\n\t // Shift geometry up so it sits on the ground\n\t _geometry.translate(0, geometryHeight * 0.5, 0);\n\t\n\t // Pull attributes out of debug geometry\n\t geometry = new _three2['default'].BufferGeometry().fromGeometry(_geometry);\n\t } else {\n\t if (this._options.geometry instanceof _three2['default'].BufferGeometry) {\n\t geometry = this._options.geometry;\n\t } else {\n\t geometry = new _three2['default'].BufferGeometry().fromGeometry(this._options.geometry);\n\t }\n\t }\n\t\n\t // For each point\n\t var attributes = this._projectedCoordinates.map(function (coordinate) {\n\t var _vertices = [];\n\t var _normals = [];\n\t var _colours = [];\n\t\n\t var _geometry = geometry.clone();\n\t\n\t _geometry.translate(coordinate.x, height, coordinate.y);\n\t\n\t var _vertices = _geometry.attributes.position.clone().array;\n\t var _normals = _geometry.attributes.normal.clone().array;\n\t var _colours = _geometry.attributes.color.clone().array;\n\t\n\t for (var i = 0; i < _colours.length; i += 3) {\n\t _colours[i] = colour.r;\n\t _colours[i + 1] = colour.g;\n\t _colours[i + 2] = colour.b;\n\t }\n\t\n\t var _point = {\n\t vertices: _vertices,\n\t normals: _normals,\n\t colours: _colours\n\t };\n\t\n\t if (_this2._options.interactive && _this2._pickingId) {\n\t // Inject picking ID\n\t // point.pickingId = this._pickingId;\n\t _point.pickingIds = new Float32Array(_vertices.length / 3);\n\t for (var i = 0; i < _point.pickingIds.length; i++) {\n\t _point.pickingIds[i] = _this2._pickingId;\n\t }\n\t }\n\t\n\t // Convert point representation to proper attribute arrays\n\t // return this._toAttributes(_point);\n\t return _point;\n\t });\n\t\n\t this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(attributes);\n\t\n\t // Original attributes are no longer required so free the memory\n\t attributes = null;\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // This is only called if the layer is controlling its own output\n\t }, {\n\t key: '_setMesh',\n\t value: function _setMesh(attributes) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(attributes.vertices, 3));\n\t geometry.addAttribute('normal', new _three2['default'].BufferAttribute(attributes.normals, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(attributes.colours, 3));\n\t\n\t if (attributes.pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(attributes.pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t\n\t if (this._options.material && this._options.material instanceof _three2['default'].Material) {\n\t material = this._options.material;\n\t } else if (!this._world._environment._skybox) {\n\t material = new _three2['default'].MeshBasicMaterial({\n\t vertexColors: _three2['default'].VertexColors\n\t // side: THREE.BackSide\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t vertexColors: _three2['default'].VertexColors\n\t // side: THREE.BackSide\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = this._world._environment._skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof this._options.onMesh === 'function') {\n\t mesh = this._options.onMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t // mesh.receiveShadow = true;\n\t }\n\t\n\t if (this._options.interactive && this._pickingMesh) {\n\t material = new _enginePickingMaterial2['default']();\n\t // material.side = THREE.BackSide;\n\t\n\t var pickingMesh = new _three2['default'].Mesh(geometry, material);\n\t this._pickingMesh.add(pickingMesh);\n\t }\n\t\n\t this._mesh = mesh;\n\t }\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t }, {\n\t key: '_setCoordinates',\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates;\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var _point;\n\t return this._coordinates.map(function (latlon) {\n\t _point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * _point.x;\n\t _this3._offset.y = -1 * _point.y;\n\t\n\t _this3._pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return _point;\n\t });\n\t }\n\t\n\t // Transform line representation into attribute arrays that can be used by\n\t // THREE.BufferGeometry\n\t //\n\t // TODO: Can this be simplified? It's messy and huge\n\t }, {\n\t key: '_toAttributes',\n\t value: function _toAttributes(line) {\n\t // Three components per vertex\n\t var vertices = new Float32Array(line.verticesCount * 3);\n\t var colours = new Float32Array(line.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (line.pickingId) {\n\t // One component per vertex\n\t pickingIds = new Float32Array(line.verticesCount);\n\t }\n\t\n\t var _vertices = line.vertices;\n\t var _colour = line.colours;\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = line.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _vertices.length; i++) {\n\t var ax = _vertices[i][0];\n\t var ay = _vertices[i][1];\n\t var az = _vertices[i][2];\n\t\n\t var c1 = _colour[i];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t vertices: vertices,\n\t colours: colours\n\t };\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t\n\t // Returns true if the line is flat (has no height)\n\t }, {\n\t key: 'isFlat',\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiPoint GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PointLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0]);\n\t }\n\t }]);\n\t\n\t return PointLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PointLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PointLayer(coordinates, options);\n\t};\n\t\n\texports.pointLayer = noNew;\n\n/***/ },\n/* 75 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _GeoJSONTileLayer2 = __webpack_require__(57);\n\t\n\tvar _GeoJSONTileLayer3 = _interopRequireDefault(_GeoJSONTileLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar TopoJSONTileLayer = (function (_GeoJSONTileLayer) {\n\t _inherits(TopoJSONTileLayer, _GeoJSONTileLayer);\n\t\n\t function TopoJSONTileLayer(path, options) {\n\t _classCallCheck(this, TopoJSONTileLayer);\n\t\n\t var defaults = {\n\t topojson: true\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TopoJSONTileLayer.prototype), 'constructor', this).call(this, path, options);\n\t }\n\t\n\t return TopoJSONTileLayer;\n\t})(_GeoJSONTileLayer3['default']);\n\t\n\texports['default'] = TopoJSONTileLayer;\n\t\n\tvar noNew = function noNew(path, options) {\n\t return new TopoJSONTileLayer(path, options);\n\t};\n\t\n\texports.topoJSONTileLayer = noNew;\n\n/***/ },\n/* 76 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _GeoJSONLayer2 = __webpack_require__(59);\n\t\n\tvar _GeoJSONLayer3 = _interopRequireDefault(_GeoJSONLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar TopoJSONLayer = (function (_GeoJSONLayer) {\n\t _inherits(TopoJSONLayer, _GeoJSONLayer);\n\t\n\t function TopoJSONLayer(topojson, options) {\n\t _classCallCheck(this, TopoJSONLayer);\n\t\n\t var defaults = {\n\t topojson: true\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TopoJSONLayer.prototype), 'constructor', this).call(this, topojson, options);\n\t }\n\t\n\t return TopoJSONLayer;\n\t})(_GeoJSONLayer3['default']);\n\t\n\texports['default'] = TopoJSONLayer;\n\t\n\tvar noNew = function noNew(topojson, options) {\n\t return new TopoJSONLayer(topojson, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.topoJSONLayer = noNew;\n\n/***/ },\n/* 77 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// TODO: A lot of these utils don't need to be in separate, tiny files\n\t\n\tvar _wrapNum = __webpack_require__(78);\n\t\n\tvar _wrapNum2 = _interopRequireDefault(_wrapNum);\n\t\n\tvar _extrudePolygon = __webpack_require__(68);\n\t\n\tvar _extrudePolygon2 = _interopRequireDefault(_extrudePolygon);\n\t\n\tvar _GeoJSON = __webpack_require__(63);\n\t\n\tvar _GeoJSON2 = _interopRequireDefault(_GeoJSON);\n\t\n\tvar _Buffer = __webpack_require__(69);\n\t\n\tvar _Buffer2 = _interopRequireDefault(_Buffer);\n\t\n\tvar Util = {};\n\t\n\tUtil.wrapNum = _wrapNum2['default'];\n\tUtil.extrudePolygon = _extrudePolygon2['default'];\n\tUtil.GeoJSON = _GeoJSON2['default'];\n\tUtil.Buffer = _Buffer2['default'];\n\t\n\texports['default'] = Util;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 78 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t/*\n\t * Wrap the given number to lie within a certain range (eg. longitude)\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js\n\t */\n\t\n\tvar wrapNum = function wrapNum(x, range, includeMax) {\n\t var max = range[1];\n\t var min = range[0];\n\t var d = max - min;\n\t return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\n\t};\n\t\n\texports[\"default\"] = wrapNum;\n\tmodule.exports = exports[\"default\"];\n\n/***/ }\n/******/ ])\n});\n;"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 0f33548065d4c06208b0\n **/","import World, {world} from './World';\nimport Controls from './controls/index';\n\nimport Geo from './geo/Geo.js';\n\nimport Layer, {layer} from './layer/Layer';\nimport EnvironmentLayer, {environmentLayer} from './layer/environment/EnvironmentLayer';\nimport ImageTileLayer, {imageTileLayer} from './layer/tile/ImageTileLayer';\nimport GeoJSONTileLayer, {geoJSONTileLayer} from './layer/tile/GeoJSONTileLayer';\nimport TopoJSONTileLayer, {topoJSONTileLayer} from './layer/tile/TopoJSONTileLayer';\nimport GeoJSONLayer, {geoJSONLayer} from './layer/GeoJSONLayer';\nimport TopoJSONLayer, {topoJSONLayer} from './layer/TopoJSONLayer';\nimport PolygonLayer, {polygonLayer} from './layer/geometry/PolygonLayer';\nimport PolylineLayer, {polylineLayer} from './layer/geometry/PolylineLayer';\nimport PointLayer, {pointLayer} from './layer/geometry/PointLayer';\n\nimport Point, {point} from './geo/Point';\nimport LatLon, {latLon} from './geo/LatLon';\n\nimport PickingMaterial from './engine/PickingMaterial';\n\nimport Util from './util/index';\n\nconst VIZI = {\n version: '0.3',\n\n // Public API\n World: World,\n world: world,\n Controls: Controls,\n Geo: Geo,\n Layer: Layer,\n layer: layer,\n EnvironmentLayer: EnvironmentLayer,\n environmentLayer: environmentLayer,\n ImageTileLayer: ImageTileLayer,\n imageTileLayer: imageTileLayer,\n GeoJSONTileLayer: GeoJSONTileLayer,\n geoJSONTileLayer: geoJSONTileLayer,\n TopoJSONTileLayer: TopoJSONTileLayer,\n topoJSONTileLayer: topoJSONTileLayer,\n GeoJSONLayer: GeoJSONLayer,\n geoJSONLayer: geoJSONLayer,\n TopoJSONLayer: TopoJSONLayer,\n topoJSONLayer: topoJSONLayer,\n PolygonLayer: PolygonLayer,\n polygonLayer: polygonLayer,\n PolylineLayer: PolylineLayer,\n polylineLayer: polylineLayer,\n PointLayer: PointLayer,\n pointLayer: pointLayer,\n Point: Point,\n point: point,\n LatLon: LatLon,\n latLon: latLon,\n PickingMaterial: PickingMaterial,\n Util: Util\n};\n\nexport default VIZI;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vizicities.js\n **/","import EventEmitter from 'eventemitter3';\nimport extend from 'lodash.assign';\nimport Geo from './geo/Geo';\nimport {point as Point} from './geo/Point';\nimport {latLon as LatLon} from './geo/LatLon';\nimport Engine from './engine/Engine';\nimport EnvironmentLayer from './layer/environment/EnvironmentLayer';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// Pretty much any event someone using ViziCities would need will be emitted or\n// proxied by World (eg. render events, etc)\n\nclass World extends EventEmitter {\n constructor(domId, options) {\n super();\n\n var defaults = {\n skybox: false,\n postProcessing: false\n };\n\n this.options = extend({}, defaults, options);\n\n this._layers = [];\n this._controls = [];\n\n this._initContainer(domId);\n this._initAttribution();\n this._initEngine();\n\n this._initEnvironment().then(() => {\n this._initEvents();\n\n this._pause = false;\n\n // Kick off the update and render loop\n this._update();\n });\n }\n\n _initContainer(domId) {\n this._container = document.getElementById(domId);\n }\n\n _initAttribution() {\n var message = 'Powered by ViziCities';\n\n var element = document.createElement('div');\n element.classList.add('vizicities-attribution');\n\n element.innerHTML = message;\n\n this._container.appendChild(element);\n }\n\n _initEngine() {\n this._engine = new Engine(this._container, this);\n\n // Engine events\n //\n // Consider proxying these through events on World for public access\n // this._engine.on('preRender', () => {});\n // this._engine.on('postRender', () => {});\n }\n\n _initEnvironment() {\n // Not sure if I want to keep this as a private API\n //\n // Makes sense to allow others to customise their environment so perhaps\n // add some method of disable / overriding the environment settings\n this._environment = new EnvironmentLayer({\n skybox: this.options.skybox\n });\n\n return this._environment.addTo(this);\n }\n\n _initEvents() {\n this.on('controlsMoveEnd', this._onControlsMoveEnd);\n }\n\n _onControlsMoveEnd(point) {\n var _point = Point(point.x, point.z);\n this._resetView(this.pointToLatLon(_point), _point);\n }\n\n // Reset world view\n _resetView(latlon, point) {\n this.emit('preResetView');\n\n this._moveStart();\n this._move(latlon, point);\n this._moveEnd();\n\n this.emit('postResetView');\n }\n\n _moveStart() {\n this.emit('moveStart');\n }\n\n _move(latlon, point) {\n this._lastPosition = latlon;\n this.emit('move', latlon, point);\n }\n _moveEnd() {\n this.emit('moveEnd');\n }\n\n _update() {\n if (this._pause) {\n return;\n }\n\n var delta = this._engine.clock.getDelta();\n\n // Once _update is called it will run forever, for now\n window.requestAnimationFrame(this._update.bind(this));\n\n // Update controls\n this._controls.forEach(controls => {\n controls.update(delta);\n });\n\n this.emit('preUpdate', delta);\n this._engine.update(delta);\n this.emit('postUpdate', delta);\n }\n\n // Set world view\n setView(latlon) {\n // Store initial geographic coordinate for the [0,0,0] world position\n //\n // The origin point doesn't move in three.js / 3D space so only set it once\n // here instead of every time _resetView is called\n //\n // If it was updated every time then coorindates would shift over time and\n // would be out of place / context with previously-placed points (0,0 would\n // refer to a different point each time)\n this._originLatlon = latlon;\n this._originPoint = this.project(latlon);\n\n this._resetView(latlon);\n return this;\n }\n\n // Return world geographic position\n getPosition() {\n return this._lastPosition;\n }\n\n // Transform geographic coordinate to world point\n //\n // This doesn't take into account the origin offset\n //\n // For example, this takes a geographic coordinate and returns a point\n // relative to the origin point of the projection (not the world)\n project(latlon) {\n return Geo.latLonToPoint(LatLon(latlon));\n }\n\n // Transform world point to geographic coordinate\n //\n // This doesn't take into account the origin offset\n //\n // For example, this takes a point relative to the origin point of the\n // projection (not the world) and returns a geographic coordinate\n unproject(point) {\n return Geo.pointToLatLon(Point(point));\n }\n\n // Takes into account the origin offset\n //\n // For example, this takes a geographic coordinate and returns a point\n // relative to the three.js / 3D origin (0,0)\n latLonToPoint(latlon) {\n var projectedPoint = this.project(LatLon(latlon));\n return projectedPoint._subtract(this._originPoint);\n }\n\n // Takes into account the origin offset\n //\n // For example, this takes a point relative to the three.js / 3D origin (0,0)\n // and returns the exact geographic coordinate at that point\n pointToLatLon(point) {\n var projectedPoint = Point(point).add(this._originPoint);\n return this.unproject(projectedPoint);\n }\n\n // Return pointscale for a given geographic coordinate\n pointScale(latlon, accurate) {\n return Geo.pointScale(latlon, accurate);\n }\n\n // Convert from real meters to world units\n //\n // TODO: Would be nice not to have to pass in a pointscale here\n metresToWorld(metres, pointScale, zoom) {\n return Geo.metresToWorld(metres, pointScale, zoom);\n }\n\n // Convert from real meters to world units\n //\n // TODO: Would be nice not to have to pass in a pointscale here\n worldToMetres(worldUnits, pointScale, zoom) {\n return Geo.worldToMetres(worldUnits, pointScale, zoom);\n }\n\n // Unsure if it's a good idea to expose this here for components like\n // GridLayer to use (eg. to keep track of a frustum)\n getCamera() {\n return this._engine._camera;\n }\n\n addLayer(layer) {\n this._layers.push(layer);\n\n if (layer.isOutput() && layer.isOutputToScene()) {\n // Could move this into Layer but it'll do here for now\n this._engine._scene.add(layer._object3D);\n this._engine._domScene3D.add(layer._domObject3D);\n this._engine._domScene2D.add(layer._domObject2D);\n }\n\n return new Promise((resolve, reject) => {\n layer._addToWorld(this).then(() => {\n this.emit('layerAdded', layer);\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Remove layer from world and scene but don't destroy it entirely\n removeLayer(layer) {\n var layerIndex = this._layers.indexOf(layer);\n\n if (layerIndex > -1) {\n // Remove from this._layers\n this._layers.splice(layerIndex, 1);\n };\n\n if (layer.isOutput() && layer.isOutputToScene()) {\n this._engine._scene.remove(layer._object3D);\n this._engine._domScene3D.remove(layer._domObject3D);\n this._engine._domScene2D.remove(layer._domObject2D);\n }\n\n this.emit('layerRemoved');\n\n return Promise.resolve(this);\n }\n\n addControls(controls) {\n controls._addToWorld(this);\n\n this._controls.push(controls);\n\n this.emit('controlsAdded', controls);\n\n return Promise.resolve(this);\n }\n\n // Remove controls from world but don't destroy them entirely\n removeControls(controls) {\n var controlsIndex = this._controls.indexOf(controlsIndex);\n\n if (controlsIndex > -1) {\n this._controls.splice(controlsIndex, 1);\n };\n\n this.emit('controlsRemoved', controls);\n\n return Promise.resolve(this);\n }\n\n stop() {\n this._pause = true;\n }\n\n start() {\n this._pause = false;\n this._update();\n }\n\n // Destroys the world(!) and removes it from the scene and memory\n //\n // TODO: World out why so much three.js stuff is left in the heap after this\n destroy() {\n this.stop();\n\n // Remove listeners\n this.off('controlsMoveEnd', this._onControlsMoveEnd);\n\n var i;\n\n // Remove all controls\n var controls;\n for (i = this._controls.length - 1; i >= 0; i--) {\n controls = this._controls[0];\n this.removeControls(controls);\n controls.destroy();\n };\n\n // Remove all layers\n var layer;\n for (i = this._layers.length - 1; i >= 0; i--) {\n layer = this._layers[0];\n this.removeLayer(layer);\n layer.destroy();\n };\n\n // Environment layer is removed with the other layers\n this._environment = null;\n\n this._engine.destroy();\n this._engine = null;\n\n // Clean the container / remove the canvas\n while (this._container.firstChild) {\n this._container.removeChild(this._container.firstChild);\n }\n\n this._container = null;\n }\n}\n\nexport default World;\n\nvar noNew = function(domId, options) {\n return new World(domId, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as world};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/World.js\n **/","'use strict';\n\nvar has = Object.prototype.hasOwnProperty;\n\n//\n// We store our EE objects in a plain object whose properties are event names.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// `~` to make sure that the built-in object properties are not overridden or\n// used as an attack vector.\n// We also assume that `Object.create(null)` is available when the event name\n// is an ES6 Symbol.\n//\nvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\n/**\n * Representation of a single EventEmitter function.\n *\n * @param {Function} fn Event handler to be called.\n * @param {Mixed} context Context for function execution.\n * @param {Boolean} [once=false] Only emit once\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal EventEmitter interface that is molded against the Node.js\n * EventEmitter interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() { /* Nothing to set */ }\n\n/**\n * Hold the assigned EventEmitters by name.\n *\n * @type {Object}\n * @private\n */\nEventEmitter.prototype._events = undefined;\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var events = this._events\n , names = []\n , name;\n\n if (!events) return names;\n\n for (name in events) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return a list of assigned event listeners.\n *\n * @param {String} event The events that should be listed.\n * @param {Boolean} exists We only need to know if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events && this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Emit an event to all registered event listeners.\n *\n * @param {String} event The name of the event.\n * @returns {Boolean} Indication if we've emitted an event.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events || !this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if ('function' === typeof listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Register a new EventListener for the given event.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} [context=this] The context of the function.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events) this._events = prefix ? {} : Object.create(null);\n if (!this._events[evt]) this._events[evt] = listener;\n else {\n if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [\n this._events[evt], listener\n ];\n }\n\n return this;\n};\n\n/**\n * Add an EventListener that's only called once.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} [context=this] The context of the function.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events) this._events = prefix ? {} : Object.create(null);\n if (!this._events[evt]) this._events[evt] = listener;\n else {\n if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [\n this._events[evt], listener\n ];\n }\n\n return this;\n};\n\n/**\n * Remove event listeners.\n *\n * @param {String} event The event we want to remove.\n * @param {Function} fn The listener that we need to find.\n * @param {Mixed} context Only remove listeners matching this context.\n * @param {Boolean} once Only remove once listeners.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events || !this._events[evt]) return this;\n\n var listeners = this._events[evt]\n , events = [];\n\n if (fn) {\n if (listeners.fn) {\n if (\n listeners.fn !== fn\n || (once && !listeners.once)\n || (context && listeners.context !== context)\n ) {\n events.push(listeners);\n }\n } else {\n for (var i = 0, length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) {\n this._events[evt] = events.length === 1 ? events[0] : events;\n } else {\n delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners or only the listeners for the specified event.\n *\n * @param {String} event The event want to remove all listeners for.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n if (!this._events) return this;\n\n if (event) delete this._events[prefix ? prefix + event : event];\n else this._events = prefix ? {} : Object.create(null);\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/eventemitter3/index.js\n ** module id = 2\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\nvar keys = require('lodash.keys'),\n rest = require('lodash.rest');\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\nvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : source[key];\n\n assignValue(object, key, newValue);\n }\n return object;\n}\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return rest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'user': 'fred' };\n * var other = { 'user': 'fred' };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.c = 3;\n * }\n *\n * function Bar() {\n * this.e = 5;\n * }\n *\n * Foo.prototype.d = 4;\n * Bar.prototype.f = 6;\n *\n * _.assign({ 'a': 1 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3, 'e': 5 }\n */\nvar assign = createAssigner(function(object, source) {\n if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.assign/index.js\n ** module id = 3\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n stringTag = '[object String]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetPrototype = Object.getPrototypeOf,\n nativeKeys = Object.keys;\n\n/**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHas(object, key) {\n // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n // that are composed entirely of index properties, return `false` for\n // `hasOwnProperty` checks of them.\n return hasOwnProperty.call(object, key) ||\n (typeof object == 'object' && key in object && getPrototype(object) === null);\n}\n\n/**\n * The base implementation of `_.keys` which doesn't skip the constructor\n * property of prototypes or treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n return nativeKeys(Object(object));\n}\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Gets the `[[Prototype]]` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {null|Object} Returns the `[[Prototype]]`.\n */\nfunction getPrototype(value) {\n return nativeGetPrototype(Object(value));\n}\n\n/**\n * Creates an array of index keys for `object` values of arrays,\n * `arguments` objects, and strings, otherwise `null` is returned.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array|null} Returns index keys, else `null`.\n */\nfunction indexKeys(object) {\n var length = object ? object.length : undefined;\n if (isLength(length) &&\n (isArray(object) || isString(object) || isArguments(object))) {\n return baseTimes(length, String);\n }\n return null;\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @type {Function}\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n var isProto = isPrototype(object);\n if (!(isProto || isArrayLike(object))) {\n return baseKeys(object);\n }\n var indexes = indexKeys(object),\n skipIndexes = !!indexes,\n result = indexes || [],\n length = result.length;\n\n for (var key in object) {\n if (baseHas(object, key) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n !(isProto && key == 'constructor')) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = keys;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.keys/index.js\n ** module id = 4\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308,\n NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n var length = args.length;\n switch (length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\nfunction rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n switch (start) {\n case 0: return func.call(this, array);\n case 1: return func.call(this, args[0], array);\n case 2: return func.call(this, args[0], args[1], array);\n }\n var otherArgs = Array(start + 1);\n index = -1;\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = array;\n return apply(func, this, otherArgs);\n };\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This function is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = isFunction(value.valueOf) ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = rest;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.rest/index.js\n ** module id = 5\n ** module chunks = 0\n **/","import {latLon as LatLon} from './LatLon';\nimport {point as Point} from './Point';\n\nvar Geo = {};\n\n// Radius / WGS84 semi-major axis\nGeo.R = 6378137;\nGeo.MAX_LATITUDE = 85.0511287798;\n\n// WGS84 eccentricity\nGeo.ECC = 0.081819191;\nGeo.ECC2 = 0.081819191 * 0.081819191;\n\nGeo.project = function(latlon) {\n var d = Math.PI / 180;\n var max = Geo.MAX_LATITUDE;\n var lat = Math.max(Math.min(max, latlon.lat), -max);\n var sin = Math.sin(lat * d);\n\n return Point(\n Geo.R * latlon.lon * d,\n Geo.R * Math.log((1 + sin) / (1 - sin)) / 2\n );\n},\n\nGeo.unproject = function(point) {\n var d = 180 / Math.PI;\n\n return LatLon(\n (2 * Math.atan(Math.exp(point.y / Geo.R)) - (Math.PI / 2)) * d,\n point.x * d / Geo.R\n );\n};\n\n// Converts geo coords to pixel / WebGL ones\n// This just reverses the Y axis to match WebGL\nGeo.latLonToPoint = function(latlon) {\n var projected = Geo.project(latlon);\n projected.y *= -1;\n\n return projected;\n};\n\n// Converts pixel / WebGL coords to geo coords\n// This just reverses the Y axis to match WebGL\nGeo.pointToLatLon = function(point) {\n var _point = Point(point.x, point.y * -1);\n return Geo.unproject(_point);\n};\n\n// Scale factor for converting between real metres and projected metres\n//\n// projectedMetres = realMetres * pointScale\n// realMetres = projectedMetres / pointScale\n//\n// Accurate scale factor uses proper Web Mercator scaling\n// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf\n// See: http://jsfiddle.net/robhawkes/yws924cf/\nGeo.pointScale = function(latlon, accurate) {\n var rad = Math.PI / 180;\n\n var k;\n\n if (!accurate) {\n k = 1 / Math.cos(latlon.lat * rad);\n\n // [scaleX, scaleY]\n return [k, k];\n } else {\n var lat = latlon.lat * rad;\n var lon = latlon.lon * rad;\n\n var a = Geo.R;\n\n var sinLat = Math.sin(lat);\n var sinLat2 = sinLat * sinLat;\n\n var cosLat = Math.cos(lat);\n\n // Radius meridian\n var p = a * (1 - Geo.ECC2) / Math.pow(1 - Geo.ECC2 * sinLat2, 3 / 2);\n\n // Radius prime meridian\n var v = a / Math.sqrt(1 - Geo.ECC2 * sinLat2);\n\n // Scale N/S\n var h = (a / p) / cosLat;\n\n // Scale E/W\n k = (a / v) / cosLat;\n\n // [scaleX, scaleY]\n return [k, h];\n }\n};\n\n// Convert real metres to projected units\n//\n// Latitude scale is chosen because it fluctuates more than longitude\nGeo.metresToProjected = function(metres, pointScale) {\n return metres * pointScale[1];\n};\n\n// Convert projected units to real metres\n//\n// Latitude scale is chosen because it fluctuates more than longitude\nGeo.projectedToMetres = function(projectedUnits, pointScale) {\n return projectedUnits / pointScale[1];\n};\n\n// Convert real metres to a value in world (WebGL) units\nGeo.metresToWorld = function(metres, pointScale) {\n // Transform metres to projected metres using the latitude point scale\n //\n // Latitude scale is chosen because it fluctuates more than longitude\n var projectedMetres = Geo.metresToProjected(metres, pointScale);\n\n var scale = Geo.scale();\n\n // Scale projected metres\n var scaledMetres = (scale * projectedMetres);\n\n return scaledMetres;\n};\n\n// Convert world (WebGL) units to a value in real metres\nGeo.worldToMetres = function(worldUnits, pointScale) {\n var scale = Geo.scale();\n\n var projectedUnits = worldUnits / scale;\n var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);\n\n return realMetres;\n};\n\n// If zoom is provided, returns the map width in pixels for a given zoom\n// Else, provides fixed scale value\nGeo.scale = function(zoom) {\n // If zoom is provided then return scale based on map tile zoom\n if (zoom >= 0) {\n return 256 * Math.pow(2, zoom);\n // Else, return fixed scale value to expand projected coordinates from\n // their 0 to 1 range into something more practical\n } else {\n return 1;\n }\n};\n\n// Returns zoom level for a given scale value\n// This only works with a scale value that is based on map pixel width\nGeo.zoom = function(scale) {\n return Math.log(scale / 256) / Math.LN2;\n};\n\n// Distance between two geographical points using spherical law of cosines\n// approximation or Haversine\n//\n// See: http://www.movable-type.co.uk/scripts/latlong.html\nGeo.distance = function(latlon1, latlon2, accurate) {\n var rad = Math.PI / 180;\n\n var lat1;\n var lat2;\n\n var a;\n\n if (!accurate) {\n lat1 = latlon1.lat * rad;\n lat2 = latlon2.lat * rad;\n\n a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);\n\n return Geo.R * Math.acos(Math.min(a, 1));\n } else {\n lat1 = latlon1.lat * rad;\n lat2 = latlon2.lat * rad;\n\n var lon1 = latlon1.lon * rad;\n var lon2 = latlon2.lon * rad;\n\n var deltaLat = lat2 - lat1;\n var deltaLon = lon2 - lon1;\n\n var halfDeltaLat = deltaLat / 2;\n var halfDeltaLon = deltaLon / 2;\n\n a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);\n\n var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n return Geo.R * c;\n }\n};\n\nGeo.bounds = (function() {\n var d = Geo.R * Math.PI;\n return [[-d, -d], [d, d]];\n})();\n\nexport default Geo;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/Geo.js\n **/","/*\n * LatLon is a helper class for ensuring consistent geographic coordinates.\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js\n */\n\nclass LatLon {\n constructor(lat, lon, alt) {\n if (isNaN(lat) || isNaN(lon)) {\n throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');\n }\n\n this.lat = +lat;\n this.lon = +lon;\n\n if (alt !== undefined) {\n this.alt = +alt;\n }\n }\n\n clone() {\n return new LatLon(this.lat, this.lon, this.alt);\n }\n}\n\nexport default LatLon;\n\n// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)\n// Also converts between lng and lon\nvar noNew = function(a, b, c) {\n if (a instanceof LatLon) {\n return a;\n }\n if (Array.isArray(a) && typeof a[0] !== 'object') {\n if (a.length === 3) {\n return new LatLon(a[0], a[1], a[2]);\n }\n if (a.length === 2) {\n return new LatLon(a[0], a[1]);\n }\n return null;\n }\n if (a === undefined || a === null) {\n return a;\n }\n if (typeof a === 'object' && 'lat' in a) {\n return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\n }\n if (b === undefined) {\n return null;\n }\n return new LatLon(a, b, c);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as latLon};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/LatLon.js\n **/","/*\n * Point is a helper class for ensuring consistent world positions.\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js\n */\n\nclass Point {\n constructor(x, y, round) {\n this.x = (round ? Math.round(x) : x);\n this.y = (round ? Math.round(y) : y);\n }\n\n clone() {\n return new Point(this.x, this.y);\n }\n\n // Non-destructive\n add(point) {\n return this.clone()._add(_point(point));\n }\n\n // Destructive\n _add(point) {\n this.x += point.x;\n this.y += point.y;\n return this;\n }\n\n // Non-destructive\n subtract(point) {\n return this.clone()._subtract(_point(point));\n }\n\n // Destructive\n _subtract(point) {\n this.x -= point.x;\n this.y -= point.y;\n return this;\n }\n}\n\nexport default Point;\n\n// Accepts (point), ([x, y]) and (x, y, round)\nvar _point = function(x, y, round) {\n if (x instanceof Point) {\n return x;\n }\n if (Array.isArray(x)) {\n return new Point(x[0], x[1]);\n }\n if (x === undefined || x === null) {\n return x;\n }\n return new Point(x, y, round);\n};\n\n// Initialise without requiring new keyword\nexport {_point as point};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/Point.js\n **/","import EventEmitter from 'eventemitter3';\nimport THREE from 'three';\nimport Scene from './Scene';\nimport DOMScene3D from './DOMScene3D';\nimport DOMScene2D from './DOMScene2D';\nimport Renderer from './Renderer';\nimport DOMRenderer3D from './DOMRenderer3D';\nimport DOMRenderer2D from './DOMRenderer2D';\nimport Camera from './Camera';\nimport Picking from './Picking';\nimport EffectComposer from './EffectComposer';\nimport RenderPass from '../vendor/RenderPass';\nimport ShaderPass from '../vendor/ShaderPass';\nimport CopyShader from '../vendor/CopyShader';\nimport HorizontalTiltShiftShader from '../vendor/HorizontalTiltShiftShader';\nimport VerticalTiltShiftShader from '../vendor/VerticalTiltShiftShader';\nimport FXAAShader from '../vendor/FXAAShader';\n\nclass Engine extends EventEmitter {\n constructor(container, world) {\n console.log('Init Engine');\n\n super();\n\n this._world = world;\n\n this._scene = Scene;\n this._domScene3D = DOMScene3D;\n this._domScene2D = DOMScene2D;\n\n var antialias = (this._world.options.postProcessing) ? false : true;\n this._renderer = Renderer(container, antialias);\n this._domRenderer3D = DOMRenderer3D(container);\n this._domRenderer2D = DOMRenderer2D(container);\n\n this._camera = Camera(container);\n\n this._container = container;\n\n // TODO: Make this optional\n this._picking = Picking(this._world, this._renderer, this._camera);\n\n this.clock = new THREE.Clock();\n\n this._frustum = new THREE.Frustum();\n\n if (this._world.options.postProcessing) {\n this._initPostProcessing();\n }\n }\n\n // TODO: Set up composer to automatically resize on viewport change\n // TODO: Update passes that rely on width / height on resize\n // TODO: Merge default passes into a single shader / pass for performance\n _initPostProcessing() {\n var renderPass = new RenderPass(this._scene, this._camera);\n\n // TODO: Look at using @mattdesl's optimised FXAA shader\n // https://github.com/mattdesl/three-shader-fxaa\n var fxaaPass = new ShaderPass(FXAAShader);\n\n var hblurPass = new ShaderPass(HorizontalTiltShiftShader);\n var vblurPass = new ShaderPass(VerticalTiltShiftShader);\n var bluriness = 5;\n\n hblurPass.uniforms.r.value = vblurPass.uniforms.r.value = 0.6;\n\n var copyPass = new ShaderPass(CopyShader);\n copyPass.renderToScreen = true;\n\n this._composer = EffectComposer(this._renderer, this._container);\n\n this._composer.addPass(renderPass);\n this._composer.addPass(fxaaPass);\n this._composer.addPass(hblurPass);\n this._composer.addPass(vblurPass);\n this._composer.addPass(copyPass);\n\n var self = this;\n var updatePostProcessingSize = function() {\n var width = self._container.clientWidth;\n var height = self._container.clientHeight;\n\n // TODO: Re-enable this when perf issues can be solved\n //\n // Rendering double the resolution of the screen can be really slow\n // var pixelRatio = window.devicePixelRatio;\n var pixelRatio = 1;\n\n fxaaPass.uniforms.resolution.value.set(1 / (width * pixelRatio), 1 / (height * pixelRatio));\n\n hblurPass.uniforms.h.value = bluriness / (width * pixelRatio);\n vblurPass.uniforms.v.value = bluriness / (height * pixelRatio);\n };\n\n updatePostProcessingSize();\n window.addEventListener('resize', updatePostProcessingSize, false);\n }\n\n update(delta) {\n this.emit('preRender');\n\n if (this._world.options.postProcessing) {\n this._composer.render(delta);\n } else {\n this._renderer.render(this._scene, this._camera);\n }\n\n // Render picking scene\n // this._renderer.render(this._picking._pickingScene, this._camera);\n\n // Render DOM scenes\n this._domRenderer3D.render(this._domScene3D, this._camera);\n this._domRenderer2D.render(this._domScene2D, this._camera);\n\n this.emit('postRender');\n }\n\n destroy() {\n // Remove any remaining objects from scene\n var child;\n for (var i = this._scene.children.length - 1; i >= 0; i--) {\n child = this._scene.children[i];\n\n if (!child) {\n continue;\n }\n\n this._scene.remove(child);\n\n if (child.geometry) {\n // Dispose of mesh and materials\n child.geometry.dispose();\n child.geometry = null;\n }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n };\n\n for (var i = this._domScene3D.children.length - 1; i >= 0; i--) {\n child = this._domScene3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this._domScene3D.remove(child);\n };\n\n for (var i = this._domScene2D.children.length - 1; i >= 0; i--) {\n child = this._domScene2D.children[i];\n\n if (!child) {\n continue;\n }\n\n this._domScene2D.remove(child);\n };\n\n this._picking.destroy();\n this._picking = null;\n\n this._world = null;\n this._scene = null;\n this._domScene3D = null;\n this._domScene2D = null;\n\n this._composer = null;\n this._renderer = null;\n\n this._domRenderer3D = null;\n this._domRenderer2D = null;\n this._camera = null;\n this._clock = null;\n this._frustum = null;\n }\n}\n\nexport default Engine;\n\n// // Initialise without requiring new keyword\n// export default function(container, world) {\n// return new Engine(container, world);\n// };\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Engine.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_10__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"THREE\"\n ** module id = 10\n ** module chunks = 0\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n\n // TODO: Re-enable when this works with the skybox\n // scene.fog = new THREE.Fog(0xffffff, 1, 15000);\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Scene.js\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMScene3D.js\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMScene2D.js\n **/","import THREE from 'three';\nimport Scene from './Scene';\n\n// This can only be accessed from Engine.renderer if you want to reference the\n// same scene in multiple places\n\nexport default function(container, antialias) {\n var renderer = new THREE.WebGLRenderer({\n antialias: antialias\n });\n\n // TODO: Re-enable when this works with the skybox\n // renderer.setClearColor(Scene.fog.color, 1);\n\n renderer.setClearColor(0xffffff, 1);\n\n // TODO: Re-enable this when perf issues can be solved\n //\n // Rendering double the resolution of the screen can be really slow\n // var pixelRatio = window.devicePixelRatio;\n var pixelRatio = 1;\n\n renderer.setPixelRatio(pixelRatio);\n\n // Gamma settings make things look nicer\n renderer.gammaInput = true;\n renderer.gammaOutput = true;\n\n renderer.shadowMap.enabled = true;\n\n // TODO: Work out which of the shadowmap types is best\n // https://github.com/mrdoob/three.js/blob/r56/src/Three.js#L107\n // renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n\n // TODO: Check that leaving this as default (CullFrontFace) is right\n // renderer.shadowMap.cullFace = THREE.CullFaceBack;\n\n container.appendChild(renderer.domElement);\n\n var updateSize = function() {\n renderer.setSize(container.clientWidth, container.clientHeight);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return renderer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Renderer.js\n **/","import THREE from 'three';\nimport {CSS3DRenderer} from '../vendor/CSS3DRenderer';\nimport DOMScene3D from './DOMScene3D';\n\n// This can only be accessed from Engine.renderer if you want to reference the\n// same scene in multiple places\n\nexport default function(container) {\n var renderer = new CSS3DRenderer();\n\n renderer.domElement.style.position = 'absolute';\n renderer.domElement.style.top = 0;\n\n container.appendChild(renderer.domElement);\n\n var updateSize = function() {\n renderer.setSize(container.clientWidth, container.clientHeight);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return renderer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMRenderer3D.js\n **/","// jscs:disable\n/* eslint-disable */\n\n/**\n * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs\n * @author mrdoob / http://mrdoob.com/\n */\n\nimport THREE from 'three';\n\nvar CSS3DObject = function ( element ) {\n\n\tTHREE.Object3D.call( this );\n\n\tthis.element = element;\n\tthis.element.style.position = 'absolute';\n\n\tthis.addEventListener( 'removed', function ( event ) {\n\n\t\tif ( this.element.parentNode !== null ) {\n\n\t\t\tthis.element.parentNode.removeChild( this.element );\n\n\t\t}\n\n\t} );\n\n};\n\nCSS3DObject.prototype = Object.create( THREE.Object3D.prototype );\nCSS3DObject.prototype.constructor = CSS3DObject;\n\nvar CSS3DSprite = function ( element ) {\n\n\tCSS3DObject.call( this, element );\n\n};\n\nCSS3DSprite.prototype = Object.create( CSS3DObject.prototype );\nCSS3DSprite.prototype.constructor = CSS3DSprite;\n\n//\n\nvar CSS3DRenderer = function () {\n\n\tconsole.log( 'THREE.CSS3DRenderer', THREE.REVISION );\n\n\tvar _width, _height;\n\tvar _widthHalf, _heightHalf;\n\n\tvar matrix = new THREE.Matrix4();\n\n\tvar cache = {\n\t\tcamera: { fov: 0, style: '' },\n\t\tobjects: {}\n\t};\n\n\tvar domElement = document.createElement( 'div' );\n\tdomElement.style.overflow = 'hidden';\n\n\tdomElement.style.WebkitTransformStyle = 'preserve-3d';\n\tdomElement.style.MozTransformStyle = 'preserve-3d';\n\tdomElement.style.oTransformStyle = 'preserve-3d';\n\tdomElement.style.transformStyle = 'preserve-3d';\n\n\tthis.domElement = domElement;\n\n\tvar cameraElement = document.createElement( 'div' );\n\n\tcameraElement.style.WebkitTransformStyle = 'preserve-3d';\n\tcameraElement.style.MozTransformStyle = 'preserve-3d';\n\tcameraElement.style.oTransformStyle = 'preserve-3d';\n\tcameraElement.style.transformStyle = 'preserve-3d';\n\n\tdomElement.appendChild( cameraElement );\n\n\tthis.setClearColor = function () {};\n\n\tthis.getSize = function() {\n\n\t\treturn {\n\t\t\twidth: _width,\n\t\t\theight: _height\n\t\t};\n\n\t};\n\n\tthis.setSize = function ( width, height ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_widthHalf = _width / 2;\n\t\t_heightHalf = _height / 2;\n\n\t\tdomElement.style.width = width + 'px';\n\t\tdomElement.style.height = height + 'px';\n\n\t\tcameraElement.style.width = width + 'px';\n\t\tcameraElement.style.height = height + 'px';\n\n\t};\n\n\tvar epsilon = function ( value ) {\n\n\t\treturn Math.abs( value ) < Number.EPSILON ? 0 : value;\n\n\t};\n\n\tvar getCameraCSSMatrix = function ( matrix ) {\n\n\t\tvar elements = matrix.elements;\n\n\t\treturn 'matrix3d(' +\n\t\t\tepsilon( elements[ 0 ] ) + ',' +\n\t\t\tepsilon( - elements[ 1 ] ) + ',' +\n\t\t\tepsilon( elements[ 2 ] ) + ',' +\n\t\t\tepsilon( elements[ 3 ] ) + ',' +\n\t\t\tepsilon( elements[ 4 ] ) + ',' +\n\t\t\tepsilon( - elements[ 5 ] ) + ',' +\n\t\t\tepsilon( elements[ 6 ] ) + ',' +\n\t\t\tepsilon( elements[ 7 ] ) + ',' +\n\t\t\tepsilon( elements[ 8 ] ) + ',' +\n\t\t\tepsilon( - elements[ 9 ] ) + ',' +\n\t\t\tepsilon( elements[ 10 ] ) + ',' +\n\t\t\tepsilon( elements[ 11 ] ) + ',' +\n\t\t\tepsilon( elements[ 12 ] ) + ',' +\n\t\t\tepsilon( - elements[ 13 ] ) + ',' +\n\t\t\tepsilon( elements[ 14 ] ) + ',' +\n\t\t\tepsilon( elements[ 15 ] ) +\n\t\t')';\n\n\t};\n\n\tvar getObjectCSSMatrix = function ( matrix ) {\n\n\t\tvar elements = matrix.elements;\n\n\t\treturn 'translate3d(-50%,-50%,0) matrix3d(' +\n\t\t\tepsilon( elements[ 0 ] ) + ',' +\n\t\t\tepsilon( elements[ 1 ] ) + ',' +\n\t\t\tepsilon( elements[ 2 ] ) + ',' +\n\t\t\tepsilon( elements[ 3 ] ) + ',' +\n\t\t\tepsilon( - elements[ 4 ] ) + ',' +\n\t\t\tepsilon( - elements[ 5 ] ) + ',' +\n\t\t\tepsilon( - elements[ 6 ] ) + ',' +\n\t\t\tepsilon( - elements[ 7 ] ) + ',' +\n\t\t\tepsilon( elements[ 8 ] ) + ',' +\n\t\t\tepsilon( elements[ 9 ] ) + ',' +\n\t\t\tepsilon( elements[ 10 ] ) + ',' +\n\t\t\tepsilon( elements[ 11 ] ) + ',' +\n\t\t\tepsilon( elements[ 12 ] ) + ',' +\n\t\t\tepsilon( elements[ 13 ] ) + ',' +\n\t\t\tepsilon( elements[ 14 ] ) + ',' +\n\t\t\tepsilon( elements[ 15 ] ) +\n\t\t')';\n\n\t};\n\n\tvar renderObject = function ( object, camera ) {\n\n\t\tif ( object instanceof CSS3DObject ) {\n\n\t\t\tvar style;\n\n\t\t\tif ( object instanceof CSS3DSprite ) {\n\n\t\t\t\t// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/\n\n\t\t\t\tmatrix.copy( camera.matrixWorldInverse );\n\t\t\t\tmatrix.transpose();\n\t\t\t\tmatrix.copyPosition( object.matrixWorld );\n\t\t\t\tmatrix.scale( object.scale );\n\n\t\t\t\tmatrix.elements[ 3 ] = 0;\n\t\t\t\tmatrix.elements[ 7 ] = 0;\n\t\t\t\tmatrix.elements[ 11 ] = 0;\n\t\t\t\tmatrix.elements[ 15 ] = 1;\n\n\t\t\t\tstyle = getObjectCSSMatrix( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tstyle = getObjectCSSMatrix( object.matrixWorld );\n\n\t\t\t}\n\n\t\t\tvar element = object.element;\n\t\t\tvar cachedStyle = cache.objects[ object.id ];\n\n\t\t\tif ( cachedStyle === undefined || cachedStyle !== style ) {\n\n\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\telement.style.MozTransform = style;\n\t\t\t\telement.style.oTransform = style;\n\t\t\t\telement.style.transform = style;\n\n\t\t\t\tcache.objects[ object.id ] = style;\n\n\t\t\t}\n\n\t\t\tif ( element.parentNode !== cameraElement ) {\n\n\t\t\t\tcameraElement.appendChild( element );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( var i = 0, l = object.children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( object.children[ i ], camera );\n\n\t\t}\n\n\t};\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tvar fov = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * _height;\n\n\t\tif ( cache.camera.fov !== fov ) {\n\n\t\t\tdomElement.style.WebkitPerspective = fov + 'px';\n\t\t\tdomElement.style.MozPerspective = fov + 'px';\n\t\t\tdomElement.style.oPerspective = fov + 'px';\n\t\t\tdomElement.style.perspective = fov + 'px';\n\n\t\t\tcache.camera.fov = fov;\n\n\t\t}\n\n\t\tscene.updateMatrixWorld();\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\tvar style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) +\n\t\t\t' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)';\n\n\t\tif ( cache.camera.style !== style ) {\n\n\t\t\tcameraElement.style.WebkitTransform = style;\n\t\t\tcameraElement.style.MozTransform = style;\n\t\t\tcameraElement.style.oTransform = style;\n\t\t\tcameraElement.style.transform = style;\n\n\t\t\tcache.camera.style = style;\n\n\t\t}\n\n\t\trenderObject( scene, camera );\n\n\t};\n\n};\n\nexport {CSS3DObject as CSS3DObject};\nexport {CSS3DSprite as CSS3DSprite};\nexport {CSS3DRenderer as CSS3DRenderer};\n\nTHREE.CSS3DObject = CSS3DObject;\nTHREE.CSS3DSprite = CSS3DSprite;\nTHREE.CSS3DRenderer = CSS3DRenderer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CSS3DRenderer.js\n **/","import THREE from 'three';\nimport {CSS2DRenderer} from '../vendor/CSS2DRenderer';\nimport DOMScene2D from './DOMScene2D';\n\n// This can only be accessed from Engine.renderer if you want to reference the\n// same scene in multiple places\n\nexport default function(container) {\n var renderer = new CSS2DRenderer();\n\n renderer.domElement.style.position = 'absolute';\n renderer.domElement.style.top = 0;\n\n container.appendChild(renderer.domElement);\n\n var updateSize = function() {\n renderer.setSize(container.clientWidth, container.clientHeight);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return renderer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMRenderer2D.js\n **/","// jscs:disable\n/* eslint-disable */\n\n/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nimport THREE from 'three';\n\nvar CSS2DObject = function ( element ) {\n\n\tTHREE.Object3D.call( this );\n\n\tthis.element = element;\n\tthis.element.style.position = 'absolute';\n\n\tthis.addEventListener( 'removed', function ( event ) {\n\n\t\tif ( this.element.parentNode !== null ) {\n\n\t\t\tthis.element.parentNode.removeChild( this.element );\n\n\t\t}\n\n\t} );\n\n};\n\nCSS2DObject.prototype = Object.create( THREE.Object3D.prototype );\nCSS2DObject.prototype.constructor = CSS2DObject;\n\n//\n\nvar CSS2DRenderer = function () {\n\n\tconsole.log( 'THREE.CSS2DRenderer', THREE.REVISION );\n\n\tvar _width, _height;\n\tvar _widthHalf, _heightHalf;\n\n\tvar vector = new THREE.Vector3();\n\tvar viewMatrix = new THREE.Matrix4();\n\tvar viewProjectionMatrix = new THREE.Matrix4();\n\n\tvar frustum = new THREE.Frustum();\n\n\tvar domElement = document.createElement( 'div' );\n\tdomElement.style.overflow = 'hidden';\n\n\tthis.domElement = domElement;\n\n\tthis.setSize = function ( width, height ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_widthHalf = _width / 2;\n\t\t_heightHalf = _height / 2;\n\n\t\tdomElement.style.width = width + 'px';\n\t\tdomElement.style.height = height + 'px';\n\n\t};\n\n\tvar renderObject = function ( object, camera ) {\n\n\t\tif ( object instanceof CSS2DObject ) {\n\n\t\t\tvector.setFromMatrixPosition( object.matrixWorld );\n\t\t\tvector.applyProjection( viewProjectionMatrix );\n\n\t\t\tvar element = object.element;\n\t\t\tvar style = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';\n\n\t\t\telement.style.WebkitTransform = style;\n\t\t\telement.style.MozTransform = style;\n\t\t\telement.style.oTransform = style;\n\t\t\telement.style.transform = style;\n\n\t\t\tif ( element.parentNode !== domElement ) {\n\n\t\t\t\tdomElement.appendChild( element );\n\n\t\t\t}\n\n\t\t\t// Hide if outside view frustum\n\t\t\tif (!frustum.containsPoint(object.position)) {\n\t\t\t\telement.style.display = 'none';\n\t\t\t} else {\n\t\t\t\telement.style.display = 'block';\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( var i = 0, l = object.children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( object.children[ i ], camera );\n\n\t\t}\n\n\t};\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tscene.updateMatrixWorld();\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\tviewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );\n\t\tviewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );\n\n\t\tfrustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );\n\n\t\trenderObject( scene, camera );\n\n\t};\n\n};\n\nexport {CSS2DObject as CSS2DObject};\nexport {CSS2DRenderer as CSS2DRenderer};\n\nTHREE.CSS2DObject = CSS2DObject;\nTHREE.CSS2DRenderer = CSS2DRenderer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CSS2DRenderer.js\n **/","import THREE from 'three';\n\n// This can only be accessed from Engine.camera if you want to reference the\n// same scene in multiple places\n\n// TODO: Ensure that FOV looks natural on all aspect ratios\n// http://stackoverflow.com/q/26655930/997339\n\nexport default function(container) {\n var camera = new THREE.PerspectiveCamera(45, 1, 1, 2000000);\n camera.position.y = 4000;\n camera.position.z = 4000;\n\n var updateSize = function() {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return camera;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Camera.js\n **/","import THREE from 'three';\nimport {point as Point} from '../geo/Point';\nimport PickingScene from './PickingScene';\n\n// TODO: Look into a way of setting this up without passing in a renderer and\n// camera from the engine\n\n// TODO: Add a basic indicator on or around the mouse pointer when it is over\n// something pickable / clickable\n//\n// A simple transparent disc or ring at the mouse point should work to start, or\n// even just changing the cursor to the CSS 'pointer' style\n//\n// Probably want this on mousemove with a throttled update as not to spam the\n// picking method\n//\n// Relies upon the picking method not redrawing the scene every call due to\n// the way TileLayer invalidates the picking scene\n\nvar nextId = 1;\n\nclass Picking {\n constructor(world, renderer, camera) {\n this._world = world;\n this._renderer = renderer;\n this._camera = camera;\n\n this._raycaster = new THREE.Raycaster();\n\n // TODO: Match this with the line width used in the picking layers\n this._raycaster.linePrecision = 3;\n\n this._pickingScene = PickingScene;\n this._pickingTexture = new THREE.WebGLRenderTarget();\n this._pickingTexture.texture.minFilter = THREE.LinearFilter;\n this._pickingTexture.texture.generateMipmaps = false;\n\n this._nextId = 1;\n\n this._resizeTexture();\n this._initEvents();\n }\n\n _initEvents() {\n this._resizeHandler = this._resizeTexture.bind(this);\n window.addEventListener('resize', this._resizeHandler, false);\n\n this._mouseUpHandler = this._onMouseUp.bind(this);\n this._world._container.addEventListener('mouseup', this._mouseUpHandler, false);\n\n this._world.on('move', this._onWorldMove, this);\n }\n\n _onMouseUp(event) {\n // Only react to main button click\n if (event.button !== 0) {\n return;\n }\n\n var point = Point(event.clientX, event.clientY);\n\n var normalisedPoint = Point(0, 0);\n normalisedPoint.x = (point.x / this._width) * 2 - 1;\n normalisedPoint.y = -(point.y / this._height) * 2 + 1;\n\n this._pick(point, normalisedPoint);\n }\n\n _onWorldMove() {\n this._needUpdate = true;\n }\n\n // TODO: Ensure this doesn't get out of sync issue with the renderer resize\n _resizeTexture() {\n var size = this._renderer.getSize();\n\n this._width = size.width;\n this._height = size.height;\n\n this._pickingTexture.setSize(this._width, this._height);\n this._pixelBuffer = new Uint8Array(4 * this._width * this._height);\n\n this._needUpdate = true;\n }\n\n // TODO: Make this only re-draw the scene if both an update is needed and the\n // camera has moved since the last update\n //\n // Otherwise it re-draws the scene on every click due to the way LOD updates\n // work in TileLayer – spamming this.add() and this.remove()\n //\n // TODO: Pause updates during map move / orbit / zoom as this is unlikely to\n // be a point in time where the user cares for picking functionality\n _update() {\n if (this._needUpdate) {\n var texture = this._pickingTexture;\n\n this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);\n\n // Read the rendering texture\n this._renderer.readRenderTargetPixels(texture, 0, 0, texture.width, texture.height, this._pixelBuffer);\n\n this._needUpdate = false;\n }\n }\n\n _pick(point, normalisedPoint) {\n this._update();\n\n var index = point.x + (this._pickingTexture.height - point.y) * this._pickingTexture.width;\n\n // Interpret the pixel as an ID\n var id = (this._pixelBuffer[index * 4 + 2] * 255 * 255) + (this._pixelBuffer[index * 4 + 1] * 255) + (this._pixelBuffer[index * 4 + 0]);\n\n // Skip if ID is 16646655 (white) as the background returns this\n if (id === 16646655) {\n return;\n }\n\n this._raycaster.setFromCamera(normalisedPoint, this._camera);\n\n // Perform ray intersection on picking scene\n //\n // TODO: Only perform intersection test on the relevant picking mesh\n var intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);\n\n var _point2d = point.clone();\n\n var _point3d;\n if (intersects.length > 0) {\n _point3d = intersects[0].point.clone();\n }\n\n // Pass along as much data as possible for now until we know more about how\n // people use the picking API and what the returned data should be\n //\n // TODO: Look into the leak potential for passing so much by reference here\n this._world.emit('pick', id, _point2d, _point3d, intersects);\n this._world.emit('pick-' + id, _point2d, _point3d, intersects);\n }\n\n // Add mesh to picking scene\n //\n // Picking ID should already be added as an attribute\n add(mesh) {\n this._pickingScene.add(mesh);\n this._needUpdate = true;\n }\n\n // Remove mesh from picking scene\n remove(mesh) {\n this._pickingScene.remove(mesh);\n this._needUpdate = true;\n }\n\n // Returns next ID to use for picking\n getNextId() {\n return nextId++;\n }\n\n destroy() {\n // TODO: Find a way to properly remove these listeners as they stay\n // active at the moment\n window.removeEventListener('resize', this._resizeHandler, false);\n this._world._container.removeEventListener('mouseup', this._mouseUpHandler, false);\n\n this._world.off('move', this._onWorldMove);\n\n if (this._pickingScene.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._pickingScene.children.length - 1; i >= 0; i--) {\n child = this._pickingScene.children[i];\n\n if (!child) {\n continue;\n }\n\n this._pickingScene.remove(child);\n\n // Probably not a good idea to dispose of geometry due to it being\n // shared with the non-picking scene\n // if (child.geometry) {\n // // Dispose of mesh and materials\n // child.geometry.dispose();\n // child.geometry = null;\n // }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n }\n }\n\n this._pickingScene = null;\n this._pickingTexture = null;\n this._pixelBuffer = null;\n\n this._world = null;\n this._renderer = null;\n this._camera = null;\n }\n}\n\n// Initialise without requiring new keyword\nexport default function(world, renderer, camera) {\n return new Picking(world, renderer, camera);\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Picking.js\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.pickingScene\n\nexport default (function() {\n var scene = new THREE.Scene();\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingScene.js\n **/","import THREE from 'three';\nimport EffectComposer from '../vendor/EffectComposer';\n\nexport default function(renderer, container) {\n var composer = new EffectComposer(renderer);\n\n var updateSize = function() {\n // TODO: Re-enable this when perf issues can be solved\n //\n // Rendering double the resolution of the screen can be really slow\n // var pixelRatio = window.devicePixelRatio;\n var pixelRatio = 1;\n\n composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return composer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/EffectComposer.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\nimport CopyShader from './CopyShader';\nimport ShaderPass from './ShaderPass';\nimport MaskPass, {ClearMaskPass} from './MaskPass';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar EffectComposer = function ( renderer, renderTarget ) {\n\n\tthis.renderer = renderer;\n\n\tif ( renderTarget === undefined ) {\n\n\t\tvar pixelRatio = renderer.getPixelRatio();\n\n\t\tvar width = Math.floor( renderer.context.canvas.width / pixelRatio ) || 1;\n\t\tvar height = Math.floor( renderer.context.canvas.height / pixelRatio ) || 1;\n\t\tvar parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };\n\n\t\trenderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n\n\t}\n\n\tthis.renderTarget1 = renderTarget;\n\tthis.renderTarget2 = renderTarget.clone();\n\n\tthis.writeBuffer = this.renderTarget1;\n\tthis.readBuffer = this.renderTarget2;\n\n\tthis.passes = [];\n\n\tif ( CopyShader === undefined )\n\t\tconsole.error( \"EffectComposer relies on THREE.CopyShader\" );\n\n\tthis.copyPass = new ShaderPass( CopyShader );\n\n};\n\nEffectComposer.prototype = {\n\n\tswapBuffers: function() {\n\n\t\tvar tmp = this.readBuffer;\n\t\tthis.readBuffer = this.writeBuffer;\n\t\tthis.writeBuffer = tmp;\n\n\t},\n\n\taddPass: function ( pass ) {\n\n\t\tthis.passes.push( pass );\n\n\t},\n\n\tinsertPass: function ( pass, index ) {\n\n\t\tthis.passes.splice( index, 0, pass );\n\n\t},\n\n\trender: function ( delta ) {\n\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\n\t\tvar maskActive = false;\n\n\t\tvar pass, i, il = this.passes.length;\n\n\t\tfor ( i = 0; i < il; i ++ ) {\n\n\t\t\tpass = this.passes[ i ];\n\n\t\t\tif ( ! pass.enabled ) continue;\n\n\t\t\tpass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n\t\t\tif ( pass.needsSwap ) {\n\n\t\t\t\tif ( maskActive ) {\n\n\t\t\t\t\tvar context = this.renderer.context;\n\n\t\t\t\t\tcontext.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n\t\t\t\t\tthis.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n\t\t\t\t\tcontext.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n\t\t\t\t}\n\n\t\t\t\tthis.swapBuffers();\n\n\t\t\t}\n\n\t\t\tif ( pass instanceof MaskPass ) {\n\n\t\t\t\tmaskActive = true;\n\n\t\t\t} else if ( pass instanceof ClearMaskPass ) {\n\n\t\t\t\tmaskActive = false;\n\n\t\t\t}\n\n\t\t}\n\n\t},\n\n\treset: function ( renderTarget ) {\n\n\t\tif ( renderTarget === undefined ) {\n\n\t\t\trenderTarget = this.renderTarget1.clone();\n\n\t\t\tvar pixelRatio = this.renderer.getPixelRatio();\n\n\t\t\trenderTarget.setSize(\n\t\t\t\tMath.floor( this.renderer.context.canvas.width / pixelRatio ),\n\t\t\t\tMath.floor( this.renderer.context.canvas.height / pixelRatio )\n\t\t\t);\n\n\t\t}\n\n\t\tthis.renderTarget1.dispose();\n\t\tthis.renderTarget1 = renderTarget;\n\t\tthis.renderTarget2.dispose();\n\t\tthis.renderTarget2 = renderTarget.clone();\n\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\n\t},\n\n\tsetSize: function ( width, height ) {\n\n\t\tthis.renderTarget1.setSize( width, height );\n\t\tthis.renderTarget2.setSize( width, height );\n\n\t}\n\n};\n\nexport default EffectComposer;\nTHREE.EffectComposer = EffectComposer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/EffectComposer.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nvar CopyShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"opacity\": { type: \"f\", value: 1.0 }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vUv = uv;\",\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform float opacity;\",\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec4 texel = texture2D( tDiffuse, vUv );\",\n\t\t\t\"gl_FragColor = opacity * texel;\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default CopyShader;\nTHREE.CopyShader = CopyShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CopyShader.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar ShaderPass = function( shader, textureID ) {\n\n\tthis.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n\tif ( shader instanceof THREE.ShaderMaterial ) {\n\n\t\tthis.uniforms = shader.uniforms;\n\n\t\tthis.material = shader;\n\n\t}\n\telse if ( shader ) {\n\n\t\tthis.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n\t\tthis.material = new THREE.ShaderMaterial( {\n\n\t\t\tdefines: shader.defines || {},\n\t\t\tuniforms: this.uniforms,\n\t\t\tvertexShader: shader.vertexShader,\n\t\t\tfragmentShader: shader.fragmentShader\n\n\t\t} );\n\n\t}\n\n\tthis.renderToScreen = false;\n\n\tthis.enabled = true;\n\tthis.needsSwap = true;\n\tthis.clear = false;\n\n\n\tthis.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\tthis.scene = new THREE.Scene();\n\n\tthis.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );\n\tthis.scene.add( this.quad );\n\n};\n\nShaderPass.prototype = {\n\n\trender: function( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tif ( this.uniforms[ this.textureID ] ) {\n\n\t\t\tthis.uniforms[ this.textureID ].value = readBuffer;\n\n\t\t}\n\n\t\tthis.quad.material = this.material;\n\n\t\tif ( this.renderToScreen ) {\n\n\t\t\trenderer.render( this.scene, this.camera );\n\n\t\t} else {\n\n\t\t\trenderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n\t\t}\n\n\t}\n\n};\n\nexport default ShaderPass;\nTHREE.ShaderPass = ShaderPass;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/ShaderPass.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar MaskPass = function ( scene, camera ) {\n\n\tthis.scene = scene;\n\tthis.camera = camera;\n\n\tthis.enabled = true;\n\tthis.clear = true;\n\tthis.needsSwap = false;\n\n\tthis.inverse = false;\n\n};\n\nMaskPass.prototype = {\n\n\trender: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tvar context = renderer.context;\n\n\t\t// don't update color or depth\n\n\t\tcontext.colorMask( false, false, false, false );\n\t\tcontext.depthMask( false );\n\n\t\t// set up stencil\n\n\t\tvar writeValue, clearValue;\n\n\t\tif ( this.inverse ) {\n\n\t\t\twriteValue = 0;\n\t\t\tclearValue = 1;\n\n\t\t} else {\n\n\t\t\twriteValue = 1;\n\t\t\tclearValue = 0;\n\n\t\t}\n\n\t\tcontext.enable( context.STENCIL_TEST );\n\t\tcontext.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n\t\tcontext.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n\t\tcontext.clearStencil( clearValue );\n\n\t\t// draw into the stencil buffer\n\n\t\trenderer.render( this.scene, this.camera, readBuffer, this.clear );\n\t\trenderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n\t\t// re-enable update of color and depth\n\n\t\tcontext.colorMask( true, true, true, true );\n\t\tcontext.depthMask( true );\n\n\t\t// only render where stencil is set to 1\n\n\t\tcontext.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n\t\tcontext.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n\t}\n\n};\n\n\nvar ClearMaskPass = function () {\n\n\tthis.enabled = true;\n\n};\n\nClearMaskPass.prototype = {\n\n\trender: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tvar context = renderer.context;\n\n\t\tcontext.disable( context.STENCIL_TEST );\n\n\t}\n\n};\n\nexport default MaskPass;\nexport {ClearMaskPass as ClearMaskPass};\n\nTHREE.MaskPass = MaskPass;\nTHREE.ClearMaskPass = ClearMaskPass;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/MaskPass.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n\n\tthis.scene = scene;\n\tthis.camera = camera;\n\n\tthis.overrideMaterial = overrideMaterial;\n\n\tthis.clearColor = clearColor;\n\tthis.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n\tthis.oldClearColor = new THREE.Color();\n\tthis.oldClearAlpha = 1;\n\n\tthis.enabled = true;\n\tthis.clear = true;\n\tthis.needsSwap = false;\n\n};\n\nRenderPass.prototype = {\n\n\trender: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tthis.scene.overrideMaterial = this.overrideMaterial;\n\n\t\tif ( this.clearColor ) {\n\n\t\t\tthis.oldClearColor.copy( renderer.getClearColor() );\n\t\t\tthis.oldClearAlpha = renderer.getClearAlpha();\n\n\t\t\trenderer.setClearColor( this.clearColor, this.clearAlpha );\n\n\t\t}\n\n\t\trenderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n\t\tif ( this.clearColor ) {\n\n\t\t\trenderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n\t\t}\n\n\t\tthis.scene.overrideMaterial = null;\n\n\t}\n\n};\n\nexport default RenderPass;\nTHREE.RenderPass = RenderPass;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/RenderPass.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n *\n * - 9 samples per pass\n * - standard deviation 2.7\n * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n * - \"r\" parameter control where \"focused\" horizontal line lies\n */\n\nvar HorizontalTiltShiftShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"h\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\"r\": { type: \"f\", value: 0.35 }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vUv = uv;\",\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\t\t\"uniform float h;\",\n\t\t\"uniform float r;\",\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec4 sum = vec4( 0.0 );\",\n\n\t\t\t\"float hh = h * abs( r - vUv.y );\",\n\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;\",\n\n\t\t\t\"gl_FragColor = sum;\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default HorizontalTiltShiftShader;\nTHREE.HorizontalTiltShiftShader = HorizontalTiltShiftShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/HorizontalTiltShiftShader.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n *\n * - 9 samples per pass\n * - standard deviation 2.7\n * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n * - \"r\" parameter control where \"focused\" horizontal line lies\n */\n\nvar VerticalTiltShiftShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"v\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\"r\": { type: \"f\", value: 0.35 }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vUv = uv;\",\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\t\t\"uniform float v;\",\n\t\t\"uniform float r;\",\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec4 sum = vec4( 0.0 );\",\n\n\t\t\t\"float vv = v * abs( r - vUv.y );\",\n\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;\",\n\n\t\t\t\"gl_FragColor = sum;\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default VerticalTiltShiftShader;\nTHREE.VerticalTiltShiftShader = VerticalTiltShiftShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/VerticalTiltShiftShader.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n * @author davidedc / http://www.sketchpatch.net/\n *\n * NVIDIA FXAA by Timothy Lottes\n * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html\n * - WebGL port by @supereggbert\n * http://www.glge.org/demos/fxaa/\n */\n\nvar FXAAShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"resolution\": { type: \"v2\", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"void main() {\",\n\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\t\t\"uniform vec2 resolution;\",\n\n\t\t\"#define FXAA_REDUCE_MIN (1.0/128.0)\",\n\t\t\"#define FXAA_REDUCE_MUL (1.0/8.0)\",\n\t\t\"#define FXAA_SPAN_MAX 8.0\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );\",\n\t\t\t\"vec3 rgbM = rgbaM.xyz;\",\n\t\t\t\"vec3 luma = vec3( 0.299, 0.587, 0.114 );\",\n\n\t\t\t\"float lumaNW = dot( rgbNW, luma );\",\n\t\t\t\"float lumaNE = dot( rgbNE, luma );\",\n\t\t\t\"float lumaSW = dot( rgbSW, luma );\",\n\t\t\t\"float lumaSE = dot( rgbSE, luma );\",\n\t\t\t\"float lumaM = dot( rgbM, luma );\",\n\t\t\t\"float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\",\n\t\t\t\"float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\",\n\n\t\t\t\"vec2 dir;\",\n\t\t\t\"dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\",\n\t\t\t\"dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\",\n\n\t\t\t\"float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\",\n\n\t\t\t\"float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\",\n\t\t\t\"dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\",\n\t\t\t\t \"max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\",\n\t\t\t\t\t\t\"dir * rcpDirMin)) * resolution;\",\n\t\t\t\"vec4 rgbA = (1.0/2.0) * (\",\n \t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +\",\n\t\t\t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));\",\n \t\t\"vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (\",\n\t\t\t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +\",\n \t\t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));\",\n \t\t\"float lumaB = dot(rgbB, vec4(luma, 0.0));\",\n\n\t\t\t\"if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {\",\n\n\t\t\t\t\"gl_FragColor = rgbA;\",\n\n\t\t\t\"} else {\",\n\t\t\t\t\"gl_FragColor = rgbB;\",\n\n\t\t\t\"}\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default FXAAShader;\nTHREE.FXAAShader = FXAAShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/FXAAShader.js\n **/","import Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Skybox from './Skybox';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\nclass EnvironmentLayer extends Layer {\n constructor(options) {\n var defaults = {\n skybox: false\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n }\n\n _onAdd() {\n this._initLights();\n\n if (this._options.skybox) {\n this._initSkybox();\n }\n\n // this._initGrid();\n\n return Promise.resolve(this);\n }\n\n // Not fleshed out or thought through yet\n //\n // Lights could potentially be put it their own 'layer' to keep this class\n // much simpler and less messy\n _initLights() {\n // Position doesn't really matter (the angle is important), however it's\n // used here so the helpers look more natural.\n\n if (!this._options.skybox) {\n var directionalLight = new THREE.DirectionalLight(0xffffff, 1);\n directionalLight.position.x = 10000;\n directionalLight.position.y = 10000;\n directionalLight.position.z = 10000;\n\n // TODO: Get shadows working in non-PBR scenes\n\n // directionalLight.castShadow = true;\n //\n // var d = 100;\n // directionalLight.shadow.camera.left = -d;\n // directionalLight.shadow.camera.right = d;\n // directionalLight.shadow.camera.top = d;\n // directionalLight.shadow.camera.bottom = -d;\n //\n // directionalLight.shadow.camera.near = 10;\n // directionalLight.shadow.camera.far = 100;\n //\n // // TODO: Need to dial in on a good shadowmap size\n // directionalLight.shadow.mapSize.width = 2048;\n // directionalLight.shadow.mapSize.height = 2048;\n //\n // // directionalLight.shadowBias = -0.0010;\n // // directionalLight.shadow.darkness = 0.15;\n\n var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.5);\n directionalLight2.position.x = -10000;\n directionalLight2.position.y = 10000;\n directionalLight2.position.z = 0;\n\n var directionalLight3 = new THREE.DirectionalLight(0xffffff, 0.5);\n directionalLight3.position.x = 10000;\n directionalLight3.position.y = 10000;\n directionalLight3.position.z = -10000;\n\n this.add(directionalLight);\n this.add(directionalLight2);\n this.add(directionalLight3);\n\n // var helper = new THREE.DirectionalLightHelper(directionalLight, 10);\n // var helper2 = new THREE.DirectionalLightHelper(directionalLight2, 10);\n // var helper3 = new THREE.DirectionalLightHelper(directionalLight3, 10);\n //\n // this.add(helper);\n // this.add(helper2);\n // this.add(helper3);\n } else {\n // Directional light that will be projected from the sun\n this._skyboxLight = new THREE.DirectionalLight(0xffffff, 1);\n\n this._skyboxLight.castShadow = true;\n\n var d = 10000;\n this._skyboxLight.shadow.camera.left = -d;\n this._skyboxLight.shadow.camera.right = d;\n this._skyboxLight.shadow.camera.top = d;\n this._skyboxLight.shadow.camera.bottom = -d;\n\n this._skyboxLight.shadow.camera.near = 10000;\n this._skyboxLight.shadow.camera.far = 70000;\n\n // TODO: Need to dial in on a good shadowmap size\n this._skyboxLight.shadow.mapSize.width = 2048;\n this._skyboxLight.shadow.mapSize.height = 2048;\n\n // this._skyboxLight.shadowBias = -0.0010;\n // this._skyboxLight.shadow.darkness = 0.15;\n\n // this._object3D.add(new THREE.CameraHelper(this._skyboxLight.shadow.camera));\n\n this.add(this._skyboxLight);\n }\n }\n\n _initSkybox() {\n this._skybox = new Skybox(this._world, this._skyboxLight);\n this.add(this._skybox._mesh);\n }\n\n // Add grid helper for context during initial development\n _initGrid() {\n var size = 4000;\n var step = 100;\n\n var gridHelper = new THREE.GridHelper(size, step);\n this.add(gridHelper);\n }\n\n // Clean up environment\n destroy() {\n this._skyboxLight = null;\n\n this.remove(this._skybox._mesh);\n this._skybox.destroy();\n this._skybox = null;\n\n super.destroy();\n }\n}\n\nexport default EnvironmentLayer;\n\nvar noNew = function(options) {\n return new EnvironmentLayer(options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as environmentLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/environment/EnvironmentLayer.js\n **/","import EventEmitter from 'eventemitter3';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Scene from '../engine/Scene';\nimport {CSS3DObject} from '../vendor/CSS3DRenderer';\nimport {CSS2DObject} from '../vendor/CSS2DRenderer';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Need a single move method that handles moving all the various object\n// layers so that the DOM layers stay in sync with the 3D layer\n\n// TODO: Double check that objects within the _object3D Object3D parent are frustum\n// culled even if the layer position stays at the default (0,0,0) and the child\n// objects are positioned much further away\n//\n// Or does the layer being at (0,0,0) prevent the child objects from being\n// culled because the layer parent is effectively always in view even if the\n// child is actually out of camera\n\nclass Layer extends EventEmitter {\n constructor(options) {\n super();\n\n var defaults = {\n output: true,\n outputToScene: true\n };\n\n this._options = extend({}, defaults, options);\n\n if (this.isOutput()) {\n this._object3D = new THREE.Object3D();\n\n this._dom3D = document.createElement('div');\n this._domObject3D = new CSS3DObject(this._dom3D);\n\n this._dom2D = document.createElement('div');\n this._domObject2D = new CSS2DObject(this._dom2D);\n }\n }\n\n // Add THREE object directly to layer\n add(object) {\n this._object3D.add(object);\n }\n\n // Remove THREE object from to layer\n remove(object) {\n this._object3D.remove(object);\n }\n\n addDOM3D(object) {\n this._domObject3D.add(object);\n }\n\n removeDOM3D(object) {\n this._domObject3D.remove(object);\n }\n\n addDOM2D(object) {\n this._domObject2D.add(object);\n }\n\n removeDOM2D(object) {\n this._domObject2D.remove(object);\n }\n\n // Add layer to world instance and store world reference\n addTo(world) {\n return world.addLayer(this);\n }\n\n // Internal method called by World.addLayer to actually add the layer\n _addToWorld(world) {\n this._world = world;\n\n return new Promise((resolve, reject) => {\n this._onAdd(world).then(() => {\n this.emit('added');\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Must return a promise\n _onAdd(world) {}\n\n getPickingId() {\n if (this._world._engine._picking) {\n return this._world._engine._picking.getNextId();\n }\n\n return false;\n }\n\n // TODO: Tidy this up and don't access so many private properties to work\n addToPicking(object) {\n if (!this._world._engine._picking) {\n return;\n }\n\n this._world._engine._picking.add(object);\n }\n\n removeFromPicking(object) {\n if (!this._world._engine._picking) {\n return;\n }\n\n this._world._engine._picking.remove(object);\n }\n\n isOutput() {\n return this._options.output;\n }\n\n isOutputToScene() {\n return this._options.outputToScene;\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n if (this._object3D && this._object3D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._object3D.children.length - 1; i >= 0; i--) {\n child = this._object3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.remove(child);\n\n if (child.geometry) {\n // Dispose of mesh and materials\n child.geometry.dispose();\n child.geometry = null;\n }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n }\n }\n\n if (this._domObject3D && this._domObject3D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._domObject3D.children.length - 1; i >= 0; i--) {\n child = this._domObject3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.removeDOM3D(child);\n }\n }\n\n if (this._domObject2D && this._domObject2D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._domObject2D.children.length - 1; i >= 0; i--) {\n child = this._domObject2D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.removeDOM2D(child);\n }\n }\n\n this._domObject3D = null;\n this._domObject2D = null;\n\n this._world = null;\n this._object3D = null;\n }\n}\n\nexport default Layer;\n\nvar noNew = function(options) {\n return new Layer(options);\n};\n\nexport {noNew as layer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/Layer.js\n **/","import THREE from 'three';\nimport Sky from './Sky';\nimport throttle from 'lodash.throttle';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\nvar cubemap = {\n vertexShader: [\n\t\t'varying vec3 vPosition;',\n\t\t'void main() {',\n\t\t\t'vPosition = position;',\n\t\t\t'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\t\t'}'\n\t].join('\\n'),\n\n fragmentShader: [\n 'uniform samplerCube cubemap;',\n 'varying vec3 vPosition;',\n\n 'void main() {',\n 'gl_FragColor = textureCube(cubemap, normalize(vPosition));',\n '}'\n ].join('\\n')\n};\n\nclass Skybox {\n constructor(world, light) {\n this._world = world;\n this._light = light;\n\n this._settings = {\n distance: 38000,\n turbidity: 10,\n reileigh: 2,\n mieCoefficient: 0.005,\n mieDirectionalG: 0.8,\n luminance: 1,\n // 0.48 is a cracking dusk / sunset\n // 0.4 is a beautiful early-morning / late-afternoon\n // 0.2 is a nice day time\n inclination: 0.48, // Elevation / inclination\n azimuth: 0.25, // Facing front\n };\n\n this._initSkybox();\n this._updateUniforms();\n this._initEvents();\n }\n\n _initEvents() {\n // Throttled to 1 per 100ms\n this._throttledWorldUpdate = throttle(this._update, 100);\n this._world.on('preUpdate', this._throttledWorldUpdate, this);\n }\n\n _initSkybox() {\n // Cube camera for skybox\n this._cubeCamera = new THREE.CubeCamera(1, 20000000, 128);\n\n // Cube material\n var cubeTarget = this._cubeCamera.renderTarget;\n\n // Add Sky Mesh\n this._sky = new Sky();\n this._skyScene = new THREE.Scene();\n this._skyScene.add(this._sky.mesh);\n\n // Add Sun Helper\n this._sunSphere = new THREE.Mesh(\n new THREE.SphereBufferGeometry(2000, 16, 8),\n new THREE.MeshBasicMaterial({\n color: 0xffffff\n })\n );\n\n // TODO: This isn't actually visible because it's not added to the layer\n // this._sunSphere.visible = true;\n\n var skyboxUniforms = {\n cubemap: { type: 't', value: cubeTarget }\n };\n\n var skyboxMat = new THREE.ShaderMaterial({\n uniforms: skyboxUniforms,\n vertexShader: cubemap.vertexShader,\n fragmentShader: cubemap.fragmentShader,\n side: THREE.BackSide\n });\n\n this._mesh = new THREE.Mesh(new THREE.BoxGeometry(1900000, 1900000, 1900000), skyboxMat);\n\n this._updateSkybox = true;\n }\n\n _updateUniforms() {\n var settings = this._settings;\n var uniforms = this._sky.uniforms;\n uniforms.turbidity.value = settings.turbidity;\n uniforms.reileigh.value = settings.reileigh;\n uniforms.luminance.value = settings.luminance;\n uniforms.mieCoefficient.value = settings.mieCoefficient;\n uniforms.mieDirectionalG.value = settings.mieDirectionalG;\n\n var theta = Math.PI * (settings.inclination - 0.5);\n var phi = 2 * Math.PI * (settings.azimuth - 0.5);\n\n this._sunSphere.position.x = settings.distance * Math.cos(phi);\n this._sunSphere.position.y = settings.distance * Math.sin(phi) * Math.sin(theta);\n this._sunSphere.position.z = settings.distance * Math.sin(phi) * Math.cos(theta);\n\n // Move directional light to sun position\n this._light.position.copy(this._sunSphere.position);\n\n this._sky.uniforms.sunPosition.value.copy(this._sunSphere.position);\n }\n\n _update(delta) {\n if (this._updateSkybox) {\n this._updateSkybox = false;\n } else {\n return;\n }\n\n // if (!this._angle) {\n // this._angle = 0;\n // }\n //\n // // Animate inclination\n // this._angle += Math.PI * delta;\n // this._settings.inclination = 0.5 * (Math.sin(this._angle) / 2 + 0.5);\n\n // Update light intensity depending on elevation of sun (day to night)\n this._light.intensity = 1 - 0.95 * (this._settings.inclination / 0.5);\n\n // // console.log(delta, this._angle, this._settings.inclination);\n //\n // TODO: Only do this when the uniforms have been changed\n this._updateUniforms();\n\n // TODO: Only do this when the cubemap has actually changed\n this._cubeCamera.updateCubeMap(this._world._engine._renderer, this._skyScene);\n }\n\n getRenderTarget() {\n return this._cubeCamera.renderTarget;\n }\n\n setInclination(inclination) {\n this._settings.inclination = inclination;\n this._updateSkybox = true;\n }\n\n // Destroy the skybox and remove it from memory\n destroy() {\n this._world.off('preUpdate', this._throttledWorldUpdate);\n this._throttledWorldUpdate = null;\n\n this._world = null;\n this._light = null;\n\n this._cubeCamera = null;\n\n this._sky.mesh.geometry.dispose();\n this._sky.mesh.geometry = null;\n\n if (this._sky.mesh.material.map) {\n this._sky.mesh.material.map.dispose();\n this._sky.mesh.material.map = null;\n }\n\n this._sky.mesh.material.dispose();\n this._sky.mesh.material = null;\n\n this._sky.mesh = null;\n this._sky = null;\n\n this._skyScene = null;\n\n this._sunSphere.geometry.dispose();\n this._sunSphere.geometry = null;\n\n if (this._sunSphere.material.map) {\n this._sunSphere.material.map.dispose();\n this._sunSphere.material.map = null;\n }\n\n this._sunSphere.material.dispose();\n this._sunSphere.material = null;\n\n this._sunSphere = null;\n\n this._mesh.geometry.dispose();\n this._mesh.geometry = null;\n\n if (this._mesh.material.map) {\n this._mesh.material.map.dispose();\n this._mesh.material.map = null;\n }\n\n this._mesh.material.dispose();\n this._mesh.material = null;\n }\n}\n\nexport default Skybox;\n\nvar noNew = function(world, light) {\n return new Skybox(world, light);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as skybox};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/environment/Skybox.js\n **/","// jscs:disable\n/*eslint eqeqeq:0*/\n\n/**\n * @author zz85 / https://github.com/zz85\n *\n * Based on 'A Practical Analytic Model for Daylight'\n * aka The Preetham Model, the de facto standard analytic skydome model\n * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf\n *\n * First implemented by Simon Wallner\n * http://www.simonwallner.at/projects/atmospheric-scattering\n *\n * Improved by Martin Upitis\n * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR\n *\n * Three.js integration by zz85 http://twitter.com/blurspline\n*/\n\nimport THREE from 'three';\n\nTHREE.ShaderLib[ 'sky' ] = {\n\n\tuniforms: {\n\n\t\tluminance:\t { type: 'f', value: 1 },\n\t\tturbidity:\t { type: 'f', value: 2 },\n\t\treileigh:\t { type: 'f', value: 1 },\n\t\tmieCoefficient:\t { type: 'f', value: 0.005 },\n\t\tmieDirectionalG: { type: 'f', value: 0.8 },\n\t\tsunPosition: \t { type: 'v3', value: new THREE.Vector3() }\n\n\t},\n\n\tvertexShader: [\n\n\t\t'varying vec3 vWorldPosition;',\n\n\t\t'void main() {',\n\n\t\t\t'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',\n\t\t\t'vWorldPosition = worldPosition.xyz;',\n\n\t\t\t'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\n\t\t'}',\n\n\t].join( '\\n' ),\n\n\tfragmentShader: [\n\n\t\t'uniform sampler2D skySampler;',\n\t\t'uniform vec3 sunPosition;',\n\t\t'varying vec3 vWorldPosition;',\n\n\t\t'vec3 cameraPos = vec3(0., 0., 0.);',\n\t\t'// uniform sampler2D sDiffuse;',\n\t\t'// const float turbidity = 10.0; //',\n\t\t'// const float reileigh = 2.; //',\n\t\t'// const float luminance = 1.0; //',\n\t\t'// const float mieCoefficient = 0.005;',\n\t\t'// const float mieDirectionalG = 0.8;',\n\n\t\t'uniform float luminance;',\n\t\t'uniform float turbidity;',\n\t\t'uniform float reileigh;',\n\t\t'uniform float mieCoefficient;',\n\t\t'uniform float mieDirectionalG;',\n\n\t\t'// constants for atmospheric scattering',\n\t\t'const float e = 2.71828182845904523536028747135266249775724709369995957;',\n\t\t'const float pi = 3.141592653589793238462643383279502884197169;',\n\n\t\t'const float n = 1.0003; // refractive index of air',\n\t\t'const float N = 2.545E25; // number of molecules per unit volume for air at',\n\t\t\t\t\t\t\t\t'// 288.15K and 1013mb (sea level -45 celsius)',\n\t\t'const float pn = 0.035;\t// depolatization factor for standard air',\n\n\t\t'// wavelength of used primaries, according to preetham',\n\t\t'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);',\n\n\t\t'// mie stuff',\n\t\t'// K coefficient for the primaries',\n\t\t'const vec3 K = vec3(0.686, 0.678, 0.666);',\n\t\t'const float v = 4.0;',\n\n\t\t'// optical length at zenith for molecules',\n\t\t'const float rayleighZenithLength = 8.4E3;',\n\t\t'const float mieZenithLength = 1.25E3;',\n\t\t'const vec3 up = vec3(0.0, 1.0, 0.0);',\n\n\t\t'const float EE = 1000.0;',\n\t\t'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;',\n\t\t'// 66 arc seconds -> degrees, and the cosine of that',\n\n\t\t'// earth shadow hack',\n\t\t'const float cutoffAngle = pi/1.95;',\n\t\t'const float steepness = 1.5;',\n\n\n\t\t'vec3 totalRayleigh(vec3 lambda)',\n\t\t'{',\n\t\t\t'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));',\n\t\t'}',\n\n\t\t// see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness\n\t\t'// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE',\n\t\t'vec3 simplifiedRayleigh()',\n\t\t'{',\n\t\t\t'return 0.0005 / vec3(94, 40, 18);',\n\t\t\t// return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245);\n\t\t'}',\n\n\t\t'float rayleighPhase(float cosTheta)',\n\t\t'{\t ',\n\t\t\t'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));',\n\t\t'//\treturn (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));',\n\t\t'//\treturn (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));',\n\t\t'}',\n\n\t\t'vec3 totalMie(vec3 lambda, vec3 K, float T)',\n\t\t'{',\n\t\t\t'float c = (0.2 * T ) * 10E-18;',\n\t\t\t'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;',\n\t\t'}',\n\n\t\t'float hgPhase(float cosTheta, float g)',\n\t\t'{',\n\t\t\t'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));',\n\t\t'}',\n\n\t\t'float sunIntensity(float zenithAngleCos)',\n\t\t'{',\n\t\t\t'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));',\n\t\t'}',\n\n\t\t'// float logLuminance(vec3 c)',\n\t\t'// {',\n\t\t'// \treturn log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);',\n\t\t'// }',\n\n\t\t'// Filmic ToneMapping http://filmicgames.com/archives/75',\n\t\t'float A = 0.15;',\n\t\t'float B = 0.50;',\n\t\t'float C = 0.10;',\n\t\t'float D = 0.20;',\n\t\t'float E = 0.02;',\n\t\t'float F = 0.30;',\n\t\t'float W = 1000.0;',\n\n\t\t'vec3 Uncharted2Tonemap(vec3 x)',\n\t\t'{',\n\t\t 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;',\n\t\t'}',\n\n\n\t\t'void main() ',\n\t\t'{',\n\t\t\t'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);',\n\n\t\t\t'// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;',\n\n\t\t\t '// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);',\n\n\t\t\t'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));',\n\n\t\t\t'vec3 sunDirection = normalize(sunPosition);',\n\n\t\t\t'float sunE = sunIntensity(dot(sunDirection, up));',\n\n\t\t\t'// extinction (absorbtion + out scattering) ',\n\t\t\t'// rayleigh coefficients',\n\n\t\t\t// 'vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;',\n\t\t\t'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;',\n\n\t\t\t'// mie coefficients',\n\t\t\t'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;',\n\n\t\t\t'// optical length',\n\t\t\t'// cutoff angle at 90 to avoid singularity in next formula.',\n\t\t\t'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));',\n\t\t\t'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));',\n\t\t\t'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));',\n\n\n\n\t\t\t'// combined extinction factor\t',\n\t\t\t'vec3 Fex = exp(-(betaR * sR + betaM * sM));',\n\n\t\t\t'// in scattering',\n\t\t\t'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);',\n\n\t\t\t'float rPhase = rayleighPhase(cosTheta*0.5+0.5);',\n\t\t\t'vec3 betaRTheta = betaR * rPhase;',\n\n\t\t\t'float mPhase = hgPhase(cosTheta, mieDirectionalG);',\n\t\t\t'vec3 betaMTheta = betaM * mPhase;',\n\n\n\t\t\t'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));',\n\t\t\t'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));',\n\n\t\t\t'//nightsky',\n\t\t\t'vec3 direction = normalize(vWorldPosition - cameraPos);',\n\t\t\t'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]',\n\t\t\t'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]',\n\t\t\t'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);',\n\t\t\t'// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;',\n\t\t\t'vec3 L0 = vec3(0.1) * Fex;',\n\n\t\t\t'// composition + solar disc',\n\t\t\t'//if (cosTheta > sunAngularDiameterCos)',\n\t\t\t'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);',\n\t\t\t'// if (normalize(vWorldPosition - cameraPos).y>0.0)',\n\t\t\t'L0 += (sunE * 19000.0 * Fex)*sundisk;',\n\n\n\t\t\t'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));',\n\n\t\t\t'vec3 texColor = (Lin+L0); ',\n\t\t\t'texColor *= 0.04 ;',\n\t\t\t'texColor += vec3(0.0,0.001,0.0025)*0.3;',\n\n\t\t\t'float g_fMaxLuminance = 1.0;',\n\t\t\t'float fLumScaled = 0.1 / luminance; ',\n\t\t\t'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ',\n\n\t\t\t'float ExposureBias = fLumCompressed;',\n\n\t\t\t'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);',\n\t\t\t'vec3 color = curr*whiteScale;',\n\n\t\t\t'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));',\n\n\n\t\t\t'gl_FragColor.rgb = retColor;',\n\n\t\t\t'gl_FragColor.a = 1.0;',\n\t\t'}',\n\n\t].join( '\\n' )\n\n};\n\nvar Sky = function () {\n\n\tvar skyShader = THREE.ShaderLib[ 'sky' ];\n\tvar skyUniforms = THREE.UniformsUtils.clone( skyShader.uniforms );\n\n\tvar skyMat = new THREE.ShaderMaterial( {\n\t\tfragmentShader: skyShader.fragmentShader,\n\t\tvertexShader: skyShader.vertexShader,\n\t\tuniforms: skyUniforms,\n\t\tside: THREE.BackSide\n\t} );\n\n\tvar skyGeo = new THREE.SphereBufferGeometry( 450000, 32, 15 );\n\tvar skyMesh = new THREE.Mesh( skyGeo, skyMat );\n\n\n\t// Expose variables\n\tthis.mesh = skyMesh;\n\tthis.uniforms = skyUniforms;\n\n};\n\nexport default Sky;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/environment/Sky.js\n **/","/**\n * lodash 4.0.1 (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright 2012-2016 The Dojo Foundation \n * Based on Underscore.js 1.8.3 \n * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license \n */\nvar debounce = require('lodash.debounce');\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide an options object to indicate whether\n * `func` should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the throttled function is\n * invoked more than once during the `wait` timeout.\n *\n * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options] The options object.\n * @param {boolean} [options.leading=true] Specify invoking on the leading\n * edge of the timeout.\n * @param {boolean} [options.trailing=true] Specify invoking on the trailing\n * edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = throttle;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.throttle/index.js\n ** module id = 35\n ** module chunks = 0\n **/","/**\n * lodash 4.0.6 (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @type {Function}\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred function to be invoked.\n */\nvar now = Date.now;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide an options object to indicate whether `func` should be invoked on\n * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent calls\n * to the debounced function return the result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is\n * invoked more than once during the `wait` timeout.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime = 0,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (!lastCallTime || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n clearTimeout(timerId);\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastCallTime = lastInvokeTime = 0;\n lastArgs = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3);\n * // => 3\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3');\n * // => 3\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = isFunction(value.valueOf) ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = debounce;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.debounce/index.js\n ** module id = 36\n ** module chunks = 0\n **/","import Orbit, {orbit} from './Controls.Orbit';\n\nconst Controls = {\n Orbit: Orbit,\n orbit, orbit\n};\n\nexport default Controls;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/controls/index.js\n **/","import EventEmitter from 'eventemitter3';\nimport THREE from 'three';\nimport OrbitControls from '../vendor/OrbitControls';\nimport TweenLite from 'TweenLite';\n\nclass Orbit extends EventEmitter {\n constructor() {\n super();\n\n // Prevent animation from pausing when tab is inactive\n TweenLite.lagSmoothing(0);\n }\n\n // Proxy control events\n //\n // There's currently no distinction between pan, orbit and zoom events\n _initEvents() {\n this._controls.addEventListener('start', (event) => {\n this._world.emit('controlsMoveStart', event.target.target);\n });\n\n this._controls.addEventListener('change', (event) => {\n this._world.emit('controlsMove', event.target.target);\n });\n\n this._controls.addEventListener('end', (event) => {\n this._world.emit('controlsMoveEnd', event.target.target);\n });\n }\n\n // Moving the camera along the [x,y,z] axis based on a target position\n panTo(point, animate) {}\n panBy(pointDelta, animate) {}\n\n // Zooming the camera in and out\n zoomTo(metres, animate) {}\n zoomBy(metresDelta, animate) {}\n\n // Force camera to look at something other than the target\n lookAt(point, animate) {}\n\n // Make camera look at the target\n lookAtTarget() {}\n\n // Tilt (up and down)\n tiltTo(angle, animate) {}\n tiltBy(angleDelta, animate) {}\n\n // Rotate (left and right)\n rotateTo(angle, animate) {}\n rotateBy(angleDelta, animate) {}\n\n // Fly to the given point, animating pan and tilt/rotation to final position\n // with nice zoom out and in\n //\n // TODO: Calling flyTo a second time before the previous animation has\n // completed should immediately start the new animation from wherever the\n // previous one has got to\n //\n // TODO: Long-distance pans should prevent the quadtree grid from trying to\n // update by not firing the control update events every frame until the\n // pan velocity calms down a bit\n //\n // TODO: Long-distance plans should zoom out further\n //\n // TODO: Return a promise?\n flyToPoint(point, duration, zoom) {\n // Animation time in seconds\n var animationTime = duration || 2;\n\n this._flyTarget = new THREE.Vector3(point.x, 0, point.y);\n\n // Calculate delta from current position to fly target\n var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);\n\n this._flyTween = new TweenLite(\n {\n x: 0,\n z: 0,\n // zoom: 0,\n prev: {\n x: 0,\n z: 0\n }\n },\n animationTime,\n {\n x: diff.x,\n z: diff.z,\n // zoom: 1,\n onUpdate: function(tween) {\n var controls = this._controls;\n\n // Work out difference since last frame\n var deltaX = tween.target.x - tween.target.prev.x;\n var deltaZ = tween.target.z - tween.target.prev.z;\n\n // Move some fraction toward the target point\n controls.panLeft(deltaX, controls.object.matrix);\n controls.panUp(deltaZ, controls.object.matrix);\n\n tween.target.prev.x = tween.target.x;\n tween.target.prev.z = tween.target.z;\n\n // console.log(Math.sin((tween.target.zoom - 0.5) * Math.PI));\n\n // TODO: Get zoom to dolly in and out on pan\n // controls.object.zoom -= Math.sin((tween.target.zoom - 0.5) * Math.PI);\n // controls.object.updateProjectionMatrix();\n },\n onComplete: function(tween) {\n // console.log(`Arrived at flyTarget`);\n this._flyTarget = null;\n },\n onUpdateParams: ['{self}'],\n onCompleteParams: ['{self}'],\n callbackScope: this,\n ease: Power1.easeInOut\n }\n );\n\n if (!zoom) {\n return;\n }\n\n var zoomTime = animationTime / 2;\n\n this._zoomTweenIn = new TweenLite(\n {\n zoom: 0\n },\n zoomTime,\n {\n zoom: 1,\n onUpdate: function(tween) {\n var controls = this._controls;\n controls.dollyIn(1 - 0.01 * tween.target.zoom);\n },\n onComplete: function(tween) {},\n onUpdateParams: ['{self}'],\n onCompleteParams: ['{self}'],\n callbackScope: this,\n ease: Power1.easeInOut\n }\n );\n\n this._zoomTweenOut = new TweenLite(\n {\n zoom: 0\n },\n zoomTime,\n {\n zoom: 1,\n delay: zoomTime,\n onUpdate: function(tween) {\n var controls = this._controls;\n controls.dollyOut(0.99 + 0.01 * tween.target.zoom);\n },\n onComplete: function(tween) {},\n onUpdateParams: ['{self}'],\n onCompleteParams: ['{self}'],\n callbackScope: this,\n ease: Power1.easeInOut\n }\n );\n }\n\n // TODO: Return a promise?\n flyToLatLon(latlon, duration, noZoom) {\n var point = this._world.latLonToPoint(latlon);\n this.flyToPoint(point, duration, noZoom);\n }\n\n // TODO: Make this animate over a user-defined period of time\n //\n // Perhaps use TweenMax for now and implement as a more lightweight solution\n // later on once it all works\n // _animateFlyTo(delta) {\n // var controls = this._controls;\n //\n // // this._controls.panLeft(50, controls._controls.object.matrix);\n // // this._controls.panUp(50, controls._controls.object.matrix);\n // // this._controls.dollyIn(this._controls.getZoomScale());\n // // this._controls.dollyOut(this._controls.getZoomScale());\n //\n // // Calculate delta from current position to fly target\n // var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);\n //\n // // 1000 units per second\n // var speed = 1000 * (delta / 1000);\n //\n // // Remove fly target after arrival and snap to target\n // if (diff.length() < 0.01) {\n // console.log(`Arrived at flyTarget`);\n // this._flyTarget = null;\n // speed = 1;\n // }\n //\n // // Move some fraction toward the target point\n // controls.panLeft(diff.x * speed, controls.object.matrix);\n // controls.panUp(diff.z * speed, controls.object.matrix);\n // }\n\n // Proxy to OrbitControls.update()\n update(delta) {\n this._controls.update(delta);\n }\n\n // Add controls to world instance and store world reference\n addTo(world) {\n world.addControls(this);\n return Promise.resolve(this);\n }\n\n // Internal method called by World.addControls to actually add the controls\n _addToWorld(world) {\n this._world = world;\n\n // TODO: Override panLeft and panUp methods to prevent panning on Y axis\n // See: http://stackoverflow.com/a/26188674/997339\n this._controls = new OrbitControls(world._engine._camera, world._container);\n\n // Disable keys for now as no events are fired for them anyway\n this._controls.keys = false;\n\n // 89 degrees\n this._controls.maxPolarAngle = 1.5533;\n\n // this._controls.enableDamping = true;\n // this._controls.dampingFactor = 0.25;\n\n this._initEvents();\n\n // TODO: Remove now that this is a promise?\n this.emit('added');\n\n return Promise.resolve(this);\n }\n\n // Destroys the controls and removes them from memory\n destroy() {\n // TODO: Remove event listeners\n\n this._controls.dispose();\n\n this._world = null;\n this._controls = null;\n }\n}\n\nexport default Orbit;\n\nvar noNew = function() {\n return new Orbit();\n};\n\n// Initialise without requiring new keyword\nexport {noNew as orbit};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/controls/Controls.Orbit.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\nimport Hammer from 'hammerjs';\n\n/**\n * @author qiao / https://github.com/qiao\n * @author mrdoob / http://mrdoob.com\n * @author alteredq / http://alteredqualia.com/\n * @author WestLangley / http://github.com/WestLangley\n * @author erich666 / http://erichaines.com\n */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\nvar OrbitControls = function ( object, domElement ) {\n\n\tthis.object = object;\n\n\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t// Set to false to disable this control\n\tthis.enabled = true;\n\n\t// \"target\" sets the location of focus, where the object orbits around\n\tthis.target = new THREE.Vector3();\n\n\t// How far you can dolly in and out ( PerspectiveCamera only )\n\tthis.minDistance = 0;\n\tthis.maxDistance = Infinity;\n\n\t// How far you can zoom in and out ( OrthographicCamera only )\n\tthis.minZoom = 0;\n\tthis.maxZoom = Infinity;\n\n\t// How far you can orbit vertically, upper and lower limits.\n\t// Range is 0 to Math.PI radians.\n\tthis.minPolarAngle = 0; // radians\n\tthis.maxPolarAngle = Math.PI; // radians\n\n\t// How far you can orbit horizontally, upper and lower limits.\n\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\tthis.minAzimuthAngle = - Infinity; // radians\n\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t// Set to true to enable damping (inertia)\n\t// If damping is enabled, you must call controls.update() in your animation loop\n\tthis.enableDamping = false;\n\tthis.dampingFactor = 0.25;\n\n\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t// Set to false to disable zooming\n\tthis.enableZoom = true;\n\tthis.zoomSpeed = 1.0;\n\n\t// Set to false to disable rotating\n\tthis.enableRotate = true;\n\tthis.rotateSpeed = 1.0;\n\n\t// Set to false to disable panning\n\tthis.enablePan = true;\n\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t// Set to true to automatically rotate around the target\n\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\tthis.autoRotate = false;\n\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t// Set to false to disable use of the keys\n\tthis.enableKeys = true;\n\n\t// The four arrow keys\n\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t// Mouse buttons\n\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t// for reset\n\tthis.target0 = this.target.clone();\n\tthis.position0 = this.object.position.clone();\n\tthis.zoom0 = this.object.zoom;\n\n\t//\n\t// public methods\n\t//\n\n\tthis.getPolarAngle = function () {\n\n\t\treturn phi;\n\n\t};\n\n\tthis.getAzimuthalAngle = function () {\n\n\t\treturn theta;\n\n\t};\n\n\tthis.reset = function () {\n\n\t\tscope.target.copy( scope.target0 );\n\t\tscope.object.position.copy( scope.position0 );\n\t\tscope.object.zoom = scope.zoom0;\n\n\t\tscope.object.updateProjectionMatrix();\n\t\tscope.dispatchEvent( changeEvent );\n\n\t\tscope.update();\n\n\t\tstate = STATE.NONE;\n\n\t};\n\n\t// this method is exposed, but perhaps it would be better if we can make it private...\n\tthis.update = function() {\n\n\t\tvar offset = new THREE.Vector3();\n\n\t\t// so camera.up is the orbit axis\n\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\tvar quatInverse = quat.clone().inverse();\n\n\t\tvar lastPosition = new THREE.Vector3();\n\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\treturn function () {\n\n\t\t\tvar position = scope.object.position;\n\n\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t// angle from z-axis around y-axis\n\n\t\t\ttheta = Math.atan2( offset.x, offset.z );\n\n\t\t\t// angle from y-axis\n\n\t\t\tphi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );\n\n\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t}\n\n\t\t\ttheta += thetaDelta;\n\t\t\tphi += phiDelta;\n\n\t\t\t// restrict theta to be between desired limits\n\t\t\ttheta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, theta ) );\n\n\t\t\t// restrict phi to be between desired limits\n\t\t\tphi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, phi ) );\n\n\t\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\t\tphi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );\n\n\t\t\tvar radius = offset.length() * scale;\n\n\t\t\t// restrict radius to be between desired limits\n\t\t\tradius = Math.max( scope.minDistance, Math.min( scope.maxDistance, radius ) );\n\n\t\t\t// move target to panned location\n\t\t\tscope.target.add( panOffset );\n\n\t\t\toffset.x = radius * Math.sin( phi ) * Math.sin( theta );\n\t\t\toffset.y = radius * Math.cos( phi );\n\t\t\toffset.z = radius * Math.sin( phi ) * Math.cos( theta );\n\n\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\tthetaDelta *= ( 1 - scope.dampingFactor );\n\t\t\t\tphiDelta *= ( 1 - scope.dampingFactor );\n\n\t\t\t} else {\n\n\t\t\t\tthetaDelta = 0;\n\t\t\t\tphiDelta = 0;\n\n\t\t\t}\n\n\t\t\tscale = 1;\n\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t// update condition is:\n\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\tif ( zoomChanged ||\n\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\tzoomChanged = false;\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t};\n\n\t}();\n\n\tthis.dispose = function() {\n\n\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.removeEventListener( 'mousewheel', onMouseWheel, false );\n\t\tscope.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox\n\n\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\t\tdocument.removeEventListener( 'mouseout', onMouseUp, false );\n\n\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t};\n\n\t//\n\t// internals\n\t//\n\n\tvar scope = this;\n\n\tvar changeEvent = { type: 'change' };\n\tvar startEvent = { type: 'start' };\n\tvar endEvent = { type: 'end' };\n\n\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\tvar state = STATE.NONE;\n\n\tvar EPS = 0.000001;\n\n\t// current position in spherical coordinates\n\tvar theta;\n\tvar phi;\n\n\tvar phiDelta = 0;\n\tvar thetaDelta = 0;\n\tvar scale = 1;\n\tvar panOffset = new THREE.Vector3();\n\tvar zoomChanged = false;\n\n\tvar rotateStart = new THREE.Vector2();\n\tvar rotateEnd = new THREE.Vector2();\n\tvar rotateDelta = new THREE.Vector2();\n\n\tvar panStart = new THREE.Vector2();\n\tvar panEnd = new THREE.Vector2();\n\tvar panDelta = new THREE.Vector2();\n\n\tvar dollyStart = new THREE.Vector2();\n\tvar dollyEnd = new THREE.Vector2();\n\tvar dollyDelta = new THREE.Vector2();\n\n\tfunction getAutoRotationAngle() {\n\n\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t}\n\n\tfunction getZoomScale() {\n\n\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t}\n\n\tfunction rotateLeft( angle ) {\n\n\t\tthetaDelta -= angle;\n\n\t}\n\n\tfunction rotateUp( angle ) {\n\n\t\tphiDelta -= angle;\n\n\t}\n\n\tvar panLeft = function() {\n\n\t\tvar v = new THREE.Vector3();\n\n\t\t// return function panLeft( distance, objectMatrix ) {\n //\n\t\t// \tvar te = objectMatrix.elements;\n //\n\t\t// \t// get X column of objectMatrix\n\t\t// \tv.set( te[ 0 ], te[ 1 ], te[ 2 ] );\n //\n\t\t// \tv.multiplyScalar( - distance );\n //\n\t\t// \tpanOffset.add( v );\n //\n\t\t// };\n\n // Fixed panning to x/y plane\n return function panLeft(distance, objectMatrix) {\n\t var te = objectMatrix.elements;\n\t // var adjDist = distance / Math.cos(phi);\n\n\t v.set(te[ 0 ], 0, te[ 2 ]);\n\t v.multiplyScalar(-distance);\n\n\t panOffset.add(v);\n\t };\n\n\t}();\n\n // Fixed panning to x/y plane\n\tvar panUp = function() {\n\n\t\tvar v = new THREE.Vector3();\n\n\t\t// return function panUp( distance, objectMatrix ) {\n //\n\t\t// \tvar te = objectMatrix.elements;\n //\n\t\t// \t// get Y column of objectMatrix\n\t\t// \tv.set( te[ 4 ], te[ 5 ], te[ 6 ] );\n //\n\t\t// \tv.multiplyScalar( distance );\n //\n\t\t// \tpanOffset.add( v );\n //\n\t\t// };\n\n return function panUp(distance, objectMatrix) {\n\t var te = objectMatrix.elements;\n\t var adjDist = distance / Math.cos(phi);\n\n\t v.set(te[ 4 ], 0, te[ 6 ]);\n\t v.multiplyScalar(adjDist);\n\n\t panOffset.add(v);\n\t };\n\n\t}();\n\n\t// deltaX and deltaY are in pixels; right and down are positive\n\tvar pan = function() {\n\n\t\tvar offset = new THREE.Vector3();\n\n\t\treturn function( deltaX, deltaY ) {\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t// perspective\n\t\t\t\tvar position = scope.object.position;\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t// orthographic\n\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / element.clientWidth, scope.object.matrix );\n\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / element.clientHeight, scope.object.matrix );\n\n\t\t\t} else {\n\n\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\tscope.enablePan = false;\n\n\t\t\t}\n\n\t\t};\n\n\t}();\n\n\tfunction dollyIn( dollyScale ) {\n\n\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\tscale /= dollyScale;\n\n\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tzoomChanged = true;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\tscope.enableZoom = false;\n\n\t\t}\n\n\t}\n\n\tfunction dollyOut( dollyScale ) {\n\n\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\tscale *= dollyScale;\n\n\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tzoomChanged = true;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\tscope.enableZoom = false;\n\n\t\t}\n\n\t}\n\n\t//\n\t// event callbacks - update the object state\n\t//\n\n\tfunction handleMouseDownRotate( event ) {\n\n\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\trotateStart.set( event.clientX, event.clientY );\n\n\t}\n\n\tfunction handleMouseDownDolly( event ) {\n\n\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t}\n\n\tfunction handleMouseDownPan( event ) {\n\n\t\t//console.log( 'handleMouseDownPan' );\n\n\t\tpanStart.set( event.clientX, event.clientY );\n\n\t}\n\n\tfunction handleMouseMoveRotate( event ) {\n\n\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\trotateEnd.set( event.clientX, event.clientY );\n\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t// rotating across whole screen goes 360 degrees around\n\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\trotateStart.copy( rotateEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleMouseMoveDolly( event ) {\n\n\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\tdollyIn( getZoomScale() );\n\n\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\tdollyOut( getZoomScale() );\n\n\t\t}\n\n\t\tdollyStart.copy( dollyEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleMouseMovePan( event ) {\n\n\t\t//console.log( 'handleMouseMovePan' );\n\n\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\tpan( panDelta.x, panDelta.y );\n\n\t\tpanStart.copy( panEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleMouseUp( event ) {\n\n\t\t//console.log( 'handleMouseUp' );\n\n\t}\n\n\tfunction handleMouseWheel( event ) {\n\n\t\t//console.log( 'handleMouseWheel' );\n\n\t\tvar delta = 0;\n\n\t\tif ( event.wheelDelta !== undefined ) {\n\n\t\t\t// WebKit / Opera / Explorer 9\n\n\t\t\tdelta = event.wheelDelta;\n\n\t\t} else if ( event.detail !== undefined ) {\n\n\t\t\t// Firefox\n\n\t\t\tdelta = - event.detail;\n\n\t\t}\n\n\t\tif ( delta > 0 ) {\n\n\t\t\tdollyOut( getZoomScale() );\n\n\t\t} else if ( delta < 0 ) {\n\n\t\t\tdollyIn( getZoomScale() );\n\n\t\t}\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleKeyDown( event ) {\n\n\t\t//console.log( 'handleKeyDown' );\n\n\t\tswitch ( event.keyCode ) {\n\n\t\t\tcase scope.keys.UP:\n\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.LEFT:\n\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.RIGHT:\n\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\tfunction handleTouchStartRotate( event ) {\n\n\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\trotateStart.set( event.pointers[ 0 ].pageX, event.pointers[ 0 ].pageY );\n\n\t}\n\n\tfunction handleTouchStartDolly( event ) {\n\n\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\tvar dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\tvar dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\n\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\tdollyStart.set( 0, distance );\n\n\t}\n\n\tfunction handleTouchStartPan( event ) {\n\n\t\t//console.log( 'handleTouchStartPan' );\n\n\t\tpanStart.set( event.deltaX, event.deltaY );\n\n\t}\n\n\tfunction handleTouchMoveRotate( event ) {\n\n\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\trotateEnd.set( event.pointers[ 0 ].pageX, event.pointers[ 0 ].pageY );\n\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t// rotating across whole screen goes 360 degrees around\n\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\trotateStart.copy( rotateEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleTouchMoveDolly( event ) {\n\n\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\tvar dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\tvar dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\n\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\tdollyEnd.set( 0, distance );\n\n\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\tdollyOut( getZoomScale() );\n\n\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\tdollyIn( getZoomScale() );\n\n\t\t}\n\n\t\tdollyStart.copy( dollyEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleTouchMovePan( event ) {\n\n\t\t//console.log( 'handleTouchMovePan' );\n\n\t\tpanEnd.set( event.deltaX, event.deltaY );\n\n\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\tpan( panDelta.x, panDelta.y );\n\n\t\tpanStart.copy( panEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleTouchEnd( event ) {\n\n\t\t//console.log( 'handleTouchEnd' );\n\n\t}\n\n\t//\n\t// event handlers - FSM: listen for events and reset state\n\t//\n\n\tfunction onMouseDown( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\n\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\thandleMouseDownRotate( event );\n\n\t\t\tstate = STATE.ROTATE;\n\n\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\thandleMouseDownDolly( event );\n\n\t\t\tstate = STATE.DOLLY;\n\n\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\thandleMouseDownPan( event );\n\n\t\t\tstate = STATE.PAN;\n\n\t\t}\n\n\t\tif ( state !== STATE.NONE ) {\n\n\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\t\t\tdocument.addEventListener( 'mouseout', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t}\n\n\t}\n\n\tfunction onMouseMove( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\n\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\thandleMouseMoveRotate( event );\n\n\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\thandleMouseMoveDolly( event );\n\n\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\thandleMouseMovePan( event );\n\n\t\t}\n\n\t}\n\n\tfunction onMouseUp( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\thandleMouseUp( event );\n\n\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\t\tdocument.removeEventListener( 'mouseout', onMouseUp, false );\n\n\t\tscope.dispatchEvent( endEvent );\n\n\t\tstate = STATE.NONE;\n\n\t}\n\n\tfunction onMouseWheel( event ) {\n\n\t\tif ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\thandleMouseWheel( event );\n\n\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\tscope.dispatchEvent( endEvent );\n\n\t}\n\n\tfunction onKeyDown( event ) {\n\n\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\thandleKeyDown( event );\n\n\t}\n\n\tfunction onTouchStart( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tswitch ( event.touches.length ) {\n\n\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tif ( state !== STATE.NONE ) {\n\n\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t}\n\n\t}\n\n\tfunction onTouchMove( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tswitch ( event.touches.length ) {\n\n\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t}\n\n\tfunction onTouchEnd( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\thandleTouchEnd( event );\n\n\t\tscope.dispatchEvent( endEvent );\n\n\t\tstate = STATE.NONE;\n\n\t}\n\n\tfunction onContextMenu( event ) {\n\n\t\tevent.preventDefault();\n\n\t}\n\n\t//\n\n\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\tscope.domElement.addEventListener( 'mousewheel', onMouseWheel, false );\n\tscope.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox\n\n\t// scope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t// scope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t// scope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\tscope.hammer = new Hammer(scope.domElement);\n\n\tscope.hammer.get('pan').set({\n\t\tpointers: 0,\n\t\tdirection: Hammer.DIRECTION_ALL\n\t});\n\n\tscope.hammer.get('pinch').set({\n\t\tenable: true,\n\t\tthreshold: 0.1\n\t});\n\n\tscope.hammer.on('panstart', function(event) {\n\t\tif (scope.enabled === false) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.pointers.length === 1) {\n\t\t\tif (scope.enablePan === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\thandleTouchStartPan(event);\n\t\t\t// panStart.set(event.deltaX, event.deltaY);\n\n\t\t\tstate = STATE.TOUCH_PAN;\n\t\t} else if (event.pointers.length === 2) {\n\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\thandleTouchStartRotate( event );\n\n\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\t}\n\n\t\tif (state !== STATE.NONE) {\n\t\t\tscope.dispatchEvent(startEvent);\n\t\t}\n\t});\n\n\tscope.hammer.on('panend', function(event) {\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tonTouchEnd(event);\n\t});\n\n\tscope.hammer.on('panmove', function(event) {\n\t\tif ( scope.enabled === false ) return;\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\t// event.preventDefault();\n\t\t// event.stopPropagation();\n\n\t\tif (event.pointers.length === 1) {\n\t\t\tif ( scope.enablePan === false ) return;\n\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\thandleTouchMovePan( event );\n\n\t\t\t// panEnd.set( event.deltaX, event.deltaY );\n\t\t\t//\n\t\t\t// panDelta.subVectors( panEnd, panStart );\n\t\t\t//\n\t\t\t// pan( panDelta.x, panDelta.y );\n\t\t\t//\n\t\t\t// panStart.copy( panEnd );\n\t\t\t//\n\t\t\t// scope.update();\n\t\t} else if (event.pointers.length === 2) {\n\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\thandleTouchMoveRotate( event );\n\t\t}\n\t});\n\n\tscope.hammer.on('pinchstart', function(event) {\n\t\tif ( scope.enabled === false ) return;\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( scope.enableZoom === false ) return;\n\n\t\thandleTouchStartDolly( event );\n\n\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t//\n\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t//\n\t\t// dollyStart.set( 0, distance );\n\t\t//\n\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\tif (state !== STATE.NONE) {\n\t\t\tscope.dispatchEvent(startEvent);\n\t\t}\n\t});\n\n\tscope.hammer.on('pinchend', function(event) {\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tonTouchEnd(event);\n\t});\n\n\tscope.hammer.on('pinchmove', function(event) {\n\t\tif ( scope.enabled === false ) return;\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\t// event.preventDefault();\n\t\t// event.stopPropagation();\n\n\t\tif ( scope.enableZoom === false ) return;\n\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\thandleTouchMoveDolly( event );\n\n\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t//\n\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t//\n\t\t// dollyEnd.set( 0, distance );\n\t\t//\n\t\t// dollyDelta.subVectors( dollyEnd, dollyStart );\n\t\t//\n\t\t// if ( dollyDelta.y > 0 ) {\n\t\t//\n\t\t// \tdollyOut( getZoomScale() );\n\t\t//\n\t\t// } else if ( dollyDelta.y < 0 ) {\n\t\t//\n\t\t// \tdollyIn( getZoomScale() );\n\t\t//\n\t\t// }\n\t\t//\n\t\t// dollyStart.copy( dollyEnd );\n\t\t//\n\t\t// scope.update();\n\t});\n\n\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t// Expose controls methods for programmatic control\n\tthis.panLeft = panLeft;\n\tthis.panUp = panUp;\n\tthis.pan = pan;\n\tthis.dollyIn = dollyIn;\n\tthis.dollyOut = dollyOut;\n\tthis.getZoomScale = getZoomScale;\n\tthis.rotateLeft = rotateLeft;\n\tthis.rotateUp = rotateUp;\n\n\t// force an update at start\n\n\tthis.update();\n\n};\n\nOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\nOrbitControls.prototype.constructor = THREE.OrbitControls;\n\nObject.defineProperties( OrbitControls.prototype, {\n\n\tcenter: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\treturn this.target;\n\n\t\t}\n\n\t},\n\n\t// backward compatibility\n\n\tnoZoom: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\treturn ! this.enableZoom;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\tthis.enableZoom = ! value;\n\n\t\t}\n\n\t},\n\n\tnoRotate: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\treturn ! this.enableRotate;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\tthis.enableRotate = ! value;\n\n\t\t}\n\n\t},\n\n\tnoPan: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\treturn ! this.enablePan;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\tthis.enablePan = ! value;\n\n\t\t}\n\n\t},\n\n\tnoKeys: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\treturn ! this.enableKeys;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\tthis.enableKeys = ! value;\n\n\t\t}\n\n\t},\n\n\tstaticMoving : {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\treturn ! this.constraint.enableDamping;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\tthis.constraint.enableDamping = ! value;\n\n\t\t}\n\n\t},\n\n\tdynamicDampingFactor : {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\treturn this.constraint.dampingFactor;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\tthis.constraint.dampingFactor = value;\n\n\t\t}\n\n\t}\n\n} );\n\nexport default OrbitControls;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/OrbitControls.js\n **/","/*! Hammer.JS - v2.0.7 - 2016-04-22\n * http://hammerjs.github.io/\n *\n * Copyright (c) 2016 Jorik Tangelder;\n * Licensed under the MIT license */\n(function(window, document, exportName, undefined) {\n 'use strict';\n\nvar VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];\nvar TEST_ELEMENT = document.createElement('div');\n\nvar TYPE_FUNCTION = 'function';\n\nvar round = Math.round;\nvar abs = Math.abs;\nvar now = Date.now;\n\n/**\n * set a timeout with a given scope\n * @param {Function} fn\n * @param {Number} timeout\n * @param {Object} context\n * @returns {number}\n */\nfunction setTimeoutContext(fn, timeout, context) {\n return setTimeout(bindFn(fn, context), timeout);\n}\n\n/**\n * if the argument is an array, we want to execute the fn on each entry\n * if it aint an array we don't want to do a thing.\n * this is used by all the methods that accept a single and array argument.\n * @param {*|Array} arg\n * @param {String} fn\n * @param {Object} [context]\n * @returns {Boolean}\n */\nfunction invokeArrayArg(arg, fn, context) {\n if (Array.isArray(arg)) {\n each(arg, context[fn], context);\n return true;\n }\n return false;\n}\n\n/**\n * walk objects and arrays\n * @param {Object} obj\n * @param {Function} iterator\n * @param {Object} context\n */\nfunction each(obj, iterator, context) {\n var i;\n\n if (!obj) {\n return;\n }\n\n if (obj.forEach) {\n obj.forEach(iterator, context);\n } else if (obj.length !== undefined) {\n i = 0;\n while (i < obj.length) {\n iterator.call(context, obj[i], i, obj);\n i++;\n }\n } else {\n for (i in obj) {\n obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);\n }\n }\n}\n\n/**\n * wrap a method with a deprecation warning and stack trace\n * @param {Function} method\n * @param {String} name\n * @param {String} message\n * @returns {Function} A new function wrapping the supplied method.\n */\nfunction deprecate(method, name, message) {\n var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\\n' + message + ' AT \\n';\n return function() {\n var e = new Error('get-stack-trace');\n var stack = e && e.stack ? e.stack.replace(/^[^\\(]+?[\\n$]/gm, '')\n .replace(/^\\s+at\\s+/gm, '')\n .replace(/^Object.\\s*\\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';\n\n var log = window.console && (window.console.warn || window.console.log);\n if (log) {\n log.call(window.console, deprecationMessage, stack);\n }\n return method.apply(this, arguments);\n };\n}\n\n/**\n * extend object.\n * means that properties in dest will be overwritten by the ones in src.\n * @param {Object} target\n * @param {...Object} objects_to_assign\n * @returns {Object} target\n */\nvar assign;\nif (typeof Object.assign !== 'function') {\n assign = function assign(target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n var output = Object(target);\n for (var index = 1; index < arguments.length; index++) {\n var source = arguments[index];\n if (source !== undefined && source !== null) {\n for (var nextKey in source) {\n if (source.hasOwnProperty(nextKey)) {\n output[nextKey] = source[nextKey];\n }\n }\n }\n }\n return output;\n };\n} else {\n assign = Object.assign;\n}\n\n/**\n * extend object.\n * means that properties in dest will be overwritten by the ones in src.\n * @param {Object} dest\n * @param {Object} src\n * @param {Boolean} [merge=false]\n * @returns {Object} dest\n */\nvar extend = deprecate(function extend(dest, src, merge) {\n var keys = Object.keys(src);\n var i = 0;\n while (i < keys.length) {\n if (!merge || (merge && dest[keys[i]] === undefined)) {\n dest[keys[i]] = src[keys[i]];\n }\n i++;\n }\n return dest;\n}, 'extend', 'Use `assign`.');\n\n/**\n * merge the values from src in the dest.\n * means that properties that exist in dest will not be overwritten by src\n * @param {Object} dest\n * @param {Object} src\n * @returns {Object} dest\n */\nvar merge = deprecate(function merge(dest, src) {\n return extend(dest, src, true);\n}, 'merge', 'Use `assign`.');\n\n/**\n * simple class inheritance\n * @param {Function} child\n * @param {Function} base\n * @param {Object} [properties]\n */\nfunction inherit(child, base, properties) {\n var baseP = base.prototype,\n childP;\n\n childP = child.prototype = Object.create(baseP);\n childP.constructor = child;\n childP._super = baseP;\n\n if (properties) {\n assign(childP, properties);\n }\n}\n\n/**\n * simple function bind\n * @param {Function} fn\n * @param {Object} context\n * @returns {Function}\n */\nfunction bindFn(fn, context) {\n return function boundFn() {\n return fn.apply(context, arguments);\n };\n}\n\n/**\n * let a boolean value also be a function that must return a boolean\n * this first item in args will be used as the context\n * @param {Boolean|Function} val\n * @param {Array} [args]\n * @returns {Boolean}\n */\nfunction boolOrFn(val, args) {\n if (typeof val == TYPE_FUNCTION) {\n return val.apply(args ? args[0] || undefined : undefined, args);\n }\n return val;\n}\n\n/**\n * use the val2 when val1 is undefined\n * @param {*} val1\n * @param {*} val2\n * @returns {*}\n */\nfunction ifUndefined(val1, val2) {\n return (val1 === undefined) ? val2 : val1;\n}\n\n/**\n * addEventListener with multiple events at once\n * @param {EventTarget} target\n * @param {String} types\n * @param {Function} handler\n */\nfunction addEventListeners(target, types, handler) {\n each(splitStr(types), function(type) {\n target.addEventListener(type, handler, false);\n });\n}\n\n/**\n * removeEventListener with multiple events at once\n * @param {EventTarget} target\n * @param {String} types\n * @param {Function} handler\n */\nfunction removeEventListeners(target, types, handler) {\n each(splitStr(types), function(type) {\n target.removeEventListener(type, handler, false);\n });\n}\n\n/**\n * find if a node is in the given parent\n * @method hasParent\n * @param {HTMLElement} node\n * @param {HTMLElement} parent\n * @return {Boolean} found\n */\nfunction hasParent(node, parent) {\n while (node) {\n if (node == parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n}\n\n/**\n * small indexOf wrapper\n * @param {String} str\n * @param {String} find\n * @returns {Boolean} found\n */\nfunction inStr(str, find) {\n return str.indexOf(find) > -1;\n}\n\n/**\n * split string on whitespace\n * @param {String} str\n * @returns {Array} words\n */\nfunction splitStr(str) {\n return str.trim().split(/\\s+/g);\n}\n\n/**\n * find if a array contains the object using indexOf or a simple polyFill\n * @param {Array} src\n * @param {String} find\n * @param {String} [findByKey]\n * @return {Boolean|Number} false when not found, or the index\n */\nfunction inArray(src, find, findByKey) {\n if (src.indexOf && !findByKey) {\n return src.indexOf(find);\n } else {\n var i = 0;\n while (i < src.length) {\n if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {\n return i;\n }\n i++;\n }\n return -1;\n }\n}\n\n/**\n * convert array-like objects to real arrays\n * @param {Object} obj\n * @returns {Array}\n */\nfunction toArray(obj) {\n return Array.prototype.slice.call(obj, 0);\n}\n\n/**\n * unique array with objects based on a key (like 'id') or just by the array's value\n * @param {Array} src [{id:1},{id:2},{id:1}]\n * @param {String} [key]\n * @param {Boolean} [sort=False]\n * @returns {Array} [{id:1},{id:2}]\n */\nfunction uniqueArray(src, key, sort) {\n var results = [];\n var values = [];\n var i = 0;\n\n while (i < src.length) {\n var val = key ? src[i][key] : src[i];\n if (inArray(values, val) < 0) {\n results.push(src[i]);\n }\n values[i] = val;\n i++;\n }\n\n if (sort) {\n if (!key) {\n results = results.sort();\n } else {\n results = results.sort(function sortUniqueArray(a, b) {\n return a[key] > b[key];\n });\n }\n }\n\n return results;\n}\n\n/**\n * get the prefixed property\n * @param {Object} obj\n * @param {String} property\n * @returns {String|Undefined} prefixed\n */\nfunction prefixed(obj, property) {\n var prefix, prop;\n var camelProp = property[0].toUpperCase() + property.slice(1);\n\n var i = 0;\n while (i < VENDOR_PREFIXES.length) {\n prefix = VENDOR_PREFIXES[i];\n prop = (prefix) ? prefix + camelProp : property;\n\n if (prop in obj) {\n return prop;\n }\n i++;\n }\n return undefined;\n}\n\n/**\n * get a unique id\n * @returns {number} uniqueId\n */\nvar _uniqueId = 1;\nfunction uniqueId() {\n return _uniqueId++;\n}\n\n/**\n * get the window object of an element\n * @param {HTMLElement} element\n * @returns {DocumentView|Window}\n */\nfunction getWindowForElement(element) {\n var doc = element.ownerDocument || element;\n return (doc.defaultView || doc.parentWindow || window);\n}\n\nvar MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;\n\nvar SUPPORT_TOUCH = ('ontouchstart' in window);\nvar SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;\nvar SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);\n\nvar INPUT_TYPE_TOUCH = 'touch';\nvar INPUT_TYPE_PEN = 'pen';\nvar INPUT_TYPE_MOUSE = 'mouse';\nvar INPUT_TYPE_KINECT = 'kinect';\n\nvar COMPUTE_INTERVAL = 25;\n\nvar INPUT_START = 1;\nvar INPUT_MOVE = 2;\nvar INPUT_END = 4;\nvar INPUT_CANCEL = 8;\n\nvar DIRECTION_NONE = 1;\nvar DIRECTION_LEFT = 2;\nvar DIRECTION_RIGHT = 4;\nvar DIRECTION_UP = 8;\nvar DIRECTION_DOWN = 16;\n\nvar DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;\nvar DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;\nvar DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;\n\nvar PROPS_XY = ['x', 'y'];\nvar PROPS_CLIENT_XY = ['clientX', 'clientY'];\n\n/**\n * create new input type manager\n * @param {Manager} manager\n * @param {Function} callback\n * @returns {Input}\n * @constructor\n */\nfunction Input(manager, callback) {\n var self = this;\n this.manager = manager;\n this.callback = callback;\n this.element = manager.element;\n this.target = manager.options.inputTarget;\n\n // smaller wrapper around the handler, for the scope and the enabled state of the manager,\n // so when disabled the input events are completely bypassed.\n this.domHandler = function(ev) {\n if (boolOrFn(manager.options.enable, [manager])) {\n self.handler(ev);\n }\n };\n\n this.init();\n\n}\n\nInput.prototype = {\n /**\n * should handle the inputEvent data and trigger the callback\n * @virtual\n */\n handler: function() { },\n\n /**\n * bind the events\n */\n init: function() {\n this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);\n this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);\n this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n },\n\n /**\n * unbind the events\n */\n destroy: function() {\n this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);\n this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);\n this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n }\n};\n\n/**\n * create new input type manager\n * called by the Manager constructor\n * @param {Hammer} manager\n * @returns {Input}\n */\nfunction createInputInstance(manager) {\n var Type;\n var inputClass = manager.options.inputClass;\n\n if (inputClass) {\n Type = inputClass;\n } else if (SUPPORT_POINTER_EVENTS) {\n Type = PointerEventInput;\n } else if (SUPPORT_ONLY_TOUCH) {\n Type = TouchInput;\n } else if (!SUPPORT_TOUCH) {\n Type = MouseInput;\n } else {\n Type = TouchMouseInput;\n }\n return new (Type)(manager, inputHandler);\n}\n\n/**\n * handle input events\n * @param {Manager} manager\n * @param {String} eventType\n * @param {Object} input\n */\nfunction inputHandler(manager, eventType, input) {\n var pointersLen = input.pointers.length;\n var changedPointersLen = input.changedPointers.length;\n var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));\n var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));\n\n input.isFirst = !!isFirst;\n input.isFinal = !!isFinal;\n\n if (isFirst) {\n manager.session = {};\n }\n\n // source event is the normalized value of the domEvents\n // like 'touchstart, mouseup, pointerdown'\n input.eventType = eventType;\n\n // compute scale, rotation etc\n computeInputData(manager, input);\n\n // emit secret event\n manager.emit('hammer.input', input);\n\n manager.recognize(input);\n manager.session.prevInput = input;\n}\n\n/**\n * extend the data with some usable properties like scale, rotate, velocity etc\n * @param {Object} manager\n * @param {Object} input\n */\nfunction computeInputData(manager, input) {\n var session = manager.session;\n var pointers = input.pointers;\n var pointersLength = pointers.length;\n\n // store the first input to calculate the distance and direction\n if (!session.firstInput) {\n session.firstInput = simpleCloneInputData(input);\n }\n\n // to compute scale and rotation we need to store the multiple touches\n if (pointersLength > 1 && !session.firstMultiple) {\n session.firstMultiple = simpleCloneInputData(input);\n } else if (pointersLength === 1) {\n session.firstMultiple = false;\n }\n\n var firstInput = session.firstInput;\n var firstMultiple = session.firstMultiple;\n var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;\n\n var center = input.center = getCenter(pointers);\n input.timeStamp = now();\n input.deltaTime = input.timeStamp - firstInput.timeStamp;\n\n input.angle = getAngle(offsetCenter, center);\n input.distance = getDistance(offsetCenter, center);\n\n computeDeltaXY(session, input);\n input.offsetDirection = getDirection(input.deltaX, input.deltaY);\n\n var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);\n input.overallVelocityX = overallVelocity.x;\n input.overallVelocityY = overallVelocity.y;\n input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;\n\n input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;\n input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;\n\n input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >\n session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);\n\n computeIntervalInputData(session, input);\n\n // find the correct target\n var target = manager.element;\n if (hasParent(input.srcEvent.target, target)) {\n target = input.srcEvent.target;\n }\n input.target = target;\n}\n\nfunction computeDeltaXY(session, input) {\n var center = input.center;\n var offset = session.offsetDelta || {};\n var prevDelta = session.prevDelta || {};\n var prevInput = session.prevInput || {};\n\n if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {\n prevDelta = session.prevDelta = {\n x: prevInput.deltaX || 0,\n y: prevInput.deltaY || 0\n };\n\n offset = session.offsetDelta = {\n x: center.x,\n y: center.y\n };\n }\n\n input.deltaX = prevDelta.x + (center.x - offset.x);\n input.deltaY = prevDelta.y + (center.y - offset.y);\n}\n\n/**\n * velocity is calculated every x ms\n * @param {Object} session\n * @param {Object} input\n */\nfunction computeIntervalInputData(session, input) {\n var last = session.lastInterval || input,\n deltaTime = input.timeStamp - last.timeStamp,\n velocity, velocityX, velocityY, direction;\n\n if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {\n var deltaX = input.deltaX - last.deltaX;\n var deltaY = input.deltaY - last.deltaY;\n\n var v = getVelocity(deltaTime, deltaX, deltaY);\n velocityX = v.x;\n velocityY = v.y;\n velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;\n direction = getDirection(deltaX, deltaY);\n\n session.lastInterval = input;\n } else {\n // use latest velocity info if it doesn't overtake a minimum period\n velocity = last.velocity;\n velocityX = last.velocityX;\n velocityY = last.velocityY;\n direction = last.direction;\n }\n\n input.velocity = velocity;\n input.velocityX = velocityX;\n input.velocityY = velocityY;\n input.direction = direction;\n}\n\n/**\n * create a simple clone from the input used for storage of firstInput and firstMultiple\n * @param {Object} input\n * @returns {Object} clonedInputData\n */\nfunction simpleCloneInputData(input) {\n // make a simple copy of the pointers because we will get a reference if we don't\n // we only need clientXY for the calculations\n var pointers = [];\n var i = 0;\n while (i < input.pointers.length) {\n pointers[i] = {\n clientX: round(input.pointers[i].clientX),\n clientY: round(input.pointers[i].clientY)\n };\n i++;\n }\n\n return {\n timeStamp: now(),\n pointers: pointers,\n center: getCenter(pointers),\n deltaX: input.deltaX,\n deltaY: input.deltaY\n };\n}\n\n/**\n * get the center of all the pointers\n * @param {Array} pointers\n * @return {Object} center contains `x` and `y` properties\n */\nfunction getCenter(pointers) {\n var pointersLength = pointers.length;\n\n // no need to loop when only one touch\n if (pointersLength === 1) {\n return {\n x: round(pointers[0].clientX),\n y: round(pointers[0].clientY)\n };\n }\n\n var x = 0, y = 0, i = 0;\n while (i < pointersLength) {\n x += pointers[i].clientX;\n y += pointers[i].clientY;\n i++;\n }\n\n return {\n x: round(x / pointersLength),\n y: round(y / pointersLength)\n };\n}\n\n/**\n * calculate the velocity between two points. unit is in px per ms.\n * @param {Number} deltaTime\n * @param {Number} x\n * @param {Number} y\n * @return {Object} velocity `x` and `y`\n */\nfunction getVelocity(deltaTime, x, y) {\n return {\n x: x / deltaTime || 0,\n y: y / deltaTime || 0\n };\n}\n\n/**\n * get the direction between two points\n * @param {Number} x\n * @param {Number} y\n * @return {Number} direction\n */\nfunction getDirection(x, y) {\n if (x === y) {\n return DIRECTION_NONE;\n }\n\n if (abs(x) >= abs(y)) {\n return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;\n}\n\n/**\n * calculate the absolute distance between two points\n * @param {Object} p1 {x, y}\n * @param {Object} p2 {x, y}\n * @param {Array} [props] containing x and y keys\n * @return {Number} distance\n */\nfunction getDistance(p1, p2, props) {\n if (!props) {\n props = PROPS_XY;\n }\n var x = p2[props[0]] - p1[props[0]],\n y = p2[props[1]] - p1[props[1]];\n\n return Math.sqrt((x * x) + (y * y));\n}\n\n/**\n * calculate the angle between two coordinates\n * @param {Object} p1\n * @param {Object} p2\n * @param {Array} [props] containing x and y keys\n * @return {Number} angle\n */\nfunction getAngle(p1, p2, props) {\n if (!props) {\n props = PROPS_XY;\n }\n var x = p2[props[0]] - p1[props[0]],\n y = p2[props[1]] - p1[props[1]];\n return Math.atan2(y, x) * 180 / Math.PI;\n}\n\n/**\n * calculate the rotation degrees between two pointersets\n * @param {Array} start array of pointers\n * @param {Array} end array of pointers\n * @return {Number} rotation\n */\nfunction getRotation(start, end) {\n return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);\n}\n\n/**\n * calculate the scale factor between two pointersets\n * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out\n * @param {Array} start array of pointers\n * @param {Array} end array of pointers\n * @return {Number} scale\n */\nfunction getScale(start, end) {\n return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);\n}\n\nvar MOUSE_INPUT_MAP = {\n mousedown: INPUT_START,\n mousemove: INPUT_MOVE,\n mouseup: INPUT_END\n};\n\nvar MOUSE_ELEMENT_EVENTS = 'mousedown';\nvar MOUSE_WINDOW_EVENTS = 'mousemove mouseup';\n\n/**\n * Mouse events input\n * @constructor\n * @extends Input\n */\nfunction MouseInput() {\n this.evEl = MOUSE_ELEMENT_EVENTS;\n this.evWin = MOUSE_WINDOW_EVENTS;\n\n this.pressed = false; // mousedown state\n\n Input.apply(this, arguments);\n}\n\ninherit(MouseInput, Input, {\n /**\n * handle mouse events\n * @param {Object} ev\n */\n handler: function MEhandler(ev) {\n var eventType = MOUSE_INPUT_MAP[ev.type];\n\n // on start we want to have the left mouse button down\n if (eventType & INPUT_START && ev.button === 0) {\n this.pressed = true;\n }\n\n if (eventType & INPUT_MOVE && ev.which !== 1) {\n eventType = INPUT_END;\n }\n\n // mouse must be down\n if (!this.pressed) {\n return;\n }\n\n if (eventType & INPUT_END) {\n this.pressed = false;\n }\n\n this.callback(this.manager, eventType, {\n pointers: [ev],\n changedPointers: [ev],\n pointerType: INPUT_TYPE_MOUSE,\n srcEvent: ev\n });\n }\n});\n\nvar POINTER_INPUT_MAP = {\n pointerdown: INPUT_START,\n pointermove: INPUT_MOVE,\n pointerup: INPUT_END,\n pointercancel: INPUT_CANCEL,\n pointerout: INPUT_CANCEL\n};\n\n// in IE10 the pointer types is defined as an enum\nvar IE10_POINTER_TYPE_ENUM = {\n 2: INPUT_TYPE_TOUCH,\n 3: INPUT_TYPE_PEN,\n 4: INPUT_TYPE_MOUSE,\n 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816\n};\n\nvar POINTER_ELEMENT_EVENTS = 'pointerdown';\nvar POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';\n\n// IE10 has prefixed support, and case-sensitive\nif (window.MSPointerEvent && !window.PointerEvent) {\n POINTER_ELEMENT_EVENTS = 'MSPointerDown';\n POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';\n}\n\n/**\n * Pointer events input\n * @constructor\n * @extends Input\n */\nfunction PointerEventInput() {\n this.evEl = POINTER_ELEMENT_EVENTS;\n this.evWin = POINTER_WINDOW_EVENTS;\n\n Input.apply(this, arguments);\n\n this.store = (this.manager.session.pointerEvents = []);\n}\n\ninherit(PointerEventInput, Input, {\n /**\n * handle mouse events\n * @param {Object} ev\n */\n handler: function PEhandler(ev) {\n var store = this.store;\n var removePointer = false;\n\n var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');\n var eventType = POINTER_INPUT_MAP[eventTypeNormalized];\n var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;\n\n var isTouch = (pointerType == INPUT_TYPE_TOUCH);\n\n // get index of the event in the store\n var storeIndex = inArray(store, ev.pointerId, 'pointerId');\n\n // start and mouse must be down\n if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {\n if (storeIndex < 0) {\n store.push(ev);\n storeIndex = store.length - 1;\n }\n } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n removePointer = true;\n }\n\n // it not found, so the pointer hasn't been down (so it's probably a hover)\n if (storeIndex < 0) {\n return;\n }\n\n // update the event in the store\n store[storeIndex] = ev;\n\n this.callback(this.manager, eventType, {\n pointers: store,\n changedPointers: [ev],\n pointerType: pointerType,\n srcEvent: ev\n });\n\n if (removePointer) {\n // remove from the store\n store.splice(storeIndex, 1);\n }\n }\n});\n\nvar SINGLE_TOUCH_INPUT_MAP = {\n touchstart: INPUT_START,\n touchmove: INPUT_MOVE,\n touchend: INPUT_END,\n touchcancel: INPUT_CANCEL\n};\n\nvar SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';\nvar SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';\n\n/**\n * Touch events input\n * @constructor\n * @extends Input\n */\nfunction SingleTouchInput() {\n this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;\n this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;\n this.started = false;\n\n Input.apply(this, arguments);\n}\n\ninherit(SingleTouchInput, Input, {\n handler: function TEhandler(ev) {\n var type = SINGLE_TOUCH_INPUT_MAP[ev.type];\n\n // should we handle the touch events?\n if (type === INPUT_START) {\n this.started = true;\n }\n\n if (!this.started) {\n return;\n }\n\n var touches = normalizeSingleTouches.call(this, ev, type);\n\n // when done, reset the started state\n if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {\n this.started = false;\n }\n\n this.callback(this.manager, type, {\n pointers: touches[0],\n changedPointers: touches[1],\n pointerType: INPUT_TYPE_TOUCH,\n srcEvent: ev\n });\n }\n});\n\n/**\n * @this {TouchInput}\n * @param {Object} ev\n * @param {Number} type flag\n * @returns {undefined|Array} [all, changed]\n */\nfunction normalizeSingleTouches(ev, type) {\n var all = toArray(ev.touches);\n var changed = toArray(ev.changedTouches);\n\n if (type & (INPUT_END | INPUT_CANCEL)) {\n all = uniqueArray(all.concat(changed), 'identifier', true);\n }\n\n return [all, changed];\n}\n\nvar TOUCH_INPUT_MAP = {\n touchstart: INPUT_START,\n touchmove: INPUT_MOVE,\n touchend: INPUT_END,\n touchcancel: INPUT_CANCEL\n};\n\nvar TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';\n\n/**\n * Multi-user touch events input\n * @constructor\n * @extends Input\n */\nfunction TouchInput() {\n this.evTarget = TOUCH_TARGET_EVENTS;\n this.targetIds = {};\n\n Input.apply(this, arguments);\n}\n\ninherit(TouchInput, Input, {\n handler: function MTEhandler(ev) {\n var type = TOUCH_INPUT_MAP[ev.type];\n var touches = getTouches.call(this, ev, type);\n if (!touches) {\n return;\n }\n\n this.callback(this.manager, type, {\n pointers: touches[0],\n changedPointers: touches[1],\n pointerType: INPUT_TYPE_TOUCH,\n srcEvent: ev\n });\n }\n});\n\n/**\n * @this {TouchInput}\n * @param {Object} ev\n * @param {Number} type flag\n * @returns {undefined|Array} [all, changed]\n */\nfunction getTouches(ev, type) {\n var allTouches = toArray(ev.touches);\n var targetIds = this.targetIds;\n\n // when there is only one touch, the process can be simplified\n if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {\n targetIds[allTouches[0].identifier] = true;\n return [allTouches, allTouches];\n }\n\n var i,\n targetTouches,\n changedTouches = toArray(ev.changedTouches),\n changedTargetTouches = [],\n target = this.target;\n\n // get target touches from touches\n targetTouches = allTouches.filter(function(touch) {\n return hasParent(touch.target, target);\n });\n\n // collect touches\n if (type === INPUT_START) {\n i = 0;\n while (i < targetTouches.length) {\n targetIds[targetTouches[i].identifier] = true;\n i++;\n }\n }\n\n // filter changed touches to only contain touches that exist in the collected target ids\n i = 0;\n while (i < changedTouches.length) {\n if (targetIds[changedTouches[i].identifier]) {\n changedTargetTouches.push(changedTouches[i]);\n }\n\n // cleanup removed touches\n if (type & (INPUT_END | INPUT_CANCEL)) {\n delete targetIds[changedTouches[i].identifier];\n }\n i++;\n }\n\n if (!changedTargetTouches.length) {\n return;\n }\n\n return [\n // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'\n uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),\n changedTargetTouches\n ];\n}\n\n/**\n * Combined touch and mouse input\n *\n * Touch has a higher priority then mouse, and while touching no mouse events are allowed.\n * This because touch devices also emit mouse events while doing a touch.\n *\n * @constructor\n * @extends Input\n */\n\nvar DEDUP_TIMEOUT = 2500;\nvar DEDUP_DISTANCE = 25;\n\nfunction TouchMouseInput() {\n Input.apply(this, arguments);\n\n var handler = bindFn(this.handler, this);\n this.touch = new TouchInput(this.manager, handler);\n this.mouse = new MouseInput(this.manager, handler);\n\n this.primaryTouch = null;\n this.lastTouches = [];\n}\n\ninherit(TouchMouseInput, Input, {\n /**\n * handle mouse and touch events\n * @param {Hammer} manager\n * @param {String} inputEvent\n * @param {Object} inputData\n */\n handler: function TMEhandler(manager, inputEvent, inputData) {\n var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),\n isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);\n\n if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {\n return;\n }\n\n // when we're in a touch event, record touches to de-dupe synthetic mouse event\n if (isTouch) {\n recordTouches.call(this, inputEvent, inputData);\n } else if (isMouse && isSyntheticEvent.call(this, inputData)) {\n return;\n }\n\n this.callback(manager, inputEvent, inputData);\n },\n\n /**\n * remove the event listeners\n */\n destroy: function destroy() {\n this.touch.destroy();\n this.mouse.destroy();\n }\n});\n\nfunction recordTouches(eventType, eventData) {\n if (eventType & INPUT_START) {\n this.primaryTouch = eventData.changedPointers[0].identifier;\n setLastTouch.call(this, eventData);\n } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n setLastTouch.call(this, eventData);\n }\n}\n\nfunction setLastTouch(eventData) {\n var touch = eventData.changedPointers[0];\n\n if (touch.identifier === this.primaryTouch) {\n var lastTouch = {x: touch.clientX, y: touch.clientY};\n this.lastTouches.push(lastTouch);\n var lts = this.lastTouches;\n var removeLastTouch = function() {\n var i = lts.indexOf(lastTouch);\n if (i > -1) {\n lts.splice(i, 1);\n }\n };\n setTimeout(removeLastTouch, DEDUP_TIMEOUT);\n }\n}\n\nfunction isSyntheticEvent(eventData) {\n var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;\n for (var i = 0; i < this.lastTouches.length; i++) {\n var t = this.lastTouches[i];\n var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {\n return true;\n }\n }\n return false;\n}\n\nvar PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');\nvar NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;\n\n// magical touchAction value\nvar TOUCH_ACTION_COMPUTE = 'compute';\nvar TOUCH_ACTION_AUTO = 'auto';\nvar TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented\nvar TOUCH_ACTION_NONE = 'none';\nvar TOUCH_ACTION_PAN_X = 'pan-x';\nvar TOUCH_ACTION_PAN_Y = 'pan-y';\nvar TOUCH_ACTION_MAP = getTouchActionProps();\n\n/**\n * Touch Action\n * sets the touchAction property or uses the js alternative\n * @param {Manager} manager\n * @param {String} value\n * @constructor\n */\nfunction TouchAction(manager, value) {\n this.manager = manager;\n this.set(value);\n}\n\nTouchAction.prototype = {\n /**\n * set the touchAction value on the element or enable the polyfill\n * @param {String} value\n */\n set: function(value) {\n // find out the touch-action by the event handlers\n if (value == TOUCH_ACTION_COMPUTE) {\n value = this.compute();\n }\n\n if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {\n this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;\n }\n this.actions = value.toLowerCase().trim();\n },\n\n /**\n * just re-set the touchAction value\n */\n update: function() {\n this.set(this.manager.options.touchAction);\n },\n\n /**\n * compute the value for the touchAction property based on the recognizer's settings\n * @returns {String} value\n */\n compute: function() {\n var actions = [];\n each(this.manager.recognizers, function(recognizer) {\n if (boolOrFn(recognizer.options.enable, [recognizer])) {\n actions = actions.concat(recognizer.getTouchAction());\n }\n });\n return cleanTouchActions(actions.join(' '));\n },\n\n /**\n * this method is called on each input cycle and provides the preventing of the browser behavior\n * @param {Object} input\n */\n preventDefaults: function(input) {\n var srcEvent = input.srcEvent;\n var direction = input.offsetDirection;\n\n // if the touch action did prevented once this session\n if (this.manager.session.prevented) {\n srcEvent.preventDefault();\n return;\n }\n\n var actions = this.actions;\n var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];\n var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];\n var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];\n\n if (hasNone) {\n //do not prevent defaults if this is a tap gesture\n\n var isTapPointer = input.pointers.length === 1;\n var isTapMovement = input.distance < 2;\n var isTapTouchTime = input.deltaTime < 250;\n\n if (isTapPointer && isTapMovement && isTapTouchTime) {\n return;\n }\n }\n\n if (hasPanX && hasPanY) {\n // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent\n return;\n }\n\n if (hasNone ||\n (hasPanY && direction & DIRECTION_HORIZONTAL) ||\n (hasPanX && direction & DIRECTION_VERTICAL)) {\n return this.preventSrc(srcEvent);\n }\n },\n\n /**\n * call preventDefault to prevent the browser's default behavior (scrolling in most cases)\n * @param {Object} srcEvent\n */\n preventSrc: function(srcEvent) {\n this.manager.session.prevented = true;\n srcEvent.preventDefault();\n }\n};\n\n/**\n * when the touchActions are collected they are not a valid value, so we need to clean things up. *\n * @param {String} actions\n * @returns {*}\n */\nfunction cleanTouchActions(actions) {\n // none\n if (inStr(actions, TOUCH_ACTION_NONE)) {\n return TOUCH_ACTION_NONE;\n }\n\n var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);\n var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);\n\n // if both pan-x and pan-y are set (different recognizers\n // for different directions, e.g. horizontal pan but vertical swipe?)\n // we need none (as otherwise with pan-x pan-y combined none of these\n // recognizers will work, since the browser would handle all panning\n if (hasPanX && hasPanY) {\n return TOUCH_ACTION_NONE;\n }\n\n // pan-x OR pan-y\n if (hasPanX || hasPanY) {\n return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;\n }\n\n // manipulation\n if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {\n return TOUCH_ACTION_MANIPULATION;\n }\n\n return TOUCH_ACTION_AUTO;\n}\n\nfunction getTouchActionProps() {\n if (!NATIVE_TOUCH_ACTION) {\n return false;\n }\n var touchMap = {};\n var cssSupports = window.CSS && window.CSS.supports;\n ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {\n\n // If css.supports is not supported but there is native touch-action assume it supports\n // all values. This is the case for IE 10 and 11.\n touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;\n });\n return touchMap;\n}\n\n/**\n * Recognizer flow explained; *\n * All recognizers have the initial state of POSSIBLE when a input session starts.\n * The definition of a input session is from the first input until the last input, with all it's movement in it. *\n * Example session for mouse-input: mousedown -> mousemove -> mouseup\n *\n * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed\n * which determines with state it should be.\n *\n * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to\n * POSSIBLE to give it another change on the next cycle.\n *\n * Possible\n * |\n * +-----+---------------+\n * | |\n * +-----+-----+ |\n * | | |\n * Failed Cancelled |\n * +-------+------+\n * | |\n * Recognized Began\n * |\n * Changed\n * |\n * Ended/Recognized\n */\nvar STATE_POSSIBLE = 1;\nvar STATE_BEGAN = 2;\nvar STATE_CHANGED = 4;\nvar STATE_ENDED = 8;\nvar STATE_RECOGNIZED = STATE_ENDED;\nvar STATE_CANCELLED = 16;\nvar STATE_FAILED = 32;\n\n/**\n * Recognizer\n * Every recognizer needs to extend from this class.\n * @constructor\n * @param {Object} options\n */\nfunction Recognizer(options) {\n this.options = assign({}, this.defaults, options || {});\n\n this.id = uniqueId();\n\n this.manager = null;\n\n // default is enable true\n this.options.enable = ifUndefined(this.options.enable, true);\n\n this.state = STATE_POSSIBLE;\n\n this.simultaneous = {};\n this.requireFail = [];\n}\n\nRecognizer.prototype = {\n /**\n * @virtual\n * @type {Object}\n */\n defaults: {},\n\n /**\n * set options\n * @param {Object} options\n * @return {Recognizer}\n */\n set: function(options) {\n assign(this.options, options);\n\n // also update the touchAction, in case something changed about the directions/enabled state\n this.manager && this.manager.touchAction.update();\n return this;\n },\n\n /**\n * recognize simultaneous with an other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n recognizeWith: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {\n return this;\n }\n\n var simultaneous = this.simultaneous;\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n if (!simultaneous[otherRecognizer.id]) {\n simultaneous[otherRecognizer.id] = otherRecognizer;\n otherRecognizer.recognizeWith(this);\n }\n return this;\n },\n\n /**\n * drop the simultaneous link. it doesnt remove the link on the other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n dropRecognizeWith: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {\n return this;\n }\n\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n delete this.simultaneous[otherRecognizer.id];\n return this;\n },\n\n /**\n * recognizer can only run when an other is failing\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n requireFailure: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {\n return this;\n }\n\n var requireFail = this.requireFail;\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n if (inArray(requireFail, otherRecognizer) === -1) {\n requireFail.push(otherRecognizer);\n otherRecognizer.requireFailure(this);\n }\n return this;\n },\n\n /**\n * drop the requireFailure link. it does not remove the link on the other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n dropRequireFailure: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {\n return this;\n }\n\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n var index = inArray(this.requireFail, otherRecognizer);\n if (index > -1) {\n this.requireFail.splice(index, 1);\n }\n return this;\n },\n\n /**\n * has require failures boolean\n * @returns {boolean}\n */\n hasRequireFailures: function() {\n return this.requireFail.length > 0;\n },\n\n /**\n * if the recognizer can recognize simultaneous with an other recognizer\n * @param {Recognizer} otherRecognizer\n * @returns {Boolean}\n */\n canRecognizeWith: function(otherRecognizer) {\n return !!this.simultaneous[otherRecognizer.id];\n },\n\n /**\n * You should use `tryEmit` instead of `emit` directly to check\n * that all the needed recognizers has failed before emitting.\n * @param {Object} input\n */\n emit: function(input) {\n var self = this;\n var state = this.state;\n\n function emit(event) {\n self.manager.emit(event, input);\n }\n\n // 'panstart' and 'panmove'\n if (state < STATE_ENDED) {\n emit(self.options.event + stateStr(state));\n }\n\n emit(self.options.event); // simple 'eventName' events\n\n if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)\n emit(input.additionalEvent);\n }\n\n // panend and pancancel\n if (state >= STATE_ENDED) {\n emit(self.options.event + stateStr(state));\n }\n },\n\n /**\n * Check that all the require failure recognizers has failed,\n * if true, it emits a gesture event,\n * otherwise, setup the state to FAILED.\n * @param {Object} input\n */\n tryEmit: function(input) {\n if (this.canEmit()) {\n return this.emit(input);\n }\n // it's failing anyway\n this.state = STATE_FAILED;\n },\n\n /**\n * can we emit?\n * @returns {boolean}\n */\n canEmit: function() {\n var i = 0;\n while (i < this.requireFail.length) {\n if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {\n return false;\n }\n i++;\n }\n return true;\n },\n\n /**\n * update the recognizer\n * @param {Object} inputData\n */\n recognize: function(inputData) {\n // make a new copy of the inputData\n // so we can change the inputData without messing up the other recognizers\n var inputDataClone = assign({}, inputData);\n\n // is is enabled and allow recognizing?\n if (!boolOrFn(this.options.enable, [this, inputDataClone])) {\n this.reset();\n this.state = STATE_FAILED;\n return;\n }\n\n // reset when we've reached the end\n if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {\n this.state = STATE_POSSIBLE;\n }\n\n this.state = this.process(inputDataClone);\n\n // the recognizer has recognized a gesture\n // so trigger an event\n if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {\n this.tryEmit(inputDataClone);\n }\n },\n\n /**\n * return the state of the recognizer\n * the actual recognizing happens in this method\n * @virtual\n * @param {Object} inputData\n * @returns {Const} STATE\n */\n process: function(inputData) { }, // jshint ignore:line\n\n /**\n * return the preferred touch-action\n * @virtual\n * @returns {Array}\n */\n getTouchAction: function() { },\n\n /**\n * called when the gesture isn't allowed to recognize\n * like when another is being recognized or it is disabled\n * @virtual\n */\n reset: function() { }\n};\n\n/**\n * get a usable string, used as event postfix\n * @param {Const} state\n * @returns {String} state\n */\nfunction stateStr(state) {\n if (state & STATE_CANCELLED) {\n return 'cancel';\n } else if (state & STATE_ENDED) {\n return 'end';\n } else if (state & STATE_CHANGED) {\n return 'move';\n } else if (state & STATE_BEGAN) {\n return 'start';\n }\n return '';\n}\n\n/**\n * direction cons to string\n * @param {Const} direction\n * @returns {String}\n */\nfunction directionStr(direction) {\n if (direction == DIRECTION_DOWN) {\n return 'down';\n } else if (direction == DIRECTION_UP) {\n return 'up';\n } else if (direction == DIRECTION_LEFT) {\n return 'left';\n } else if (direction == DIRECTION_RIGHT) {\n return 'right';\n }\n return '';\n}\n\n/**\n * get a recognizer by name if it is bound to a manager\n * @param {Recognizer|String} otherRecognizer\n * @param {Recognizer} recognizer\n * @returns {Recognizer}\n */\nfunction getRecognizerByNameIfManager(otherRecognizer, recognizer) {\n var manager = recognizer.manager;\n if (manager) {\n return manager.get(otherRecognizer);\n }\n return otherRecognizer;\n}\n\n/**\n * This recognizer is just used as a base for the simple attribute recognizers.\n * @constructor\n * @extends Recognizer\n */\nfunction AttrRecognizer() {\n Recognizer.apply(this, arguments);\n}\n\ninherit(AttrRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof AttrRecognizer\n */\n defaults: {\n /**\n * @type {Number}\n * @default 1\n */\n pointers: 1\n },\n\n /**\n * Used to check if it the recognizer receives valid input, like input.distance > 10.\n * @memberof AttrRecognizer\n * @param {Object} input\n * @returns {Boolean} recognized\n */\n attrTest: function(input) {\n var optionPointers = this.options.pointers;\n return optionPointers === 0 || input.pointers.length === optionPointers;\n },\n\n /**\n * Process the input and return the state for the recognizer\n * @memberof AttrRecognizer\n * @param {Object} input\n * @returns {*} State\n */\n process: function(input) {\n var state = this.state;\n var eventType = input.eventType;\n\n var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);\n var isValid = this.attrTest(input);\n\n // on cancel input and we've recognized before, return STATE_CANCELLED\n if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {\n return state | STATE_CANCELLED;\n } else if (isRecognized || isValid) {\n if (eventType & INPUT_END) {\n return state | STATE_ENDED;\n } else if (!(state & STATE_BEGAN)) {\n return STATE_BEGAN;\n }\n return state | STATE_CHANGED;\n }\n return STATE_FAILED;\n }\n});\n\n/**\n * Pan\n * Recognized when the pointer is down and moved in the allowed direction.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction PanRecognizer() {\n AttrRecognizer.apply(this, arguments);\n\n this.pX = null;\n this.pY = null;\n}\n\ninherit(PanRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof PanRecognizer\n */\n defaults: {\n event: 'pan',\n threshold: 10,\n pointers: 1,\n direction: DIRECTION_ALL\n },\n\n getTouchAction: function() {\n var direction = this.options.direction;\n var actions = [];\n if (direction & DIRECTION_HORIZONTAL) {\n actions.push(TOUCH_ACTION_PAN_Y);\n }\n if (direction & DIRECTION_VERTICAL) {\n actions.push(TOUCH_ACTION_PAN_X);\n }\n return actions;\n },\n\n directionTest: function(input) {\n var options = this.options;\n var hasMoved = true;\n var distance = input.distance;\n var direction = input.direction;\n var x = input.deltaX;\n var y = input.deltaY;\n\n // lock to axis?\n if (!(direction & options.direction)) {\n if (options.direction & DIRECTION_HORIZONTAL) {\n direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;\n hasMoved = x != this.pX;\n distance = Math.abs(input.deltaX);\n } else {\n direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;\n hasMoved = y != this.pY;\n distance = Math.abs(input.deltaY);\n }\n }\n input.direction = direction;\n return hasMoved && distance > options.threshold && direction & options.direction;\n },\n\n attrTest: function(input) {\n return AttrRecognizer.prototype.attrTest.call(this, input) &&\n (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));\n },\n\n emit: function(input) {\n\n this.pX = input.deltaX;\n this.pY = input.deltaY;\n\n var direction = directionStr(input.direction);\n\n if (direction) {\n input.additionalEvent = this.options.event + direction;\n }\n this._super.emit.call(this, input);\n }\n});\n\n/**\n * Pinch\n * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).\n * @constructor\n * @extends AttrRecognizer\n */\nfunction PinchRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(PinchRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof PinchRecognizer\n */\n defaults: {\n event: 'pinch',\n threshold: 0,\n pointers: 2\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_NONE];\n },\n\n attrTest: function(input) {\n return this._super.attrTest.call(this, input) &&\n (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);\n },\n\n emit: function(input) {\n if (input.scale !== 1) {\n var inOut = input.scale < 1 ? 'in' : 'out';\n input.additionalEvent = this.options.event + inOut;\n }\n this._super.emit.call(this, input);\n }\n});\n\n/**\n * Press\n * Recognized when the pointer is down for x ms without any movement.\n * @constructor\n * @extends Recognizer\n */\nfunction PressRecognizer() {\n Recognizer.apply(this, arguments);\n\n this._timer = null;\n this._input = null;\n}\n\ninherit(PressRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof PressRecognizer\n */\n defaults: {\n event: 'press',\n pointers: 1,\n time: 251, // minimal time of the pointer to be pressed\n threshold: 9 // a minimal movement is ok, but keep it low\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_AUTO];\n },\n\n process: function(input) {\n var options = this.options;\n var validPointers = input.pointers.length === options.pointers;\n var validMovement = input.distance < options.threshold;\n var validTime = input.deltaTime > options.time;\n\n this._input = input;\n\n // we only allow little movement\n // and we've reached an end event, so a tap is possible\n if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {\n this.reset();\n } else if (input.eventType & INPUT_START) {\n this.reset();\n this._timer = setTimeoutContext(function() {\n this.state = STATE_RECOGNIZED;\n this.tryEmit();\n }, options.time, this);\n } else if (input.eventType & INPUT_END) {\n return STATE_RECOGNIZED;\n }\n return STATE_FAILED;\n },\n\n reset: function() {\n clearTimeout(this._timer);\n },\n\n emit: function(input) {\n if (this.state !== STATE_RECOGNIZED) {\n return;\n }\n\n if (input && (input.eventType & INPUT_END)) {\n this.manager.emit(this.options.event + 'up', input);\n } else {\n this._input.timeStamp = now();\n this.manager.emit(this.options.event, this._input);\n }\n }\n});\n\n/**\n * Rotate\n * Recognized when two or more pointer are moving in a circular motion.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction RotateRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(RotateRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof RotateRecognizer\n */\n defaults: {\n event: 'rotate',\n threshold: 0,\n pointers: 2\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_NONE];\n },\n\n attrTest: function(input) {\n return this._super.attrTest.call(this, input) &&\n (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);\n }\n});\n\n/**\n * Swipe\n * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction SwipeRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(SwipeRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof SwipeRecognizer\n */\n defaults: {\n event: 'swipe',\n threshold: 10,\n velocity: 0.3,\n direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,\n pointers: 1\n },\n\n getTouchAction: function() {\n return PanRecognizer.prototype.getTouchAction.call(this);\n },\n\n attrTest: function(input) {\n var direction = this.options.direction;\n var velocity;\n\n if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {\n velocity = input.overallVelocity;\n } else if (direction & DIRECTION_HORIZONTAL) {\n velocity = input.overallVelocityX;\n } else if (direction & DIRECTION_VERTICAL) {\n velocity = input.overallVelocityY;\n }\n\n return this._super.attrTest.call(this, input) &&\n direction & input.offsetDirection &&\n input.distance > this.options.threshold &&\n input.maxPointers == this.options.pointers &&\n abs(velocity) > this.options.velocity && input.eventType & INPUT_END;\n },\n\n emit: function(input) {\n var direction = directionStr(input.offsetDirection);\n if (direction) {\n this.manager.emit(this.options.event + direction, input);\n }\n\n this.manager.emit(this.options.event, input);\n }\n});\n\n/**\n * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur\n * between the given interval and position. The delay option can be used to recognize multi-taps without firing\n * a single tap.\n *\n * The eventData from the emitted event contains the property `tapCount`, which contains the amount of\n * multi-taps being recognized.\n * @constructor\n * @extends Recognizer\n */\nfunction TapRecognizer() {\n Recognizer.apply(this, arguments);\n\n // previous time and center,\n // used for tap counting\n this.pTime = false;\n this.pCenter = false;\n\n this._timer = null;\n this._input = null;\n this.count = 0;\n}\n\ninherit(TapRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof PinchRecognizer\n */\n defaults: {\n event: 'tap',\n pointers: 1,\n taps: 1,\n interval: 300, // max time between the multi-tap taps\n time: 250, // max time of the pointer to be down (like finger on the screen)\n threshold: 9, // a minimal movement is ok, but keep it low\n posThreshold: 10 // a multi-tap can be a bit off the initial position\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_MANIPULATION];\n },\n\n process: function(input) {\n var options = this.options;\n\n var validPointers = input.pointers.length === options.pointers;\n var validMovement = input.distance < options.threshold;\n var validTouchTime = input.deltaTime < options.time;\n\n this.reset();\n\n if ((input.eventType & INPUT_START) && (this.count === 0)) {\n return this.failTimeout();\n }\n\n // we only allow little movement\n // and we've reached an end event, so a tap is possible\n if (validMovement && validTouchTime && validPointers) {\n if (input.eventType != INPUT_END) {\n return this.failTimeout();\n }\n\n var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;\n var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;\n\n this.pTime = input.timeStamp;\n this.pCenter = input.center;\n\n if (!validMultiTap || !validInterval) {\n this.count = 1;\n } else {\n this.count += 1;\n }\n\n this._input = input;\n\n // if tap count matches we have recognized it,\n // else it has began recognizing...\n var tapCount = this.count % options.taps;\n if (tapCount === 0) {\n // no failing requirements, immediately trigger the tap event\n // or wait as long as the multitap interval to trigger\n if (!this.hasRequireFailures()) {\n return STATE_RECOGNIZED;\n } else {\n this._timer = setTimeoutContext(function() {\n this.state = STATE_RECOGNIZED;\n this.tryEmit();\n }, options.interval, this);\n return STATE_BEGAN;\n }\n }\n }\n return STATE_FAILED;\n },\n\n failTimeout: function() {\n this._timer = setTimeoutContext(function() {\n this.state = STATE_FAILED;\n }, this.options.interval, this);\n return STATE_FAILED;\n },\n\n reset: function() {\n clearTimeout(this._timer);\n },\n\n emit: function() {\n if (this.state == STATE_RECOGNIZED) {\n this._input.tapCount = this.count;\n this.manager.emit(this.options.event, this._input);\n }\n }\n});\n\n/**\n * Simple way to create a manager with a default set of recognizers.\n * @param {HTMLElement} element\n * @param {Object} [options]\n * @constructor\n */\nfunction Hammer(element, options) {\n options = options || {};\n options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);\n return new Manager(element, options);\n}\n\n/**\n * @const {string}\n */\nHammer.VERSION = '2.0.7';\n\n/**\n * default settings\n * @namespace\n */\nHammer.defaults = {\n /**\n * set if DOM events are being triggered.\n * But this is slower and unused by simple implementations, so disabled by default.\n * @type {Boolean}\n * @default false\n */\n domEvents: false,\n\n /**\n * The value for the touchAction property/fallback.\n * When set to `compute` it will magically set the correct value based on the added recognizers.\n * @type {String}\n * @default compute\n */\n touchAction: TOUCH_ACTION_COMPUTE,\n\n /**\n * @type {Boolean}\n * @default true\n */\n enable: true,\n\n /**\n * EXPERIMENTAL FEATURE -- can be removed/changed\n * Change the parent input target element.\n * If Null, then it is being set the to main element.\n * @type {Null|EventTarget}\n * @default null\n */\n inputTarget: null,\n\n /**\n * force an input class\n * @type {Null|Function}\n * @default null\n */\n inputClass: null,\n\n /**\n * Default recognizer setup when calling `Hammer()`\n * When creating a new Manager these will be skipped.\n * @type {Array}\n */\n preset: [\n // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]\n [RotateRecognizer, {enable: false}],\n [PinchRecognizer, {enable: false}, ['rotate']],\n [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],\n [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],\n [TapRecognizer],\n [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],\n [PressRecognizer]\n ],\n\n /**\n * Some CSS properties can be used to improve the working of Hammer.\n * Add them to this method and they will be set when creating a new Manager.\n * @namespace\n */\n cssProps: {\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n * @type {String}\n * @default 'none'\n */\n userSelect: 'none',\n\n /**\n * Disable the Windows Phone grippers when pressing an element.\n * @type {String}\n * @default 'none'\n */\n touchSelect: 'none',\n\n /**\n * Disables the default callout shown when you touch and hold a touch target.\n * On iOS, when you touch and hold a touch target such as a link, Safari displays\n * a callout containing information about the link. This property allows you to disable that callout.\n * @type {String}\n * @default 'none'\n */\n touchCallout: 'none',\n\n /**\n * Specifies whether zooming is enabled. Used by IE10>\n * @type {String}\n * @default 'none'\n */\n contentZooming: 'none',\n\n /**\n * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.\n * @type {String}\n * @default 'none'\n */\n userDrag: 'none',\n\n /**\n * Overrides the highlight color shown when the user taps a link or a JavaScript\n * clickable element in iOS. This property obeys the alpha value, if specified.\n * @type {String}\n * @default 'rgba(0,0,0,0)'\n */\n tapHighlightColor: 'rgba(0,0,0,0)'\n }\n};\n\nvar STOP = 1;\nvar FORCED_STOP = 2;\n\n/**\n * Manager\n * @param {HTMLElement} element\n * @param {Object} [options]\n * @constructor\n */\nfunction Manager(element, options) {\n this.options = assign({}, Hammer.defaults, options || {});\n\n this.options.inputTarget = this.options.inputTarget || element;\n\n this.handlers = {};\n this.session = {};\n this.recognizers = [];\n this.oldCssProps = {};\n\n this.element = element;\n this.input = createInputInstance(this);\n this.touchAction = new TouchAction(this, this.options.touchAction);\n\n toggleCssProps(this, true);\n\n each(this.options.recognizers, function(item) {\n var recognizer = this.add(new (item[0])(item[1]));\n item[2] && recognizer.recognizeWith(item[2]);\n item[3] && recognizer.requireFailure(item[3]);\n }, this);\n}\n\nManager.prototype = {\n /**\n * set options\n * @param {Object} options\n * @returns {Manager}\n */\n set: function(options) {\n assign(this.options, options);\n\n // Options that need a little more setup\n if (options.touchAction) {\n this.touchAction.update();\n }\n if (options.inputTarget) {\n // Clean up existing event listeners and reinitialize\n this.input.destroy();\n this.input.target = options.inputTarget;\n this.input.init();\n }\n return this;\n },\n\n /**\n * stop recognizing for this session.\n * This session will be discarded, when a new [input]start event is fired.\n * When forced, the recognizer cycle is stopped immediately.\n * @param {Boolean} [force]\n */\n stop: function(force) {\n this.session.stopped = force ? FORCED_STOP : STOP;\n },\n\n /**\n * run the recognizers!\n * called by the inputHandler function on every movement of the pointers (touches)\n * it walks through all the recognizers and tries to detect the gesture that is being made\n * @param {Object} inputData\n */\n recognize: function(inputData) {\n var session = this.session;\n if (session.stopped) {\n return;\n }\n\n // run the touch-action polyfill\n this.touchAction.preventDefaults(inputData);\n\n var recognizer;\n var recognizers = this.recognizers;\n\n // this holds the recognizer that is being recognized.\n // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED\n // if no recognizer is detecting a thing, it is set to `null`\n var curRecognizer = session.curRecognizer;\n\n // reset when the last recognizer is recognized\n // or when we're in a new session\n if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {\n curRecognizer = session.curRecognizer = null;\n }\n\n var i = 0;\n while (i < recognizers.length) {\n recognizer = recognizers[i];\n\n // find out if we are allowed try to recognize the input for this one.\n // 1. allow if the session is NOT forced stopped (see the .stop() method)\n // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one\n // that is being recognized.\n // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.\n // this can be setup with the `recognizeWith()` method on the recognizer.\n if (session.stopped !== FORCED_STOP && ( // 1\n !curRecognizer || recognizer == curRecognizer || // 2\n recognizer.canRecognizeWith(curRecognizer))) { // 3\n recognizer.recognize(inputData);\n } else {\n recognizer.reset();\n }\n\n // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the\n // current active recognizer. but only if we don't already have an active recognizer\n if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {\n curRecognizer = session.curRecognizer = recognizer;\n }\n i++;\n }\n },\n\n /**\n * get a recognizer by its event name.\n * @param {Recognizer|String} recognizer\n * @returns {Recognizer|Null}\n */\n get: function(recognizer) {\n if (recognizer instanceof Recognizer) {\n return recognizer;\n }\n\n var recognizers = this.recognizers;\n for (var i = 0; i < recognizers.length; i++) {\n if (recognizers[i].options.event == recognizer) {\n return recognizers[i];\n }\n }\n return null;\n },\n\n /**\n * add a recognizer to the manager\n * existing recognizers with the same event name will be removed\n * @param {Recognizer} recognizer\n * @returns {Recognizer|Manager}\n */\n add: function(recognizer) {\n if (invokeArrayArg(recognizer, 'add', this)) {\n return this;\n }\n\n // remove existing\n var existing = this.get(recognizer.options.event);\n if (existing) {\n this.remove(existing);\n }\n\n this.recognizers.push(recognizer);\n recognizer.manager = this;\n\n this.touchAction.update();\n return recognizer;\n },\n\n /**\n * remove a recognizer by name or instance\n * @param {Recognizer|String} recognizer\n * @returns {Manager}\n */\n remove: function(recognizer) {\n if (invokeArrayArg(recognizer, 'remove', this)) {\n return this;\n }\n\n recognizer = this.get(recognizer);\n\n // let's make sure this recognizer exists\n if (recognizer) {\n var recognizers = this.recognizers;\n var index = inArray(recognizers, recognizer);\n\n if (index !== -1) {\n recognizers.splice(index, 1);\n this.touchAction.update();\n }\n }\n\n return this;\n },\n\n /**\n * bind event\n * @param {String} events\n * @param {Function} handler\n * @returns {EventEmitter} this\n */\n on: function(events, handler) {\n if (events === undefined) {\n return;\n }\n if (handler === undefined) {\n return;\n }\n\n var handlers = this.handlers;\n each(splitStr(events), function(event) {\n handlers[event] = handlers[event] || [];\n handlers[event].push(handler);\n });\n return this;\n },\n\n /**\n * unbind event, leave emit blank to remove all handlers\n * @param {String} events\n * @param {Function} [handler]\n * @returns {EventEmitter} this\n */\n off: function(events, handler) {\n if (events === undefined) {\n return;\n }\n\n var handlers = this.handlers;\n each(splitStr(events), function(event) {\n if (!handler) {\n delete handlers[event];\n } else {\n handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);\n }\n });\n return this;\n },\n\n /**\n * emit event to the listeners\n * @param {String} event\n * @param {Object} data\n */\n emit: function(event, data) {\n // we also want to trigger dom events\n if (this.options.domEvents) {\n triggerDomEvent(event, data);\n }\n\n // no handlers, so skip it all\n var handlers = this.handlers[event] && this.handlers[event].slice();\n if (!handlers || !handlers.length) {\n return;\n }\n\n data.type = event;\n data.preventDefault = function() {\n data.srcEvent.preventDefault();\n };\n\n var i = 0;\n while (i < handlers.length) {\n handlers[i](data);\n i++;\n }\n },\n\n /**\n * destroy the manager and unbinds all events\n * it doesn't unbind dom events, that is the user own responsibility\n */\n destroy: function() {\n this.element && toggleCssProps(this, false);\n\n this.handlers = {};\n this.session = {};\n this.input.destroy();\n this.element = null;\n }\n};\n\n/**\n * add/remove the css properties as defined in manager.options.cssProps\n * @param {Manager} manager\n * @param {Boolean} add\n */\nfunction toggleCssProps(manager, add) {\n var element = manager.element;\n if (!element.style) {\n return;\n }\n var prop;\n each(manager.options.cssProps, function(value, name) {\n prop = prefixed(element.style, name);\n if (add) {\n manager.oldCssProps[prop] = element.style[prop];\n element.style[prop] = value;\n } else {\n element.style[prop] = manager.oldCssProps[prop] || '';\n }\n });\n if (!add) {\n manager.oldCssProps = {};\n }\n}\n\n/**\n * trigger dom event\n * @param {String} event\n * @param {Object} data\n */\nfunction triggerDomEvent(event, data) {\n var gestureEvent = document.createEvent('Event');\n gestureEvent.initEvent(event, true, true);\n gestureEvent.gesture = data;\n data.target.dispatchEvent(gestureEvent);\n}\n\nassign(Hammer, {\n INPUT_START: INPUT_START,\n INPUT_MOVE: INPUT_MOVE,\n INPUT_END: INPUT_END,\n INPUT_CANCEL: INPUT_CANCEL,\n\n STATE_POSSIBLE: STATE_POSSIBLE,\n STATE_BEGAN: STATE_BEGAN,\n STATE_CHANGED: STATE_CHANGED,\n STATE_ENDED: STATE_ENDED,\n STATE_RECOGNIZED: STATE_RECOGNIZED,\n STATE_CANCELLED: STATE_CANCELLED,\n STATE_FAILED: STATE_FAILED,\n\n DIRECTION_NONE: DIRECTION_NONE,\n DIRECTION_LEFT: DIRECTION_LEFT,\n DIRECTION_RIGHT: DIRECTION_RIGHT,\n DIRECTION_UP: DIRECTION_UP,\n DIRECTION_DOWN: DIRECTION_DOWN,\n DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,\n DIRECTION_VERTICAL: DIRECTION_VERTICAL,\n DIRECTION_ALL: DIRECTION_ALL,\n\n Manager: Manager,\n Input: Input,\n TouchAction: TouchAction,\n\n TouchInput: TouchInput,\n MouseInput: MouseInput,\n PointerEventInput: PointerEventInput,\n TouchMouseInput: TouchMouseInput,\n SingleTouchInput: SingleTouchInput,\n\n Recognizer: Recognizer,\n AttrRecognizer: AttrRecognizer,\n Tap: TapRecognizer,\n Pan: PanRecognizer,\n Swipe: SwipeRecognizer,\n Pinch: PinchRecognizer,\n Rotate: RotateRecognizer,\n Press: PressRecognizer,\n\n on: addEventListeners,\n off: removeEventListeners,\n each: each,\n merge: merge,\n extend: extend,\n assign: assign,\n inherit: inherit,\n bindFn: bindFn,\n prefixed: prefixed\n});\n\n// this prevents errors when Hammer is loaded in the presence of an AMD\n// style loader but by script tag, not by the loader.\nvar freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line\nfreeGlobal.Hammer = Hammer;\n\nif (typeof define === 'function' && define.amd) {\n define(function() {\n return Hammer;\n });\n} else if (typeof module != 'undefined' && module.exports) {\n module.exports = Hammer;\n} else {\n window[exportName] = Hammer;\n}\n\n})(window, document, 'Hammer');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/hammerjs/hammer.js\n ** module id = 40\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_41__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"TweenLite\"\n ** module id = 41\n ** module chunks = 0\n **/","import TileLayer from './TileLayer';\nimport ImageTile from './ImageTile';\nimport ImageTileLayerBaseMaterial from './ImageTileLayerBaseMaterial';\nimport throttle from 'lodash.throttle';\nimport THREE from 'three';\nimport extend from 'lodash.assign';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// DONE: Find a way to avoid the flashing caused by the gap between old tiles\n// being removed and the new tiles being ready for display\n//\n// DONE: Simplest first step for MVP would be to give each tile mesh the colour\n// of the basemap ground so it blends in a little more, or have a huge ground\n// plane underneath all the tiles that shows through between tile updates.\n//\n// Could keep the old tiles around until the new ones are ready, though they'd\n// probably need to be layered in a way so the old tiles don't overlap new ones,\n// which is similar to how Leaflet approaches this (it has 2 layers)\n//\n// Could keep the tile from the previous quadtree level visible until all 4\n// tiles at the new / current level have finished loading and are displayed.\n// Perhaps by keeping a map of tiles by quadcode and a boolean for each of the\n// child quadcodes showing whether they are loaded and in view. If all true then\n// remove the parent tile, otherwise keep it on a lower layer.\n\n// TODO: Load and display a base layer separate to the LOD grid that is at a low\n// resolution – used as a backup / background to fill in empty areas / distance\n\n// DONE: Fix the issue where some tiles just don't load, or at least the texture\n// never shows up – tends to happen if you quickly zoom in / out past it while\n// it's still loading, leaving a blank space\n\n// TODO: Optimise the request of many image tiles – look at how Leaflet and\n// OpenWebGlobe approach this (eg. batching, queues, etc)\n\n// TODO: Cancel pending tile requests if they get removed from view before they\n// reach a ready state (eg. cancel image requests, etc). Need to ensure that the\n// images are re-requested when the tile is next in scene (even if from cache)\n\n// TODO: Consider not performing an LOD calculation on every frame, instead only\n// on move end so panning, orbiting and zooming stays smooth. Otherwise it's\n// possible for performance to tank if you pan, orbit or zoom rapidly while all\n// the LOD calculations are being made and new tiles requested.\n//\n// Pending tiles should continue to be requested and output to the scene on each\n// frame, but no new LOD calculations should be made.\n\n// This tile layer both updates the quadtree and outputs tiles on every frame\n// (throttled to some amount)\n//\n// This is because the computational complexity of image tiles is generally low\n// and so there isn't much jank when running these calculations and outputs in\n// realtime\n//\n// The benefit to doing this is that the underlying map layer continues to\n// refresh and update during movement, which is an arguably better experience\n\nclass ImageTileLayer extends TileLayer {\n constructor(path, options) {\n var defaults = {\n distance: 300000\n };\n\n options = extend({}, defaults, options);\n\n super(options);\n\n this._path = path;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n super._onAdd(world).then(() => {\n // Add base layer\n var geom = new THREE.PlaneBufferGeometry(2000000, 2000000, 1);\n\n var baseMaterial;\n if (this._world._environment._skybox) {\n baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3', this._world._environment._skybox.getRenderTarget());\n } else {\n baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3');\n }\n\n var mesh = new THREE.Mesh(geom, baseMaterial);\n mesh.renderOrder = 0;\n mesh.rotation.x = -90 * Math.PI / 180;\n\n // TODO: It might be overkill to receive a shadow on the base layer as it's\n // rarely seen (good to have if performance difference is negligible)\n mesh.receiveShadow = true;\n\n this._baseLayer = mesh;\n this.add(mesh);\n\n // Trigger initial quadtree calculation on the next frame\n //\n // TODO: This is a hack to ensure the camera is all set up - a better\n // solution should be found\n setTimeout(() => {\n this._calculateLOD();\n this._initEvents();\n }, 0);\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n _initEvents() {\n // Run LOD calculations based on render calls\n //\n // Throttled to 1 LOD calculation per 100ms\n this._throttledWorldUpdate = throttle(this._onWorldUpdate, 100);\n\n this._world.on('preUpdate', this._throttledWorldUpdate, this);\n this._world.on('move', this._onWorldMove, this);\n }\n\n _onWorldUpdate() {\n this._calculateLOD();\n this._outputTiles();\n }\n\n _onWorldMove(latlon, point) {\n this._moveBaseLayer(point);\n }\n\n _moveBaseLayer(point) {\n this._baseLayer.position.x = point.x;\n this._baseLayer.position.z = point.y;\n }\n\n _createTile(quadcode, layer) {\n return new ImageTile(quadcode, this._path, layer);\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n this._world.off('preUpdate', this._throttledWorldUpdate);\n this._world.off('move', this._onWorldMove);\n\n this._throttledWorldUpdate = null;\n\n // Dispose of mesh and materials\n this._baseLayer.geometry.dispose();\n this._baseLayer.geometry = null;\n\n if (this._baseLayer.material.map) {\n this._baseLayer.material.map.dispose();\n this._baseLayer.material.map = null;\n }\n\n this._baseLayer.material.dispose();\n this._baseLayer.material = null;\n\n this._baseLayer = null;\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default ImageTileLayer;\n\nvar noNew = function(path, options) {\n return new ImageTileLayer(path, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as imageTileLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/ImageTileLayer.js\n **/","import Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport TileCache from './TileCache';\nimport THREE from 'three';\n\n// TODO: Consider removing picking from TileLayer instances as there aren't\n// (m)any situations where it would be practical\n//\n// For example, how would you even know what picking IDs to listen to and what\n// to do with them?\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Consider keeping a single TileLayer / LOD instance running by default\n// that keeps a standard LOD grid for other layers to utilise, rather than\n// having to create their own, unique LOD grid and duplicate calculations when\n// they're going to use the same grid setup anyway\n//\n// It still makes sense to be able to have a custom LOD grid for some layers as\n// they may want to customise things, maybe not even using a quadtree at all!\n//\n// Perhaps it makes sense to split out the quadtree stuff into a singleton and\n// pass in the necessary parameters each time for the calculation step.\n//\n// Either way, it seems silly to force layers to have to create a new LOD grid\n// each time and create extra, duplicated processing every frame.\n\n// TODO: Allow passing in of options to define min/max LOD and a distance to use\n// for culling tiles beyond that distance.\n\n// DONE: Prevent tiles from being loaded if they are further than a certain\n// distance from the camera and are unlikely to be seen anyway\n\n// TODO: Avoid performing LOD calculation when it isn't required. For example,\n// when nothing has changed since the last frame and there are no tiles to be\n// loaded or in need of rendering\n\n// TODO: Only remove tiles from the layer that aren't to be rendered in the\n// current frame – it seems excessive to remove all tiles and re-add them on\n// every single frame, even if it's just array manipulation\n\n// TODO: Fix LOD calculation so min and max LOD can be changed without causing\n// problems (eg. making min above 5 causes all sorts of issues)\n\n// TODO: Reuse THREE objects where possible instead of creating new instances\n// on every LOD calculation\n\n// TODO: Consider not using THREE or LatLon / Point objects in LOD calculations\n// to avoid creating unnecessary memory for garbage collection\n\n// TODO: Prioritise loading of tiles at highest level in the quadtree (those\n// closest to the camera) so visual inconsistancies during loading are minimised\n\nclass TileLayer extends Layer {\n constructor(options) {\n var defaults = {\n picking: false,\n maxCache: 1000,\n maxLOD: 18\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n this._tileCache = new TileCache(this._options.maxCache, tile => {\n this._destroyTile(tile);\n });\n\n // List of tiles from the previous LOD calculation\n this._tileList = [];\n\n // TODO: Work out why changing the minLOD causes loads of issues\n this._minLOD = 3;\n this._maxLOD = this._options.maxLOD;\n\n this._frustum = new THREE.Frustum();\n this._tiles = new THREE.Object3D();\n this._tilesPicking = new THREE.Object3D();\n }\n\n _onAdd(world) {\n this.addToPicking(this._tilesPicking);\n this.add(this._tiles);\n\n return Promise.resolve();\n }\n\n _updateFrustum() {\n var camera = this._world.getCamera();\n var projScreenMatrix = new THREE.Matrix4();\n projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n\n this._frustum.setFromMatrix(camera.projectionMatrix);\n this._frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n }\n\n _tileInFrustum(tile) {\n var bounds = tile.getBounds();\n return this._frustum.intersectsBox(new THREE.Box3(new THREE.Vector3(bounds[0], 0, bounds[3]), new THREE.Vector3(bounds[2], 0, bounds[1])));\n }\n\n // Update and output tiles from the previous LOD checklist\n _outputTiles() {\n if (!this._tiles) {\n return;\n }\n\n // Remove all tiles from layer\n this._removeTiles();\n\n // Add / re-add tiles\n this._tileList.forEach(tile => {\n // Are the mesh and texture ready?\n //\n // If yes, continue\n // If no, skip\n if (!tile.isReady()) {\n return;\n }\n\n // Add tile to layer (and to scene) if not already there\n this._tiles.add(tile.getMesh());\n\n if (tile.getPickingMesh()) {\n this._tilesPicking.add(tile.getPickingMesh());\n }\n });\n }\n\n // Works out tiles in the view frustum and stores them in an array\n //\n // Does not output the tiles, deferring this to _outputTiles()\n _calculateLOD() {\n if (this._stop || !this._world) {\n return;\n }\n\n // var start = performance.now();\n\n var camera = this._world.getCamera();\n\n // 1. Update and retrieve camera frustum\n this._updateFrustum(this._frustum, camera);\n\n // 2. Add the four root items of the quadtree to a check list\n var checkList = this._checklist;\n checkList = [];\n checkList.push(this._requestTile('0', this));\n checkList.push(this._requestTile('1', this));\n checkList.push(this._requestTile('2', this));\n checkList.push(this._requestTile('3', this));\n\n // 3. Call Divide, passing in the check list\n this._divide(checkList);\n\n // // 4. Remove all tiles from layer\n //\n // Moved to _outputTiles() for now\n // this._removeTiles();\n\n // Order tile-list by zoom so nearest tiles are requested first\n checkList.sort((a, b) => {\n return a._quadcode.length < b._quadcode.length;\n });\n\n // 5. Filter the tiles remaining in the check list\n this._tileList = checkList.filter((tile, index) => {\n // Skip tile if it's not in the current view frustum\n if (!this._tileInFrustum(tile)) {\n return false;\n }\n\n if (this._options.distance && this._options.distance > 0) {\n // TODO: Can probably speed this up\n var center = tile.getCenter();\n var dist = (new THREE.Vector3(center[0], 0, center[1])).sub(camera.position).length();\n\n // Manual distance limit to cut down on tiles so far away\n if (dist > this._options.distance) {\n return false;\n }\n }\n\n // Does the tile have a mesh?\n //\n // If yes, continue\n // If no, generate tile mesh, request texture and skip\n if (!tile.getMesh()) {\n tile.requestTileAsync();\n }\n\n return true;\n\n // Are the mesh and texture ready?\n //\n // If yes, continue\n // If no, skip\n // if (!tile.isReady()) {\n // return;\n // }\n //\n // // Add tile to layer (and to scene)\n // this._tiles.add(tile.getMesh());\n });\n\n // console.log(performance.now() - start);\n }\n\n _divide(checkList) {\n var count = 0;\n var currentItem;\n var quadcode;\n\n // 1. Loop until count equals check list length\n while (count != checkList.length) {\n currentItem = checkList[count];\n quadcode = currentItem.getQuadcode();\n\n // 2. Increase count and continue loop if quadcode equals max LOD / zoom\n if (currentItem.length === this._maxLOD) {\n count++;\n continue;\n }\n\n // 3. Else, calculate screen-space error metric for quadcode\n if (this._screenSpaceError(currentItem)) {\n // 4. If error is sufficient...\n\n // 4a. Remove parent item from the check list\n checkList.splice(count, 1);\n\n // 4b. Add 4 child items to the check list\n checkList.push(this._requestTile(quadcode + '0', this));\n checkList.push(this._requestTile(quadcode + '1', this));\n checkList.push(this._requestTile(quadcode + '2', this));\n checkList.push(this._requestTile(quadcode + '3', this));\n\n // 4d. Continue the loop without increasing count\n continue;\n } else {\n // 5. Else, increase count and continue loop\n count++;\n }\n }\n }\n\n _screenSpaceError(tile) {\n var minDepth = this._minLOD;\n var maxDepth = this._maxLOD;\n\n var quadcode = tile.getQuadcode();\n\n var camera = this._world.getCamera();\n\n // Tweak this value to refine specific point that each quad is subdivided\n //\n // It's used to multiple the dimensions of the tile sides before\n // comparing against the tile distance from camera\n var quality = 3.0;\n\n // 1. Return false if quadcode length equals maxDepth (stop dividing)\n if (quadcode.length === maxDepth) {\n return false;\n }\n\n // 2. Return true if quadcode length is less than minDepth\n if (quadcode.length < minDepth) {\n return true;\n }\n\n // 3. Return false if quadcode bounds are not in view frustum\n if (!this._tileInFrustum(tile)) {\n return false;\n }\n\n var center = tile.getCenter();\n\n // 4. Calculate screen-space error metric\n // TODO: Use closest distance to one of the 4 tile corners\n var dist = (new THREE.Vector3(center[0], 0, center[1])).sub(camera.position).length();\n\n var error = quality * tile.getSide() / dist;\n\n // 5. Return true if error is greater than 1.0, else return false\n return (error > 1.0);\n }\n\n _removeTiles() {\n if (!this._tiles || !this._tiles.children) {\n return;\n }\n\n for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n this._tiles.remove(this._tiles.children[i]);\n }\n\n if (!this._tilesPicking || !this._tilesPicking.children) {\n return;\n }\n\n for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n this._tilesPicking.remove(this._tilesPicking.children[i]);\n }\n }\n\n // Return a new tile instance\n _createTile(quadcode, layer) {}\n\n // Get a cached tile or request a new one if not in cache\n _requestTile(quadcode, layer) {\n var tile = this._tileCache.getTile(quadcode);\n\n if (!tile) {\n // Set up a brand new tile\n tile = this._createTile(quadcode, layer);\n\n // Add tile to cache, though it won't be ready yet as the data is being\n // requested from various places asynchronously\n this._tileCache.setTile(quadcode, tile);\n }\n\n return tile;\n }\n\n _destroyTile(tile) {\n // Remove tile from scene\n this._tiles.remove(tile.getMesh());\n\n // Delete any references to the tile within this component\n\n // Call destory on tile instance\n tile.destroy();\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n if (this._tiles.children) {\n // Remove all tiles\n for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n this._tiles.remove(this._tiles.children[i]);\n }\n }\n\n // Remove tile from picking scene\n this.removeFromPicking(this._tilesPicking);\n\n if (this._tilesPicking.children) {\n // Remove all tiles\n for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n this._tilesPicking.remove(this._tilesPicking.children[i]);\n }\n }\n\n this._tileCache.destroy();\n this._tileCache = null;\n\n this._tiles = null;\n this._tilesPicking = null;\n this._frustum = null;\n\n super.destroy();\n }\n}\n\nexport default TileLayer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/TileLayer.js\n **/","import LRUCache from 'lru-cache';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// This process is based on a similar approach taken by OpenWebGlobe\n// See: https://github.com/OpenWebGlobe/WebViewer/blob/master/source/core/globecache.js\n\nclass TileCache {\n constructor(cacheLimit, onDestroyTile) {\n this._cache = LRUCache({\n max: cacheLimit,\n dispose: (key, tile) => {\n onDestroyTile(tile);\n }\n });\n }\n\n // Returns true if all specified tile providers are ready to be used\n // Otherwise, returns false\n isReady() {\n return false;\n }\n\n // Get a cached tile without requesting a new one\n getTile(quadcode) {\n return this._cache.get(quadcode);\n }\n\n // Add tile to cache\n setTile(quadcode, tile) {\n this._cache.set(quadcode, tile);\n }\n\n // Destroy the cache and remove it from memory\n //\n // TODO: Call destroy method on items in cache\n destroy() {\n this._cache.reset();\n this._cache = null;\n }\n}\n\nexport default TileCache;\n\nvar noNew = function(cacheLimit, onDestroyTile) {\n return new TileCache(cacheLimit, onDestroyTile);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as tileCache};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/TileCache.js\n **/","module.exports = LRUCache\n\n// This will be a proper iterable 'Map' in engines that support it,\n// or a fakey-fake PseudoMap in older versions.\nvar Map = require('pseudomap')\nvar util = require('util')\n\n// A linked list to keep track of recently-used-ness\nvar Yallist = require('yallist')\n\n// use symbols if possible, otherwise just _props\nvar symbols = {}\nvar hasSymbol = typeof Symbol === 'function'\nvar makeSymbol\n/* istanbul ignore if */\nif (hasSymbol) {\n makeSymbol = function (key) {\n return Symbol.for(key)\n }\n} else {\n makeSymbol = function (key) {\n return '_' + key\n }\n}\n\nfunction priv (obj, key, val) {\n var sym\n if (symbols[key]) {\n sym = symbols[key]\n } else {\n sym = makeSymbol(key)\n symbols[key] = sym\n }\n if (arguments.length === 2) {\n return obj[sym]\n } else {\n obj[sym] = val\n return val\n }\n}\n\nfunction naiveLength () { return 1 }\n\n// lruList is a yallist where the head is the youngest\n// item, and the tail is the oldest. the list contains the Hit\n// objects as the entries.\n// Each Hit object has a reference to its Yallist.Node. This\n// never changes.\n//\n// cache is a Map (or PseudoMap) that matches the keys to\n// the Yallist.Node object.\nfunction LRUCache (options) {\n if (!(this instanceof LRUCache)) {\n return new LRUCache(options)\n }\n\n if (typeof options === 'number') {\n options = { max: options }\n }\n\n if (!options) {\n options = {}\n }\n\n var max = priv(this, 'max', options.max)\n // Kind of weird to have a default max of Infinity, but oh well.\n if (!max ||\n !(typeof max === 'number') ||\n max <= 0) {\n priv(this, 'max', Infinity)\n }\n\n var lc = options.length || naiveLength\n if (typeof lc !== 'function') {\n lc = naiveLength\n }\n priv(this, 'lengthCalculator', lc)\n\n priv(this, 'allowStale', options.stale || false)\n priv(this, 'maxAge', options.maxAge || 0)\n priv(this, 'dispose', options.dispose)\n this.reset()\n}\n\n// resize the cache when the max changes.\nObject.defineProperty(LRUCache.prototype, 'max', {\n set: function (mL) {\n if (!mL || !(typeof mL === 'number') || mL <= 0) {\n mL = Infinity\n }\n priv(this, 'max', mL)\n trim(this)\n },\n get: function () {\n return priv(this, 'max')\n },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'allowStale', {\n set: function (allowStale) {\n priv(this, 'allowStale', !!allowStale)\n },\n get: function () {\n return priv(this, 'allowStale')\n },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'maxAge', {\n set: function (mA) {\n if (!mA || !(typeof mA === 'number') || mA < 0) {\n mA = 0\n }\n priv(this, 'maxAge', mA)\n trim(this)\n },\n get: function () {\n return priv(this, 'maxAge')\n },\n enumerable: true\n})\n\n// resize the cache when the lengthCalculator changes.\nObject.defineProperty(LRUCache.prototype, 'lengthCalculator', {\n set: function (lC) {\n if (typeof lC !== 'function') {\n lC = naiveLength\n }\n if (lC !== priv(this, 'lengthCalculator')) {\n priv(this, 'lengthCalculator', lC)\n priv(this, 'length', 0)\n priv(this, 'lruList').forEach(function (hit) {\n hit.length = priv(this, 'lengthCalculator').call(this, hit.value, hit.key)\n priv(this, 'length', priv(this, 'length') + hit.length)\n }, this)\n }\n trim(this)\n },\n get: function () { return priv(this, 'lengthCalculator') },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'length', {\n get: function () { return priv(this, 'length') },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'itemCount', {\n get: function () { return priv(this, 'lruList').length },\n enumerable: true\n})\n\nLRUCache.prototype.rforEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = priv(this, 'lruList').tail; walker !== null;) {\n var prev = walker.prev\n forEachStep(this, fn, walker, thisp)\n walker = prev\n }\n}\n\nfunction forEachStep (self, fn, node, thisp) {\n var hit = node.value\n if (isStale(self, hit)) {\n del(self, node)\n if (!priv(self, 'allowStale')) {\n hit = undefined\n }\n }\n if (hit) {\n fn.call(thisp, hit.value, hit.key, self)\n }\n}\n\nLRUCache.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = priv(this, 'lruList').head; walker !== null;) {\n var next = walker.next\n forEachStep(this, fn, walker, thisp)\n walker = next\n }\n}\n\nLRUCache.prototype.keys = function () {\n return priv(this, 'lruList').toArray().map(function (k) {\n return k.key\n }, this)\n}\n\nLRUCache.prototype.values = function () {\n return priv(this, 'lruList').toArray().map(function (k) {\n return k.value\n }, this)\n}\n\nLRUCache.prototype.reset = function () {\n if (priv(this, 'dispose') &&\n priv(this, 'lruList') &&\n priv(this, 'lruList').length) {\n priv(this, 'lruList').forEach(function (hit) {\n priv(this, 'dispose').call(this, hit.key, hit.value)\n }, this)\n }\n\n priv(this, 'cache', new Map()) // hash of items by key\n priv(this, 'lruList', new Yallist()) // list of items in order of use recency\n priv(this, 'length', 0) // length of items in the list\n}\n\nLRUCache.prototype.dump = function () {\n return priv(this, 'lruList').map(function (hit) {\n if (!isStale(this, hit)) {\n return {\n k: hit.key,\n v: hit.value,\n e: hit.now + (hit.maxAge || 0)\n }\n }\n }, this).toArray().filter(function (h) {\n return h\n })\n}\n\nLRUCache.prototype.dumpLru = function () {\n return priv(this, 'lruList')\n}\n\nLRUCache.prototype.inspect = function (n, opts) {\n var str = 'LRUCache {'\n var extras = false\n\n var as = priv(this, 'allowStale')\n if (as) {\n str += '\\n allowStale: true'\n extras = true\n }\n\n var max = priv(this, 'max')\n if (max && max !== Infinity) {\n if (extras) {\n str += ','\n }\n str += '\\n max: ' + util.inspect(max, opts)\n extras = true\n }\n\n var maxAge = priv(this, 'maxAge')\n if (maxAge) {\n if (extras) {\n str += ','\n }\n str += '\\n maxAge: ' + util.inspect(maxAge, opts)\n extras = true\n }\n\n var lc = priv(this, 'lengthCalculator')\n if (lc && lc !== naiveLength) {\n if (extras) {\n str += ','\n }\n str += '\\n length: ' + util.inspect(priv(this, 'length'), opts)\n extras = true\n }\n\n var didFirst = false\n priv(this, 'lruList').forEach(function (item) {\n if (didFirst) {\n str += ',\\n '\n } else {\n if (extras) {\n str += ',\\n'\n }\n didFirst = true\n str += '\\n '\n }\n var key = util.inspect(item.key).split('\\n').join('\\n ')\n var val = { value: item.value }\n if (item.maxAge !== maxAge) {\n val.maxAge = item.maxAge\n }\n if (lc !== naiveLength) {\n val.length = item.length\n }\n if (isStale(this, item)) {\n val.stale = true\n }\n\n val = util.inspect(val, opts).split('\\n').join('\\n ')\n str += key + ' => ' + val\n })\n\n if (didFirst || extras) {\n str += '\\n'\n }\n str += '}'\n\n return str\n}\n\nLRUCache.prototype.set = function (key, value, maxAge) {\n maxAge = maxAge || priv(this, 'maxAge')\n\n var now = maxAge ? Date.now() : 0\n var len = priv(this, 'lengthCalculator').call(this, value, key)\n\n if (priv(this, 'cache').has(key)) {\n if (len > priv(this, 'max')) {\n del(this, priv(this, 'cache').get(key))\n return false\n }\n\n var node = priv(this, 'cache').get(key)\n var item = node.value\n\n // dispose of the old one before overwriting\n if (priv(this, 'dispose')) {\n priv(this, 'dispose').call(this, key, item.value)\n }\n\n item.now = now\n item.maxAge = maxAge\n item.value = value\n priv(this, 'length', priv(this, 'length') + (len - item.length))\n item.length = len\n this.get(key)\n trim(this)\n return true\n }\n\n var hit = new Entry(key, value, len, now, maxAge)\n\n // oversized objects fall out of cache automatically.\n if (hit.length > priv(this, 'max')) {\n if (priv(this, 'dispose')) {\n priv(this, 'dispose').call(this, key, value)\n }\n return false\n }\n\n priv(this, 'length', priv(this, 'length') + hit.length)\n priv(this, 'lruList').unshift(hit)\n priv(this, 'cache').set(key, priv(this, 'lruList').head)\n trim(this)\n return true\n}\n\nLRUCache.prototype.has = function (key) {\n if (!priv(this, 'cache').has(key)) return false\n var hit = priv(this, 'cache').get(key).value\n if (isStale(this, hit)) {\n return false\n }\n return true\n}\n\nLRUCache.prototype.get = function (key) {\n return get(this, key, true)\n}\n\nLRUCache.prototype.peek = function (key) {\n return get(this, key, false)\n}\n\nLRUCache.prototype.pop = function () {\n var node = priv(this, 'lruList').tail\n if (!node) return null\n del(this, node)\n return node.value\n}\n\nLRUCache.prototype.del = function (key) {\n del(this, priv(this, 'cache').get(key))\n}\n\nLRUCache.prototype.load = function (arr) {\n // reset the cache\n this.reset()\n\n var now = Date.now()\n // A previous serialized cache has the most recent items first\n for (var l = arr.length - 1; l >= 0; l--) {\n var hit = arr[l]\n var expiresAt = hit.e || 0\n if (expiresAt === 0) {\n // the item was created without expiration in a non aged cache\n this.set(hit.k, hit.v)\n } else {\n var maxAge = expiresAt - now\n // dont add already expired items\n if (maxAge > 0) {\n this.set(hit.k, hit.v, maxAge)\n }\n }\n }\n}\n\nLRUCache.prototype.prune = function () {\n var self = this\n priv(this, 'cache').forEach(function (value, key) {\n get(self, key, false)\n })\n}\n\nfunction get (self, key, doUse) {\n var node = priv(self, 'cache').get(key)\n if (node) {\n var hit = node.value\n if (isStale(self, hit)) {\n del(self, node)\n if (!priv(self, 'allowStale')) hit = undefined\n } else {\n if (doUse) {\n priv(self, 'lruList').unshiftNode(node)\n }\n }\n if (hit) hit = hit.value\n }\n return hit\n}\n\nfunction isStale (self, hit) {\n if (!hit || (!hit.maxAge && !priv(self, 'maxAge'))) {\n return false\n }\n var stale = false\n var diff = Date.now() - hit.now\n if (hit.maxAge) {\n stale = diff > hit.maxAge\n } else {\n stale = priv(self, 'maxAge') && (diff > priv(self, 'maxAge'))\n }\n return stale\n}\n\nfunction trim (self) {\n if (priv(self, 'length') > priv(self, 'max')) {\n for (var walker = priv(self, 'lruList').tail;\n priv(self, 'length') > priv(self, 'max') && walker !== null;) {\n // We know that we're about to delete this one, and also\n // what the next least recently used key will be, so just\n // go ahead and set it now.\n var prev = walker.prev\n del(self, walker)\n walker = prev\n }\n }\n}\n\nfunction del (self, node) {\n if (node) {\n var hit = node.value\n if (priv(self, 'dispose')) {\n priv(self, 'dispose').call(this, hit.key, hit.value)\n }\n priv(self, 'length', priv(self, 'length') - hit.length)\n priv(self, 'cache').delete(hit.key)\n priv(self, 'lruList').removeNode(node)\n }\n}\n\n// classy, since V8 prefers predictable objects.\nfunction Entry (key, value, length, now, maxAge) {\n this.key = key\n this.value = value\n this.length = length\n this.now = now\n this.maxAge = maxAge || 0\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lru-cache/lib/lru-cache.js\n ** module id = 45\n ** module chunks = 0\n **/","if (process.env.npm_package_name === 'pseudomap' &&\n process.env.npm_lifecycle_script === 'test')\n process.env.TEST_PSEUDOMAP = 'true'\n\nif (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) {\n module.exports = Map\n} else {\n module.exports = require('./pseudomap')\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/pseudomap/map.js\n ** module id = 46\n ** module chunks = 0\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\n(function () {\n try {\n cachedSetTimeout = setTimeout;\n } catch (e) {\n cachedSetTimeout = function () {\n throw new Error('setTimeout is not defined');\n }\n }\n try {\n cachedClearTimeout = clearTimeout;\n } catch (e) {\n cachedClearTimeout = function () {\n throw new Error('clearTimeout is not defined');\n }\n }\n} ())\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = cachedSetTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n cachedClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n cachedSetTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/process/browser.js\n ** module id = 47\n ** module chunks = 0\n **/","var hasOwnProperty = Object.prototype.hasOwnProperty\n\nmodule.exports = PseudoMap\n\nfunction PseudoMap (set) {\n if (!(this instanceof PseudoMap)) // whyyyyyyy\n throw new TypeError(\"Constructor PseudoMap requires 'new'\")\n\n this.clear()\n\n if (set) {\n if ((set instanceof PseudoMap) ||\n (typeof Map === 'function' && set instanceof Map))\n set.forEach(function (value, key) {\n this.set(key, value)\n }, this)\n else if (Array.isArray(set))\n set.forEach(function (kv) {\n this.set(kv[0], kv[1])\n }, this)\n else\n throw new TypeError('invalid argument')\n }\n}\n\nPseudoMap.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n Object.keys(this._data).forEach(function (k) {\n if (k !== 'size')\n fn.call(thisp, this._data[k].value, this._data[k].key)\n }, this)\n}\n\nPseudoMap.prototype.has = function (k) {\n return !!find(this._data, k)\n}\n\nPseudoMap.prototype.get = function (k) {\n var res = find(this._data, k)\n return res && res.value\n}\n\nPseudoMap.prototype.set = function (k, v) {\n set(this._data, k, v)\n}\n\nPseudoMap.prototype.delete = function (k) {\n var res = find(this._data, k)\n if (res) {\n delete this._data[res._index]\n this._data.size--\n }\n}\n\nPseudoMap.prototype.clear = function () {\n var data = Object.create(null)\n data.size = 0\n\n Object.defineProperty(this, '_data', {\n value: data,\n enumerable: false,\n configurable: true,\n writable: false\n })\n}\n\nObject.defineProperty(PseudoMap.prototype, 'size', {\n get: function () {\n return this._data.size\n },\n set: function (n) {},\n enumerable: true,\n configurable: true\n})\n\nPseudoMap.prototype.values =\nPseudoMap.prototype.keys =\nPseudoMap.prototype.entries = function () {\n throw new Error('iterators are not implemented in this version')\n}\n\n// Either identical, or both NaN\nfunction same (a, b) {\n return a === b || a !== a && b !== b\n}\n\nfunction Entry (k, v, i) {\n this.key = k\n this.value = v\n this._index = i\n}\n\nfunction find (data, k) {\n for (var i = 0, s = '_' + k, key = s;\n hasOwnProperty.call(data, key);\n key = s + i++) {\n if (same(data[key].key, k))\n return data[key]\n }\n}\n\nfunction set (data, k, v) {\n for (var i = 0, s = '_' + k, key = s;\n hasOwnProperty.call(data, key);\n key = s + i++) {\n if (same(data[key].key, k)) {\n data[key].value = v\n return\n }\n }\n data.size++\n data[key] = new Entry(k, v, key)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/pseudomap/pseudomap.js\n ** module id = 48\n ** module chunks = 0\n **/","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n if (!isString(f)) {\n var objects = [];\n for (var i = 0; i < arguments.length; i++) {\n objects.push(inspect(arguments[i]));\n }\n return objects.join(' ');\n }\n\n var i = 1;\n var args = arguments;\n var len = args.length;\n var str = String(f).replace(formatRegExp, function(x) {\n if (x === '%%') return '%';\n if (i >= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n // Allow for deprecating things in the process of starting up.\n if (isUndefined(global.process)) {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n if (process.noDeprecation === true) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = process.env.NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/util/util.js\n ** module id = 49\n ** module chunks = 0\n **/","module.exports = function isBuffer(arg) {\n return arg && typeof arg === 'object'\n && typeof arg.copy === 'function'\n && typeof arg.fill === 'function'\n && typeof arg.readUInt8 === 'function';\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/util/support/isBufferBrowser.js\n ** module id = 50\n ** module chunks = 0\n **/","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/inherits/inherits_browser.js\n ** module id = 51\n ** module chunks = 0\n **/","module.exports = Yallist\n\nYallist.Node = Node\nYallist.create = Yallist\n\nfunction Yallist (list) {\n var self = this\n if (!(self instanceof Yallist)) {\n self = new Yallist()\n }\n\n self.tail = null\n self.head = null\n self.length = 0\n\n if (list && typeof list.forEach === 'function') {\n list.forEach(function (item) {\n self.push(item)\n })\n } else if (arguments.length > 0) {\n for (var i = 0, l = arguments.length; i < l; i++) {\n self.push(arguments[i])\n }\n }\n\n return self\n}\n\nYallist.prototype.removeNode = function (node) {\n if (node.list !== this) {\n throw new Error('removing node which does not belong to this list')\n }\n\n var next = node.next\n var prev = node.prev\n\n if (next) {\n next.prev = prev\n }\n\n if (prev) {\n prev.next = next\n }\n\n if (node === this.head) {\n this.head = next\n }\n if (node === this.tail) {\n this.tail = prev\n }\n\n node.list.length --\n node.next = null\n node.prev = null\n node.list = null\n}\n\nYallist.prototype.unshiftNode = function (node) {\n if (node === this.head) {\n return\n }\n\n if (node.list) {\n node.list.removeNode(node)\n }\n\n var head = this.head\n node.list = this\n node.next = head\n if (head) {\n head.prev = node\n }\n\n this.head = node\n if (!this.tail) {\n this.tail = node\n }\n this.length ++\n}\n\nYallist.prototype.pushNode = function (node) {\n if (node === this.tail) {\n return\n }\n\n if (node.list) {\n node.list.removeNode(node)\n }\n\n var tail = this.tail\n node.list = this\n node.prev = tail\n if (tail) {\n tail.next = node\n }\n\n this.tail = node\n if (!this.head) {\n this.head = node\n }\n this.length ++\n}\n\nYallist.prototype.push = function () {\n for (var i = 0, l = arguments.length; i < l; i++) {\n push(this, arguments[i])\n }\n return this.length\n}\n\nYallist.prototype.unshift = function () {\n for (var i = 0, l = arguments.length; i < l; i++) {\n unshift(this, arguments[i])\n }\n return this.length\n}\n\nYallist.prototype.pop = function () {\n if (!this.tail)\n return undefined\n\n var res = this.tail.value\n this.tail = this.tail.prev\n this.tail.next = null\n this.length --\n return res\n}\n\nYallist.prototype.shift = function () {\n if (!this.head)\n return undefined\n\n var res = this.head.value\n this.head = this.head.next\n this.head.prev = null\n this.length --\n return res\n}\n\nYallist.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = this.head, i = 0; walker !== null; i++) {\n fn.call(thisp, walker.value, i, this)\n walker = walker.next\n }\n}\n\nYallist.prototype.forEachReverse = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {\n fn.call(thisp, walker.value, i, this)\n walker = walker.prev\n }\n}\n\nYallist.prototype.get = function (n) {\n for (var i = 0, walker = this.head; walker !== null && i < n; i++) {\n // abort out of the list early if we hit a cycle\n walker = walker.next\n }\n if (i === n && walker !== null) {\n return walker.value\n }\n}\n\nYallist.prototype.getReverse = function (n) {\n for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {\n // abort out of the list early if we hit a cycle\n walker = walker.prev\n }\n if (i === n && walker !== null) {\n return walker.value\n }\n}\n\nYallist.prototype.map = function (fn, thisp) {\n thisp = thisp || this\n var res = new Yallist()\n for (var walker = this.head; walker !== null; ) {\n res.push(fn.call(thisp, walker.value, this))\n walker = walker.next\n }\n return res\n}\n\nYallist.prototype.mapReverse = function (fn, thisp) {\n thisp = thisp || this\n var res = new Yallist()\n for (var walker = this.tail; walker !== null;) {\n res.push(fn.call(thisp, walker.value, this))\n walker = walker.prev\n }\n return res\n}\n\nYallist.prototype.reduce = function (fn, initial) {\n var acc\n var walker = this.head\n if (arguments.length > 1) {\n acc = initial\n } else if (this.head) {\n walker = this.head.next\n acc = this.head.value\n } else {\n throw new TypeError('Reduce of empty list with no initial value')\n }\n\n for (var i = 0; walker !== null; i++) {\n acc = fn(acc, walker.value, i)\n walker = walker.next\n }\n\n return acc\n}\n\nYallist.prototype.reduceReverse = function (fn, initial) {\n var acc\n var walker = this.tail\n if (arguments.length > 1) {\n acc = initial\n } else if (this.tail) {\n walker = this.tail.prev\n acc = this.tail.value\n } else {\n throw new TypeError('Reduce of empty list with no initial value')\n }\n\n for (var i = this.length - 1; walker !== null; i--) {\n acc = fn(acc, walker.value, i)\n walker = walker.prev\n }\n\n return acc\n}\n\nYallist.prototype.toArray = function () {\n var arr = new Array(this.length)\n for (var i = 0, walker = this.head; walker !== null; i++) {\n arr[i] = walker.value\n walker = walker.next\n }\n return arr\n}\n\nYallist.prototype.toArrayReverse = function () {\n var arr = new Array(this.length)\n for (var i = 0, walker = this.tail; walker !== null; i++) {\n arr[i] = walker.value\n walker = walker.prev\n }\n return arr\n}\n\nYallist.prototype.slice = function (from, to) {\n to = to || this.length\n if (to < 0) {\n to += this.length\n }\n from = from || 0\n if (from < 0) {\n from += this.length\n }\n var ret = new Yallist()\n if (to < from || to < 0) {\n return ret\n }\n if (from < 0) {\n from = 0\n }\n if (to > this.length) {\n to = this.length\n }\n for (var i = 0, walker = this.head; walker !== null && i < from; i++) {\n walker = walker.next\n }\n for (; walker !== null && i < to; i++, walker = walker.next) {\n ret.push(walker.value)\n }\n return ret\n}\n\nYallist.prototype.sliceReverse = function (from, to) {\n to = to || this.length\n if (to < 0) {\n to += this.length\n }\n from = from || 0\n if (from < 0) {\n from += this.length\n }\n var ret = new Yallist()\n if (to < from || to < 0) {\n return ret\n }\n if (from < 0) {\n from = 0\n }\n if (to > this.length) {\n to = this.length\n }\n for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {\n walker = walker.prev\n }\n for (; walker !== null && i > from; i--, walker = walker.prev) {\n ret.push(walker.value)\n }\n return ret\n}\n\nYallist.prototype.reverse = function () {\n var head = this.head\n var tail = this.tail\n for (var walker = head; walker !== null; walker = walker.prev) {\n var p = walker.prev\n walker.prev = walker.next\n walker.next = p\n }\n this.head = tail\n this.tail = head\n return this\n}\n\nfunction push (self, item) {\n self.tail = new Node(item, self.tail, null, self)\n if (!self.head) {\n self.head = self.tail\n }\n self.length ++\n}\n\nfunction unshift (self, item) {\n self.head = new Node(item, null, self.head, self)\n if (!self.tail) {\n self.tail = self.head\n }\n self.length ++\n}\n\nfunction Node (value, prev, next, list) {\n if (!(this instanceof Node)) {\n return new Node(value, prev, next, list)\n }\n\n this.list = list\n this.value = value\n\n if (prev) {\n prev.next = this\n this.prev = prev\n } else {\n this.prev = null\n }\n\n if (next) {\n next.prev = this\n this.next = next\n } else {\n this.next = null\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/yallist/yallist.js\n ** module id = 52\n ** module chunks = 0\n **/","import Tile from './Tile';\nimport BoxHelper from '../../vendor/BoxHelper';\nimport THREE from 'three';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\nclass ImageTile extends Tile {\n constructor(quadcode, path, layer) {\n super(quadcode, path, layer);\n }\n\n // Request data for the tile\n requestTileAsync() {\n // Making this asynchronous really speeds up the LOD framerate\n setTimeout(() => {\n if (!this._mesh) {\n this._mesh = this._createMesh();\n this._requestTile();\n }\n }, 0);\n }\n\n destroy() {\n // Cancel any pending requests\n this._abortRequest();\n\n // Clear image reference\n this._image = null;\n\n super.destroy();\n }\n\n _createMesh() {\n // Something went wrong and the tile\n //\n // Possibly removed by the cache before loaded\n if (!this._center) {\n return;\n }\n\n var mesh = new THREE.Object3D();\n var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n\n var material;\n if (!this._world._environment._skybox) {\n material = new THREE.MeshBasicMaterial({\n depthWrite: false\n });\n\n // var material = new THREE.MeshPhongMaterial({\n // depthWrite: false\n // });\n } else {\n // Other MeshStandardMaterial settings\n //\n // material.envMapIntensity will change the amount of colour reflected(?)\n // from the environment map – can be greater than 1 for more intensity\n\n material = new THREE.MeshStandardMaterial({\n depthWrite: false\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMap = this._world._environment._skybox.getRenderTarget();\n }\n\n var localMesh = new THREE.Mesh(geom, material);\n localMesh.rotation.x = -90 * Math.PI / 180;\n\n localMesh.receiveShadow = true;\n\n mesh.add(localMesh);\n mesh.renderOrder = 0.1;\n\n mesh.position.x = this._center[0];\n mesh.position.z = this._center[1];\n\n // var box = new BoxHelper(localMesh);\n // mesh.add(box);\n //\n // mesh.add(this._createDebugMesh());\n\n return mesh;\n }\n\n _createDebugMesh() {\n var canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n\n var context = canvas.getContext('2d');\n context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n context.fillStyle = '#ff0000';\n context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\n var texture = new THREE.Texture(canvas);\n\n // Silky smooth images when tilted\n texture.magFilter = THREE.LinearFilter;\n texture.minFilter = THREE.LinearMipMapLinearFilter;\n\n // TODO: Set this to renderer.getMaxAnisotropy() / 4\n texture.anisotropy = 4;\n\n texture.needsUpdate = true;\n\n var material = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n depthWrite: false\n });\n\n var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n var mesh = new THREE.Mesh(geom, material);\n\n mesh.rotation.x = -90 * Math.PI / 180;\n mesh.position.y = 0.1;\n\n return mesh;\n }\n\n _requestTile() {\n var urlParams = {\n x: this._tile[0],\n y: this._tile[1],\n z: this._tile[2]\n };\n\n var url = this._getTileURL(urlParams);\n\n var image = document.createElement('img');\n\n image.addEventListener('load', event => {\n var texture = new THREE.Texture();\n\n texture.image = image;\n texture.needsUpdate = true;\n\n // Silky smooth images when tilted\n texture.magFilter = THREE.LinearFilter;\n texture.minFilter = THREE.LinearMipMapLinearFilter;\n\n // TODO: Set this to renderer.getMaxAnisotropy() / 4\n texture.anisotropy = 4;\n\n texture.needsUpdate = true;\n\n // Something went wrong and the tile or its material is missing\n //\n // Possibly removed by the cache before the image loaded\n if (!this._mesh || !this._mesh.children[0] || !this._mesh.children[0].material) {\n return;\n }\n\n this._mesh.children[0].material.map = texture;\n this._mesh.children[0].material.needsUpdate = true;\n\n this._texture = texture;\n this._ready = true;\n }, false);\n\n // image.addEventListener('progress', event => {}, false);\n // image.addEventListener('error', event => {}, false);\n\n image.crossOrigin = '';\n\n // Load image\n image.src = url;\n\n this._image = image;\n }\n\n _abortRequest() {\n if (!this._image) {\n return;\n }\n\n this._image.src = '';\n }\n}\n\nexport default ImageTile;\n\nvar noNew = function(quadcode, path, layer) {\n return new ImageTile(quadcode, path, layer);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as imageTile};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/ImageTile.js\n **/","import {point as Point} from '../../geo/Point';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport THREE from 'three';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// Manages a single tile and its layers\n\nvar r2d = 180 / Math.PI;\n\nvar tileURLRegex = /\\{([szxy])\\}/g;\n\nclass Tile {\n constructor(quadcode, path, layer) {\n this._layer = layer;\n this._world = layer._world;\n this._quadcode = quadcode;\n this._path = path;\n\n this._ready = false;\n\n this._tile = this._quadcodeToTile(quadcode);\n\n // Bottom-left and top-right bounds in WGS84 coordinates\n this._boundsLatLon = this._tileBoundsWGS84(this._tile);\n\n // Bottom-left and top-right bounds in world coordinates\n this._boundsWorld = this._tileBoundsFromWGS84(this._boundsLatLon);\n\n // Tile center in world coordinates\n this._center = this._boundsToCenter(this._boundsWorld);\n\n // Tile center in projected coordinates\n this._centerLatlon = this._world.pointToLatLon(Point(this._center[0], this._center[1]));\n\n // Length of a tile side in world coorindates\n this._side = this._getSide(this._boundsWorld);\n\n // Point scale for tile (for unit conversion)\n this._pointScale = this._world.pointScale(this._centerLatlon);\n }\n\n // Returns true if the tile mesh and texture are ready to be used\n // Otherwise, returns false\n isReady() {\n return this._ready;\n }\n\n // Request data for the tile\n requestTileAsync() {}\n\n getQuadcode() {\n return this._quadcode;\n }\n\n getBounds() {\n return this._boundsWorld;\n }\n\n getCenter() {\n return this._center;\n }\n\n getSide() {\n return this._side;\n }\n\n getMesh() {\n return this._mesh;\n }\n\n getPickingMesh() {\n return this._pickingMesh;\n }\n\n // Destroys the tile and removes it from the layer and memory\n //\n // Ensure that this leaves no trace of the tile – no textures, no meshes,\n // nothing in memory or the GPU\n destroy() {\n // Delete reference to layer and world\n this._layer = null;\n this._world = null;\n\n // Delete location references\n this._boundsLatLon = null;\n this._boundsWorld = null;\n this._center = null;\n\n // Done if no mesh\n if (!this._mesh) {\n return;\n }\n\n if (this._mesh.children) {\n // Dispose of mesh and materials\n this._mesh.children.forEach(child => {\n child.geometry.dispose();\n child.geometry = null;\n\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n });\n } else {\n this._mesh.geometry.dispose();\n this._mesh.geometry = null;\n\n if (this._mesh.material.map) {\n this._mesh.material.map.dispose();\n this._mesh.material.map = null;\n }\n\n this._mesh.material.dispose();\n this._mesh.material = null;\n }\n }\n\n _createMesh() {}\n _createDebugMesh() {}\n\n _getTileURL(urlParams) {\n if (!urlParams.s) {\n // Default to a random choice of a, b or c\n urlParams.s = String.fromCharCode(97 + Math.floor(Math.random() * 3));\n }\n\n tileURLRegex.lastIndex = 0;\n return this._path.replace(tileURLRegex, function(value, key) {\n // Replace with paramter, otherwise keep existing value\n return urlParams[key];\n });\n }\n\n // Convert from quadcode to TMS tile coordinates\n _quadcodeToTile(quadcode) {\n var x = 0;\n var y = 0;\n var z = quadcode.length;\n\n for (var i = z; i > 0; i--) {\n var mask = 1 << (i - 1);\n var q = +quadcode[z - i];\n if (q === 1) {\n x |= mask;\n }\n if (q === 2) {\n y |= mask;\n }\n if (q === 3) {\n x |= mask;\n y |= mask;\n }\n }\n\n return [x, y, z];\n }\n\n // Convert WGS84 tile bounds to world coordinates\n _tileBoundsFromWGS84(boundsWGS84) {\n var sw = this._layer._world.latLonToPoint(LatLon(boundsWGS84[1], boundsWGS84[0]));\n var ne = this._layer._world.latLonToPoint(LatLon(boundsWGS84[3], boundsWGS84[2]));\n\n return [sw.x, sw.y, ne.x, ne.y];\n }\n\n // Get tile bounds in WGS84 coordinates\n _tileBoundsWGS84(tile) {\n var e = this._tile2lon(tile[0] + 1, tile[2]);\n var w = this._tile2lon(tile[0], tile[2]);\n var s = this._tile2lat(tile[1] + 1, tile[2]);\n var n = this._tile2lat(tile[1], tile[2]);\n return [w, s, e, n];\n }\n\n _tile2lon(x, z) {\n return x / Math.pow(2, z) * 360 - 180;\n }\n\n _tile2lat(y, z) {\n var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);\n return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));\n }\n\n _boundsToCenter(bounds) {\n var x = bounds[0] + (bounds[2] - bounds[0]) / 2;\n var y = bounds[1] + (bounds[3] - bounds[1]) / 2;\n\n return [x, y];\n }\n\n _getSide(bounds) {\n return (new THREE.Vector3(bounds[0], 0, bounds[3])).sub(new THREE.Vector3(bounds[0], 0, bounds[1])).length();\n }\n}\n\nexport default Tile;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/Tile.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nBoxHelper = function ( object ) {\n\n\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\tvar positions = new Float32Array( 8 * 3 );\n\n\tvar geometry = new THREE.BufferGeometry();\n\tgeometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );\n\tgeometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\n\n\tTHREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { linewidth: 2, color: 0xff0000 } ) );\n\n\tif ( object !== undefined ) {\n\n\t\tthis.update( object );\n\n\t}\n\n};\n\nBoxHelper.prototype = Object.create( THREE.LineSegments.prototype );\nBoxHelper.prototype.constructor = BoxHelper;\n\nBoxHelper.prototype.update = ( function () {\n\n\tvar box = new THREE.Box3();\n\n\treturn function ( object ) {\n\n\t\tbox.setFromObject( object );\n\n\t\tif ( box.isEmpty() ) return;\n\n\t\tvar min = box.min;\n\t\tvar max = box.max;\n\n\t\t/*\n\t\t 5____4\n\t\t1/___0/|\n\t\t| 6__|_7\n\t\t2/___3/\n\n\t\t0: max.x, max.y, max.z\n\t\t1: min.x, max.y, max.z\n\t\t2: min.x, min.y, max.z\n\t\t3: max.x, min.y, max.z\n\t\t4: max.x, max.y, min.z\n\t\t5: min.x, max.y, min.z\n\t\t6: min.x, min.y, min.z\n\t\t7: max.x, min.y, min.z\n\t\t*/\n\n\t\tvar position = this.geometry.attributes.position;\n\t\tvar array = position.array;\n\n\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\tposition.needsUpdate = true;\n\n\t\tthis.geometry.computeBoundingSphere();\n\n\t};\n\n} )();\n\nexport default BoxHelper;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/BoxHelper.js\n **/","import THREE from 'three';\n\nexport default function(colour, skyboxTarget) {\n var canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n\n var context = canvas.getContext('2d');\n context.fillStyle = colour;\n context.fillRect(0, 0, canvas.width, canvas.height);\n // context.strokeStyle = '#D0D0CF';\n // context.strokeRect(0, 0, canvas.width, canvas.height);\n\n var texture = new THREE.Texture(canvas);\n\n // // Silky smooth images when tilted\n // texture.magFilter = THREE.LinearFilter;\n // texture.minFilter = THREE.LinearMipMapLinearFilter;\n // //\n // // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n // texture.anisotropy = 4;\n\n // texture.wrapS = THREE.RepeatWrapping;\n // texture.wrapT = THREE.RepeatWrapping;\n // texture.repeat.set(segments, segments);\n\n texture.needsUpdate = true;\n\n var material;\n\n if (!skyboxTarget) {\n material = new THREE.MeshBasicMaterial({\n map: texture,\n depthWrite: false\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n map: texture,\n depthWrite: false\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMap = skyboxTarget;\n }\n\n return material;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/ImageTileLayerBaseMaterial.js\n **/","import TileLayer from './TileLayer';\nimport extend from 'lodash.assign';\nimport GeoJSONTile from './GeoJSONTile';\nimport throttle from 'lodash.throttle';\nimport THREE from 'three';\n\n// TODO: Offer on-the-fly slicing of static, non-tile-based GeoJSON files into a\n// tile grid using geojson-vt\n//\n// See: https://github.com/mapbox/geojson-vt\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Consider pausing per-frame output during movement so there's little to\n// no jank caused by previous tiles still processing\n\n// This tile layer only updates the quadtree after world movement has occurred\n//\n// Tiles from previous quadtree updates are updated and outputted every frame\n// (or at least every frame, throttled to some amount)\n//\n// This is because the complexity of TopoJSON tiles requires a lot of processing\n// and so makes movement janky if updates occur every frame – only updating\n// after movement means frame drops are less obvious due to heavy processing\n// occurring while the view is generally stationary\n//\n// The downside is that until new tiles are requested and outputted you will\n// see blank spaces as you orbit and move around\n//\n// An added benefit is that it dramatically reduces the number of tiles being\n// requested over a period of time and the time it takes to go from request to\n// screen output\n//\n// It may be possible to perform these updates per-frame once Web Worker\n// processing is added\n\nclass GeoJSONTileLayer extends TileLayer {\n constructor(path, options) {\n var defaults = {\n maxLOD: 14,\n distance: 30000\n };\n\n options = extend({}, defaults, options);\n\n super(options);\n\n this._path = path;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n super._onAdd(world).then(() => {\n // Trigger initial quadtree calculation on the next frame\n //\n // TODO: This is a hack to ensure the camera is all set up - a better\n // solution should be found\n setTimeout(() => {\n this._calculateLOD();\n this._initEvents();\n }, 0);\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n _initEvents() {\n // Run LOD calculations based on render calls\n //\n // Throttled to 1 LOD calculation per 100ms\n this._throttledWorldUpdate = throttle(this._onWorldUpdate, 100);\n\n this._world.on('preUpdate', this._throttledWorldUpdate, this);\n this._world.on('move', this._onWorldMove, this);\n this._world.on('controlsMove', this._onControlsMove, this);\n }\n\n // Update and output tiles each frame (throttled)\n _onWorldUpdate() {\n if (this._pauseOutput) {\n return;\n }\n\n this._outputTiles();\n }\n\n // Update tiles grid after world move, but don't output them\n _onWorldMove(latlon, point) {\n this._pauseOutput = false;\n this._calculateLOD();\n }\n\n // Pause updates during control movement for less visual jank\n _onControlsMove() {\n this._pauseOutput = true;\n }\n\n _createTile(quadcode, layer) {\n var options = {};\n\n // if (this._options.filter) {\n // options.filter = this._options.filter;\n // }\n //\n // if (this._options.style) {\n // options.style = this._options.style;\n // }\n //\n // if (this._options.topojson) {\n // options.topojson = true;\n // }\n //\n // if (this._options.interactive) {\n // options.interactive = true;\n // }\n //\n // if (this._options.onClick) {\n // options.onClick = this._options.onClick;\n // }\n\n return new GeoJSONTile(quadcode, this._path, layer, this._options);\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n this._world.off('preUpdate', this._throttledWorldUpdate);\n this._world.off('move', this._onWorldMove);\n\n this._throttledWorldUpdate = null;\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default GeoJSONTileLayer;\n\nvar noNew = function(path, options) {\n return new GeoJSONTileLayer(path, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as geoJSONTileLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/GeoJSONTileLayer.js\n **/","import Tile from './Tile';\nimport {geoJSONLayer as GeoJSONLayer} from '../GeoJSONLayer';\nimport BoxHelper from '../../vendor/BoxHelper';\nimport THREE from 'three';\nimport reqwest from 'reqwest';\nimport {point as Point} from '../../geo/Point';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport extend from 'lodash.assign';\n// import Offset from 'polygon-offset';\nimport GeoJSON from '../../util/GeoJSON';\nimport Buffer from '../../util/Buffer';\nimport PickingMaterial from '../../engine/PickingMaterial';\n\n// TODO: Map picking IDs to some reference within the tile data / geometry so\n// that something useful can be done when an object is picked / clicked on\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Perform tile request and processing in a Web Worker\n//\n// Use Operative (https://github.com/padolsey/operative)\n//\n// Would it make sense to have the worker functionality defined in a static\n// method so it only gets initialised once and not on every tile instance?\n//\n// Otherwise, worker processing logic would have to go in the tile layer so not\n// to waste loads of time setting up a brand new worker with three.js for each\n// tile every single time.\n//\n// Unsure of the best way to get three.js and VIZI into the worker\n//\n// Would need to set up a CRS / projection identical to the world instance\n//\n// Is it possible to bypass requirements on external script by having multiple\n// simple worker methods that each take enough inputs to perform a single task\n// without requiring VIZI or three.js? So long as the heaviest logic is done in\n// the worker and transferrable objects are used then it should be better than\n// nothing. Would probably still need things like earcut...\n//\n// After all, the three.js logic and object creation will still need to be\n// done on the main thread regardless so the worker should try to do as much as\n// possible with as few dependencies as possible.\n//\n// Have a look at how this is done in Tangram before implementing anything as\n// the approach there is pretty similar and robust.\n\nclass GeoJSONTile extends Tile {\n constructor(quadcode, path, layer, options) {\n super(quadcode, path, layer);\n\n this._defaultStyle = GeoJSON.defaultStyle;\n\n var defaults = {\n output: true,\n outputToScene: false,\n interactive: false,\n topojson: false,\n filter: null,\n onEachFeature: null,\n polygonMaterial: null,\n onPolygonMesh: null,\n onPolygonBufferAttributes: null,\n polylineMaterial: null,\n onPolylineMesh: null,\n onPolylineBufferAttributes: null,\n pointGeometry: null,\n pointMaterial: null,\n onPointMesh: null,\n style: GeoJSON.defaultStyle,\n keepFeatures: false\n };\n\n var _options = extend({}, defaults, options);\n\n if (typeof options.style === 'function') {\n _options.style = options.style;\n } else {\n _options.style = extend({}, defaults.style, options.style);\n }\n\n this._options = _options;\n }\n\n // Request data for the tile\n requestTileAsync() {\n // Making this asynchronous really speeds up the LOD framerate\n setTimeout(() => {\n if (!this._mesh) {\n this._mesh = this._createMesh();\n\n // this._shadowCanvas = this._createShadowCanvas();\n\n this._requestTile();\n }\n }, 0);\n }\n\n // TODO: Destroy GeoJSONLayer\n destroy() {\n // Cancel any pending requests\n this._abortRequest();\n\n // Clear request reference\n this._request = null;\n\n if (this._geojsonLayer) {\n this._geojsonLayer.destroy();\n this._geojsonLayer = null;\n }\n\n this._mesh = null;\n\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n\n super.destroy();\n }\n\n _createMesh() {\n // Something went wrong and the tile\n //\n // Possibly removed by the cache before loaded\n if (!this._center) {\n return;\n }\n\n var mesh = new THREE.Object3D();\n // mesh.add(this._createDebugMesh());\n\n return mesh;\n }\n\n _createDebugMesh() {\n var canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n\n var context = canvas.getContext('2d');\n context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n context.fillStyle = '#ff0000';\n context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\n var texture = new THREE.Texture(canvas);\n\n // Silky smooth images when tilted\n texture.magFilter = THREE.LinearFilter;\n texture.minFilter = THREE.LinearMipMapLinearFilter;\n\n // TODO: Set this to renderer.getMaxAnisotropy() / 4\n texture.anisotropy = 4;\n\n texture.needsUpdate = true;\n\n var material = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n depthWrite: false\n });\n\n var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n var mesh = new THREE.Mesh(geom, material);\n\n mesh.rotation.x = -90 * Math.PI / 180;\n mesh.position.y = 0.1;\n\n return mesh;\n }\n\n // _createShadowCanvas() {\n // var canvas = document.createElement('canvas');\n //\n // // Rendered at a low resolution and later scaled up for a low-quality blur\n // canvas.width = 512;\n // canvas.height = 512;\n //\n // return canvas;\n // }\n\n // _addShadow(coordinates) {\n // var ctx = this._shadowCanvas.getContext('2d');\n // var width = this._shadowCanvas.width;\n // var height = this._shadowCanvas.height;\n //\n // var _coords;\n // var _offset;\n // var offset = new Offset();\n //\n // // Transform coordinates to shadowCanvas space and draw on canvas\n // coordinates.forEach((ring, index) => {\n // ctx.beginPath();\n //\n // _coords = ring.map(coord => {\n // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n // return [xFrac * width, yFrac * height];\n // });\n //\n // if (index > 0) {\n // _offset = _coords;\n // } else {\n // _offset = offset.data(_coords).padding(1.3);\n // }\n //\n // // TODO: This is super flaky and crashes the browser if run on anything\n // // put the outer ring (potentially due to winding)\n // _offset.forEach((coord, index) => {\n // // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n // // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n //\n // if (index === 0) {\n // ctx.moveTo(coord[0], coord[1]);\n // } else {\n // ctx.lineTo(coord[0], coord[1]);\n // }\n // });\n //\n // ctx.closePath();\n // });\n //\n // ctx.fillStyle = 'rgba(80, 80, 80, 0.7)';\n // ctx.fill();\n // }\n\n _requestTile() {\n var urlParams = {\n x: this._tile[0],\n y: this._tile[1],\n z: this._tile[2]\n };\n\n var url = this._getTileURL(urlParams);\n\n this._request = reqwest({\n url: url,\n type: 'json',\n crossOrigin: true\n }).then(res => {\n // Clear request reference\n this._request = null;\n this._processTileData(res);\n }).catch(err => {\n console.error(err);\n\n // Clear request reference\n this._request = null;\n });\n }\n\n _processTileData(data) {\n console.time(this._tile);\n\n // Using this creates a huge amount of memory due to the quantity of tiles\n this._geojsonLayer = GeoJSONLayer(data, this._options);\n this._geojsonLayer.addTo(this._world).then(() => {\n this._mesh = this._geojsonLayer._object3D;\n this._pickingMesh = this._geojsonLayer._pickingMesh;\n\n // Free the GeoJSON memory as we don't need it\n //\n // TODO: This should probably be a method within GeoJSONLayer\n this._geojsonLayer._geojson = null;\n\n // TODO: Fix or store shadow canvas stuff and get rid of this code\n // Draw footprint on shadow canvas\n //\n // TODO: Disabled for the time-being until it can be sped up / moved to\n // a worker\n // this._addShadow(coordinates);\n\n // Output shadow canvas\n\n // TODO: Disabled for the time-being until it can be sped up / moved to\n // a worker\n\n // var texture = new THREE.Texture(this._shadowCanvas);\n //\n // // Silky smooth images when tilted\n // texture.magFilter = THREE.LinearFilter;\n // texture.minFilter = THREE.LinearMipMapLinearFilter;\n //\n // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n // texture.anisotropy = 4;\n //\n // texture.needsUpdate = true;\n //\n // var material;\n // if (!this._world._environment._skybox) {\n // material = new THREE.MeshBasicMaterial({\n // map: texture,\n // transparent: true,\n // depthWrite: false\n // });\n // } else {\n // material = new THREE.MeshStandardMaterial({\n // map: texture,\n // transparent: true,\n // depthWrite: false\n // });\n // material.roughness = 1;\n // material.metalness = 0.1;\n // material.envMap = this._world._environment._skybox.getRenderTarget();\n // }\n //\n // var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n // var mesh = new THREE.Mesh(geom, material);\n //\n // mesh.castShadow = false;\n // mesh.receiveShadow = false;\n // mesh.renderOrder = 1;\n //\n // mesh.rotation.x = -90 * Math.PI / 180;\n //\n // this._mesh.add(mesh);\n\n this._ready = true;\n console.timeEnd(this._tile);\n });\n }\n\n _abortRequest() {\n if (!this._request) {\n return;\n }\n\n this._request.abort();\n }\n}\n\nexport default GeoJSONTile;\n\nvar noNew = function(quadcode, path, layer, options) {\n return new GeoJSONTile(quadcode, path, layer, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as geoJSONTile};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/GeoJSONTile.js\n **/","// TODO: Consider adopting GeoJSON CSS\n// http://wiki.openstreetmap.org/wiki/Geojson_CSS\n\n// TODO: Allow interaction to be defined per-layer to save on resources\n//\n// For example, only allow polygons to be interactive via a polygonInteractive\n// option\n\nimport LayerGroup from './LayerGroup';\nimport extend from 'lodash.assign';\nimport reqwest from 'reqwest';\nimport GeoJSON from '../util/GeoJSON';\nimport Buffer from '../util/Buffer';\nimport PickingMaterial from '../engine/PickingMaterial';\nimport PolygonLayer from './geometry/PolygonLayer';\nimport PolylineLayer from './geometry/PolylineLayer';\nimport PointLayer from './geometry/PointLayer';\n\nclass GeoJSONLayer extends LayerGroup {\n constructor(geojson, options) {\n var defaults = {\n output: false,\n interactive: false,\n topojson: false,\n filter: null,\n onEachFeature: null,\n polygonMaterial: null,\n onPolygonMesh: null,\n onPolygonBufferAttributes: null,\n polylineMaterial: null,\n onPolylineMesh: null,\n onPolylineBufferAttributes: null,\n pointGeometry: null,\n pointMaterial: null,\n onPointMesh: null,\n style: GeoJSON.defaultStyle,\n keepFeatures: true\n };\n\n var _options = extend({}, defaults, options);\n\n if (typeof options.style === 'function') {\n _options.style = options.style;\n } else {\n _options.style = extend({}, defaults.style, options.style);\n }\n\n super(_options);\n\n this._geojson = geojson;\n }\n\n _onAdd(world) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n // Request data from URL if needed\n if (typeof this._geojson === 'string') {\n return this._requestData(this._geojson);\n } else {\n // Process and add GeoJSON to layer\n return this._processData(this._geojson);\n }\n }\n\n _requestData(url) {\n return new Promise((resolve, reject) => {\n this._request = reqwest({\n url: url,\n type: 'json',\n crossOrigin: true\n }).then(res => {\n // Clear request reference\n this._request = null;\n this._processData(res).then(() => {\n resolve(this);\n });\n }).catch(err => {\n console.error(err);\n\n // Clear request reference\n this._request = null;\n });\n });\n }\n\n // TODO: Wrap into a helper method so this isn't duplicated in the tiled\n // GeoJSON output layer\n //\n // Need to be careful as to not make it impossible to fork this off into a\n // worker script at a later stage\n _processData(data) {\n // Collects features into a single FeatureCollection\n //\n // Also converts TopoJSON to GeoJSON if instructed\n this._geojson = GeoJSON.collectFeatures(data, this._options.topojson);\n\n // TODO: Check that GeoJSON is valid / usable\n\n var features = this._geojson.features;\n\n // Run filter, if provided\n if (this._options.filter) {\n features = this._geojson.features.filter(this._options.filter);\n }\n\n var defaults = {};\n\n // Assume that a style won't be set per feature\n var style = this._options.style;\n\n var options;\n features.forEach(feature => {\n // Get per-feature style object, if provided\n if (typeof this._options.style === 'function') {\n style = extend({}, GeoJSON.defaultStyle, this._options.style(feature));\n }\n\n options = extend({}, defaults, {\n // If merging feature layers, stop them outputting themselves\n // If not, let feature layers output themselves to the world\n output: !this.isOutput(),\n interactive: this._options.interactive,\n style: style\n });\n\n var layer = this._featureToLayer(feature, options);\n\n if (!layer) {\n return;\n }\n\n // Sometimes you don't want to store a reference to the feature\n //\n // For example, to save memory when being used by tile layers\n if (this._options.keepFeatures) {\n layer.feature = feature;\n }\n\n // If defined, call a function for each feature\n //\n // This is commonly used for adding event listeners from the user script\n if (this._options.onEachFeature) {\n this._options.onEachFeature(feature, layer);\n }\n\n // TODO: Make this a promise array and only continue on completion\n this.addLayer(layer);\n });\n\n // If merging layers do that now, otherwise skip as the geometry layers\n // should have already outputted themselves\n if (!this.isOutput()) {\n return;\n }\n\n // From here on we can assume that we want to merge the layers\n\n var polygonAttributes = [];\n var polygonFlat = true;\n\n var polylineAttributes = [];\n var pointAttributes = [];\n\n this._layers.forEach(layer => {\n if (layer instanceof PolygonLayer) {\n polygonAttributes.push(layer.getBufferAttributes());\n\n if (polygonFlat && !layer.isFlat()) {\n polygonFlat = false;\n }\n } else if (layer instanceof PolylineLayer) {\n polylineAttributes.push(layer.getBufferAttributes());\n } else if (layer instanceof PointLayer) {\n pointAttributes.push(layer.getBufferAttributes());\n }\n });\n\n if (polygonAttributes.length > 0) {\n var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);\n this._setPolygonMesh(mergedPolygonAttributes, polygonFlat);\n this.add(this._polygonMesh);\n }\n\n if (polylineAttributes.length > 0) {\n var mergedPolylineAttributes = Buffer.mergeAttributes(polylineAttributes);\n this._setPolylineMesh(mergedPolylineAttributes);\n this.add(this._polylineMesh);\n }\n\n if (pointAttributes.length > 0) {\n var mergedPointAttributes = Buffer.mergeAttributes(pointAttributes);\n this._setPointMesh(mergedPointAttributes);\n this.add(this._pointMesh);\n }\n\n // Clean up layers\n //\n // TODO: Are there ever situations where the unmerged buffer attributes\n // and coordinates would still be required?\n this._layers.forEach(layer => {\n layer.clearBufferAttributes();\n layer.clearCoordinates();\n });\n\n return Promise.resolve();\n }\n\n // Create and store mesh from buffer attributes\n //\n // TODO: De-dupe this from the individual mesh creation logic within each\n // geometry layer (materials, settings, etc)\n //\n // Could make this an abstract method for each geometry layer\n _setPolygonMesh(attributes, flat) {\n var geometry = new THREE.BufferGeometry();\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\n if (attributes.pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n // TODO: Make this work when style is a function per feature\n var style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n var material;\n if (this._options.polygonMaterial && this._options.polygonMaterial instanceof THREE.Material) {\n material = this._options.polygonMaterial;\n } else if (!this._world._environment._skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = this._world._environment._skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof this._options.onPolygonMesh === 'function') {\n mesh = this._options.onPolygonMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n }\n\n if (flat) {\n material.depthWrite = false;\n mesh.renderOrder = 1;\n }\n\n if (this._options.interactive && this._pickingMesh) {\n material = new PickingMaterial();\n material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n this._pickingMesh.add(pickingMesh);\n }\n\n this._polygonMesh = mesh;\n }\n\n _setPolylineMesh(attributes) {\n var geometry = new THREE.BufferGeometry();\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n\n if (attributes.normals) {\n geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n }\n\n geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\n if (attributes.pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n // TODO: Make this work when style is a function per feature\n var style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n var material;\n if (this._options.polylineMaterial && this._options.polylineMaterial instanceof THREE.Material) {\n material = this._options.polylineMaterial;\n } else {\n material = new THREE.LineBasicMaterial({\n vertexColors: THREE.VertexColors,\n linewidth: style.lineWidth,\n transparent: style.lineTransparent,\n opacity: style.lineOpacity,\n blending: style.lineBlending\n });\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof this._options.onPolylineMesh === 'function') {\n mesh = this._options.onPolylineMesh(geometry, material);\n } else {\n mesh = new THREE.LineSegments(geometry, material);\n\n if (style.lineRenderOrder !== undefined) {\n material.depthWrite = false;\n mesh.renderOrder = style.lineRenderOrder;\n }\n\n mesh.castShadow = true;\n // mesh.receiveShadow = true;\n }\n\n // TODO: Allow this to be overridden, or copy mesh instead of creating a new\n // one just for picking\n if (this._options.interactive && this._pickingMesh) {\n material = new PickingMaterial();\n // material.side = THREE.BackSide;\n\n // Make the line wider / easier to pick\n material.linewidth = style.lineWidth + material.linePadding;\n\n var pickingMesh = new THREE.LineSegments(geometry, material);\n this._pickingMesh.add(pickingMesh);\n }\n\n this._polylineMesh = mesh;\n }\n\n _setPointMesh(attributes) {\n var geometry = new THREE.BufferGeometry();\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\n if (attributes.pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (this._options.pointMaterial && this._options.pointMaterial instanceof THREE.Material) {\n material = this._options.pointMaterial;\n } else if (!this._world._environment._skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors\n // side: THREE.BackSide\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors\n // side: THREE.BackSide\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = this._world._environment._skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh callback, if defined\n if (typeof this._options.onPointMesh === 'function') {\n mesh = this._options.onPointMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n // mesh.receiveShadow = true;\n }\n\n if (this._options.interactive && this._pickingMesh) {\n material = new PickingMaterial();\n // material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n this._pickingMesh.add(pickingMesh);\n }\n\n this._pointMesh = mesh;\n }\n\n // TODO: Support all GeoJSON geometry types\n _featureToLayer(feature, options) {\n var geometry = feature.geometry;\n var coordinates = (geometry.coordinates) ? geometry.coordinates : null;\n\n if (!coordinates || !geometry) {\n return;\n }\n\n if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n // Get material instance to use for polygon, if provided\n if (typeof this._options.polygonMaterial === 'function') {\n options.geometry = this._options.polygonMaterial(feature);\n }\n\n if (typeof this._options.onPolygonMesh === 'function') {\n options.onMesh = this._options.onPolygonMesh;\n }\n\n // Pass onBufferAttributes callback, if defined\n if (typeof this._options.onPolygonBufferAttributes === 'function') {\n options.onBufferAttributes = this._options.onPolygonBufferAttributes;\n }\n\n return new PolygonLayer(coordinates, options);\n }\n\n if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n // Get material instance to use for line, if provided\n if (typeof this._options.lineMaterial === 'function') {\n options.geometry = this._options.lineMaterial(feature);\n }\n\n if (typeof this._options.onPolylineMesh === 'function') {\n options.onMesh = this._options.onPolylineMesh;\n }\n\n // Pass onBufferAttributes callback, if defined\n if (typeof this._options.onPolylineBufferAttributes === 'function') {\n options.onBufferAttributes = this._options.onPolylineBufferAttributes;\n }\n\n return new PolylineLayer(coordinates, options);\n }\n\n if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n // Get geometry object to use for point, if provided\n if (typeof this._options.pointGeometry === 'function') {\n options.geometry = this._options.pointGeometry(feature);\n }\n\n // Get material instance to use for point, if provided\n if (typeof this._options.pointMaterial === 'function') {\n options.geometry = this._options.pointMaterial(feature);\n }\n\n if (typeof this._options.onPointMesh === 'function') {\n options.onMesh = this._options.onPointMesh;\n }\n\n return new PointLayer(coordinates, options);\n }\n }\n\n _abortRequest() {\n if (!this._request) {\n return;\n }\n\n this._request.abort();\n }\n\n // Destroy the layers and remove them from the scene and memory\n destroy() {\n // Cancel any pending requests\n this._abortRequest();\n\n // Clear request reference\n this._request = null;\n\n this._geojson = null;\n\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n if (this._polygonMesh) {\n this._polygonMesh = null;\n }\n\n if (this._polylineMesh) {\n this._polylineMesh = null;\n }\n\n if (this._pointMesh) {\n this._pointMesh = null;\n }\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default GeoJSONLayer;\n\nvar noNew = function(geojson, options) {\n return new GeoJSONLayer(geojson, options);\n};\n\nexport {noNew as geoJSONLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/GeoJSONLayer.js\n **/","import Layer from './Layer';\nimport extend from 'lodash.assign';\n\nclass LayerGroup extends Layer {\n constructor(options) {\n var defaults = {\n output: false\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n this._layers = [];\n }\n\n addLayer(layer) {\n this._layers.push(layer);\n return this._world.addLayer(layer);\n }\n\n removeLayer(layer) {\n var layerIndex = this._layers.indexOf(layer);\n\n if (layerIndex > -1) {\n // Remove from this._layers\n this._layers.splice(layerIndex, 1);\n };\n\n this._world.removeLayer(layer);\n }\n\n _onAdd(world) {}\n\n // Destroy the layers and remove them from the scene and memory\n destroy() {\n // TODO: Sometimes this is already null, find out why\n if (this._layers) {\n for (var i = 0; i < this._layers.length; i++) {\n this._layers[i].destroy();\n }\n\n this._layers = null;\n }\n\n super.destroy();\n }\n}\n\nexport default LayerGroup;\n\nvar noNew = function(options) {\n return new LayerGroup(options);\n};\n\nexport {noNew as layerGroup};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/LayerGroup.js\n **/","/*!\n * Reqwest! A general purpose XHR connection manager\n * license MIT (c) Dustin Diaz 2015\n * https://github.com/ded/reqwest\n */\n\n!function (name, context, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(definition)\n else context[name] = definition()\n}('reqwest', this, function () {\n\n var context = this\n\n if ('window' in context) {\n var doc = document\n , byTag = 'getElementsByTagName'\n , head = doc[byTag]('head')[0]\n } else {\n var XHR2\n try {\n XHR2 = require('xhr2')\n } catch (ex) {\n throw new Error('Peer dependency `xhr2` required! Please npm install xhr2')\n }\n }\n\n\n var httpsRe = /^http/\n , protocolRe = /(^\\w+):\\/\\//\n , twoHundo = /^(20\\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\n , readyState = 'readyState'\n , contentType = 'Content-Type'\n , requestedWith = 'X-Requested-With'\n , uniqid = 0\n , callbackPrefix = 'reqwest_' + (+new Date())\n , lastValue // data stored by the most recent JSONP callback\n , xmlHttpRequest = 'XMLHttpRequest'\n , xDomainRequest = 'XDomainRequest'\n , noop = function () {}\n\n , isArray = typeof Array.isArray == 'function'\n ? Array.isArray\n : function (a) {\n return a instanceof Array\n }\n\n , defaultHeaders = {\n 'contentType': 'application/x-www-form-urlencoded'\n , 'requestedWith': xmlHttpRequest\n , 'accept': {\n '*': 'text/javascript, text/html, application/xml, text/xml, */*'\n , 'xml': 'application/xml, text/xml'\n , 'html': 'text/html'\n , 'text': 'text/plain'\n , 'json': 'application/json, text/javascript'\n , 'js': 'application/javascript, text/javascript'\n }\n }\n\n , xhr = function(o) {\n // is it x-domain\n if (o['crossOrigin'] === true) {\n var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null\n if (xhr && 'withCredentials' in xhr) {\n return xhr\n } else if (context[xDomainRequest]) {\n return new XDomainRequest()\n } else {\n throw new Error('Browser does not support cross-origin requests')\n }\n } else if (context[xmlHttpRequest]) {\n return new XMLHttpRequest()\n } else if (XHR2) {\n return new XHR2()\n } else {\n return new ActiveXObject('Microsoft.XMLHTTP')\n }\n }\n , globalSetupOptions = {\n dataFilter: function (data) {\n return data\n }\n }\n\n function succeed(r) {\n var protocol = protocolRe.exec(r.url)\n protocol = (protocol && protocol[1]) || context.location.protocol\n return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response\n }\n\n function handleReadyState(r, success, error) {\n return function () {\n // use _aborted to mitigate against IE err c00c023f\n // (can't read props on aborted request objects)\n if (r._aborted) return error(r.request)\n if (r._timedOut) return error(r.request, 'Request is aborted: timeout')\n if (r.request && r.request[readyState] == 4) {\n r.request.onreadystatechange = noop\n if (succeed(r)) success(r.request)\n else\n error(r.request)\n }\n }\n }\n\n function setHeaders(http, o) {\n var headers = o['headers'] || {}\n , h\n\n headers['Accept'] = headers['Accept']\n || defaultHeaders['accept'][o['type']]\n || defaultHeaders['accept']['*']\n\n var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData);\n // breaks cross-origin requests with legacy browsers\n if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']\n if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']\n for (h in headers)\n headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])\n }\n\n function setCredentials(http, o) {\n if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n http.withCredentials = !!o['withCredentials']\n }\n }\n\n function generalCallback(data) {\n lastValue = data\n }\n\n function urlappend (url, s) {\n return url + (/\\?/.test(url) ? '&' : '?') + s\n }\n\n function handleJsonp(o, fn, err, url) {\n var reqId = uniqid++\n , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key\n , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)\n , cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)')\n , match = url.match(cbreg)\n , script = doc.createElement('script')\n , loaded = 0\n , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1\n\n if (match) {\n if (match[3] === '?') {\n url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name\n } else {\n cbval = match[3] // provided callback func name\n }\n } else {\n url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em\n }\n\n context[cbval] = generalCallback\n\n script.type = 'text/javascript'\n script.src = url\n script.async = true\n if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n // need this for IE due to out-of-order onreadystatechange(), binding script\n // execution to an event listener gives us control over when the script\n // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n script.htmlFor = script.id = '_reqwest_' + reqId\n }\n\n script.onload = script.onreadystatechange = function () {\n if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {\n return false\n }\n script.onload = script.onreadystatechange = null\n script.onclick && script.onclick()\n // Call the user callback with the last value stored and clean up values and scripts.\n fn(lastValue)\n lastValue = undefined\n head.removeChild(script)\n loaded = 1\n }\n\n // Add the script to the DOM head\n head.appendChild(script)\n\n // Enable JSONP timeout\n return {\n abort: function () {\n script.onload = script.onreadystatechange = null\n err({}, 'Request is aborted: timeout', {})\n lastValue = undefined\n head.removeChild(script)\n loaded = 1\n }\n }\n }\n\n function getRequest(fn, err) {\n var o = this.o\n , method = (o['method'] || 'GET').toUpperCase()\n , url = typeof o === 'string' ? o : o['url']\n // convert non-string objects to query-string form unless o['processData'] is false\n , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')\n ? reqwest.toQueryString(o['data'])\n : (o['data'] || null)\n , http\n , sendWait = false\n\n // if we're working on a GET request and we have data then we should append\n // query string to end of URL and not post data\n if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n url = urlappend(url, data)\n data = null\n }\n\n if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)\n\n // get the xhr from the factory if passed\n // if the factory returns null, fall-back to ours\n http = (o.xhr && o.xhr(o)) || xhr(o)\n\n http.open(method, url, o['async'] === false ? false : true)\n setHeaders(http, o)\n setCredentials(http, o)\n if (context[xDomainRequest] && http instanceof context[xDomainRequest]) {\n http.onload = fn\n http.onerror = err\n // NOTE: see\n // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e\n http.onprogress = function() {}\n sendWait = true\n } else {\n http.onreadystatechange = handleReadyState(this, fn, err)\n }\n o['before'] && o['before'](http)\n if (sendWait) {\n setTimeout(function () {\n http.send(data)\n }, 200)\n } else {\n http.send(data)\n }\n return http\n }\n\n function Reqwest(o, fn) {\n this.o = o\n this.fn = fn\n\n init.apply(this, arguments)\n }\n\n function setType(header) {\n // json, javascript, text/plain, text/html, xml\n if (header === null) return undefined; //In case of no content-type.\n if (header.match('json')) return 'json'\n if (header.match('javascript')) return 'js'\n if (header.match('text')) return 'html'\n if (header.match('xml')) return 'xml'\n }\n\n function init(o, fn) {\n\n this.url = typeof o == 'string' ? o : o['url']\n this.timeout = null\n\n // whether request has been fulfilled for purpose\n // of tracking the Promises\n this._fulfilled = false\n // success handlers\n this._successHandler = function(){}\n this._fulfillmentHandlers = []\n // error handlers\n this._errorHandlers = []\n // complete (both success and fail) handlers\n this._completeHandlers = []\n this._erred = false\n this._responseArgs = {}\n\n var self = this\n\n fn = fn || function () {}\n\n if (o['timeout']) {\n this.timeout = setTimeout(function () {\n timedOut()\n }, o['timeout'])\n }\n\n if (o['success']) {\n this._successHandler = function () {\n o['success'].apply(o, arguments)\n }\n }\n\n if (o['error']) {\n this._errorHandlers.push(function () {\n o['error'].apply(o, arguments)\n })\n }\n\n if (o['complete']) {\n this._completeHandlers.push(function () {\n o['complete'].apply(o, arguments)\n })\n }\n\n function complete (resp) {\n o['timeout'] && clearTimeout(self.timeout)\n self.timeout = null\n while (self._completeHandlers.length > 0) {\n self._completeHandlers.shift()(resp)\n }\n }\n\n function success (resp) {\n var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE\n resp = (type !== 'jsonp') ? self.request : resp\n // use global data filter on response text\n var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)\n , r = filteredResponse\n try {\n resp.responseText = r\n } catch (e) {\n // can't assign this in IE<=8, just ignore\n }\n if (r) {\n switch (type) {\n case 'json':\n try {\n resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')')\n } catch (err) {\n return error(resp, 'Could not parse JSON in response', err)\n }\n break\n case 'js':\n resp = eval(r)\n break\n case 'html':\n resp = r\n break\n case 'xml':\n resp = resp.responseXML\n && resp.responseXML.parseError // IE trololo\n && resp.responseXML.parseError.errorCode\n && resp.responseXML.parseError.reason\n ? null\n : resp.responseXML\n break\n }\n }\n\n self._responseArgs.resp = resp\n self._fulfilled = true\n fn(resp)\n self._successHandler(resp)\n while (self._fulfillmentHandlers.length > 0) {\n resp = self._fulfillmentHandlers.shift()(resp)\n }\n\n complete(resp)\n }\n\n function timedOut() {\n self._timedOut = true\n self.request.abort()\n }\n\n function error(resp, msg, t) {\n resp = self.request\n self._responseArgs.resp = resp\n self._responseArgs.msg = msg\n self._responseArgs.t = t\n self._erred = true\n while (self._errorHandlers.length > 0) {\n self._errorHandlers.shift()(resp, msg, t)\n }\n complete(resp)\n }\n\n this.request = getRequest.call(this, success, error)\n }\n\n Reqwest.prototype = {\n abort: function () {\n this._aborted = true\n this.request.abort()\n }\n\n , retry: function () {\n init.call(this, this.o, this.fn)\n }\n\n /**\n * Small deviation from the Promises A CommonJs specification\n * http://wiki.commonjs.org/wiki/Promises/A\n */\n\n /**\n * `then` will execute upon successful requests\n */\n , then: function (success, fail) {\n success = success || function () {}\n fail = fail || function () {}\n if (this._fulfilled) {\n this._responseArgs.resp = success(this._responseArgs.resp)\n } else if (this._erred) {\n fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n } else {\n this._fulfillmentHandlers.push(success)\n this._errorHandlers.push(fail)\n }\n return this\n }\n\n /**\n * `always` will execute whether the request succeeds or fails\n */\n , always: function (fn) {\n if (this._fulfilled || this._erred) {\n fn(this._responseArgs.resp)\n } else {\n this._completeHandlers.push(fn)\n }\n return this\n }\n\n /**\n * `fail` will execute when the request fails\n */\n , fail: function (fn) {\n if (this._erred) {\n fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n } else {\n this._errorHandlers.push(fn)\n }\n return this\n }\n , 'catch': function (fn) {\n return this.fail(fn)\n }\n }\n\n function reqwest(o, fn) {\n return new Reqwest(o, fn)\n }\n\n // normalize newline variants according to spec -> CRLF\n function normalize(s) {\n return s ? s.replace(/\\r?\\n/g, '\\r\\n') : ''\n }\n\n function serial(el, cb) {\n var n = el.name\n , t = el.tagName.toLowerCase()\n , optCb = function (o) {\n // IE gives value=\"\" even where there is no value attribute\n // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273\n if (o && !o['disabled'])\n cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))\n }\n , ch, ra, val, i\n\n // don't serialize elements that are disabled or without a name\n if (el.disabled || !n) return\n\n switch (t) {\n case 'input':\n if (!/reset|button|image|file/i.test(el.type)) {\n ch = /checkbox/i.test(el.type)\n ra = /radio/i.test(el.type)\n val = el.value\n // WebKit gives us \"\" instead of \"on\" if a checkbox has no value, so correct it here\n ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))\n }\n break\n case 'textarea':\n cb(n, normalize(el.value))\n break\n case 'select':\n if (el.type.toLowerCase() === 'select-one') {\n optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)\n } else {\n for (i = 0; el.length && i < el.length; i++) {\n el.options[i].selected && optCb(el.options[i])\n }\n }\n break\n }\n }\n\n // collect up all form elements found from the passed argument elements all\n // the way down to child elements; pass a '' or form fields.\n // called with 'this'=callback to use for serial() on each element\n function eachFormElement() {\n var cb = this\n , e, i\n , serializeSubtags = function (e, tags) {\n var i, j, fa\n for (i = 0; i < tags.length; i++) {\n fa = e[byTag](tags[i])\n for (j = 0; j < fa.length; j++) serial(fa[j], cb)\n }\n }\n\n for (i = 0; i < arguments.length; i++) {\n e = arguments[i]\n if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)\n serializeSubtags(e, [ 'input', 'select', 'textarea' ])\n }\n }\n\n // standard query string style serialization\n function serializeQueryString() {\n return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))\n }\n\n // { 'name': 'value', ... } style serialization\n function serializeHash() {\n var hash = {}\n eachFormElement.apply(function (name, value) {\n if (name in hash) {\n hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])\n hash[name].push(value)\n } else hash[name] = value\n }, arguments)\n return hash\n }\n\n // [ { name: 'name', value: 'value' }, ... ] style serialization\n reqwest.serializeArray = function () {\n var arr = []\n eachFormElement.apply(function (name, value) {\n arr.push({name: name, value: value})\n }, arguments)\n return arr\n }\n\n reqwest.serialize = function () {\n if (arguments.length === 0) return ''\n var opt, fn\n , args = Array.prototype.slice.call(arguments, 0)\n\n opt = args.pop()\n opt && opt.nodeType && args.push(opt) && (opt = null)\n opt && (opt = opt.type)\n\n if (opt == 'map') fn = serializeHash\n else if (opt == 'array') fn = reqwest.serializeArray\n else fn = serializeQueryString\n\n return fn.apply(null, args)\n }\n\n reqwest.toQueryString = function (o, trad) {\n var prefix, i\n , traditional = trad || false\n , s = []\n , enc = encodeURIComponent\n , add = function (key, value) {\n // If value is a function, invoke it and return its value\n value = ('function' === typeof value) ? value() : (value == null ? '' : value)\n s[s.length] = enc(key) + '=' + enc(value)\n }\n // If an array was passed in, assume that it is an array of form elements.\n if (isArray(o)) {\n for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])\n } else {\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for (prefix in o) {\n if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)\n }\n }\n\n // spaces should be + according to spec\n return s.join('&').replace(/%20/g, '+')\n }\n\n function buildParams(prefix, obj, traditional, add) {\n var name, i, v\n , rbracket = /\\[\\]$/\n\n if (isArray(obj)) {\n // Serialize array item.\n for (i = 0; obj && i < obj.length; i++) {\n v = obj[i]\n if (traditional || rbracket.test(prefix)) {\n // Treat each array item as a scalar.\n add(prefix, v)\n } else {\n buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)\n }\n }\n } else if (obj && obj.toString() === '[object Object]') {\n // Serialize object item.\n for (name in obj) {\n buildParams(prefix + '[' + name + ']', obj[name], traditional, add)\n }\n\n } else {\n // Serialize scalar item.\n add(prefix, obj)\n }\n }\n\n reqwest.getcallbackPrefix = function () {\n return callbackPrefix\n }\n\n // jQuery and Zepto compatibility, differences can be remapped here so you can call\n // .ajax.compat(options, callback)\n reqwest.compat = function (o, fn) {\n if (o) {\n o['type'] && (o['method'] = o['type']) && delete o['type']\n o['dataType'] && (o['type'] = o['dataType'])\n o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']\n o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])\n }\n return new Reqwest(o, fn)\n }\n\n reqwest.ajaxSetup = function (options) {\n options = options || {}\n for (var k in options) {\n globalSetupOptions[k] = options[k]\n }\n }\n\n return reqwest\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/reqwest/reqwest.js\n ** module id = 61\n ** module chunks = 0\n **/","/*\n * GeoJSON helpers for handling data and generating objects\n */\n\nimport THREE from 'three';\nimport topojson from 'topojson';\nimport geojsonMerge from 'geojson-merge';\nimport earcut from 'earcut';\nimport extrudePolygon from './extrudePolygon';\n\n// TODO: Make it so height can be per-coordinate / point but connected together\n// as a linestring (eg. GPS points with an elevation at each point)\n//\n// This isn't really valid GeoJSON so perhaps something best left to an external\n// component for now, until a better approach can be considered\n//\n// See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html\n\n// Light and dark colours used for poor-mans AO gradient on object sides\nvar light = new THREE.Color(0xffffff);\nvar shadow = new THREE.Color(0x666666);\n\nvar GeoJSON = (function() {\n var defaultStyle = {\n color: '#ffffff',\n transparent: false,\n opacity: 1,\n blending: THREE.NormalBlending,\n height: 0,\n lineOpacity: 1,\n lineTransparent: false,\n lineColor: '#ffffff',\n lineWidth: 1,\n lineBlending: THREE.NormalBlending\n };\n\n // Attempts to merge together multiple GeoJSON Features or FeatureCollections\n // into a single FeatureCollection\n var collectFeatures = function(data, _topojson) {\n var collections = [];\n\n if (_topojson) {\n // TODO: Allow TopoJSON objects to be overridden as an option\n\n // If not overridden, merge all features from all objects\n for (var tk in data.objects) {\n collections.push(topojson.feature(data, data.objects[tk]));\n }\n\n return geojsonMerge(collections);\n } else {\n // If root doesn't have a type then let's see if there are features in the\n // next step down\n if (!data.type) {\n // TODO: Allow GeoJSON objects to be overridden as an option\n\n // If not overridden, merge all features from all objects\n for (var gk in data) {\n if (!data[gk].type) {\n continue;\n }\n\n collections.push(data[gk]);\n }\n\n return geojsonMerge(collections);\n } else if (Array.isArray(data)) {\n return geojsonMerge(data);\n } else {\n return data;\n }\n }\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var lineStringAttributes = function(coordinates, colour, height) {\n var _coords = [];\n var _colours = [];\n\n var nextCoord;\n\n // Connect coordinate with the next to make a pair\n //\n // LineSegments requires pairs of vertices so repeat the last point if\n // there's an odd number of vertices\n coordinates.forEach((coordinate, index) => {\n _colours.push([colour.r, colour.g, colour.b]);\n _coords.push([coordinate[0], height, coordinate[1]]);\n\n nextCoord = (coordinates[index + 1]) ? coordinates[index + 1] : coordinate;\n\n _colours.push([colour.r, colour.g, colour.b]);\n _coords.push([nextCoord[0], height, nextCoord[1]]);\n });\n\n return {\n vertices: _coords,\n colours: _colours\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var multiLineStringAttributes = function(coordinates, colour, height) {\n var _coords = [];\n var _colours = [];\n\n var result;\n coordinates.forEach(coordinate => {\n result = lineStringAttributes(coordinate, colour, height);\n\n result.vertices.forEach(coord => {\n _coords.push(coord);\n });\n\n result.colours.forEach(colour => {\n _colours.push(colour);\n });\n });\n\n return {\n vertices: _coords,\n colours: _colours\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var polygonAttributes = function(coordinates, colour, height) {\n var earcutData = _toEarcut(coordinates);\n\n var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions);\n\n var groupedVertices = [];\n for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) {\n groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions));\n }\n\n var extruded = extrudePolygon(groupedVertices, faces, {\n bottom: 0,\n top: height\n });\n\n var topColor = colour.clone().multiply(light);\n var bottomColor = colour.clone().multiply(shadow);\n\n var _vertices = extruded.positions;\n var _faces = [];\n var _colours = [];\n\n var _colour;\n extruded.top.forEach((face, fi) => {\n _colour = [];\n\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n\n _faces.push(face);\n _colours.push(_colour);\n });\n\n var allFlat = true;\n\n if (extruded.sides) {\n if (allFlat) {\n allFlat = false;\n }\n\n // Set up colours for every vertex with poor-mans AO on the sides\n extruded.sides.forEach((face, fi) => {\n _colour = [];\n\n // First face is always bottom-bottom-top\n if (fi % 2 === 0) {\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n // Reverse winding for the second face\n // top-top-bottom\n } else {\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n }\n\n _faces.push(face);\n _colours.push(_colour);\n });\n }\n\n // Skip bottom as there's no point rendering it\n // allFaces.push(extruded.faces);\n\n return {\n vertices: _vertices,\n faces: _faces,\n colours: _colours,\n flat: allFlat\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var _toEarcut = function(data) {\n var dim = data[0][0].length;\n var result = {vertices: [], holes: [], dimensions: dim};\n var holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) {\n result.vertices.push(data[i][j][d]);\n }\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n\n return result;\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var _triangulate = function(contour, holes, dim) {\n // console.time('earcut');\n\n var faces = earcut(contour, holes, dim);\n var result = [];\n\n for (i = 0, il = faces.length; i < il; i += 3) {\n result.push(faces.slice(i, i + 3));\n }\n\n // console.timeEnd('earcut');\n\n return result;\n };\n\n return {\n defaultStyle: defaultStyle,\n collectFeatures: collectFeatures,\n lineStringAttributes: lineStringAttributes,\n multiLineStringAttributes: multiLineStringAttributes,\n polygonAttributes: polygonAttributes\n };\n})();\n\nexport default GeoJSON;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/GeoJSON.js\n **/","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (factory((global.topojson = global.topojson || {})));\n}(this, function (exports) { 'use strict';\n\n function noop() {}\n\n function transformAbsolute(transform) {\n if (!transform) return noop;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n point[0] = (x0 += point[0]) * kx + dx;\n point[1] = (y0 += point[1]) * ky + dy;\n };\n }\n\n function transformRelative(transform) {\n if (!transform) return noop;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n var x1 = Math.round((point[0] - dx) / kx),\n y1 = Math.round((point[1] - dy) / ky);\n point[0] = x1 - x0;\n point[1] = y1 - y0;\n x0 = x1;\n y0 = y1;\n };\n }\n\n function reverse(array, n) {\n var t, j = array.length, i = j - n;\n while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n }\n\n function bisect(a, x) {\n var lo = 0, hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (a[mid] < x) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n }\n\n function feature(topology, o) {\n return o.type === \"GeometryCollection\" ? {\n type: \"FeatureCollection\",\n features: o.geometries.map(function(o) { return feature$1(topology, o); })\n } : feature$1(topology, o);\n }\n\n function feature$1(topology, o) {\n var f = {\n type: \"Feature\",\n id: o.id,\n properties: o.properties || {},\n geometry: object(topology, o)\n };\n if (o.id == null) delete f.id;\n return f;\n }\n\n function object(topology, o) {\n var absolute = transformAbsolute(topology.transform),\n arcs = topology.arcs;\n\n function arc(i, points) {\n if (points.length) points.pop();\n for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {\n points.push(p = a[k].slice());\n absolute(p, k);\n }\n if (i < 0) reverse(points, n);\n }\n\n function point(p) {\n p = p.slice();\n absolute(p, 0);\n return p;\n }\n\n function line(arcs) {\n var points = [];\n for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n if (points.length < 2) points.push(points[0].slice());\n return points;\n }\n\n function ring(arcs) {\n var points = line(arcs);\n while (points.length < 4) points.push(points[0].slice());\n return points;\n }\n\n function polygon(arcs) {\n return arcs.map(ring);\n }\n\n function geometry(o) {\n var t = o.type;\n return t === \"GeometryCollection\" ? {type: t, geometries: o.geometries.map(geometry)}\n : t in geometryType ? {type: t, coordinates: geometryType[t](o)}\n : null;\n }\n\n var geometryType = {\n Point: function(o) { return point(o.coordinates); },\n MultiPoint: function(o) { return o.coordinates.map(point); },\n LineString: function(o) { return line(o.arcs); },\n MultiLineString: function(o) { return o.arcs.map(line); },\n Polygon: function(o) { return polygon(o.arcs); },\n MultiPolygon: function(o) { return o.arcs.map(polygon); }\n };\n\n return geometry(o);\n }\n\n function stitchArcs(topology, arcs) {\n var stitchedArcs = {},\n fragmentByStart = {},\n fragmentByEnd = {},\n fragments = [],\n emptyIndex = -1;\n\n // Stitch empty arcs first, since they may be subsumed by other arcs.\n arcs.forEach(function(i, j) {\n var arc = topology.arcs[i < 0 ? ~i : i], t;\n if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n }\n });\n\n arcs.forEach(function(i) {\n var e = ends(i),\n start = e[0],\n end = e[1],\n f, g;\n\n if (f = fragmentByEnd[start]) {\n delete fragmentByEnd[f.end];\n f.push(i);\n f.end = end;\n if (g = fragmentByStart[end]) {\n delete fragmentByStart[g.start];\n var fg = g === f ? f : f.concat(g);\n fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else if (f = fragmentByStart[end]) {\n delete fragmentByStart[f.start];\n f.unshift(i);\n f.start = start;\n if (g = fragmentByEnd[start]) {\n delete fragmentByEnd[g.end];\n var gf = g === f ? f : g.concat(f);\n fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else {\n f = [i];\n fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n }\n });\n\n function ends(i) {\n var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n else p1 = arc[arc.length - 1];\n return i < 0 ? [p1, p0] : [p0, p1];\n }\n\n function flush(fragmentByEnd, fragmentByStart) {\n for (var k in fragmentByEnd) {\n var f = fragmentByEnd[k];\n delete fragmentByStart[f.start];\n delete f.start;\n delete f.end;\n f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n fragments.push(f);\n }\n }\n\n flush(fragmentByEnd, fragmentByStart);\n flush(fragmentByStart, fragmentByEnd);\n arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\n return fragments;\n }\n\n function mesh(topology) {\n return object(topology, meshArcs.apply(this, arguments));\n }\n\n function meshArcs(topology, o, filter) {\n var arcs = [];\n\n function arc(i) {\n var j = i < 0 ? ~i : i;\n (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n }\n\n function line(arcs) {\n arcs.forEach(arc);\n }\n\n function polygon(arcs) {\n arcs.forEach(line);\n }\n\n function geometry(o) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(geometry);\n else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);\n }\n\n if (arguments.length > 1) {\n var geomsByArc = [],\n geom;\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs) { arcs.forEach(polygon); }\n };\n\n geometry(o);\n\n geomsByArc.forEach(arguments.length < 3\n ? function(geoms) { arcs.push(geoms[0].i); }\n : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n } else {\n for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);\n }\n\n return {type: \"MultiLineString\", arcs: stitchArcs(topology, arcs)};\n }\n\n function cartesianTriangleArea(triangle) {\n var a = triangle[0], b = triangle[1], c = triangle[2];\n return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));\n }\n\n function ring(ring) {\n var i = -1,\n n = ring.length,\n a,\n b = ring[n - 1],\n area = 0;\n\n while (++i < n) {\n a = b;\n b = ring[i];\n area += a[0] * b[1] - a[1] * b[0];\n }\n\n return area / 2;\n }\n\n function merge(topology) {\n return object(topology, mergeArcs.apply(this, arguments));\n }\n\n function mergeArcs(topology, objects) {\n var polygonsByArc = {},\n polygons = [],\n components = [];\n\n objects.forEach(function(o) {\n if (o.type === \"Polygon\") register(o.arcs);\n else if (o.type === \"MultiPolygon\") o.arcs.forEach(register);\n });\n\n function register(polygon) {\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n });\n });\n polygons.push(polygon);\n }\n\n function area(ring$$) {\n return Math.abs(ring(object(topology, {type: \"Polygon\", arcs: [ring$$]}).coordinates[0]));\n }\n\n polygons.forEach(function(polygon) {\n if (!polygon._) {\n var component = [],\n neighbors = [polygon];\n polygon._ = 1;\n components.push(component);\n while (polygon = neighbors.pop()) {\n component.push(polygon);\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n if (!polygon._) {\n polygon._ = 1;\n neighbors.push(polygon);\n }\n });\n });\n });\n }\n }\n });\n\n polygons.forEach(function(polygon) {\n delete polygon._;\n });\n\n return {\n type: \"MultiPolygon\",\n arcs: components.map(function(polygons) {\n var arcs = [], n;\n\n // Extract the exterior (unique) arcs.\n polygons.forEach(function(polygon) {\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n arcs.push(arc);\n }\n });\n });\n });\n\n // Stitch the arcs into one or more rings.\n arcs = stitchArcs(topology, arcs);\n\n // If more than one ring is returned,\n // at most one of these rings can be the exterior;\n // choose the one with the greatest absolute area.\n if ((n = arcs.length) > 1) {\n for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n if ((ki = area(arcs[i])) > k) {\n t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n }\n }\n }\n\n return arcs;\n })\n };\n }\n\n function neighbors(objects) {\n var indexesByArc = {}, // arc index -> array of object indexes\n neighbors = objects.map(function() { return []; });\n\n function line(arcs, i) {\n arcs.forEach(function(a) {\n if (a < 0) a = ~a;\n var o = indexesByArc[a];\n if (o) o.push(i);\n else indexesByArc[a] = [i];\n });\n }\n\n function polygon(arcs, i) {\n arcs.forEach(function(arc) { line(arc, i); });\n }\n\n function geometry(o, i) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n }\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n };\n\n objects.forEach(geometry);\n\n for (var i in indexesByArc) {\n for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n for (var k = j + 1; k < m; ++k) {\n var ij = indexes[j], ik = indexes[k], n;\n if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);\n if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);\n }\n }\n }\n\n return neighbors;\n }\n\n function compareArea(a, b) {\n return a[1][2] - b[1][2];\n }\n\n function minAreaHeap() {\n var heap = {},\n array = [],\n size = 0;\n\n heap.push = function(object) {\n up(array[object._ = size] = object, size++);\n return size;\n };\n\n heap.pop = function() {\n if (size <= 0) return;\n var removed = array[0], object;\n if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);\n return removed;\n };\n\n heap.remove = function(removed) {\n var i = removed._, object;\n if (array[i] !== removed) return; // invalid request\n if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);\n return i;\n };\n\n function up(object, i) {\n while (i > 0) {\n var j = ((i + 1) >> 1) - 1,\n parent = array[j];\n if (compareArea(object, parent) >= 0) break;\n array[parent._ = i] = parent;\n array[object._ = i = j] = object;\n }\n }\n\n function down(object, i) {\n while (true) {\n var r = (i + 1) << 1,\n l = r - 1,\n j = i,\n child = array[j];\n if (l < size && compareArea(array[l], child) < 0) child = array[j = l];\n if (r < size && compareArea(array[r], child) < 0) child = array[j = r];\n if (j === i) break;\n array[child._ = i] = child;\n array[object._ = i = j] = object;\n }\n }\n\n return heap;\n }\n\n function presimplify(topology, triangleArea) {\n var absolute = transformAbsolute(topology.transform),\n relative = transformRelative(topology.transform),\n heap = minAreaHeap();\n\n if (!triangleArea) triangleArea = cartesianTriangleArea;\n\n topology.arcs.forEach(function(arc) {\n var triangles = [],\n maxArea = 0,\n triangle,\n i,\n n,\n p;\n\n // To store each point’s effective area, we create a new array rather than\n // extending the passed-in point to workaround a Chrome/V8 bug (getting\n // stuck in smi mode). For midpoints, the initial effective area of\n // Infinity will be computed in the next step.\n for (i = 0, n = arc.length; i < n; ++i) {\n p = arc[i];\n absolute(arc[i] = [p[0], p[1], Infinity], i);\n }\n\n for (i = 1, n = arc.length - 1; i < n; ++i) {\n triangle = arc.slice(i - 1, i + 2);\n triangle[1][2] = triangleArea(triangle);\n triangles.push(triangle);\n heap.push(triangle);\n }\n\n for (i = 0, n = triangles.length; i < n; ++i) {\n triangle = triangles[i];\n triangle.previous = triangles[i - 1];\n triangle.next = triangles[i + 1];\n }\n\n while (triangle = heap.pop()) {\n var previous = triangle.previous,\n next = triangle.next;\n\n // If the area of the current point is less than that of the previous point\n // to be eliminated, use the latter's area instead. This ensures that the\n // current point cannot be eliminated without eliminating previously-\n // eliminated points.\n if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;\n else maxArea = triangle[1][2];\n\n if (previous) {\n previous.next = next;\n previous[2] = triangle[2];\n update(previous);\n }\n\n if (next) {\n next.previous = previous;\n next[0] = triangle[0];\n update(next);\n }\n }\n\n arc.forEach(relative);\n });\n\n function update(triangle) {\n heap.remove(triangle);\n triangle[1][2] = triangleArea(triangle);\n heap.push(triangle);\n }\n\n return topology;\n }\n\n var version = \"1.6.26\";\n\n exports.version = version;\n exports.mesh = mesh;\n exports.meshArcs = meshArcs;\n exports.merge = merge;\n exports.mergeArcs = mergeArcs;\n exports.feature = feature;\n exports.neighbors = neighbors;\n exports.presimplify = presimplify;\n\n}));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/topojson/build/topojson.js\n ** module id = 64\n ** module chunks = 0\n **/","var normalize = require('geojson-normalize');\n\nmodule.exports = function(inputs) {\n return {\n type: 'FeatureCollection',\n features: inputs.reduce(function(memo, input) {\n return memo.concat(normalize(input).features);\n }, [])\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/geojson-merge/index.js\n ** module id = 65\n ** module chunks = 0\n **/","module.exports = normalize;\n\nvar types = {\n Point: 'geometry',\n MultiPoint: 'geometry',\n LineString: 'geometry',\n MultiLineString: 'geometry',\n Polygon: 'geometry',\n MultiPolygon: 'geometry',\n GeometryCollection: 'geometry',\n Feature: 'feature',\n FeatureCollection: 'featurecollection'\n};\n\n/**\n * Normalize a GeoJSON feature into a FeatureCollection.\n *\n * @param {object} gj geojson data\n * @returns {object} normalized geojson data\n */\nfunction normalize(gj) {\n if (!gj || !gj.type) return null;\n var type = types[gj.type];\n if (!type) return null;\n\n if (type === 'geometry') {\n return {\n type: 'FeatureCollection',\n features: [{\n type: 'Feature',\n properties: {},\n geometry: gj\n }]\n };\n } else if (type === 'feature') {\n return {\n type: 'FeatureCollection',\n features: [gj]\n };\n } else if (type === 'featurecollection') {\n return gj;\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/geojson-normalize/index.js\n ** module id = 66\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = earcut;\n\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode) return triangles;\n\n var minX, minY, maxX, maxY, x, y, size;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and size are later used to transform coords into integers for z-order calculation\n size = Math.max(maxX - minX, maxY - minY);\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) return null;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && size) indexCurve(ear, minX, minY, size);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertice leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(ear, triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, size);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, size) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, size),\n maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\n // first look for points inside the triangle in increasing z-order\n var p = ear.nextZ;\n\n while (p && p.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.nextZ;\n }\n\n // then look for points in decreasing z-order\n p = ear.prevZ;\n\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return p;\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, size);\n earcutLinked(c, triangles, dim, minX, minY, size);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m.next;\n\n while (p !== stop) {\n if (hx >= p.x && p.x >= mx &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n }\n\n return m;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, size) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize === 0) {\n e = q;\n q = q.nextZ;\n qSize--;\n } else if (qSize === 0 || !q) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else if (p.z <= q.z) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and size of the data bounding box\nfunction zOrder(x, y, minX, minY, size) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) / size;\n y = 32767 * (y - minY) / size;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n if ((equals(p1, q1) && equals(p2, q2)) ||\n (equals(p1, q2) && equals(p2, q1))) return true;\n return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertice index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertice nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/earcut/src/earcut.js\n ** module id = 67\n ** module chunks = 0\n **/","/*\n * Extrude a polygon given its vertices and triangulated faces\n *\n * Based on:\n * https://github.com/freeman-lab/extrude\n */\n\nimport extend from 'lodash.assign';\n\nvar extrudePolygon = function(points, faces, _options) {\n var defaults = {\n top: 1,\n bottom: 0,\n closed: true\n };\n\n var options = extend({}, defaults, _options);\n\n var n = points.length;\n var positions;\n var cells;\n var topCells;\n var bottomCells;\n var sideCells;\n\n // If bottom and top values are identical then return the flat shape\n (options.top === options.bottom) ? flat() : full();\n\n function flat() {\n positions = points.map(function(p) { return [p[0], options.top, p[1]]; });\n cells = faces;\n topCells = faces;\n }\n\n function full() {\n positions = [];\n points.forEach(function(p) { positions.push([p[0], options.top, p[1]]); });\n points.forEach(function(p) { positions.push([p[0], options.bottom, p[1]]); });\n\n cells = [];\n for (var i = 0; i < n; i++) {\n if (i === (n - 1)) {\n cells.push([i + n, n, i]);\n cells.push([0, i, n]);\n } else {\n cells.push([i + n, i + n + 1, i]);\n cells.push([i + 1, i, i + n + 1]);\n }\n }\n\n sideCells = [].concat(cells);\n\n if (options.closed) {\n var top = faces;\n var bottom = top.map(function(p) { return p.map(function(v) { return v + n; }); });\n bottom = bottom.map(function(p) { return [p[0], p[2], p[1]]; });\n cells = cells.concat(top).concat(bottom);\n\n topCells = top;\n bottomCells = bottom;\n }\n }\n\n return {\n positions: positions,\n faces: cells,\n top: topCells,\n bottom: bottomCells,\n sides: sideCells\n };\n};\n\nexport default extrudePolygon;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/extrudePolygon.js\n **/","/*\n * BufferGeometry helpers\n */\n\nimport THREE from 'three';\n\nvar Buffer = (function() {\n // Merge multiple attribute objects into a single attribute object\n //\n // Attribute objects must all use the same attribute keys\n var mergeAttributes = function(attributes) {\n var lengths = {};\n\n // Find array lengths\n attributes.forEach(_attributes => {\n for (var k in _attributes) {\n if (!lengths[k]) {\n lengths[k] = 0;\n }\n\n lengths[k] += _attributes[k].length;\n }\n });\n\n var mergedAttributes = {};\n\n // Set up arrays to merge into\n for (var k in lengths) {\n mergedAttributes[k] = new Float32Array(lengths[k]);\n }\n\n var lastLengths = {};\n\n attributes.forEach(_attributes => {\n for (var k in _attributes) {\n if (!lastLengths[k]) {\n lastLengths[k] = 0;\n }\n\n mergedAttributes[k].set(_attributes[k], lastLengths[k]);\n\n lastLengths[k] += _attributes[k].length;\n }\n });\n\n return mergedAttributes;\n };\n\n var createLineGeometry = function(lines, offset) {\n var geometry = new THREE.BufferGeometry();\n\n var vertices = new Float32Array(lines.verticesCount * 3);\n var colours = new Float32Array(lines.verticesCount * 3);\n\n var pickingIds;\n if (lines.pickingIds) {\n // One component per vertex (1)\n pickingIds = new Float32Array(lines.verticesCount);\n }\n\n var _vertices;\n var _colour;\n var _pickingId;\n\n var lastIndex = 0;\n\n for (var i = 0; i < lines.vertices.length; i++) {\n _vertices = lines.vertices[i];\n _colour = lines.colours[i];\n\n if (pickingIds) {\n _pickingId = lines.pickingIds[i];\n }\n\n for (var j = 0; j < _vertices.length; j++) {\n var ax = _vertices[j][0] + offset.x;\n var ay = _vertices[j][1];\n var az = _vertices[j][2] + offset.y;\n\n var c1 = _colour[j];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n }\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(colours, 3));\n\n if (pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n return geometry;\n };\n\n // TODO: Make picking IDs optional\n var createGeometry = function(attributes, offset) {\n var geometry = new THREE.BufferGeometry();\n\n // Three components per vertex per face (3 x 3 = 9)\n var vertices = new Float32Array(attributes.facesCount * 9);\n var normals = new Float32Array(attributes.facesCount * 9);\n var colours = new Float32Array(attributes.facesCount * 9);\n\n var pickingIds;\n if (attributes.pickingIds) {\n // One component per vertex per face (1 x 3 = 3)\n pickingIds = new Float32Array(attributes.facesCount * 3);\n }\n\n var pA = new THREE.Vector3();\n var pB = new THREE.Vector3();\n var pC = new THREE.Vector3();\n\n var cb = new THREE.Vector3();\n var ab = new THREE.Vector3();\n\n var index;\n var _faces;\n var _vertices;\n var _colour;\n var _pickingId;\n var lastIndex = 0;\n for (var i = 0; i < attributes.faces.length; i++) {\n _faces = attributes.faces[i];\n _vertices = attributes.vertices[i];\n _colour = attributes.colours[i];\n\n if (pickingIds) {\n _pickingId = attributes.pickingIds[i];\n }\n\n for (var j = 0; j < _faces.length; j++) {\n // Array of vertex indexes for the face\n index = _faces[j][0];\n\n var ax = _vertices[index][0] + offset.x;\n var ay = _vertices[index][1];\n var az = _vertices[index][2] + offset.y;\n\n var c1 = _colour[j][0];\n\n index = _faces[j][1];\n\n var bx = _vertices[index][0] + offset.x;\n var by = _vertices[index][1];\n var bz = _vertices[index][2] + offset.y;\n\n var c2 = _colour[j][1];\n\n index = _faces[j][2];\n\n var cx = _vertices[index][0] + offset.x;\n var cy = _vertices[index][1];\n var cz = _vertices[index][2] + offset.y;\n\n var c3 = _colour[j][2];\n\n // Flat face normals\n // From: http://threejs.org/examples/webgl_buffergeometry.html\n pA.set(ax, ay, az);\n pB.set(bx, by, bz);\n pC.set(cx, cy, cz);\n\n cb.subVectors(pC, pB);\n ab.subVectors(pA, pB);\n cb.cross(ab);\n\n cb.normalize();\n\n var nx = cb.x;\n var ny = cb.y;\n var nz = cb.z;\n\n vertices[lastIndex * 9 + 0] = ax;\n vertices[lastIndex * 9 + 1] = ay;\n vertices[lastIndex * 9 + 2] = az;\n\n normals[lastIndex * 9 + 0] = nx;\n normals[lastIndex * 9 + 1] = ny;\n normals[lastIndex * 9 + 2] = nz;\n\n colours[lastIndex * 9 + 0] = c1[0];\n colours[lastIndex * 9 + 1] = c1[1];\n colours[lastIndex * 9 + 2] = c1[2];\n\n vertices[lastIndex * 9 + 3] = bx;\n vertices[lastIndex * 9 + 4] = by;\n vertices[lastIndex * 9 + 5] = bz;\n\n normals[lastIndex * 9 + 3] = nx;\n normals[lastIndex * 9 + 4] = ny;\n normals[lastIndex * 9 + 5] = nz;\n\n colours[lastIndex * 9 + 3] = c2[0];\n colours[lastIndex * 9 + 4] = c2[1];\n colours[lastIndex * 9 + 5] = c2[2];\n\n vertices[lastIndex * 9 + 6] = cx;\n vertices[lastIndex * 9 + 7] = cy;\n vertices[lastIndex * 9 + 8] = cz;\n\n normals[lastIndex * 9 + 6] = nx;\n normals[lastIndex * 9 + 7] = ny;\n normals[lastIndex * 9 + 8] = nz;\n\n colours[lastIndex * 9 + 6] = c3[0];\n colours[lastIndex * 9 + 7] = c3[1];\n colours[lastIndex * 9 + 8] = c3[2];\n\n if (pickingIds) {\n pickingIds[lastIndex * 3 + 0] = _pickingId;\n pickingIds[lastIndex * 3 + 1] = _pickingId;\n pickingIds[lastIndex * 3 + 2] = _pickingId;\n }\n\n lastIndex++;\n }\n }\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(colours, 3));\n\n if (pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n return geometry;\n };\n\n return {\n mergeAttributes: mergeAttributes,\n createLineGeometry: createLineGeometry,\n createGeometry: createGeometry\n };\n})();\n\nexport default Buffer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Buffer.js\n **/","import THREE from 'three';\nimport PickingShader from './PickingShader';\n\n// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\nvar PickingMaterial = function() {\n THREE.ShaderMaterial.call(this, {\n uniforms: {\n size: {\n type: 'f',\n value: 0.01,\n },\n scale: {\n type: 'f',\n value: 400,\n }\n },\n // attributes: ['position', 'id'],\n vertexShader: PickingShader.vertexShader,\n fragmentShader: PickingShader.fragmentShader\n });\n\n this.linePadding = 2;\n};\n\nPickingMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype);\n\nPickingMaterial.prototype.constructor = PickingMaterial;\n\nPickingMaterial.prototype.setPointSize = function(size) {\n this.uniforms.size.value = size;\n};\n\nPickingMaterial.prototype.setPointScale = function(scale) {\n this.uniforms.scale.value = scale;\n};\n\nexport default PickingMaterial;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingMaterial.js\n **/","// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\nvar PickingShader = {\n vertexShader: [\n\t\t'attribute float pickingId;',\n\t\t// '',\n\t\t// 'uniform float size;',\n\t\t// 'uniform float scale;',\n\t\t'',\n\t\t'varying vec4 worldId;',\n\t\t'',\n\t\t'void main() {',\n\t\t' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',\n\t\t// ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );',\n\t\t' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);',\n\t\t' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);',\n\t\t' worldId = vec4(a,1);',\n\t\t' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\t\t'}'\n\t].join('\\n'),\n\n fragmentShader: [\n\t\t'#ifdef GL_ES\\n',\n\t\t'precision highp float;\\n',\n\t\t'#endif\\n',\n\t\t'',\n\t\t'varying vec4 worldId;',\n\t\t'',\n\t\t'void main() {',\n\t\t' gl_FragColor = worldId;',\n\t\t'}'\n\t].join('\\n')\n};\n\nexport default PickingShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingShader.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\n// TODO: Allow _setBufferAttributes to use a custom function passed in to\n// generate a custom mesh\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport earcut from 'earcut';\nimport extrudePolygon from '../../util/extrudePolygon';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PolygonLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n material: null,\n onMesh: null,\n onBufferAttributes: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n color: '#ffffff',\n transparent: false,\n opacity: 1,\n blending: THREE.NormalBlending,\n height: 0\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of polygons so it's easy to support\n // MultiPolygon features (a single polygon would be a MultiPolygon with a\n // single polygon in the array)\n this._coordinates = (PolygonLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n }\n\n _onAdd(world) {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n this._setBufferAttributes();\n\n if (this.isOutput()) {\n // Set mesh if not merging elsewhere\n this._setMesh(this._bufferAttributes);\n\n // Output mesh\n this.add(this._mesh);\n }\n\n return Promise.resolve(this);\n }\n\n // Return center of polygon as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n //\n // TODO: Find proper center position instead of returning first coordinate\n // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15\n getCenter() {\n return this._center;\n }\n\n // Return polygon bounds in geographic coordinates\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n // Create and store reference to THREE.BufferAttribute data for this layer\n _setBufferAttributes() {\n var attributes;\n\n // Only use this if you know what you're doing\n if (typeof this._options.onBufferAttributes === 'function') {\n // TODO: Probably want to pass something less general as arguments,\n // though passing the instance will do for now (it's everything)\n attributes = this._options.onBufferAttributes(this);\n } else {\n var height = 0;\n\n // Convert height into world units\n if (this._options.style.height && this._options.style.height !== 0) {\n height = this._world.metresToWorld(this._options.style.height, this._pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(this._options.style.color);\n\n // Light and dark colours used for poor-mans AO gradient on object sides\n var light = new THREE.Color(0xffffff);\n var shadow = new THREE.Color(0x666666);\n\n // For each polygon\n attributes = this._projectedCoordinates.map(_projectedCoordinates => {\n // Convert coordinates to earcut format\n var _earcut = this._toEarcut(_projectedCoordinates);\n\n // Triangulate faces using earcut\n var faces = this._triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions);\n\n var groupedVertices = [];\n for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) {\n groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions));\n }\n\n var extruded = extrudePolygon(groupedVertices, faces, {\n bottom: 0,\n top: height\n });\n\n var topColor = colour.clone().multiply(light);\n var bottomColor = colour.clone().multiply(shadow);\n\n var _vertices = extruded.positions;\n var _faces = [];\n var _colours = [];\n\n var _colour;\n extruded.top.forEach((face, fi) => {\n _colour = [];\n\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n\n _faces.push(face);\n _colours.push(_colour);\n });\n\n this._flat = true;\n\n if (extruded.sides) {\n this._flat = false;\n\n // Set up colours for every vertex with poor-mans AO on the sides\n extruded.sides.forEach((face, fi) => {\n _colour = [];\n\n // First face is always bottom-bottom-top\n if (fi % 2 === 0) {\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n // Reverse winding for the second face\n // top-top-bottom\n } else {\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n }\n\n _faces.push(face);\n _colours.push(_colour);\n });\n }\n\n // Skip bottom as there's no point rendering it\n // allFaces.push(extruded.faces);\n\n var polygon = {\n vertices: _vertices,\n faces: _faces,\n colours: _colours,\n facesCount: _faces.length\n };\n\n if (this._options.interactive && this._pickingId) {\n // Inject picking ID\n polygon.pickingId = this._pickingId;\n }\n\n // Convert polygon representation to proper attribute arrays\n return this._toAttributes(polygon);\n });\n }\n\n this._bufferAttributes = Buffer.mergeAttributes(attributes);\n\n // Original attributes are no longer required so free the memory\n attributes = null;\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n // Create and store mesh from buffer attributes\n //\n // This is only called if the layer is controlling its own output\n _setMesh(attributes) {\n var geometry = new THREE.BufferGeometry();\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\n if (attributes.pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (this._options.material && this._options.material instanceof THREE.Material) {\n material = this._options.material;\n } else if (!this._world._environment._skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: this._options.style.transparent,\n opacity: this._options.style.opacity,\n blending: this._options.style.blending\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: this._options.style.transparent,\n opacity: this._options.style.opacity,\n blending: this._options.style.blending\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = this._world._environment._skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof this._options.onMesh === 'function') {\n mesh = this._options.onMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n }\n\n if (this.isFlat()) {\n material.depthWrite = false;\n mesh.renderOrder = 1;\n }\n\n if (this._options.interactive && this._pickingMesh) {\n material = new PickingMaterial();\n material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n this._pickingMesh.add(pickingMesh);\n }\n\n this._mesh = mesh;\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates[0][0][0];\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var point;\n return this._coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(latlon => {\n point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * point.x;\n this._offset.y = -1 * point.y;\n\n this._pointScale = this._world.pointScale(latlon);\n }\n\n return point;\n });\n });\n });\n }\n\n // Convert coordinates array to something earcut can understand\n _toEarcut(coordinates) {\n var dim = 2;\n var result = {vertices: [], holes: [], dimensions: dim};\n var holeIndex = 0;\n\n for (var i = 0; i < coordinates.length; i++) {\n for (var j = 0; j < coordinates[i].length; j++) {\n // for (var d = 0; d < dim; d++) {\n result.vertices.push(coordinates[i][j].x);\n result.vertices.push(coordinates[i][j].y);\n // }\n }\n if (i > 0) {\n holeIndex += coordinates[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n\n return result;\n }\n\n // Triangulate earcut-based input using earcut\n _triangulate(contour, holes, dim) {\n // console.time('earcut');\n\n var faces = earcut(contour, holes, dim);\n var result = [];\n\n for (i = 0, il = faces.length; i < il; i += 3) {\n result.push(faces.slice(i, i + 3));\n }\n\n // console.timeEnd('earcut');\n\n return result;\n }\n\n // Transform polygon representation into attribute arrays that can be used by\n // THREE.BufferGeometry\n //\n // TODO: Can this be simplified? It's messy and huge\n _toAttributes(polygon) {\n // Three components per vertex per face (3 x 3 = 9)\n var vertices = new Float32Array(polygon.facesCount * 9);\n var normals = new Float32Array(polygon.facesCount * 9);\n var colours = new Float32Array(polygon.facesCount * 9);\n\n var pickingIds;\n if (polygon.pickingId) {\n // One component per vertex per face (1 x 3 = 3)\n pickingIds = new Float32Array(polygon.facesCount * 3);\n }\n\n var pA = new THREE.Vector3();\n var pB = new THREE.Vector3();\n var pC = new THREE.Vector3();\n\n var cb = new THREE.Vector3();\n var ab = new THREE.Vector3();\n\n var index;\n\n var _faces = polygon.faces;\n var _vertices = polygon.vertices;\n var _colour = polygon.colours;\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = polygon.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _faces.length; i++) {\n // Array of vertex indexes for the face\n index = _faces[i][0];\n\n var ax = _vertices[index][0];\n var ay = _vertices[index][1];\n var az = _vertices[index][2];\n\n var c1 = _colour[i][0];\n\n index = _faces[i][1];\n\n var bx = _vertices[index][0];\n var by = _vertices[index][1];\n var bz = _vertices[index][2];\n\n var c2 = _colour[i][1];\n\n index = _faces[i][2];\n\n var cx = _vertices[index][0];\n var cy = _vertices[index][1];\n var cz = _vertices[index][2];\n\n var c3 = _colour[i][2];\n\n // Flat face normals\n // From: http://threejs.org/examples/webgl_buffergeometry.html\n pA.set(ax, ay, az);\n pB.set(bx, by, bz);\n pC.set(cx, cy, cz);\n\n cb.subVectors(pC, pB);\n ab.subVectors(pA, pB);\n cb.cross(ab);\n\n cb.normalize();\n\n var nx = cb.x;\n var ny = cb.y;\n var nz = cb.z;\n\n vertices[lastIndex * 9 + 0] = ax;\n vertices[lastIndex * 9 + 1] = ay;\n vertices[lastIndex * 9 + 2] = az;\n\n normals[lastIndex * 9 + 0] = nx;\n normals[lastIndex * 9 + 1] = ny;\n normals[lastIndex * 9 + 2] = nz;\n\n colours[lastIndex * 9 + 0] = c1[0];\n colours[lastIndex * 9 + 1] = c1[1];\n colours[lastIndex * 9 + 2] = c1[2];\n\n vertices[lastIndex * 9 + 3] = bx;\n vertices[lastIndex * 9 + 4] = by;\n vertices[lastIndex * 9 + 5] = bz;\n\n normals[lastIndex * 9 + 3] = nx;\n normals[lastIndex * 9 + 4] = ny;\n normals[lastIndex * 9 + 5] = nz;\n\n colours[lastIndex * 9 + 3] = c2[0];\n colours[lastIndex * 9 + 4] = c2[1];\n colours[lastIndex * 9 + 5] = c2[2];\n\n vertices[lastIndex * 9 + 6] = cx;\n vertices[lastIndex * 9 + 7] = cy;\n vertices[lastIndex * 9 + 8] = cz;\n\n normals[lastIndex * 9 + 6] = nx;\n normals[lastIndex * 9 + 7] = ny;\n normals[lastIndex * 9 + 8] = nz;\n\n colours[lastIndex * 9 + 6] = c3[0];\n colours[lastIndex * 9 + 7] = c3[1];\n colours[lastIndex * 9 + 8] = c3[2];\n\n if (pickingIds) {\n pickingIds[lastIndex * 3 + 0] = _pickingId;\n pickingIds[lastIndex * 3 + 1] = _pickingId;\n pickingIds[lastIndex * 3 + 2] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n vertices: vertices,\n normals: normals,\n colours: colours\n };\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the polygon is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiPolygon GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0][0][0]);\n }\n\n // TODO: Make sure this is cleaning everything\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PolygonLayer;\n\nvar noNew = function(coordinates, options) {\n return new PolygonLayer(coordinates, options);\n};\n\nexport {noNew as polygonLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PolygonLayer.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Provide alternative output using tubes and splines / curves\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\n// TODO: Allow _setBufferAttributes to use a custom function passed in to\n// generate a custom mesh\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PolylineLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n material: null,\n onMesh: null,\n onBufferAttributes: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n lineOpacity: 1,\n lineTransparent: false,\n lineColor: '#ffffff',\n lineWidth: 1,\n lineBlending: THREE.NormalBlending\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of lines so it's easy to support\n // MultiLineString features (a single line would be a MultiLineString with a\n // single line in the array)\n this._coordinates = (PolylineLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n // Polyline features are always flat (for now at least)\n this._flat = true;\n }\n\n _onAdd(world) {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n this._setBufferAttributes();\n\n if (this.isOutput()) {\n // Set mesh if not merging elsewhere\n this._setMesh(this._bufferAttributes);\n\n // Output mesh\n this.add(this._mesh);\n }\n\n return Promise.resolve(this);\n }\n\n // Return center of polyline as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n //\n // TODO: Find proper center position instead of returning first coordinate\n // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59\n getCenter() {\n return this._center;\n }\n\n // Return line bounds in geographic coordinates\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n // Create and store reference to THREE.BufferAttribute data for this layer\n _setBufferAttributes() {\n var attributes;\n\n // Only use this if you know what you're doing\n if (typeof this._options.onBufferAttributes === 'function') {\n // TODO: Probably want to pass something less general as arguments,\n // though passing the instance will do for now (it's everything)\n attributes = this._options.onBufferAttributes(this);\n } else {\n var height = 0;\n\n // Convert height into world units\n if (this._options.style.lineHeight) {\n height = this._world.metresToWorld(this._options.style.lineHeight, this._pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(this._options.style.lineColor);\n\n // For each line\n attributes = this._projectedCoordinates.map(_projectedCoordinates => {\n var _vertices = [];\n var _colours = [];\n\n // Connect coordinate with the next to make a pair\n //\n // LineSegments requires pairs of vertices so repeat the last point if\n // there's an odd number of vertices\n var nextCoord;\n _projectedCoordinates.forEach((coordinate, index) => {\n _colours.push([colour.r, colour.g, colour.b]);\n _vertices.push([coordinate.x, height, coordinate.y]);\n\n nextCoord = (_projectedCoordinates[index + 1]) ? _projectedCoordinates[index + 1] : coordinate;\n\n _colours.push([colour.r, colour.g, colour.b]);\n _vertices.push([nextCoord.x, height, nextCoord.y]);\n });\n\n var line = {\n vertices: _vertices,\n colours: _colours,\n verticesCount: _vertices.length\n };\n\n if (this._options.interactive && this._pickingId) {\n // Inject picking ID\n line.pickingId = this._pickingId;\n }\n\n // Convert line representation to proper attribute arrays\n return this._toAttributes(line);\n });\n }\n\n this._bufferAttributes = Buffer.mergeAttributes(attributes);\n\n // Original attributes are no longer required so free the memory\n attributes = null;\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n // Create and store mesh from buffer attributes\n //\n // This is only called if the layer is controlling its own output\n _setMesh(attributes) {\n var geometry = new THREE.BufferGeometry();\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n\n if (attributes.normals) {\n geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n }\n\n geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\n if (attributes.pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n var style = this._options.style;\n var material;\n\n if (this._options.material && this._options.material instanceof THREE.Material) {\n material = this._options.material;\n } else {\n material = new THREE.LineBasicMaterial({\n vertexColors: THREE.VertexColors,\n linewidth: style.lineWidth,\n transparent: style.lineTransparent,\n opacity: style.lineOpacity,\n blending: style.lineBlending\n });\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof this._options.onMesh === 'function') {\n mesh = this._options.onMesh(geometry, material);\n } else {\n mesh = new THREE.LineSegments(geometry, material);\n\n if (style.lineRenderOrder !== undefined) {\n material.depthWrite = false;\n mesh.renderOrder = style.lineRenderOrder;\n }\n\n mesh.castShadow = true;\n // mesh.receiveShadow = true;\n }\n\n // TODO: Allow this to be overridden, or copy mesh instead of creating a new\n // one just for picking\n if (this._options.interactive && this._pickingMesh) {\n material = new PickingMaterial();\n // material.side = THREE.BackSide;\n\n // Make the line wider / easier to pick\n material.linewidth = style.lineWidth + material.linePadding;\n\n var pickingMesh = new THREE.LineSegments(geometry, material);\n this._pickingMesh.add(pickingMesh);\n }\n\n this._mesh = mesh;\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates[0][0];\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(_coordinates => {\n return _coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var point;\n return this._coordinates.map(_coordinates => {\n return _coordinates.map(latlon => {\n point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * point.x;\n this._offset.y = -1 * point.y;\n\n this._pointScale = this._world.pointScale(latlon);\n }\n\n return point;\n });\n });\n }\n\n // Transform line representation into attribute arrays that can be used by\n // THREE.BufferGeometry\n //\n // TODO: Can this be simplified? It's messy and huge\n _toAttributes(line) {\n // Three components per vertex\n var vertices = new Float32Array(line.verticesCount * 3);\n var colours = new Float32Array(line.verticesCount * 3);\n\n var pickingIds;\n if (line.pickingId) {\n // One component per vertex\n pickingIds = new Float32Array(line.verticesCount);\n }\n\n var _vertices = line.vertices;\n var _colour = line.colours;\n\n var normals;\n var _normals;\n if (line.normals) {\n normals = new Float32Array(line.verticesCount * 3);\n _normals = line.normals;\n }\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = line.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _vertices.length; i++) {\n var ax = _vertices[i][0];\n var ay = _vertices[i][1];\n var az = _vertices[i][2];\n\n var nx;\n var ny;\n var nz;\n if (_normals) {\n nx = _normals[i][0];\n ny = _normals[i][1];\n nz = _normals[i][2];\n }\n\n var c1 = _colour[i];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n if (normals) {\n normals[lastIndex * 3 + 0] = nx;\n normals[lastIndex * 3 + 1] = ny;\n normals[lastIndex * 3 + 2] = nz;\n }\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n vertices: vertices,\n colours: colours\n };\n\n if (normals) {\n attributes.normals = normals;\n }\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the line is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiLineString GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0][0]);\n }\n\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PolylineLayer;\n\nvar noNew = function(coordinates, options) {\n return new PolylineLayer(coordinates, options);\n};\n\nexport {noNew as polylineLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PolylineLayer.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Point features may be using custom models / meshes and so an approach\n// needs to be found to allow these to be brokwn down into buffer attributes for\n// merging\n//\n// Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry\n// and pull out the attributes\n\n// TODO: Support sprite objects using textures\n\n// TODO: Provide option to billboard geometry so it always faces the camera\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PointLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // THREE.Geometry or THREE.BufferGeometry to use for point output\n geometry: null,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n material: null,\n onMesh: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n pointColor: '#ff0000'\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of points so it's easy to support\n // MultiPoint features (a single point would be a MultiPoint with a\n // single point in the array)\n this._coordinates = (PointLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n // Point features are always flat (for now at least)\n //\n // This won't always be the case once custom point objects / meshes are\n // added\n this._flat = true;\n }\n\n _onAdd(world) {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n this._setBufferAttributes();\n\n if (this.isOutput()) {\n // Set mesh if not merging elsewhere\n this._setMesh(this._bufferAttributes);\n\n // Output mesh\n this.add(this._mesh);\n }\n\n return Promise.resolve(this);\n }\n\n // Return center of point as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n getCenter() {\n return this._center;\n }\n\n // Return point bounds in geographic coordinates\n //\n // While not useful for single points, it could be useful for MultiPoint\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n // Create and store reference to THREE.BufferAttribute data for this layer\n _setBufferAttributes() {\n var height = 0;\n\n // Convert height into world units\n if (this._options.style.pointHeight) {\n height = this._world.metresToWorld(this._options.style.pointHeight, this._pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(this._options.style.pointColor);\n\n var geometry;\n\n // Use default geometry if none has been provided or the provided geometry\n // isn't valid\n if (!this._options.geometry || (!this._options.geometry instanceof THREE.Geometry || !this._options.geometry instanceof THREE.BufferGeometry)) {\n // Debug geometry for points is a thin bar\n //\n // TODO: Allow point geometry to be customised / overridden\n var geometryWidth = this._world.metresToWorld(25, this._pointScale);\n var geometryHeight = this._world.metresToWorld(200, this._pointScale);\n var _geometry = new THREE.BoxGeometry(geometryWidth, geometryHeight, geometryWidth);\n\n // Shift geometry up so it sits on the ground\n _geometry.translate(0, geometryHeight * 0.5, 0);\n\n // Pull attributes out of debug geometry\n geometry = new THREE.BufferGeometry().fromGeometry(_geometry);\n } else {\n if (this._options.geometry instanceof THREE.BufferGeometry) {\n geometry = this._options.geometry;\n } else {\n geometry = new THREE.BufferGeometry().fromGeometry(this._options.geometry);\n }\n }\n\n // For each point\n var attributes = this._projectedCoordinates.map(coordinate => {\n var _vertices = [];\n var _normals = [];\n var _colours = [];\n\n var _geometry = geometry.clone();\n\n _geometry.translate(coordinate.x, height, coordinate.y);\n\n var _vertices = _geometry.attributes.position.clone().array;\n var _normals = _geometry.attributes.normal.clone().array;\n var _colours = _geometry.attributes.color.clone().array;\n\n for (var i = 0; i < _colours.length; i += 3) {\n _colours[i] = colour.r;\n _colours[i + 1] = colour.g;\n _colours[i + 2] = colour.b;\n }\n\n var _point = {\n vertices: _vertices,\n normals: _normals,\n colours: _colours\n };\n\n if (this._options.interactive && this._pickingId) {\n // Inject picking ID\n // point.pickingId = this._pickingId;\n _point.pickingIds = new Float32Array(_vertices.length / 3);\n for (var i = 0; i < _point.pickingIds.length; i++) {\n _point.pickingIds[i] = this._pickingId;\n }\n }\n\n // Convert point representation to proper attribute arrays\n // return this._toAttributes(_point);\n return _point;\n });\n\n this._bufferAttributes = Buffer.mergeAttributes(attributes);\n\n // Original attributes are no longer required so free the memory\n attributes = null;\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n // Create and store mesh from buffer attributes\n //\n // This is only called if the layer is controlling its own output\n _setMesh(attributes) {\n var geometry = new THREE.BufferGeometry();\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(attributes.vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(attributes.normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(attributes.colours, 3));\n\n if (attributes.pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(attributes.pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n\n if (this._options.material && this._options.material instanceof THREE.Material) {\n material = this._options.material;\n } else if (!this._world._environment._skybox) {\n material = new THREE.MeshBasicMaterial({\n vertexColors: THREE.VertexColors\n // side: THREE.BackSide\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors\n // side: THREE.BackSide\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = this._world._environment._skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof this._options.onMesh === 'function') {\n mesh = this._options.onMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n // mesh.receiveShadow = true;\n }\n\n if (this._options.interactive && this._pickingMesh) {\n material = new PickingMaterial();\n // material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n this._pickingMesh.add(pickingMesh);\n }\n\n this._mesh = mesh;\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates;\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var _point;\n return this._coordinates.map(latlon => {\n _point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * _point.x;\n this._offset.y = -1 * _point.y;\n\n this._pointScale = this._world.pointScale(latlon);\n }\n\n return _point;\n });\n }\n\n // Transform line representation into attribute arrays that can be used by\n // THREE.BufferGeometry\n //\n // TODO: Can this be simplified? It's messy and huge\n _toAttributes(line) {\n // Three components per vertex\n var vertices = new Float32Array(line.verticesCount * 3);\n var colours = new Float32Array(line.verticesCount * 3);\n\n var pickingIds;\n if (line.pickingId) {\n // One component per vertex\n pickingIds = new Float32Array(line.verticesCount);\n }\n\n var _vertices = line.vertices;\n var _colour = line.colours;\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = line.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _vertices.length; i++) {\n var ax = _vertices[i][0];\n var ay = _vertices[i][1];\n var az = _vertices[i][2];\n\n var c1 = _colour[i];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n vertices: vertices,\n colours: colours\n };\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the line is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiPoint GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0]);\n }\n\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PointLayer;\n\nvar noNew = function(coordinates, options) {\n return new PointLayer(coordinates, options);\n};\n\nexport {noNew as pointLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PointLayer.js\n **/","import GeoJSONTileLayer from './GeoJSONTileLayer';\nimport extend from 'lodash.assign';\n\nclass TopoJSONTileLayer extends GeoJSONTileLayer {\n constructor(path, options) {\n var defaults = {\n topojson: true\n };\n\n options = extend({}, defaults, options);\n\n super(path, options);\n }\n}\n\nexport default TopoJSONTileLayer;\n\nvar noNew = function(path, options) {\n return new TopoJSONTileLayer(path, options);\n};\n\nexport {noNew as topoJSONTileLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/TopoJSONTileLayer.js\n **/","import GeoJSONLayer from './GeoJSONLayer';\nimport extend from 'lodash.assign';\n\nclass TopoJSONLayer extends GeoJSONLayer {\n constructor(topojson, options) {\n var defaults = {\n topojson: true\n };\n\n options = extend({}, defaults, options);\n\n super(topojson, options);\n }\n}\n\nexport default TopoJSONLayer;\n\nvar noNew = function(topojson, options) {\n return new TopoJSONLayer(topojson, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as topoJSONLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/TopoJSONLayer.js\n **/","// TODO: A lot of these utils don't need to be in separate, tiny files\n\nimport wrapNum from './wrapNum';\nimport extrudePolygon from './extrudePolygon';\nimport GeoJSON from './GeoJSON';\nimport Buffer from './Buffer';\n\nconst Util = {};\n\nUtil.wrapNum = wrapNum;\nUtil.extrudePolygon = extrudePolygon;\nUtil.GeoJSON = GeoJSON;\nUtil.Buffer = Buffer;\n\nexport default Util;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/index.js\n **/","/*\n * Wrap the given number to lie within a certain range (eg. longitude)\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js\n */\n\nvar wrapNum = function(x, range, includeMax) {\n var max = range[1];\n var min = range[0];\n var d = max - min;\n return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\n};\n\nexport default wrapNum;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/wrapNum.js\n **/"],"sourceRoot":"/source/"} \ No newline at end of file +{"version":3,"sources":["webpack:///webpack/universalModuleDefinition","vizicities.min.js","webpack:/webpack/bootstrap 64490f947fe5779175f4","webpack:///src/vizicities.js","webpack:///src/World.js","webpack:///~/eventemitter3/index.js","webpack:///~/lodash.assign/index.js","webpack:///~/lodash.keys/index.js","webpack:///~/lodash.rest/index.js","webpack:///src/geo/Geo.js","webpack:///src/geo/LatLon.js","webpack:///src/geo/Point.js","webpack:///src/engine/Engine.js","webpack:/external \"THREE\"","webpack:///src/engine/Scene.js","webpack:///src/engine/DOMScene3D.js","webpack:///src/engine/DOMScene2D.js","webpack:///src/engine/Renderer.js","webpack:///src/engine/DOMRenderer3D.js","webpack:///src/vendor/CSS3DRenderer.js","webpack:///src/engine/DOMRenderer2D.js","webpack:///src/vendor/CSS2DRenderer.js","webpack:///src/engine/Camera.js","webpack:///src/engine/Picking.js","webpack:///src/engine/PickingScene.js","webpack:///~/lodash.throttle/index.js","webpack:///~/lodash.debounce/index.js","webpack:///src/engine/EffectComposer.js","webpack:///src/vendor/EffectComposer.js","webpack:///src/vendor/CopyShader.js","webpack:///src/vendor/ShaderPass.js","webpack:///src/vendor/MaskPass.js","webpack:///src/vendor/RenderPass.js","webpack:///src/vendor/HorizontalTiltShiftShader.js","webpack:///src/vendor/VerticalTiltShiftShader.js","webpack:///src/vendor/FXAAShader.js","webpack:///src/layer/environment/EnvironmentLayer.js","webpack:///src/layer/Layer.js","webpack:///~/shortid/index.js","webpack:///~/shortid/lib/index.js","webpack:///~/shortid/lib/alphabet.js","webpack:///~/shortid/lib/random/random-from-seed.js","webpack:///~/shortid/lib/encode.js","webpack:///~/shortid/lib/random/random-byte-browser.js","webpack:///~/shortid/lib/decode.js","webpack:///~/shortid/lib/is-valid.js","webpack:///~/shortid/lib/util/cluster-worker-id-browser.js","webpack:///src/layer/environment/Skybox.js","webpack:///src/layer/environment/Sky.js","webpack:///src/util/Worker.js","webpack:///src/util/WorkerPool.js","webpack:///src/util/WorkerPoolWorker.js","webpack:///src/controls/index.js","webpack:///src/controls/Controls.Orbit.js","webpack:///src/vendor/OrbitControls.js","webpack:///~/hammerjs/hammer.js","webpack:/external \"TweenLite\"","webpack:///src/layer/LayerGroup.js","webpack:///src/layer/tile/ImageTileLayer.js","webpack:///src/layer/tile/TileLayer.js","webpack:///src/layer/tile/TileCache.js","webpack:///~/lru-cache/lib/lru-cache.js","webpack:///~/pseudomap/map.js","webpack:///~/process/browser.js","webpack:///~/pseudomap/pseudomap.js","webpack:///~/util/util.js","webpack:///~/util/support/isBufferBrowser.js","webpack:///~/inherits/inherits_browser.js","webpack:///~/yallist/yallist.js","webpack:///src/layer/tile/ImageTile.js","webpack:///src/layer/tile/Tile.js","webpack:///src/vendor/BoxHelper.js","webpack:///src/layer/tile/ImageTileLayerBaseMaterial.js","webpack:///src/layer/tile/GeoJSONTileLayer.js","webpack:///src/layer/tile/GeoJSONTile.js","webpack:///src/layer/GeoJSONLayer.js","webpack:///~/reqwest/reqwest.js","webpack:///src/util/GeoJSON.js","webpack:///~/topojson/build/topojson.js","webpack:///~/geojson-merge/index.js","webpack:///~/geojson-normalize/index.js","webpack:///~/earcut/src/earcut.js","webpack:///src/util/extrudePolygon.js","webpack:///src/util/Buffer.js","webpack:///src/engine/PickingMaterial.js","webpack:///src/engine/PickingShader.js","webpack:///src/layer/geometry/PolygonLayer.js","webpack:///src/layer/geometry/PolylineLayer.js","webpack:///src/layer/geometry/PointLayer.js","webpack:///src/layer/GeoJSONWorkerLayer.js","webpack:///src/util/Stringify.js","webpack:///src/layer/tile/TopoJSONTileLayer.js","webpack:///src/layer/TopoJSONLayer.js","webpack:///src/layer/TopoJSONWorkerLayer.js","webpack:///src/util/index.js","webpack:///src/util/wrapNum.js"],"names":["root","factory","exports","module","require","define","amd","this","__WEBPACK_EXTERNAL_MODULE_10__","__WEBPACK_EXTERNAL_MODULE_53__","modules","__webpack_require__","moduleId","installedModules","id","loaded","call","m","c","p","_interopRequireDefault","obj","__esModule","default","Object","defineProperty","value","_World","_World2","_controlsIndex","_controlsIndex2","_geoGeoJs","_geoGeoJs2","_layerLayer","_layerLayer2","_layerLayerGroup","_layerEnvironmentEnvironmentLayer","_layerEnvironmentEnvironmentLayer2","_layerTileImageTileLayer","_layerTileImageTileLayer2","_layerTileGeoJSONTileLayer","_layerTileGeoJSONTileLayer2","_layerTileTopoJSONTileLayer","_layerTileTopoJSONTileLayer2","_layerTileGeoJSONTile","_layerTileGeoJSONTile2","_layerGeoJSONLayer","_layerGeoJSONLayer2","_layerTopoJSONLayer","_layerTopoJSONLayer2","_layerGeoJSONWorkerLayer","_layerGeoJSONWorkerLayer2","_layerTopoJSONWorkerLayer","_layerTopoJSONWorkerLayer2","_layerGeometryPolygonLayer","_layerGeometryPolygonLayer2","_layerGeometryPolylineLayer","_layerGeometryPolylineLayer2","_layerGeometryPointLayer","_layerGeometryPointLayer2","_geoPoint","_geoPoint2","_geoLatLon","_geoLatLon2","_enginePickingMaterial","_enginePickingMaterial2","_utilIndex","_utilIndex2","VIZI","version","World","world","Controls","Geo","Layer","layer","EnvironmentLayer","environmentLayer","ImageTileLayer","imageTileLayer","GeoJSONTileLayer","geoJSONTileLayer","GeoJSONTile","geoJSONTile","TopoJSONTileLayer","topoJSONTileLayer","GeoJSONLayer","geoJSONLayer","TopoJSONLayer","topoJSONLayer","GeoJSONWorkerLayer","geoJSONWorkerLayer","TopoJSONWorkerLayer","topoJSONWorkerLayer","PolygonLayer","polygonLayer","PolylineLayer","polylineLayer","PointLayer","pointLayer","Point","point","LatLon","latLon","PickingMaterial","Util","_classCallCheck","instance","Constructor","TypeError","_inherits","subClass","superClass","prototype","create","constructor","enumerable","writable","configurable","setPrototypeOf","__proto__","_createClass","defineProperties","target","props","i","length","descriptor","key","protoProps","staticProps","_get","_x","_x2","_x3","_again","object","property","receiver","Function","desc","getOwnPropertyDescriptor","undefined","getter","get","parent","getPrototypeOf","_eventemitter3","_eventemitter32","_lodashAssign","_lodashAssign2","_geoGeo","_geoGeo2","_engineEngine","_engineEngine2","_utilWorker","_utilWorker2","_EventEmitter","domId","options","_this","defaults","skybox","postProcessing","_layers","_controls","_initContainer","_initAttribution","_initEngine","_initEnvironment","then","_initEvents","_pause","_update","maxWorkers","workerScript","createWorkers","_container","document","getElementById","message","element","createElement","classList","add","additionalElem","innerHTML","appendChild","addEventListener","e","currentTarget","parentNode","toggle","_engine","_environment","addTo","on","_onControlsMoveEnd","_point","x","z","_resetView","pointToLatLon","latlon","emit","_moveStart","_move","_moveEnd","_lastPosition","delta","clock","getDelta","window","requestAnimationFrame","bind","forEach","controls","update","container","span","dataset","elem","querySelectorAll","remove","_originLatlon","_originPoint","project","latLonToPoint","projectedPoint","_subtract","unproject","accurate","pointScale","metres","zoom","metresToWorld","worldUnits","worldToMetres","_camera","_this2","push","isOutput","isOutputToScene","_scene","_object3D","_domScene3D","_domObject3D","_domScene2D","_domObject2D","Promise","resolve","reject","_addToWorld","_options","attribution","_addAttribution","layerIndex","indexOf","splice","controlsIndex","stop","off","removeControls","destroy","removeLayer","firstChild","removeChild","noNew","EE","fn","context","once","EventEmitter","has","hasOwnProperty","prefix","_events","eventNames","name","events","names","slice","getOwnPropertySymbols","concat","listeners","event","exists","evt","available","l","ee","Array","a1","a2","a3","a4","a5","args","len","arguments","removeListener","apply","j","listener","removeAllListeners","addListener","setMaxListeners","prefixed","assignValue","objValue","eq","baseProperty","copyObject","source","customizer","index","newValue","createAssigner","assigner","rest","sources","guard","isIterateeCall","isIndex","MAX_SAFE_INTEGER","reIsUint","test","isObject","type","isArrayLike","isPrototype","Ctor","proto","objectProto","other","isLength","getLength","isFunction","tag","objectToString","funcTag","genTag","keys","toString","propertyIsEnumerable","nonEnumShadows","valueOf","assign","baseTimes","n","iteratee","result","baseHas","getPrototype","baseKeys","nativeKeys","nativeGetPrototype","indexKeys","isArray","isString","isArguments","String","isArrayLikeObject","argsTag","isObjectLike","stringTag","isProto","indexes","skipIndexes","func","thisArg","start","FUNC_ERROR_TEXT","nativeMax","toInteger","array","otherArgs","isSymbol","symbolTag","toFinite","toNumber","INFINITY","sign","MAX_INTEGER","remainder","NAN","replace","reTrim","isBinary","reIsBinary","reIsOctal","freeParseInt","reIsBadHex","parseInt","Math","max","_LatLon","_Point","R","MAX_LATITUDE","ECC","ECC2","d","PI","lat","min","sin","lon","log","atan","exp","y","projected","k","rad","a","sinLat","sinLat2","cosLat","cos","pow","v","sqrt","h","metresToProjected","projectedToMetres","projectedUnits","projectedMetres","scale","scaledMetres","realMetres","LN2","distance","latlon1","latlon2","lat1","lat2","lon1","lon2","deltaLat","deltaLon","halfDeltaLat","halfDeltaLon","atan2","acos","bounds","alt","isNaN","Error","b","lng","round","clone","_add","_three","_three2","_Scene","_Scene2","_DOMScene3D","_DOMScene3D2","_DOMScene2D","_DOMScene2D2","_Renderer","_Renderer2","_DOMRenderer3D","_DOMRenderer3D2","_DOMRenderer2D","_DOMRenderer2D2","_Camera","_Camera2","_Picking","_Picking2","_EffectComposer","_EffectComposer2","_vendorRenderPass","_vendorRenderPass2","_vendorShaderPass","_vendorShaderPass2","_vendorCopyShader","_vendorCopyShader2","_vendorHorizontalTiltShiftShader","_vendorHorizontalTiltShiftShader2","_vendorVerticalTiltShiftShader","_vendorVerticalTiltShiftShader2","_vendorFXAAShader","_vendorFXAAShader2","Engine","console","_world","antialias","_renderer","_domRenderer3D","_domRenderer2D","_picking","Clock","_frustum","Frustum","_initPostProcessing","renderPass","fxaaPass","hblurPass","vblurPass","bluriness","uniforms","r","copyPass","renderToScreen","_composer","addPass","self","updatePostProcessingSize","width","clientWidth","height","clientHeight","pixelRatio","resolution","set","render","child","children","geometry","dispose","material","map","_clock","scene","Scene","renderer","WebGLRenderer","setClearColor","setPixelRatio","gammaInput","gammaOutput","shadowMap","enabled","domElement","updateSize","setSize","_vendorCSS3DRenderer","CSS3DRenderer","style","position","top","CSS3DObject","Object3D","CSS3DSprite","REVISION","_width","_height","_widthHalf","_heightHalf","matrix","Matrix4","cache","camera","fov","objects","overflow","WebkitTransformStyle","MozTransformStyle","oTransformStyle","transformStyle","cameraElement","getSize","epsilon","abs","Number","EPSILON","getCameraCSSMatrix","elements","getObjectCSSMatrix","renderObject","copy","matrixWorldInverse","transpose","copyPosition","matrixWorld","cachedStyle","WebkitTransform","MozTransform","oTransform","transform","tan","degToRad","WebkitPerspective","MozPerspective","oPerspective","perspective","updateMatrixWorld","getInverse","_vendorCSS2DRenderer","CSS2DRenderer","CSS2DObject","vector","Vector3","viewMatrix","viewProjectionMatrix","frustum","setFromMatrixPosition","applyProjection","containsPoint","display","multiplyMatrices","projectionMatrix","setFromMatrix","PerspectiveCamera","aspect","updateProjectionMatrix","_PickingScene","_PickingScene2","_lodashThrottle","_lodashThrottle2","nextId","Picking","_raycaster","Raycaster","linePrecision","_pickingScene","_pickingTexture","WebGLRenderTarget","texture","minFilter","LinearFilter","generateMipmaps","_nextId","_resizeTexture","_resizeHandler","_throttledMouseMoveHandler","_onMouseMove","_mouseUpHandler","_onMouseUp","_onWorldMove","button","clientX","offsetLeft","clientY","offsetTop","normalisedPoint","_pick","_needUpdate","size","_pixelBuffer","Uint8Array","readRenderTargetPixels","hover","setFromCamera","_point3d","intersects","intersectObjects","_point2d","mesh","removeEventListener","throttle","wait","leading","trailing","debounce","maxWait","invokeFunc","time","lastArgs","lastThis","lastInvokeTime","leadingEdge","timerId","setTimeout","timerExpired","remainingWait","timeSinceLastCall","lastCallTime","timeSinceLastInvoke","maxing","nativeMin","shouldInvoke","now","trailingEdge","clearTimeout","cancel","flush","debounced","isInvoking","Date","_vendorEffectComposer","_vendorEffectComposer2","composer","_CopyShader","_CopyShader2","_ShaderPass","_ShaderPass2","_MaskPass","_MaskPass2","EffectComposer","renderTarget","getPixelRatio","floor","canvas","parameters","magFilter","format","RGBAFormat","stencilBuffer","renderTarget1","renderTarget2","writeBuffer","readBuffer","passes","error","swapBuffers","tmp","pass","insertPass","maskActive","il","needsSwap","stencilFunc","NOTEQUAL","EQUAL","ClearMaskPass","reset","CopyShader","tDiffuse","opacity","vertexShader","join","fragmentShader","ShaderPass","shader","textureID","ShaderMaterial","UniformsUtils","defines","clear","OrthographicCamera","quad","Mesh","PlaneBufferGeometry","MaskPass","inverse","colorMask","depthMask","writeValue","clearValue","enable","STENCIL_TEST","stencilOp","REPLACE","ALWAYS","clearStencil","KEEP","disable","RenderPass","overrideMaterial","clearColor","clearAlpha","oldClearColor","Color","oldClearAlpha","getClearColor","getClearAlpha","HorizontalTiltShiftShader","VerticalTiltShiftShader","FXAAShader","Vector2","_Layer2","_Layer3","_Skybox","_Skybox2","_Layer","_initLights","_initSkybox","_skyboxLight","DirectionalLight","castShadow","shadow","left","right","bottom","near","far","mapSize","directionalLight","directionalLight2","directionalLight3","_skybox","_mesh","step","gridHelper","GridHelper","_shortid","_shortid2","_engineScene","generate","output","outputToScene","_dom3D","_dom2D","addLayer","_onAdd","getNextId","visible","_pickingMesh","removeDOM3D","removeDOM2D","str","seconds","REDUCE_TIME","previousSeconds","counter","encode","alphabet","lookup","clusterWorkerId","seed","seedValue","worker","workerId","characters","newCharacters","shuffled","decode","isValid","setCharacters","_alphabet_","ORIGINAL","unique","split","filter","item","ind","arr","lastIndexOf","setSeed","randomFromSeed","previousSeed","shuffle","characterIndex","sourceArray","targetArray","nextValue","getShuffled","alphabetShuffled","getNextValue","_seed_","number","done","loopCounter","randomByte","crypto","getRandomValues","random","dest","msCrypto","substr","isShortId","_Sky","_Sky2","cubemap","Skybox","light","_light","_settings","turbidity","reileigh","mieCoefficient","mieDirectionalG","luminance","inclination","azimuth","_updateUniforms","_throttledWorldUpdate","_cubeCamera","CubeCamera","cubeTarget","_sky","_skyScene","_sunSphere","SphereBufferGeometry","MeshBasicMaterial","color","skyboxUniforms","skyboxMat","side","BackSide","BoxGeometry","_updateSkybox","settings","theta","phi","sunPosition","intensity","updateCubeMap","ShaderLib","Sky","skyShader","skyUniforms","skyMat","skyGeo","skyMesh","_WorkerPool","_WorkerPool2","Worker","pool","_maxWorkers","numThreads","exec","method","transferrables","_WorkerPoolWorker","_WorkerPoolWorker2","DEBUG","WorkerPool","workers","tasks","workerPromises","createWorker","all","performance","find","busy","deferred","task","processTasks","promise","_this3","getFreeWorker","shift","WorkerPoolWorker","ready","onStartup","data","onMessage","postMessage","payload","_ControlsOrbit","_ControlsOrbit2","Orbit","orbit","_vendorOrbitControls","_vendorOrbitControls2","_TweenLite","_TweenLite2","lagSmoothing","animate","pointDelta","metresDelta","angle","angleDelta","duration","animationTime","_flyTarget","diff","subVectors","_flyTween","prev","onUpdate","tween","deltaX","deltaZ","panLeft","panUp","onComplete","onUpdateParams","onCompleteParams","callbackScope","ease","Power1","easeInOut","zoomTime","_zoomTweenIn","dollyIn","_zoomTweenOut","delay","dollyOut","noZoom","flyToPoint","addControls","maxPolarAngle","_hammerjs","_hammerjs2","OrbitControls","getAutoRotationAngle","scope","autoRotateSpeed","getZoomScale","zoomSpeed","rotateLeft","thetaDelta","rotateUp","phiDelta","dollyScale","minZoom","maxZoom","zoomChanged","warn","enableZoom","handleMouseDownRotate","rotateStart","handleMouseDownDolly","dollyStart","handleMouseDownPan","panStart","handleMouseMoveRotate","rotateEnd","rotateDelta","body","rotateSpeed","handleMouseMoveDolly","dollyEnd","dollyDelta","handleMouseMovePan","panEnd","panDelta","pan","handleMouseUp","handleMouseWheel","wheelDelta","detail","handleKeyDown","keyCode","UP","keyPanSpeed","BOTTOM","LEFT","RIGHT","handleTouchStartRotate","pointers","pageX","pageY","handleTouchStartDolly","dx","dy","handleTouchStartPan","deltaY","handleTouchMoveRotate","handleTouchMoveDolly","handleTouchMovePan","handleTouchEnd","onMouseDown","preventDefault","mouseButtons","ORBIT","enableRotate","state","STATE","ROTATE","ZOOM","DOLLY","PAN","enablePan","NONE","onMouseMove","onMouseUp","dispatchEvent","startEvent","endEvent","onMouseWheel","stopPropagation","onKeyDown","enableKeys","onTouchStart","touches","TOUCH_ROTATE","TOUCH_DOLLY","TOUCH_PAN","onTouchMove","onTouchEnd","onContextMenu","minDistance","maxDistance","Infinity","minPolarAngle","minAzimuthAngle","maxAzimuthAngle","enableDamping","dampingFactor","autoRotate","MOUSE","MIDDLE","target0","position0","zoom0","getPolarAngle","getAzimuthalAngle","changeEvent","offset","quat","Quaternion","setFromUnitVectors","up","quatInverse","lastPosition","lastQuaternion","sub","applyQuaternion","EPS","radius","panOffset","lookAt","distanceToSquared","dot","quaternion","objectMatrix","te","multiplyScalar","adjDist","targetDistance","hammer","direction","DIRECTION_ALL","threshold","pointerType","EventDispatcher","center","noRotate","noPan","noKeys","staticMoving","constraint","dynamicDampingFactor","__WEBPACK_AMD_DEFINE_RESULT__","exportName","setTimeoutContext","timeout","bindFn","invokeArrayArg","arg","each","iterator","deprecate","deprecationMessage","stack","inherit","base","properties","childP","baseP","_super","boolOrFn","val","TYPE_FUNCTION","ifUndefined","val1","val2","addEventListeners","types","handler","splitStr","removeEventListeners","hasParent","node","inStr","trim","inArray","src","findByKey","toArray","uniqueArray","sort","results","values","prop","camelProp","toUpperCase","VENDOR_PREFIXES","uniqueId","_uniqueId","getWindowForElement","doc","ownerDocument","defaultView","parentWindow","Input","manager","callback","inputTarget","domHandler","ev","init","createInputInstance","Type","inputClass","SUPPORT_POINTER_EVENTS","PointerEventInput","SUPPORT_ONLY_TOUCH","TouchInput","SUPPORT_TOUCH","TouchMouseInput","MouseInput","inputHandler","eventType","input","pointersLen","changedPointersLen","changedPointers","isFirst","INPUT_START","isFinal","INPUT_END","INPUT_CANCEL","session","computeInputData","recognize","prevInput","pointersLength","firstInput","simpleCloneInputData","firstMultiple","offsetCenter","getCenter","timeStamp","deltaTime","getAngle","getDistance","computeDeltaXY","offsetDirection","getDirection","overallVelocity","getVelocity","overallVelocityX","overallVelocityY","getScale","rotation","getRotation","maxPointers","computeIntervalInputData","srcEvent","offsetDelta","prevDelta","velocity","velocityX","velocityY","last","lastInterval","COMPUTE_INTERVAL","DIRECTION_NONE","DIRECTION_LEFT","DIRECTION_RIGHT","DIRECTION_UP","DIRECTION_DOWN","p1","p2","PROPS_XY","end","PROPS_CLIENT_XY","evEl","MOUSE_ELEMENT_EVENTS","evWin","MOUSE_WINDOW_EVENTS","pressed","POINTER_ELEMENT_EVENTS","POINTER_WINDOW_EVENTS","store","pointerEvents","SingleTouchInput","evTarget","SINGLE_TOUCH_TARGET_EVENTS","SINGLE_TOUCH_WINDOW_EVENTS","started","normalizeSingleTouches","changed","changedTouches","TOUCH_TARGET_EVENTS","targetIds","getTouches","allTouches","INPUT_MOVE","identifier","targetTouches","changedTargetTouches","touch","mouse","primaryTouch","lastTouches","recordTouches","eventData","setLastTouch","lastTouch","lts","removeLastTouch","DEDUP_TIMEOUT","isSyntheticEvent","t","DEDUP_DISTANCE","TouchAction","cleanTouchActions","actions","TOUCH_ACTION_NONE","hasPanX","TOUCH_ACTION_PAN_X","hasPanY","TOUCH_ACTION_PAN_Y","TOUCH_ACTION_MANIPULATION","TOUCH_ACTION_AUTO","getTouchActionProps","NATIVE_TOUCH_ACTION","touchMap","cssSupports","CSS","supports","Recognizer","STATE_POSSIBLE","simultaneous","requireFail","stateStr","STATE_CANCELLED","STATE_ENDED","STATE_CHANGED","STATE_BEGAN","directionStr","getRecognizerByNameIfManager","otherRecognizer","recognizer","AttrRecognizer","PanRecognizer","pX","pY","PinchRecognizer","PressRecognizer","_timer","_input","RotateRecognizer","SwipeRecognizer","TapRecognizer","pTime","pCenter","count","Hammer","recognizers","preset","Manager","handlers","oldCssProps","touchAction","toggleCssProps","recognizeWith","requireFailure","cssProps","triggerDomEvent","gestureEvent","createEvent","initEvent","gesture","TEST_ELEMENT","nextKey","extend","merge","MOBILE_REGEX","navigator","userAgent","INPUT_TYPE_TOUCH","INPUT_TYPE_PEN","INPUT_TYPE_MOUSE","INPUT_TYPE_KINECT","DIRECTION_HORIZONTAL","DIRECTION_VERTICAL","MOUSE_INPUT_MAP","mousedown","mousemove","mouseup","which","POINTER_INPUT_MAP","pointerdown","pointermove","pointerup","pointercancel","pointerout","IE10_POINTER_TYPE_ENUM","2","3","4","5","MSPointerEvent","PointerEvent","removePointer","eventTypeNormalized","toLowerCase","isTouch","storeIndex","pointerId","SINGLE_TOUCH_INPUT_MAP","touchstart","touchmove","touchend","touchcancel","TOUCH_INPUT_MAP","inputEvent","inputData","isMouse","sourceCapabilities","firesTouchEvents","PREFIXED_TOUCH_ACTION","TOUCH_ACTION_COMPUTE","TOUCH_ACTION_MAP","compute","getTouchAction","preventDefaults","prevented","hasNone","isTapPointer","isTapMovement","isTapTouchTime","preventSrc","STATE_RECOGNIZED","STATE_FAILED","dropRecognizeWith","dropRequireFailure","hasRequireFailures","canRecognizeWith","additionalEvent","tryEmit","canEmit","inputDataClone","process","attrTest","optionPointers","isRecognized","directionTest","hasMoved","inOut","validPointers","validMovement","validTime","taps","interval","posThreshold","validTouchTime","failTimeout","validInterval","validMultiTap","tapCount","VERSION","domEvents","userSelect","touchSelect","touchCallout","contentZooming","userDrag","tapHighlightColor","STOP","FORCED_STOP","force","stopped","curRecognizer","existing","Tap","Pan","Swipe","Pinch","Rotate","Press","freeGlobal","LayerGroup","layerGroup","_TileLayer2","_TileLayer3","_ImageTile","_ImageTile2","_ImageTileLayerBaseMaterial","_TileLayer","path","_path","_calculateLOD","_onWorldUpdate","_outputTiles","_moveBaseLayer","_baseLayer","quadcode","_TileCache","_TileCache2","TileLayer","picking","maxCache","maxLOD","_destroy","_tileCache","tile","_destroyTile","_tileList","_minLOD","_maxLOD","_tiles","_tilesPicking","addToPicking","getCamera","projScreenMatrix","getBounds","intersectsBox","Box3","_removeTiles","isReady","getMesh","getPickingMesh","_stop","_updateFrustum","checkList","_checklist","_requestTile","_divide","_quadcode","tileList","_tileInFrustum","dist","isAborted","requestTileAsync","missingTiles","includes","_abortRequest","currentItem","getQuadcode","_screenSpaceError","minDepth","maxDepth","quality","getSide","getTile","_createTile","setTile","removeFromPicking","_lruCache","_lruCache2","TileCache","cacheLimit","onDestroyTile","_cache","tileCache","priv","sym","symbols","makeSymbol","naiveLength","LRUCache","lc","stale","maxAge","forEachStep","thisp","hit","isStale","del","doUse","unshiftNode","walker","tail","removeNode","Entry","Map","util","Yallist","hasSymbol","Symbol","mL","allowStale","mA","lC","rforEach","head","next","dump","dumpLru","inspect","opts","extras","as","didFirst","unshift","peek","pop","load","expiresAt","prune","env","npm_package_name","npm_lifecycle_script","TEST_PSEUDOMAP","cleanUpNextTick","draining","currentQueue","queue","queueIndex","drainQueue","cachedSetTimeout","run","cachedClearTimeout","Item","fun","noop","nextTick","title","browser","argv","versions","binding","cwd","chdir","dir","umask","PseudoMap","kv","same","_index","s","_data","res","entries","global","ctx","seen","stylize","stylizeNoColor","depth","colors","isBoolean","showHidden","_extend","isUndefined","customInspect","stylizeWithColor","formatValue","styleType","styles","arrayToHash","hash","idx","recurseTimes","ret","primitive","formatPrimitive","visibleKeys","getOwnPropertyNames","isError","formatError","isRegExp","RegExp","isDate","braces","toUTCString","formatArray","formatProperty","reduceToSingleString","simple","JSON","stringify","isNumber","isNull","match","line","numLinesEst","reduce","cur","ar","isNullOrUndefined","re","isPrimitive","o","pad","timestamp","getHours","getMinutes","getSeconds","getDate","months","getMonth","formatRegExp","f","_","msg","deprecated","warned","throwDeprecation","traceDeprecation","trace","noDeprecation","debugEnviron","debugs","debuglog","NODE_DEBUG","pid","bold","italic","underline","white","grey","black","blue","cyan","green","magenta","red","yellow","special","boolean","null","string","date","regexp","isBuffer","inherits","origin","fill","readUInt8","ctor","superCtor","super_","TempCtor","list","Node","pushNode","forEachReverse","getReverse","mapReverse","initial","acc","reduceReverse","toArrayReverse","from","to","sliceReverse","reverse","_Tile2","_Tile3","_vendorBoxHelper","ImageTile","_Tile","_createMesh","_image","_center","geom","_side","MeshStandardMaterial","depthWrite","roughness","metalness","envMap","getRenderTarget","localMesh","receiveShadow","getContext","font","fillStyle","fillText","_tile","Texture","LinearMipMapLinearFilter","anisotropy","needsUpdate","transparent","urlParams","url","_getTileURL","image","_aborted","_texture","_ready","crossOrigin","imageTile","r2d","tileURLRegex","Tile","_layer","_quadcodeToTile","_boundsLatLon","_tileBoundsWGS84","_boundsWorld","_tileBoundsFromWGS84","_boundsToCenter","_centerLatlon","_getSide","_pointScale","destroyMesh","fromCharCode","lastIndex","mask","q","boundsWGS84","sw","ne","_tile2lon","w","_tile2lat","BoxHelper","indices","Uint16Array","positions","Float32Array","BufferGeometry","setIndex","BufferAttribute","addAttribute","LineSegments","LineBasicMaterial","linewidth","box","setFromObject","isEmpty","attributes","computeBoundingSphere","colour","skyboxTarget","fillRect","_GeoJSONTile","_GeoJSONTile2","_onControlsMove","_pauseOutput","_disableOutput","newOptions","_GeoJSONLayer","_GeoJSONWorkerLayer","_reqwest","_reqwest2","_utilGeoJSON","_utilGeoJSON2","_utilBuffer","_defaultStyle","defaultStyle","interactive","topojson","onEachFeature","polygonMaterial","onPolygonMesh","onPolygonBufferAttributes","polylineMaterial","onPolylineMesh","onPolylineBufferAttributes","pointGeometry","pointMaterial","onPointMesh","keepFeatures","_request","_geojsonLayer","_processTileData","headers","err","GeoJSONClass","_geojson","abort","_LayerGroup2","_LayerGroup3","_utilBuffer2","_geometryPolygonLayer","_geometryPolygonLayer2","_geometryPolylineLayer","_geometryPolylineLayer2","_geometryPointLayer","_geometryPointLayer2","_LayerGroup","geojson","THREE","_requestData","_processData","collectFeatures","features","layerPromises","feature","_featureToLayer","polygonAttributes","polygonOutlineAttributes","polygonAttributeLengths","normals","polygonFlat","polylineAttributes","polylineAttributeLengths","polylineFlat","pointAttributes","pointAttributeLengths","pointFlat","getBufferAttributes","outlineBufferAttributes","getOutlineBufferAttributes","isFlat","pickingIds","mergedPolygonOutlineAttributes","mergedPolygonAttributes","mergeAttributes","_setPolygonMesh","_polygonMesh","outlineRenderOrder","lineRenderOrder","renderOrder","outlineWidth","lineWidth","_setPolylineMesh","pickingMesh","mergedPolylineAttributes","_polylineMesh","mergedPointAttributes","_setPointMesh","_pointMesh","clearBufferAttributes","clearCoordinates","attributeLengths","flat","SetMesh","coordinates","onBufferAttributes","lineMaterial","__WEBPACK_AMD_DEFINE_FACTORY__","definition","succeed","protocol","protocolRe","location","httpsRe","twoHundo","request","status","response","handleReadyState","success","_timedOut","readyState","onreadystatechange","setHeaders","http","defaultHeaders","isAFormData","FormData","requestedWith","contentType","setRequestHeader","setCredentials","withCredentials","generalCallback","lastValue","urlappend","handleJsonp","reqId","uniqid","cbkey","cbval","reqwest","getcallbackPrefix","cbreg","script","isIE10","async","htmlFor","onload","onclick","getRequest","toQueryString","sendWait","xhr","open","xDomainRequest","onerror","onprogress","send","Reqwest","setType","header","complete","resp","_completeHandlers","getResponseHeader","filteredResponse","globalSetupOptions","dataFilter","responseText","parse","eval","responseXML","parseError","errorCode","reason","_responseArgs","_fulfilled","_successHandler","_fulfillmentHandlers","timedOut","_erred","_errorHandlers","normalize","serial","el","cb","ch","ra","tagName","optCb","disabled","checked","selectedIndex","selected","eachFormElement","serializeSubtags","tags","fa","byTag","serializeQueryString","serializeArray","serializeHash","buildParams","traditional","rbracket","XHR2","ex","callbackPrefix","xmlHttpRequest","accept","*","xml","html","text","json","js","XMLHttpRequest","XDomainRequest","ActiveXObject","retry","fail","always","catch","serialize","opt","nodeType","trad","enc","encodeURIComponent","compat","ajaxSetup","_interopRequireWildcard","newObj","_topojson2","_geojsonMerge","_geojsonMerge2","_earcut","_earcut2","_extrudePolygon","_extrudePolygon2","GeoJSON","outline","outlineColor","blending","NormalBlending","lineOpacity","lineTransparent","lineColor","lineBlending","_topojson","collections","tk","gk","lineStringAttributes","nextCoord","_coords","_colours","coordinate","g","vertices","colours","multiLineStringAttributes","coord","earcutData","_toEarcut","faces","_triangulate","holes","dimensions","groupedVertices","_colour","extruded","topColor","multiply","bottomColor","_vertices","_faces","face","fi","allFlat","sides","dim","holeIndex","contour","transformAbsolute","x0","y0","kx","ky","translate","transformRelative","x1","y1","bisect","lo","hi","mid","topology","geometries","feature$1","arc","points","arcs","absolute","ring","polygon","geometryType","MultiPoint","LineString","MultiLineString","Polygon","MultiPolygon","stitchArcs","ends","p0","dp","fragmentByEnd","fragmentByStart","stitchedArcs","fragments","emptyIndex","fg","gf","meshArcs","geomsByArc","geoms","cartesianTriangleArea","triangle","area","mergeArcs","register","ring$$","polygonsByArc","polygons","components","component","neighbors","ki","indexesByArc","ij","ik","compareArea","minAreaHeap","down","heap","removed","presimplify","triangleArea","relative","triangles","maxArea","previous","inputs","memo","gj","GeometryCollection","Feature","FeatureCollection","earcut","holeIndices","hasHoles","outerLen","outerNode","linkedList","minX","minY","maxX","maxY","eliminateHoles","earcutLinked","clockwise","signedArea","insertNode","equals","filterPoints","again","steiner","ear","indexCurve","isEarHashed","isEar","cureLocalIntersections","splitEarcut","pointInTriangle","minTX","minTY","maxTX","maxTY","minZ","zOrder","maxZ","nextZ","prevZ","locallyInside","isValidDiagonal","splitPolygon","getLeftmost","compareX","eliminateHole","hole","findHoleBridge","hx","hy","qx","mx","my","tanMin","sortLinked","numMerges","pSize","qSize","inSize","leftmost","ax","ay","bx","by","cx","cy","px","py","intersectsPolygon","middleInside","q1","q2","inside","b2","an","bp","sum","deviation","polygonArea","trianglesArea","flatten","extrudePolygon","cells","topCells","full","sideCells","closed","bottomCells","Buffer","mergeFloat32Arrays","arrays","Int32Array","_array","mergedArray","splitFloat32Array","subarray","mergeUint8Arrays","splitUint8Array","lengths","_attributes","mergedAttributes","lastLengths","createLineGeometry","lines","verticesCount","_pickingId","az","c1","computeBoundingBox","createGeometry","facesCount","pA","pB","pC","ab","bz","c2","cz","c3","cross","nx","ny","nz","textEncoder","TextEncoder","textDecoder","TextDecoder","stringToUint8Array","uint8ArrayToString","_PickingShader","_PickingShader2","linePadding","setPointSize","setPointScale","PickingShader","_earcut3","_utilExtrudePolygon","_utilExtrudePolygon2","_coordinates","isSingle","_setCoordinates","_setPickingId","_addPickingEvents","SetBufferAttributes","_projectedCoordinates","_bufferAttributes","outlineAttributes","_outlineBufferAttributes","_flat","tops","getPickingId","point2d","point3d","_bounds","_convertCoordinates","_projectedBounds","_projectCoordinates","_offset","ToEarcut","Triangulate","_tops","outlineColour","Set2DOutline","pickingId","ToAttributes","_ring","verticeCount","first","Material","vertexColors","VertexColors","envMapIntensity","MeshPhongMaterial","t1","t2","t3","lineHeight","_PolygonLayer","pointColor","pointHeight","Geometry","geometryWidth","geometryHeight","_geometry","fromGeometry","_normals","normal","_slicedToArray","sliceIterator","_arr","_n","_d","_e","_s","_i","_utilStringify","_utilStringify2","onEachFeatureWorker","onAddAttributes","onClick","_process","functionToString","buffer","_execWorker","RequestGeoJSON","fc","originPoint","timeEnd","processPromises","_processPolygonResults","polylines","_processPolylineResults","_processPointResults","splitOutlinePositions","splitOutlineColors","splitPositions","splitNormals","splitColors","splitTops","splitProperties","flats","outlineObjects","polygonOutlineAttributeLengths","_addPicking","customAttribute","customAttributes","bufferAttributes","outputPromises","_results","polygonResult","outlineResult","_this4","_this5","_this6","_style","_properties","_pointGeometry","ProcessGeoJSON","stringToFunction","converted","polyline","polygonBufferPromises","polylineBufferPromises","pointBufferPromises","ProcessPolygons","ProcessPolylines","ProcessPoints","polygonPromises","outlinePositions","outlineColors","mergedOutlineAttributes","mergedProperties","polylinePromises","pointPromises","Stringify","_GeoJSONTileLayer2","_GeoJSONTileLayer3","_GeoJSONTileLayer","_GeoJSONLayer2","_GeoJSONLayer3","_GeoJSONWorkerLayer2","_GeoJSONWorkerLayer3","_wrapNum","_wrapNum2","_GeoJSON","_GeoJSON2","_Buffer","_Buffer2","_Worker","_Worker2","_Stringify","_Stringify2","wrapNum","range","includeMax"],"mappings":"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","file":"vizicities.min.js","sourcesContent":["(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"THREE\"), require(\"TweenLite\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"THREE\", \"TweenLite\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VIZI\"] = factory(require(\"THREE\"), require(\"TweenLite\"));\n\telse\n\t\troot[\"VIZI\"] = factory(root[\"THREE\"], root[\"TweenLite\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_53__) {\nreturn \n\n\n/** WEBPACK FOOTER **\n ** webpack/universalModuleDefinition\n **/","(function webpackUniversalModuleDefinition(root, factory) {\n\tif(typeof exports === 'object' && typeof module === 'object')\n\t\tmodule.exports = factory(require(\"THREE\"), require(\"TweenLite\"));\n\telse if(typeof define === 'function' && define.amd)\n\t\tdefine([\"THREE\", \"TweenLite\"], factory);\n\telse if(typeof exports === 'object')\n\t\texports[\"VIZI\"] = factory(require(\"THREE\"), require(\"TweenLite\"));\n\telse\n\t\troot[\"VIZI\"] = factory(root[\"THREE\"], root[\"TweenLite\"]);\n})(this, function(__WEBPACK_EXTERNAL_MODULE_10__, __WEBPACK_EXTERNAL_MODULE_53__) {\nreturn /******/ (function(modules) { // webpackBootstrap\n/******/ \t// The module cache\n/******/ \tvar installedModules = {};\n/******/\n/******/ \t// The require function\n/******/ \tfunction __webpack_require__(moduleId) {\n/******/\n/******/ \t\t// Check if module is in cache\n/******/ \t\tif(installedModules[moduleId])\n/******/ \t\t\treturn installedModules[moduleId].exports;\n/******/\n/******/ \t\t// Create a new module (and put it into the cache)\n/******/ \t\tvar module = installedModules[moduleId] = {\n/******/ \t\t\texports: {},\n/******/ \t\t\tid: moduleId,\n/******/ \t\t\tloaded: false\n/******/ \t\t};\n/******/\n/******/ \t\t// Execute the module function\n/******/ \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n/******/\n/******/ \t\t// Flag the module as loaded\n/******/ \t\tmodule.loaded = true;\n/******/\n/******/ \t\t// Return the exports of the module\n/******/ \t\treturn module.exports;\n/******/ \t}\n/******/\n/******/\n/******/ \t// expose the modules object (__webpack_modules__)\n/******/ \t__webpack_require__.m = modules;\n/******/\n/******/ \t// expose the module cache\n/******/ \t__webpack_require__.c = installedModules;\n/******/\n/******/ \t// __webpack_public_path__\n/******/ \t__webpack_require__.p = \"\";\n/******/\n/******/ \t// Load entry module and return exports\n/******/ \treturn __webpack_require__(0);\n/******/ })\n/************************************************************************/\n/******/ ([\n/* 0 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _World = __webpack_require__(1);\n\t\n\tvar _World2 = _interopRequireDefault(_World);\n\t\n\tvar _controlsIndex = __webpack_require__(49);\n\t\n\tvar _controlsIndex2 = _interopRequireDefault(_controlsIndex);\n\t\n\tvar _geoGeoJs = __webpack_require__(6);\n\t\n\tvar _geoGeoJs2 = _interopRequireDefault(_geoGeoJs);\n\t\n\tvar _layerLayer = __webpack_require__(34);\n\t\n\tvar _layerLayer2 = _interopRequireDefault(_layerLayer);\n\t\n\tvar _layerLayerGroup = __webpack_require__(54);\n\t\n\tvar _layerLayerGroup2 = _interopRequireDefault(_layerLayerGroup);\n\t\n\tvar _layerEnvironmentEnvironmentLayer = __webpack_require__(33);\n\t\n\tvar _layerEnvironmentEnvironmentLayer2 = _interopRequireDefault(_layerEnvironmentEnvironmentLayer);\n\t\n\tvar _layerTileImageTileLayer = __webpack_require__(55);\n\t\n\tvar _layerTileImageTileLayer2 = _interopRequireDefault(_layerTileImageTileLayer);\n\t\n\tvar _layerTileGeoJSONTileLayer = __webpack_require__(70);\n\t\n\tvar _layerTileGeoJSONTileLayer2 = _interopRequireDefault(_layerTileGeoJSONTileLayer);\n\t\n\tvar _layerTileTopoJSONTileLayer = __webpack_require__(89);\n\t\n\tvar _layerTileTopoJSONTileLayer2 = _interopRequireDefault(_layerTileTopoJSONTileLayer);\n\t\n\tvar _layerTileGeoJSONTile = __webpack_require__(71);\n\t\n\tvar _layerTileGeoJSONTile2 = _interopRequireDefault(_layerTileGeoJSONTile);\n\t\n\tvar _layerGeoJSONLayer = __webpack_require__(72);\n\t\n\tvar _layerGeoJSONLayer2 = _interopRequireDefault(_layerGeoJSONLayer);\n\t\n\tvar _layerTopoJSONLayer = __webpack_require__(90);\n\t\n\tvar _layerTopoJSONLayer2 = _interopRequireDefault(_layerTopoJSONLayer);\n\t\n\tvar _layerGeoJSONWorkerLayer = __webpack_require__(87);\n\t\n\tvar _layerGeoJSONWorkerLayer2 = _interopRequireDefault(_layerGeoJSONWorkerLayer);\n\t\n\tvar _layerTopoJSONWorkerLayer = __webpack_require__(91);\n\t\n\tvar _layerTopoJSONWorkerLayer2 = _interopRequireDefault(_layerTopoJSONWorkerLayer);\n\t\n\tvar _layerGeometryPolygonLayer = __webpack_require__(84);\n\t\n\tvar _layerGeometryPolygonLayer2 = _interopRequireDefault(_layerGeometryPolygonLayer);\n\t\n\tvar _layerGeometryPolylineLayer = __webpack_require__(85);\n\t\n\tvar _layerGeometryPolylineLayer2 = _interopRequireDefault(_layerGeometryPolylineLayer);\n\t\n\tvar _layerGeometryPointLayer = __webpack_require__(86);\n\t\n\tvar _layerGeometryPointLayer2 = _interopRequireDefault(_layerGeometryPointLayer);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoPoint2 = _interopRequireDefault(_geoPoint);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoLatLon2 = _interopRequireDefault(_geoLatLon);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilIndex = __webpack_require__(92);\n\t\n\tvar _utilIndex2 = _interopRequireDefault(_utilIndex);\n\t\n\tvar VIZI = {\n\t version: '0.3',\n\t\n\t // Public API\n\t World: _World2['default'],\n\t world: _World.world,\n\t Controls: _controlsIndex2['default'],\n\t Geo: _geoGeoJs2['default'],\n\t Layer: _layerLayer2['default'],\n\t layer: _layerLayer.layer,\n\t EnvironmentLayer: _layerEnvironmentEnvironmentLayer2['default'],\n\t environmentLayer: _layerEnvironmentEnvironmentLayer.environmentLayer,\n\t ImageTileLayer: _layerTileImageTileLayer2['default'],\n\t imageTileLayer: _layerTileImageTileLayer.imageTileLayer,\n\t GeoJSONTileLayer: _layerTileGeoJSONTileLayer2['default'],\n\t geoJSONTileLayer: _layerTileGeoJSONTileLayer.geoJSONTileLayer,\n\t GeoJSONTile: _layerTileGeoJSONTile2['default'],\n\t geoJSONTile: _layerTileGeoJSONTile.geoJSONTile,\n\t TopoJSONTileLayer: _layerTileTopoJSONTileLayer2['default'],\n\t topoJSONTileLayer: _layerTileTopoJSONTileLayer.topoJSONTileLayer,\n\t GeoJSONLayer: _layerGeoJSONLayer2['default'],\n\t geoJSONLayer: _layerGeoJSONLayer.geoJSONLayer,\n\t TopoJSONLayer: _layerTopoJSONLayer2['default'],\n\t topoJSONLayer: _layerTopoJSONLayer.topoJSONLayer,\n\t GeoJSONWorkerLayer: _layerGeoJSONWorkerLayer2['default'],\n\t geoJSONWorkerLayer: _layerGeoJSONWorkerLayer.geoJSONWorkerLayer,\n\t TopoJSONWorkerLayer: _layerTopoJSONWorkerLayer2['default'],\n\t topoJSONWorkerLayer: _layerTopoJSONWorkerLayer.topoJSONWorkerLayer,\n\t PolygonLayer: _layerGeometryPolygonLayer2['default'],\n\t polygonLayer: _layerGeometryPolygonLayer.polygonLayer,\n\t PolylineLayer: _layerGeometryPolylineLayer2['default'],\n\t polylineLayer: _layerGeometryPolylineLayer.polylineLayer,\n\t PointLayer: _layerGeometryPointLayer2['default'],\n\t pointLayer: _layerGeometryPointLayer.pointLayer,\n\t Point: _geoPoint2['default'],\n\t point: _geoPoint.point,\n\t LatLon: _geoLatLon2['default'],\n\t latLon: _geoLatLon.latLon,\n\t PickingMaterial: _enginePickingMaterial2['default'],\n\t Util: _utilIndex2['default']\n\t};\n\t\n\texports['default'] = VIZI;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 1 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _geoGeo = __webpack_require__(6);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _engineEngine = __webpack_require__(9);\n\t\n\tvar _engineEngine2 = _interopRequireDefault(_engineEngine);\n\t\n\tvar _layerEnvironmentEnvironmentLayer = __webpack_require__(33);\n\t\n\tvar _layerEnvironmentEnvironmentLayer2 = _interopRequireDefault(_layerEnvironmentEnvironmentLayer);\n\t\n\tvar _utilWorker = __webpack_require__(46);\n\t\n\tvar _utilWorker2 = _interopRequireDefault(_utilWorker);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// Pretty much any event someone using ViziCities would need will be emitted or\n\t// proxied by World (eg. render events, etc)\n\t\n\tvar World = (function (_EventEmitter) {\n\t _inherits(World, _EventEmitter);\n\t\n\t function World(domId, options) {\n\t var _this = this;\n\t\n\t _classCallCheck(this, World);\n\t\n\t _get(Object.getPrototypeOf(World.prototype), 'constructor', this).call(this);\n\t\n\t var defaults = {\n\t skybox: false,\n\t postProcessing: false\n\t };\n\t\n\t this.options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t this._layers = [];\n\t this._controls = [];\n\t\n\t this._initContainer(domId);\n\t this._initAttribution();\n\t this._initEngine();\n\t\n\t this._initEnvironment().then(function () {\n\t _this._initEvents();\n\t\n\t _this._pause = false;\n\t\n\t // Kick off the update and render loop\n\t _this._update();\n\t });\n\t }\n\t\n\t _createClass(World, [{\n\t key: 'createWorkers',\n\t value: function createWorkers(maxWorkers, workerScript) {\n\t return _utilWorker2['default'].createWorkers(maxWorkers, workerScript);\n\t }\n\t }, {\n\t key: '_initContainer',\n\t value: function _initContainer(domId) {\n\t this._container = document.getElementById(domId);\n\t }\n\t }, {\n\t key: '_initAttribution',\n\t value: function _initAttribution() {\n\t var message = 'ViziCities | Attribution';\n\t\n\t var element = document.createElement('div');\n\t element.classList.add('vizicities-attribution');\n\t\n\t var additionalElem = document.createElement('div');\n\t additionalElem.id = 'attribution-container';\n\t\n\t element.innerHTML = message;\n\t element.appendChild(additionalElem);\n\t\n\t this._container.appendChild(element);\n\t\n\t document.getElementById('show-attr').addEventListener('click', function (e) {\n\t e.currentTarget.parentNode.classList.toggle('is-visible');\n\t });\n\t }\n\t }, {\n\t key: '_initEngine',\n\t value: function _initEngine() {\n\t this._engine = new _engineEngine2['default'](this._container, this);\n\t\n\t // Engine events\n\t //\n\t // Consider proxying these through events on World for public access\n\t // this._engine.on('preRender', () => {});\n\t // this._engine.on('postRender', () => {});\n\t }\n\t }, {\n\t key: '_initEnvironment',\n\t value: function _initEnvironment() {\n\t // Not sure if I want to keep this as a private API\n\t //\n\t // Makes sense to allow others to customise their environment so perhaps\n\t // add some method of disable / overriding the environment settings\n\t this._environment = new _layerEnvironmentEnvironmentLayer2['default']({\n\t skybox: this.options.skybox\n\t });\n\t\n\t return this._environment.addTo(this);\n\t }\n\t }, {\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t this.on('controlsMoveEnd', this._onControlsMoveEnd);\n\t }\n\t }, {\n\t key: '_onControlsMoveEnd',\n\t value: function _onControlsMoveEnd(point) {\n\t var _point = (0, _geoPoint.point)(point.x, point.z);\n\t this._resetView(this.pointToLatLon(_point), _point);\n\t }\n\t\n\t // Reset world view\n\t }, {\n\t key: '_resetView',\n\t value: function _resetView(latlon, point) {\n\t this.emit('preResetView');\n\t\n\t this._moveStart();\n\t this._move(latlon, point);\n\t this._moveEnd();\n\t\n\t this.emit('postResetView');\n\t }\n\t }, {\n\t key: '_moveStart',\n\t value: function _moveStart() {\n\t this.emit('moveStart');\n\t }\n\t }, {\n\t key: '_move',\n\t value: function _move(latlon, point) {\n\t this._lastPosition = latlon;\n\t this.emit('move', latlon, point);\n\t }\n\t }, {\n\t key: '_moveEnd',\n\t value: function _moveEnd() {\n\t this.emit('moveEnd');\n\t }\n\t }, {\n\t key: '_update',\n\t value: function _update() {\n\t if (this._pause) {\n\t return;\n\t }\n\t\n\t var delta = this._engine.clock.getDelta();\n\t\n\t // Once _update is called it will run forever, for now\n\t window.requestAnimationFrame(this._update.bind(this));\n\t\n\t // Update controls\n\t this._controls.forEach(function (controls) {\n\t controls.update(delta);\n\t });\n\t\n\t this.emit('preUpdate', delta);\n\t this._engine.update(delta);\n\t this.emit('postUpdate', delta);\n\t }\n\t }, {\n\t key: '_addAttribution',\n\t value: function _addAttribution(id, message) {\n\t var container = document.getElementById('attribution-container');\n\t\n\t var span = document.createElement('p');\n\t span.dataset.layer = id;\n\t span.innerHTML = message;\n\t\n\t container.appendChild(span);\n\t }\n\t }, {\n\t key: '_removeAttribution',\n\t value: function _removeAttribution(id) {\n\t var elem = document.querySelectorAll('#attribution-container [data-layer=\"' + id + '\"]')[0];\n\t elem.remove();\n\t }\n\t\n\t // Set world view\n\t }, {\n\t key: 'setView',\n\t value: function setView(latlon) {\n\t // Store initial geographic coordinate for the [0,0,0] world position\n\t //\n\t // The origin point doesn't move in three.js / 3D space so only set it once\n\t // here instead of every time _resetView is called\n\t //\n\t // If it was updated every time then coorindates would shift over time and\n\t // would be out of place / context with previously-placed points (0,0 would\n\t // refer to a different point each time)\n\t this._originLatlon = latlon;\n\t this._originPoint = this.project(latlon);\n\t\n\t this._resetView(latlon);\n\t return this;\n\t }\n\t\n\t // Return world geographic position\n\t }, {\n\t key: 'getPosition',\n\t value: function getPosition() {\n\t return this._lastPosition;\n\t }\n\t\n\t // Transform geographic coordinate to world point\n\t //\n\t // This doesn't take into account the origin offset\n\t //\n\t // For example, this takes a geographic coordinate and returns a point\n\t // relative to the origin point of the projection (not the world)\n\t }, {\n\t key: 'project',\n\t value: function project(latlon) {\n\t return _geoGeo2['default'].latLonToPoint((0, _geoLatLon.latLon)(latlon));\n\t }\n\t\n\t // Transform world point to geographic coordinate\n\t //\n\t // This doesn't take into account the origin offset\n\t //\n\t // For example, this takes a point relative to the origin point of the\n\t // projection (not the world) and returns a geographic coordinate\n\t }, {\n\t key: 'unproject',\n\t value: function unproject(point) {\n\t return _geoGeo2['default'].pointToLatLon((0, _geoPoint.point)(point));\n\t }\n\t\n\t // Takes into account the origin offset\n\t //\n\t // For example, this takes a geographic coordinate and returns a point\n\t // relative to the three.js / 3D origin (0,0)\n\t }, {\n\t key: 'latLonToPoint',\n\t value: function latLonToPoint(latlon) {\n\t var projectedPoint = this.project((0, _geoLatLon.latLon)(latlon));\n\t return projectedPoint._subtract(this._originPoint);\n\t }\n\t\n\t // Takes into account the origin offset\n\t //\n\t // For example, this takes a point relative to the three.js / 3D origin (0,0)\n\t // and returns the exact geographic coordinate at that point\n\t }, {\n\t key: 'pointToLatLon',\n\t value: function pointToLatLon(point) {\n\t var projectedPoint = (0, _geoPoint.point)(point).add(this._originPoint);\n\t return this.unproject(projectedPoint);\n\t }\n\t\n\t // Return pointscale for a given geographic coordinate\n\t }, {\n\t key: 'pointScale',\n\t value: function pointScale(latlon, accurate) {\n\t return _geoGeo2['default'].pointScale(latlon, accurate);\n\t }\n\t\n\t // Convert from real meters to world units\n\t //\n\t // TODO: Would be nice not to have to pass in a pointscale here\n\t }, {\n\t key: 'metresToWorld',\n\t value: function metresToWorld(metres, pointScale, zoom) {\n\t return _geoGeo2['default'].metresToWorld(metres, pointScale, zoom);\n\t }\n\t\n\t // Convert from real meters to world units\n\t //\n\t // TODO: Would be nice not to have to pass in a pointscale here\n\t }, {\n\t key: 'worldToMetres',\n\t value: function worldToMetres(worldUnits, pointScale, zoom) {\n\t return _geoGeo2['default'].worldToMetres(worldUnits, pointScale, zoom);\n\t }\n\t\n\t // Unsure if it's a good idea to expose this here for components like\n\t // GridLayer to use (eg. to keep track of a frustum)\n\t }, {\n\t key: 'getCamera',\n\t value: function getCamera() {\n\t return this._engine._camera;\n\t }\n\t }, {\n\t key: 'addLayer',\n\t value: function addLayer(layer) {\n\t var _this2 = this;\n\t\n\t // Is is right to assume that there will always be some other layer\n\t // managing layers with output set to false?\n\t this._layers.push(layer);\n\t\n\t if (layer.isOutput() && layer.isOutputToScene()) {\n\t // Could move this into Layer but it'll do here for now\n\t this._engine._scene.add(layer._object3D);\n\t this._engine._domScene3D.add(layer._domObject3D);\n\t this._engine._domScene2D.add(layer._domObject2D);\n\t }\n\t\n\t return new Promise(function (resolve, reject) {\n\t layer._addToWorld(_this2).then(function () {\n\t if (layer._options.attribution) {\n\t _this2._addAttribution(layer._options.id, layer._options.attribution);\n\t }\n\t\n\t // TODO: Consider moving this so it doesn't fire for layers that are\n\t // actually managed by a parent layer (eg. tiles)\n\t _this2.emit('layerAdded', layer);\n\t\n\t resolve(_this2);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Remove layer from world and scene but don't destroy it entirely\n\t }, {\n\t key: 'removeLayer',\n\t value: function removeLayer(layer) {\n\t var layerIndex = this._layers.indexOf(layer);\n\t\n\t if (layerIndex > -1) {\n\t // Remove from this._layers\n\t this._layers.splice(layerIndex, 1);\n\t };\n\t\n\t if (layer.isOutput() && layer.isOutputToScene()) {\n\t this._engine._scene.remove(layer._object3D);\n\t this._engine._domScene3D.remove(layer._domObject3D);\n\t this._engine._domScene2D.remove(layer._domObject2D);\n\t }\n\t\n\t this.emit('layerRemoved');\n\t\n\t return Promise.resolve(this);\n\t }\n\t }, {\n\t key: 'addControls',\n\t value: function addControls(controls) {\n\t controls._addToWorld(this);\n\t\n\t this._controls.push(controls);\n\t\n\t this.emit('controlsAdded', controls);\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Remove controls from world but don't destroy them entirely\n\t }, {\n\t key: 'removeControls',\n\t value: function removeControls(controls) {\n\t var controlsIndex = this._controls.indexOf(controlsIndex);\n\t\n\t if (controlsIndex > -1) {\n\t this._controls.splice(controlsIndex, 1);\n\t };\n\t\n\t this.emit('controlsRemoved', controls);\n\t\n\t return Promise.resolve(this);\n\t }\n\t }, {\n\t key: 'stop',\n\t value: function stop() {\n\t this._pause = true;\n\t }\n\t }, {\n\t key: 'start',\n\t value: function start() {\n\t this._pause = false;\n\t this._update();\n\t }\n\t\n\t // Destroys the world(!) and removes it from the scene and memory\n\t //\n\t // TODO: World out why so much three.js stuff is left in the heap after this\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this.stop();\n\t\n\t // Remove listeners\n\t this.off('controlsMoveEnd', this._onControlsMoveEnd);\n\t\n\t var i;\n\t\n\t // Remove all controls\n\t var controls;\n\t for (i = this._controls.length - 1; i >= 0; i--) {\n\t controls = this._controls[0];\n\t this.removeControls(controls);\n\t controls.destroy();\n\t };\n\t\n\t // Remove all layers\n\t var layer;\n\t for (i = this._layers.length - 1; i >= 0; i--) {\n\t layer = this._layers[0];\n\t this.removeLayer(layer);\n\t layer.destroy();\n\t };\n\t\n\t // Environment layer is removed with the other layers\n\t this._environment = null;\n\t\n\t this._engine.destroy();\n\t this._engine = null;\n\t\n\t // Clean the container / remove the canvas\n\t while (this._container.firstChild) {\n\t this._container.removeChild(this._container.firstChild);\n\t }\n\t\n\t this._container = null;\n\t }\n\t }]);\n\t\n\t return World;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = World;\n\t\n\tvar noNew = function noNew(domId, options) {\n\t return new World(domId, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.world = noNew;\n\n/***/ },\n/* 2 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar has = Object.prototype.hasOwnProperty;\n\t\n\t//\n\t// We store our EE objects in a plain object whose properties are event names.\n\t// If `Object.create(null)` is not supported we prefix the event names with a\n\t// `~` to make sure that the built-in object properties are not overridden or\n\t// used as an attack vector.\n\t// We also assume that `Object.create(null)` is available when the event name\n\t// is an ES6 Symbol.\n\t//\n\tvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\t\n\t/**\n\t * Representation of a single EventEmitter function.\n\t *\n\t * @param {Function} fn Event handler to be called.\n\t * @param {Mixed} context Context for function execution.\n\t * @param {Boolean} [once=false] Only emit once\n\t * @api private\n\t */\n\tfunction EE(fn, context, once) {\n\t this.fn = fn;\n\t this.context = context;\n\t this.once = once || false;\n\t}\n\t\n\t/**\n\t * Minimal EventEmitter interface that is molded against the Node.js\n\t * EventEmitter interface.\n\t *\n\t * @constructor\n\t * @api public\n\t */\n\tfunction EventEmitter() { /* Nothing to set */ }\n\t\n\t/**\n\t * Hold the assigned EventEmitters by name.\n\t *\n\t * @type {Object}\n\t * @private\n\t */\n\tEventEmitter.prototype._events = undefined;\n\t\n\t/**\n\t * Return an array listing the events for which the emitter has registered\n\t * listeners.\n\t *\n\t * @returns {Array}\n\t * @api public\n\t */\n\tEventEmitter.prototype.eventNames = function eventNames() {\n\t var events = this._events\n\t , names = []\n\t , name;\n\t\n\t if (!events) return names;\n\t\n\t for (name in events) {\n\t if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n\t }\n\t\n\t if (Object.getOwnPropertySymbols) {\n\t return names.concat(Object.getOwnPropertySymbols(events));\n\t }\n\t\n\t return names;\n\t};\n\t\n\t/**\n\t * Return a list of assigned event listeners.\n\t *\n\t * @param {String} event The events that should be listed.\n\t * @param {Boolean} exists We only need to know if there are listeners.\n\t * @returns {Array|Boolean}\n\t * @api public\n\t */\n\tEventEmitter.prototype.listeners = function listeners(event, exists) {\n\t var evt = prefix ? prefix + event : event\n\t , available = this._events && this._events[evt];\n\t\n\t if (exists) return !!available;\n\t if (!available) return [];\n\t if (available.fn) return [available.fn];\n\t\n\t for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n\t ee[i] = available[i].fn;\n\t }\n\t\n\t return ee;\n\t};\n\t\n\t/**\n\t * Emit an event to all registered event listeners.\n\t *\n\t * @param {String} event The name of the event.\n\t * @returns {Boolean} Indication if we've emitted an event.\n\t * @api public\n\t */\n\tEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n\t var evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events || !this._events[evt]) return false;\n\t\n\t var listeners = this._events[evt]\n\t , len = arguments.length\n\t , args\n\t , i;\n\t\n\t if ('function' === typeof listeners.fn) {\n\t if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\t\n\t switch (len) {\n\t case 1: return listeners.fn.call(listeners.context), true;\n\t case 2: return listeners.fn.call(listeners.context, a1), true;\n\t case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n\t case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n\t case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n\t case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n\t }\n\t\n\t for (i = 1, args = new Array(len -1); i < len; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t\n\t listeners.fn.apply(listeners.context, args);\n\t } else {\n\t var length = listeners.length\n\t , j;\n\t\n\t for (i = 0; i < length; i++) {\n\t if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\t\n\t switch (len) {\n\t case 1: listeners[i].fn.call(listeners[i].context); break;\n\t case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n\t case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n\t default:\n\t if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n\t args[j - 1] = arguments[j];\n\t }\n\t\n\t listeners[i].fn.apply(listeners[i].context, args);\n\t }\n\t }\n\t }\n\t\n\t return true;\n\t};\n\t\n\t/**\n\t * Register a new EventListener for the given event.\n\t *\n\t * @param {String} event Name of the event.\n\t * @param {Function} fn Callback function.\n\t * @param {Mixed} [context=this] The context of the function.\n\t * @api public\n\t */\n\tEventEmitter.prototype.on = function on(event, fn, context) {\n\t var listener = new EE(fn, context || this)\n\t , evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events) this._events = prefix ? {} : Object.create(null);\n\t if (!this._events[evt]) this._events[evt] = listener;\n\t else {\n\t if (!this._events[evt].fn) this._events[evt].push(listener);\n\t else this._events[evt] = [\n\t this._events[evt], listener\n\t ];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Add an EventListener that's only called once.\n\t *\n\t * @param {String} event Name of the event.\n\t * @param {Function} fn Callback function.\n\t * @param {Mixed} [context=this] The context of the function.\n\t * @api public\n\t */\n\tEventEmitter.prototype.once = function once(event, fn, context) {\n\t var listener = new EE(fn, context || this, true)\n\t , evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events) this._events = prefix ? {} : Object.create(null);\n\t if (!this._events[evt]) this._events[evt] = listener;\n\t else {\n\t if (!this._events[evt].fn) this._events[evt].push(listener);\n\t else this._events[evt] = [\n\t this._events[evt], listener\n\t ];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Remove event listeners.\n\t *\n\t * @param {String} event The event we want to remove.\n\t * @param {Function} fn The listener that we need to find.\n\t * @param {Mixed} context Only remove listeners matching this context.\n\t * @param {Boolean} once Only remove once listeners.\n\t * @api public\n\t */\n\tEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n\t var evt = prefix ? prefix + event : event;\n\t\n\t if (!this._events || !this._events[evt]) return this;\n\t\n\t var listeners = this._events[evt]\n\t , events = [];\n\t\n\t if (fn) {\n\t if (listeners.fn) {\n\t if (\n\t listeners.fn !== fn\n\t || (once && !listeners.once)\n\t || (context && listeners.context !== context)\n\t ) {\n\t events.push(listeners);\n\t }\n\t } else {\n\t for (var i = 0, length = listeners.length; i < length; i++) {\n\t if (\n\t listeners[i].fn !== fn\n\t || (once && !listeners[i].once)\n\t || (context && listeners[i].context !== context)\n\t ) {\n\t events.push(listeners[i]);\n\t }\n\t }\n\t }\n\t }\n\t\n\t //\n\t // Reset the array, or remove it completely if we have no more listeners.\n\t //\n\t if (events.length) {\n\t this._events[evt] = events.length === 1 ? events[0] : events;\n\t } else {\n\t delete this._events[evt];\n\t }\n\t\n\t return this;\n\t};\n\t\n\t/**\n\t * Remove all listeners or only the listeners for the specified event.\n\t *\n\t * @param {String} event The event want to remove all listeners for.\n\t * @api public\n\t */\n\tEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n\t if (!this._events) return this;\n\t\n\t if (event) delete this._events[prefix ? prefix + event : event];\n\t else this._events = prefix ? {} : Object.create(null);\n\t\n\t return this;\n\t};\n\t\n\t//\n\t// Alias methods names because people roll like that.\n\t//\n\tEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\n\tEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\t\n\t//\n\t// This function doesn't apply anymore.\n\t//\n\tEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n\t return this;\n\t};\n\t\n\t//\n\t// Expose the prefix.\n\t//\n\tEventEmitter.prefixed = prefix;\n\t\n\t//\n\t// Expose the module.\n\t//\n\tif (true) {\n\t module.exports = EventEmitter;\n\t}\n\n\n/***/ },\n/* 3 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\tvar keys = __webpack_require__(4),\n\t rest = __webpack_require__(5);\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]';\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\t\n\t/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\n\tvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\t\n\t/**\n\t * Assigns `value` to `key` of `object` if the existing value is not equivalent\n\t * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n\t * for equality comparisons.\n\t *\n\t * @private\n\t * @param {Object} object The object to modify.\n\t * @param {string} key The key of the property to assign.\n\t * @param {*} value The value to assign.\n\t */\n\tfunction assignValue(object, key, value) {\n\t var objValue = object[key];\n\t if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n\t (value === undefined && !(key in object))) {\n\t object[key] = value;\n\t }\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * Copies properties of `source` to `object`.\n\t *\n\t * @private\n\t * @param {Object} source The object to copy properties from.\n\t * @param {Array} props The property identifiers to copy.\n\t * @param {Object} [object={}] The object to copy properties to.\n\t * @param {Function} [customizer] The function to customize copied values.\n\t * @returns {Object} Returns `object`.\n\t */\n\tfunction copyObject(source, props, object, customizer) {\n\t object || (object = {});\n\t\n\t var index = -1,\n\t length = props.length;\n\t\n\t while (++index < length) {\n\t var key = props[index];\n\t\n\t var newValue = customizer\n\t ? customizer(object[key], source[key], key, object, source)\n\t : source[key];\n\t\n\t assignValue(object, key, newValue);\n\t }\n\t return object;\n\t}\n\t\n\t/**\n\t * Creates a function like `_.assign`.\n\t *\n\t * @private\n\t * @param {Function} assigner The function to assign values.\n\t * @returns {Function} Returns the new assigner function.\n\t */\n\tfunction createAssigner(assigner) {\n\t return rest(function(object, sources) {\n\t var index = -1,\n\t length = sources.length,\n\t customizer = length > 1 ? sources[length - 1] : undefined,\n\t guard = length > 2 ? sources[2] : undefined;\n\t\n\t customizer = (assigner.length > 3 && typeof customizer == 'function')\n\t ? (length--, customizer)\n\t : undefined;\n\t\n\t if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n\t customizer = length < 3 ? undefined : customizer;\n\t length = 1;\n\t }\n\t object = Object(object);\n\t while (++index < length) {\n\t var source = sources[index];\n\t if (source) {\n\t assigner(object, source, index, customizer);\n\t }\n\t }\n\t return object;\n\t });\n\t}\n\t\n\t/**\n\t * Gets the \"length\" property value of `object`.\n\t *\n\t * **Note:** This function is used to avoid a\n\t * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n\t * Safari on at least iOS 8.1-8.3 ARM64.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {*} Returns the \"length\" value.\n\t */\n\tvar getLength = baseProperty('length');\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if the given arguments are from an iteratee call.\n\t *\n\t * @private\n\t * @param {*} value The potential iteratee value argument.\n\t * @param {*} index The potential iteratee index or key argument.\n\t * @param {*} object The potential iteratee object argument.\n\t * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n\t * else `false`.\n\t */\n\tfunction isIterateeCall(value, index, object) {\n\t if (!isObject(object)) {\n\t return false;\n\t }\n\t var type = typeof index;\n\t if (type == 'number'\n\t ? (isArrayLike(object) && isIndex(index, object.length))\n\t : (type == 'string' && index in object)\n\t ) {\n\t return eq(object[index], value);\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Performs a\n\t * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n\t * comparison between two values to determine if they are equivalent.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to compare.\n\t * @param {*} other The other value to compare.\n\t * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n\t * @example\n\t *\n\t * var object = { 'user': 'fred' };\n\t * var other = { 'user': 'fred' };\n\t *\n\t * _.eq(object, object);\n\t * // => true\n\t *\n\t * _.eq(object, other);\n\t * // => false\n\t *\n\t * _.eq('a', 'a');\n\t * // => true\n\t *\n\t * _.eq('a', Object('a'));\n\t * // => false\n\t *\n\t * _.eq(NaN, NaN);\n\t * // => true\n\t */\n\tfunction eq(value, other) {\n\t return value === other || (value !== value && other !== other);\n\t}\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(getLength(value)) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Assigns own enumerable string keyed properties of source objects to the\n\t * destination object. Source objects are applied from left to right.\n\t * Subsequent sources overwrite property assignments of previous sources.\n\t *\n\t * **Note:** This method mutates `object` and is loosely based on\n\t * [`Object.assign`](https://mdn.io/Object/assign).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.10.0\n\t * @category Object\n\t * @param {Object} object The destination object.\n\t * @param {...Object} [sources] The source objects.\n\t * @returns {Object} Returns `object`.\n\t * @see _.assignIn\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.c = 3;\n\t * }\n\t *\n\t * function Bar() {\n\t * this.e = 5;\n\t * }\n\t *\n\t * Foo.prototype.d = 4;\n\t * Bar.prototype.f = 6;\n\t *\n\t * _.assign({ 'a': 1 }, new Foo, new Bar);\n\t * // => { 'a': 1, 'c': 3, 'e': 5 }\n\t */\n\tvar assign = createAssigner(function(object, source) {\n\t if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n\t copyObject(source, keys(source), object);\n\t return;\n\t }\n\t for (var key in source) {\n\t if (hasOwnProperty.call(source, key)) {\n\t assignValue(object, key, source[key]);\n\t }\n\t }\n\t});\n\t\n\tmodule.exports = assign;\n\n\n/***/ },\n/* 4 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar MAX_SAFE_INTEGER = 9007199254740991;\n\t\n\t/** `Object#toString` result references. */\n\tvar argsTag = '[object Arguments]',\n\t funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t stringTag = '[object String]';\n\t\n\t/** Used to detect unsigned integer values. */\n\tvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\t\n\t/**\n\t * The base implementation of `_.times` without support for iteratee shorthands\n\t * or max array length checks.\n\t *\n\t * @private\n\t * @param {number} n The number of times to invoke `iteratee`.\n\t * @param {Function} iteratee The function invoked per iteration.\n\t * @returns {Array} Returns the array of results.\n\t */\n\tfunction baseTimes(n, iteratee) {\n\t var index = -1,\n\t result = Array(n);\n\t\n\t while (++index < n) {\n\t result[index] = iteratee(index);\n\t }\n\t return result;\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/** Used to check objects for own properties. */\n\tvar hasOwnProperty = objectProto.hasOwnProperty;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/** Built-in value references. */\n\tvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeGetPrototype = Object.getPrototypeOf,\n\t nativeKeys = Object.keys;\n\t\n\t/**\n\t * The base implementation of `_.has` without support for deep paths.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @param {Array|string} key The key to check.\n\t * @returns {boolean} Returns `true` if `key` exists, else `false`.\n\t */\n\tfunction baseHas(object, key) {\n\t // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n\t // that are composed entirely of index properties, return `false` for\n\t // `hasOwnProperty` checks of them.\n\t return hasOwnProperty.call(object, key) ||\n\t (typeof object == 'object' && key in object && getPrototype(object) === null);\n\t}\n\t\n\t/**\n\t * The base implementation of `_.keys` which doesn't skip the constructor\n\t * property of prototypes or treat sparse arrays as dense.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t */\n\tfunction baseKeys(object) {\n\t return nativeKeys(Object(object));\n\t}\n\t\n\t/**\n\t * The base implementation of `_.property` without support for deep paths.\n\t *\n\t * @private\n\t * @param {string} key The key of the property to get.\n\t * @returns {Function} Returns the new accessor function.\n\t */\n\tfunction baseProperty(key) {\n\t return function(object) {\n\t return object == null ? undefined : object[key];\n\t };\n\t}\n\t\n\t/**\n\t * Gets the \"length\" property value of `object`.\n\t *\n\t * **Note:** This function is used to avoid a\n\t * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n\t * Safari on at least iOS 8.1-8.3 ARM64.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {*} Returns the \"length\" value.\n\t */\n\tvar getLength = baseProperty('length');\n\t\n\t/**\n\t * Gets the `[[Prototype]]` of `value`.\n\t *\n\t * @private\n\t * @param {*} value The value to query.\n\t * @returns {null|Object} Returns the `[[Prototype]]`.\n\t */\n\tfunction getPrototype(value) {\n\t return nativeGetPrototype(Object(value));\n\t}\n\t\n\t/**\n\t * Creates an array of index keys for `object` values of arrays,\n\t * `arguments` objects, and strings, otherwise `null` is returned.\n\t *\n\t * @private\n\t * @param {Object} object The object to query.\n\t * @returns {Array|null} Returns index keys, else `null`.\n\t */\n\tfunction indexKeys(object) {\n\t var length = object ? object.length : undefined;\n\t if (isLength(length) &&\n\t (isArray(object) || isString(object) || isArguments(object))) {\n\t return baseTimes(length, String);\n\t }\n\t return null;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like index.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n\t * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n\t */\n\tfunction isIndex(value, length) {\n\t length = length == null ? MAX_SAFE_INTEGER : length;\n\t return !!length &&\n\t (typeof value == 'number' || reIsUint.test(value)) &&\n\t (value > -1 && value % 1 == 0 && value < length);\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely a prototype object.\n\t *\n\t * @private\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n\t */\n\tfunction isPrototype(value) {\n\t var Ctor = value && value.constructor,\n\t proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\t\n\t return value === proto;\n\t}\n\t\n\t/**\n\t * Checks if `value` is likely an `arguments` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArguments(function() { return arguments; }());\n\t * // => true\n\t *\n\t * _.isArguments([1, 2, 3]);\n\t * // => false\n\t */\n\tfunction isArguments(value) {\n\t // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n\t return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n\t (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as an `Array` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @type {Function}\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArray([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArray(document.body.children);\n\t * // => false\n\t *\n\t * _.isArray('abc');\n\t * // => false\n\t *\n\t * _.isArray(_.noop);\n\t * // => false\n\t */\n\tvar isArray = Array.isArray;\n\t\n\t/**\n\t * Checks if `value` is array-like. A value is considered array-like if it's\n\t * not a function and has a `value.length` that's an integer greater than or\n\t * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n\t * @example\n\t *\n\t * _.isArrayLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLike(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLike('abc');\n\t * // => true\n\t *\n\t * _.isArrayLike(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLike(value) {\n\t return value != null && isLength(getLength(value)) && !isFunction(value);\n\t}\n\t\n\t/**\n\t * This method is like `_.isArrayLike` except that it also checks if `value`\n\t * is an object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an array-like object,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isArrayLikeObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject(document.body.children);\n\t * // => true\n\t *\n\t * _.isArrayLikeObject('abc');\n\t * // => false\n\t *\n\t * _.isArrayLikeObject(_.noop);\n\t * // => false\n\t */\n\tfunction isArrayLikeObject(value) {\n\t return isObjectLike(value) && isArrayLike(value);\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is a valid array-like length.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is a valid length,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isLength(3);\n\t * // => true\n\t *\n\t * _.isLength(Number.MIN_VALUE);\n\t * // => false\n\t *\n\t * _.isLength(Infinity);\n\t * // => false\n\t *\n\t * _.isLength('3');\n\t * // => false\n\t */\n\tfunction isLength(value) {\n\t return typeof value == 'number' &&\n\t value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `String` primitive or object.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isString('abc');\n\t * // => true\n\t *\n\t * _.isString(1);\n\t * // => false\n\t */\n\tfunction isString(value) {\n\t return typeof value == 'string' ||\n\t (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n\t}\n\t\n\t/**\n\t * Creates an array of the own enumerable property names of `object`.\n\t *\n\t * **Note:** Non-object values are coerced to objects. See the\n\t * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n\t * for more details.\n\t *\n\t * @static\n\t * @since 0.1.0\n\t * @memberOf _\n\t * @category Object\n\t * @param {Object} object The object to query.\n\t * @returns {Array} Returns the array of property names.\n\t * @example\n\t *\n\t * function Foo() {\n\t * this.a = 1;\n\t * this.b = 2;\n\t * }\n\t *\n\t * Foo.prototype.c = 3;\n\t *\n\t * _.keys(new Foo);\n\t * // => ['a', 'b'] (iteration order is not guaranteed)\n\t *\n\t * _.keys('hi');\n\t * // => ['0', '1']\n\t */\n\tfunction keys(object) {\n\t var isProto = isPrototype(object);\n\t if (!(isProto || isArrayLike(object))) {\n\t return baseKeys(object);\n\t }\n\t var indexes = indexKeys(object),\n\t skipIndexes = !!indexes,\n\t result = indexes || [],\n\t length = result.length;\n\t\n\t for (var key in object) {\n\t if (baseHas(object, key) &&\n\t !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n\t !(isProto && key == 'constructor')) {\n\t result.push(key);\n\t }\n\t }\n\t return result;\n\t}\n\t\n\tmodule.exports = keys;\n\n\n/***/ },\n/* 5 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar INFINITY = 1 / 0,\n\t MAX_INTEGER = 1.7976931348623157e+308,\n\t NAN = 0 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t symbolTag = '[object Symbol]';\n\t\n\t/** Used to match leading and trailing whitespace. */\n\tvar reTrim = /^\\s+|\\s+$/g;\n\t\n\t/** Used to detect bad signed hexadecimal string values. */\n\tvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\t\n\t/** Used to detect binary string values. */\n\tvar reIsBinary = /^0b[01]+$/i;\n\t\n\t/** Used to detect octal string values. */\n\tvar reIsOctal = /^0o[0-7]+$/i;\n\t\n\t/** Built-in method references without a dependency on `root`. */\n\tvar freeParseInt = parseInt;\n\t\n\t/**\n\t * A faster alternative to `Function#apply`, this function invokes `func`\n\t * with the `this` binding of `thisArg` and the arguments of `args`.\n\t *\n\t * @private\n\t * @param {Function} func The function to invoke.\n\t * @param {*} thisArg The `this` binding of `func`.\n\t * @param {Array} args The arguments to invoke `func` with.\n\t * @returns {*} Returns the result of `func`.\n\t */\n\tfunction apply(func, thisArg, args) {\n\t var length = args.length;\n\t switch (length) {\n\t case 0: return func.call(thisArg);\n\t case 1: return func.call(thisArg, args[0]);\n\t case 2: return func.call(thisArg, args[0], args[1]);\n\t case 3: return func.call(thisArg, args[0], args[1], args[2]);\n\t }\n\t return func.apply(thisArg, args);\n\t}\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeMax = Math.max;\n\t\n\t/**\n\t * Creates a function that invokes `func` with the `this` binding of the\n\t * created function and arguments from `start` and beyond provided as\n\t * an array.\n\t *\n\t * **Note:** This method is based on the\n\t * [rest parameter](https://mdn.io/rest_parameters).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Function\n\t * @param {Function} func The function to apply a rest parameter to.\n\t * @param {number} [start=func.length-1] The start position of the rest parameter.\n\t * @returns {Function} Returns the new function.\n\t * @example\n\t *\n\t * var say = _.rest(function(what, names) {\n\t * return what + ' ' + _.initial(names).join(', ') +\n\t * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n\t * });\n\t *\n\t * say('hello', 'fred', 'barney', 'pebbles');\n\t * // => 'hello fred, barney, & pebbles'\n\t */\n\tfunction rest(func, start) {\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n\t return function() {\n\t var args = arguments,\n\t index = -1,\n\t length = nativeMax(args.length - start, 0),\n\t array = Array(length);\n\t\n\t while (++index < length) {\n\t array[index] = args[start + index];\n\t }\n\t switch (start) {\n\t case 0: return func.call(this, array);\n\t case 1: return func.call(this, args[0], array);\n\t case 2: return func.call(this, args[0], args[1], array);\n\t }\n\t var otherArgs = Array(start + 1);\n\t index = -1;\n\t while (++index < start) {\n\t otherArgs[index] = args[index];\n\t }\n\t otherArgs[start] = array;\n\t return apply(func, this, otherArgs);\n\t };\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a finite number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.12.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted number.\n\t * @example\n\t *\n\t * _.toFinite(3.2);\n\t * // => 3.2\n\t *\n\t * _.toFinite(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toFinite(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toFinite('3.2');\n\t * // => 3.2\n\t */\n\tfunction toFinite(value) {\n\t if (!value) {\n\t return value === 0 ? value : 0;\n\t }\n\t value = toNumber(value);\n\t if (value === INFINITY || value === -INFINITY) {\n\t var sign = (value < 0 ? -1 : 1);\n\t return sign * MAX_INTEGER;\n\t }\n\t return value === value ? value : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to an integer.\n\t *\n\t * **Note:** This function is loosely based on\n\t * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to convert.\n\t * @returns {number} Returns the converted integer.\n\t * @example\n\t *\n\t * _.toInteger(3.2);\n\t * // => 3\n\t *\n\t * _.toInteger(Number.MIN_VALUE);\n\t * // => 0\n\t *\n\t * _.toInteger(Infinity);\n\t * // => 1.7976931348623157e+308\n\t *\n\t * _.toInteger('3.2');\n\t * // => 3\n\t */\n\tfunction toInteger(value) {\n\t var result = toFinite(value),\n\t remainder = result % 1;\n\t\n\t return result === result ? (remainder ? result - remainder : result) : 0;\n\t}\n\t\n\t/**\n\t * Converts `value` to a number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {number} Returns the number.\n\t * @example\n\t *\n\t * _.toNumber(3.2);\n\t * // => 3.2\n\t *\n\t * _.toNumber(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toNumber(Infinity);\n\t * // => Infinity\n\t *\n\t * _.toNumber('3.2');\n\t * // => 3.2\n\t */\n\tfunction toNumber(value) {\n\t if (typeof value == 'number') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return NAN;\n\t }\n\t if (isObject(value)) {\n\t var other = isFunction(value.valueOf) ? value.valueOf() : value;\n\t value = isObject(other) ? (other + '') : other;\n\t }\n\t if (typeof value != 'string') {\n\t return value === 0 ? value : +value;\n\t }\n\t value = value.replace(reTrim, '');\n\t var isBinary = reIsBinary.test(value);\n\t return (isBinary || reIsOctal.test(value))\n\t ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n\t : (reIsBadHex.test(value) ? NAN : +value);\n\t}\n\t\n\tmodule.exports = rest;\n\n\n/***/ },\n/* 6 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _LatLon = __webpack_require__(7);\n\t\n\tvar _Point = __webpack_require__(8);\n\t\n\tvar Geo = {};\n\t\n\t// Radius / WGS84 semi-major axis\n\tGeo.R = 6378137;\n\tGeo.MAX_LATITUDE = 85.0511287798;\n\t\n\t// WGS84 eccentricity\n\tGeo.ECC = 0.081819191;\n\tGeo.ECC2 = 0.081819191 * 0.081819191;\n\t\n\tGeo.project = function (latlon) {\n\t var d = Math.PI / 180;\n\t var max = Geo.MAX_LATITUDE;\n\t var lat = Math.max(Math.min(max, latlon.lat), -max);\n\t var sin = Math.sin(lat * d);\n\t\n\t return (0, _Point.point)(Geo.R * latlon.lon * d, Geo.R * Math.log((1 + sin) / (1 - sin)) / 2);\n\t}, Geo.unproject = function (point) {\n\t var d = 180 / Math.PI;\n\t\n\t return (0, _LatLon.latLon)((2 * Math.atan(Math.exp(point.y / Geo.R)) - Math.PI / 2) * d, point.x * d / Geo.R);\n\t};\n\t\n\t// Converts geo coords to pixel / WebGL ones\n\t// This just reverses the Y axis to match WebGL\n\tGeo.latLonToPoint = function (latlon) {\n\t var projected = Geo.project(latlon);\n\t projected.y *= -1;\n\t\n\t return projected;\n\t};\n\t\n\t// Converts pixel / WebGL coords to geo coords\n\t// This just reverses the Y axis to match WebGL\n\tGeo.pointToLatLon = function (point) {\n\t var _point = (0, _Point.point)(point.x, point.y * -1);\n\t return Geo.unproject(_point);\n\t};\n\t\n\t// Scale factor for converting between real metres and projected metres\n\t//\n\t// projectedMetres = realMetres * pointScale\n\t// realMetres = projectedMetres / pointScale\n\t//\n\t// Accurate scale factor uses proper Web Mercator scaling\n\t// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf\n\t// See: http://jsfiddle.net/robhawkes/yws924cf/\n\tGeo.pointScale = function (latlon, accurate) {\n\t var rad = Math.PI / 180;\n\t\n\t var k;\n\t\n\t if (!accurate) {\n\t k = 1 / Math.cos(latlon.lat * rad);\n\t\n\t // [scaleX, scaleY]\n\t return [k, k];\n\t } else {\n\t var lat = latlon.lat * rad;\n\t var lon = latlon.lon * rad;\n\t\n\t var a = Geo.R;\n\t\n\t var sinLat = Math.sin(lat);\n\t var sinLat2 = sinLat * sinLat;\n\t\n\t var cosLat = Math.cos(lat);\n\t\n\t // Radius meridian\n\t var p = a * (1 - Geo.ECC2) / Math.pow(1 - Geo.ECC2 * sinLat2, 3 / 2);\n\t\n\t // Radius prime meridian\n\t var v = a / Math.sqrt(1 - Geo.ECC2 * sinLat2);\n\t\n\t // Scale N/S\n\t var h = a / p / cosLat;\n\t\n\t // Scale E/W\n\t k = a / v / cosLat;\n\t\n\t // [scaleX, scaleY]\n\t return [k, h];\n\t }\n\t};\n\t\n\t// Convert real metres to projected units\n\t//\n\t// Latitude scale is chosen because it fluctuates more than longitude\n\tGeo.metresToProjected = function (metres, pointScale) {\n\t return metres * pointScale[1];\n\t};\n\t\n\t// Convert projected units to real metres\n\t//\n\t// Latitude scale is chosen because it fluctuates more than longitude\n\tGeo.projectedToMetres = function (projectedUnits, pointScale) {\n\t return projectedUnits / pointScale[1];\n\t};\n\t\n\t// Convert real metres to a value in world (WebGL) units\n\tGeo.metresToWorld = function (metres, pointScale) {\n\t // Transform metres to projected metres using the latitude point scale\n\t //\n\t // Latitude scale is chosen because it fluctuates more than longitude\n\t var projectedMetres = Geo.metresToProjected(metres, pointScale);\n\t\n\t var scale = Geo.scale();\n\t\n\t // Scale projected metres\n\t var scaledMetres = scale * projectedMetres;\n\t\n\t return scaledMetres;\n\t};\n\t\n\t// Convert world (WebGL) units to a value in real metres\n\tGeo.worldToMetres = function (worldUnits, pointScale) {\n\t var scale = Geo.scale();\n\t\n\t var projectedUnits = worldUnits / scale;\n\t var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);\n\t\n\t return realMetres;\n\t};\n\t\n\t// If zoom is provided, returns the map width in pixels for a given zoom\n\t// Else, provides fixed scale value\n\tGeo.scale = function (zoom) {\n\t // If zoom is provided then return scale based on map tile zoom\n\t if (zoom >= 0) {\n\t return 256 * Math.pow(2, zoom);\n\t // Else, return fixed scale value to expand projected coordinates from\n\t // their 0 to 1 range into something more practical\n\t } else {\n\t return 1;\n\t }\n\t};\n\t\n\t// Returns zoom level for a given scale value\n\t// This only works with a scale value that is based on map pixel width\n\tGeo.zoom = function (scale) {\n\t return Math.log(scale / 256) / Math.LN2;\n\t};\n\t\n\t// Distance between two geographical points using spherical law of cosines\n\t// approximation or Haversine\n\t//\n\t// See: http://www.movable-type.co.uk/scripts/latlong.html\n\tGeo.distance = function (latlon1, latlon2, accurate) {\n\t var rad = Math.PI / 180;\n\t\n\t var lat1;\n\t var lat2;\n\t\n\t var a;\n\t\n\t if (!accurate) {\n\t lat1 = latlon1.lat * rad;\n\t lat2 = latlon2.lat * rad;\n\t\n\t a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);\n\t\n\t return Geo.R * Math.acos(Math.min(a, 1));\n\t } else {\n\t lat1 = latlon1.lat * rad;\n\t lat2 = latlon2.lat * rad;\n\t\n\t var lon1 = latlon1.lon * rad;\n\t var lon2 = latlon2.lon * rad;\n\t\n\t var deltaLat = lat2 - lat1;\n\t var deltaLon = lon2 - lon1;\n\t\n\t var halfDeltaLat = deltaLat / 2;\n\t var halfDeltaLon = deltaLon / 2;\n\t\n\t a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);\n\t\n\t var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\t\n\t return Geo.R * c;\n\t }\n\t};\n\t\n\tGeo.bounds = (function () {\n\t var d = Geo.R * Math.PI;\n\t return [[-d, -d], [d, d]];\n\t})();\n\t\n\texports['default'] = Geo;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 7 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\t/*\n\t * LatLon is a helper class for ensuring consistent geographic coordinates.\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js\n\t */\n\t\n\tvar LatLon = (function () {\n\t function LatLon(lat, lon, alt) {\n\t _classCallCheck(this, LatLon);\n\t\n\t if (isNaN(lat) || isNaN(lon)) {\n\t throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');\n\t }\n\t\n\t this.lat = +lat;\n\t this.lon = +lon;\n\t\n\t if (alt !== undefined) {\n\t this.alt = +alt;\n\t }\n\t }\n\t\n\t _createClass(LatLon, [{\n\t key: 'clone',\n\t value: function clone() {\n\t return new LatLon(this.lat, this.lon, this.alt);\n\t }\n\t }]);\n\t\n\t return LatLon;\n\t})();\n\t\n\texports['default'] = LatLon;\n\t\n\t// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)\n\t// Also converts between lng and lon\n\tvar noNew = function noNew(a, b, c) {\n\t if (a instanceof LatLon) {\n\t return a;\n\t }\n\t if (Array.isArray(a) && typeof a[0] !== 'object') {\n\t if (a.length === 3) {\n\t return new LatLon(a[0], a[1], a[2]);\n\t }\n\t if (a.length === 2) {\n\t return new LatLon(a[0], a[1]);\n\t }\n\t return null;\n\t }\n\t if (a === undefined || a === null) {\n\t return a;\n\t }\n\t if (typeof a === 'object' && 'lat' in a) {\n\t return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\n\t }\n\t if (b === undefined) {\n\t return null;\n\t }\n\t return new LatLon(a, b, c);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.latLon = noNew;\n\n/***/ },\n/* 8 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError(\"Cannot call a class as a function\"); } }\n\t\n\t/*\n\t * Point is a helper class for ensuring consistent world positions.\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js\n\t */\n\t\n\tvar Point = (function () {\n\t function Point(x, y, round) {\n\t _classCallCheck(this, Point);\n\t\n\t this.x = round ? Math.round(x) : x;\n\t this.y = round ? Math.round(y) : y;\n\t }\n\t\n\t _createClass(Point, [{\n\t key: \"clone\",\n\t value: function clone() {\n\t return new Point(this.x, this.y);\n\t }\n\t\n\t // Non-destructive\n\t }, {\n\t key: \"add\",\n\t value: function add(point) {\n\t return this.clone()._add(_point(point));\n\t }\n\t\n\t // Destructive\n\t }, {\n\t key: \"_add\",\n\t value: function _add(point) {\n\t this.x += point.x;\n\t this.y += point.y;\n\t return this;\n\t }\n\t\n\t // Non-destructive\n\t }, {\n\t key: \"subtract\",\n\t value: function subtract(point) {\n\t return this.clone()._subtract(_point(point));\n\t }\n\t\n\t // Destructive\n\t }, {\n\t key: \"_subtract\",\n\t value: function _subtract(point) {\n\t this.x -= point.x;\n\t this.y -= point.y;\n\t return this;\n\t }\n\t }]);\n\t\n\t return Point;\n\t})();\n\t\n\texports[\"default\"] = Point;\n\t\n\t// Accepts (point), ([x, y]) and (x, y, round)\n\tvar _point = function _point(x, y, round) {\n\t if (x instanceof Point) {\n\t return x;\n\t }\n\t if (Array.isArray(x)) {\n\t return new Point(x[0], x[1]);\n\t }\n\t if (x === undefined || x === null) {\n\t return x;\n\t }\n\t return new Point(x, y, round);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.point = _point;\n\n/***/ },\n/* 9 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Scene = __webpack_require__(11);\n\t\n\tvar _Scene2 = _interopRequireDefault(_Scene);\n\t\n\tvar _DOMScene3D = __webpack_require__(12);\n\t\n\tvar _DOMScene3D2 = _interopRequireDefault(_DOMScene3D);\n\t\n\tvar _DOMScene2D = __webpack_require__(13);\n\t\n\tvar _DOMScene2D2 = _interopRequireDefault(_DOMScene2D);\n\t\n\tvar _Renderer = __webpack_require__(14);\n\t\n\tvar _Renderer2 = _interopRequireDefault(_Renderer);\n\t\n\tvar _DOMRenderer3D = __webpack_require__(15);\n\t\n\tvar _DOMRenderer3D2 = _interopRequireDefault(_DOMRenderer3D);\n\t\n\tvar _DOMRenderer2D = __webpack_require__(17);\n\t\n\tvar _DOMRenderer2D2 = _interopRequireDefault(_DOMRenderer2D);\n\t\n\tvar _Camera = __webpack_require__(19);\n\t\n\tvar _Camera2 = _interopRequireDefault(_Camera);\n\t\n\tvar _Picking = __webpack_require__(20);\n\t\n\tvar _Picking2 = _interopRequireDefault(_Picking);\n\t\n\tvar _EffectComposer = __webpack_require__(24);\n\t\n\tvar _EffectComposer2 = _interopRequireDefault(_EffectComposer);\n\t\n\tvar _vendorRenderPass = __webpack_require__(29);\n\t\n\tvar _vendorRenderPass2 = _interopRequireDefault(_vendorRenderPass);\n\t\n\tvar _vendorShaderPass = __webpack_require__(27);\n\t\n\tvar _vendorShaderPass2 = _interopRequireDefault(_vendorShaderPass);\n\t\n\tvar _vendorCopyShader = __webpack_require__(26);\n\t\n\tvar _vendorCopyShader2 = _interopRequireDefault(_vendorCopyShader);\n\t\n\tvar _vendorHorizontalTiltShiftShader = __webpack_require__(30);\n\t\n\tvar _vendorHorizontalTiltShiftShader2 = _interopRequireDefault(_vendorHorizontalTiltShiftShader);\n\t\n\tvar _vendorVerticalTiltShiftShader = __webpack_require__(31);\n\t\n\tvar _vendorVerticalTiltShiftShader2 = _interopRequireDefault(_vendorVerticalTiltShiftShader);\n\t\n\tvar _vendorFXAAShader = __webpack_require__(32);\n\t\n\tvar _vendorFXAAShader2 = _interopRequireDefault(_vendorFXAAShader);\n\t\n\tvar Engine = (function (_EventEmitter) {\n\t _inherits(Engine, _EventEmitter);\n\t\n\t function Engine(container, world) {\n\t _classCallCheck(this, Engine);\n\t\n\t console.log('Init Engine');\n\t\n\t _get(Object.getPrototypeOf(Engine.prototype), 'constructor', this).call(this);\n\t\n\t this._world = world;\n\t\n\t this._scene = _Scene2['default'];\n\t this._domScene3D = _DOMScene3D2['default'];\n\t this._domScene2D = _DOMScene2D2['default'];\n\t\n\t var antialias = this._world.options.postProcessing ? false : true;\n\t this._renderer = (0, _Renderer2['default'])(container, antialias);\n\t this._domRenderer3D = (0, _DOMRenderer3D2['default'])(container);\n\t this._domRenderer2D = (0, _DOMRenderer2D2['default'])(container);\n\t\n\t this._camera = (0, _Camera2['default'])(container);\n\t\n\t this._container = container;\n\t\n\t // TODO: Make this optional\n\t this._picking = (0, _Picking2['default'])(this._world, this._renderer, this._camera);\n\t\n\t this.clock = new _three2['default'].Clock();\n\t\n\t this._frustum = new _three2['default'].Frustum();\n\t\n\t if (this._world.options.postProcessing) {\n\t this._initPostProcessing();\n\t }\n\t }\n\t\n\t // TODO: Set up composer to automatically resize on viewport change\n\t // TODO: Update passes that rely on width / height on resize\n\t // TODO: Merge default passes into a single shader / pass for performance\n\t\n\t _createClass(Engine, [{\n\t key: '_initPostProcessing',\n\t value: function _initPostProcessing() {\n\t var renderPass = new _vendorRenderPass2['default'](this._scene, this._camera);\n\t\n\t // TODO: Look at using @mattdesl's optimised FXAA shader\n\t // https://github.com/mattdesl/three-shader-fxaa\n\t var fxaaPass = new _vendorShaderPass2['default'](_vendorFXAAShader2['default']);\n\t\n\t var hblurPass = new _vendorShaderPass2['default'](_vendorHorizontalTiltShiftShader2['default']);\n\t var vblurPass = new _vendorShaderPass2['default'](_vendorVerticalTiltShiftShader2['default']);\n\t var bluriness = 5;\n\t\n\t hblurPass.uniforms.r.value = vblurPass.uniforms.r.value = 0.6;\n\t\n\t var copyPass = new _vendorShaderPass2['default'](_vendorCopyShader2['default']);\n\t copyPass.renderToScreen = true;\n\t\n\t this._composer = (0, _EffectComposer2['default'])(this._renderer, this._container);\n\t\n\t this._composer.addPass(renderPass);\n\t this._composer.addPass(fxaaPass);\n\t this._composer.addPass(hblurPass);\n\t this._composer.addPass(vblurPass);\n\t this._composer.addPass(copyPass);\n\t\n\t var self = this;\n\t var updatePostProcessingSize = function updatePostProcessingSize() {\n\t var width = self._container.clientWidth;\n\t var height = self._container.clientHeight;\n\t\n\t // TODO: Re-enable this when perf issues can be solved\n\t //\n\t // Rendering double the resolution of the screen can be really slow\n\t // var pixelRatio = window.devicePixelRatio;\n\t var pixelRatio = 1;\n\t\n\t fxaaPass.uniforms.resolution.value.set(1 / (width * pixelRatio), 1 / (height * pixelRatio));\n\t\n\t hblurPass.uniforms.h.value = bluriness / (width * pixelRatio);\n\t vblurPass.uniforms.v.value = bluriness / (height * pixelRatio);\n\t };\n\t\n\t updatePostProcessingSize();\n\t window.addEventListener('resize', updatePostProcessingSize, false);\n\t }\n\t }, {\n\t key: 'update',\n\t value: function update(delta) {\n\t this.emit('preRender');\n\t\n\t if (this._world.options.postProcessing) {\n\t this._composer.render(delta);\n\t } else {\n\t this._renderer.render(this._scene, this._camera);\n\t }\n\t\n\t // Render picking scene\n\t // this._renderer.render(this._picking._pickingScene, this._camera);\n\t\n\t // Render DOM scenes\n\t this._domRenderer3D.render(this._domScene3D, this._camera);\n\t this._domRenderer2D.render(this._domScene2D, this._camera);\n\t\n\t this.emit('postRender');\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Remove any remaining objects from scene\n\t var child;\n\t for (var i = this._scene.children.length - 1; i >= 0; i--) {\n\t child = this._scene.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._scene.remove(child);\n\t\n\t if (child.geometry) {\n\t // Dispose of mesh and materials\n\t child.geometry.dispose();\n\t child.geometry = null;\n\t }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t };\n\t\n\t for (var i = this._domScene3D.children.length - 1; i >= 0; i--) {\n\t child = this._domScene3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._domScene3D.remove(child);\n\t };\n\t\n\t for (var i = this._domScene2D.children.length - 1; i >= 0; i--) {\n\t child = this._domScene2D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._domScene2D.remove(child);\n\t };\n\t\n\t this._picking.destroy();\n\t this._picking = null;\n\t\n\t this._world = null;\n\t this._scene = null;\n\t this._domScene3D = null;\n\t this._domScene2D = null;\n\t\n\t this._composer = null;\n\t this._renderer = null;\n\t\n\t this._domRenderer3D = null;\n\t this._domRenderer2D = null;\n\t this._camera = null;\n\t this._clock = null;\n\t this._frustum = null;\n\t }\n\t }]);\n\t\n\t return Engine;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Engine;\n\t\n\t// // Initialise without requiring new keyword\n\t// export default function(container, world) {\n\t// return new Engine(container, world);\n\t// };\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 10 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_10__;\n\n/***/ },\n/* 11 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t\n\t // TODO: Re-enable when this works with the skybox\n\t // scene.fog = new THREE.Fog(0xffffff, 1, 15000);\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 12 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 13 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.scene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 14 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Scene = __webpack_require__(11);\n\t\n\tvar _Scene2 = _interopRequireDefault(_Scene);\n\t\n\t// This can only be accessed from Engine.renderer if you want to reference the\n\t// same scene in multiple places\n\t\n\texports['default'] = function (container, antialias) {\n\t var renderer = new _three2['default'].WebGLRenderer({\n\t antialias: antialias\n\t\n\t // Enabling this removes a lot of z-index intersecting but it also removes\n\t // shadows due to a bug in three.js\n\t //\n\t // See: https://github.com/mrdoob/three.js/issues/7815\n\t // logarithmicDepthBuffer: true\n\t });\n\t\n\t // TODO: Re-enable when this works with the skybox\n\t // renderer.setClearColor(Scene.fog.color, 1);\n\t\n\t renderer.setClearColor(0xffffff, 1);\n\t\n\t // TODO: Re-enable this when perf issues can be solved\n\t //\n\t // Rendering double the resolution of the screen can be really slow\n\t // var pixelRatio = window.devicePixelRatio;\n\t var pixelRatio = 1;\n\t\n\t renderer.setPixelRatio(pixelRatio);\n\t\n\t // Gamma settings make things look nicer\n\t renderer.gammaInput = true;\n\t renderer.gammaOutput = true;\n\t\n\t renderer.shadowMap.enabled = true;\n\t\n\t // TODO: Work out which of the shadowmap types is best\n\t // https://github.com/mrdoob/three.js/blob/r56/src/Three.js#L107\n\t // renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n\t\n\t // TODO: Check that leaving this as default (CullFrontFace) is right\n\t // renderer.shadowMap.cullFace = THREE.CullFaceBack;\n\t\n\t container.appendChild(renderer.domElement);\n\t\n\t var updateSize = function updateSize() {\n\t renderer.setSize(container.clientWidth, container.clientHeight);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return renderer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 15 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorCSS3DRenderer = __webpack_require__(16);\n\t\n\tvar _DOMScene3D = __webpack_require__(12);\n\t\n\tvar _DOMScene3D2 = _interopRequireDefault(_DOMScene3D);\n\t\n\t// This can only be accessed from Engine.renderer if you want to reference the\n\t// same scene in multiple places\n\t\n\texports['default'] = function (container) {\n\t var renderer = new _vendorCSS3DRenderer.CSS3DRenderer();\n\t\n\t renderer.domElement.style.position = 'absolute';\n\t renderer.domElement.style.top = 0;\n\t\n\t container.appendChild(renderer.domElement);\n\t\n\t var updateSize = function updateSize() {\n\t renderer.setSize(container.clientWidth, container.clientHeight);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return renderer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 16 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\t/**\n\t * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar CSS3DObject = function CSS3DObject(element) {\n\t\n\t\t_three2['default'].Object3D.call(this);\n\t\n\t\tthis.element = element;\n\t\tthis.element.style.position = 'absolute';\n\t\n\t\tthis.addEventListener('removed', function (event) {\n\t\n\t\t\tif (this.element.parentNode !== null) {\n\t\n\t\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t\t}\n\t\t});\n\t};\n\t\n\tCSS3DObject.prototype = Object.create(_three2['default'].Object3D.prototype);\n\tCSS3DObject.prototype.constructor = CSS3DObject;\n\t\n\tvar CSS3DSprite = function CSS3DSprite(element) {\n\t\n\t\tCSS3DObject.call(this, element);\n\t};\n\t\n\tCSS3DSprite.prototype = Object.create(CSS3DObject.prototype);\n\tCSS3DSprite.prototype.constructor = CSS3DSprite;\n\t\n\t//\n\t\n\tvar CSS3DRenderer = function CSS3DRenderer() {\n\t\n\t\tconsole.log('THREE.CSS3DRenderer', _three2['default'].REVISION);\n\t\n\t\tvar _width, _height;\n\t\tvar _widthHalf, _heightHalf;\n\t\n\t\tvar matrix = new _three2['default'].Matrix4();\n\t\n\t\tvar cache = {\n\t\t\tcamera: { fov: 0, style: '' },\n\t\t\tobjects: {}\n\t\t};\n\t\n\t\tvar domElement = document.createElement('div');\n\t\tdomElement.style.overflow = 'hidden';\n\t\n\t\tdomElement.style.WebkitTransformStyle = 'preserve-3d';\n\t\tdomElement.style.MozTransformStyle = 'preserve-3d';\n\t\tdomElement.style.oTransformStyle = 'preserve-3d';\n\t\tdomElement.style.transformStyle = 'preserve-3d';\n\t\n\t\tthis.domElement = domElement;\n\t\n\t\tvar cameraElement = document.createElement('div');\n\t\n\t\tcameraElement.style.WebkitTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.MozTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.oTransformStyle = 'preserve-3d';\n\t\tcameraElement.style.transformStyle = 'preserve-3d';\n\t\n\t\tdomElement.appendChild(cameraElement);\n\t\n\t\tthis.setClearColor = function () {};\n\t\n\t\tthis.getSize = function () {\n\t\n\t\t\treturn {\n\t\t\t\twidth: _width,\n\t\t\t\theight: _height\n\t\t\t};\n\t\t};\n\t\n\t\tthis.setSize = function (width, height) {\n\t\n\t\t\t_width = width;\n\t\t\t_height = height;\n\t\n\t\t\t_widthHalf = _width / 2;\n\t\t\t_heightHalf = _height / 2;\n\t\n\t\t\tdomElement.style.width = width + 'px';\n\t\t\tdomElement.style.height = height + 'px';\n\t\n\t\t\tcameraElement.style.width = width + 'px';\n\t\t\tcameraElement.style.height = height + 'px';\n\t\t};\n\t\n\t\tvar epsilon = function epsilon(value) {\n\t\n\t\t\treturn Math.abs(value) < Number.EPSILON ? 0 : value;\n\t\t};\n\t\n\t\tvar getCameraCSSMatrix = function getCameraCSSMatrix(matrix) {\n\t\n\t\t\tvar elements = matrix.elements;\n\t\n\t\t\treturn 'matrix3d(' + epsilon(elements[0]) + ',' + epsilon(-elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(elements[6]) + ',' + epsilon(elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(-elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(-elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')';\n\t\t};\n\t\n\t\tvar getObjectCSSMatrix = function getObjectCSSMatrix(matrix) {\n\t\n\t\t\tvar elements = matrix.elements;\n\t\n\t\t\treturn 'translate3d(-50%,-50%,0) matrix3d(' + epsilon(elements[0]) + ',' + epsilon(elements[1]) + ',' + epsilon(elements[2]) + ',' + epsilon(elements[3]) + ',' + epsilon(-elements[4]) + ',' + epsilon(-elements[5]) + ',' + epsilon(-elements[6]) + ',' + epsilon(-elements[7]) + ',' + epsilon(elements[8]) + ',' + epsilon(elements[9]) + ',' + epsilon(elements[10]) + ',' + epsilon(elements[11]) + ',' + epsilon(elements[12]) + ',' + epsilon(elements[13]) + ',' + epsilon(elements[14]) + ',' + epsilon(elements[15]) + ')';\n\t\t};\n\t\n\t\tvar renderObject = function renderObject(object, camera) {\n\t\n\t\t\tif (object instanceof CSS3DObject) {\n\t\n\t\t\t\tvar style;\n\t\n\t\t\t\tif (object instanceof CSS3DSprite) {\n\t\n\t\t\t\t\t// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/\n\t\n\t\t\t\t\tmatrix.copy(camera.matrixWorldInverse);\n\t\t\t\t\tmatrix.transpose();\n\t\t\t\t\tmatrix.copyPosition(object.matrixWorld);\n\t\t\t\t\tmatrix.scale(object.scale);\n\t\n\t\t\t\t\tmatrix.elements[3] = 0;\n\t\t\t\t\tmatrix.elements[7] = 0;\n\t\t\t\t\tmatrix.elements[11] = 0;\n\t\t\t\t\tmatrix.elements[15] = 1;\n\t\n\t\t\t\t\tstyle = getObjectCSSMatrix(matrix);\n\t\t\t\t} else {\n\t\n\t\t\t\t\tstyle = getObjectCSSMatrix(object.matrixWorld);\n\t\t\t\t}\n\t\n\t\t\t\tvar element = object.element;\n\t\t\t\tvar cachedStyle = cache.objects[object.id];\n\t\n\t\t\t\tif (cachedStyle === undefined || cachedStyle !== style) {\n\t\n\t\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\t\telement.style.MozTransform = style;\n\t\t\t\t\telement.style.oTransform = style;\n\t\t\t\t\telement.style.transform = style;\n\t\n\t\t\t\t\tcache.objects[object.id] = style;\n\t\t\t\t}\n\t\n\t\t\t\tif (element.parentNode !== cameraElement) {\n\t\n\t\t\t\t\tcameraElement.appendChild(element);\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (var i = 0, l = object.children.length; i < l; i++) {\n\t\n\t\t\t\trenderObject(object.children[i], camera);\n\t\t\t}\n\t\t};\n\t\n\t\tthis.render = function (scene, camera) {\n\t\n\t\t\tvar fov = 0.5 / Math.tan(_three2['default'].Math.degToRad(camera.fov * 0.5)) * _height;\n\t\n\t\t\tif (cache.camera.fov !== fov) {\n\t\n\t\t\t\tdomElement.style.WebkitPerspective = fov + 'px';\n\t\t\t\tdomElement.style.MozPerspective = fov + 'px';\n\t\t\t\tdomElement.style.oPerspective = fov + 'px';\n\t\t\t\tdomElement.style.perspective = fov + 'px';\n\t\n\t\t\t\tcache.camera.fov = fov;\n\t\t\t}\n\t\n\t\t\tscene.updateMatrixWorld();\n\t\n\t\t\tif (camera.parent === null) camera.updateMatrixWorld();\n\t\n\t\t\tcamera.matrixWorldInverse.getInverse(camera.matrixWorld);\n\t\n\t\t\tvar style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix(camera.matrixWorldInverse) + ' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)';\n\t\n\t\t\tif (cache.camera.style !== style) {\n\t\n\t\t\t\tcameraElement.style.WebkitTransform = style;\n\t\t\t\tcameraElement.style.MozTransform = style;\n\t\t\t\tcameraElement.style.oTransform = style;\n\t\t\t\tcameraElement.style.transform = style;\n\t\n\t\t\t\tcache.camera.style = style;\n\t\t\t}\n\t\n\t\t\trenderObject(scene, camera);\n\t\t};\n\t};\n\t\n\texports.CSS3DObject = CSS3DObject;\n\texports.CSS3DSprite = CSS3DSprite;\n\texports.CSS3DRenderer = CSS3DRenderer;\n\t\n\t_three2['default'].CSS3DObject = CSS3DObject;\n\t_three2['default'].CSS3DSprite = CSS3DSprite;\n\t_three2['default'].CSS3DRenderer = CSS3DRenderer;\n\n/***/ },\n/* 17 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorCSS2DRenderer = __webpack_require__(18);\n\t\n\tvar _DOMScene2D = __webpack_require__(13);\n\t\n\tvar _DOMScene2D2 = _interopRequireDefault(_DOMScene2D);\n\t\n\t// This can only be accessed from Engine.renderer if you want to reference the\n\t// same scene in multiple places\n\t\n\texports['default'] = function (container) {\n\t var renderer = new _vendorCSS2DRenderer.CSS2DRenderer();\n\t\n\t renderer.domElement.style.position = 'absolute';\n\t renderer.domElement.style.top = 0;\n\t\n\t container.appendChild(renderer.domElement);\n\t\n\t var updateSize = function updateSize() {\n\t renderer.setSize(container.clientWidth, container.clientHeight);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return renderer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 18 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar CSS2DObject = function CSS2DObject(element) {\n\t\n\t\t_three2['default'].Object3D.call(this);\n\t\n\t\tthis.element = element;\n\t\tthis.element.style.position = 'absolute';\n\t\n\t\tthis.addEventListener('removed', function (event) {\n\t\n\t\t\tif (this.element.parentNode !== null) {\n\t\n\t\t\t\tthis.element.parentNode.removeChild(this.element);\n\t\t\t}\n\t\t});\n\t};\n\t\n\tCSS2DObject.prototype = Object.create(_three2['default'].Object3D.prototype);\n\tCSS2DObject.prototype.constructor = CSS2DObject;\n\t\n\t//\n\t\n\tvar CSS2DRenderer = function CSS2DRenderer() {\n\t\n\t\tconsole.log('THREE.CSS2DRenderer', _three2['default'].REVISION);\n\t\n\t\tvar _width, _height;\n\t\tvar _widthHalf, _heightHalf;\n\t\n\t\tvar vector = new _three2['default'].Vector3();\n\t\tvar viewMatrix = new _three2['default'].Matrix4();\n\t\tvar viewProjectionMatrix = new _three2['default'].Matrix4();\n\t\n\t\tvar frustum = new _three2['default'].Frustum();\n\t\n\t\tvar domElement = document.createElement('div');\n\t\tdomElement.style.overflow = 'hidden';\n\t\n\t\tthis.domElement = domElement;\n\t\n\t\tthis.setSize = function (width, height) {\n\t\n\t\t\t_width = width;\n\t\t\t_height = height;\n\t\n\t\t\t_widthHalf = _width / 2;\n\t\t\t_heightHalf = _height / 2;\n\t\n\t\t\tdomElement.style.width = width + 'px';\n\t\t\tdomElement.style.height = height + 'px';\n\t\t};\n\t\n\t\tvar renderObject = function renderObject(object, camera) {\n\t\n\t\t\tif (object instanceof CSS2DObject) {\n\t\n\t\t\t\tvector.setFromMatrixPosition(object.matrixWorld);\n\t\t\t\tvector.applyProjection(viewProjectionMatrix);\n\t\n\t\t\t\tvar element = object.element;\n\t\t\t\tvar style = 'translate(-50%,-50%) translate(' + (vector.x * _widthHalf + _widthHalf) + 'px,' + (-vector.y * _heightHalf + _heightHalf) + 'px)';\n\t\n\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\telement.style.MozTransform = style;\n\t\t\t\telement.style.oTransform = style;\n\t\t\t\telement.style.transform = style;\n\t\n\t\t\t\tif (element.parentNode !== domElement) {\n\t\n\t\t\t\t\tdomElement.appendChild(element);\n\t\t\t\t}\n\t\n\t\t\t\t// Hide if outside view frustum\n\t\t\t\tif (!frustum.containsPoint(object.position)) {\n\t\t\t\t\telement.style.display = 'none';\n\t\t\t\t} else {\n\t\t\t\t\telement.style.display = 'block';\n\t\t\t\t}\n\t\t\t}\n\t\n\t\t\tfor (var i = 0, l = object.children.length; i < l; i++) {\n\t\n\t\t\t\trenderObject(object.children[i], camera);\n\t\t\t}\n\t\t};\n\t\n\t\tthis.render = function (scene, camera) {\n\t\n\t\t\tscene.updateMatrixWorld();\n\t\n\t\t\tif (camera.parent === null) camera.updateMatrixWorld();\n\t\n\t\t\tcamera.matrixWorldInverse.getInverse(camera.matrixWorld);\n\t\n\t\t\tviewMatrix.copy(camera.matrixWorldInverse.getInverse(camera.matrixWorld));\n\t\t\tviewProjectionMatrix.multiplyMatrices(camera.projectionMatrix, viewMatrix);\n\t\n\t\t\tfrustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n\t\n\t\t\trenderObject(scene, camera);\n\t\t};\n\t};\n\t\n\texports.CSS2DObject = CSS2DObject;\n\texports.CSS2DRenderer = CSS2DRenderer;\n\t\n\t_three2['default'].CSS2DObject = CSS2DObject;\n\t_three2['default'].CSS2DRenderer = CSS2DRenderer;\n\n/***/ },\n/* 19 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can only be accessed from Engine.camera if you want to reference the\n\t// same scene in multiple places\n\t\n\t// TODO: Ensure that FOV looks natural on all aspect ratios\n\t// http://stackoverflow.com/q/26655930/997339\n\t\n\texports['default'] = function (container) {\n\t var camera = new _three2['default'].PerspectiveCamera(45, 1, 1, 2000000);\n\t camera.position.y = 4000;\n\t camera.position.z = 4000;\n\t\n\t var updateSize = function updateSize() {\n\t camera.aspect = container.clientWidth / container.clientHeight;\n\t camera.updateProjectionMatrix();\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return camera;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 20 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _PickingScene = __webpack_require__(21);\n\t\n\tvar _PickingScene2 = _interopRequireDefault(_PickingScene);\n\t\n\tvar _lodashThrottle = __webpack_require__(22);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\t// TODO: Look into a way of setting this up without passing in a renderer and\n\t// camera from the engine\n\t\n\t// TODO: Add a basic indicator on or around the mouse pointer when it is over\n\t// something pickable / clickable\n\t//\n\t// A simple transparent disc or ring at the mouse point should work to start, or\n\t// even just changing the cursor to the CSS 'pointer' style\n\t//\n\t// Probably want this on mousemove with a throttled update as not to spam the\n\t// picking method\n\t//\n\t// Relies upon the picking method not redrawing the scene every call due to\n\t// the way TileLayer invalidates the picking scene\n\t\n\tvar nextId = 1;\n\t\n\tvar Picking = (function () {\n\t function Picking(world, renderer, camera) {\n\t _classCallCheck(this, Picking);\n\t\n\t this._world = world;\n\t this._renderer = renderer;\n\t this._camera = camera;\n\t\n\t this._raycaster = new _three2['default'].Raycaster();\n\t\n\t // TODO: Match this with the line width used in the picking layers\n\t this._raycaster.linePrecision = 3;\n\t\n\t this._pickingScene = _PickingScene2['default'];\n\t this._pickingTexture = new _three2['default'].WebGLRenderTarget();\n\t this._pickingTexture.texture.minFilter = _three2['default'].LinearFilter;\n\t this._pickingTexture.texture.generateMipmaps = false;\n\t\n\t this._nextId = 1;\n\t\n\t this._resizeTexture();\n\t this._initEvents();\n\t }\n\t\n\t // Initialise without requiring new keyword\n\t\n\t _createClass(Picking, [{\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t this._resizeHandler = this._resizeTexture.bind(this);\n\t window.addEventListener('resize', this._resizeHandler, false);\n\t\n\t this._throttledMouseMoveHandler = (0, _lodashThrottle2['default'])(this._onMouseMove.bind(this), 50);\n\t this._mouseUpHandler = this._onMouseUp.bind(this);\n\t this._world._container.addEventListener('mouseup', this._mouseUpHandler, false);\n\t this._world._container.addEventListener('mousemove', this._throttledMouseMoveHandler, false);\n\t\n\t this._world.on('move', this._onWorldMove, this);\n\t }\n\t }, {\n\t key: '_onMouseUp',\n\t value: function _onMouseUp(event) {\n\t // Only react to main button click\n\t if (event.button !== 0) {\n\t return;\n\t }\n\t\n\t var point = (0, _geoPoint.point)(event.clientX - this._world._container.offsetLeft, event.clientY - this._world._container.offsetTop);\n\t\n\t var normalisedPoint = (0, _geoPoint.point)(0, 0);\n\t normalisedPoint.x = point.x / this._width * 2 - 1;\n\t normalisedPoint.y = -(point.y / this._height) * 2 + 1;\n\t\n\t this._pick(point, normalisedPoint);\n\t }\n\t }, {\n\t key: '_onMouseMove',\n\t value: function _onMouseMove(event) {\n\t var point = (0, _geoPoint.point)(event.clientX - this._world._container.offsetLeft, event.clientY - this._world._container.offsetTop);\n\t\n\t var normalisedPoint = (0, _geoPoint.point)(0, 0);\n\t normalisedPoint.x = point.x / this._width * 2 - 1;\n\t normalisedPoint.y = -(point.y / this._height) * 2 + 1;\n\t\n\t this._pick(point, normalisedPoint, true);\n\t }\n\t }, {\n\t key: '_onWorldMove',\n\t value: function _onWorldMove() {\n\t this._needUpdate = true;\n\t }\n\t\n\t // TODO: Ensure this doesn't get out of sync issue with the renderer resize\n\t }, {\n\t key: '_resizeTexture',\n\t value: function _resizeTexture() {\n\t var size = this._renderer.getSize();\n\t\n\t this._width = size.width;\n\t this._height = size.height;\n\t\n\t this._pickingTexture.setSize(this._width, this._height);\n\t this._pixelBuffer = new Uint8Array(4 * this._width * this._height);\n\t\n\t this._needUpdate = true;\n\t }\n\t\n\t // TODO: Make this only re-draw the scene if both an update is needed and the\n\t // camera has moved since the last update\n\t //\n\t // Otherwise it re-draws the scene on every click due to the way LOD updates\n\t // work in TileLayer – spamming this.add() and this.remove()\n\t //\n\t // TODO: Pause updates during map move / orbit / zoom as this is unlikely to\n\t // be a point in time where the user cares for picking functionality\n\t }, {\n\t key: '_update',\n\t value: function _update() {\n\t if (this._needUpdate) {\n\t var texture = this._pickingTexture;\n\t\n\t this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);\n\t\n\t // Read the rendering texture\n\t this._renderer.readRenderTargetPixels(texture, 0, 0, texture.width, texture.height, this._pixelBuffer);\n\t\n\t this._needUpdate = false;\n\t }\n\t }\n\t }, {\n\t key: '_pick',\n\t value: function _pick(point, normalisedPoint, hover) {\n\t this._update();\n\t\n\t var index = point.x + (this._pickingTexture.height - point.y) * this._pickingTexture.width;\n\t\n\t // Interpret the pixel as an ID\n\t var id = this._pixelBuffer[index * 4 + 2] * 255 * 255 + this._pixelBuffer[index * 4 + 1] * 255 + this._pixelBuffer[index * 4 + 0];\n\t\n\t // Skip if ID is 16646655 (white) as the background returns this\n\t if (id === 16646655) {\n\t if (hover) {\n\t this._world.emit('pick-hover-reset');\n\t } else {\n\t this._world.emit('pick-click-reset');\n\t }\n\t\n\t return;\n\t }\n\t\n\t this._raycaster.setFromCamera(normalisedPoint, this._camera);\n\t\n\t // Perform ray intersection on picking scene\n\t //\n\t // TODO: Only perform intersection test on the relevant picking mesh\n\t var intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);\n\t\n\t var _point2d = point.clone();\n\t\n\t var _point3d;\n\t if (intersects.length > 0) {\n\t _point3d = intersects[0].point.clone();\n\t }\n\t\n\t // Pass along as much data as possible for now until we know more about how\n\t // people use the picking API and what the returned data should be\n\t //\n\t // TODO: Look into the leak potential for passing so much by reference here\n\t // this._world.emit('pick', id, _point2d, _point3d, intersects);\n\t // this._world.emit('pick-' + id, _point2d, _point3d, intersects);\n\t\n\t if (hover) {\n\t this._world.emit('pick-hover', id, _point2d, _point3d, intersects);\n\t this._world.emit('pick-hover-' + id, _point2d, _point3d, intersects);\n\t } else {\n\t this._world.emit('pick-click', id, _point2d, _point3d, intersects);\n\t this._world.emit('pick-click-' + id, _point2d, _point3d, intersects);\n\t }\n\t }\n\t\n\t // Add mesh to picking scene\n\t //\n\t // Picking ID should already be added as an attribute\n\t }, {\n\t key: 'add',\n\t value: function add(mesh) {\n\t this._pickingScene.add(mesh);\n\t this._needUpdate = true;\n\t }\n\t\n\t // Remove mesh from picking scene\n\t }, {\n\t key: 'remove',\n\t value: function remove(mesh) {\n\t this._pickingScene.remove(mesh);\n\t this._needUpdate = true;\n\t }\n\t\n\t // Returns next ID to use for picking\n\t }, {\n\t key: 'getNextId',\n\t value: function getNextId() {\n\t return nextId++;\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // TODO: Find a way to properly remove these listeners as they stay\n\t // active at the moment\n\t window.removeEventListener('resize', this._resizeHandler, false);\n\t this._world._container.removeEventListener('mouseup', this._mouseUpHandler, false);\n\t this._world._container.removeEventListener('mousemove', this._throttledMouseMoveHandler, false);\n\t\n\t this._world.off('move', this._onWorldMove);\n\t\n\t if (this._pickingScene.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._pickingScene.children.length - 1; i >= 0; i--) {\n\t child = this._pickingScene.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this._pickingScene.remove(child);\n\t\n\t // Probably not a good idea to dispose of geometry due to it being\n\t // shared with the non-picking scene\n\t // if (child.geometry) {\n\t // // Dispose of mesh and materials\n\t // child.geometry.dispose();\n\t // child.geometry = null;\n\t // }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t }\n\t }\n\t\n\t this._pickingScene = null;\n\t this._pickingTexture = null;\n\t this._pixelBuffer = null;\n\t\n\t this._world = null;\n\t this._renderer = null;\n\t this._camera = null;\n\t }\n\t }]);\n\t\n\t return Picking;\n\t})();\n\t\n\texports['default'] = function (world, renderer, camera) {\n\t return new Picking(world, renderer, camera);\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 21 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// This can be imported from anywhere and will still reference the same scene,\n\t// though there is a helper reference in Engine.pickingScene\n\t\n\texports['default'] = (function () {\n\t var scene = new _three2['default'].Scene();\n\t return scene;\n\t})();\n\t\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 22 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/**\n\t * lodash 4.0.1 (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright 2012-2016 The Dojo Foundation \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t * Available under MIT license \n\t */\n\tvar debounce = __webpack_require__(23);\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/**\n\t * Creates a throttled function that only invokes `func` at most once per\n\t * every `wait` milliseconds. The throttled function comes with a `cancel`\n\t * method to cancel delayed `func` invocations and a `flush` method to\n\t * immediately invoke them. Provide an options object to indicate whether\n\t * `func` should be invoked on the leading and/or trailing edge of the `wait`\n\t * timeout. The `func` is invoked with the last arguments provided to the\n\t * throttled function. Subsequent calls to the throttled function return the\n\t * result of the last `func` invocation.\n\t *\n\t * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n\t * on the trailing edge of the timeout only if the throttled function is\n\t * invoked more than once during the `wait` timeout.\n\t *\n\t * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)\n\t * for details over the differences between `_.throttle` and `_.debounce`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @category Function\n\t * @param {Function} func The function to throttle.\n\t * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n\t * @param {Object} [options] The options object.\n\t * @param {boolean} [options.leading=true] Specify invoking on the leading\n\t * edge of the timeout.\n\t * @param {boolean} [options.trailing=true] Specify invoking on the trailing\n\t * edge of the timeout.\n\t * @returns {Function} Returns the new throttled function.\n\t * @example\n\t *\n\t * // Avoid excessively updating the position while scrolling.\n\t * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n\t *\n\t * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n\t * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n\t * jQuery(element).on('click', throttled);\n\t *\n\t * // Cancel the trailing throttled invocation.\n\t * jQuery(window).on('popstate', throttled.cancel);\n\t */\n\tfunction throttle(func, wait, options) {\n\t var leading = true,\n\t trailing = true;\n\t\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t if (isObject(options)) {\n\t leading = 'leading' in options ? !!options.leading : leading;\n\t trailing = 'trailing' in options ? !!options.trailing : trailing;\n\t }\n\t return debounce(func, wait, {\n\t 'leading': leading,\n\t 'maxWait': wait,\n\t 'trailing': trailing\n\t });\n\t}\n\t\n\t/**\n\t * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n\t * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\tmodule.exports = throttle;\n\n\n/***/ },\n/* 23 */\n/***/ function(module, exports) {\n\n\t/**\n\t * lodash 4.0.6 (Custom Build) \n\t * Build: `lodash modularize exports=\"npm\" -o ./`\n\t * Copyright jQuery Foundation and other contributors \n\t * Released under MIT license \n\t * Based on Underscore.js 1.8.3 \n\t * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n\t */\n\t\n\t/** Used as the `TypeError` message for \"Functions\" methods. */\n\tvar FUNC_ERROR_TEXT = 'Expected a function';\n\t\n\t/** Used as references for various `Number` constants. */\n\tvar NAN = 0 / 0;\n\t\n\t/** `Object#toString` result references. */\n\tvar funcTag = '[object Function]',\n\t genTag = '[object GeneratorFunction]',\n\t symbolTag = '[object Symbol]';\n\t\n\t/** Used to match leading and trailing whitespace. */\n\tvar reTrim = /^\\s+|\\s+$/g;\n\t\n\t/** Used to detect bad signed hexadecimal string values. */\n\tvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\t\n\t/** Used to detect binary string values. */\n\tvar reIsBinary = /^0b[01]+$/i;\n\t\n\t/** Used to detect octal string values. */\n\tvar reIsOctal = /^0o[0-7]+$/i;\n\t\n\t/** Built-in method references without a dependency on `root`. */\n\tvar freeParseInt = parseInt;\n\t\n\t/** Used for built-in method references. */\n\tvar objectProto = Object.prototype;\n\t\n\t/**\n\t * Used to resolve the\n\t * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n\t * of values.\n\t */\n\tvar objectToString = objectProto.toString;\n\t\n\t/* Built-in method references for those with the same name as other `lodash` methods. */\n\tvar nativeMax = Math.max,\n\t nativeMin = Math.min;\n\t\n\t/**\n\t * Gets the timestamp of the number of milliseconds that have elapsed since\n\t * the Unix epoch (1 January 1970 00:00:00 UTC).\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 2.4.0\n\t * @type {Function}\n\t * @category Date\n\t * @returns {number} Returns the timestamp.\n\t * @example\n\t *\n\t * _.defer(function(stamp) {\n\t * console.log(_.now() - stamp);\n\t * }, _.now());\n\t * // => Logs the number of milliseconds it took for the deferred function to be invoked.\n\t */\n\tvar now = Date.now;\n\t\n\t/**\n\t * Creates a debounced function that delays invoking `func` until after `wait`\n\t * milliseconds have elapsed since the last time the debounced function was\n\t * invoked. The debounced function comes with a `cancel` method to cancel\n\t * delayed `func` invocations and a `flush` method to immediately invoke them.\n\t * Provide an options object to indicate whether `func` should be invoked on\n\t * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n\t * with the last arguments provided to the debounced function. Subsequent calls\n\t * to the debounced function return the result of the last `func` invocation.\n\t *\n\t * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n\t * on the trailing edge of the timeout only if the debounced function is\n\t * invoked more than once during the `wait` timeout.\n\t *\n\t * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n\t * for details over the differences between `_.debounce` and `_.throttle`.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Function\n\t * @param {Function} func The function to debounce.\n\t * @param {number} [wait=0] The number of milliseconds to delay.\n\t * @param {Object} [options={}] The options object.\n\t * @param {boolean} [options.leading=false]\n\t * Specify invoking on the leading edge of the timeout.\n\t * @param {number} [options.maxWait]\n\t * The maximum time `func` is allowed to be delayed before it's invoked.\n\t * @param {boolean} [options.trailing=true]\n\t * Specify invoking on the trailing edge of the timeout.\n\t * @returns {Function} Returns the new debounced function.\n\t * @example\n\t *\n\t * // Avoid costly calculations while the window size is in flux.\n\t * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n\t *\n\t * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n\t * jQuery(element).on('click', _.debounce(sendMail, 300, {\n\t * 'leading': true,\n\t * 'trailing': false\n\t * }));\n\t *\n\t * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n\t * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n\t * var source = new EventSource('/stream');\n\t * jQuery(source).on('message', debounced);\n\t *\n\t * // Cancel the trailing debounced invocation.\n\t * jQuery(window).on('popstate', debounced.cancel);\n\t */\n\tfunction debounce(func, wait, options) {\n\t var lastArgs,\n\t lastThis,\n\t maxWait,\n\t result,\n\t timerId,\n\t lastCallTime = 0,\n\t lastInvokeTime = 0,\n\t leading = false,\n\t maxing = false,\n\t trailing = true;\n\t\n\t if (typeof func != 'function') {\n\t throw new TypeError(FUNC_ERROR_TEXT);\n\t }\n\t wait = toNumber(wait) || 0;\n\t if (isObject(options)) {\n\t leading = !!options.leading;\n\t maxing = 'maxWait' in options;\n\t maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n\t trailing = 'trailing' in options ? !!options.trailing : trailing;\n\t }\n\t\n\t function invokeFunc(time) {\n\t var args = lastArgs,\n\t thisArg = lastThis;\n\t\n\t lastArgs = lastThis = undefined;\n\t lastInvokeTime = time;\n\t result = func.apply(thisArg, args);\n\t return result;\n\t }\n\t\n\t function leadingEdge(time) {\n\t // Reset any `maxWait` timer.\n\t lastInvokeTime = time;\n\t // Start the timer for the trailing edge.\n\t timerId = setTimeout(timerExpired, wait);\n\t // Invoke the leading edge.\n\t return leading ? invokeFunc(time) : result;\n\t }\n\t\n\t function remainingWait(time) {\n\t var timeSinceLastCall = time - lastCallTime,\n\t timeSinceLastInvoke = time - lastInvokeTime,\n\t result = wait - timeSinceLastCall;\n\t\n\t return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n\t }\n\t\n\t function shouldInvoke(time) {\n\t var timeSinceLastCall = time - lastCallTime,\n\t timeSinceLastInvoke = time - lastInvokeTime;\n\t\n\t // Either this is the first call, activity has stopped and we're at the\n\t // trailing edge, the system time has gone backwards and we're treating\n\t // it as the trailing edge, or we've hit the `maxWait` limit.\n\t return (!lastCallTime || (timeSinceLastCall >= wait) ||\n\t (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n\t }\n\t\n\t function timerExpired() {\n\t var time = now();\n\t if (shouldInvoke(time)) {\n\t return trailingEdge(time);\n\t }\n\t // Restart the timer.\n\t timerId = setTimeout(timerExpired, remainingWait(time));\n\t }\n\t\n\t function trailingEdge(time) {\n\t clearTimeout(timerId);\n\t timerId = undefined;\n\t\n\t // Only invoke if we have `lastArgs` which means `func` has been\n\t // debounced at least once.\n\t if (trailing && lastArgs) {\n\t return invokeFunc(time);\n\t }\n\t lastArgs = lastThis = undefined;\n\t return result;\n\t }\n\t\n\t function cancel() {\n\t if (timerId !== undefined) {\n\t clearTimeout(timerId);\n\t }\n\t lastCallTime = lastInvokeTime = 0;\n\t lastArgs = lastThis = timerId = undefined;\n\t }\n\t\n\t function flush() {\n\t return timerId === undefined ? result : trailingEdge(now());\n\t }\n\t\n\t function debounced() {\n\t var time = now(),\n\t isInvoking = shouldInvoke(time);\n\t\n\t lastArgs = arguments;\n\t lastThis = this;\n\t lastCallTime = time;\n\t\n\t if (isInvoking) {\n\t if (timerId === undefined) {\n\t return leadingEdge(lastCallTime);\n\t }\n\t if (maxing) {\n\t // Handle invocations in a tight loop.\n\t clearTimeout(timerId);\n\t timerId = setTimeout(timerExpired, wait);\n\t return invokeFunc(lastCallTime);\n\t }\n\t }\n\t if (timerId === undefined) {\n\t timerId = setTimeout(timerExpired, wait);\n\t }\n\t return result;\n\t }\n\t debounced.cancel = cancel;\n\t debounced.flush = flush;\n\t return debounced;\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Function` object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isFunction(_);\n\t * // => true\n\t *\n\t * _.isFunction(/abc/);\n\t * // => false\n\t */\n\tfunction isFunction(value) {\n\t // The use of `Object#toString` avoids issues with the `typeof` operator\n\t // in Safari 8 which returns 'object' for typed array and weak map constructors,\n\t // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n\t var tag = isObject(value) ? objectToString.call(value) : '';\n\t return tag == funcTag || tag == genTag;\n\t}\n\t\n\t/**\n\t * Checks if `value` is the\n\t * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n\t * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 0.1.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n\t * @example\n\t *\n\t * _.isObject({});\n\t * // => true\n\t *\n\t * _.isObject([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObject(_.noop);\n\t * // => true\n\t *\n\t * _.isObject(null);\n\t * // => false\n\t */\n\tfunction isObject(value) {\n\t var type = typeof value;\n\t return !!value && (type == 'object' || type == 'function');\n\t}\n\t\n\t/**\n\t * Checks if `value` is object-like. A value is object-like if it's not `null`\n\t * and has a `typeof` result of \"object\".\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n\t * @example\n\t *\n\t * _.isObjectLike({});\n\t * // => true\n\t *\n\t * _.isObjectLike([1, 2, 3]);\n\t * // => true\n\t *\n\t * _.isObjectLike(_.noop);\n\t * // => false\n\t *\n\t * _.isObjectLike(null);\n\t * // => false\n\t */\n\tfunction isObjectLike(value) {\n\t return !!value && typeof value == 'object';\n\t}\n\t\n\t/**\n\t * Checks if `value` is classified as a `Symbol` primitive or object.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to check.\n\t * @returns {boolean} Returns `true` if `value` is correctly classified,\n\t * else `false`.\n\t * @example\n\t *\n\t * _.isSymbol(Symbol.iterator);\n\t * // => true\n\t *\n\t * _.isSymbol('abc');\n\t * // => false\n\t */\n\tfunction isSymbol(value) {\n\t return typeof value == 'symbol' ||\n\t (isObjectLike(value) && objectToString.call(value) == symbolTag);\n\t}\n\t\n\t/**\n\t * Converts `value` to a number.\n\t *\n\t * @static\n\t * @memberOf _\n\t * @since 4.0.0\n\t * @category Lang\n\t * @param {*} value The value to process.\n\t * @returns {number} Returns the number.\n\t * @example\n\t *\n\t * _.toNumber(3);\n\t * // => 3\n\t *\n\t * _.toNumber(Number.MIN_VALUE);\n\t * // => 5e-324\n\t *\n\t * _.toNumber(Infinity);\n\t * // => Infinity\n\t *\n\t * _.toNumber('3');\n\t * // => 3\n\t */\n\tfunction toNumber(value) {\n\t if (typeof value == 'number') {\n\t return value;\n\t }\n\t if (isSymbol(value)) {\n\t return NAN;\n\t }\n\t if (isObject(value)) {\n\t var other = isFunction(value.valueOf) ? value.valueOf() : value;\n\t value = isObject(other) ? (other + '') : other;\n\t }\n\t if (typeof value != 'string') {\n\t return value === 0 ? value : +value;\n\t }\n\t value = value.replace(reTrim, '');\n\t var isBinary = reIsBinary.test(value);\n\t return (isBinary || reIsOctal.test(value))\n\t ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n\t : (reIsBadHex.test(value) ? NAN : +value);\n\t}\n\t\n\tmodule.exports = debounce;\n\n\n/***/ },\n/* 24 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorEffectComposer = __webpack_require__(25);\n\t\n\tvar _vendorEffectComposer2 = _interopRequireDefault(_vendorEffectComposer);\n\t\n\texports['default'] = function (renderer, container) {\n\t var composer = new _vendorEffectComposer2['default'](renderer);\n\t\n\t var updateSize = function updateSize() {\n\t // TODO: Re-enable this when perf issues can be solved\n\t //\n\t // Rendering double the resolution of the screen can be really slow\n\t // var pixelRatio = window.devicePixelRatio;\n\t var pixelRatio = 1;\n\t\n\t composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio);\n\t };\n\t\n\t window.addEventListener('resize', updateSize, false);\n\t updateSize();\n\t\n\t return composer;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 25 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _CopyShader = __webpack_require__(26);\n\t\n\tvar _CopyShader2 = _interopRequireDefault(_CopyShader);\n\t\n\tvar _ShaderPass = __webpack_require__(27);\n\t\n\tvar _ShaderPass2 = _interopRequireDefault(_ShaderPass);\n\t\n\tvar _MaskPass = __webpack_require__(28);\n\t\n\tvar _MaskPass2 = _interopRequireDefault(_MaskPass);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar EffectComposer = function EffectComposer(renderer, renderTarget) {\n\t\n\t\tthis.renderer = renderer;\n\t\n\t\tif (renderTarget === undefined) {\n\t\n\t\t\tvar pixelRatio = renderer.getPixelRatio();\n\t\n\t\t\tvar width = Math.floor(renderer.context.canvas.width / pixelRatio) || 1;\n\t\t\tvar height = Math.floor(renderer.context.canvas.height / pixelRatio) || 1;\n\t\t\tvar parameters = { minFilter: _three2['default'].LinearFilter, magFilter: _three2['default'].LinearFilter, format: _three2['default'].RGBAFormat, stencilBuffer: false };\n\t\n\t\t\trenderTarget = new _three2['default'].WebGLRenderTarget(width, height, parameters);\n\t\t}\n\t\n\t\tthis.renderTarget1 = renderTarget;\n\t\tthis.renderTarget2 = renderTarget.clone();\n\t\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\t\n\t\tthis.passes = [];\n\t\n\t\tif (_CopyShader2['default'] === undefined) console.error(\"EffectComposer relies on THREE.CopyShader\");\n\t\n\t\tthis.copyPass = new _ShaderPass2['default'](_CopyShader2['default']);\n\t};\n\t\n\tEffectComposer.prototype = {\n\t\n\t\tswapBuffers: function swapBuffers() {\n\t\n\t\t\tvar tmp = this.readBuffer;\n\t\t\tthis.readBuffer = this.writeBuffer;\n\t\t\tthis.writeBuffer = tmp;\n\t\t},\n\t\n\t\taddPass: function addPass(pass) {\n\t\n\t\t\tthis.passes.push(pass);\n\t\t},\n\t\n\t\tinsertPass: function insertPass(pass, index) {\n\t\n\t\t\tthis.passes.splice(index, 0, pass);\n\t\t},\n\t\n\t\trender: function render(delta) {\n\t\n\t\t\tthis.writeBuffer = this.renderTarget1;\n\t\t\tthis.readBuffer = this.renderTarget2;\n\t\n\t\t\tvar maskActive = false;\n\t\n\t\t\tvar pass,\n\t\t\t i,\n\t\t\t il = this.passes.length;\n\t\n\t\t\tfor (i = 0; i < il; i++) {\n\t\n\t\t\t\tpass = this.passes[i];\n\t\n\t\t\t\tif (!pass.enabled) continue;\n\t\n\t\t\t\tpass.render(this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive);\n\t\n\t\t\t\tif (pass.needsSwap) {\n\t\n\t\t\t\t\tif (maskActive) {\n\t\n\t\t\t\t\t\tvar context = this.renderer.context;\n\t\n\t\t\t\t\t\tcontext.stencilFunc(context.NOTEQUAL, 1, 0xffffffff);\n\t\n\t\t\t\t\t\tthis.copyPass.render(this.renderer, this.writeBuffer, this.readBuffer, delta);\n\t\n\t\t\t\t\t\tcontext.stencilFunc(context.EQUAL, 1, 0xffffffff);\n\t\t\t\t\t}\n\t\n\t\t\t\t\tthis.swapBuffers();\n\t\t\t\t}\n\t\n\t\t\t\tif (pass instanceof _MaskPass2['default']) {\n\t\n\t\t\t\t\tmaskActive = true;\n\t\t\t\t} else if (pass instanceof _MaskPass.ClearMaskPass) {\n\t\n\t\t\t\t\tmaskActive = false;\n\t\t\t\t}\n\t\t\t}\n\t\t},\n\t\n\t\treset: function reset(renderTarget) {\n\t\n\t\t\tif (renderTarget === undefined) {\n\t\n\t\t\t\trenderTarget = this.renderTarget1.clone();\n\t\n\t\t\t\tvar pixelRatio = this.renderer.getPixelRatio();\n\t\n\t\t\t\trenderTarget.setSize(Math.floor(this.renderer.context.canvas.width / pixelRatio), Math.floor(this.renderer.context.canvas.height / pixelRatio));\n\t\t\t}\n\t\n\t\t\tthis.renderTarget1.dispose();\n\t\t\tthis.renderTarget1 = renderTarget;\n\t\t\tthis.renderTarget2.dispose();\n\t\t\tthis.renderTarget2 = renderTarget.clone();\n\t\n\t\t\tthis.writeBuffer = this.renderTarget1;\n\t\t\tthis.readBuffer = this.renderTarget2;\n\t\t},\n\t\n\t\tsetSize: function setSize(width, height) {\n\t\n\t\t\tthis.renderTarget1.setSize(width, height);\n\t\t\tthis.renderTarget2.setSize(width, height);\n\t\t}\n\t\n\t};\n\t\n\texports['default'] = EffectComposer;\n\t\n\t_three2['default'].EffectComposer = EffectComposer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 26 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Full-screen textured quad shader\n\t */\n\t\n\tvar CopyShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"opacity\": { type: \"f\", value: 1.0 }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"varying vec2 vUv;\", \"void main() {\", \"vUv = uv;\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform float opacity;\", \"uniform sampler2D tDiffuse;\", \"varying vec2 vUv;\", \"void main() {\", \"vec4 texel = texture2D( tDiffuse, vUv );\", \"gl_FragColor = opacity * texel;\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = CopyShader;\n\t\n\t_three2[\"default\"].CopyShader = CopyShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 27 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar ShaderPass = function ShaderPass(shader, textureID) {\n\t\n\t\tthis.textureID = textureID !== undefined ? textureID : \"tDiffuse\";\n\t\n\t\tif (shader instanceof _three2[\"default\"].ShaderMaterial) {\n\t\n\t\t\tthis.uniforms = shader.uniforms;\n\t\n\t\t\tthis.material = shader;\n\t\t} else if (shader) {\n\t\n\t\t\tthis.uniforms = _three2[\"default\"].UniformsUtils.clone(shader.uniforms);\n\t\n\t\t\tthis.material = new _three2[\"default\"].ShaderMaterial({\n\t\n\t\t\t\tdefines: shader.defines || {},\n\t\t\t\tuniforms: this.uniforms,\n\t\t\t\tvertexShader: shader.vertexShader,\n\t\t\t\tfragmentShader: shader.fragmentShader\n\t\n\t\t\t});\n\t\t}\n\t\n\t\tthis.renderToScreen = false;\n\t\n\t\tthis.enabled = true;\n\t\tthis.needsSwap = true;\n\t\tthis.clear = false;\n\t\n\t\tthis.camera = new _three2[\"default\"].OrthographicCamera(-1, 1, 1, -1, 0, 1);\n\t\tthis.scene = new _three2[\"default\"].Scene();\n\t\n\t\tthis.quad = new _three2[\"default\"].Mesh(new _three2[\"default\"].PlaneBufferGeometry(2, 2), null);\n\t\tthis.scene.add(this.quad);\n\t};\n\t\n\tShaderPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tif (this.uniforms[this.textureID]) {\n\t\n\t\t\t\tthis.uniforms[this.textureID].value = readBuffer;\n\t\t\t}\n\t\n\t\t\tthis.quad.material = this.material;\n\t\n\t\t\tif (this.renderToScreen) {\n\t\n\t\t\t\trenderer.render(this.scene, this.camera);\n\t\t\t} else {\n\t\n\t\t\t\trenderer.render(this.scene, this.camera, writeBuffer, this.clear);\n\t\t\t}\n\t\t}\n\t\n\t};\n\t\n\texports[\"default\"] = ShaderPass;\n\t\n\t_three2[\"default\"].ShaderPass = ShaderPass;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 28 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar MaskPass = function MaskPass(scene, camera) {\n\t\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\t\n\t\tthis.enabled = true;\n\t\tthis.clear = true;\n\t\tthis.needsSwap = false;\n\t\n\t\tthis.inverse = false;\n\t};\n\t\n\tMaskPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tvar context = renderer.context;\n\t\n\t\t\t// don't update color or depth\n\t\n\t\t\tcontext.colorMask(false, false, false, false);\n\t\t\tcontext.depthMask(false);\n\t\n\t\t\t// set up stencil\n\t\n\t\t\tvar writeValue, clearValue;\n\t\n\t\t\tif (this.inverse) {\n\t\n\t\t\t\twriteValue = 0;\n\t\t\t\tclearValue = 1;\n\t\t\t} else {\n\t\n\t\t\t\twriteValue = 1;\n\t\t\t\tclearValue = 0;\n\t\t\t}\n\t\n\t\t\tcontext.enable(context.STENCIL_TEST);\n\t\t\tcontext.stencilOp(context.REPLACE, context.REPLACE, context.REPLACE);\n\t\t\tcontext.stencilFunc(context.ALWAYS, writeValue, 0xffffffff);\n\t\t\tcontext.clearStencil(clearValue);\n\t\n\t\t\t// draw into the stencil buffer\n\t\n\t\t\trenderer.render(this.scene, this.camera, readBuffer, this.clear);\n\t\t\trenderer.render(this.scene, this.camera, writeBuffer, this.clear);\n\t\n\t\t\t// re-enable update of color and depth\n\t\n\t\t\tcontext.colorMask(true, true, true, true);\n\t\t\tcontext.depthMask(true);\n\t\n\t\t\t// only render where stencil is set to 1\n\t\n\t\t\tcontext.stencilFunc(context.EQUAL, 1, 0xffffffff); // draw if == 1\n\t\t\tcontext.stencilOp(context.KEEP, context.KEEP, context.KEEP);\n\t\t}\n\t\n\t};\n\t\n\tvar ClearMaskPass = function ClearMaskPass() {\n\t\n\t\tthis.enabled = true;\n\t};\n\t\n\tClearMaskPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tvar context = renderer.context;\n\t\n\t\t\tcontext.disable(context.STENCIL_TEST);\n\t\t}\n\t\n\t};\n\t\n\texports['default'] = MaskPass;\n\texports.ClearMaskPass = ClearMaskPass;\n\t\n\t_three2['default'].MaskPass = MaskPass;\n\t_three2['default'].ClearMaskPass = ClearMaskPass;\n\n/***/ },\n/* 29 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t */\n\t\n\tvar RenderPass = function RenderPass(scene, camera, overrideMaterial, clearColor, clearAlpha) {\n\t\n\t\tthis.scene = scene;\n\t\tthis.camera = camera;\n\t\n\t\tthis.overrideMaterial = overrideMaterial;\n\t\n\t\tthis.clearColor = clearColor;\n\t\tthis.clearAlpha = clearAlpha !== undefined ? clearAlpha : 1;\n\t\n\t\tthis.oldClearColor = new _three2['default'].Color();\n\t\tthis.oldClearAlpha = 1;\n\t\n\t\tthis.enabled = true;\n\t\tthis.clear = true;\n\t\tthis.needsSwap = false;\n\t};\n\t\n\tRenderPass.prototype = {\n\t\n\t\trender: function render(renderer, writeBuffer, readBuffer, delta) {\n\t\n\t\t\tthis.scene.overrideMaterial = this.overrideMaterial;\n\t\n\t\t\tif (this.clearColor) {\n\t\n\t\t\t\tthis.oldClearColor.copy(renderer.getClearColor());\n\t\t\t\tthis.oldClearAlpha = renderer.getClearAlpha();\n\t\n\t\t\t\trenderer.setClearColor(this.clearColor, this.clearAlpha);\n\t\t\t}\n\t\n\t\t\trenderer.render(this.scene, this.camera, readBuffer, this.clear);\n\t\n\t\t\tif (this.clearColor) {\n\t\n\t\t\t\trenderer.setClearColor(this.oldClearColor, this.oldClearAlpha);\n\t\t\t}\n\t\n\t\t\tthis.scene.overrideMaterial = null;\n\t\t}\n\t\n\t};\n\t\n\texports['default'] = RenderPass;\n\t\n\t_three2['default'].RenderPass = RenderPass;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 30 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n\t *\n\t * - 9 samples per pass\n\t * - standard deviation 2.7\n\t * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n\t * - \"r\" parameter control where \"focused\" horizontal line lies\n\t */\n\t\n\tvar HorizontalTiltShiftShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"h\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\t\"r\": { type: \"f\", value: 0.35 }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"varying vec2 vUv;\", \"void main() {\", \"vUv = uv;\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform sampler2D tDiffuse;\", \"uniform float h;\", \"uniform float r;\", \"varying vec2 vUv;\", \"void main() {\", \"vec4 sum = vec4( 0.0 );\", \"float hh = h * abs( r - vUv.y );\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;\", \"gl_FragColor = sum;\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = HorizontalTiltShiftShader;\n\t\n\t_three2[\"default\"].HorizontalTiltShiftShader = HorizontalTiltShiftShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 31 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t *\n\t * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n\t *\n\t * - 9 samples per pass\n\t * - standard deviation 2.7\n\t * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n\t * - \"r\" parameter control where \"focused\" horizontal line lies\n\t */\n\t\n\tvar VerticalTiltShiftShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"v\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\t\"r\": { type: \"f\", value: 0.35 }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"varying vec2 vUv;\", \"void main() {\", \"vUv = uv;\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform sampler2D tDiffuse;\", \"uniform float v;\", \"uniform float r;\", \"varying vec2 vUv;\", \"void main() {\", \"vec4 sum = vec4( 0.0 );\", \"float vv = v * abs( r - vUv.y );\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;\", \"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;\", \"gl_FragColor = sum;\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = VerticalTiltShiftShader;\n\t\n\t_three2[\"default\"].VerticalTiltShiftShader = VerticalTiltShiftShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 32 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { \"default\": obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author davidedc / http://www.sketchpatch.net/\n\t *\n\t * NVIDIA FXAA by Timothy Lottes\n\t * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html\n\t * - WebGL port by @supereggbert\n\t * http://www.glge.org/demos/fxaa/\n\t */\n\t\n\tvar FXAAShader = {\n\t\n\t\tuniforms: {\n\t\n\t\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\t\"resolution\": { type: \"v2\", value: new _three2[\"default\"].Vector2(1 / 1024, 1 / 512) }\n\t\n\t\t},\n\t\n\t\tvertexShader: [\"void main() {\", \"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\", \"}\"].join(\"\\n\"),\n\t\n\t\tfragmentShader: [\"uniform sampler2D tDiffuse;\", \"uniform vec2 resolution;\", \"#define FXAA_REDUCE_MIN (1.0/128.0)\", \"#define FXAA_REDUCE_MUL (1.0/8.0)\", \"#define FXAA_SPAN_MAX 8.0\", \"void main() {\", \"vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;\", \"vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;\", \"vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;\", \"vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;\", \"vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );\", \"vec3 rgbM = rgbaM.xyz;\", \"vec3 luma = vec3( 0.299, 0.587, 0.114 );\", \"float lumaNW = dot( rgbNW, luma );\", \"float lumaNE = dot( rgbNE, luma );\", \"float lumaSW = dot( rgbSW, luma );\", \"float lumaSE = dot( rgbSE, luma );\", \"float lumaM = dot( rgbM, luma );\", \"float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\", \"float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\", \"vec2 dir;\", \"dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\", \"dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\", \"float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\", \"float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\", \"dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\", \"max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\", \"dir * rcpDirMin)) * resolution;\", \"vec4 rgbA = (1.0/2.0) * (\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));\", \"vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +\", \"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));\", \"float lumaB = dot(rgbB, vec4(luma, 0.0));\", \"if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {\", \"gl_FragColor = rgbA;\", \"} else {\", \"gl_FragColor = rgbB;\", \"}\", \"}\"].join(\"\\n\")\n\t\n\t};\n\t\n\texports[\"default\"] = FXAAShader;\n\t\n\t_three2[\"default\"].FXAAShader = FXAAShader;\n\tmodule.exports = exports[\"default\"];\n\n/***/ },\n/* 33 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Skybox = __webpack_require__(44);\n\t\n\tvar _Skybox2 = _interopRequireDefault(_Skybox);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\tvar EnvironmentLayer = (function (_Layer) {\n\t _inherits(EnvironmentLayer, _Layer);\n\t\n\t function EnvironmentLayer(options) {\n\t _classCallCheck(this, EnvironmentLayer);\n\t\n\t var defaults = {\n\t skybox: false\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'constructor', this).call(this, _options);\n\t }\n\t\n\t _createClass(EnvironmentLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd() {\n\t this._initLights();\n\t\n\t if (this._options.skybox) {\n\t this._initSkybox();\n\t }\n\t\n\t // this._initGrid();\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Not fleshed out or thought through yet\n\t //\n\t // Lights could potentially be put it their own 'layer' to keep this class\n\t // much simpler and less messy\n\t }, {\n\t key: '_initLights',\n\t value: function _initLights() {\n\t // Position doesn't really matter (the angle is important), however it's\n\t // used here so the helpers look more natural.\n\t\n\t if (!this._options.skybox) {\n\t var directionalLight = new _three2['default'].DirectionalLight(0xffffff, 1);\n\t directionalLight.position.x = 10000;\n\t directionalLight.position.y = 10000;\n\t directionalLight.position.z = 10000;\n\t\n\t // TODO: Get shadows working in non-PBR scenes\n\t\n\t // directionalLight.castShadow = true;\n\t //\n\t // var d = 100;\n\t // directionalLight.shadow.camera.left = -d;\n\t // directionalLight.shadow.camera.right = d;\n\t // directionalLight.shadow.camera.top = d;\n\t // directionalLight.shadow.camera.bottom = -d;\n\t //\n\t // directionalLight.shadow.camera.near = 10;\n\t // directionalLight.shadow.camera.far = 100;\n\t //\n\t // // TODO: Need to dial in on a good shadowmap size\n\t // directionalLight.shadow.mapSize.width = 2048;\n\t // directionalLight.shadow.mapSize.height = 2048;\n\t //\n\t // // directionalLight.shadowBias = -0.0010;\n\t // // directionalLight.shadow.darkness = 0.15;\n\t\n\t var directionalLight2 = new _three2['default'].DirectionalLight(0xffffff, 0.5);\n\t directionalLight2.position.x = -10000;\n\t directionalLight2.position.y = 10000;\n\t directionalLight2.position.z = 0;\n\t\n\t var directionalLight3 = new _three2['default'].DirectionalLight(0xffffff, 0.5);\n\t directionalLight3.position.x = 10000;\n\t directionalLight3.position.y = 10000;\n\t directionalLight3.position.z = -10000;\n\t\n\t this.add(directionalLight);\n\t this.add(directionalLight2);\n\t this.add(directionalLight3);\n\t\n\t // var helper = new THREE.DirectionalLightHelper(directionalLight, 10);\n\t // var helper2 = new THREE.DirectionalLightHelper(directionalLight2, 10);\n\t // var helper3 = new THREE.DirectionalLightHelper(directionalLight3, 10);\n\t //\n\t // this.add(helper);\n\t // this.add(helper2);\n\t // this.add(helper3);\n\t } else {\n\t // Directional light that will be projected from the sun\n\t this._skyboxLight = new _three2['default'].DirectionalLight(0xffffff, 1);\n\t\n\t this._skyboxLight.castShadow = true;\n\t\n\t var d = 10000;\n\t this._skyboxLight.shadow.camera.left = -d;\n\t this._skyboxLight.shadow.camera.right = d;\n\t this._skyboxLight.shadow.camera.top = d;\n\t this._skyboxLight.shadow.camera.bottom = -d;\n\t\n\t this._skyboxLight.shadow.camera.near = 10000;\n\t this._skyboxLight.shadow.camera.far = 70000;\n\t\n\t // TODO: Need to dial in on a good shadowmap size\n\t this._skyboxLight.shadow.mapSize.width = 2048;\n\t this._skyboxLight.shadow.mapSize.height = 2048;\n\t\n\t // this._skyboxLight.shadowBias = -0.0010;\n\t // this._skyboxLight.shadow.darkness = 0.15;\n\t\n\t // this._object3D.add(new THREE.CameraHelper(this._skyboxLight.shadow.camera));\n\t\n\t this.add(this._skyboxLight);\n\t }\n\t }\n\t }, {\n\t key: '_initSkybox',\n\t value: function _initSkybox() {\n\t this._skybox = new _Skybox2['default'](this._world, this._skyboxLight);\n\t this.add(this._skybox._mesh);\n\t }\n\t\n\t // Add grid helper for context during initial development\n\t }, {\n\t key: '_initGrid',\n\t value: function _initGrid() {\n\t var size = 4000;\n\t var step = 100;\n\t\n\t var gridHelper = new _three2['default'].GridHelper(size, step);\n\t this.add(gridHelper);\n\t }\n\t\n\t // Clean up environment\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._skyboxLight = null;\n\t\n\t this.remove(this._skybox._mesh);\n\t this._skybox.destroy();\n\t this._skybox = null;\n\t\n\t _get(Object.getPrototypeOf(EnvironmentLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return EnvironmentLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = EnvironmentLayer;\n\t\n\tvar noNew = function noNew(options) {\n\t return new EnvironmentLayer(options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.environmentLayer = noNew;\n\n/***/ },\n/* 34 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _shortid = __webpack_require__(35);\n\t\n\tvar _shortid2 = _interopRequireDefault(_shortid);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _engineScene = __webpack_require__(11);\n\t\n\tvar _engineScene2 = _interopRequireDefault(_engineScene);\n\t\n\tvar _vendorCSS3DRenderer = __webpack_require__(16);\n\t\n\tvar _vendorCSS2DRenderer = __webpack_require__(18);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Need a single move method that handles moving all the various object\n\t// layers so that the DOM layers stay in sync with the 3D layer\n\t\n\t// TODO: Double check that objects within the _object3D Object3D parent are frustum\n\t// culled even if the layer position stays at the default (0,0,0) and the child\n\t// objects are positioned much further away\n\t//\n\t// Or does the layer being at (0,0,0) prevent the child objects from being\n\t// culled because the layer parent is effectively always in view even if the\n\t// child is actually out of camera\n\t\n\tvar Layer = (function (_EventEmitter) {\n\t _inherits(Layer, _EventEmitter);\n\t\n\t function Layer(options) {\n\t _classCallCheck(this, Layer);\n\t\n\t _get(Object.getPrototypeOf(Layer.prototype), 'constructor', this).call(this);\n\t\n\t var defaults = {\n\t id: _shortid2['default'].generate(),\n\t output: true,\n\t outputToScene: true\n\t };\n\t\n\t this._options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (this.isOutput()) {\n\t this._object3D = new _three2['default'].Object3D();\n\t\n\t this._dom3D = document.createElement('div');\n\t this._domObject3D = new _vendorCSS3DRenderer.CSS3DObject(this._dom3D);\n\t\n\t this._dom2D = document.createElement('div');\n\t this._domObject2D = new _vendorCSS2DRenderer.CSS2DObject(this._dom2D);\n\t }\n\t }\n\t\n\t // Add THREE object directly to layer\n\t\n\t _createClass(Layer, [{\n\t key: 'add',\n\t value: function add(object) {\n\t this._object3D.add(object);\n\t }\n\t\n\t // Remove THREE object from to layer\n\t }, {\n\t key: 'remove',\n\t value: function remove(object) {\n\t this._object3D.remove(object);\n\t }\n\t }, {\n\t key: 'addDOM3D',\n\t value: function addDOM3D(object) {\n\t this._domObject3D.add(object);\n\t }\n\t }, {\n\t key: 'removeDOM3D',\n\t value: function removeDOM3D(object) {\n\t this._domObject3D.remove(object);\n\t }\n\t }, {\n\t key: 'addDOM2D',\n\t value: function addDOM2D(object) {\n\t this._domObject2D.add(object);\n\t }\n\t }, {\n\t key: 'removeDOM2D',\n\t value: function removeDOM2D(object) {\n\t this._domObject2D.remove(object);\n\t }\n\t\n\t // Add layer to world instance and store world reference\n\t }, {\n\t key: 'addTo',\n\t value: function addTo(world) {\n\t return world.addLayer(this);\n\t }\n\t\n\t // Internal method called by World.addLayer to actually add the layer\n\t }, {\n\t key: '_addToWorld',\n\t value: function _addToWorld(world) {\n\t var _this = this;\n\t\n\t this._world = world;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._onAdd(world).then(function () {\n\t _this.emit('added');\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Must return a promise\n\t }, {\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t return Promise.resolve(this);\n\t }\n\t }, {\n\t key: 'getPickingId',\n\t value: function getPickingId() {\n\t if (this._world._engine._picking) {\n\t return this._world._engine._picking.getNextId();\n\t }\n\t\n\t return false;\n\t }\n\t\n\t // TODO: Tidy this up and don't access so many private properties to work\n\t }, {\n\t key: 'addToPicking',\n\t value: function addToPicking(object) {\n\t if (!this._world._engine._picking) {\n\t return;\n\t }\n\t\n\t this._world._engine._picking.add(object);\n\t }\n\t }, {\n\t key: 'removeFromPicking',\n\t value: function removeFromPicking(object) {\n\t if (!this._world._engine._picking) {\n\t return;\n\t }\n\t\n\t this._world._engine._picking.remove(object);\n\t }\n\t }, {\n\t key: 'isOutput',\n\t value: function isOutput() {\n\t return this._options.output;\n\t }\n\t }, {\n\t key: 'isOutputToScene',\n\t value: function isOutputToScene() {\n\t return this._options.outputToScene;\n\t }\n\t\n\t // TODO: Also hide any attached DOM layers\n\t }, {\n\t key: 'hide',\n\t value: function hide() {\n\t this._object3D.visible = false;\n\t\n\t if (this._pickingMesh) {\n\t this._pickingMesh.visible = false;\n\t }\n\t }\n\t\n\t // TODO: Also show any attached DOM layers\n\t }, {\n\t key: 'show',\n\t value: function show() {\n\t this._object3D.visible = true;\n\t\n\t if (this._pickingMesh) {\n\t this._pickingMesh.visible = true;\n\t }\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._object3D && this._object3D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._object3D.children.length - 1; i >= 0; i--) {\n\t child = this._object3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.remove(child);\n\t\n\t if (child.geometry) {\n\t // Dispose of mesh and materials\n\t child.geometry.dispose();\n\t child.geometry = null;\n\t }\n\t\n\t if (child.material) {\n\t if (child.material.map) {\n\t child.material.map.dispose();\n\t child.material.map = null;\n\t }\n\t\n\t child.material.dispose();\n\t child.material = null;\n\t }\n\t }\n\t }\n\t\n\t if (this._domObject3D && this._domObject3D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._domObject3D.children.length - 1; i >= 0; i--) {\n\t child = this._domObject3D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.removeDOM3D(child);\n\t }\n\t }\n\t\n\t if (this._domObject2D && this._domObject2D.children) {\n\t // Remove everything else in the layer\n\t var child;\n\t for (var i = this._domObject2D.children.length - 1; i >= 0; i--) {\n\t child = this._domObject2D.children[i];\n\t\n\t if (!child) {\n\t continue;\n\t }\n\t\n\t this.removeDOM2D(child);\n\t }\n\t }\n\t\n\t this._domObject3D = null;\n\t this._domObject2D = null;\n\t\n\t this._world = null;\n\t this._object3D = null;\n\t }\n\t }]);\n\t\n\t return Layer;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Layer;\n\t\n\tvar noNew = function noNew(options) {\n\t return new Layer(options);\n\t};\n\t\n\texports.layer = noNew;\n\n/***/ },\n/* 35 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\tmodule.exports = __webpack_require__(36);\n\n\n/***/ },\n/* 36 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar alphabet = __webpack_require__(37);\n\tvar encode = __webpack_require__(39);\n\tvar decode = __webpack_require__(41);\n\tvar isValid = __webpack_require__(42);\n\t\n\t// Ignore all milliseconds before a certain time to reduce the size of the date entropy without sacrificing uniqueness.\n\t// This number should be updated every year or so to keep the generated id short.\n\t// To regenerate `new Date() - 0` and bump the version. Always bump the version!\n\tvar REDUCE_TIME = 1459707606518;\n\t\n\t// don't change unless we change the algos or REDUCE_TIME\n\t// must be an integer and less than 16\n\tvar version = 6;\n\t\n\t// if you are using cluster or multiple servers use this to make each instance\n\t// has a unique value for worker\n\t// Note: I don't know if this is automatically set when using third\n\t// party cluster solutions such as pm2.\n\tvar clusterWorkerId = __webpack_require__(43) || 0;\n\t\n\t// Counter is used when shortid is called multiple times in one second.\n\tvar counter;\n\t\n\t// Remember the last time shortid was called in case counter is needed.\n\tvar previousSeconds;\n\t\n\t/**\n\t * Generate unique id\n\t * Returns string id\n\t */\n\tfunction generate() {\n\t\n\t var str = '';\n\t\n\t var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);\n\t\n\t if (seconds === previousSeconds) {\n\t counter++;\n\t } else {\n\t counter = 0;\n\t previousSeconds = seconds;\n\t }\n\t\n\t str = str + encode(alphabet.lookup, version);\n\t str = str + encode(alphabet.lookup, clusterWorkerId);\n\t if (counter > 0) {\n\t str = str + encode(alphabet.lookup, counter);\n\t }\n\t str = str + encode(alphabet.lookup, seconds);\n\t\n\t return str;\n\t}\n\t\n\t\n\t/**\n\t * Set the seed.\n\t * Highly recommended if you don't want people to try to figure out your id schema.\n\t * exposed as shortid.seed(int)\n\t * @param seed Integer value to seed the random alphabet. ALWAYS USE THE SAME SEED or you might get overlaps.\n\t */\n\tfunction seed(seedValue) {\n\t alphabet.seed(seedValue);\n\t return module.exports;\n\t}\n\t\n\t/**\n\t * Set the cluster worker or machine id\n\t * exposed as shortid.worker(int)\n\t * @param workerId worker must be positive integer. Number less than 16 is recommended.\n\t * returns shortid module so it can be chained.\n\t */\n\tfunction worker(workerId) {\n\t clusterWorkerId = workerId;\n\t return module.exports;\n\t}\n\t\n\t/**\n\t *\n\t * sets new characters to use in the alphabet\n\t * returns the shuffled alphabet\n\t */\n\tfunction characters(newCharacters) {\n\t if (newCharacters !== undefined) {\n\t alphabet.characters(newCharacters);\n\t }\n\t\n\t return alphabet.shuffled();\n\t}\n\t\n\t\n\t// Export all other functions as properties of the generate function\n\tmodule.exports = generate;\n\tmodule.exports.generate = generate;\n\tmodule.exports.seed = seed;\n\tmodule.exports.worker = worker;\n\tmodule.exports.characters = characters;\n\tmodule.exports.decode = decode;\n\tmodule.exports.isValid = isValid;\n\n\n/***/ },\n/* 37 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar randomFromSeed = __webpack_require__(38);\n\t\n\tvar ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';\n\tvar alphabet;\n\tvar previousSeed;\n\t\n\tvar shuffled;\n\t\n\tfunction reset() {\n\t shuffled = false;\n\t}\n\t\n\tfunction setCharacters(_alphabet_) {\n\t if (!_alphabet_) {\n\t if (alphabet !== ORIGINAL) {\n\t alphabet = ORIGINAL;\n\t reset();\n\t }\n\t return;\n\t }\n\t\n\t if (_alphabet_ === alphabet) {\n\t return;\n\t }\n\t\n\t if (_alphabet_.length !== ORIGINAL.length) {\n\t throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_);\n\t }\n\t\n\t var unique = _alphabet_.split('').filter(function(item, ind, arr){\n\t return ind !== arr.lastIndexOf(item);\n\t });\n\t\n\t if (unique.length) {\n\t throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', '));\n\t }\n\t\n\t alphabet = _alphabet_;\n\t reset();\n\t}\n\t\n\tfunction characters(_alphabet_) {\n\t setCharacters(_alphabet_);\n\t return alphabet;\n\t}\n\t\n\tfunction setSeed(seed) {\n\t randomFromSeed.seed(seed);\n\t if (previousSeed !== seed) {\n\t reset();\n\t previousSeed = seed;\n\t }\n\t}\n\t\n\tfunction shuffle() {\n\t if (!alphabet) {\n\t setCharacters(ORIGINAL);\n\t }\n\t\n\t var sourceArray = alphabet.split('');\n\t var targetArray = [];\n\t var r = randomFromSeed.nextValue();\n\t var characterIndex;\n\t\n\t while (sourceArray.length > 0) {\n\t r = randomFromSeed.nextValue();\n\t characterIndex = Math.floor(r * sourceArray.length);\n\t targetArray.push(sourceArray.splice(characterIndex, 1)[0]);\n\t }\n\t return targetArray.join('');\n\t}\n\t\n\tfunction getShuffled() {\n\t if (shuffled) {\n\t return shuffled;\n\t }\n\t shuffled = shuffle();\n\t return shuffled;\n\t}\n\t\n\t/**\n\t * lookup shuffled letter\n\t * @param index\n\t * @returns {string}\n\t */\n\tfunction lookup(index) {\n\t var alphabetShuffled = getShuffled();\n\t return alphabetShuffled[index];\n\t}\n\t\n\tmodule.exports = {\n\t characters: characters,\n\t seed: setSeed,\n\t lookup: lookup,\n\t shuffled: getShuffled\n\t};\n\n\n/***/ },\n/* 38 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\t// Found this seed-based random generator somewhere\n\t// Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu)\n\t\n\tvar seed = 1;\n\t\n\t/**\n\t * return a random number based on a seed\n\t * @param seed\n\t * @returns {number}\n\t */\n\tfunction getNextValue() {\n\t seed = (seed * 9301 + 49297) % 233280;\n\t return seed/(233280.0);\n\t}\n\t\n\tfunction setSeed(_seed_) {\n\t seed = _seed_;\n\t}\n\t\n\tmodule.exports = {\n\t nextValue: getNextValue,\n\t seed: setSeed\n\t};\n\n\n/***/ },\n/* 39 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\t\n\tvar randomByte = __webpack_require__(40);\n\t\n\tfunction encode(lookup, number) {\n\t var loopCounter = 0;\n\t var done;\n\t\n\t var str = '';\n\t\n\t while (!done) {\n\t str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );\n\t done = number < (Math.pow(16, loopCounter + 1 ) );\n\t loopCounter++;\n\t }\n\t return str;\n\t}\n\t\n\tmodule.exports = encode;\n\n\n/***/ },\n/* 40 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tvar crypto = typeof window === 'object' && (window.crypto || window.msCrypto); // IE 11 uses window.msCrypto\n\t\n\tfunction randomByte() {\n\t if (!crypto || !crypto.getRandomValues) {\n\t return Math.floor(Math.random() * 256) & 0x30;\n\t }\n\t var dest = new Uint8Array(1);\n\t crypto.getRandomValues(dest);\n\t return dest[0] & 0x30;\n\t}\n\t\n\tmodule.exports = randomByte;\n\n\n/***/ },\n/* 41 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\tvar alphabet = __webpack_require__(37);\n\t\n\t/**\n\t * Decode the id to get the version and worker\n\t * Mainly for debugging and testing.\n\t * @param id - the shortid-generated id.\n\t */\n\tfunction decode(id) {\n\t var characters = alphabet.shuffled();\n\t return {\n\t version: characters.indexOf(id.substr(0, 1)) & 0x0f,\n\t worker: characters.indexOf(id.substr(1, 1)) & 0x0f\n\t };\n\t}\n\t\n\tmodule.exports = decode;\n\n\n/***/ },\n/* 42 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t'use strict';\n\tvar alphabet = __webpack_require__(37);\n\t\n\tfunction isShortId(id) {\n\t if (!id || typeof id !== 'string' || id.length < 6 ) {\n\t return false;\n\t }\n\t\n\t var characters = alphabet.characters();\n\t var len = id.length;\n\t for(var i = 0; i < len;i++) {\n\t if (characters.indexOf(id[i]) === -1) {\n\t return false;\n\t }\n\t }\n\t return true;\n\t}\n\t\n\tmodule.exports = isShortId;\n\n\n/***/ },\n/* 43 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = 0;\n\n\n/***/ },\n/* 44 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _Sky = __webpack_require__(45);\n\t\n\tvar _Sky2 = _interopRequireDefault(_Sky);\n\t\n\tvar _lodashThrottle = __webpack_require__(22);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\tvar cubemap = {\n\t vertexShader: ['varying vec3 vPosition;', 'void main() {', 'vPosition = position;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t fragmentShader: ['uniform samplerCube cubemap;', 'varying vec3 vPosition;', 'void main() {', 'gl_FragColor = textureCube(cubemap, normalize(vPosition));', '}'].join('\\n')\n\t};\n\t\n\tvar Skybox = (function () {\n\t function Skybox(world, light) {\n\t _classCallCheck(this, Skybox);\n\t\n\t this._world = world;\n\t this._light = light;\n\t\n\t this._settings = {\n\t distance: 38000,\n\t turbidity: 10,\n\t reileigh: 2,\n\t mieCoefficient: 0.005,\n\t mieDirectionalG: 0.8,\n\t luminance: 1,\n\t // 0.48 is a cracking dusk / sunset\n\t // 0.4 is a beautiful early-morning / late-afternoon\n\t // 0.2 is a nice day time\n\t inclination: 0.48, // Elevation / inclination\n\t azimuth: 0.25 };\n\t\n\t // Facing front\n\t this._initSkybox();\n\t this._updateUniforms();\n\t this._initEvents();\n\t }\n\t\n\t _createClass(Skybox, [{\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t // Throttled to 1 per 100ms\n\t this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._update, 100);\n\t this._world.on('preUpdate', this._throttledWorldUpdate, this);\n\t }\n\t }, {\n\t key: '_initSkybox',\n\t value: function _initSkybox() {\n\t // Cube camera for skybox\n\t this._cubeCamera = new _three2['default'].CubeCamera(1, 20000000, 128);\n\t\n\t // Cube material\n\t var cubeTarget = this._cubeCamera.renderTarget;\n\t\n\t // Add Sky Mesh\n\t this._sky = new _Sky2['default']();\n\t this._skyScene = new _three2['default'].Scene();\n\t this._skyScene.add(this._sky.mesh);\n\t\n\t // Add Sun Helper\n\t this._sunSphere = new _three2['default'].Mesh(new _three2['default'].SphereBufferGeometry(2000, 16, 8), new _three2['default'].MeshBasicMaterial({\n\t color: 0xffffff\n\t }));\n\t\n\t // TODO: This isn't actually visible because it's not added to the layer\n\t // this._sunSphere.visible = true;\n\t\n\t var skyboxUniforms = {\n\t cubemap: { type: 't', value: cubeTarget }\n\t };\n\t\n\t var skyboxMat = new _three2['default'].ShaderMaterial({\n\t uniforms: skyboxUniforms,\n\t vertexShader: cubemap.vertexShader,\n\t fragmentShader: cubemap.fragmentShader,\n\t side: _three2['default'].BackSide\n\t });\n\t\n\t this._mesh = new _three2['default'].Mesh(new _three2['default'].BoxGeometry(1900000, 1900000, 1900000), skyboxMat);\n\t\n\t this._updateSkybox = true;\n\t }\n\t }, {\n\t key: '_updateUniforms',\n\t value: function _updateUniforms() {\n\t var settings = this._settings;\n\t var uniforms = this._sky.uniforms;\n\t uniforms.turbidity.value = settings.turbidity;\n\t uniforms.reileigh.value = settings.reileigh;\n\t uniforms.luminance.value = settings.luminance;\n\t uniforms.mieCoefficient.value = settings.mieCoefficient;\n\t uniforms.mieDirectionalG.value = settings.mieDirectionalG;\n\t\n\t var theta = Math.PI * (settings.inclination - 0.5);\n\t var phi = 2 * Math.PI * (settings.azimuth - 0.5);\n\t\n\t this._sunSphere.position.x = settings.distance * Math.cos(phi);\n\t this._sunSphere.position.y = settings.distance * Math.sin(phi) * Math.sin(theta);\n\t this._sunSphere.position.z = settings.distance * Math.sin(phi) * Math.cos(theta);\n\t\n\t // Move directional light to sun position\n\t this._light.position.copy(this._sunSphere.position);\n\t\n\t this._sky.uniforms.sunPosition.value.copy(this._sunSphere.position);\n\t }\n\t }, {\n\t key: '_update',\n\t value: function _update(delta) {\n\t if (this._updateSkybox) {\n\t this._updateSkybox = false;\n\t } else {\n\t return;\n\t }\n\t\n\t // if (!this._angle) {\n\t // this._angle = 0;\n\t // }\n\t //\n\t // // Animate inclination\n\t // this._angle += Math.PI * delta;\n\t // this._settings.inclination = 0.5 * (Math.sin(this._angle) / 2 + 0.5);\n\t\n\t // Update light intensity depending on elevation of sun (day to night)\n\t this._light.intensity = 1 - 0.95 * (this._settings.inclination / 0.5);\n\t\n\t // // console.log(delta, this._angle, this._settings.inclination);\n\t //\n\t // TODO: Only do this when the uniforms have been changed\n\t this._updateUniforms();\n\t\n\t // TODO: Only do this when the cubemap has actually changed\n\t this._cubeCamera.updateCubeMap(this._world._engine._renderer, this._skyScene);\n\t }\n\t }, {\n\t key: 'getRenderTarget',\n\t value: function getRenderTarget() {\n\t return this._cubeCamera.renderTarget;\n\t }\n\t }, {\n\t key: 'setInclination',\n\t value: function setInclination(inclination) {\n\t this._settings.inclination = inclination;\n\t this._updateSkybox = true;\n\t }\n\t\n\t // Destroy the skybox and remove it from memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._world.off('preUpdate', this._throttledWorldUpdate);\n\t this._throttledWorldUpdate = null;\n\t\n\t this._world = null;\n\t this._light = null;\n\t\n\t this._cubeCamera = null;\n\t\n\t this._sky.mesh.geometry.dispose();\n\t this._sky.mesh.geometry = null;\n\t\n\t if (this._sky.mesh.material.map) {\n\t this._sky.mesh.material.map.dispose();\n\t this._sky.mesh.material.map = null;\n\t }\n\t\n\t this._sky.mesh.material.dispose();\n\t this._sky.mesh.material = null;\n\t\n\t this._sky.mesh = null;\n\t this._sky = null;\n\t\n\t this._skyScene = null;\n\t\n\t this._sunSphere.geometry.dispose();\n\t this._sunSphere.geometry = null;\n\t\n\t if (this._sunSphere.material.map) {\n\t this._sunSphere.material.map.dispose();\n\t this._sunSphere.material.map = null;\n\t }\n\t\n\t this._sunSphere.material.dispose();\n\t this._sunSphere.material = null;\n\t\n\t this._sunSphere = null;\n\t\n\t this._mesh.geometry.dispose();\n\t this._mesh.geometry = null;\n\t\n\t if (this._mesh.material.map) {\n\t this._mesh.material.map.dispose();\n\t this._mesh.material.map = null;\n\t }\n\t\n\t this._mesh.material.dispose();\n\t this._mesh.material = null;\n\t }\n\t }]);\n\t\n\t return Skybox;\n\t})();\n\t\n\texports['default'] = Skybox;\n\t\n\tvar noNew = function noNew(world, light) {\n\t return new Skybox(world, light);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.skybox = noNew;\n\n/***/ },\n/* 45 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/*eslint eqeqeq:0*/\n\t\n\t/**\n\t * @author zz85 / https://github.com/zz85\n\t *\n\t * Based on 'A Practical Analytic Model for Daylight'\n\t * aka The Preetham Model, the de facto standard analytic skydome model\n\t * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf\n\t *\n\t * First implemented by Simon Wallner\n\t * http://www.simonwallner.at/projects/atmospheric-scattering\n\t *\n\t * Improved by Martin Upitis\n\t * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR\n\t *\n\t * Three.js integration by zz85 http://twitter.com/blurspline\n\t*/\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t_three2['default'].ShaderLib['sky'] = {\n\t\n\t\tuniforms: {\n\t\n\t\t\tluminance: { type: 'f', value: 1 },\n\t\t\tturbidity: { type: 'f', value: 2 },\n\t\t\treileigh: { type: 'f', value: 1 },\n\t\t\tmieCoefficient: { type: 'f', value: 0.005 },\n\t\t\tmieDirectionalG: { type: 'f', value: 0.8 },\n\t\t\tsunPosition: { type: 'v3', value: new _three2['default'].Vector3() }\n\t\n\t\t},\n\t\n\t\tvertexShader: ['varying vec3 vWorldPosition;', 'void main() {', 'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );', 'vWorldPosition = worldPosition.xyz;', 'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t\tfragmentShader: ['uniform sampler2D skySampler;', 'uniform vec3 sunPosition;', 'varying vec3 vWorldPosition;', 'vec3 cameraPos = vec3(0., 0., 0.);', '// uniform sampler2D sDiffuse;', '// const float turbidity = 10.0; //', '// const float reileigh = 2.; //', '// const float luminance = 1.0; //', '// const float mieCoefficient = 0.005;', '// const float mieDirectionalG = 0.8;', 'uniform float luminance;', 'uniform float turbidity;', 'uniform float reileigh;', 'uniform float mieCoefficient;', 'uniform float mieDirectionalG;', '// constants for atmospheric scattering', 'const float e = 2.71828182845904523536028747135266249775724709369995957;', 'const float pi = 3.141592653589793238462643383279502884197169;', 'const float n = 1.0003; // refractive index of air', 'const float N = 2.545E25; // number of molecules per unit volume for air at', '// 288.15K and 1013mb (sea level -45 celsius)', 'const float pn = 0.035;\t// depolatization factor for standard air', '// wavelength of used primaries, according to preetham', 'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);', '// mie stuff', '// K coefficient for the primaries', 'const vec3 K = vec3(0.686, 0.678, 0.666);', 'const float v = 4.0;', '// optical length at zenith for molecules', 'const float rayleighZenithLength = 8.4E3;', 'const float mieZenithLength = 1.25E3;', 'const vec3 up = vec3(0.0, 1.0, 0.0);', 'const float EE = 1000.0;', 'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;', '// 66 arc seconds -> degrees, and the cosine of that', '// earth shadow hack', 'const float cutoffAngle = pi/1.95;', 'const float steepness = 1.5;', 'vec3 totalRayleigh(vec3 lambda)', '{', 'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));', '}',\n\t\n\t\t// see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness\n\t\t'// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE', 'vec3 simplifiedRayleigh()', '{', 'return 0.0005 / vec3(94, 40, 18);',\n\t\t// return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245);\n\t\t'}', 'float rayleighPhase(float cosTheta)', '{\t ', 'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '//\treturn (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));', '//\treturn (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));', '}', 'vec3 totalMie(vec3 lambda, vec3 K, float T)', '{', 'float c = (0.2 * T ) * 10E-18;', 'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;', '}', 'float hgPhase(float cosTheta, float g)', '{', 'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));', '}', 'float sunIntensity(float zenithAngleCos)', '{', 'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));', '}', '// float logLuminance(vec3 c)', '// {', '// \treturn log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);', '// }', '// Filmic ToneMapping http://filmicgames.com/archives/75', 'float A = 0.15;', 'float B = 0.50;', 'float C = 0.10;', 'float D = 0.20;', 'float E = 0.02;', 'float F = 0.30;', 'float W = 1000.0;', 'vec3 Uncharted2Tonemap(vec3 x)', '{', 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;', '}', 'void main() ', '{', 'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);', '// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;', '// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);', 'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));', 'vec3 sunDirection = normalize(sunPosition);', 'float sunE = sunIntensity(dot(sunDirection, up));', '// extinction (absorbtion + out scattering) ', '// rayleigh coefficients',\n\t\n\t\t// 'vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;',\n\t\t'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;', '// mie coefficients', 'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;', '// optical length', '// cutoff angle at 90 to avoid singularity in next formula.', 'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));', 'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', 'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));', '// combined extinction factor\t', 'vec3 Fex = exp(-(betaR * sR + betaM * sM));', '// in scattering', 'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);', 'float rPhase = rayleighPhase(cosTheta*0.5+0.5);', 'vec3 betaRTheta = betaR * rPhase;', 'float mPhase = hgPhase(cosTheta, mieDirectionalG);', 'vec3 betaMTheta = betaM * mPhase;', 'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));', 'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));', '//nightsky', 'vec3 direction = normalize(vWorldPosition - cameraPos);', 'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]', 'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]', 'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);', '// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;', 'vec3 L0 = vec3(0.1) * Fex;', '// composition + solar disc', '//if (cosTheta > sunAngularDiameterCos)', 'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);', '// if (normalize(vWorldPosition - cameraPos).y>0.0)', 'L0 += (sunE * 19000.0 * Fex)*sundisk;', 'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));', 'vec3 texColor = (Lin+L0); ', 'texColor *= 0.04 ;', 'texColor += vec3(0.0,0.001,0.0025)*0.3;', 'float g_fMaxLuminance = 1.0;', 'float fLumScaled = 0.1 / luminance; ', 'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ', 'float ExposureBias = fLumCompressed;', 'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);', 'vec3 color = curr*whiteScale;', 'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));', 'gl_FragColor.rgb = retColor;', 'gl_FragColor.a = 1.0;', '}'].join('\\n')\n\t\n\t};\n\t\n\tvar Sky = function Sky() {\n\t\n\t\tvar skyShader = _three2['default'].ShaderLib['sky'];\n\t\tvar skyUniforms = _three2['default'].UniformsUtils.clone(skyShader.uniforms);\n\t\n\t\tvar skyMat = new _three2['default'].ShaderMaterial({\n\t\t\tfragmentShader: skyShader.fragmentShader,\n\t\t\tvertexShader: skyShader.vertexShader,\n\t\t\tuniforms: skyUniforms,\n\t\t\tside: _three2['default'].BackSide\n\t\t});\n\t\n\t\tvar skyGeo = new _three2['default'].SphereBufferGeometry(450000, 32, 15);\n\t\tvar skyMesh = new _three2['default'].Mesh(skyGeo, skyMat);\n\t\n\t\t// Expose variables\n\t\tthis.mesh = skyMesh;\n\t\tthis.uniforms = skyUniforms;\n\t};\n\t\n\texports['default'] = Sky;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 46 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _WorkerPool = __webpack_require__(47);\n\t\n\tvar _WorkerPool2 = _interopRequireDefault(_WorkerPool);\n\t\n\tvar Worker = (function () {\n\t var _maxWorkers = 2;\n\t var pool;\n\t\n\t var createWorkers = function createWorkers(maxWorkers, workerScript) {\n\t pool = new _WorkerPool2['default']({\n\t numThreads: maxWorkers ? maxWorkers : _maxWorkers,\n\t workerScript: workerScript ? workerScript : 'vizicities-worker.js'\n\t });\n\t\n\t return pool.createWorkers();\n\t };\n\t\n\t var exec = function exec(method, args, transferrables) {\n\t return pool.exec(method, args, transferrables);\n\t };\n\t\n\t return {\n\t createWorkers: createWorkers,\n\t exec: exec\n\t };\n\t})();\n\t\n\texports['default'] = Worker;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 47 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _WorkerPoolWorker = __webpack_require__(48);\n\t\n\tvar _WorkerPoolWorker2 = _interopRequireDefault(_WorkerPoolWorker);\n\t\n\tvar DEBUG = false;\n\t\n\tvar WorkerPool = (function () {\n\t function WorkerPool(options) {\n\t _classCallCheck(this, WorkerPool);\n\t\n\t this.numThreads = options.numThreads || 2;\n\t this.workerScript = options.workerScript;\n\t\n\t this.workers = [];\n\t this.tasks = [];\n\t }\n\t\n\t _createClass(WorkerPool, [{\n\t key: 'createWorkers',\n\t value: function createWorkers() {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var workerPromises = [];\n\t\n\t for (var i = 0; i < _this.numThreads; i++) {\n\t workerPromises.push(_this.createWorker());\n\t }\n\t\n\t Promise.all(workerPromises).then(function () {\n\t if (DEBUG) {\n\t console.log('All workers ready', performance.now());\n\t }\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'createWorker',\n\t value: function createWorker() {\n\t var _this2 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t // Initialise worker\n\t var worker = new _WorkerPoolWorker2['default']({\n\t workerScript: _this2.workerScript\n\t });\n\t\n\t // Start worker and wait for it to be ready\n\t return worker.start().then(function () {\n\t if (DEBUG) {\n\t console.log('Worker ready', performance.now());\n\t }\n\t\n\t // Add worker to pool\n\t _this2.workers.push(worker);\n\t\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'getFreeWorker',\n\t value: function getFreeWorker() {\n\t return this.workers.find(function (worker) {\n\t return !worker.busy;\n\t });\n\t }\n\t\n\t // Execute task on a worker\n\t }, {\n\t key: 'exec',\n\t value: function exec(method, args, transferrables) {\n\t var deferred = Promise.deferred();\n\t\n\t // Create task\n\t var task = {\n\t method: method,\n\t args: args,\n\t transferrables: transferrables,\n\t deferred: deferred\n\t };\n\t\n\t // Add task to queue\n\t this.tasks.push(task);\n\t\n\t // Trigger task processing\n\t this.processTasks();\n\t\n\t // Return task promise\n\t return task.deferred.promise;\n\t }\n\t }, {\n\t key: 'processTasks',\n\t value: function processTasks() {\n\t var _this3 = this;\n\t\n\t if (DEBUG) {\n\t console.log('Processing tasks');\n\t }\n\t\n\t if (this.tasks.length === 0) {\n\t return;\n\t }\n\t\n\t // Find free worker\n\t var worker = this.getFreeWorker();\n\t\n\t if (!worker) {\n\t if (DEBUG) {\n\t console.log('No workers free');\n\t }\n\t return;\n\t }\n\t\n\t // Get oldest task\n\t var task = this.tasks.shift();\n\t\n\t // Execute task on worker\n\t worker.exec(task.method, task.args, task.transferrables).then(function (result) {\n\t // Trigger task processing\n\t _this3.processTasks();\n\t\n\t // Return result in deferred task promise\n\t task.deferred.resolve(result);\n\t });\n\t }\n\t }]);\n\t\n\t return WorkerPool;\n\t})();\n\t\n\texports['default'] = WorkerPool;\n\t\n\t// Quick shim to create deferred native promises\n\tPromise.deferred = function () {\n\t var result = {};\n\t\n\t result.promise = new Promise(function (resolve, reject) {\n\t result.resolve = resolve;\n\t result.reject = reject;\n\t });\n\t\n\t return result;\n\t};\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 48 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar DEBUG = false;\n\t\n\tvar WorkerPoolWorker = (function () {\n\t function WorkerPoolWorker(options) {\n\t _classCallCheck(this, WorkerPoolWorker);\n\t\n\t this.workerScript = options.workerScript;\n\t\n\t this.ready = false;\n\t this.busy = false;\n\t this.deferred = null;\n\t }\n\t\n\t _createClass(WorkerPoolWorker, [{\n\t key: 'start',\n\t value: function start() {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this.worker = new Worker(_this.workerScript);\n\t\n\t var onStartup = function onStartup(event) {\n\t if (!event.data || event.data.type !== 'startup') {\n\t reject();\n\t return;\n\t }\n\t\n\t _this.ready = true;\n\t\n\t // Remove temporary message handler\n\t _this.worker.removeEventListener('message', onStartup);\n\t\n\t // Set up listener to respond to normal events now\n\t _this.worker.addEventListener('message', function (event) {\n\t _this.onMessage(event);\n\t });\n\t\n\t // Resolve once worker is ready\n\t resolve();\n\t };\n\t\n\t // Set up temporary event listener for warmup\n\t _this.worker.addEventListener('message', onStartup);\n\t });\n\t }\n\t }, {\n\t key: 'exec',\n\t value: function exec(method, args, transferrables) {\n\t if (DEBUG) {\n\t console.log('Execute', method, args, transferrables);\n\t }\n\t\n\t var deferred = Promise.deferred();\n\t\n\t this.busy = true;\n\t this.deferred = deferred;\n\t\n\t this.worker.postMessage({\n\t method: method,\n\t args: args\n\t }, transferrables);\n\t\n\t return deferred.promise;\n\t }\n\t }, {\n\t key: 'onMessage',\n\t value: function onMessage(event) {\n\t console.log('Message received from worker', performance.now());\n\t\n\t this.busy = false;\n\t\n\t if (!event.data || event.data.type === 'error' || event.data.type !== 'result') {\n\t this.deferred.reject(event.data.payload);\n\t return;\n\t }\n\t\n\t this.deferred.resolve(event.data.payload);\n\t }\n\t }]);\n\t\n\t return WorkerPoolWorker;\n\t})();\n\t\n\texports['default'] = WorkerPoolWorker;\n\t\n\t// Quick shim to create deferred native promises\n\tPromise.deferred = function () {\n\t var result = {};\n\t\n\t result.promise = new Promise(function (resolve, reject) {\n\t result.resolve = resolve;\n\t result.reject = reject;\n\t });\n\t\n\t return result;\n\t};\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 49 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _ControlsOrbit = __webpack_require__(50);\n\t\n\tvar _ControlsOrbit2 = _interopRequireDefault(_ControlsOrbit);\n\t\n\tvar Controls = {\n\t Orbit: _ControlsOrbit2['default'],\n\t orbit: _ControlsOrbit.orbit, orbit: _ControlsOrbit.orbit\n\t};\n\t\n\texports['default'] = Controls;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 50 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _eventemitter3 = __webpack_require__(2);\n\t\n\tvar _eventemitter32 = _interopRequireDefault(_eventemitter3);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _vendorOrbitControls = __webpack_require__(51);\n\t\n\tvar _vendorOrbitControls2 = _interopRequireDefault(_vendorOrbitControls);\n\t\n\tvar _TweenLite = __webpack_require__(53);\n\t\n\tvar _TweenLite2 = _interopRequireDefault(_TweenLite);\n\t\n\tvar Orbit = (function (_EventEmitter) {\n\t _inherits(Orbit, _EventEmitter);\n\t\n\t function Orbit() {\n\t _classCallCheck(this, Orbit);\n\t\n\t _get(Object.getPrototypeOf(Orbit.prototype), 'constructor', this).call(this);\n\t\n\t // Prevent animation from pausing when tab is inactive\n\t _TweenLite2['default'].lagSmoothing(0);\n\t }\n\t\n\t // Proxy control events\n\t //\n\t // There's currently no distinction between pan, orbit and zoom events\n\t\n\t _createClass(Orbit, [{\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t var _this = this;\n\t\n\t this._controls.addEventListener('start', function (event) {\n\t _this._world.emit('controlsMoveStart', event.target.target);\n\t });\n\t\n\t this._controls.addEventListener('change', function (event) {\n\t _this._world.emit('controlsMove', event.target.target);\n\t });\n\t\n\t this._controls.addEventListener('end', function (event) {\n\t _this._world.emit('controlsMoveEnd', event.target.target);\n\t });\n\t }\n\t\n\t // Moving the camera along the [x,y,z] axis based on a target position\n\t }, {\n\t key: 'panTo',\n\t value: function panTo(point, animate) {}\n\t }, {\n\t key: 'panBy',\n\t value: function panBy(pointDelta, animate) {}\n\t\n\t // Zooming the camera in and out\n\t }, {\n\t key: 'zoomTo',\n\t value: function zoomTo(metres, animate) {}\n\t }, {\n\t key: 'zoomBy',\n\t value: function zoomBy(metresDelta, animate) {}\n\t\n\t // Force camera to look at something other than the target\n\t }, {\n\t key: 'lookAt',\n\t value: function lookAt(point, animate) {}\n\t\n\t // Make camera look at the target\n\t }, {\n\t key: 'lookAtTarget',\n\t value: function lookAtTarget() {}\n\t\n\t // Tilt (up and down)\n\t }, {\n\t key: 'tiltTo',\n\t value: function tiltTo(angle, animate) {}\n\t }, {\n\t key: 'tiltBy',\n\t value: function tiltBy(angleDelta, animate) {}\n\t\n\t // Rotate (left and right)\n\t }, {\n\t key: 'rotateTo',\n\t value: function rotateTo(angle, animate) {}\n\t }, {\n\t key: 'rotateBy',\n\t value: function rotateBy(angleDelta, animate) {}\n\t\n\t // Fly to the given point, animating pan and tilt/rotation to final position\n\t // with nice zoom out and in\n\t //\n\t // TODO: Calling flyTo a second time before the previous animation has\n\t // completed should immediately start the new animation from wherever the\n\t // previous one has got to\n\t //\n\t // TODO: Long-distance pans should prevent the quadtree grid from trying to\n\t // update by not firing the control update events every frame until the\n\t // pan velocity calms down a bit\n\t //\n\t // TODO: Long-distance plans should zoom out further\n\t //\n\t // TODO: Return a promise?\n\t }, {\n\t key: 'flyToPoint',\n\t value: function flyToPoint(point, duration, zoom) {\n\t // Animation time in seconds\n\t var animationTime = duration || 2;\n\t\n\t this._flyTarget = new _three2['default'].Vector3(point.x, 0, point.y);\n\t\n\t // Calculate delta from current position to fly target\n\t var diff = new _three2['default'].Vector3().subVectors(this._controls.target, this._flyTarget);\n\t\n\t this._flyTween = new _TweenLite2['default']({\n\t x: 0,\n\t z: 0,\n\t // zoom: 0,\n\t prev: {\n\t x: 0,\n\t z: 0\n\t }\n\t }, animationTime, {\n\t x: diff.x,\n\t z: diff.z,\n\t // zoom: 1,\n\t onUpdate: function onUpdate(tween) {\n\t var controls = this._controls;\n\t\n\t // Work out difference since last frame\n\t var deltaX = tween.target.x - tween.target.prev.x;\n\t var deltaZ = tween.target.z - tween.target.prev.z;\n\t\n\t // Move some fraction toward the target point\n\t controls.panLeft(deltaX, controls.object.matrix);\n\t controls.panUp(deltaZ, controls.object.matrix);\n\t\n\t tween.target.prev.x = tween.target.x;\n\t tween.target.prev.z = tween.target.z;\n\t\n\t // console.log(Math.sin((tween.target.zoom - 0.5) * Math.PI));\n\t\n\t // TODO: Get zoom to dolly in and out on pan\n\t // controls.object.zoom -= Math.sin((tween.target.zoom - 0.5) * Math.PI);\n\t // controls.object.updateProjectionMatrix();\n\t },\n\t onComplete: function onComplete(tween) {\n\t // console.log(`Arrived at flyTarget`);\n\t this._flyTarget = null;\n\t },\n\t onUpdateParams: ['{self}'],\n\t onCompleteParams: ['{self}'],\n\t callbackScope: this,\n\t ease: Power1.easeInOut\n\t });\n\t\n\t if (!zoom) {\n\t return;\n\t }\n\t\n\t var zoomTime = animationTime / 2;\n\t\n\t this._zoomTweenIn = new _TweenLite2['default']({\n\t zoom: 0\n\t }, zoomTime, {\n\t zoom: 1,\n\t onUpdate: function onUpdate(tween) {\n\t var controls = this._controls;\n\t controls.dollyIn(1 - 0.01 * tween.target.zoom);\n\t },\n\t onComplete: function onComplete(tween) {},\n\t onUpdateParams: ['{self}'],\n\t onCompleteParams: ['{self}'],\n\t callbackScope: this,\n\t ease: Power1.easeInOut\n\t });\n\t\n\t this._zoomTweenOut = new _TweenLite2['default']({\n\t zoom: 0\n\t }, zoomTime, {\n\t zoom: 1,\n\t delay: zoomTime,\n\t onUpdate: function onUpdate(tween) {\n\t var controls = this._controls;\n\t controls.dollyOut(0.99 + 0.01 * tween.target.zoom);\n\t },\n\t onComplete: function onComplete(tween) {},\n\t onUpdateParams: ['{self}'],\n\t onCompleteParams: ['{self}'],\n\t callbackScope: this,\n\t ease: Power1.easeInOut\n\t });\n\t }\n\t\n\t // TODO: Return a promise?\n\t }, {\n\t key: 'flyToLatLon',\n\t value: function flyToLatLon(latlon, duration, noZoom) {\n\t var point = this._world.latLonToPoint(latlon);\n\t this.flyToPoint(point, duration, noZoom);\n\t }\n\t\n\t // TODO: Make this animate over a user-defined period of time\n\t //\n\t // Perhaps use TweenMax for now and implement as a more lightweight solution\n\t // later on once it all works\n\t // _animateFlyTo(delta) {\n\t // var controls = this._controls;\n\t //\n\t // // this._controls.panLeft(50, controls._controls.object.matrix);\n\t // // this._controls.panUp(50, controls._controls.object.matrix);\n\t // // this._controls.dollyIn(this._controls.getZoomScale());\n\t // // this._controls.dollyOut(this._controls.getZoomScale());\n\t //\n\t // // Calculate delta from current position to fly target\n\t // var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);\n\t //\n\t // // 1000 units per second\n\t // var speed = 1000 * (delta / 1000);\n\t //\n\t // // Remove fly target after arrival and snap to target\n\t // if (diff.length() < 0.01) {\n\t // console.log(`Arrived at flyTarget`);\n\t // this._flyTarget = null;\n\t // speed = 1;\n\t // }\n\t //\n\t // // Move some fraction toward the target point\n\t // controls.panLeft(diff.x * speed, controls.object.matrix);\n\t // controls.panUp(diff.z * speed, controls.object.matrix);\n\t // }\n\t\n\t // Proxy to OrbitControls.update()\n\t }, {\n\t key: 'update',\n\t value: function update(delta) {\n\t this._controls.update(delta);\n\t }\n\t\n\t // Add controls to world instance and store world reference\n\t }, {\n\t key: 'addTo',\n\t value: function addTo(world) {\n\t return world.addControls(this);\n\t }\n\t\n\t // Internal method called by World.addControls to actually add the controls\n\t }, {\n\t key: '_addToWorld',\n\t value: function _addToWorld(world) {\n\t this._world = world;\n\t\n\t // TODO: Override panLeft and panUp methods to prevent panning on Y axis\n\t // See: http://stackoverflow.com/a/26188674/997339\n\t this._controls = new _vendorOrbitControls2['default'](world._engine._camera, world._container);\n\t\n\t // Disable keys for now as no events are fired for them anyway\n\t this._controls.keys = false;\n\t\n\t // 89 degrees\n\t this._controls.maxPolarAngle = 1.5533;\n\t\n\t // this._controls.enableDamping = true;\n\t // this._controls.dampingFactor = 0.25;\n\t\n\t this._initEvents();\n\t\n\t // TODO: Remove now that this is a promise?\n\t this.emit('added');\n\t\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Destroys the controls and removes them from memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // TODO: Remove event listeners\n\t\n\t this._controls.dispose();\n\t\n\t this._world = null;\n\t this._controls = null;\n\t }\n\t }]);\n\t\n\t return Orbit;\n\t})(_eventemitter32['default']);\n\t\n\texports['default'] = Orbit;\n\t\n\tvar noNew = function noNew() {\n\t return new Orbit();\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.orbit = noNew;\n\n/***/ },\n/* 51 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _hammerjs = __webpack_require__(52);\n\t\n\tvar _hammerjs2 = _interopRequireDefault(_hammerjs);\n\t\n\t/**\n\t * @author qiao / https://github.com/qiao\n\t * @author mrdoob / http://mrdoob.com\n\t * @author alteredq / http://alteredqualia.com/\n\t * @author WestLangley / http://github.com/WestLangley\n\t * @author erich666 / http://erichaines.com\n\t */\n\t\n\t// This set of controls performs orbiting, dollying (zooming), and panning.\n\t// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n\t//\n\t// Orbit - left mouse / touch: one finger move\n\t// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n\t// Pan - right mouse, or arrow keys / touch: three finter swipe\n\t\n\tvar OrbitControls = function OrbitControls(object, domElement) {\n\t\n\t\tthis.object = object;\n\t\n\t\tthis.domElement = domElement !== undefined ? domElement : document;\n\t\n\t\t// Set to false to disable this control\n\t\tthis.enabled = true;\n\t\n\t\t// \"target\" sets the location of focus, where the object orbits around\n\t\tthis.target = new _three2['default'].Vector3();\n\t\n\t\t// How far you can dolly in and out ( PerspectiveCamera only )\n\t\tthis.minDistance = 0;\n\t\tthis.maxDistance = Infinity;\n\t\n\t\t// How far you can zoom in and out ( OrthographicCamera only )\n\t\tthis.minZoom = 0;\n\t\tthis.maxZoom = Infinity;\n\t\n\t\t// How far you can orbit vertically, upper and lower limits.\n\t\t// Range is 0 to Math.PI radians.\n\t\tthis.minPolarAngle = 0; // radians\n\t\tthis.maxPolarAngle = Math.PI; // radians\n\t\n\t\t// How far you can orbit horizontally, upper and lower limits.\n\t\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\t\tthis.minAzimuthAngle = -Infinity; // radians\n\t\tthis.maxAzimuthAngle = Infinity; // radians\n\t\n\t\t// Set to true to enable damping (inertia)\n\t\t// If damping is enabled, you must call controls.update() in your animation loop\n\t\tthis.enableDamping = false;\n\t\tthis.dampingFactor = 0.25;\n\t\n\t\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t\t// Set to false to disable zooming\n\t\tthis.enableZoom = true;\n\t\tthis.zoomSpeed = 1.0;\n\t\n\t\t// Set to false to disable rotating\n\t\tthis.enableRotate = true;\n\t\tthis.rotateSpeed = 1.0;\n\t\n\t\t// Set to false to disable panning\n\t\tthis.enablePan = true;\n\t\tthis.keyPanSpeed = 7.0; // pixels moved per arrow key push\n\t\n\t\t// Set to true to automatically rotate around the target\n\t\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\t\tthis.autoRotate = false;\n\t\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\t\n\t\t// Set to false to disable use of the keys\n\t\tthis.enableKeys = true;\n\t\n\t\t// The four arrow keys\n\t\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\t\n\t\t// Mouse buttons\n\t\tthis.mouseButtons = { ORBIT: _three2['default'].MOUSE.LEFT, ZOOM: _three2['default'].MOUSE.MIDDLE, PAN: _three2['default'].MOUSE.RIGHT };\n\t\n\t\t// for reset\n\t\tthis.target0 = this.target.clone();\n\t\tthis.position0 = this.object.position.clone();\n\t\tthis.zoom0 = this.object.zoom;\n\t\n\t\t//\n\t\t// public methods\n\t\t//\n\t\n\t\tthis.getPolarAngle = function () {\n\t\n\t\t\treturn phi;\n\t\t};\n\t\n\t\tthis.getAzimuthalAngle = function () {\n\t\n\t\t\treturn theta;\n\t\t};\n\t\n\t\tthis.reset = function () {\n\t\n\t\t\tscope.target.copy(scope.target0);\n\t\t\tscope.object.position.copy(scope.position0);\n\t\t\tscope.object.zoom = scope.zoom0;\n\t\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tscope.dispatchEvent(changeEvent);\n\t\n\t\t\tscope.update();\n\t\n\t\t\tstate = STATE.NONE;\n\t\t};\n\t\n\t\t// this method is exposed, but perhaps it would be better if we can make it private...\n\t\tthis.update = (function () {\n\t\n\t\t\tvar offset = new _three2['default'].Vector3();\n\t\n\t\t\t// so camera.up is the orbit axis\n\t\t\tvar quat = new _three2['default'].Quaternion().setFromUnitVectors(object.up, new _three2['default'].Vector3(0, 1, 0));\n\t\t\tvar quatInverse = quat.clone().inverse();\n\t\n\t\t\tvar lastPosition = new _three2['default'].Vector3();\n\t\t\tvar lastQuaternion = new _three2['default'].Quaternion();\n\t\n\t\t\treturn function () {\n\t\n\t\t\t\tvar position = scope.object.position;\n\t\n\t\t\t\toffset.copy(position).sub(scope.target);\n\t\n\t\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\t\toffset.applyQuaternion(quat);\n\t\n\t\t\t\t// angle from z-axis around y-axis\n\t\n\t\t\t\ttheta = Math.atan2(offset.x, offset.z);\n\t\n\t\t\t\t// angle from y-axis\n\t\n\t\t\t\tphi = Math.atan2(Math.sqrt(offset.x * offset.x + offset.z * offset.z), offset.y);\n\t\n\t\t\t\tif (scope.autoRotate && state === STATE.NONE) {\n\t\n\t\t\t\t\trotateLeft(getAutoRotationAngle());\n\t\t\t\t}\n\t\n\t\t\t\ttheta += thetaDelta;\n\t\t\t\tphi += phiDelta;\n\t\n\t\t\t\t// restrict theta to be between desired limits\n\t\t\t\ttheta = Math.max(scope.minAzimuthAngle, Math.min(scope.maxAzimuthAngle, theta));\n\t\n\t\t\t\t// restrict phi to be between desired limits\n\t\t\t\tphi = Math.max(scope.minPolarAngle, Math.min(scope.maxPolarAngle, phi));\n\t\n\t\t\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\t\t\tphi = Math.max(EPS, Math.min(Math.PI - EPS, phi));\n\t\n\t\t\t\tvar radius = offset.length() * scale;\n\t\n\t\t\t\t// restrict radius to be between desired limits\n\t\t\t\tradius = Math.max(scope.minDistance, Math.min(scope.maxDistance, radius));\n\t\n\t\t\t\t// move target to panned location\n\t\t\t\tscope.target.add(panOffset);\n\t\n\t\t\t\toffset.x = radius * Math.sin(phi) * Math.sin(theta);\n\t\t\t\toffset.y = radius * Math.cos(phi);\n\t\t\t\toffset.z = radius * Math.sin(phi) * Math.cos(theta);\n\t\n\t\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\t\toffset.applyQuaternion(quatInverse);\n\t\n\t\t\t\tposition.copy(scope.target).add(offset);\n\t\n\t\t\t\tscope.object.lookAt(scope.target);\n\t\n\t\t\t\tif (scope.enableDamping === true) {\n\t\n\t\t\t\t\tthetaDelta *= 1 - scope.dampingFactor;\n\t\t\t\t\tphiDelta *= 1 - scope.dampingFactor;\n\t\t\t\t} else {\n\t\n\t\t\t\t\tthetaDelta = 0;\n\t\t\t\t\tphiDelta = 0;\n\t\t\t\t}\n\t\n\t\t\t\tscale = 1;\n\t\t\t\tpanOffset.set(0, 0, 0);\n\t\n\t\t\t\t// update condition is:\n\t\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\t\n\t\t\t\tif (zoomChanged || lastPosition.distanceToSquared(scope.object.position) > EPS || 8 * (1 - lastQuaternion.dot(scope.object.quaternion)) > EPS) {\n\t\n\t\t\t\t\tscope.dispatchEvent(changeEvent);\n\t\n\t\t\t\t\tlastPosition.copy(scope.object.position);\n\t\t\t\t\tlastQuaternion.copy(scope.object.quaternion);\n\t\t\t\t\tzoomChanged = false;\n\t\n\t\t\t\t\treturn true;\n\t\t\t\t}\n\t\n\t\t\t\treturn false;\n\t\t\t};\n\t\t})();\n\t\n\t\tthis.dispose = function () {\n\t\n\t\t\tscope.domElement.removeEventListener('contextmenu', onContextMenu, false);\n\t\t\tscope.domElement.removeEventListener('mousedown', onMouseDown, false);\n\t\t\tscope.domElement.removeEventListener('mousewheel', onMouseWheel, false);\n\t\t\tscope.domElement.removeEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox\n\t\n\t\t\tscope.domElement.removeEventListener('touchstart', onTouchStart, false);\n\t\t\tscope.domElement.removeEventListener('touchend', onTouchEnd, false);\n\t\t\tscope.domElement.removeEventListener('touchmove', onTouchMove, false);\n\t\n\t\t\tdocument.removeEventListener('mousemove', onMouseMove, false);\n\t\t\tdocument.removeEventListener('mouseup', onMouseUp, false);\n\t\t\tdocument.removeEventListener('mouseout', onMouseUp, false);\n\t\n\t\t\twindow.removeEventListener('keydown', onKeyDown, false);\n\t\n\t\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\t\t};\n\t\n\t\t//\n\t\t// internals\n\t\t//\n\t\n\t\tvar scope = this;\n\t\n\t\tvar changeEvent = { type: 'change' };\n\t\tvar startEvent = { type: 'start' };\n\t\tvar endEvent = { type: 'end' };\n\t\n\t\tvar STATE = { NONE: -1, ROTATE: 0, DOLLY: 1, PAN: 2, TOUCH_ROTATE: 3, TOUCH_DOLLY: 4, TOUCH_PAN: 5 };\n\t\n\t\tvar state = STATE.NONE;\n\t\n\t\tvar EPS = 0.000001;\n\t\n\t\t// current position in spherical coordinates\n\t\tvar theta;\n\t\tvar phi;\n\t\n\t\tvar phiDelta = 0;\n\t\tvar thetaDelta = 0;\n\t\tvar scale = 1;\n\t\tvar panOffset = new _three2['default'].Vector3();\n\t\tvar zoomChanged = false;\n\t\n\t\tvar rotateStart = new _three2['default'].Vector2();\n\t\tvar rotateEnd = new _three2['default'].Vector2();\n\t\tvar rotateDelta = new _three2['default'].Vector2();\n\t\n\t\tvar panStart = new _three2['default'].Vector2();\n\t\tvar panEnd = new _three2['default'].Vector2();\n\t\tvar panDelta = new _three2['default'].Vector2();\n\t\n\t\tvar dollyStart = new _three2['default'].Vector2();\n\t\tvar dollyEnd = new _three2['default'].Vector2();\n\t\tvar dollyDelta = new _three2['default'].Vector2();\n\t\n\t\tfunction getAutoRotationAngle() {\n\t\n\t\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\t\t}\n\t\n\t\tfunction getZoomScale() {\n\t\n\t\t\treturn Math.pow(0.95, scope.zoomSpeed);\n\t\t}\n\t\n\t\tfunction rotateLeft(angle) {\n\t\n\t\t\tthetaDelta -= angle;\n\t\t}\n\t\n\t\tfunction rotateUp(angle) {\n\t\n\t\t\tphiDelta -= angle;\n\t\t}\n\t\n\t\tvar panLeft = (function () {\n\t\n\t\t\tvar v = new _three2['default'].Vector3();\n\t\n\t\t\t// return function panLeft( distance, objectMatrix ) {\n\t\t\t//\n\t\t\t// \tvar te = objectMatrix.elements;\n\t\t\t//\n\t\t\t// \t// get X column of objectMatrix\n\t\t\t// \tv.set( te[ 0 ], te[ 1 ], te[ 2 ] );\n\t\t\t//\n\t\t\t// \tv.multiplyScalar( - distance );\n\t\t\t//\n\t\t\t// \tpanOffset.add( v );\n\t\t\t//\n\t\t\t// };\n\t\n\t\t\t// Fixed panning to x/y plane\n\t\t\treturn function panLeft(distance, objectMatrix) {\n\t\t\t\tvar te = objectMatrix.elements;\n\t\t\t\t// var adjDist = distance / Math.cos(phi);\n\t\n\t\t\t\tv.set(te[0], 0, te[2]);\n\t\t\t\tv.multiplyScalar(-distance);\n\t\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t})();\n\t\n\t\t// Fixed panning to x/y plane\n\t\tvar panUp = (function () {\n\t\n\t\t\tvar v = new _three2['default'].Vector3();\n\t\n\t\t\t// return function panUp( distance, objectMatrix ) {\n\t\t\t//\n\t\t\t// \tvar te = objectMatrix.elements;\n\t\t\t//\n\t\t\t// \t// get Y column of objectMatrix\n\t\t\t// \tv.set( te[ 4 ], te[ 5 ], te[ 6 ] );\n\t\t\t//\n\t\t\t// \tv.multiplyScalar( distance );\n\t\t\t//\n\t\t\t// \tpanOffset.add( v );\n\t\t\t//\n\t\t\t// };\n\t\n\t\t\treturn function panUp(distance, objectMatrix) {\n\t\t\t\tvar te = objectMatrix.elements;\n\t\t\t\tvar adjDist = distance / Math.cos(phi);\n\t\n\t\t\t\tv.set(te[4], 0, te[6]);\n\t\t\t\tv.multiplyScalar(adjDist);\n\t\n\t\t\t\tpanOffset.add(v);\n\t\t\t};\n\t\t})();\n\t\n\t\t// deltaX and deltaY are in pixels; right and down are positive\n\t\tvar pan = (function () {\n\t\n\t\t\tvar offset = new _three2['default'].Vector3();\n\t\n\t\t\treturn function (deltaX, deltaY) {\n\t\n\t\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\n\t\t\t\tif (scope.object instanceof _three2['default'].PerspectiveCamera) {\n\t\n\t\t\t\t\t// perspective\n\t\t\t\t\tvar position = scope.object.position;\n\t\t\t\t\toffset.copy(position).sub(scope.target);\n\t\t\t\t\tvar targetDistance = offset.length();\n\t\n\t\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\t\ttargetDistance *= Math.tan(scope.object.fov / 2 * Math.PI / 180.0);\n\t\n\t\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\t\tpanLeft(2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t\tpanUp(2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix);\n\t\t\t\t} else if (scope.object instanceof _three2['default'].OrthographicCamera) {\n\t\n\t\t\t\t\t// orthographic\n\t\t\t\t\tpanLeft(deltaX * (scope.object.right - scope.object.left) / element.clientWidth, scope.object.matrix);\n\t\t\t\t\tpanUp(deltaY * (scope.object.top - scope.object.bottom) / element.clientHeight, scope.object.matrix);\n\t\t\t\t} else {\n\t\n\t\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\t\tconsole.warn('WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.');\n\t\t\t\t\tscope.enablePan = false;\n\t\t\t\t}\n\t\t\t};\n\t\t})();\n\t\n\t\tfunction dollyIn(dollyScale) {\n\t\n\t\t\tif (scope.object instanceof _three2['default'].PerspectiveCamera) {\n\t\n\t\t\t\tscale /= dollyScale;\n\t\t\t} else if (scope.object instanceof _three2['default'].OrthographicCamera) {\n\t\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom * dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t} else {\n\t\n\t\t\t\tconsole.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\n\t\tfunction dollyOut(dollyScale) {\n\t\n\t\t\tif (scope.object instanceof _three2['default'].PerspectiveCamera) {\n\t\n\t\t\t\tscale *= dollyScale;\n\t\t\t} else if (scope.object instanceof _three2['default'].OrthographicCamera) {\n\t\n\t\t\t\tscope.object.zoom = Math.max(scope.minZoom, Math.min(scope.maxZoom, scope.object.zoom / dollyScale));\n\t\t\t\tscope.object.updateProjectionMatrix();\n\t\t\t\tzoomChanged = true;\n\t\t\t} else {\n\t\n\t\t\t\tconsole.warn('WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.');\n\t\t\t\tscope.enableZoom = false;\n\t\t\t}\n\t\t}\n\t\n\t\t//\n\t\t// event callbacks - update the object state\n\t\t//\n\t\n\t\tfunction handleMouseDownRotate(event) {\n\t\n\t\t\t//console.log( 'handleMouseDownRotate' );\n\t\n\t\t\trotateStart.set(event.clientX, event.clientY);\n\t\t}\n\t\n\t\tfunction handleMouseDownDolly(event) {\n\t\n\t\t\t//console.log( 'handleMouseDownDolly' );\n\t\n\t\t\tdollyStart.set(event.clientX, event.clientY);\n\t\t}\n\t\n\t\tfunction handleMouseDownPan(event) {\n\t\n\t\t\t//console.log( 'handleMouseDownPan' );\n\t\n\t\t\tpanStart.set(event.clientX, event.clientY);\n\t\t}\n\t\n\t\tfunction handleMouseMoveRotate(event) {\n\t\n\t\t\t//console.log( 'handleMouseMoveRotate' );\n\t\n\t\t\trotateEnd.set(event.clientX, event.clientY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\n\t\t\trotateStart.copy(rotateEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleMouseMoveDolly(event) {\n\t\n\t\t\t//console.log( 'handleMouseMoveDolly' );\n\t\n\t\t\tdollyEnd.set(event.clientX, event.clientY);\n\t\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\n\t\t\tif (dollyDelta.y > 0) {\n\t\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t} else if (dollyDelta.y < 0) {\n\t\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t}\n\t\n\t\t\tdollyStart.copy(dollyEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleMouseMovePan(event) {\n\t\n\t\t\t//console.log( 'handleMouseMovePan' );\n\t\n\t\t\tpanEnd.set(event.clientX, event.clientY);\n\t\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\n\t\t\tpanStart.copy(panEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleMouseUp(event) {\n\t\n\t\t\t//console.log( 'handleMouseUp' );\n\t\n\t\t}\n\t\n\t\tfunction handleMouseWheel(event) {\n\t\n\t\t\t//console.log( 'handleMouseWheel' );\n\t\n\t\t\tvar delta = 0;\n\t\n\t\t\tif (event.wheelDelta !== undefined) {\n\t\n\t\t\t\t// WebKit / Opera / Explorer 9\n\t\n\t\t\t\tdelta = event.wheelDelta;\n\t\t\t} else if (event.detail !== undefined) {\n\t\n\t\t\t\t// Firefox\n\t\n\t\t\t\tdelta = -event.detail;\n\t\t\t}\n\t\n\t\t\tif (delta > 0) {\n\t\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t} else if (delta < 0) {\n\t\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleKeyDown(event) {\n\t\n\t\t\t//console.log( 'handleKeyDown' );\n\t\n\t\t\tswitch (event.keyCode) {\n\t\n\t\t\t\tcase scope.keys.UP:\n\t\t\t\t\tpan(0, scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\t\tpan(0, -scope.keyPanSpeed);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase scope.keys.LEFT:\n\t\t\t\t\tpan(scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase scope.keys.RIGHT:\n\t\t\t\t\tpan(-scope.keyPanSpeed, 0);\n\t\t\t\t\tscope.update();\n\t\t\t\t\tbreak;\n\t\n\t\t\t}\n\t\t}\n\t\n\t\tfunction handleTouchStartRotate(event) {\n\t\n\t\t\t//console.log( 'handleTouchStartRotate' );\n\t\n\t\t\trotateStart.set(event.pointers[0].pageX, event.pointers[0].pageY);\n\t\t}\n\t\n\t\tfunction handleTouchStartDolly(event) {\n\t\n\t\t\t//console.log( 'handleTouchStartDolly' );\n\t\n\t\t\tvar dx = event.pointers[0].pageX - event.pointers[1].pageX;\n\t\t\tvar dy = event.pointers[0].pageY - event.pointers[1].pageY;\n\t\n\t\t\tvar distance = Math.sqrt(dx * dx + dy * dy);\n\t\n\t\t\tdollyStart.set(0, distance);\n\t\t}\n\t\n\t\tfunction handleTouchStartPan(event) {\n\t\n\t\t\t//console.log( 'handleTouchStartPan' );\n\t\n\t\t\tpanStart.set(event.deltaX, event.deltaY);\n\t\t}\n\t\n\t\tfunction handleTouchMoveRotate(event) {\n\t\n\t\t\t//console.log( 'handleTouchMoveRotate' );\n\t\n\t\t\trotateEnd.set(event.pointers[0].pageX, event.pointers[0].pageY);\n\t\t\trotateDelta.subVectors(rotateEnd, rotateStart);\n\t\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\t\n\t\t\t// rotating across whole screen goes 360 degrees around\n\t\t\trotateLeft(2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed);\n\t\n\t\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\t\trotateUp(2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed);\n\t\n\t\t\trotateStart.copy(rotateEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleTouchMoveDolly(event) {\n\t\n\t\t\t//console.log( 'handleTouchMoveDolly' );\n\t\n\t\t\tvar dx = event.pointers[0].pageX - event.pointers[1].pageX;\n\t\t\tvar dy = event.pointers[0].pageY - event.pointers[1].pageY;\n\t\n\t\t\tvar distance = Math.sqrt(dx * dx + dy * dy);\n\t\n\t\t\tdollyEnd.set(0, distance);\n\t\n\t\t\tdollyDelta.subVectors(dollyEnd, dollyStart);\n\t\n\t\t\tif (dollyDelta.y > 0) {\n\t\n\t\t\t\tdollyOut(getZoomScale());\n\t\t\t} else if (dollyDelta.y < 0) {\n\t\n\t\t\t\tdollyIn(getZoomScale());\n\t\t\t}\n\t\n\t\t\tdollyStart.copy(dollyEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleTouchMovePan(event) {\n\t\n\t\t\t//console.log( 'handleTouchMovePan' );\n\t\n\t\t\tpanEnd.set(event.deltaX, event.deltaY);\n\t\n\t\t\tpanDelta.subVectors(panEnd, panStart);\n\t\n\t\t\tpan(panDelta.x, panDelta.y);\n\t\n\t\t\tpanStart.copy(panEnd);\n\t\n\t\t\tscope.update();\n\t\t}\n\t\n\t\tfunction handleTouchEnd(event) {}\n\t\n\t\t//console.log( 'handleTouchEnd' );\n\t\n\t\t//\n\t\t// event handlers - FSM: listen for events and reset state\n\t\t//\n\t\n\t\tfunction onMouseDown(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tif (event.button === scope.mouseButtons.ORBIT) {\n\t\n\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\thandleMouseDownRotate(event);\n\t\n\t\t\t\tstate = STATE.ROTATE;\n\t\t\t} else if (event.button === scope.mouseButtons.ZOOM) {\n\t\n\t\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\t\thandleMouseDownDolly(event);\n\t\n\t\t\t\tstate = STATE.DOLLY;\n\t\t\t} else if (event.button === scope.mouseButtons.PAN) {\n\t\n\t\t\t\tif (scope.enablePan === false) return;\n\t\n\t\t\t\thandleMouseDownPan(event);\n\t\n\t\t\t\tstate = STATE.PAN;\n\t\t\t}\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\n\t\t\t\tdocument.addEventListener('mousemove', onMouseMove, false);\n\t\t\t\tdocument.addEventListener('mouseup', onMouseUp, false);\n\t\t\t\tdocument.addEventListener('mouseout', onMouseUp, false);\n\t\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onMouseMove(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tevent.preventDefault();\n\t\n\t\t\tif (state === STATE.ROTATE) {\n\t\n\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\thandleMouseMoveRotate(event);\n\t\t\t} else if (state === STATE.DOLLY) {\n\t\n\t\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\t\thandleMouseMoveDolly(event);\n\t\t\t} else if (state === STATE.PAN) {\n\t\n\t\t\t\tif (scope.enablePan === false) return;\n\t\n\t\t\t\thandleMouseMovePan(event);\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onMouseUp(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\thandleMouseUp(event);\n\t\n\t\t\tdocument.removeEventListener('mousemove', onMouseMove, false);\n\t\t\tdocument.removeEventListener('mouseup', onMouseUp, false);\n\t\t\tdocument.removeEventListener('mouseout', onMouseUp, false);\n\t\n\t\t\tscope.dispatchEvent(endEvent);\n\t\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\n\t\tfunction onMouseWheel(event) {\n\t\n\t\t\tif (scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE) return;\n\t\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\n\t\t\thandleMouseWheel(event);\n\t\n\t\t\tscope.dispatchEvent(startEvent); // not sure why these are here...\n\t\t\tscope.dispatchEvent(endEvent);\n\t\t}\n\t\n\t\tfunction onKeyDown(event) {\n\t\n\t\t\tif (scope.enabled === false || scope.enableKeys === false || scope.enablePan === false) return;\n\t\n\t\t\thandleKeyDown(event);\n\t\t}\n\t\n\t\tfunction onTouchStart(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tswitch (event.touches.length) {\n\t\n\t\t\t\tcase 1:\n\t\t\t\t\t// one-fingered touch: rotate\n\t\n\t\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\t\thandleTouchStartRotate(event);\n\t\n\t\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 2:\n\t\t\t\t\t// two-fingered touch: dolly\n\t\n\t\t\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\t\t\thandleTouchStartDolly(event);\n\t\n\t\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 3:\n\t\t\t\t\t// three-fingered touch: pan\n\t\n\t\t\t\t\tif (scope.enablePan === false) return;\n\t\n\t\t\t\t\thandleTouchStartPan(event);\n\t\n\t\t\t\t\tstate = STATE.TOUCH_PAN;\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tdefault:\n\t\n\t\t\t\t\tstate = STATE.NONE;\n\t\n\t\t\t}\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onTouchMove(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tevent.preventDefault();\n\t\t\tevent.stopPropagation();\n\t\n\t\t\tswitch (event.touches.length) {\n\t\n\t\t\t\tcase 1:\n\t\t\t\t\t// one-fingered touch: rotate\n\t\n\t\t\t\t\tif (scope.enableRotate === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_ROTATE) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMoveRotate(event);\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 2:\n\t\t\t\t\t// two-fingered touch: dolly\n\t\n\t\t\t\t\tif (scope.enableZoom === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_DOLLY) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMoveDolly(event);\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tcase 3:\n\t\t\t\t\t// three-fingered touch: pan\n\t\n\t\t\t\t\tif (scope.enablePan === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_PAN) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMovePan(event);\n\t\n\t\t\t\t\tbreak;\n\t\n\t\t\t\tdefault:\n\t\n\t\t\t\t\tstate = STATE.NONE;\n\t\n\t\t\t}\n\t\t}\n\t\n\t\tfunction onTouchEnd(event) {\n\t\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\thandleTouchEnd(event);\n\t\n\t\t\tscope.dispatchEvent(endEvent);\n\t\n\t\t\tstate = STATE.NONE;\n\t\t}\n\t\n\t\tfunction onContextMenu(event) {\n\t\n\t\t\tevent.preventDefault();\n\t\t}\n\t\n\t\t//\n\t\n\t\tscope.domElement.addEventListener('contextmenu', onContextMenu, false);\n\t\n\t\tscope.domElement.addEventListener('mousedown', onMouseDown, false);\n\t\tscope.domElement.addEventListener('mousewheel', onMouseWheel, false);\n\t\tscope.domElement.addEventListener('MozMousePixelScroll', onMouseWheel, false); // firefox\n\t\n\t\t// scope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t\t// scope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t\t// scope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\t\n\t\tscope.hammer = new _hammerjs2['default'](scope.domElement);\n\t\n\t\tscope.hammer.get('pan').set({\n\t\t\tpointers: 0,\n\t\t\tdirection: _hammerjs2['default'].DIRECTION_ALL\n\t\t});\n\t\n\t\tscope.hammer.get('pinch').set({\n\t\t\tenable: true,\n\t\t\tthreshold: 0.1\n\t\t});\n\t\n\t\tscope.hammer.on('panstart', function (event) {\n\t\t\tif (scope.enabled === false) {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif (event.pointers.length === 1) {\n\t\t\t\tif (scope.enablePan === false) {\n\t\t\t\t\treturn;\n\t\t\t\t}\n\t\n\t\t\t\thandleTouchStartPan(event);\n\t\t\t\t// panStart.set(event.deltaX, event.deltaY);\n\t\n\t\t\t\tstate = STATE.TOUCH_PAN;\n\t\t\t} else if (event.pointers.length === 2) {\n\t\t\t\tif (scope.enableRotate === false) return;\n\t\n\t\t\t\thandleTouchStartRotate(event);\n\t\n\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\t\t}\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t});\n\t\n\t\tscope.hammer.on('panend', function (event) {\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tonTouchEnd(event);\n\t\t});\n\t\n\t\tscope.hammer.on('panmove', function (event) {\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// event.preventDefault();\n\t\t\t// event.stopPropagation();\n\t\n\t\t\tif (event.pointers.length === 1) {\n\t\t\t\tif (scope.enablePan === false) return;\n\t\t\t\tif (state !== STATE.TOUCH_PAN) return; // is this needed?...\n\t\n\t\t\t\thandleTouchMovePan(event);\n\t\n\t\t\t\t// panEnd.set( event.deltaX, event.deltaY );\n\t\t\t\t//\n\t\t\t\t// panDelta.subVectors( panEnd, panStart );\n\t\t\t\t//\n\t\t\t\t// pan( panDelta.x, panDelta.y );\n\t\t\t\t//\n\t\t\t\t// panStart.copy( panEnd );\n\t\t\t\t//\n\t\t\t\t// scope.update();\n\t\t\t} else if (event.pointers.length === 2) {\n\t\t\t\t\tif (scope.enableRotate === false) return;\n\t\t\t\t\tif (state !== STATE.TOUCH_ROTATE) return; // is this needed?...\n\t\n\t\t\t\t\thandleTouchMoveRotate(event);\n\t\t\t\t}\n\t\t});\n\t\n\t\tscope.hammer.on('pinchstart', function (event) {\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tif (scope.enableZoom === false) return;\n\t\n\t\t\thandleTouchStartDolly(event);\n\t\n\t\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t\t//\n\t\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t\t//\n\t\t\t// dollyStart.set( 0, distance );\n\t\t\t//\n\t\t\tstate = STATE.TOUCH_DOLLY;\n\t\n\t\t\tif (state !== STATE.NONE) {\n\t\t\t\tscope.dispatchEvent(startEvent);\n\t\t\t}\n\t\t});\n\t\n\t\tscope.hammer.on('pinchend', function (event) {\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\tonTouchEnd(event);\n\t\t});\n\t\n\t\tscope.hammer.on('pinchmove', function (event) {\n\t\t\tif (scope.enabled === false) return;\n\t\n\t\t\tif (event.pointerType === 'mouse') {\n\t\t\t\treturn;\n\t\t\t}\n\t\n\t\t\t// event.preventDefault();\n\t\t\t// event.stopPropagation();\n\t\n\t\t\tif (scope.enableZoom === false) return;\n\t\t\tif (state !== STATE.TOUCH_DOLLY) return; // is this needed?...\n\t\n\t\t\thandleTouchMoveDolly(event);\n\t\n\t\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t\t//\n\t\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t\t//\n\t\t\t// dollyEnd.set( 0, distance );\n\t\t\t//\n\t\t\t// dollyDelta.subVectors( dollyEnd, dollyStart );\n\t\t\t//\n\t\t\t// if ( dollyDelta.y > 0 ) {\n\t\t\t//\n\t\t\t// \tdollyOut( getZoomScale() );\n\t\t\t//\n\t\t\t// } else if ( dollyDelta.y < 0 ) {\n\t\t\t//\n\t\t\t// \tdollyIn( getZoomScale() );\n\t\t\t//\n\t\t\t// }\n\t\t\t//\n\t\t\t// dollyStart.copy( dollyEnd );\n\t\t\t//\n\t\t\t// scope.update();\n\t\t});\n\t\n\t\twindow.addEventListener('keydown', onKeyDown, false);\n\t\n\t\t// Expose controls methods for programmatic control\n\t\tthis.panLeft = panLeft;\n\t\tthis.panUp = panUp;\n\t\tthis.pan = pan;\n\t\tthis.dollyIn = dollyIn;\n\t\tthis.dollyOut = dollyOut;\n\t\tthis.getZoomScale = getZoomScale;\n\t\tthis.rotateLeft = rotateLeft;\n\t\tthis.rotateUp = rotateUp;\n\t\n\t\t// force an update at start\n\t\n\t\tthis.update();\n\t};\n\t\n\tOrbitControls.prototype = Object.create(_three2['default'].EventDispatcher.prototype);\n\tOrbitControls.prototype.constructor = _three2['default'].OrbitControls;\n\t\n\tObject.defineProperties(OrbitControls.prototype, {\n\t\n\t\tcenter: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .center has been renamed to .target');\n\t\t\t\treturn this.target;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\t// backward compatibility\n\t\n\t\tnoZoom: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');\n\t\t\t\treturn !this.enableZoom;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.');\n\t\t\t\tthis.enableZoom = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tnoRotate: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');\n\t\t\t\treturn !this.enableRotate;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.');\n\t\t\t\tthis.enableRotate = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tnoPan: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');\n\t\t\t\treturn !this.enablePan;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.');\n\t\t\t\tthis.enablePan = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tnoKeys: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');\n\t\t\t\treturn !this.enableKeys;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.');\n\t\t\t\tthis.enableKeys = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tstaticMoving: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');\n\t\t\t\treturn !this.constraint.enableDamping;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.');\n\t\t\t\tthis.constraint.enableDamping = !value;\n\t\t\t}\n\t\n\t\t},\n\t\n\t\tdynamicDampingFactor: {\n\t\n\t\t\tget: function get() {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');\n\t\t\t\treturn this.constraint.dampingFactor;\n\t\t\t},\n\t\n\t\t\tset: function set(value) {\n\t\n\t\t\t\tconsole.warn('THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.');\n\t\t\t\tthis.constraint.dampingFactor = value;\n\t\t\t}\n\t\n\t\t}\n\t\n\t});\n\t\n\texports['default'] = OrbitControls;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 52 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_RESULT__;/*! Hammer.JS - v2.0.7 - 2016-04-22\n\t * http://hammerjs.github.io/\n\t *\n\t * Copyright (c) 2016 Jorik Tangelder;\n\t * Licensed under the MIT license */\n\t(function(window, document, exportName, undefined) {\n\t 'use strict';\n\t\n\tvar VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];\n\tvar TEST_ELEMENT = document.createElement('div');\n\t\n\tvar TYPE_FUNCTION = 'function';\n\t\n\tvar round = Math.round;\n\tvar abs = Math.abs;\n\tvar now = Date.now;\n\t\n\t/**\n\t * set a timeout with a given scope\n\t * @param {Function} fn\n\t * @param {Number} timeout\n\t * @param {Object} context\n\t * @returns {number}\n\t */\n\tfunction setTimeoutContext(fn, timeout, context) {\n\t return setTimeout(bindFn(fn, context), timeout);\n\t}\n\t\n\t/**\n\t * if the argument is an array, we want to execute the fn on each entry\n\t * if it aint an array we don't want to do a thing.\n\t * this is used by all the methods that accept a single and array argument.\n\t * @param {*|Array} arg\n\t * @param {String} fn\n\t * @param {Object} [context]\n\t * @returns {Boolean}\n\t */\n\tfunction invokeArrayArg(arg, fn, context) {\n\t if (Array.isArray(arg)) {\n\t each(arg, context[fn], context);\n\t return true;\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * walk objects and arrays\n\t * @param {Object} obj\n\t * @param {Function} iterator\n\t * @param {Object} context\n\t */\n\tfunction each(obj, iterator, context) {\n\t var i;\n\t\n\t if (!obj) {\n\t return;\n\t }\n\t\n\t if (obj.forEach) {\n\t obj.forEach(iterator, context);\n\t } else if (obj.length !== undefined) {\n\t i = 0;\n\t while (i < obj.length) {\n\t iterator.call(context, obj[i], i, obj);\n\t i++;\n\t }\n\t } else {\n\t for (i in obj) {\n\t obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);\n\t }\n\t }\n\t}\n\t\n\t/**\n\t * wrap a method with a deprecation warning and stack trace\n\t * @param {Function} method\n\t * @param {String} name\n\t * @param {String} message\n\t * @returns {Function} A new function wrapping the supplied method.\n\t */\n\tfunction deprecate(method, name, message) {\n\t var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\\n' + message + ' AT \\n';\n\t return function() {\n\t var e = new Error('get-stack-trace');\n\t var stack = e && e.stack ? e.stack.replace(/^[^\\(]+?[\\n$]/gm, '')\n\t .replace(/^\\s+at\\s+/gm, '')\n\t .replace(/^Object.\\s*\\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';\n\t\n\t var log = window.console && (window.console.warn || window.console.log);\n\t if (log) {\n\t log.call(window.console, deprecationMessage, stack);\n\t }\n\t return method.apply(this, arguments);\n\t };\n\t}\n\t\n\t/**\n\t * extend object.\n\t * means that properties in dest will be overwritten by the ones in src.\n\t * @param {Object} target\n\t * @param {...Object} objects_to_assign\n\t * @returns {Object} target\n\t */\n\tvar assign;\n\tif (typeof Object.assign !== 'function') {\n\t assign = function assign(target) {\n\t if (target === undefined || target === null) {\n\t throw new TypeError('Cannot convert undefined or null to object');\n\t }\n\t\n\t var output = Object(target);\n\t for (var index = 1; index < arguments.length; index++) {\n\t var source = arguments[index];\n\t if (source !== undefined && source !== null) {\n\t for (var nextKey in source) {\n\t if (source.hasOwnProperty(nextKey)) {\n\t output[nextKey] = source[nextKey];\n\t }\n\t }\n\t }\n\t }\n\t return output;\n\t };\n\t} else {\n\t assign = Object.assign;\n\t}\n\t\n\t/**\n\t * extend object.\n\t * means that properties in dest will be overwritten by the ones in src.\n\t * @param {Object} dest\n\t * @param {Object} src\n\t * @param {Boolean} [merge=false]\n\t * @returns {Object} dest\n\t */\n\tvar extend = deprecate(function extend(dest, src, merge) {\n\t var keys = Object.keys(src);\n\t var i = 0;\n\t while (i < keys.length) {\n\t if (!merge || (merge && dest[keys[i]] === undefined)) {\n\t dest[keys[i]] = src[keys[i]];\n\t }\n\t i++;\n\t }\n\t return dest;\n\t}, 'extend', 'Use `assign`.');\n\t\n\t/**\n\t * merge the values from src in the dest.\n\t * means that properties that exist in dest will not be overwritten by src\n\t * @param {Object} dest\n\t * @param {Object} src\n\t * @returns {Object} dest\n\t */\n\tvar merge = deprecate(function merge(dest, src) {\n\t return extend(dest, src, true);\n\t}, 'merge', 'Use `assign`.');\n\t\n\t/**\n\t * simple class inheritance\n\t * @param {Function} child\n\t * @param {Function} base\n\t * @param {Object} [properties]\n\t */\n\tfunction inherit(child, base, properties) {\n\t var baseP = base.prototype,\n\t childP;\n\t\n\t childP = child.prototype = Object.create(baseP);\n\t childP.constructor = child;\n\t childP._super = baseP;\n\t\n\t if (properties) {\n\t assign(childP, properties);\n\t }\n\t}\n\t\n\t/**\n\t * simple function bind\n\t * @param {Function} fn\n\t * @param {Object} context\n\t * @returns {Function}\n\t */\n\tfunction bindFn(fn, context) {\n\t return function boundFn() {\n\t return fn.apply(context, arguments);\n\t };\n\t}\n\t\n\t/**\n\t * let a boolean value also be a function that must return a boolean\n\t * this first item in args will be used as the context\n\t * @param {Boolean|Function} val\n\t * @param {Array} [args]\n\t * @returns {Boolean}\n\t */\n\tfunction boolOrFn(val, args) {\n\t if (typeof val == TYPE_FUNCTION) {\n\t return val.apply(args ? args[0] || undefined : undefined, args);\n\t }\n\t return val;\n\t}\n\t\n\t/**\n\t * use the val2 when val1 is undefined\n\t * @param {*} val1\n\t * @param {*} val2\n\t * @returns {*}\n\t */\n\tfunction ifUndefined(val1, val2) {\n\t return (val1 === undefined) ? val2 : val1;\n\t}\n\t\n\t/**\n\t * addEventListener with multiple events at once\n\t * @param {EventTarget} target\n\t * @param {String} types\n\t * @param {Function} handler\n\t */\n\tfunction addEventListeners(target, types, handler) {\n\t each(splitStr(types), function(type) {\n\t target.addEventListener(type, handler, false);\n\t });\n\t}\n\t\n\t/**\n\t * removeEventListener with multiple events at once\n\t * @param {EventTarget} target\n\t * @param {String} types\n\t * @param {Function} handler\n\t */\n\tfunction removeEventListeners(target, types, handler) {\n\t each(splitStr(types), function(type) {\n\t target.removeEventListener(type, handler, false);\n\t });\n\t}\n\t\n\t/**\n\t * find if a node is in the given parent\n\t * @method hasParent\n\t * @param {HTMLElement} node\n\t * @param {HTMLElement} parent\n\t * @return {Boolean} found\n\t */\n\tfunction hasParent(node, parent) {\n\t while (node) {\n\t if (node == parent) {\n\t return true;\n\t }\n\t node = node.parentNode;\n\t }\n\t return false;\n\t}\n\t\n\t/**\n\t * small indexOf wrapper\n\t * @param {String} str\n\t * @param {String} find\n\t * @returns {Boolean} found\n\t */\n\tfunction inStr(str, find) {\n\t return str.indexOf(find) > -1;\n\t}\n\t\n\t/**\n\t * split string on whitespace\n\t * @param {String} str\n\t * @returns {Array} words\n\t */\n\tfunction splitStr(str) {\n\t return str.trim().split(/\\s+/g);\n\t}\n\t\n\t/**\n\t * find if a array contains the object using indexOf or a simple polyFill\n\t * @param {Array} src\n\t * @param {String} find\n\t * @param {String} [findByKey]\n\t * @return {Boolean|Number} false when not found, or the index\n\t */\n\tfunction inArray(src, find, findByKey) {\n\t if (src.indexOf && !findByKey) {\n\t return src.indexOf(find);\n\t } else {\n\t var i = 0;\n\t while (i < src.length) {\n\t if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {\n\t return i;\n\t }\n\t i++;\n\t }\n\t return -1;\n\t }\n\t}\n\t\n\t/**\n\t * convert array-like objects to real arrays\n\t * @param {Object} obj\n\t * @returns {Array}\n\t */\n\tfunction toArray(obj) {\n\t return Array.prototype.slice.call(obj, 0);\n\t}\n\t\n\t/**\n\t * unique array with objects based on a key (like 'id') or just by the array's value\n\t * @param {Array} src [{id:1},{id:2},{id:1}]\n\t * @param {String} [key]\n\t * @param {Boolean} [sort=False]\n\t * @returns {Array} [{id:1},{id:2}]\n\t */\n\tfunction uniqueArray(src, key, sort) {\n\t var results = [];\n\t var values = [];\n\t var i = 0;\n\t\n\t while (i < src.length) {\n\t var val = key ? src[i][key] : src[i];\n\t if (inArray(values, val) < 0) {\n\t results.push(src[i]);\n\t }\n\t values[i] = val;\n\t i++;\n\t }\n\t\n\t if (sort) {\n\t if (!key) {\n\t results = results.sort();\n\t } else {\n\t results = results.sort(function sortUniqueArray(a, b) {\n\t return a[key] > b[key];\n\t });\n\t }\n\t }\n\t\n\t return results;\n\t}\n\t\n\t/**\n\t * get the prefixed property\n\t * @param {Object} obj\n\t * @param {String} property\n\t * @returns {String|Undefined} prefixed\n\t */\n\tfunction prefixed(obj, property) {\n\t var prefix, prop;\n\t var camelProp = property[0].toUpperCase() + property.slice(1);\n\t\n\t var i = 0;\n\t while (i < VENDOR_PREFIXES.length) {\n\t prefix = VENDOR_PREFIXES[i];\n\t prop = (prefix) ? prefix + camelProp : property;\n\t\n\t if (prop in obj) {\n\t return prop;\n\t }\n\t i++;\n\t }\n\t return undefined;\n\t}\n\t\n\t/**\n\t * get a unique id\n\t * @returns {number} uniqueId\n\t */\n\tvar _uniqueId = 1;\n\tfunction uniqueId() {\n\t return _uniqueId++;\n\t}\n\t\n\t/**\n\t * get the window object of an element\n\t * @param {HTMLElement} element\n\t * @returns {DocumentView|Window}\n\t */\n\tfunction getWindowForElement(element) {\n\t var doc = element.ownerDocument || element;\n\t return (doc.defaultView || doc.parentWindow || window);\n\t}\n\t\n\tvar MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;\n\t\n\tvar SUPPORT_TOUCH = ('ontouchstart' in window);\n\tvar SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;\n\tvar SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);\n\t\n\tvar INPUT_TYPE_TOUCH = 'touch';\n\tvar INPUT_TYPE_PEN = 'pen';\n\tvar INPUT_TYPE_MOUSE = 'mouse';\n\tvar INPUT_TYPE_KINECT = 'kinect';\n\t\n\tvar COMPUTE_INTERVAL = 25;\n\t\n\tvar INPUT_START = 1;\n\tvar INPUT_MOVE = 2;\n\tvar INPUT_END = 4;\n\tvar INPUT_CANCEL = 8;\n\t\n\tvar DIRECTION_NONE = 1;\n\tvar DIRECTION_LEFT = 2;\n\tvar DIRECTION_RIGHT = 4;\n\tvar DIRECTION_UP = 8;\n\tvar DIRECTION_DOWN = 16;\n\t\n\tvar DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;\n\tvar DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;\n\tvar DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;\n\t\n\tvar PROPS_XY = ['x', 'y'];\n\tvar PROPS_CLIENT_XY = ['clientX', 'clientY'];\n\t\n\t/**\n\t * create new input type manager\n\t * @param {Manager} manager\n\t * @param {Function} callback\n\t * @returns {Input}\n\t * @constructor\n\t */\n\tfunction Input(manager, callback) {\n\t var self = this;\n\t this.manager = manager;\n\t this.callback = callback;\n\t this.element = manager.element;\n\t this.target = manager.options.inputTarget;\n\t\n\t // smaller wrapper around the handler, for the scope and the enabled state of the manager,\n\t // so when disabled the input events are completely bypassed.\n\t this.domHandler = function(ev) {\n\t if (boolOrFn(manager.options.enable, [manager])) {\n\t self.handler(ev);\n\t }\n\t };\n\t\n\t this.init();\n\t\n\t}\n\t\n\tInput.prototype = {\n\t /**\n\t * should handle the inputEvent data and trigger the callback\n\t * @virtual\n\t */\n\t handler: function() { },\n\t\n\t /**\n\t * bind the events\n\t */\n\t init: function() {\n\t this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);\n\t this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);\n\t this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n\t },\n\t\n\t /**\n\t * unbind the events\n\t */\n\t destroy: function() {\n\t this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);\n\t this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);\n\t this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n\t }\n\t};\n\t\n\t/**\n\t * create new input type manager\n\t * called by the Manager constructor\n\t * @param {Hammer} manager\n\t * @returns {Input}\n\t */\n\tfunction createInputInstance(manager) {\n\t var Type;\n\t var inputClass = manager.options.inputClass;\n\t\n\t if (inputClass) {\n\t Type = inputClass;\n\t } else if (SUPPORT_POINTER_EVENTS) {\n\t Type = PointerEventInput;\n\t } else if (SUPPORT_ONLY_TOUCH) {\n\t Type = TouchInput;\n\t } else if (!SUPPORT_TOUCH) {\n\t Type = MouseInput;\n\t } else {\n\t Type = TouchMouseInput;\n\t }\n\t return new (Type)(manager, inputHandler);\n\t}\n\t\n\t/**\n\t * handle input events\n\t * @param {Manager} manager\n\t * @param {String} eventType\n\t * @param {Object} input\n\t */\n\tfunction inputHandler(manager, eventType, input) {\n\t var pointersLen = input.pointers.length;\n\t var changedPointersLen = input.changedPointers.length;\n\t var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));\n\t var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));\n\t\n\t input.isFirst = !!isFirst;\n\t input.isFinal = !!isFinal;\n\t\n\t if (isFirst) {\n\t manager.session = {};\n\t }\n\t\n\t // source event is the normalized value of the domEvents\n\t // like 'touchstart, mouseup, pointerdown'\n\t input.eventType = eventType;\n\t\n\t // compute scale, rotation etc\n\t computeInputData(manager, input);\n\t\n\t // emit secret event\n\t manager.emit('hammer.input', input);\n\t\n\t manager.recognize(input);\n\t manager.session.prevInput = input;\n\t}\n\t\n\t/**\n\t * extend the data with some usable properties like scale, rotate, velocity etc\n\t * @param {Object} manager\n\t * @param {Object} input\n\t */\n\tfunction computeInputData(manager, input) {\n\t var session = manager.session;\n\t var pointers = input.pointers;\n\t var pointersLength = pointers.length;\n\t\n\t // store the first input to calculate the distance and direction\n\t if (!session.firstInput) {\n\t session.firstInput = simpleCloneInputData(input);\n\t }\n\t\n\t // to compute scale and rotation we need to store the multiple touches\n\t if (pointersLength > 1 && !session.firstMultiple) {\n\t session.firstMultiple = simpleCloneInputData(input);\n\t } else if (pointersLength === 1) {\n\t session.firstMultiple = false;\n\t }\n\t\n\t var firstInput = session.firstInput;\n\t var firstMultiple = session.firstMultiple;\n\t var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;\n\t\n\t var center = input.center = getCenter(pointers);\n\t input.timeStamp = now();\n\t input.deltaTime = input.timeStamp - firstInput.timeStamp;\n\t\n\t input.angle = getAngle(offsetCenter, center);\n\t input.distance = getDistance(offsetCenter, center);\n\t\n\t computeDeltaXY(session, input);\n\t input.offsetDirection = getDirection(input.deltaX, input.deltaY);\n\t\n\t var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);\n\t input.overallVelocityX = overallVelocity.x;\n\t input.overallVelocityY = overallVelocity.y;\n\t input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;\n\t\n\t input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;\n\t input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;\n\t\n\t input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >\n\t session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);\n\t\n\t computeIntervalInputData(session, input);\n\t\n\t // find the correct target\n\t var target = manager.element;\n\t if (hasParent(input.srcEvent.target, target)) {\n\t target = input.srcEvent.target;\n\t }\n\t input.target = target;\n\t}\n\t\n\tfunction computeDeltaXY(session, input) {\n\t var center = input.center;\n\t var offset = session.offsetDelta || {};\n\t var prevDelta = session.prevDelta || {};\n\t var prevInput = session.prevInput || {};\n\t\n\t if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {\n\t prevDelta = session.prevDelta = {\n\t x: prevInput.deltaX || 0,\n\t y: prevInput.deltaY || 0\n\t };\n\t\n\t offset = session.offsetDelta = {\n\t x: center.x,\n\t y: center.y\n\t };\n\t }\n\t\n\t input.deltaX = prevDelta.x + (center.x - offset.x);\n\t input.deltaY = prevDelta.y + (center.y - offset.y);\n\t}\n\t\n\t/**\n\t * velocity is calculated every x ms\n\t * @param {Object} session\n\t * @param {Object} input\n\t */\n\tfunction computeIntervalInputData(session, input) {\n\t var last = session.lastInterval || input,\n\t deltaTime = input.timeStamp - last.timeStamp,\n\t velocity, velocityX, velocityY, direction;\n\t\n\t if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {\n\t var deltaX = input.deltaX - last.deltaX;\n\t var deltaY = input.deltaY - last.deltaY;\n\t\n\t var v = getVelocity(deltaTime, deltaX, deltaY);\n\t velocityX = v.x;\n\t velocityY = v.y;\n\t velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;\n\t direction = getDirection(deltaX, deltaY);\n\t\n\t session.lastInterval = input;\n\t } else {\n\t // use latest velocity info if it doesn't overtake a minimum period\n\t velocity = last.velocity;\n\t velocityX = last.velocityX;\n\t velocityY = last.velocityY;\n\t direction = last.direction;\n\t }\n\t\n\t input.velocity = velocity;\n\t input.velocityX = velocityX;\n\t input.velocityY = velocityY;\n\t input.direction = direction;\n\t}\n\t\n\t/**\n\t * create a simple clone from the input used for storage of firstInput and firstMultiple\n\t * @param {Object} input\n\t * @returns {Object} clonedInputData\n\t */\n\tfunction simpleCloneInputData(input) {\n\t // make a simple copy of the pointers because we will get a reference if we don't\n\t // we only need clientXY for the calculations\n\t var pointers = [];\n\t var i = 0;\n\t while (i < input.pointers.length) {\n\t pointers[i] = {\n\t clientX: round(input.pointers[i].clientX),\n\t clientY: round(input.pointers[i].clientY)\n\t };\n\t i++;\n\t }\n\t\n\t return {\n\t timeStamp: now(),\n\t pointers: pointers,\n\t center: getCenter(pointers),\n\t deltaX: input.deltaX,\n\t deltaY: input.deltaY\n\t };\n\t}\n\t\n\t/**\n\t * get the center of all the pointers\n\t * @param {Array} pointers\n\t * @return {Object} center contains `x` and `y` properties\n\t */\n\tfunction getCenter(pointers) {\n\t var pointersLength = pointers.length;\n\t\n\t // no need to loop when only one touch\n\t if (pointersLength === 1) {\n\t return {\n\t x: round(pointers[0].clientX),\n\t y: round(pointers[0].clientY)\n\t };\n\t }\n\t\n\t var x = 0, y = 0, i = 0;\n\t while (i < pointersLength) {\n\t x += pointers[i].clientX;\n\t y += pointers[i].clientY;\n\t i++;\n\t }\n\t\n\t return {\n\t x: round(x / pointersLength),\n\t y: round(y / pointersLength)\n\t };\n\t}\n\t\n\t/**\n\t * calculate the velocity between two points. unit is in px per ms.\n\t * @param {Number} deltaTime\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @return {Object} velocity `x` and `y`\n\t */\n\tfunction getVelocity(deltaTime, x, y) {\n\t return {\n\t x: x / deltaTime || 0,\n\t y: y / deltaTime || 0\n\t };\n\t}\n\t\n\t/**\n\t * get the direction between two points\n\t * @param {Number} x\n\t * @param {Number} y\n\t * @return {Number} direction\n\t */\n\tfunction getDirection(x, y) {\n\t if (x === y) {\n\t return DIRECTION_NONE;\n\t }\n\t\n\t if (abs(x) >= abs(y)) {\n\t return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;\n\t }\n\t return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;\n\t}\n\t\n\t/**\n\t * calculate the absolute distance between two points\n\t * @param {Object} p1 {x, y}\n\t * @param {Object} p2 {x, y}\n\t * @param {Array} [props] containing x and y keys\n\t * @return {Number} distance\n\t */\n\tfunction getDistance(p1, p2, props) {\n\t if (!props) {\n\t props = PROPS_XY;\n\t }\n\t var x = p2[props[0]] - p1[props[0]],\n\t y = p2[props[1]] - p1[props[1]];\n\t\n\t return Math.sqrt((x * x) + (y * y));\n\t}\n\t\n\t/**\n\t * calculate the angle between two coordinates\n\t * @param {Object} p1\n\t * @param {Object} p2\n\t * @param {Array} [props] containing x and y keys\n\t * @return {Number} angle\n\t */\n\tfunction getAngle(p1, p2, props) {\n\t if (!props) {\n\t props = PROPS_XY;\n\t }\n\t var x = p2[props[0]] - p1[props[0]],\n\t y = p2[props[1]] - p1[props[1]];\n\t return Math.atan2(y, x) * 180 / Math.PI;\n\t}\n\t\n\t/**\n\t * calculate the rotation degrees between two pointersets\n\t * @param {Array} start array of pointers\n\t * @param {Array} end array of pointers\n\t * @return {Number} rotation\n\t */\n\tfunction getRotation(start, end) {\n\t return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);\n\t}\n\t\n\t/**\n\t * calculate the scale factor between two pointersets\n\t * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out\n\t * @param {Array} start array of pointers\n\t * @param {Array} end array of pointers\n\t * @return {Number} scale\n\t */\n\tfunction getScale(start, end) {\n\t return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);\n\t}\n\t\n\tvar MOUSE_INPUT_MAP = {\n\t mousedown: INPUT_START,\n\t mousemove: INPUT_MOVE,\n\t mouseup: INPUT_END\n\t};\n\t\n\tvar MOUSE_ELEMENT_EVENTS = 'mousedown';\n\tvar MOUSE_WINDOW_EVENTS = 'mousemove mouseup';\n\t\n\t/**\n\t * Mouse events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction MouseInput() {\n\t this.evEl = MOUSE_ELEMENT_EVENTS;\n\t this.evWin = MOUSE_WINDOW_EVENTS;\n\t\n\t this.pressed = false; // mousedown state\n\t\n\t Input.apply(this, arguments);\n\t}\n\t\n\tinherit(MouseInput, Input, {\n\t /**\n\t * handle mouse events\n\t * @param {Object} ev\n\t */\n\t handler: function MEhandler(ev) {\n\t var eventType = MOUSE_INPUT_MAP[ev.type];\n\t\n\t // on start we want to have the left mouse button down\n\t if (eventType & INPUT_START && ev.button === 0) {\n\t this.pressed = true;\n\t }\n\t\n\t if (eventType & INPUT_MOVE && ev.which !== 1) {\n\t eventType = INPUT_END;\n\t }\n\t\n\t // mouse must be down\n\t if (!this.pressed) {\n\t return;\n\t }\n\t\n\t if (eventType & INPUT_END) {\n\t this.pressed = false;\n\t }\n\t\n\t this.callback(this.manager, eventType, {\n\t pointers: [ev],\n\t changedPointers: [ev],\n\t pointerType: INPUT_TYPE_MOUSE,\n\t srcEvent: ev\n\t });\n\t }\n\t});\n\t\n\tvar POINTER_INPUT_MAP = {\n\t pointerdown: INPUT_START,\n\t pointermove: INPUT_MOVE,\n\t pointerup: INPUT_END,\n\t pointercancel: INPUT_CANCEL,\n\t pointerout: INPUT_CANCEL\n\t};\n\t\n\t// in IE10 the pointer types is defined as an enum\n\tvar IE10_POINTER_TYPE_ENUM = {\n\t 2: INPUT_TYPE_TOUCH,\n\t 3: INPUT_TYPE_PEN,\n\t 4: INPUT_TYPE_MOUSE,\n\t 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816\n\t};\n\t\n\tvar POINTER_ELEMENT_EVENTS = 'pointerdown';\n\tvar POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';\n\t\n\t// IE10 has prefixed support, and case-sensitive\n\tif (window.MSPointerEvent && !window.PointerEvent) {\n\t POINTER_ELEMENT_EVENTS = 'MSPointerDown';\n\t POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';\n\t}\n\t\n\t/**\n\t * Pointer events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction PointerEventInput() {\n\t this.evEl = POINTER_ELEMENT_EVENTS;\n\t this.evWin = POINTER_WINDOW_EVENTS;\n\t\n\t Input.apply(this, arguments);\n\t\n\t this.store = (this.manager.session.pointerEvents = []);\n\t}\n\t\n\tinherit(PointerEventInput, Input, {\n\t /**\n\t * handle mouse events\n\t * @param {Object} ev\n\t */\n\t handler: function PEhandler(ev) {\n\t var store = this.store;\n\t var removePointer = false;\n\t\n\t var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');\n\t var eventType = POINTER_INPUT_MAP[eventTypeNormalized];\n\t var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;\n\t\n\t var isTouch = (pointerType == INPUT_TYPE_TOUCH);\n\t\n\t // get index of the event in the store\n\t var storeIndex = inArray(store, ev.pointerId, 'pointerId');\n\t\n\t // start and mouse must be down\n\t if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {\n\t if (storeIndex < 0) {\n\t store.push(ev);\n\t storeIndex = store.length - 1;\n\t }\n\t } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n\t removePointer = true;\n\t }\n\t\n\t // it not found, so the pointer hasn't been down (so it's probably a hover)\n\t if (storeIndex < 0) {\n\t return;\n\t }\n\t\n\t // update the event in the store\n\t store[storeIndex] = ev;\n\t\n\t this.callback(this.manager, eventType, {\n\t pointers: store,\n\t changedPointers: [ev],\n\t pointerType: pointerType,\n\t srcEvent: ev\n\t });\n\t\n\t if (removePointer) {\n\t // remove from the store\n\t store.splice(storeIndex, 1);\n\t }\n\t }\n\t});\n\t\n\tvar SINGLE_TOUCH_INPUT_MAP = {\n\t touchstart: INPUT_START,\n\t touchmove: INPUT_MOVE,\n\t touchend: INPUT_END,\n\t touchcancel: INPUT_CANCEL\n\t};\n\t\n\tvar SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';\n\tvar SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';\n\t\n\t/**\n\t * Touch events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction SingleTouchInput() {\n\t this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;\n\t this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;\n\t this.started = false;\n\t\n\t Input.apply(this, arguments);\n\t}\n\t\n\tinherit(SingleTouchInput, Input, {\n\t handler: function TEhandler(ev) {\n\t var type = SINGLE_TOUCH_INPUT_MAP[ev.type];\n\t\n\t // should we handle the touch events?\n\t if (type === INPUT_START) {\n\t this.started = true;\n\t }\n\t\n\t if (!this.started) {\n\t return;\n\t }\n\t\n\t var touches = normalizeSingleTouches.call(this, ev, type);\n\t\n\t // when done, reset the started state\n\t if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {\n\t this.started = false;\n\t }\n\t\n\t this.callback(this.manager, type, {\n\t pointers: touches[0],\n\t changedPointers: touches[1],\n\t pointerType: INPUT_TYPE_TOUCH,\n\t srcEvent: ev\n\t });\n\t }\n\t});\n\t\n\t/**\n\t * @this {TouchInput}\n\t * @param {Object} ev\n\t * @param {Number} type flag\n\t * @returns {undefined|Array} [all, changed]\n\t */\n\tfunction normalizeSingleTouches(ev, type) {\n\t var all = toArray(ev.touches);\n\t var changed = toArray(ev.changedTouches);\n\t\n\t if (type & (INPUT_END | INPUT_CANCEL)) {\n\t all = uniqueArray(all.concat(changed), 'identifier', true);\n\t }\n\t\n\t return [all, changed];\n\t}\n\t\n\tvar TOUCH_INPUT_MAP = {\n\t touchstart: INPUT_START,\n\t touchmove: INPUT_MOVE,\n\t touchend: INPUT_END,\n\t touchcancel: INPUT_CANCEL\n\t};\n\t\n\tvar TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';\n\t\n\t/**\n\t * Multi-user touch events input\n\t * @constructor\n\t * @extends Input\n\t */\n\tfunction TouchInput() {\n\t this.evTarget = TOUCH_TARGET_EVENTS;\n\t this.targetIds = {};\n\t\n\t Input.apply(this, arguments);\n\t}\n\t\n\tinherit(TouchInput, Input, {\n\t handler: function MTEhandler(ev) {\n\t var type = TOUCH_INPUT_MAP[ev.type];\n\t var touches = getTouches.call(this, ev, type);\n\t if (!touches) {\n\t return;\n\t }\n\t\n\t this.callback(this.manager, type, {\n\t pointers: touches[0],\n\t changedPointers: touches[1],\n\t pointerType: INPUT_TYPE_TOUCH,\n\t srcEvent: ev\n\t });\n\t }\n\t});\n\t\n\t/**\n\t * @this {TouchInput}\n\t * @param {Object} ev\n\t * @param {Number} type flag\n\t * @returns {undefined|Array} [all, changed]\n\t */\n\tfunction getTouches(ev, type) {\n\t var allTouches = toArray(ev.touches);\n\t var targetIds = this.targetIds;\n\t\n\t // when there is only one touch, the process can be simplified\n\t if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {\n\t targetIds[allTouches[0].identifier] = true;\n\t return [allTouches, allTouches];\n\t }\n\t\n\t var i,\n\t targetTouches,\n\t changedTouches = toArray(ev.changedTouches),\n\t changedTargetTouches = [],\n\t target = this.target;\n\t\n\t // get target touches from touches\n\t targetTouches = allTouches.filter(function(touch) {\n\t return hasParent(touch.target, target);\n\t });\n\t\n\t // collect touches\n\t if (type === INPUT_START) {\n\t i = 0;\n\t while (i < targetTouches.length) {\n\t targetIds[targetTouches[i].identifier] = true;\n\t i++;\n\t }\n\t }\n\t\n\t // filter changed touches to only contain touches that exist in the collected target ids\n\t i = 0;\n\t while (i < changedTouches.length) {\n\t if (targetIds[changedTouches[i].identifier]) {\n\t changedTargetTouches.push(changedTouches[i]);\n\t }\n\t\n\t // cleanup removed touches\n\t if (type & (INPUT_END | INPUT_CANCEL)) {\n\t delete targetIds[changedTouches[i].identifier];\n\t }\n\t i++;\n\t }\n\t\n\t if (!changedTargetTouches.length) {\n\t return;\n\t }\n\t\n\t return [\n\t // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'\n\t uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),\n\t changedTargetTouches\n\t ];\n\t}\n\t\n\t/**\n\t * Combined touch and mouse input\n\t *\n\t * Touch has a higher priority then mouse, and while touching no mouse events are allowed.\n\t * This because touch devices also emit mouse events while doing a touch.\n\t *\n\t * @constructor\n\t * @extends Input\n\t */\n\t\n\tvar DEDUP_TIMEOUT = 2500;\n\tvar DEDUP_DISTANCE = 25;\n\t\n\tfunction TouchMouseInput() {\n\t Input.apply(this, arguments);\n\t\n\t var handler = bindFn(this.handler, this);\n\t this.touch = new TouchInput(this.manager, handler);\n\t this.mouse = new MouseInput(this.manager, handler);\n\t\n\t this.primaryTouch = null;\n\t this.lastTouches = [];\n\t}\n\t\n\tinherit(TouchMouseInput, Input, {\n\t /**\n\t * handle mouse and touch events\n\t * @param {Hammer} manager\n\t * @param {String} inputEvent\n\t * @param {Object} inputData\n\t */\n\t handler: function TMEhandler(manager, inputEvent, inputData) {\n\t var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),\n\t isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);\n\t\n\t if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {\n\t return;\n\t }\n\t\n\t // when we're in a touch event, record touches to de-dupe synthetic mouse event\n\t if (isTouch) {\n\t recordTouches.call(this, inputEvent, inputData);\n\t } else if (isMouse && isSyntheticEvent.call(this, inputData)) {\n\t return;\n\t }\n\t\n\t this.callback(manager, inputEvent, inputData);\n\t },\n\t\n\t /**\n\t * remove the event listeners\n\t */\n\t destroy: function destroy() {\n\t this.touch.destroy();\n\t this.mouse.destroy();\n\t }\n\t});\n\t\n\tfunction recordTouches(eventType, eventData) {\n\t if (eventType & INPUT_START) {\n\t this.primaryTouch = eventData.changedPointers[0].identifier;\n\t setLastTouch.call(this, eventData);\n\t } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n\t setLastTouch.call(this, eventData);\n\t }\n\t}\n\t\n\tfunction setLastTouch(eventData) {\n\t var touch = eventData.changedPointers[0];\n\t\n\t if (touch.identifier === this.primaryTouch) {\n\t var lastTouch = {x: touch.clientX, y: touch.clientY};\n\t this.lastTouches.push(lastTouch);\n\t var lts = this.lastTouches;\n\t var removeLastTouch = function() {\n\t var i = lts.indexOf(lastTouch);\n\t if (i > -1) {\n\t lts.splice(i, 1);\n\t }\n\t };\n\t setTimeout(removeLastTouch, DEDUP_TIMEOUT);\n\t }\n\t}\n\t\n\tfunction isSyntheticEvent(eventData) {\n\t var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;\n\t for (var i = 0; i < this.lastTouches.length; i++) {\n\t var t = this.lastTouches[i];\n\t var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n\t if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {\n\t return true;\n\t }\n\t }\n\t return false;\n\t}\n\t\n\tvar PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');\n\tvar NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;\n\t\n\t// magical touchAction value\n\tvar TOUCH_ACTION_COMPUTE = 'compute';\n\tvar TOUCH_ACTION_AUTO = 'auto';\n\tvar TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented\n\tvar TOUCH_ACTION_NONE = 'none';\n\tvar TOUCH_ACTION_PAN_X = 'pan-x';\n\tvar TOUCH_ACTION_PAN_Y = 'pan-y';\n\tvar TOUCH_ACTION_MAP = getTouchActionProps();\n\t\n\t/**\n\t * Touch Action\n\t * sets the touchAction property or uses the js alternative\n\t * @param {Manager} manager\n\t * @param {String} value\n\t * @constructor\n\t */\n\tfunction TouchAction(manager, value) {\n\t this.manager = manager;\n\t this.set(value);\n\t}\n\t\n\tTouchAction.prototype = {\n\t /**\n\t * set the touchAction value on the element or enable the polyfill\n\t * @param {String} value\n\t */\n\t set: function(value) {\n\t // find out the touch-action by the event handlers\n\t if (value == TOUCH_ACTION_COMPUTE) {\n\t value = this.compute();\n\t }\n\t\n\t if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {\n\t this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;\n\t }\n\t this.actions = value.toLowerCase().trim();\n\t },\n\t\n\t /**\n\t * just re-set the touchAction value\n\t */\n\t update: function() {\n\t this.set(this.manager.options.touchAction);\n\t },\n\t\n\t /**\n\t * compute the value for the touchAction property based on the recognizer's settings\n\t * @returns {String} value\n\t */\n\t compute: function() {\n\t var actions = [];\n\t each(this.manager.recognizers, function(recognizer) {\n\t if (boolOrFn(recognizer.options.enable, [recognizer])) {\n\t actions = actions.concat(recognizer.getTouchAction());\n\t }\n\t });\n\t return cleanTouchActions(actions.join(' '));\n\t },\n\t\n\t /**\n\t * this method is called on each input cycle and provides the preventing of the browser behavior\n\t * @param {Object} input\n\t */\n\t preventDefaults: function(input) {\n\t var srcEvent = input.srcEvent;\n\t var direction = input.offsetDirection;\n\t\n\t // if the touch action did prevented once this session\n\t if (this.manager.session.prevented) {\n\t srcEvent.preventDefault();\n\t return;\n\t }\n\t\n\t var actions = this.actions;\n\t var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];\n\t var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];\n\t var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];\n\t\n\t if (hasNone) {\n\t //do not prevent defaults if this is a tap gesture\n\t\n\t var isTapPointer = input.pointers.length === 1;\n\t var isTapMovement = input.distance < 2;\n\t var isTapTouchTime = input.deltaTime < 250;\n\t\n\t if (isTapPointer && isTapMovement && isTapTouchTime) {\n\t return;\n\t }\n\t }\n\t\n\t if (hasPanX && hasPanY) {\n\t // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent\n\t return;\n\t }\n\t\n\t if (hasNone ||\n\t (hasPanY && direction & DIRECTION_HORIZONTAL) ||\n\t (hasPanX && direction & DIRECTION_VERTICAL)) {\n\t return this.preventSrc(srcEvent);\n\t }\n\t },\n\t\n\t /**\n\t * call preventDefault to prevent the browser's default behavior (scrolling in most cases)\n\t * @param {Object} srcEvent\n\t */\n\t preventSrc: function(srcEvent) {\n\t this.manager.session.prevented = true;\n\t srcEvent.preventDefault();\n\t }\n\t};\n\t\n\t/**\n\t * when the touchActions are collected they are not a valid value, so we need to clean things up. *\n\t * @param {String} actions\n\t * @returns {*}\n\t */\n\tfunction cleanTouchActions(actions) {\n\t // none\n\t if (inStr(actions, TOUCH_ACTION_NONE)) {\n\t return TOUCH_ACTION_NONE;\n\t }\n\t\n\t var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);\n\t var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);\n\t\n\t // if both pan-x and pan-y are set (different recognizers\n\t // for different directions, e.g. horizontal pan but vertical swipe?)\n\t // we need none (as otherwise with pan-x pan-y combined none of these\n\t // recognizers will work, since the browser would handle all panning\n\t if (hasPanX && hasPanY) {\n\t return TOUCH_ACTION_NONE;\n\t }\n\t\n\t // pan-x OR pan-y\n\t if (hasPanX || hasPanY) {\n\t return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;\n\t }\n\t\n\t // manipulation\n\t if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {\n\t return TOUCH_ACTION_MANIPULATION;\n\t }\n\t\n\t return TOUCH_ACTION_AUTO;\n\t}\n\t\n\tfunction getTouchActionProps() {\n\t if (!NATIVE_TOUCH_ACTION) {\n\t return false;\n\t }\n\t var touchMap = {};\n\t var cssSupports = window.CSS && window.CSS.supports;\n\t ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {\n\t\n\t // If css.supports is not supported but there is native touch-action assume it supports\n\t // all values. This is the case for IE 10 and 11.\n\t touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;\n\t });\n\t return touchMap;\n\t}\n\t\n\t/**\n\t * Recognizer flow explained; *\n\t * All recognizers have the initial state of POSSIBLE when a input session starts.\n\t * The definition of a input session is from the first input until the last input, with all it's movement in it. *\n\t * Example session for mouse-input: mousedown -> mousemove -> mouseup\n\t *\n\t * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed\n\t * which determines with state it should be.\n\t *\n\t * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to\n\t * POSSIBLE to give it another change on the next cycle.\n\t *\n\t * Possible\n\t * |\n\t * +-----+---------------+\n\t * | |\n\t * +-----+-----+ |\n\t * | | |\n\t * Failed Cancelled |\n\t * +-------+------+\n\t * | |\n\t * Recognized Began\n\t * |\n\t * Changed\n\t * |\n\t * Ended/Recognized\n\t */\n\tvar STATE_POSSIBLE = 1;\n\tvar STATE_BEGAN = 2;\n\tvar STATE_CHANGED = 4;\n\tvar STATE_ENDED = 8;\n\tvar STATE_RECOGNIZED = STATE_ENDED;\n\tvar STATE_CANCELLED = 16;\n\tvar STATE_FAILED = 32;\n\t\n\t/**\n\t * Recognizer\n\t * Every recognizer needs to extend from this class.\n\t * @constructor\n\t * @param {Object} options\n\t */\n\tfunction Recognizer(options) {\n\t this.options = assign({}, this.defaults, options || {});\n\t\n\t this.id = uniqueId();\n\t\n\t this.manager = null;\n\t\n\t // default is enable true\n\t this.options.enable = ifUndefined(this.options.enable, true);\n\t\n\t this.state = STATE_POSSIBLE;\n\t\n\t this.simultaneous = {};\n\t this.requireFail = [];\n\t}\n\t\n\tRecognizer.prototype = {\n\t /**\n\t * @virtual\n\t * @type {Object}\n\t */\n\t defaults: {},\n\t\n\t /**\n\t * set options\n\t * @param {Object} options\n\t * @return {Recognizer}\n\t */\n\t set: function(options) {\n\t assign(this.options, options);\n\t\n\t // also update the touchAction, in case something changed about the directions/enabled state\n\t this.manager && this.manager.touchAction.update();\n\t return this;\n\t },\n\t\n\t /**\n\t * recognize simultaneous with an other recognizer.\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t recognizeWith: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {\n\t return this;\n\t }\n\t\n\t var simultaneous = this.simultaneous;\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t if (!simultaneous[otherRecognizer.id]) {\n\t simultaneous[otherRecognizer.id] = otherRecognizer;\n\t otherRecognizer.recognizeWith(this);\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * drop the simultaneous link. it doesnt remove the link on the other recognizer.\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t dropRecognizeWith: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {\n\t return this;\n\t }\n\t\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t delete this.simultaneous[otherRecognizer.id];\n\t return this;\n\t },\n\t\n\t /**\n\t * recognizer can only run when an other is failing\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t requireFailure: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {\n\t return this;\n\t }\n\t\n\t var requireFail = this.requireFail;\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t if (inArray(requireFail, otherRecognizer) === -1) {\n\t requireFail.push(otherRecognizer);\n\t otherRecognizer.requireFailure(this);\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * drop the requireFailure link. it does not remove the link on the other recognizer.\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Recognizer} this\n\t */\n\t dropRequireFailure: function(otherRecognizer) {\n\t if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {\n\t return this;\n\t }\n\t\n\t otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n\t var index = inArray(this.requireFail, otherRecognizer);\n\t if (index > -1) {\n\t this.requireFail.splice(index, 1);\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * has require failures boolean\n\t * @returns {boolean}\n\t */\n\t hasRequireFailures: function() {\n\t return this.requireFail.length > 0;\n\t },\n\t\n\t /**\n\t * if the recognizer can recognize simultaneous with an other recognizer\n\t * @param {Recognizer} otherRecognizer\n\t * @returns {Boolean}\n\t */\n\t canRecognizeWith: function(otherRecognizer) {\n\t return !!this.simultaneous[otherRecognizer.id];\n\t },\n\t\n\t /**\n\t * You should use `tryEmit` instead of `emit` directly to check\n\t * that all the needed recognizers has failed before emitting.\n\t * @param {Object} input\n\t */\n\t emit: function(input) {\n\t var self = this;\n\t var state = this.state;\n\t\n\t function emit(event) {\n\t self.manager.emit(event, input);\n\t }\n\t\n\t // 'panstart' and 'panmove'\n\t if (state < STATE_ENDED) {\n\t emit(self.options.event + stateStr(state));\n\t }\n\t\n\t emit(self.options.event); // simple 'eventName' events\n\t\n\t if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)\n\t emit(input.additionalEvent);\n\t }\n\t\n\t // panend and pancancel\n\t if (state >= STATE_ENDED) {\n\t emit(self.options.event + stateStr(state));\n\t }\n\t },\n\t\n\t /**\n\t * Check that all the require failure recognizers has failed,\n\t * if true, it emits a gesture event,\n\t * otherwise, setup the state to FAILED.\n\t * @param {Object} input\n\t */\n\t tryEmit: function(input) {\n\t if (this.canEmit()) {\n\t return this.emit(input);\n\t }\n\t // it's failing anyway\n\t this.state = STATE_FAILED;\n\t },\n\t\n\t /**\n\t * can we emit?\n\t * @returns {boolean}\n\t */\n\t canEmit: function() {\n\t var i = 0;\n\t while (i < this.requireFail.length) {\n\t if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {\n\t return false;\n\t }\n\t i++;\n\t }\n\t return true;\n\t },\n\t\n\t /**\n\t * update the recognizer\n\t * @param {Object} inputData\n\t */\n\t recognize: function(inputData) {\n\t // make a new copy of the inputData\n\t // so we can change the inputData without messing up the other recognizers\n\t var inputDataClone = assign({}, inputData);\n\t\n\t // is is enabled and allow recognizing?\n\t if (!boolOrFn(this.options.enable, [this, inputDataClone])) {\n\t this.reset();\n\t this.state = STATE_FAILED;\n\t return;\n\t }\n\t\n\t // reset when we've reached the end\n\t if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {\n\t this.state = STATE_POSSIBLE;\n\t }\n\t\n\t this.state = this.process(inputDataClone);\n\t\n\t // the recognizer has recognized a gesture\n\t // so trigger an event\n\t if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {\n\t this.tryEmit(inputDataClone);\n\t }\n\t },\n\t\n\t /**\n\t * return the state of the recognizer\n\t * the actual recognizing happens in this method\n\t * @virtual\n\t * @param {Object} inputData\n\t * @returns {Const} STATE\n\t */\n\t process: function(inputData) { }, // jshint ignore:line\n\t\n\t /**\n\t * return the preferred touch-action\n\t * @virtual\n\t * @returns {Array}\n\t */\n\t getTouchAction: function() { },\n\t\n\t /**\n\t * called when the gesture isn't allowed to recognize\n\t * like when another is being recognized or it is disabled\n\t * @virtual\n\t */\n\t reset: function() { }\n\t};\n\t\n\t/**\n\t * get a usable string, used as event postfix\n\t * @param {Const} state\n\t * @returns {String} state\n\t */\n\tfunction stateStr(state) {\n\t if (state & STATE_CANCELLED) {\n\t return 'cancel';\n\t } else if (state & STATE_ENDED) {\n\t return 'end';\n\t } else if (state & STATE_CHANGED) {\n\t return 'move';\n\t } else if (state & STATE_BEGAN) {\n\t return 'start';\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * direction cons to string\n\t * @param {Const} direction\n\t * @returns {String}\n\t */\n\tfunction directionStr(direction) {\n\t if (direction == DIRECTION_DOWN) {\n\t return 'down';\n\t } else if (direction == DIRECTION_UP) {\n\t return 'up';\n\t } else if (direction == DIRECTION_LEFT) {\n\t return 'left';\n\t } else if (direction == DIRECTION_RIGHT) {\n\t return 'right';\n\t }\n\t return '';\n\t}\n\t\n\t/**\n\t * get a recognizer by name if it is bound to a manager\n\t * @param {Recognizer|String} otherRecognizer\n\t * @param {Recognizer} recognizer\n\t * @returns {Recognizer}\n\t */\n\tfunction getRecognizerByNameIfManager(otherRecognizer, recognizer) {\n\t var manager = recognizer.manager;\n\t if (manager) {\n\t return manager.get(otherRecognizer);\n\t }\n\t return otherRecognizer;\n\t}\n\t\n\t/**\n\t * This recognizer is just used as a base for the simple attribute recognizers.\n\t * @constructor\n\t * @extends Recognizer\n\t */\n\tfunction AttrRecognizer() {\n\t Recognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(AttrRecognizer, Recognizer, {\n\t /**\n\t * @namespace\n\t * @memberof AttrRecognizer\n\t */\n\t defaults: {\n\t /**\n\t * @type {Number}\n\t * @default 1\n\t */\n\t pointers: 1\n\t },\n\t\n\t /**\n\t * Used to check if it the recognizer receives valid input, like input.distance > 10.\n\t * @memberof AttrRecognizer\n\t * @param {Object} input\n\t * @returns {Boolean} recognized\n\t */\n\t attrTest: function(input) {\n\t var optionPointers = this.options.pointers;\n\t return optionPointers === 0 || input.pointers.length === optionPointers;\n\t },\n\t\n\t /**\n\t * Process the input and return the state for the recognizer\n\t * @memberof AttrRecognizer\n\t * @param {Object} input\n\t * @returns {*} State\n\t */\n\t process: function(input) {\n\t var state = this.state;\n\t var eventType = input.eventType;\n\t\n\t var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);\n\t var isValid = this.attrTest(input);\n\t\n\t // on cancel input and we've recognized before, return STATE_CANCELLED\n\t if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {\n\t return state | STATE_CANCELLED;\n\t } else if (isRecognized || isValid) {\n\t if (eventType & INPUT_END) {\n\t return state | STATE_ENDED;\n\t } else if (!(state & STATE_BEGAN)) {\n\t return STATE_BEGAN;\n\t }\n\t return state | STATE_CHANGED;\n\t }\n\t return STATE_FAILED;\n\t }\n\t});\n\t\n\t/**\n\t * Pan\n\t * Recognized when the pointer is down and moved in the allowed direction.\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction PanRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t\n\t this.pX = null;\n\t this.pY = null;\n\t}\n\t\n\tinherit(PanRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PanRecognizer\n\t */\n\t defaults: {\n\t event: 'pan',\n\t threshold: 10,\n\t pointers: 1,\n\t direction: DIRECTION_ALL\n\t },\n\t\n\t getTouchAction: function() {\n\t var direction = this.options.direction;\n\t var actions = [];\n\t if (direction & DIRECTION_HORIZONTAL) {\n\t actions.push(TOUCH_ACTION_PAN_Y);\n\t }\n\t if (direction & DIRECTION_VERTICAL) {\n\t actions.push(TOUCH_ACTION_PAN_X);\n\t }\n\t return actions;\n\t },\n\t\n\t directionTest: function(input) {\n\t var options = this.options;\n\t var hasMoved = true;\n\t var distance = input.distance;\n\t var direction = input.direction;\n\t var x = input.deltaX;\n\t var y = input.deltaY;\n\t\n\t // lock to axis?\n\t if (!(direction & options.direction)) {\n\t if (options.direction & DIRECTION_HORIZONTAL) {\n\t direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;\n\t hasMoved = x != this.pX;\n\t distance = Math.abs(input.deltaX);\n\t } else {\n\t direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;\n\t hasMoved = y != this.pY;\n\t distance = Math.abs(input.deltaY);\n\t }\n\t }\n\t input.direction = direction;\n\t return hasMoved && distance > options.threshold && direction & options.direction;\n\t },\n\t\n\t attrTest: function(input) {\n\t return AttrRecognizer.prototype.attrTest.call(this, input) &&\n\t (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));\n\t },\n\t\n\t emit: function(input) {\n\t\n\t this.pX = input.deltaX;\n\t this.pY = input.deltaY;\n\t\n\t var direction = directionStr(input.direction);\n\t\n\t if (direction) {\n\t input.additionalEvent = this.options.event + direction;\n\t }\n\t this._super.emit.call(this, input);\n\t }\n\t});\n\t\n\t/**\n\t * Pinch\n\t * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction PinchRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(PinchRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PinchRecognizer\n\t */\n\t defaults: {\n\t event: 'pinch',\n\t threshold: 0,\n\t pointers: 2\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_NONE];\n\t },\n\t\n\t attrTest: function(input) {\n\t return this._super.attrTest.call(this, input) &&\n\t (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);\n\t },\n\t\n\t emit: function(input) {\n\t if (input.scale !== 1) {\n\t var inOut = input.scale < 1 ? 'in' : 'out';\n\t input.additionalEvent = this.options.event + inOut;\n\t }\n\t this._super.emit.call(this, input);\n\t }\n\t});\n\t\n\t/**\n\t * Press\n\t * Recognized when the pointer is down for x ms without any movement.\n\t * @constructor\n\t * @extends Recognizer\n\t */\n\tfunction PressRecognizer() {\n\t Recognizer.apply(this, arguments);\n\t\n\t this._timer = null;\n\t this._input = null;\n\t}\n\t\n\tinherit(PressRecognizer, Recognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PressRecognizer\n\t */\n\t defaults: {\n\t event: 'press',\n\t pointers: 1,\n\t time: 251, // minimal time of the pointer to be pressed\n\t threshold: 9 // a minimal movement is ok, but keep it low\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_AUTO];\n\t },\n\t\n\t process: function(input) {\n\t var options = this.options;\n\t var validPointers = input.pointers.length === options.pointers;\n\t var validMovement = input.distance < options.threshold;\n\t var validTime = input.deltaTime > options.time;\n\t\n\t this._input = input;\n\t\n\t // we only allow little movement\n\t // and we've reached an end event, so a tap is possible\n\t if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {\n\t this.reset();\n\t } else if (input.eventType & INPUT_START) {\n\t this.reset();\n\t this._timer = setTimeoutContext(function() {\n\t this.state = STATE_RECOGNIZED;\n\t this.tryEmit();\n\t }, options.time, this);\n\t } else if (input.eventType & INPUT_END) {\n\t return STATE_RECOGNIZED;\n\t }\n\t return STATE_FAILED;\n\t },\n\t\n\t reset: function() {\n\t clearTimeout(this._timer);\n\t },\n\t\n\t emit: function(input) {\n\t if (this.state !== STATE_RECOGNIZED) {\n\t return;\n\t }\n\t\n\t if (input && (input.eventType & INPUT_END)) {\n\t this.manager.emit(this.options.event + 'up', input);\n\t } else {\n\t this._input.timeStamp = now();\n\t this.manager.emit(this.options.event, this._input);\n\t }\n\t }\n\t});\n\t\n\t/**\n\t * Rotate\n\t * Recognized when two or more pointer are moving in a circular motion.\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction RotateRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(RotateRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof RotateRecognizer\n\t */\n\t defaults: {\n\t event: 'rotate',\n\t threshold: 0,\n\t pointers: 2\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_NONE];\n\t },\n\t\n\t attrTest: function(input) {\n\t return this._super.attrTest.call(this, input) &&\n\t (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);\n\t }\n\t});\n\t\n\t/**\n\t * Swipe\n\t * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.\n\t * @constructor\n\t * @extends AttrRecognizer\n\t */\n\tfunction SwipeRecognizer() {\n\t AttrRecognizer.apply(this, arguments);\n\t}\n\t\n\tinherit(SwipeRecognizer, AttrRecognizer, {\n\t /**\n\t * @namespace\n\t * @memberof SwipeRecognizer\n\t */\n\t defaults: {\n\t event: 'swipe',\n\t threshold: 10,\n\t velocity: 0.3,\n\t direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,\n\t pointers: 1\n\t },\n\t\n\t getTouchAction: function() {\n\t return PanRecognizer.prototype.getTouchAction.call(this);\n\t },\n\t\n\t attrTest: function(input) {\n\t var direction = this.options.direction;\n\t var velocity;\n\t\n\t if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {\n\t velocity = input.overallVelocity;\n\t } else if (direction & DIRECTION_HORIZONTAL) {\n\t velocity = input.overallVelocityX;\n\t } else if (direction & DIRECTION_VERTICAL) {\n\t velocity = input.overallVelocityY;\n\t }\n\t\n\t return this._super.attrTest.call(this, input) &&\n\t direction & input.offsetDirection &&\n\t input.distance > this.options.threshold &&\n\t input.maxPointers == this.options.pointers &&\n\t abs(velocity) > this.options.velocity && input.eventType & INPUT_END;\n\t },\n\t\n\t emit: function(input) {\n\t var direction = directionStr(input.offsetDirection);\n\t if (direction) {\n\t this.manager.emit(this.options.event + direction, input);\n\t }\n\t\n\t this.manager.emit(this.options.event, input);\n\t }\n\t});\n\t\n\t/**\n\t * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur\n\t * between the given interval and position. The delay option can be used to recognize multi-taps without firing\n\t * a single tap.\n\t *\n\t * The eventData from the emitted event contains the property `tapCount`, which contains the amount of\n\t * multi-taps being recognized.\n\t * @constructor\n\t * @extends Recognizer\n\t */\n\tfunction TapRecognizer() {\n\t Recognizer.apply(this, arguments);\n\t\n\t // previous time and center,\n\t // used for tap counting\n\t this.pTime = false;\n\t this.pCenter = false;\n\t\n\t this._timer = null;\n\t this._input = null;\n\t this.count = 0;\n\t}\n\t\n\tinherit(TapRecognizer, Recognizer, {\n\t /**\n\t * @namespace\n\t * @memberof PinchRecognizer\n\t */\n\t defaults: {\n\t event: 'tap',\n\t pointers: 1,\n\t taps: 1,\n\t interval: 300, // max time between the multi-tap taps\n\t time: 250, // max time of the pointer to be down (like finger on the screen)\n\t threshold: 9, // a minimal movement is ok, but keep it low\n\t posThreshold: 10 // a multi-tap can be a bit off the initial position\n\t },\n\t\n\t getTouchAction: function() {\n\t return [TOUCH_ACTION_MANIPULATION];\n\t },\n\t\n\t process: function(input) {\n\t var options = this.options;\n\t\n\t var validPointers = input.pointers.length === options.pointers;\n\t var validMovement = input.distance < options.threshold;\n\t var validTouchTime = input.deltaTime < options.time;\n\t\n\t this.reset();\n\t\n\t if ((input.eventType & INPUT_START) && (this.count === 0)) {\n\t return this.failTimeout();\n\t }\n\t\n\t // we only allow little movement\n\t // and we've reached an end event, so a tap is possible\n\t if (validMovement && validTouchTime && validPointers) {\n\t if (input.eventType != INPUT_END) {\n\t return this.failTimeout();\n\t }\n\t\n\t var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;\n\t var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;\n\t\n\t this.pTime = input.timeStamp;\n\t this.pCenter = input.center;\n\t\n\t if (!validMultiTap || !validInterval) {\n\t this.count = 1;\n\t } else {\n\t this.count += 1;\n\t }\n\t\n\t this._input = input;\n\t\n\t // if tap count matches we have recognized it,\n\t // else it has began recognizing...\n\t var tapCount = this.count % options.taps;\n\t if (tapCount === 0) {\n\t // no failing requirements, immediately trigger the tap event\n\t // or wait as long as the multitap interval to trigger\n\t if (!this.hasRequireFailures()) {\n\t return STATE_RECOGNIZED;\n\t } else {\n\t this._timer = setTimeoutContext(function() {\n\t this.state = STATE_RECOGNIZED;\n\t this.tryEmit();\n\t }, options.interval, this);\n\t return STATE_BEGAN;\n\t }\n\t }\n\t }\n\t return STATE_FAILED;\n\t },\n\t\n\t failTimeout: function() {\n\t this._timer = setTimeoutContext(function() {\n\t this.state = STATE_FAILED;\n\t }, this.options.interval, this);\n\t return STATE_FAILED;\n\t },\n\t\n\t reset: function() {\n\t clearTimeout(this._timer);\n\t },\n\t\n\t emit: function() {\n\t if (this.state == STATE_RECOGNIZED) {\n\t this._input.tapCount = this.count;\n\t this.manager.emit(this.options.event, this._input);\n\t }\n\t }\n\t});\n\t\n\t/**\n\t * Simple way to create a manager with a default set of recognizers.\n\t * @param {HTMLElement} element\n\t * @param {Object} [options]\n\t * @constructor\n\t */\n\tfunction Hammer(element, options) {\n\t options = options || {};\n\t options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);\n\t return new Manager(element, options);\n\t}\n\t\n\t/**\n\t * @const {string}\n\t */\n\tHammer.VERSION = '2.0.7';\n\t\n\t/**\n\t * default settings\n\t * @namespace\n\t */\n\tHammer.defaults = {\n\t /**\n\t * set if DOM events are being triggered.\n\t * But this is slower and unused by simple implementations, so disabled by default.\n\t * @type {Boolean}\n\t * @default false\n\t */\n\t domEvents: false,\n\t\n\t /**\n\t * The value for the touchAction property/fallback.\n\t * When set to `compute` it will magically set the correct value based on the added recognizers.\n\t * @type {String}\n\t * @default compute\n\t */\n\t touchAction: TOUCH_ACTION_COMPUTE,\n\t\n\t /**\n\t * @type {Boolean}\n\t * @default true\n\t */\n\t enable: true,\n\t\n\t /**\n\t * EXPERIMENTAL FEATURE -- can be removed/changed\n\t * Change the parent input target element.\n\t * If Null, then it is being set the to main element.\n\t * @type {Null|EventTarget}\n\t * @default null\n\t */\n\t inputTarget: null,\n\t\n\t /**\n\t * force an input class\n\t * @type {Null|Function}\n\t * @default null\n\t */\n\t inputClass: null,\n\t\n\t /**\n\t * Default recognizer setup when calling `Hammer()`\n\t * When creating a new Manager these will be skipped.\n\t * @type {Array}\n\t */\n\t preset: [\n\t // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]\n\t [RotateRecognizer, {enable: false}],\n\t [PinchRecognizer, {enable: false}, ['rotate']],\n\t [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],\n\t [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],\n\t [TapRecognizer],\n\t [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],\n\t [PressRecognizer]\n\t ],\n\t\n\t /**\n\t * Some CSS properties can be used to improve the working of Hammer.\n\t * Add them to this method and they will be set when creating a new Manager.\n\t * @namespace\n\t */\n\t cssProps: {\n\t /**\n\t * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t userSelect: 'none',\n\t\n\t /**\n\t * Disable the Windows Phone grippers when pressing an element.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t touchSelect: 'none',\n\t\n\t /**\n\t * Disables the default callout shown when you touch and hold a touch target.\n\t * On iOS, when you touch and hold a touch target such as a link, Safari displays\n\t * a callout containing information about the link. This property allows you to disable that callout.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t touchCallout: 'none',\n\t\n\t /**\n\t * Specifies whether zooming is enabled. Used by IE10>\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t contentZooming: 'none',\n\t\n\t /**\n\t * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.\n\t * @type {String}\n\t * @default 'none'\n\t */\n\t userDrag: 'none',\n\t\n\t /**\n\t * Overrides the highlight color shown when the user taps a link or a JavaScript\n\t * clickable element in iOS. This property obeys the alpha value, if specified.\n\t * @type {String}\n\t * @default 'rgba(0,0,0,0)'\n\t */\n\t tapHighlightColor: 'rgba(0,0,0,0)'\n\t }\n\t};\n\t\n\tvar STOP = 1;\n\tvar FORCED_STOP = 2;\n\t\n\t/**\n\t * Manager\n\t * @param {HTMLElement} element\n\t * @param {Object} [options]\n\t * @constructor\n\t */\n\tfunction Manager(element, options) {\n\t this.options = assign({}, Hammer.defaults, options || {});\n\t\n\t this.options.inputTarget = this.options.inputTarget || element;\n\t\n\t this.handlers = {};\n\t this.session = {};\n\t this.recognizers = [];\n\t this.oldCssProps = {};\n\t\n\t this.element = element;\n\t this.input = createInputInstance(this);\n\t this.touchAction = new TouchAction(this, this.options.touchAction);\n\t\n\t toggleCssProps(this, true);\n\t\n\t each(this.options.recognizers, function(item) {\n\t var recognizer = this.add(new (item[0])(item[1]));\n\t item[2] && recognizer.recognizeWith(item[2]);\n\t item[3] && recognizer.requireFailure(item[3]);\n\t }, this);\n\t}\n\t\n\tManager.prototype = {\n\t /**\n\t * set options\n\t * @param {Object} options\n\t * @returns {Manager}\n\t */\n\t set: function(options) {\n\t assign(this.options, options);\n\t\n\t // Options that need a little more setup\n\t if (options.touchAction) {\n\t this.touchAction.update();\n\t }\n\t if (options.inputTarget) {\n\t // Clean up existing event listeners and reinitialize\n\t this.input.destroy();\n\t this.input.target = options.inputTarget;\n\t this.input.init();\n\t }\n\t return this;\n\t },\n\t\n\t /**\n\t * stop recognizing for this session.\n\t * This session will be discarded, when a new [input]start event is fired.\n\t * When forced, the recognizer cycle is stopped immediately.\n\t * @param {Boolean} [force]\n\t */\n\t stop: function(force) {\n\t this.session.stopped = force ? FORCED_STOP : STOP;\n\t },\n\t\n\t /**\n\t * run the recognizers!\n\t * called by the inputHandler function on every movement of the pointers (touches)\n\t * it walks through all the recognizers and tries to detect the gesture that is being made\n\t * @param {Object} inputData\n\t */\n\t recognize: function(inputData) {\n\t var session = this.session;\n\t if (session.stopped) {\n\t return;\n\t }\n\t\n\t // run the touch-action polyfill\n\t this.touchAction.preventDefaults(inputData);\n\t\n\t var recognizer;\n\t var recognizers = this.recognizers;\n\t\n\t // this holds the recognizer that is being recognized.\n\t // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED\n\t // if no recognizer is detecting a thing, it is set to `null`\n\t var curRecognizer = session.curRecognizer;\n\t\n\t // reset when the last recognizer is recognized\n\t // or when we're in a new session\n\t if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {\n\t curRecognizer = session.curRecognizer = null;\n\t }\n\t\n\t var i = 0;\n\t while (i < recognizers.length) {\n\t recognizer = recognizers[i];\n\t\n\t // find out if we are allowed try to recognize the input for this one.\n\t // 1. allow if the session is NOT forced stopped (see the .stop() method)\n\t // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one\n\t // that is being recognized.\n\t // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.\n\t // this can be setup with the `recognizeWith()` method on the recognizer.\n\t if (session.stopped !== FORCED_STOP && ( // 1\n\t !curRecognizer || recognizer == curRecognizer || // 2\n\t recognizer.canRecognizeWith(curRecognizer))) { // 3\n\t recognizer.recognize(inputData);\n\t } else {\n\t recognizer.reset();\n\t }\n\t\n\t // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the\n\t // current active recognizer. but only if we don't already have an active recognizer\n\t if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {\n\t curRecognizer = session.curRecognizer = recognizer;\n\t }\n\t i++;\n\t }\n\t },\n\t\n\t /**\n\t * get a recognizer by its event name.\n\t * @param {Recognizer|String} recognizer\n\t * @returns {Recognizer|Null}\n\t */\n\t get: function(recognizer) {\n\t if (recognizer instanceof Recognizer) {\n\t return recognizer;\n\t }\n\t\n\t var recognizers = this.recognizers;\n\t for (var i = 0; i < recognizers.length; i++) {\n\t if (recognizers[i].options.event == recognizer) {\n\t return recognizers[i];\n\t }\n\t }\n\t return null;\n\t },\n\t\n\t /**\n\t * add a recognizer to the manager\n\t * existing recognizers with the same event name will be removed\n\t * @param {Recognizer} recognizer\n\t * @returns {Recognizer|Manager}\n\t */\n\t add: function(recognizer) {\n\t if (invokeArrayArg(recognizer, 'add', this)) {\n\t return this;\n\t }\n\t\n\t // remove existing\n\t var existing = this.get(recognizer.options.event);\n\t if (existing) {\n\t this.remove(existing);\n\t }\n\t\n\t this.recognizers.push(recognizer);\n\t recognizer.manager = this;\n\t\n\t this.touchAction.update();\n\t return recognizer;\n\t },\n\t\n\t /**\n\t * remove a recognizer by name or instance\n\t * @param {Recognizer|String} recognizer\n\t * @returns {Manager}\n\t */\n\t remove: function(recognizer) {\n\t if (invokeArrayArg(recognizer, 'remove', this)) {\n\t return this;\n\t }\n\t\n\t recognizer = this.get(recognizer);\n\t\n\t // let's make sure this recognizer exists\n\t if (recognizer) {\n\t var recognizers = this.recognizers;\n\t var index = inArray(recognizers, recognizer);\n\t\n\t if (index !== -1) {\n\t recognizers.splice(index, 1);\n\t this.touchAction.update();\n\t }\n\t }\n\t\n\t return this;\n\t },\n\t\n\t /**\n\t * bind event\n\t * @param {String} events\n\t * @param {Function} handler\n\t * @returns {EventEmitter} this\n\t */\n\t on: function(events, handler) {\n\t if (events === undefined) {\n\t return;\n\t }\n\t if (handler === undefined) {\n\t return;\n\t }\n\t\n\t var handlers = this.handlers;\n\t each(splitStr(events), function(event) {\n\t handlers[event] = handlers[event] || [];\n\t handlers[event].push(handler);\n\t });\n\t return this;\n\t },\n\t\n\t /**\n\t * unbind event, leave emit blank to remove all handlers\n\t * @param {String} events\n\t * @param {Function} [handler]\n\t * @returns {EventEmitter} this\n\t */\n\t off: function(events, handler) {\n\t if (events === undefined) {\n\t return;\n\t }\n\t\n\t var handlers = this.handlers;\n\t each(splitStr(events), function(event) {\n\t if (!handler) {\n\t delete handlers[event];\n\t } else {\n\t handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);\n\t }\n\t });\n\t return this;\n\t },\n\t\n\t /**\n\t * emit event to the listeners\n\t * @param {String} event\n\t * @param {Object} data\n\t */\n\t emit: function(event, data) {\n\t // we also want to trigger dom events\n\t if (this.options.domEvents) {\n\t triggerDomEvent(event, data);\n\t }\n\t\n\t // no handlers, so skip it all\n\t var handlers = this.handlers[event] && this.handlers[event].slice();\n\t if (!handlers || !handlers.length) {\n\t return;\n\t }\n\t\n\t data.type = event;\n\t data.preventDefault = function() {\n\t data.srcEvent.preventDefault();\n\t };\n\t\n\t var i = 0;\n\t while (i < handlers.length) {\n\t handlers[i](data);\n\t i++;\n\t }\n\t },\n\t\n\t /**\n\t * destroy the manager and unbinds all events\n\t * it doesn't unbind dom events, that is the user own responsibility\n\t */\n\t destroy: function() {\n\t this.element && toggleCssProps(this, false);\n\t\n\t this.handlers = {};\n\t this.session = {};\n\t this.input.destroy();\n\t this.element = null;\n\t }\n\t};\n\t\n\t/**\n\t * add/remove the css properties as defined in manager.options.cssProps\n\t * @param {Manager} manager\n\t * @param {Boolean} add\n\t */\n\tfunction toggleCssProps(manager, add) {\n\t var element = manager.element;\n\t if (!element.style) {\n\t return;\n\t }\n\t var prop;\n\t each(manager.options.cssProps, function(value, name) {\n\t prop = prefixed(element.style, name);\n\t if (add) {\n\t manager.oldCssProps[prop] = element.style[prop];\n\t element.style[prop] = value;\n\t } else {\n\t element.style[prop] = manager.oldCssProps[prop] || '';\n\t }\n\t });\n\t if (!add) {\n\t manager.oldCssProps = {};\n\t }\n\t}\n\t\n\t/**\n\t * trigger dom event\n\t * @param {String} event\n\t * @param {Object} data\n\t */\n\tfunction triggerDomEvent(event, data) {\n\t var gestureEvent = document.createEvent('Event');\n\t gestureEvent.initEvent(event, true, true);\n\t gestureEvent.gesture = data;\n\t data.target.dispatchEvent(gestureEvent);\n\t}\n\t\n\tassign(Hammer, {\n\t INPUT_START: INPUT_START,\n\t INPUT_MOVE: INPUT_MOVE,\n\t INPUT_END: INPUT_END,\n\t INPUT_CANCEL: INPUT_CANCEL,\n\t\n\t STATE_POSSIBLE: STATE_POSSIBLE,\n\t STATE_BEGAN: STATE_BEGAN,\n\t STATE_CHANGED: STATE_CHANGED,\n\t STATE_ENDED: STATE_ENDED,\n\t STATE_RECOGNIZED: STATE_RECOGNIZED,\n\t STATE_CANCELLED: STATE_CANCELLED,\n\t STATE_FAILED: STATE_FAILED,\n\t\n\t DIRECTION_NONE: DIRECTION_NONE,\n\t DIRECTION_LEFT: DIRECTION_LEFT,\n\t DIRECTION_RIGHT: DIRECTION_RIGHT,\n\t DIRECTION_UP: DIRECTION_UP,\n\t DIRECTION_DOWN: DIRECTION_DOWN,\n\t DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,\n\t DIRECTION_VERTICAL: DIRECTION_VERTICAL,\n\t DIRECTION_ALL: DIRECTION_ALL,\n\t\n\t Manager: Manager,\n\t Input: Input,\n\t TouchAction: TouchAction,\n\t\n\t TouchInput: TouchInput,\n\t MouseInput: MouseInput,\n\t PointerEventInput: PointerEventInput,\n\t TouchMouseInput: TouchMouseInput,\n\t SingleTouchInput: SingleTouchInput,\n\t\n\t Recognizer: Recognizer,\n\t AttrRecognizer: AttrRecognizer,\n\t Tap: TapRecognizer,\n\t Pan: PanRecognizer,\n\t Swipe: SwipeRecognizer,\n\t Pinch: PinchRecognizer,\n\t Rotate: RotateRecognizer,\n\t Press: PressRecognizer,\n\t\n\t on: addEventListeners,\n\t off: removeEventListeners,\n\t each: each,\n\t merge: merge,\n\t extend: extend,\n\t assign: assign,\n\t inherit: inherit,\n\t bindFn: bindFn,\n\t prefixed: prefixed\n\t});\n\t\n\t// this prevents errors when Hammer is loaded in the presence of an AMD\n\t// style loader but by script tag, not by the loader.\n\tvar freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line\n\tfreeGlobal.Hammer = Hammer;\n\t\n\tif (true) {\n\t !(__WEBPACK_AMD_DEFINE_RESULT__ = function() {\n\t return Hammer;\n\t }.call(exports, __webpack_require__, exports, module), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__));\n\t} else if (typeof module != 'undefined' && module.exports) {\n\t module.exports = Hammer;\n\t} else {\n\t window[exportName] = Hammer;\n\t}\n\t\n\t})(window, document, 'Hammer');\n\n\n/***/ },\n/* 53 */\n/***/ function(module, exports) {\n\n\tmodule.exports = __WEBPACK_EXTERNAL_MODULE_53__;\n\n/***/ },\n/* 54 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar LayerGroup = (function (_Layer) {\n\t _inherits(LayerGroup, _Layer);\n\t\n\t function LayerGroup(options) {\n\t _classCallCheck(this, LayerGroup);\n\t\n\t var defaults = {\n\t output: false\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(LayerGroup.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._layers = [];\n\t }\n\t\n\t _createClass(LayerGroup, [{\n\t key: 'addLayer',\n\t value: function addLayer(layer) {\n\t this._layers.push(layer);\n\t return this._world.addLayer(layer);\n\t }\n\t }, {\n\t key: 'removeLayer',\n\t value: function removeLayer(layer) {\n\t var layerIndex = this._layers.indexOf(layer);\n\t\n\t if (layerIndex > -1) {\n\t // Remove from this._layers\n\t this._layers.splice(layerIndex, 1);\n\t };\n\t\n\t this._world.removeLayer(layer);\n\t }\n\t }, {\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t return Promise.resolve(this);\n\t }\n\t\n\t // Destroy the layers and remove them from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // TODO: Sometimes this is already null, find out why\n\t if (this._layers) {\n\t for (var i = 0; i < this._layers.length; i++) {\n\t this._layers[i].destroy();\n\t }\n\t\n\t this._layers = null;\n\t }\n\t\n\t _get(Object.getPrototypeOf(LayerGroup.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return LayerGroup;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = LayerGroup;\n\t\n\tvar noNew = function noNew(options) {\n\t return new LayerGroup(options);\n\t};\n\t\n\texports.layerGroup = noNew;\n\n/***/ },\n/* 55 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _TileLayer2 = __webpack_require__(56);\n\t\n\tvar _TileLayer3 = _interopRequireDefault(_TileLayer2);\n\t\n\tvar _ImageTile = __webpack_require__(66);\n\t\n\tvar _ImageTile2 = _interopRequireDefault(_ImageTile);\n\t\n\tvar _ImageTileLayerBaseMaterial = __webpack_require__(69);\n\t\n\tvar _ImageTileLayerBaseMaterial2 = _interopRequireDefault(_ImageTileLayerBaseMaterial);\n\t\n\tvar _lodashThrottle = __webpack_require__(22);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// DONE: Find a way to avoid the flashing caused by the gap between old tiles\n\t// being removed and the new tiles being ready for display\n\t//\n\t// DONE: Simplest first step for MVP would be to give each tile mesh the colour\n\t// of the basemap ground so it blends in a little more, or have a huge ground\n\t// plane underneath all the tiles that shows through between tile updates.\n\t//\n\t// Could keep the old tiles around until the new ones are ready, though they'd\n\t// probably need to be layered in a way so the old tiles don't overlap new ones,\n\t// which is similar to how Leaflet approaches this (it has 2 layers)\n\t//\n\t// Could keep the tile from the previous quadtree level visible until all 4\n\t// tiles at the new / current level have finished loading and are displayed.\n\t// Perhaps by keeping a map of tiles by quadcode and a boolean for each of the\n\t// child quadcodes showing whether they are loaded and in view. If all true then\n\t// remove the parent tile, otherwise keep it on a lower layer.\n\t\n\t// TODO: Load and display a base layer separate to the LOD grid that is at a low\n\t// resolution – used as a backup / background to fill in empty areas / distance\n\t\n\t// DONE: Fix the issue where some tiles just don't load, or at least the texture\n\t// never shows up – tends to happen if you quickly zoom in / out past it while\n\t// it's still loading, leaving a blank space\n\t\n\t// TODO: Optimise the request of many image tiles – look at how Leaflet and\n\t// OpenWebGlobe approach this (eg. batching, queues, etc)\n\t\n\t// TODO: Cancel pending tile requests if they get removed from view before they\n\t// reach a ready state (eg. cancel image requests, etc). Need to ensure that the\n\t// images are re-requested when the tile is next in scene (even if from cache)\n\t\n\t// TODO: Consider not performing an LOD calculation on every frame, instead only\n\t// on move end so panning, orbiting and zooming stays smooth. Otherwise it's\n\t// possible for performance to tank if you pan, orbit or zoom rapidly while all\n\t// the LOD calculations are being made and new tiles requested.\n\t//\n\t// Pending tiles should continue to be requested and output to the scene on each\n\t// frame, but no new LOD calculations should be made.\n\t\n\t// This tile layer both updates the quadtree and outputs tiles on every frame\n\t// (throttled to some amount)\n\t//\n\t// This is because the computational complexity of image tiles is generally low\n\t// and so there isn't much jank when running these calculations and outputs in\n\t// realtime\n\t//\n\t// The benefit to doing this is that the underlying map layer continues to\n\t// refresh and update during movement, which is an arguably better experience\n\t\n\tvar ImageTileLayer = (function (_TileLayer) {\n\t _inherits(ImageTileLayer, _TileLayer);\n\t\n\t function ImageTileLayer(path, options) {\n\t _classCallCheck(this, ImageTileLayer);\n\t\n\t var defaults = {\n\t distance: 300000\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(ImageTileLayer.prototype), 'constructor', this).call(this, options);\n\t\n\t this._path = path;\n\t }\n\t\n\t _createClass(ImageTileLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _get(Object.getPrototypeOf(ImageTileLayer.prototype), '_onAdd', _this).call(_this, world).then(function () {\n\t // TODO: Removed because it causes depth buffer intersection issues\n\t // with layer on top for some reason. Need to work out why and fix.\n\t //\n\t // Add base layer\n\t // var geom = new THREE.PlaneBufferGeometry(2000000, 2000000, 1);\n\t\n\t // var baseMaterial;\n\t // if (this._world._environment._skybox) {\n\t // baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3', this._world._environment._skybox.getRenderTarget());\n\t // } else {\n\t // baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3');\n\t // }\n\t\n\t // var mesh = new THREE.Mesh(geom, baseMaterial);\n\t\n\t // // Setting this causes a depth-buffer intersection issue on the\n\t // // all-the-things example\n\t // // mesh.renderOrder = -1;\n\t\n\t // mesh.rotation.x = -90 * Math.PI / 180;\n\t\n\t // // TODO: It might be overkill to receive a shadow on the base layer as it's\n\t // // rarely seen (good to have if performance difference is negligible)\n\t // mesh.receiveShadow = true;\n\t\n\t // this._baseLayer = mesh;\n\t // this.add(mesh);\n\t\n\t // Trigger initial quadtree calculation on the next frame\n\t //\n\t // TODO: This is a hack to ensure the camera is all set up - a better\n\t // solution should be found\n\t setTimeout(function () {\n\t _this._calculateLOD();\n\t _this._initEvents();\n\t }, 0);\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t // Run LOD calculations based on render calls\n\t //\n\t // Throttled to 1 LOD calculation per 100ms\n\t this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._onWorldUpdate, 100);\n\t\n\t this._world.on('preUpdate', this._throttledWorldUpdate, this);\n\t // this._world.on('move', this._onWorldMove, this);\n\t }\n\t }, {\n\t key: '_onWorldUpdate',\n\t value: function _onWorldUpdate() {\n\t this._calculateLOD();\n\t this._outputTiles();\n\t }\n\t }, {\n\t key: '_onWorldMove',\n\t value: function _onWorldMove(latlon, point) {\n\t this._moveBaseLayer(point);\n\t }\n\t }, {\n\t key: '_moveBaseLayer',\n\t value: function _moveBaseLayer(point) {\n\t this._baseLayer.position.x = point.x;\n\t this._baseLayer.position.z = point.y;\n\t }\n\t }, {\n\t key: '_createTile',\n\t value: function _createTile(quadcode, layer) {\n\t return new _ImageTile2['default'](quadcode, this._path, layer);\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._world.off('preUpdate', this._throttledWorldUpdate);\n\t this._world.off('move', this._onWorldMove);\n\t\n\t this._throttledWorldUpdate = null;\n\t\n\t // Dispose of mesh and materials\n\t this._baseLayer.geometry.dispose();\n\t this._baseLayer.geometry = null;\n\t\n\t if (this._baseLayer.material.map) {\n\t this._baseLayer.material.map.dispose();\n\t this._baseLayer.material.map = null;\n\t }\n\t\n\t this._baseLayer.material.dispose();\n\t this._baseLayer.material = null;\n\t\n\t this._baseLayer = null;\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(ImageTileLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return ImageTileLayer;\n\t})(_TileLayer3['default']);\n\t\n\texports['default'] = ImageTileLayer;\n\t\n\tvar noNew = function noNew(path, options) {\n\t return new ImageTileLayer(path, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.imageTileLayer = noNew;\n\n/***/ },\n/* 56 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _TileCache = __webpack_require__(57);\n\t\n\tvar _TileCache2 = _interopRequireDefault(_TileCache);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Consider removing picking from TileLayer instances as there aren't\n\t// (m)any situations where it would be practical\n\t//\n\t// For example, how would you even know what picking IDs to listen to and what\n\t// to do with them?\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Consider keeping a single TileLayer / LOD instance running by default\n\t// that keeps a standard LOD grid for other layers to utilise, rather than\n\t// having to create their own, unique LOD grid and duplicate calculations when\n\t// they're going to use the same grid setup anyway\n\t//\n\t// It still makes sense to be able to have a custom LOD grid for some layers as\n\t// they may want to customise things, maybe not even using a quadtree at all!\n\t//\n\t// Perhaps it makes sense to split out the quadtree stuff into a singleton and\n\t// pass in the necessary parameters each time for the calculation step.\n\t//\n\t// Either way, it seems silly to force layers to have to create a new LOD grid\n\t// each time and create extra, duplicated processing every frame.\n\t\n\t// TODO: Allow passing in of options to define min/max LOD and a distance to use\n\t// for culling tiles beyond that distance.\n\t\n\t// DONE: Prevent tiles from being loaded if they are further than a certain\n\t// distance from the camera and are unlikely to be seen anyway\n\t\n\t// TODO: Avoid performing LOD calculation when it isn't required. For example,\n\t// when nothing has changed since the last frame and there are no tiles to be\n\t// loaded or in need of rendering\n\t\n\t// TODO: Only remove tiles from the layer that aren't to be rendered in the\n\t// current frame – it seems excessive to remove all tiles and re-add them on\n\t// every single frame, even if it's just array manipulation\n\t\n\t// TODO: Fix LOD calculation so min and max LOD can be changed without causing\n\t// problems (eg. making min above 5 causes all sorts of issues)\n\t\n\t// TODO: Reuse THREE objects where possible instead of creating new instances\n\t// on every LOD calculation\n\t\n\t// TODO: Consider not using THREE or LatLon / Point objects in LOD calculations\n\t// to avoid creating unnecessary memory for garbage collection\n\t\n\t// TODO: Prioritise loading of tiles at highest level in the quadtree (those\n\t// closest to the camera) so visual inconsistancies during loading are minimised\n\t\n\tvar TileLayer = (function (_Layer) {\n\t _inherits(TileLayer, _Layer);\n\t\n\t function TileLayer(options) {\n\t var _this = this;\n\t\n\t _classCallCheck(this, TileLayer);\n\t\n\t var defaults = {\n\t picking: false,\n\t maxCache: 1000,\n\t maxLOD: 18\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TileLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._destroy = false;\n\t\n\t this._tileCache = new _TileCache2['default'](this._options.maxCache, function (tile) {\n\t _this._destroyTile(tile);\n\t });\n\t\n\t // List of tiles from the previous LOD calculation\n\t this._tileList = [];\n\t\n\t // TODO: Work out why changing the minLOD causes loads of issues\n\t this._minLOD = 3;\n\t this._maxLOD = this._options.maxLOD;\n\t\n\t this._frustum = new _three2['default'].Frustum();\n\t this._tiles = new _three2['default'].Object3D();\n\t this._tilesPicking = new _three2['default'].Object3D();\n\t }\n\t\n\t _createClass(TileLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t this.addToPicking(this._tilesPicking);\n\t this.add(this._tiles);\n\t\n\t return Promise.resolve();\n\t }\n\t }, {\n\t key: '_updateFrustum',\n\t value: function _updateFrustum() {\n\t var camera = this._world.getCamera();\n\t var projScreenMatrix = new _three2['default'].Matrix4();\n\t projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n\t\n\t this._frustum.setFromMatrix(camera.projectionMatrix);\n\t this._frustum.setFromMatrix(new _three2['default'].Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n\t }\n\t }, {\n\t key: '_tileInFrustum',\n\t value: function _tileInFrustum(tile) {\n\t var bounds = tile.getBounds();\n\t return this._frustum.intersectsBox(new _three2['default'].Box3(new _three2['default'].Vector3(bounds[0], 0, bounds[3]), new _three2['default'].Vector3(bounds[2], 0, bounds[1])));\n\t }\n\t\n\t // Update and output tiles from the previous LOD checklist\n\t }, {\n\t key: '_outputTiles',\n\t value: function _outputTiles() {\n\t var _this2 = this;\n\t\n\t if (!this._tiles || this._destroy) {\n\t return;\n\t }\n\t\n\t // Remove all tiles from layer\n\t this._removeTiles();\n\t\n\t // Add / re-add tiles\n\t this._tileList.forEach(function (tile) {\n\t // Are the mesh and texture ready?\n\t //\n\t // If yes, continue\n\t // If no, skip\n\t if (!tile.isReady()) {\n\t return;\n\t }\n\t\n\t // Add tile to layer (and to scene) if not already there\n\t _this2._tiles.add(tile.getMesh());\n\t\n\t if (tile.getPickingMesh()) {\n\t _this2._tilesPicking.add(tile.getPickingMesh());\n\t }\n\t });\n\t\n\t // Emit event notifying of new tiles\n\t this.emit('tilesList', this._tileList.map(function (tile) {\n\t return tile;\n\t }));\n\t }\n\t\n\t // Works out tiles in the view frustum and stores them in an array\n\t //\n\t // Does not output the tiles, deferring this to _outputTiles()\n\t }, {\n\t key: '_calculateLOD',\n\t value: function _calculateLOD() {\n\t var _this3 = this;\n\t\n\t if (this._stop || !this._world || this._destroy) {\n\t return;\n\t }\n\t\n\t // var start = performance.now();\n\t\n\t var camera = this._world.getCamera();\n\t\n\t // 1. Update and retrieve camera frustum\n\t this._updateFrustum(this._frustum, camera);\n\t\n\t // 2. Add the four root items of the quadtree to a check list\n\t var checkList = this._checklist;\n\t checkList = [];\n\t checkList.push(this._requestTile('0', this));\n\t checkList.push(this._requestTile('1', this));\n\t checkList.push(this._requestTile('2', this));\n\t checkList.push(this._requestTile('3', this));\n\t\n\t // 3. Call Divide, passing in the check list\n\t this._divide(checkList);\n\t\n\t // // 4. Remove all tiles from layer\n\t //\n\t // Moved to _outputTiles() for now\n\t // this._removeTiles();\n\t\n\t // Order tile-list by zoom so nearest tiles are requested first\n\t checkList.sort(function (a, b) {\n\t return a._quadcode.length < b._quadcode.length;\n\t });\n\t\n\t // 5. Filter the tiles remaining in the check list\n\t var tileList = checkList.filter(function (tile, index) {\n\t // Skip tile if it's not in the current view frustum\n\t if (!_this3._tileInFrustum(tile)) {\n\t return false;\n\t }\n\t\n\t if (_this3._options.distance && _this3._options.distance > 0) {\n\t // TODO: Can probably speed this up\n\t var center = tile.getCenter();\n\t var dist = new _three2['default'].Vector3(center[0], 0, center[1]).sub(camera.position).length();\n\t\n\t // Manual distance limit to cut down on tiles so far away\n\t if (dist > _this3._options.distance) {\n\t return false;\n\t }\n\t }\n\t\n\t // Does the tile have a mesh?\n\t //\n\t // If yes, continue\n\t // If no, generate tile mesh, request texture and skip\n\t if (!tile.getMesh() || tile.isAborted()) {\n\t tile.requestTileAsync();\n\t }\n\t\n\t return true;\n\t\n\t // Are the mesh and texture ready?\n\t //\n\t // If yes, continue\n\t // If no, skip\n\t // if (!tile.isReady()) {\n\t // return;\n\t // }\n\t //\n\t // // Add tile to layer (and to scene)\n\t // this._tiles.add(tile.getMesh());\n\t });\n\t\n\t // Get list of tiles that were in the previous update but not the\n\t // current one (for aborting requests, etc)\n\t var missingTiles = this._tileList.filter(function (item) {\n\t return !tileList.includes(item);\n\t });\n\t\n\t // Abort tiles that are no longer in view\n\t missingTiles.forEach(function (tile) {\n\t return tile._abortRequest();\n\t });\n\t\n\t this._tileList = tileList;\n\t\n\t // console.log(performance.now() - start);\n\t }\n\t }, {\n\t key: '_divide',\n\t value: function _divide(checkList) {\n\t var count = 0;\n\t var currentItem;\n\t var quadcode;\n\t\n\t // 1. Loop until count equals check list length\n\t while (count != checkList.length) {\n\t currentItem = checkList[count];\n\t quadcode = currentItem.getQuadcode();\n\t\n\t // 2. Increase count and continue loop if quadcode equals max LOD / zoom\n\t if (currentItem.length === this._maxLOD) {\n\t count++;\n\t continue;\n\t }\n\t\n\t // 3. Else, calculate screen-space error metric for quadcode\n\t if (this._screenSpaceError(currentItem)) {\n\t // 4. If error is sufficient...\n\t\n\t // 4a. Remove parent item from the check list\n\t checkList.splice(count, 1);\n\t\n\t // 4b. Add 4 child items to the check list\n\t checkList.push(this._requestTile(quadcode + '0', this));\n\t checkList.push(this._requestTile(quadcode + '1', this));\n\t checkList.push(this._requestTile(quadcode + '2', this));\n\t checkList.push(this._requestTile(quadcode + '3', this));\n\t\n\t // 4d. Continue the loop without increasing count\n\t continue;\n\t } else {\n\t // 5. Else, increase count and continue loop\n\t count++;\n\t }\n\t }\n\t }\n\t }, {\n\t key: '_screenSpaceError',\n\t value: function _screenSpaceError(tile) {\n\t var minDepth = this._minLOD;\n\t var maxDepth = this._maxLOD;\n\t\n\t var quadcode = tile.getQuadcode();\n\t\n\t var camera = this._world.getCamera();\n\t\n\t // Tweak this value to refine specific point that each quad is subdivided\n\t //\n\t // It's used to multiple the dimensions of the tile sides before\n\t // comparing against the tile distance from camera\n\t var quality = 3.0;\n\t\n\t // 1. Return false if quadcode length equals maxDepth (stop dividing)\n\t if (quadcode.length === maxDepth) {\n\t return false;\n\t }\n\t\n\t // 2. Return true if quadcode length is less than minDepth\n\t if (quadcode.length < minDepth) {\n\t return true;\n\t }\n\t\n\t // 3. Return false if quadcode bounds are not in view frustum\n\t if (!this._tileInFrustum(tile)) {\n\t return false;\n\t }\n\t\n\t var center = tile.getCenter();\n\t\n\t // 4. Calculate screen-space error metric\n\t // TODO: Use closest distance to one of the 4 tile corners\n\t var dist = new _three2['default'].Vector3(center[0], 0, center[1]).sub(camera.position).length();\n\t\n\t var error = quality * tile.getSide() / dist;\n\t\n\t // 5. Return true if error is greater than 1.0, else return false\n\t return error > 1.0;\n\t }\n\t }, {\n\t key: '_removeTiles',\n\t value: function _removeTiles() {\n\t if (!this._tiles || !this._tiles.children) {\n\t return;\n\t }\n\t\n\t for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n\t this._tiles.remove(this._tiles.children[i]);\n\t }\n\t\n\t if (!this._tilesPicking || !this._tilesPicking.children) {\n\t return;\n\t }\n\t\n\t for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n\t this._tilesPicking.remove(this._tilesPicking.children[i]);\n\t }\n\t }\n\t\n\t // Return a new tile instance\n\t }, {\n\t key: '_createTile',\n\t value: function _createTile(quadcode, layer) {}\n\t\n\t // Get a cached tile or request a new one if not in cache\n\t }, {\n\t key: '_requestTile',\n\t value: function _requestTile(quadcode, layer) {\n\t var tile = this._tileCache.getTile(quadcode);\n\t\n\t if (!tile) {\n\t // Set up a brand new tile\n\t tile = this._createTile(quadcode, layer);\n\t\n\t // Add tile to cache, though it won't be ready yet as the data is being\n\t // requested from various places asynchronously\n\t this._tileCache.setTile(quadcode, tile);\n\t }\n\t\n\t return tile;\n\t }\n\t }, {\n\t key: '_destroyTile',\n\t value: function _destroyTile(tile) {\n\t // Remove tile from scene\n\t this._tiles.remove(tile.getMesh());\n\t\n\t // Delete any references to the tile within this component\n\t\n\t // Call destory on tile instance\n\t tile.destroy();\n\t }\n\t }, {\n\t key: 'show',\n\t value: function show() {\n\t this._stop = false;\n\t\n\t if (this._tilesPicking) {\n\t this._tilesPicking.visible = true;\n\t }\n\t\n\t this._calculateLOD();\n\t _get(Object.getPrototypeOf(TileLayer.prototype), 'show', this).call(this);\n\t }\n\t }, {\n\t key: 'hide',\n\t value: function hide() {\n\t this._stop = true;\n\t\n\t if (this._tilesPicking) {\n\t this._tilesPicking.visible = false;\n\t }\n\t\n\t _get(Object.getPrototypeOf(TileLayer.prototype), 'hide', this).call(this);\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._destroy = true;\n\t\n\t if (this._tiles.children) {\n\t // Remove all tiles\n\t for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n\t this._tiles.remove(this._tiles.children[i]);\n\t }\n\t }\n\t\n\t // Remove tile from picking scene\n\t this.removeFromPicking(this._tilesPicking);\n\t\n\t if (this._tilesPicking.children) {\n\t // Remove all tiles\n\t for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n\t this._tilesPicking.remove(this._tilesPicking.children[i]);\n\t }\n\t }\n\t\n\t this._tileCache.destroy();\n\t this._tileCache = null;\n\t\n\t this._tiles = null;\n\t this._tilesPicking = null;\n\t this._frustum = null;\n\t\n\t _get(Object.getPrototypeOf(TileLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return TileLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = TileLayer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 57 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _lruCache = __webpack_require__(58);\n\t\n\tvar _lruCache2 = _interopRequireDefault(_lruCache);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// This process is based on a similar approach taken by OpenWebGlobe\n\t// See: https://github.com/OpenWebGlobe/WebViewer/blob/master/source/core/globecache.js\n\t\n\tvar TileCache = (function () {\n\t function TileCache(cacheLimit, onDestroyTile) {\n\t _classCallCheck(this, TileCache);\n\t\n\t this._cache = (0, _lruCache2['default'])({\n\t max: cacheLimit,\n\t dispose: function dispose(key, tile) {\n\t onDestroyTile(tile);\n\t }\n\t });\n\t }\n\t\n\t // Returns true if all specified tile providers are ready to be used\n\t // Otherwise, returns false\n\t\n\t _createClass(TileCache, [{\n\t key: 'isReady',\n\t value: function isReady() {\n\t return false;\n\t }\n\t\n\t // Get a cached tile without requesting a new one\n\t }, {\n\t key: 'getTile',\n\t value: function getTile(quadcode) {\n\t return this._cache.get(quadcode);\n\t }\n\t\n\t // Add tile to cache\n\t }, {\n\t key: 'setTile',\n\t value: function setTile(quadcode, tile) {\n\t this._cache.set(quadcode, tile);\n\t }\n\t\n\t // Destroy the cache and remove it from memory\n\t //\n\t // TODO: Call destroy method on items in cache\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._cache.reset();\n\t this._cache = null;\n\t }\n\t }]);\n\t\n\t return TileCache;\n\t})();\n\t\n\texports['default'] = TileCache;\n\t\n\tvar noNew = function noNew(cacheLimit, onDestroyTile) {\n\t return new TileCache(cacheLimit, onDestroyTile);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.tileCache = noNew;\n\n/***/ },\n/* 58 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tmodule.exports = LRUCache\n\t\n\t// This will be a proper iterable 'Map' in engines that support it,\n\t// or a fakey-fake PseudoMap in older versions.\n\tvar Map = __webpack_require__(59)\n\tvar util = __webpack_require__(62)\n\t\n\t// A linked list to keep track of recently-used-ness\n\tvar Yallist = __webpack_require__(65)\n\t\n\t// use symbols if possible, otherwise just _props\n\tvar symbols = {}\n\tvar hasSymbol = typeof Symbol === 'function'\n\tvar makeSymbol\n\t/* istanbul ignore if */\n\tif (hasSymbol) {\n\t makeSymbol = function (key) {\n\t return Symbol.for(key)\n\t }\n\t} else {\n\t makeSymbol = function (key) {\n\t return '_' + key\n\t }\n\t}\n\t\n\tfunction priv (obj, key, val) {\n\t var sym\n\t if (symbols[key]) {\n\t sym = symbols[key]\n\t } else {\n\t sym = makeSymbol(key)\n\t symbols[key] = sym\n\t }\n\t if (arguments.length === 2) {\n\t return obj[sym]\n\t } else {\n\t obj[sym] = val\n\t return val\n\t }\n\t}\n\t\n\tfunction naiveLength () { return 1 }\n\t\n\t// lruList is a yallist where the head is the youngest\n\t// item, and the tail is the oldest. the list contains the Hit\n\t// objects as the entries.\n\t// Each Hit object has a reference to its Yallist.Node. This\n\t// never changes.\n\t//\n\t// cache is a Map (or PseudoMap) that matches the keys to\n\t// the Yallist.Node object.\n\tfunction LRUCache (options) {\n\t if (!(this instanceof LRUCache)) {\n\t return new LRUCache(options)\n\t }\n\t\n\t if (typeof options === 'number') {\n\t options = { max: options }\n\t }\n\t\n\t if (!options) {\n\t options = {}\n\t }\n\t\n\t var max = priv(this, 'max', options.max)\n\t // Kind of weird to have a default max of Infinity, but oh well.\n\t if (!max ||\n\t !(typeof max === 'number') ||\n\t max <= 0) {\n\t priv(this, 'max', Infinity)\n\t }\n\t\n\t var lc = options.length || naiveLength\n\t if (typeof lc !== 'function') {\n\t lc = naiveLength\n\t }\n\t priv(this, 'lengthCalculator', lc)\n\t\n\t priv(this, 'allowStale', options.stale || false)\n\t priv(this, 'maxAge', options.maxAge || 0)\n\t priv(this, 'dispose', options.dispose)\n\t this.reset()\n\t}\n\t\n\t// resize the cache when the max changes.\n\tObject.defineProperty(LRUCache.prototype, 'max', {\n\t set: function (mL) {\n\t if (!mL || !(typeof mL === 'number') || mL <= 0) {\n\t mL = Infinity\n\t }\n\t priv(this, 'max', mL)\n\t trim(this)\n\t },\n\t get: function () {\n\t return priv(this, 'max')\n\t },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'allowStale', {\n\t set: function (allowStale) {\n\t priv(this, 'allowStale', !!allowStale)\n\t },\n\t get: function () {\n\t return priv(this, 'allowStale')\n\t },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'maxAge', {\n\t set: function (mA) {\n\t if (!mA || !(typeof mA === 'number') || mA < 0) {\n\t mA = 0\n\t }\n\t priv(this, 'maxAge', mA)\n\t trim(this)\n\t },\n\t get: function () {\n\t return priv(this, 'maxAge')\n\t },\n\t enumerable: true\n\t})\n\t\n\t// resize the cache when the lengthCalculator changes.\n\tObject.defineProperty(LRUCache.prototype, 'lengthCalculator', {\n\t set: function (lC) {\n\t if (typeof lC !== 'function') {\n\t lC = naiveLength\n\t }\n\t if (lC !== priv(this, 'lengthCalculator')) {\n\t priv(this, 'lengthCalculator', lC)\n\t priv(this, 'length', 0)\n\t priv(this, 'lruList').forEach(function (hit) {\n\t hit.length = priv(this, 'lengthCalculator').call(this, hit.value, hit.key)\n\t priv(this, 'length', priv(this, 'length') + hit.length)\n\t }, this)\n\t }\n\t trim(this)\n\t },\n\t get: function () { return priv(this, 'lengthCalculator') },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'length', {\n\t get: function () { return priv(this, 'length') },\n\t enumerable: true\n\t})\n\t\n\tObject.defineProperty(LRUCache.prototype, 'itemCount', {\n\t get: function () { return priv(this, 'lruList').length },\n\t enumerable: true\n\t})\n\t\n\tLRUCache.prototype.rforEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = priv(this, 'lruList').tail; walker !== null;) {\n\t var prev = walker.prev\n\t forEachStep(this, fn, walker, thisp)\n\t walker = prev\n\t }\n\t}\n\t\n\tfunction forEachStep (self, fn, node, thisp) {\n\t var hit = node.value\n\t if (isStale(self, hit)) {\n\t del(self, node)\n\t if (!priv(self, 'allowStale')) {\n\t hit = undefined\n\t }\n\t }\n\t if (hit) {\n\t fn.call(thisp, hit.value, hit.key, self)\n\t }\n\t}\n\t\n\tLRUCache.prototype.forEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = priv(this, 'lruList').head; walker !== null;) {\n\t var next = walker.next\n\t forEachStep(this, fn, walker, thisp)\n\t walker = next\n\t }\n\t}\n\t\n\tLRUCache.prototype.keys = function () {\n\t return priv(this, 'lruList').toArray().map(function (k) {\n\t return k.key\n\t }, this)\n\t}\n\t\n\tLRUCache.prototype.values = function () {\n\t return priv(this, 'lruList').toArray().map(function (k) {\n\t return k.value\n\t }, this)\n\t}\n\t\n\tLRUCache.prototype.reset = function () {\n\t if (priv(this, 'dispose') &&\n\t priv(this, 'lruList') &&\n\t priv(this, 'lruList').length) {\n\t priv(this, 'lruList').forEach(function (hit) {\n\t priv(this, 'dispose').call(this, hit.key, hit.value)\n\t }, this)\n\t }\n\t\n\t priv(this, 'cache', new Map()) // hash of items by key\n\t priv(this, 'lruList', new Yallist()) // list of items in order of use recency\n\t priv(this, 'length', 0) // length of items in the list\n\t}\n\t\n\tLRUCache.prototype.dump = function () {\n\t return priv(this, 'lruList').map(function (hit) {\n\t if (!isStale(this, hit)) {\n\t return {\n\t k: hit.key,\n\t v: hit.value,\n\t e: hit.now + (hit.maxAge || 0)\n\t }\n\t }\n\t }, this).toArray().filter(function (h) {\n\t return h\n\t })\n\t}\n\t\n\tLRUCache.prototype.dumpLru = function () {\n\t return priv(this, 'lruList')\n\t}\n\t\n\tLRUCache.prototype.inspect = function (n, opts) {\n\t var str = 'LRUCache {'\n\t var extras = false\n\t\n\t var as = priv(this, 'allowStale')\n\t if (as) {\n\t str += '\\n allowStale: true'\n\t extras = true\n\t }\n\t\n\t var max = priv(this, 'max')\n\t if (max && max !== Infinity) {\n\t if (extras) {\n\t str += ','\n\t }\n\t str += '\\n max: ' + util.inspect(max, opts)\n\t extras = true\n\t }\n\t\n\t var maxAge = priv(this, 'maxAge')\n\t if (maxAge) {\n\t if (extras) {\n\t str += ','\n\t }\n\t str += '\\n maxAge: ' + util.inspect(maxAge, opts)\n\t extras = true\n\t }\n\t\n\t var lc = priv(this, 'lengthCalculator')\n\t if (lc && lc !== naiveLength) {\n\t if (extras) {\n\t str += ','\n\t }\n\t str += '\\n length: ' + util.inspect(priv(this, 'length'), opts)\n\t extras = true\n\t }\n\t\n\t var didFirst = false\n\t priv(this, 'lruList').forEach(function (item) {\n\t if (didFirst) {\n\t str += ',\\n '\n\t } else {\n\t if (extras) {\n\t str += ',\\n'\n\t }\n\t didFirst = true\n\t str += '\\n '\n\t }\n\t var key = util.inspect(item.key).split('\\n').join('\\n ')\n\t var val = { value: item.value }\n\t if (item.maxAge !== maxAge) {\n\t val.maxAge = item.maxAge\n\t }\n\t if (lc !== naiveLength) {\n\t val.length = item.length\n\t }\n\t if (isStale(this, item)) {\n\t val.stale = true\n\t }\n\t\n\t val = util.inspect(val, opts).split('\\n').join('\\n ')\n\t str += key + ' => ' + val\n\t })\n\t\n\t if (didFirst || extras) {\n\t str += '\\n'\n\t }\n\t str += '}'\n\t\n\t return str\n\t}\n\t\n\tLRUCache.prototype.set = function (key, value, maxAge) {\n\t maxAge = maxAge || priv(this, 'maxAge')\n\t\n\t var now = maxAge ? Date.now() : 0\n\t var len = priv(this, 'lengthCalculator').call(this, value, key)\n\t\n\t if (priv(this, 'cache').has(key)) {\n\t if (len > priv(this, 'max')) {\n\t del(this, priv(this, 'cache').get(key))\n\t return false\n\t }\n\t\n\t var node = priv(this, 'cache').get(key)\n\t var item = node.value\n\t\n\t // dispose of the old one before overwriting\n\t if (priv(this, 'dispose')) {\n\t priv(this, 'dispose').call(this, key, item.value)\n\t }\n\t\n\t item.now = now\n\t item.maxAge = maxAge\n\t item.value = value\n\t priv(this, 'length', priv(this, 'length') + (len - item.length))\n\t item.length = len\n\t this.get(key)\n\t trim(this)\n\t return true\n\t }\n\t\n\t var hit = new Entry(key, value, len, now, maxAge)\n\t\n\t // oversized objects fall out of cache automatically.\n\t if (hit.length > priv(this, 'max')) {\n\t if (priv(this, 'dispose')) {\n\t priv(this, 'dispose').call(this, key, value)\n\t }\n\t return false\n\t }\n\t\n\t priv(this, 'length', priv(this, 'length') + hit.length)\n\t priv(this, 'lruList').unshift(hit)\n\t priv(this, 'cache').set(key, priv(this, 'lruList').head)\n\t trim(this)\n\t return true\n\t}\n\t\n\tLRUCache.prototype.has = function (key) {\n\t if (!priv(this, 'cache').has(key)) return false\n\t var hit = priv(this, 'cache').get(key).value\n\t if (isStale(this, hit)) {\n\t return false\n\t }\n\t return true\n\t}\n\t\n\tLRUCache.prototype.get = function (key) {\n\t return get(this, key, true)\n\t}\n\t\n\tLRUCache.prototype.peek = function (key) {\n\t return get(this, key, false)\n\t}\n\t\n\tLRUCache.prototype.pop = function () {\n\t var node = priv(this, 'lruList').tail\n\t if (!node) return null\n\t del(this, node)\n\t return node.value\n\t}\n\t\n\tLRUCache.prototype.del = function (key) {\n\t del(this, priv(this, 'cache').get(key))\n\t}\n\t\n\tLRUCache.prototype.load = function (arr) {\n\t // reset the cache\n\t this.reset()\n\t\n\t var now = Date.now()\n\t // A previous serialized cache has the most recent items first\n\t for (var l = arr.length - 1; l >= 0; l--) {\n\t var hit = arr[l]\n\t var expiresAt = hit.e || 0\n\t if (expiresAt === 0) {\n\t // the item was created without expiration in a non aged cache\n\t this.set(hit.k, hit.v)\n\t } else {\n\t var maxAge = expiresAt - now\n\t // dont add already expired items\n\t if (maxAge > 0) {\n\t this.set(hit.k, hit.v, maxAge)\n\t }\n\t }\n\t }\n\t}\n\t\n\tLRUCache.prototype.prune = function () {\n\t var self = this\n\t priv(this, 'cache').forEach(function (value, key) {\n\t get(self, key, false)\n\t })\n\t}\n\t\n\tfunction get (self, key, doUse) {\n\t var node = priv(self, 'cache').get(key)\n\t if (node) {\n\t var hit = node.value\n\t if (isStale(self, hit)) {\n\t del(self, node)\n\t if (!priv(self, 'allowStale')) hit = undefined\n\t } else {\n\t if (doUse) {\n\t priv(self, 'lruList').unshiftNode(node)\n\t }\n\t }\n\t if (hit) hit = hit.value\n\t }\n\t return hit\n\t}\n\t\n\tfunction isStale (self, hit) {\n\t if (!hit || (!hit.maxAge && !priv(self, 'maxAge'))) {\n\t return false\n\t }\n\t var stale = false\n\t var diff = Date.now() - hit.now\n\t if (hit.maxAge) {\n\t stale = diff > hit.maxAge\n\t } else {\n\t stale = priv(self, 'maxAge') && (diff > priv(self, 'maxAge'))\n\t }\n\t return stale\n\t}\n\t\n\tfunction trim (self) {\n\t if (priv(self, 'length') > priv(self, 'max')) {\n\t for (var walker = priv(self, 'lruList').tail;\n\t priv(self, 'length') > priv(self, 'max') && walker !== null;) {\n\t // We know that we're about to delete this one, and also\n\t // what the next least recently used key will be, so just\n\t // go ahead and set it now.\n\t var prev = walker.prev\n\t del(self, walker)\n\t walker = prev\n\t }\n\t }\n\t}\n\t\n\tfunction del (self, node) {\n\t if (node) {\n\t var hit = node.value\n\t if (priv(self, 'dispose')) {\n\t priv(self, 'dispose').call(this, hit.key, hit.value)\n\t }\n\t priv(self, 'length', priv(self, 'length') - hit.length)\n\t priv(self, 'cache').delete(hit.key)\n\t priv(self, 'lruList').removeNode(node)\n\t }\n\t}\n\t\n\t// classy, since V8 prefers predictable objects.\n\tfunction Entry (key, value, length, now, maxAge) {\n\t this.key = key\n\t this.value = value\n\t this.length = length\n\t this.now = now\n\t this.maxAge = maxAge || 0\n\t}\n\n\n/***/ },\n/* 59 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(process) {if (process.env.npm_package_name === 'pseudomap' &&\n\t process.env.npm_lifecycle_script === 'test')\n\t process.env.TEST_PSEUDOMAP = 'true'\n\t\n\tif (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) {\n\t module.exports = Map\n\t} else {\n\t module.exports = __webpack_require__(61)\n\t}\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, __webpack_require__(60)))\n\n/***/ },\n/* 60 */\n/***/ function(module, exports) {\n\n\t// shim for using process in browser\n\t\n\tvar process = module.exports = {};\n\t\n\t// cached from whatever global is present so that test runners that stub it\n\t// don't break things. But we need to wrap it in a try catch in case it is\n\t// wrapped in strict mode code which doesn't define any globals. It's inside a\n\t// function because try/catches deoptimize in certain engines.\n\t\n\tvar cachedSetTimeout;\n\tvar cachedClearTimeout;\n\t\n\t(function () {\n\t try {\n\t cachedSetTimeout = setTimeout;\n\t } catch (e) {\n\t cachedSetTimeout = function () {\n\t throw new Error('setTimeout is not defined');\n\t }\n\t }\n\t try {\n\t cachedClearTimeout = clearTimeout;\n\t } catch (e) {\n\t cachedClearTimeout = function () {\n\t throw new Error('clearTimeout is not defined');\n\t }\n\t }\n\t} ())\n\tvar queue = [];\n\tvar draining = false;\n\tvar currentQueue;\n\tvar queueIndex = -1;\n\t\n\tfunction cleanUpNextTick() {\n\t if (!draining || !currentQueue) {\n\t return;\n\t }\n\t draining = false;\n\t if (currentQueue.length) {\n\t queue = currentQueue.concat(queue);\n\t } else {\n\t queueIndex = -1;\n\t }\n\t if (queue.length) {\n\t drainQueue();\n\t }\n\t}\n\t\n\tfunction drainQueue() {\n\t if (draining) {\n\t return;\n\t }\n\t var timeout = cachedSetTimeout(cleanUpNextTick);\n\t draining = true;\n\t\n\t var len = queue.length;\n\t while(len) {\n\t currentQueue = queue;\n\t queue = [];\n\t while (++queueIndex < len) {\n\t if (currentQueue) {\n\t currentQueue[queueIndex].run();\n\t }\n\t }\n\t queueIndex = -1;\n\t len = queue.length;\n\t }\n\t currentQueue = null;\n\t draining = false;\n\t cachedClearTimeout(timeout);\n\t}\n\t\n\tprocess.nextTick = function (fun) {\n\t var args = new Array(arguments.length - 1);\n\t if (arguments.length > 1) {\n\t for (var i = 1; i < arguments.length; i++) {\n\t args[i - 1] = arguments[i];\n\t }\n\t }\n\t queue.push(new Item(fun, args));\n\t if (queue.length === 1 && !draining) {\n\t cachedSetTimeout(drainQueue, 0);\n\t }\n\t};\n\t\n\t// v8 likes predictible objects\n\tfunction Item(fun, array) {\n\t this.fun = fun;\n\t this.array = array;\n\t}\n\tItem.prototype.run = function () {\n\t this.fun.apply(null, this.array);\n\t};\n\tprocess.title = 'browser';\n\tprocess.browser = true;\n\tprocess.env = {};\n\tprocess.argv = [];\n\tprocess.version = ''; // empty string to avoid regexp issues\n\tprocess.versions = {};\n\t\n\tfunction noop() {}\n\t\n\tprocess.on = noop;\n\tprocess.addListener = noop;\n\tprocess.once = noop;\n\tprocess.off = noop;\n\tprocess.removeListener = noop;\n\tprocess.removeAllListeners = noop;\n\tprocess.emit = noop;\n\t\n\tprocess.binding = function (name) {\n\t throw new Error('process.binding is not supported');\n\t};\n\t\n\tprocess.cwd = function () { return '/' };\n\tprocess.chdir = function (dir) {\n\t throw new Error('process.chdir is not supported');\n\t};\n\tprocess.umask = function() { return 0; };\n\n\n/***/ },\n/* 61 */\n/***/ function(module, exports) {\n\n\tvar hasOwnProperty = Object.prototype.hasOwnProperty\n\t\n\tmodule.exports = PseudoMap\n\t\n\tfunction PseudoMap (set) {\n\t if (!(this instanceof PseudoMap)) // whyyyyyyy\n\t throw new TypeError(\"Constructor PseudoMap requires 'new'\")\n\t\n\t this.clear()\n\t\n\t if (set) {\n\t if ((set instanceof PseudoMap) ||\n\t (typeof Map === 'function' && set instanceof Map))\n\t set.forEach(function (value, key) {\n\t this.set(key, value)\n\t }, this)\n\t else if (Array.isArray(set))\n\t set.forEach(function (kv) {\n\t this.set(kv[0], kv[1])\n\t }, this)\n\t else\n\t throw new TypeError('invalid argument')\n\t }\n\t}\n\t\n\tPseudoMap.prototype.forEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t Object.keys(this._data).forEach(function (k) {\n\t if (k !== 'size')\n\t fn.call(thisp, this._data[k].value, this._data[k].key)\n\t }, this)\n\t}\n\t\n\tPseudoMap.prototype.has = function (k) {\n\t return !!find(this._data, k)\n\t}\n\t\n\tPseudoMap.prototype.get = function (k) {\n\t var res = find(this._data, k)\n\t return res && res.value\n\t}\n\t\n\tPseudoMap.prototype.set = function (k, v) {\n\t set(this._data, k, v)\n\t}\n\t\n\tPseudoMap.prototype.delete = function (k) {\n\t var res = find(this._data, k)\n\t if (res) {\n\t delete this._data[res._index]\n\t this._data.size--\n\t }\n\t}\n\t\n\tPseudoMap.prototype.clear = function () {\n\t var data = Object.create(null)\n\t data.size = 0\n\t\n\t Object.defineProperty(this, '_data', {\n\t value: data,\n\t enumerable: false,\n\t configurable: true,\n\t writable: false\n\t })\n\t}\n\t\n\tObject.defineProperty(PseudoMap.prototype, 'size', {\n\t get: function () {\n\t return this._data.size\n\t },\n\t set: function (n) {},\n\t enumerable: true,\n\t configurable: true\n\t})\n\t\n\tPseudoMap.prototype.values =\n\tPseudoMap.prototype.keys =\n\tPseudoMap.prototype.entries = function () {\n\t throw new Error('iterators are not implemented in this version')\n\t}\n\t\n\t// Either identical, or both NaN\n\tfunction same (a, b) {\n\t return a === b || a !== a && b !== b\n\t}\n\t\n\tfunction Entry (k, v, i) {\n\t this.key = k\n\t this.value = v\n\t this._index = i\n\t}\n\t\n\tfunction find (data, k) {\n\t for (var i = 0, s = '_' + k, key = s;\n\t hasOwnProperty.call(data, key);\n\t key = s + i++) {\n\t if (same(data[key].key, k))\n\t return data[key]\n\t }\n\t}\n\t\n\tfunction set (data, k, v) {\n\t for (var i = 0, s = '_' + k, key = s;\n\t hasOwnProperty.call(data, key);\n\t key = s + i++) {\n\t if (same(data[key].key, k)) {\n\t data[key].value = v\n\t return\n\t }\n\t }\n\t data.size++\n\t data[key] = new Entry(k, v, key)\n\t}\n\n\n/***/ },\n/* 62 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t/* WEBPACK VAR INJECTION */(function(global, process) {// Copyright Joyent, Inc. and other Node contributors.\n\t//\n\t// Permission is hereby granted, free of charge, to any person obtaining a\n\t// copy of this software and associated documentation files (the\n\t// \"Software\"), to deal in the Software without restriction, including\n\t// without limitation the rights to use, copy, modify, merge, publish,\n\t// distribute, sublicense, and/or sell copies of the Software, and to permit\n\t// persons to whom the Software is furnished to do so, subject to the\n\t// following conditions:\n\t//\n\t// The above copyright notice and this permission notice shall be included\n\t// in all copies or substantial portions of the Software.\n\t//\n\t// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n\t// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n\t// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n\t// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n\t// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n\t// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n\t// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\t\n\tvar formatRegExp = /%[sdj%]/g;\n\texports.format = function(f) {\n\t if (!isString(f)) {\n\t var objects = [];\n\t for (var i = 0; i < arguments.length; i++) {\n\t objects.push(inspect(arguments[i]));\n\t }\n\t return objects.join(' ');\n\t }\n\t\n\t var i = 1;\n\t var args = arguments;\n\t var len = args.length;\n\t var str = String(f).replace(formatRegExp, function(x) {\n\t if (x === '%%') return '%';\n\t if (i >= len) return x;\n\t switch (x) {\n\t case '%s': return String(args[i++]);\n\t case '%d': return Number(args[i++]);\n\t case '%j':\n\t try {\n\t return JSON.stringify(args[i++]);\n\t } catch (_) {\n\t return '[Circular]';\n\t }\n\t default:\n\t return x;\n\t }\n\t });\n\t for (var x = args[i]; i < len; x = args[++i]) {\n\t if (isNull(x) || !isObject(x)) {\n\t str += ' ' + x;\n\t } else {\n\t str += ' ' + inspect(x);\n\t }\n\t }\n\t return str;\n\t};\n\t\n\t\n\t// Mark that a method should not be used.\n\t// Returns a modified function which warns once by default.\n\t// If --no-deprecation is set, then it is a no-op.\n\texports.deprecate = function(fn, msg) {\n\t // Allow for deprecating things in the process of starting up.\n\t if (isUndefined(global.process)) {\n\t return function() {\n\t return exports.deprecate(fn, msg).apply(this, arguments);\n\t };\n\t }\n\t\n\t if (process.noDeprecation === true) {\n\t return fn;\n\t }\n\t\n\t var warned = false;\n\t function deprecated() {\n\t if (!warned) {\n\t if (process.throwDeprecation) {\n\t throw new Error(msg);\n\t } else if (process.traceDeprecation) {\n\t console.trace(msg);\n\t } else {\n\t console.error(msg);\n\t }\n\t warned = true;\n\t }\n\t return fn.apply(this, arguments);\n\t }\n\t\n\t return deprecated;\n\t};\n\t\n\t\n\tvar debugs = {};\n\tvar debugEnviron;\n\texports.debuglog = function(set) {\n\t if (isUndefined(debugEnviron))\n\t debugEnviron = process.env.NODE_DEBUG || '';\n\t set = set.toUpperCase();\n\t if (!debugs[set]) {\n\t if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n\t var pid = process.pid;\n\t debugs[set] = function() {\n\t var msg = exports.format.apply(exports, arguments);\n\t console.error('%s %d: %s', set, pid, msg);\n\t };\n\t } else {\n\t debugs[set] = function() {};\n\t }\n\t }\n\t return debugs[set];\n\t};\n\t\n\t\n\t/**\n\t * Echos the value of a value. Trys to print the value out\n\t * in the best way possible given the different types.\n\t *\n\t * @param {Object} obj The object to print out.\n\t * @param {Object} opts Optional options object that alters the output.\n\t */\n\t/* legacy: obj, showHidden, depth, colors*/\n\tfunction inspect(obj, opts) {\n\t // default options\n\t var ctx = {\n\t seen: [],\n\t stylize: stylizeNoColor\n\t };\n\t // legacy...\n\t if (arguments.length >= 3) ctx.depth = arguments[2];\n\t if (arguments.length >= 4) ctx.colors = arguments[3];\n\t if (isBoolean(opts)) {\n\t // legacy...\n\t ctx.showHidden = opts;\n\t } else if (opts) {\n\t // got an \"options\" object\n\t exports._extend(ctx, opts);\n\t }\n\t // set default options\n\t if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n\t if (isUndefined(ctx.depth)) ctx.depth = 2;\n\t if (isUndefined(ctx.colors)) ctx.colors = false;\n\t if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n\t if (ctx.colors) ctx.stylize = stylizeWithColor;\n\t return formatValue(ctx, obj, ctx.depth);\n\t}\n\texports.inspect = inspect;\n\t\n\t\n\t// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\n\tinspect.colors = {\n\t 'bold' : [1, 22],\n\t 'italic' : [3, 23],\n\t 'underline' : [4, 24],\n\t 'inverse' : [7, 27],\n\t 'white' : [37, 39],\n\t 'grey' : [90, 39],\n\t 'black' : [30, 39],\n\t 'blue' : [34, 39],\n\t 'cyan' : [36, 39],\n\t 'green' : [32, 39],\n\t 'magenta' : [35, 39],\n\t 'red' : [31, 39],\n\t 'yellow' : [33, 39]\n\t};\n\t\n\t// Don't use 'blue' not visible on cmd.exe\n\tinspect.styles = {\n\t 'special': 'cyan',\n\t 'number': 'yellow',\n\t 'boolean': 'yellow',\n\t 'undefined': 'grey',\n\t 'null': 'bold',\n\t 'string': 'green',\n\t 'date': 'magenta',\n\t // \"name\": intentionally not styling\n\t 'regexp': 'red'\n\t};\n\t\n\t\n\tfunction stylizeWithColor(str, styleType) {\n\t var style = inspect.styles[styleType];\n\t\n\t if (style) {\n\t return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n\t '\\u001b[' + inspect.colors[style][1] + 'm';\n\t } else {\n\t return str;\n\t }\n\t}\n\t\n\t\n\tfunction stylizeNoColor(str, styleType) {\n\t return str;\n\t}\n\t\n\t\n\tfunction arrayToHash(array) {\n\t var hash = {};\n\t\n\t array.forEach(function(val, idx) {\n\t hash[val] = true;\n\t });\n\t\n\t return hash;\n\t}\n\t\n\t\n\tfunction formatValue(ctx, value, recurseTimes) {\n\t // Provide a hook for user-specified inspect functions.\n\t // Check that value is an object with an inspect function on it\n\t if (ctx.customInspect &&\n\t value &&\n\t isFunction(value.inspect) &&\n\t // Filter out the util module, it's inspect function is special\n\t value.inspect !== exports.inspect &&\n\t // Also filter out any prototype objects using the circular check.\n\t !(value.constructor && value.constructor.prototype === value)) {\n\t var ret = value.inspect(recurseTimes, ctx);\n\t if (!isString(ret)) {\n\t ret = formatValue(ctx, ret, recurseTimes);\n\t }\n\t return ret;\n\t }\n\t\n\t // Primitive types cannot have properties\n\t var primitive = formatPrimitive(ctx, value);\n\t if (primitive) {\n\t return primitive;\n\t }\n\t\n\t // Look up the keys of the object.\n\t var keys = Object.keys(value);\n\t var visibleKeys = arrayToHash(keys);\n\t\n\t if (ctx.showHidden) {\n\t keys = Object.getOwnPropertyNames(value);\n\t }\n\t\n\t // IE doesn't make error fields non-enumerable\n\t // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n\t if (isError(value)\n\t && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n\t return formatError(value);\n\t }\n\t\n\t // Some type of object without properties can be shortcutted.\n\t if (keys.length === 0) {\n\t if (isFunction(value)) {\n\t var name = value.name ? ': ' + value.name : '';\n\t return ctx.stylize('[Function' + name + ']', 'special');\n\t }\n\t if (isRegExp(value)) {\n\t return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n\t }\n\t if (isDate(value)) {\n\t return ctx.stylize(Date.prototype.toString.call(value), 'date');\n\t }\n\t if (isError(value)) {\n\t return formatError(value);\n\t }\n\t }\n\t\n\t var base = '', array = false, braces = ['{', '}'];\n\t\n\t // Make Array say that they are Array\n\t if (isArray(value)) {\n\t array = true;\n\t braces = ['[', ']'];\n\t }\n\t\n\t // Make functions say that they are functions\n\t if (isFunction(value)) {\n\t var n = value.name ? ': ' + value.name : '';\n\t base = ' [Function' + n + ']';\n\t }\n\t\n\t // Make RegExps say that they are RegExps\n\t if (isRegExp(value)) {\n\t base = ' ' + RegExp.prototype.toString.call(value);\n\t }\n\t\n\t // Make dates with properties first say the date\n\t if (isDate(value)) {\n\t base = ' ' + Date.prototype.toUTCString.call(value);\n\t }\n\t\n\t // Make error with message first say the error\n\t if (isError(value)) {\n\t base = ' ' + formatError(value);\n\t }\n\t\n\t if (keys.length === 0 && (!array || value.length == 0)) {\n\t return braces[0] + base + braces[1];\n\t }\n\t\n\t if (recurseTimes < 0) {\n\t if (isRegExp(value)) {\n\t return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n\t } else {\n\t return ctx.stylize('[Object]', 'special');\n\t }\n\t }\n\t\n\t ctx.seen.push(value);\n\t\n\t var output;\n\t if (array) {\n\t output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n\t } else {\n\t output = keys.map(function(key) {\n\t return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n\t });\n\t }\n\t\n\t ctx.seen.pop();\n\t\n\t return reduceToSingleString(output, base, braces);\n\t}\n\t\n\t\n\tfunction formatPrimitive(ctx, value) {\n\t if (isUndefined(value))\n\t return ctx.stylize('undefined', 'undefined');\n\t if (isString(value)) {\n\t var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n\t .replace(/'/g, \"\\\\'\")\n\t .replace(/\\\\\"/g, '\"') + '\\'';\n\t return ctx.stylize(simple, 'string');\n\t }\n\t if (isNumber(value))\n\t return ctx.stylize('' + value, 'number');\n\t if (isBoolean(value))\n\t return ctx.stylize('' + value, 'boolean');\n\t // For some reason typeof null is \"object\", so special case here.\n\t if (isNull(value))\n\t return ctx.stylize('null', 'null');\n\t}\n\t\n\t\n\tfunction formatError(value) {\n\t return '[' + Error.prototype.toString.call(value) + ']';\n\t}\n\t\n\t\n\tfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n\t var output = [];\n\t for (var i = 0, l = value.length; i < l; ++i) {\n\t if (hasOwnProperty(value, String(i))) {\n\t output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n\t String(i), true));\n\t } else {\n\t output.push('');\n\t }\n\t }\n\t keys.forEach(function(key) {\n\t if (!key.match(/^\\d+$/)) {\n\t output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n\t key, true));\n\t }\n\t });\n\t return output;\n\t}\n\t\n\t\n\tfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n\t var name, str, desc;\n\t desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n\t if (desc.get) {\n\t if (desc.set) {\n\t str = ctx.stylize('[Getter/Setter]', 'special');\n\t } else {\n\t str = ctx.stylize('[Getter]', 'special');\n\t }\n\t } else {\n\t if (desc.set) {\n\t str = ctx.stylize('[Setter]', 'special');\n\t }\n\t }\n\t if (!hasOwnProperty(visibleKeys, key)) {\n\t name = '[' + key + ']';\n\t }\n\t if (!str) {\n\t if (ctx.seen.indexOf(desc.value) < 0) {\n\t if (isNull(recurseTimes)) {\n\t str = formatValue(ctx, desc.value, null);\n\t } else {\n\t str = formatValue(ctx, desc.value, recurseTimes - 1);\n\t }\n\t if (str.indexOf('\\n') > -1) {\n\t if (array) {\n\t str = str.split('\\n').map(function(line) {\n\t return ' ' + line;\n\t }).join('\\n').substr(2);\n\t } else {\n\t str = '\\n' + str.split('\\n').map(function(line) {\n\t return ' ' + line;\n\t }).join('\\n');\n\t }\n\t }\n\t } else {\n\t str = ctx.stylize('[Circular]', 'special');\n\t }\n\t }\n\t if (isUndefined(name)) {\n\t if (array && key.match(/^\\d+$/)) {\n\t return str;\n\t }\n\t name = JSON.stringify('' + key);\n\t if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n\t name = name.substr(1, name.length - 2);\n\t name = ctx.stylize(name, 'name');\n\t } else {\n\t name = name.replace(/'/g, \"\\\\'\")\n\t .replace(/\\\\\"/g, '\"')\n\t .replace(/(^\"|\"$)/g, \"'\");\n\t name = ctx.stylize(name, 'string');\n\t }\n\t }\n\t\n\t return name + ': ' + str;\n\t}\n\t\n\t\n\tfunction reduceToSingleString(output, base, braces) {\n\t var numLinesEst = 0;\n\t var length = output.reduce(function(prev, cur) {\n\t numLinesEst++;\n\t if (cur.indexOf('\\n') >= 0) numLinesEst++;\n\t return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n\t }, 0);\n\t\n\t if (length > 60) {\n\t return braces[0] +\n\t (base === '' ? '' : base + '\\n ') +\n\t ' ' +\n\t output.join(',\\n ') +\n\t ' ' +\n\t braces[1];\n\t }\n\t\n\t return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n\t}\n\t\n\t\n\t// NOTE: These type checking functions intentionally don't use `instanceof`\n\t// because it is fragile and can be easily faked with `Object.create()`.\n\tfunction isArray(ar) {\n\t return Array.isArray(ar);\n\t}\n\texports.isArray = isArray;\n\t\n\tfunction isBoolean(arg) {\n\t return typeof arg === 'boolean';\n\t}\n\texports.isBoolean = isBoolean;\n\t\n\tfunction isNull(arg) {\n\t return arg === null;\n\t}\n\texports.isNull = isNull;\n\t\n\tfunction isNullOrUndefined(arg) {\n\t return arg == null;\n\t}\n\texports.isNullOrUndefined = isNullOrUndefined;\n\t\n\tfunction isNumber(arg) {\n\t return typeof arg === 'number';\n\t}\n\texports.isNumber = isNumber;\n\t\n\tfunction isString(arg) {\n\t return typeof arg === 'string';\n\t}\n\texports.isString = isString;\n\t\n\tfunction isSymbol(arg) {\n\t return typeof arg === 'symbol';\n\t}\n\texports.isSymbol = isSymbol;\n\t\n\tfunction isUndefined(arg) {\n\t return arg === void 0;\n\t}\n\texports.isUndefined = isUndefined;\n\t\n\tfunction isRegExp(re) {\n\t return isObject(re) && objectToString(re) === '[object RegExp]';\n\t}\n\texports.isRegExp = isRegExp;\n\t\n\tfunction isObject(arg) {\n\t return typeof arg === 'object' && arg !== null;\n\t}\n\texports.isObject = isObject;\n\t\n\tfunction isDate(d) {\n\t return isObject(d) && objectToString(d) === '[object Date]';\n\t}\n\texports.isDate = isDate;\n\t\n\tfunction isError(e) {\n\t return isObject(e) &&\n\t (objectToString(e) === '[object Error]' || e instanceof Error);\n\t}\n\texports.isError = isError;\n\t\n\tfunction isFunction(arg) {\n\t return typeof arg === 'function';\n\t}\n\texports.isFunction = isFunction;\n\t\n\tfunction isPrimitive(arg) {\n\t return arg === null ||\n\t typeof arg === 'boolean' ||\n\t typeof arg === 'number' ||\n\t typeof arg === 'string' ||\n\t typeof arg === 'symbol' || // ES6 symbol\n\t typeof arg === 'undefined';\n\t}\n\texports.isPrimitive = isPrimitive;\n\t\n\texports.isBuffer = __webpack_require__(63);\n\t\n\tfunction objectToString(o) {\n\t return Object.prototype.toString.call(o);\n\t}\n\t\n\t\n\tfunction pad(n) {\n\t return n < 10 ? '0' + n.toString(10) : n.toString(10);\n\t}\n\t\n\t\n\tvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n\t 'Oct', 'Nov', 'Dec'];\n\t\n\t// 26 Feb 16:19:34\n\tfunction timestamp() {\n\t var d = new Date();\n\t var time = [pad(d.getHours()),\n\t pad(d.getMinutes()),\n\t pad(d.getSeconds())].join(':');\n\t return [d.getDate(), months[d.getMonth()], time].join(' ');\n\t}\n\t\n\t\n\t// log is just a thin wrapper to console.log that prepends a timestamp\n\texports.log = function() {\n\t console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n\t};\n\t\n\t\n\t/**\n\t * Inherit the prototype methods from one constructor into another.\n\t *\n\t * The Function.prototype.inherits from lang.js rewritten as a standalone\n\t * function (not on Function.prototype). NOTE: If this file is to be loaded\n\t * during bootstrapping this function needs to be rewritten using some native\n\t * functions as prototype setup using normal JavaScript does not work as\n\t * expected during bootstrapping (see mirror.js in r114903).\n\t *\n\t * @param {function} ctor Constructor function which needs to inherit the\n\t * prototype.\n\t * @param {function} superCtor Constructor function to inherit prototype from.\n\t */\n\texports.inherits = __webpack_require__(64);\n\t\n\texports._extend = function(origin, add) {\n\t // Don't do anything if add isn't an object\n\t if (!add || !isObject(add)) return origin;\n\t\n\t var keys = Object.keys(add);\n\t var i = keys.length;\n\t while (i--) {\n\t origin[keys[i]] = add[keys[i]];\n\t }\n\t return origin;\n\t};\n\t\n\tfunction hasOwnProperty(obj, prop) {\n\t return Object.prototype.hasOwnProperty.call(obj, prop);\n\t}\n\t\n\t/* WEBPACK VAR INJECTION */}.call(exports, (function() { return this; }()), __webpack_require__(60)))\n\n/***/ },\n/* 63 */\n/***/ function(module, exports) {\n\n\tmodule.exports = function isBuffer(arg) {\n\t return arg && typeof arg === 'object'\n\t && typeof arg.copy === 'function'\n\t && typeof arg.fill === 'function'\n\t && typeof arg.readUInt8 === 'function';\n\t}\n\n/***/ },\n/* 64 */\n/***/ function(module, exports) {\n\n\tif (typeof Object.create === 'function') {\n\t // implementation from standard node.js 'util' module\n\t module.exports = function inherits(ctor, superCtor) {\n\t ctor.super_ = superCtor\n\t ctor.prototype = Object.create(superCtor.prototype, {\n\t constructor: {\n\t value: ctor,\n\t enumerable: false,\n\t writable: true,\n\t configurable: true\n\t }\n\t });\n\t };\n\t} else {\n\t // old school shim for old browsers\n\t module.exports = function inherits(ctor, superCtor) {\n\t ctor.super_ = superCtor\n\t var TempCtor = function () {}\n\t TempCtor.prototype = superCtor.prototype\n\t ctor.prototype = new TempCtor()\n\t ctor.prototype.constructor = ctor\n\t }\n\t}\n\n\n/***/ },\n/* 65 */\n/***/ function(module, exports) {\n\n\tmodule.exports = Yallist\n\t\n\tYallist.Node = Node\n\tYallist.create = Yallist\n\t\n\tfunction Yallist (list) {\n\t var self = this\n\t if (!(self instanceof Yallist)) {\n\t self = new Yallist()\n\t }\n\t\n\t self.tail = null\n\t self.head = null\n\t self.length = 0\n\t\n\t if (list && typeof list.forEach === 'function') {\n\t list.forEach(function (item) {\n\t self.push(item)\n\t })\n\t } else if (arguments.length > 0) {\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t self.push(arguments[i])\n\t }\n\t }\n\t\n\t return self\n\t}\n\t\n\tYallist.prototype.removeNode = function (node) {\n\t if (node.list !== this) {\n\t throw new Error('removing node which does not belong to this list')\n\t }\n\t\n\t var next = node.next\n\t var prev = node.prev\n\t\n\t if (next) {\n\t next.prev = prev\n\t }\n\t\n\t if (prev) {\n\t prev.next = next\n\t }\n\t\n\t if (node === this.head) {\n\t this.head = next\n\t }\n\t if (node === this.tail) {\n\t this.tail = prev\n\t }\n\t\n\t node.list.length --\n\t node.next = null\n\t node.prev = null\n\t node.list = null\n\t}\n\t\n\tYallist.prototype.unshiftNode = function (node) {\n\t if (node === this.head) {\n\t return\n\t }\n\t\n\t if (node.list) {\n\t node.list.removeNode(node)\n\t }\n\t\n\t var head = this.head\n\t node.list = this\n\t node.next = head\n\t if (head) {\n\t head.prev = node\n\t }\n\t\n\t this.head = node\n\t if (!this.tail) {\n\t this.tail = node\n\t }\n\t this.length ++\n\t}\n\t\n\tYallist.prototype.pushNode = function (node) {\n\t if (node === this.tail) {\n\t return\n\t }\n\t\n\t if (node.list) {\n\t node.list.removeNode(node)\n\t }\n\t\n\t var tail = this.tail\n\t node.list = this\n\t node.prev = tail\n\t if (tail) {\n\t tail.next = node\n\t }\n\t\n\t this.tail = node\n\t if (!this.head) {\n\t this.head = node\n\t }\n\t this.length ++\n\t}\n\t\n\tYallist.prototype.push = function () {\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t push(this, arguments[i])\n\t }\n\t return this.length\n\t}\n\t\n\tYallist.prototype.unshift = function () {\n\t for (var i = 0, l = arguments.length; i < l; i++) {\n\t unshift(this, arguments[i])\n\t }\n\t return this.length\n\t}\n\t\n\tYallist.prototype.pop = function () {\n\t if (!this.tail)\n\t return undefined\n\t\n\t var res = this.tail.value\n\t this.tail = this.tail.prev\n\t this.tail.next = null\n\t this.length --\n\t return res\n\t}\n\t\n\tYallist.prototype.shift = function () {\n\t if (!this.head)\n\t return undefined\n\t\n\t var res = this.head.value\n\t this.head = this.head.next\n\t this.head.prev = null\n\t this.length --\n\t return res\n\t}\n\t\n\tYallist.prototype.forEach = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = this.head, i = 0; walker !== null; i++) {\n\t fn.call(thisp, walker.value, i, this)\n\t walker = walker.next\n\t }\n\t}\n\t\n\tYallist.prototype.forEachReverse = function (fn, thisp) {\n\t thisp = thisp || this\n\t for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {\n\t fn.call(thisp, walker.value, i, this)\n\t walker = walker.prev\n\t }\n\t}\n\t\n\tYallist.prototype.get = function (n) {\n\t for (var i = 0, walker = this.head; walker !== null && i < n; i++) {\n\t // abort out of the list early if we hit a cycle\n\t walker = walker.next\n\t }\n\t if (i === n && walker !== null) {\n\t return walker.value\n\t }\n\t}\n\t\n\tYallist.prototype.getReverse = function (n) {\n\t for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {\n\t // abort out of the list early if we hit a cycle\n\t walker = walker.prev\n\t }\n\t if (i === n && walker !== null) {\n\t return walker.value\n\t }\n\t}\n\t\n\tYallist.prototype.map = function (fn, thisp) {\n\t thisp = thisp || this\n\t var res = new Yallist()\n\t for (var walker = this.head; walker !== null; ) {\n\t res.push(fn.call(thisp, walker.value, this))\n\t walker = walker.next\n\t }\n\t return res\n\t}\n\t\n\tYallist.prototype.mapReverse = function (fn, thisp) {\n\t thisp = thisp || this\n\t var res = new Yallist()\n\t for (var walker = this.tail; walker !== null;) {\n\t res.push(fn.call(thisp, walker.value, this))\n\t walker = walker.prev\n\t }\n\t return res\n\t}\n\t\n\tYallist.prototype.reduce = function (fn, initial) {\n\t var acc\n\t var walker = this.head\n\t if (arguments.length > 1) {\n\t acc = initial\n\t } else if (this.head) {\n\t walker = this.head.next\n\t acc = this.head.value\n\t } else {\n\t throw new TypeError('Reduce of empty list with no initial value')\n\t }\n\t\n\t for (var i = 0; walker !== null; i++) {\n\t acc = fn(acc, walker.value, i)\n\t walker = walker.next\n\t }\n\t\n\t return acc\n\t}\n\t\n\tYallist.prototype.reduceReverse = function (fn, initial) {\n\t var acc\n\t var walker = this.tail\n\t if (arguments.length > 1) {\n\t acc = initial\n\t } else if (this.tail) {\n\t walker = this.tail.prev\n\t acc = this.tail.value\n\t } else {\n\t throw new TypeError('Reduce of empty list with no initial value')\n\t }\n\t\n\t for (var i = this.length - 1; walker !== null; i--) {\n\t acc = fn(acc, walker.value, i)\n\t walker = walker.prev\n\t }\n\t\n\t return acc\n\t}\n\t\n\tYallist.prototype.toArray = function () {\n\t var arr = new Array(this.length)\n\t for (var i = 0, walker = this.head; walker !== null; i++) {\n\t arr[i] = walker.value\n\t walker = walker.next\n\t }\n\t return arr\n\t}\n\t\n\tYallist.prototype.toArrayReverse = function () {\n\t var arr = new Array(this.length)\n\t for (var i = 0, walker = this.tail; walker !== null; i++) {\n\t arr[i] = walker.value\n\t walker = walker.prev\n\t }\n\t return arr\n\t}\n\t\n\tYallist.prototype.slice = function (from, to) {\n\t to = to || this.length\n\t if (to < 0) {\n\t to += this.length\n\t }\n\t from = from || 0\n\t if (from < 0) {\n\t from += this.length\n\t }\n\t var ret = new Yallist()\n\t if (to < from || to < 0) {\n\t return ret\n\t }\n\t if (from < 0) {\n\t from = 0\n\t }\n\t if (to > this.length) {\n\t to = this.length\n\t }\n\t for (var i = 0, walker = this.head; walker !== null && i < from; i++) {\n\t walker = walker.next\n\t }\n\t for (; walker !== null && i < to; i++, walker = walker.next) {\n\t ret.push(walker.value)\n\t }\n\t return ret\n\t}\n\t\n\tYallist.prototype.sliceReverse = function (from, to) {\n\t to = to || this.length\n\t if (to < 0) {\n\t to += this.length\n\t }\n\t from = from || 0\n\t if (from < 0) {\n\t from += this.length\n\t }\n\t var ret = new Yallist()\n\t if (to < from || to < 0) {\n\t return ret\n\t }\n\t if (from < 0) {\n\t from = 0\n\t }\n\t if (to > this.length) {\n\t to = this.length\n\t }\n\t for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {\n\t walker = walker.prev\n\t }\n\t for (; walker !== null && i > from; i--, walker = walker.prev) {\n\t ret.push(walker.value)\n\t }\n\t return ret\n\t}\n\t\n\tYallist.prototype.reverse = function () {\n\t var head = this.head\n\t var tail = this.tail\n\t for (var walker = head; walker !== null; walker = walker.prev) {\n\t var p = walker.prev\n\t walker.prev = walker.next\n\t walker.next = p\n\t }\n\t this.head = tail\n\t this.tail = head\n\t return this\n\t}\n\t\n\tfunction push (self, item) {\n\t self.tail = new Node(item, self.tail, null, self)\n\t if (!self.head) {\n\t self.head = self.tail\n\t }\n\t self.length ++\n\t}\n\t\n\tfunction unshift (self, item) {\n\t self.head = new Node(item, null, self.head, self)\n\t if (!self.tail) {\n\t self.tail = self.head\n\t }\n\t self.length ++\n\t}\n\t\n\tfunction Node (value, prev, next, list) {\n\t if (!(this instanceof Node)) {\n\t return new Node(value, prev, next, list)\n\t }\n\t\n\t this.list = list\n\t this.value = value\n\t\n\t if (prev) {\n\t prev.next = this\n\t this.prev = prev\n\t } else {\n\t this.prev = null\n\t }\n\t\n\t if (next) {\n\t next.prev = this\n\t this.next = next\n\t } else {\n\t this.next = null\n\t }\n\t}\n\n\n/***/ },\n/* 66 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Tile2 = __webpack_require__(67);\n\t\n\tvar _Tile3 = _interopRequireDefault(_Tile2);\n\t\n\tvar _vendorBoxHelper = __webpack_require__(68);\n\t\n\tvar _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\tvar ImageTile = (function (_Tile) {\n\t _inherits(ImageTile, _Tile);\n\t\n\t function ImageTile(quadcode, path, layer) {\n\t _classCallCheck(this, ImageTile);\n\t\n\t _get(Object.getPrototypeOf(ImageTile.prototype), 'constructor', this).call(this, quadcode, path, layer);\n\t }\n\t\n\t // Request data for the tile\n\t\n\t _createClass(ImageTile, [{\n\t key: 'requestTileAsync',\n\t value: function requestTileAsync() {\n\t var _this = this;\n\t\n\t // Making this asynchronous really speeds up the LOD framerate\n\t setTimeout(function () {\n\t if (!_this._mesh) {\n\t _this._mesh = _this._createMesh();\n\t }\n\t\n\t _this._requestTile();\n\t }, 0);\n\t }\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Cancel any pending requests\n\t this._abortRequest();\n\t\n\t // Clear image reference\n\t this._image = null;\n\t\n\t _get(Object.getPrototypeOf(ImageTile.prototype), 'destroy', this).call(this);\n\t }\n\t }, {\n\t key: '_createMesh',\n\t value: function _createMesh() {\n\t // Something went wrong and the tile\n\t //\n\t // Possibly removed by the cache before loaded\n\t if (!this._center) {\n\t return;\n\t }\n\t\n\t var mesh = new _three2['default'].Object3D();\n\t var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);\n\t\n\t var material;\n\t if (!this._world._environment._skybox) {\n\t material = new _three2['default'].MeshBasicMaterial({\n\t depthWrite: false\n\t });\n\t\n\t // var material = new THREE.MeshPhongMaterial({\n\t // depthWrite: false\n\t // });\n\t } else {\n\t // Other MeshStandardMaterial settings\n\t //\n\t // material.envMapIntensity will change the amount of colour reflected(?)\n\t // from the environment map – can be greater than 1 for more intensity\n\t\n\t material = new _three2['default'].MeshStandardMaterial({\n\t depthWrite: false\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMap = this._world._environment._skybox.getRenderTarget();\n\t }\n\t\n\t var localMesh = new _three2['default'].Mesh(geom, material);\n\t localMesh.rotation.x = -90 * Math.PI / 180;\n\t\n\t localMesh.receiveShadow = true;\n\t\n\t // Setting this causes a depth-buffer intersection issue on the\n\t // all-the-things example\n\t // localMesh.renderOrder = 2;\n\t\n\t mesh.add(localMesh);\n\t\n\t // Setting this causes a depth-buffer intersection issue on the\n\t // all-the-things example\n\t // mesh.renderOrder = 2;\n\t\n\t mesh.position.x = this._center[0];\n\t mesh.position.z = this._center[1];\n\t\n\t // var box = new BoxHelper(localMesh);\n\t // mesh.add(box);\n\t //\n\t // mesh.add(this._createDebugMesh());\n\t\n\t return mesh;\n\t }\n\t }, {\n\t key: '_createDebugMesh',\n\t value: function _createDebugMesh() {\n\t var canvas = document.createElement('canvas');\n\t canvas.width = 256;\n\t canvas.height = 256;\n\t\n\t var context = canvas.getContext('2d');\n\t context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n\t context.fillStyle = '#ff0000';\n\t context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n\t context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\t\n\t var texture = new _three2['default'].Texture(canvas);\n\t\n\t // Silky smooth images when tilted\n\t texture.magFilter = _three2['default'].LinearFilter;\n\t texture.minFilter = _three2['default'].LinearMipMapLinearFilter;\n\t\n\t // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t texture.anisotropy = 4;\n\t\n\t texture.needsUpdate = true;\n\t\n\t var material = new _three2['default'].MeshBasicMaterial({\n\t map: texture,\n\t transparent: true,\n\t depthWrite: false\n\t });\n\t\n\t var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);\n\t var mesh = new _three2['default'].Mesh(geom, material);\n\t\n\t mesh.rotation.x = -90 * Math.PI / 180;\n\t mesh.position.y = 0.1;\n\t\n\t return mesh;\n\t }\n\t }, {\n\t key: '_requestTile',\n\t value: function _requestTile() {\n\t var _this2 = this;\n\t\n\t var urlParams = {\n\t x: this._tile[0],\n\t y: this._tile[1],\n\t z: this._tile[2]\n\t };\n\t\n\t var url = this._getTileURL(urlParams);\n\t\n\t var image = document.createElement('img');\n\t\n\t this._aborted = false;\n\t\n\t image.addEventListener('load', function (event) {\n\t if (_this2.isAborted()) {\n\t return;\n\t }\n\t\n\t var texture = new _three2['default'].Texture();\n\t\n\t texture.image = image;\n\t texture.needsUpdate = true;\n\t\n\t // Silky smooth images when tilted\n\t texture.magFilter = _three2['default'].LinearFilter;\n\t texture.minFilter = _three2['default'].LinearMipMapLinearFilter;\n\t\n\t // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t texture.anisotropy = 4;\n\t\n\t texture.needsUpdate = true;\n\t\n\t // Something went wrong and the tile or its material is missing\n\t //\n\t // Possibly removed by the cache before the image loaded\n\t if (!_this2._mesh || !_this2._mesh.children[0] || !_this2._mesh.children[0].material) {\n\t return;\n\t }\n\t\n\t _this2._mesh.children[0].material.map = texture;\n\t _this2._mesh.children[0].material.needsUpdate = true;\n\t\n\t _this2._texture = texture;\n\t _this2._ready = true;\n\t }, false);\n\t\n\t // image.addEventListener('progress', event => {}, false);\n\t // image.addEventListener('error', event => {}, false);\n\t\n\t image.crossOrigin = '';\n\t\n\t // Load image\n\t image.src = url;\n\t\n\t this._image = image;\n\t }\n\t }, {\n\t key: '_abortRequest',\n\t value: function _abortRequest() {\n\t if (!this._image || this._ready) {\n\t return;\n\t }\n\t\n\t this._aborted = true;\n\t\n\t this._image.src = '';\n\t }\n\t }]);\n\t\n\t return ImageTile;\n\t})(_Tile3['default']);\n\t\n\texports['default'] = ImageTile;\n\t\n\tvar noNew = function noNew(quadcode, path, layer) {\n\t return new ImageTile(quadcode, path, layer);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.imageTile = noNew;\n\n/***/ },\n/* 67 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// Manages a single tile and its layers\n\t\n\tvar r2d = 180 / Math.PI;\n\t\n\tvar tileURLRegex = /\\{([szxy])\\}/g;\n\t\n\tvar Tile = (function () {\n\t function Tile(quadcode, path, layer) {\n\t _classCallCheck(this, Tile);\n\t\n\t this._layer = layer;\n\t this._world = layer._world;\n\t this._quadcode = quadcode;\n\t this._path = path;\n\t\n\t this._ready = false;\n\t this._aborted = false;\n\t\n\t this._tile = this._quadcodeToTile(quadcode);\n\t\n\t // Bottom-left and top-right bounds in WGS84 coordinates\n\t this._boundsLatLon = this._tileBoundsWGS84(this._tile);\n\t\n\t // Bottom-left and top-right bounds in world coordinates\n\t this._boundsWorld = this._tileBoundsFromWGS84(this._boundsLatLon);\n\t\n\t // Tile center in world coordinates\n\t this._center = this._boundsToCenter(this._boundsWorld);\n\t\n\t // Tile center in projected coordinates\n\t this._centerLatlon = this._world.pointToLatLon((0, _geoPoint.point)(this._center[0], this._center[1]));\n\t\n\t // Length of a tile side in world coorindates\n\t this._side = this._getSide(this._boundsWorld);\n\t\n\t // Point scale for tile (for unit conversion)\n\t this._pointScale = this._world.pointScale(this._centerLatlon);\n\t }\n\t\n\t // Returns true if the tile mesh and texture are ready to be used\n\t // Otherwise, returns false\n\t\n\t _createClass(Tile, [{\n\t key: 'isReady',\n\t value: function isReady() {\n\t return this._ready;\n\t }\n\t }, {\n\t key: 'isAborted',\n\t value: function isAborted() {\n\t return this._aborted;\n\t }\n\t\n\t // Request data for the tile\n\t }, {\n\t key: 'requestTileAsync',\n\t value: function requestTileAsync() {}\n\t }, {\n\t key: 'getQuadcode',\n\t value: function getQuadcode() {\n\t return this._quadcode;\n\t }\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {\n\t return this._boundsWorld;\n\t }\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t }, {\n\t key: 'getSide',\n\t value: function getSide() {\n\t return this._side;\n\t }\n\t }, {\n\t key: 'getMesh',\n\t value: function getMesh() {\n\t return this._mesh;\n\t }\n\t }, {\n\t key: 'getPickingMesh',\n\t value: function getPickingMesh() {\n\t return this._pickingMesh;\n\t }\n\t\n\t // Destroys the tile and removes it from the layer and memory\n\t //\n\t // Ensure that this leaves no trace of the tile – no textures, no meshes,\n\t // nothing in memory or the GPU\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // console.log('Destroying tile', this._quadcode);\n\t\n\t // Delete reference to layer and world\n\t this._layer = null;\n\t this._world = null;\n\t\n\t // Delete location references\n\t this._boundsLatLon = null;\n\t this._boundsWorld = null;\n\t this._center = null;\n\t\n\t // Done if no mesh\n\t if (!this._mesh && !this._pickingMesh) {\n\t return;\n\t }\n\t\n\t this.destroyMesh(this._mesh);\n\t this.destroyMesh(this._pickingMesh);\n\t\n\t this._mesh = null;\n\t this._pickingMesh = null;\n\t }\n\t }, {\n\t key: 'destroyMesh',\n\t value: function destroyMesh(mesh) {\n\t var _this = this;\n\t\n\t var dispose = arguments.length <= 1 || arguments[1] === undefined ? true : arguments[1];\n\t\n\t if (mesh) {\n\t if (mesh.children) {\n\t mesh.children.forEach(function (child) {\n\t mesh.remove(child);\n\t _this.destroyMesh(child);\n\t });\n\t }\n\t\n\t if (dispose) {\n\t if (mesh.geometry) {\n\t mesh.geometry.dispose();\n\t mesh.geometry = null;\n\t }\n\t\n\t if (mesh.material) {\n\t if (mesh.material.map) {\n\t mesh.material.map.dispose();\n\t mesh.material.map = null;\n\t }\n\t\n\t mesh.material.dispose();\n\t mesh.material = null;\n\t }\n\t }\n\t }\n\t }\n\t }, {\n\t key: '_createMesh',\n\t value: function _createMesh() {}\n\t }, {\n\t key: '_createDebugMesh',\n\t value: function _createDebugMesh() {}\n\t }, {\n\t key: '_getTileURL',\n\t value: function _getTileURL(urlParams) {\n\t if (!urlParams.s) {\n\t // Default to a random choice of a, b or c\n\t urlParams.s = String.fromCharCode(97 + Math.floor(Math.random() * 3));\n\t }\n\t\n\t tileURLRegex.lastIndex = 0;\n\t return this._path.replace(tileURLRegex, function (value, key) {\n\t // Replace with paramter, otherwise keep existing value\n\t return urlParams[key];\n\t });\n\t }\n\t\n\t // Convert from quadcode to TMS tile coordinates\n\t }, {\n\t key: '_quadcodeToTile',\n\t value: function _quadcodeToTile(quadcode) {\n\t var x = 0;\n\t var y = 0;\n\t var z = quadcode.length;\n\t\n\t for (var i = z; i > 0; i--) {\n\t var mask = 1 << i - 1;\n\t var q = +quadcode[z - i];\n\t if (q === 1) {\n\t x |= mask;\n\t }\n\t if (q === 2) {\n\t y |= mask;\n\t }\n\t if (q === 3) {\n\t x |= mask;\n\t y |= mask;\n\t }\n\t }\n\t\n\t return [x, y, z];\n\t }\n\t\n\t // Convert WGS84 tile bounds to world coordinates\n\t }, {\n\t key: '_tileBoundsFromWGS84',\n\t value: function _tileBoundsFromWGS84(boundsWGS84) {\n\t var sw = this._layer._world.latLonToPoint((0, _geoLatLon.latLon)(boundsWGS84[1], boundsWGS84[0]));\n\t var ne = this._layer._world.latLonToPoint((0, _geoLatLon.latLon)(boundsWGS84[3], boundsWGS84[2]));\n\t\n\t return [sw.x, sw.y, ne.x, ne.y];\n\t }\n\t\n\t // Get tile bounds in WGS84 coordinates\n\t }, {\n\t key: '_tileBoundsWGS84',\n\t value: function _tileBoundsWGS84(tile) {\n\t var e = this._tile2lon(tile[0] + 1, tile[2]);\n\t var w = this._tile2lon(tile[0], tile[2]);\n\t var s = this._tile2lat(tile[1] + 1, tile[2]);\n\t var n = this._tile2lat(tile[1], tile[2]);\n\t return [w, s, e, n];\n\t }\n\t }, {\n\t key: '_tile2lon',\n\t value: function _tile2lon(x, z) {\n\t return x / Math.pow(2, z) * 360 - 180;\n\t }\n\t }, {\n\t key: '_tile2lat',\n\t value: function _tile2lat(y, z) {\n\t var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);\n\t return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));\n\t }\n\t }, {\n\t key: '_boundsToCenter',\n\t value: function _boundsToCenter(bounds) {\n\t var x = bounds[0] + (bounds[2] - bounds[0]) / 2;\n\t var y = bounds[1] + (bounds[3] - bounds[1]) / 2;\n\t\n\t return [x, y];\n\t }\n\t }, {\n\t key: '_getSide',\n\t value: function _getSide(bounds) {\n\t return new _three2['default'].Vector3(bounds[0], 0, bounds[3]).sub(new _three2['default'].Vector3(bounds[0], 0, bounds[1])).length();\n\t }\n\t }]);\n\t\n\t return Tile;\n\t})();\n\t\n\texports['default'] = Tile;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 68 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// jscs:disable\n\t/* eslint-disable */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t/**\n\t * @author mrdoob / http://mrdoob.com/\n\t */\n\t\n\tBoxHelper = function (object) {\n\t\n\t\tvar indices = new Uint16Array([0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7]);\n\t\tvar positions = new Float32Array(8 * 3);\n\t\n\t\tvar geometry = new _three2['default'].BufferGeometry();\n\t\tgeometry.setIndex(new _three2['default'].BufferAttribute(indices, 1));\n\t\tgeometry.addAttribute('position', new _three2['default'].BufferAttribute(positions, 3));\n\t\n\t\t_three2['default'].LineSegments.call(this, geometry, new _three2['default'].LineBasicMaterial({ linewidth: 2, color: 0xff0000 }));\n\t\n\t\tif (object !== undefined) {\n\t\n\t\t\tthis.update(object);\n\t\t}\n\t};\n\t\n\tBoxHelper.prototype = Object.create(_three2['default'].LineSegments.prototype);\n\tBoxHelper.prototype.constructor = BoxHelper;\n\t\n\tBoxHelper.prototype.update = (function () {\n\t\n\t\tvar box = new _three2['default'].Box3();\n\t\n\t\treturn function (object) {\n\t\n\t\t\tbox.setFromObject(object);\n\t\n\t\t\tif (box.isEmpty()) return;\n\t\n\t\t\tvar min = box.min;\n\t\t\tvar max = box.max;\n\t\n\t\t\t/*\n\t 5____4\n\t 1/___0/|\n\t | 6__|_7\n\t 2/___3/\n\t \t0: max.x, max.y, max.z\n\t 1: min.x, max.y, max.z\n\t 2: min.x, min.y, max.z\n\t 3: max.x, min.y, max.z\n\t 4: max.x, max.y, min.z\n\t 5: min.x, max.y, min.z\n\t 6: min.x, min.y, min.z\n\t 7: max.x, min.y, min.z\n\t */\n\t\n\t\t\tvar position = this.geometry.attributes.position;\n\t\t\tvar array = position.array;\n\t\n\t\t\tarray[0] = max.x;array[1] = max.y;array[2] = max.z;\n\t\t\tarray[3] = min.x;array[4] = max.y;array[5] = max.z;\n\t\t\tarray[6] = min.x;array[7] = min.y;array[8] = max.z;\n\t\t\tarray[9] = max.x;array[10] = min.y;array[11] = max.z;\n\t\t\tarray[12] = max.x;array[13] = max.y;array[14] = min.z;\n\t\t\tarray[15] = min.x;array[16] = max.y;array[17] = min.z;\n\t\t\tarray[18] = min.x;array[19] = min.y;array[20] = min.z;\n\t\t\tarray[21] = max.x;array[22] = min.y;array[23] = min.z;\n\t\n\t\t\tposition.needsUpdate = true;\n\t\n\t\t\tthis.geometry.computeBoundingSphere();\n\t\t};\n\t})();\n\t\n\texports['default'] = BoxHelper;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 69 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\texports['default'] = function (colour, skyboxTarget) {\n\t var canvas = document.createElement('canvas');\n\t canvas.width = 1;\n\t canvas.height = 1;\n\t\n\t var context = canvas.getContext('2d');\n\t context.fillStyle = colour;\n\t context.fillRect(0, 0, canvas.width, canvas.height);\n\t // context.strokeStyle = '#D0D0CF';\n\t // context.strokeRect(0, 0, canvas.width, canvas.height);\n\t\n\t var texture = new _three2['default'].Texture(canvas);\n\t\n\t // // Silky smooth images when tilted\n\t // texture.magFilter = THREE.LinearFilter;\n\t // texture.minFilter = THREE.LinearMipMapLinearFilter;\n\t // //\n\t // // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t // texture.anisotropy = 4;\n\t\n\t // texture.wrapS = THREE.RepeatWrapping;\n\t // texture.wrapT = THREE.RepeatWrapping;\n\t // texture.repeat.set(segments, segments);\n\t\n\t texture.needsUpdate = true;\n\t\n\t var material;\n\t\n\t if (!skyboxTarget) {\n\t material = new _three2['default'].MeshBasicMaterial({\n\t map: texture,\n\t depthWrite: false\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t map: texture,\n\t depthWrite: false\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMap = skyboxTarget;\n\t }\n\t\n\t return material;\n\t};\n\t\n\t;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 70 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _TileLayer2 = __webpack_require__(56);\n\t\n\tvar _TileLayer3 = _interopRequireDefault(_TileLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _GeoJSONTile = __webpack_require__(71);\n\t\n\tvar _GeoJSONTile2 = _interopRequireDefault(_GeoJSONTile);\n\t\n\tvar _lodashThrottle = __webpack_require__(22);\n\t\n\tvar _lodashThrottle2 = _interopRequireDefault(_lodashThrottle);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\t// TODO: Offer on-the-fly slicing of static, non-tile-based GeoJSON files into a\n\t// tile grid using geojson-vt\n\t//\n\t// See: https://github.com/mapbox/geojson-vt\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Consider pausing per-frame output during movement so there's little to\n\t// no jank caused by previous tiles still processing\n\t\n\t// This tile layer only updates the quadtree after world movement has occurred\n\t//\n\t// Tiles from previous quadtree updates are updated and outputted every frame\n\t// (or at least every frame, throttled to some amount)\n\t//\n\t// This is because the complexity of TopoJSON tiles requires a lot of processing\n\t// and so makes movement janky if updates occur every frame – only updating\n\t// after movement means frame drops are less obvious due to heavy processing\n\t// occurring while the view is generally stationary\n\t//\n\t// The downside is that until new tiles are requested and outputted you will\n\t// see blank spaces as you orbit and move around\n\t//\n\t// An added benefit is that it dramatically reduces the number of tiles being\n\t// requested over a period of time and the time it takes to go from request to\n\t// screen output\n\t//\n\t// It may be possible to perform these updates per-frame once Web Worker\n\t// processing is added\n\t\n\tvar GeoJSONTileLayer = (function (_TileLayer) {\n\t _inherits(GeoJSONTileLayer, _TileLayer);\n\t\n\t function GeoJSONTileLayer(path, options) {\n\t _classCallCheck(this, GeoJSONTileLayer);\n\t\n\t var defaults = {\n\t maxLOD: 14,\n\t distance: 30000,\n\t workers: false\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'constructor', this).call(this, options);\n\t\n\t this.defaults = defaults;\n\t\n\t this._path = path;\n\t }\n\t\n\t _createClass(GeoJSONTileLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), '_onAdd', _this).call(_this, world).then(function () {\n\t // Trigger initial quadtree calculation on the next frame\n\t //\n\t // TODO: This is a hack to ensure the camera is all set up - a better\n\t // solution should be found\n\t setTimeout(function () {\n\t _this._calculateLOD();\n\t _this._initEvents();\n\t }, 0);\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: '_initEvents',\n\t value: function _initEvents() {\n\t // Run LOD calculations based on render calls\n\t //\n\t // Throttled to 1 LOD calculation per 100ms\n\t this._throttledWorldUpdate = (0, _lodashThrottle2['default'])(this._onWorldUpdate, 100);\n\t\n\t this._world.on('preUpdate', this._throttledWorldUpdate, this);\n\t this._world.on('move', this._onWorldMove, this);\n\t this._world.on('controlsMove', this._onControlsMove, this);\n\t }\n\t\n\t // Update and output tiles each frame (throttled)\n\t }, {\n\t key: '_onWorldUpdate',\n\t value: function _onWorldUpdate() {\n\t if (this._pauseOutput || this._disableOutput) {\n\t return;\n\t }\n\t\n\t this._outputTiles();\n\t }\n\t\n\t // Update tiles grid after world move, but don't output them\n\t }, {\n\t key: '_onWorldMove',\n\t value: function _onWorldMove(latlon, point) {\n\t if (this._disableOutput) {\n\t return;\n\t }\n\t\n\t this._pauseOutput = false;\n\t this._calculateLOD();\n\t }\n\t\n\t // Pause updates during control movement for less visual jank\n\t }, {\n\t key: '_onControlsMove',\n\t value: function _onControlsMove() {\n\t if (this._disableOutput) {\n\t return;\n\t }\n\t\n\t this._pauseOutput = true;\n\t }\n\t }, {\n\t key: '_createTile',\n\t value: function _createTile(quadcode, layer) {\n\t var newOptions = (0, _lodashAssign2['default'])({}, this.defaults, this._options, {\n\t outputToScene: false\n\t });\n\t\n\t delete newOptions.attribution;\n\t\n\t return new _GeoJSONTile2['default'](quadcode, this._path, layer, newOptions);\n\t }\n\t }, {\n\t key: 'hide',\n\t value: function hide() {\n\t this._pauseOutput = true;\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'hide', this).call(this);\n\t }\n\t }, {\n\t key: 'show',\n\t value: function show() {\n\t this._pauseOutput = false;\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'show', this).call(this);\n\t }\n\t\n\t // Destroys the layer and removes it from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t this._world.off('preUpdate', this._throttledWorldUpdate);\n\t this._world.off('move', this._onWorldMove);\n\t\n\t this._throttledWorldUpdate = null;\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(GeoJSONTileLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return GeoJSONTileLayer;\n\t})(_TileLayer3['default']);\n\t\n\texports['default'] = GeoJSONTileLayer;\n\t\n\tvar noNew = function noNew(path, options) {\n\t return new GeoJSONTileLayer(path, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.geoJSONTileLayer = noNew;\n\n/***/ },\n/* 71 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Tile2 = __webpack_require__(67);\n\t\n\tvar _Tile3 = _interopRequireDefault(_Tile2);\n\t\n\tvar _GeoJSONLayer = __webpack_require__(72);\n\t\n\tvar _GeoJSONWorkerLayer = __webpack_require__(87);\n\t\n\tvar _vendorBoxHelper = __webpack_require__(68);\n\t\n\tvar _vendorBoxHelper2 = _interopRequireDefault(_vendorBoxHelper);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _reqwest = __webpack_require__(73);\n\t\n\tvar _reqwest2 = _interopRequireDefault(_reqwest);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\t// import Offset from 'polygon-offset';\n\t\n\tvar _utilGeoJSON = __webpack_require__(75);\n\t\n\tvar _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON);\n\t\n\tvar _utilBuffer = __webpack_require__(81);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\t// TODO: Map picking IDs to some reference within the tile data / geometry so\n\t// that something useful can be done when an object is picked / clicked on\n\t\n\t// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\t\n\t// TODO: Perform tile request and processing in a Web Worker\n\t//\n\t// Use Operative (https://github.com/padolsey/operative)\n\t//\n\t// Would it make sense to have the worker functionality defined in a static\n\t// method so it only gets initialised once and not on every tile instance?\n\t//\n\t// Otherwise, worker processing logic would have to go in the tile layer so not\n\t// to waste loads of time setting up a brand new worker with three.js for each\n\t// tile every single time.\n\t//\n\t// Unsure of the best way to get three.js and VIZI into the worker\n\t//\n\t// Would need to set up a CRS / projection identical to the world instance\n\t//\n\t// Is it possible to bypass requirements on external script by having multiple\n\t// simple worker methods that each take enough inputs to perform a single task\n\t// without requiring VIZI or three.js? So long as the heaviest logic is done in\n\t// the worker and transferrable objects are used then it should be better than\n\t// nothing. Would probably still need things like earcut...\n\t//\n\t// After all, the three.js logic and object creation will still need to be\n\t// done on the main thread regardless so the worker should try to do as much as\n\t// possible with as few dependencies as possible.\n\t//\n\t// Have a look at how this is done in Tangram before implementing anything as\n\t// the approach there is pretty similar and robust.\n\t\n\tvar GeoJSONTile = (function (_Tile) {\n\t _inherits(GeoJSONTile, _Tile);\n\t\n\t function GeoJSONTile(quadcode, path, layer, options) {\n\t _classCallCheck(this, GeoJSONTile);\n\t\n\t _get(Object.getPrototypeOf(GeoJSONTile.prototype), 'constructor', this).call(this, quadcode, path, layer);\n\t\n\t this._defaultStyle = _utilGeoJSON2['default'].defaultStyle;\n\t\n\t var defaults = {\n\t workers: false,\n\t output: true,\n\t outputToScene: false,\n\t interactive: false,\n\t topojson: false,\n\t filter: null,\n\t onEachFeature: null,\n\t polygonMaterial: null,\n\t onPolygonMesh: null,\n\t onPolygonBufferAttributes: null,\n\t polylineMaterial: null,\n\t onPolylineMesh: null,\n\t onPolylineBufferAttributes: null,\n\t pointGeometry: null,\n\t pointMaterial: null,\n\t onPointMesh: null,\n\t style: _utilGeoJSON2['default'].defaultStyle,\n\t keepFeatures: false\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (typeof options.style === 'function') {\n\t _options.style = options.style;\n\t } else {\n\t _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);\n\t }\n\t\n\t this._options = _options;\n\t }\n\t\n\t // Request data for the tile\n\t\n\t _createClass(GeoJSONTile, [{\n\t key: 'requestTileAsync',\n\t value: function requestTileAsync() {\n\t var _this = this;\n\t\n\t // Making this asynchronous really speeds up the LOD framerate\n\t setTimeout(function () {\n\t if (!_this._mesh) {\n\t _this._mesh = _this._createMesh();\n\t // this._shadowCanvas = this._createShadowCanvas();\n\t }\n\t\n\t _this._requestTile();\n\t }, 0);\n\t }\n\t\n\t // TODO: Destroy GeoJSONLayer\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Cancel any pending requests\n\t this._abortRequest();\n\t\n\t // Clear request reference\n\t this._request = null;\n\t\n\t if (this._geojsonLayer) {\n\t this._geojsonLayer.destroy();\n\t this._geojsonLayer = null;\n\t }\n\t\n\t this._mesh = null;\n\t\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t\n\t _get(Object.getPrototypeOf(GeoJSONTile.prototype), 'destroy', this).call(this);\n\t }\n\t }, {\n\t key: '_createMesh',\n\t value: function _createMesh() {\n\t // Something went wrong and the tile\n\t //\n\t // Possibly removed by the cache before loaded\n\t if (!this._center) {\n\t return;\n\t }\n\t\n\t var mesh = new _three2['default'].Object3D();\n\t // mesh.add(this._createDebugMesh());\n\t\n\t return mesh;\n\t }\n\t }, {\n\t key: '_createDebugMesh',\n\t value: function _createDebugMesh() {\n\t var canvas = document.createElement('canvas');\n\t canvas.width = 256;\n\t canvas.height = 256;\n\t\n\t var context = canvas.getContext('2d');\n\t context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n\t context.fillStyle = '#ff0000';\n\t context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n\t context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\t\n\t var texture = new _three2['default'].Texture(canvas);\n\t\n\t // Silky smooth images when tilted\n\t texture.magFilter = _three2['default'].LinearFilter;\n\t texture.minFilter = _three2['default'].LinearMipMapLinearFilter;\n\t\n\t // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t texture.anisotropy = 4;\n\t\n\t texture.needsUpdate = true;\n\t\n\t var material = new _three2['default'].MeshBasicMaterial({\n\t map: texture,\n\t transparent: true,\n\t depthWrite: false\n\t });\n\t\n\t var geom = new _three2['default'].PlaneBufferGeometry(this._side, this._side, 1);\n\t var mesh = new _three2['default'].Mesh(geom, material);\n\t\n\t mesh.rotation.x = -90 * Math.PI / 180;\n\t mesh.position.y = 0.1;\n\t\n\t return mesh;\n\t }\n\t\n\t // _createShadowCanvas() {\n\t // var canvas = document.createElement('canvas');\n\t //\n\t // // Rendered at a low resolution and later scaled up for a low-quality blur\n\t // canvas.width = 512;\n\t // canvas.height = 512;\n\t //\n\t // return canvas;\n\t // }\n\t\n\t // _addShadow(coordinates) {\n\t // var ctx = this._shadowCanvas.getContext('2d');\n\t // var width = this._shadowCanvas.width;\n\t // var height = this._shadowCanvas.height;\n\t //\n\t // var _coords;\n\t // var _offset;\n\t // var offset = new Offset();\n\t //\n\t // // Transform coordinates to shadowCanvas space and draw on canvas\n\t // coordinates.forEach((ring, index) => {\n\t // ctx.beginPath();\n\t //\n\t // _coords = ring.map(coord => {\n\t // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n\t // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n\t // return [xFrac * width, yFrac * height];\n\t // });\n\t //\n\t // if (index > 0) {\n\t // _offset = _coords;\n\t // } else {\n\t // _offset = offset.data(_coords).padding(1.3);\n\t // }\n\t //\n\t // // TODO: This is super flaky and crashes the browser if run on anything\n\t // // put the outer ring (potentially due to winding)\n\t // _offset.forEach((coord, index) => {\n\t // // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n\t // // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n\t //\n\t // if (index === 0) {\n\t // ctx.moveTo(coord[0], coord[1]);\n\t // } else {\n\t // ctx.lineTo(coord[0], coord[1]);\n\t // }\n\t // });\n\t //\n\t // ctx.closePath();\n\t // });\n\t //\n\t // ctx.fillStyle = 'rgba(80, 80, 80, 0.7)';\n\t // ctx.fill();\n\t // }\n\t\n\t }, {\n\t key: '_requestTile',\n\t value: function _requestTile() {\n\t var _this2 = this;\n\t\n\t var urlParams = {\n\t x: this._tile[0],\n\t y: this._tile[1],\n\t z: this._tile[2]\n\t };\n\t\n\t var url = this._getTileURL(urlParams);\n\t\n\t this._aborted = false;\n\t\n\t if (!this._options.workers) {\n\t this._request = (0, _reqwest2['default'])({\n\t url: url,\n\t type: 'json',\n\t crossOrigin: true,\n\t headers: this._options.headers\n\t }).then(function (res) {\n\t // Clear request reference\n\t _this2._request = null;\n\t _this2._processTileData(res);\n\t })['catch'](function (err) {\n\t // Clear request reference\n\t _this2._request = null;\n\t });\n\t } else {\n\t this._processTileData(url);\n\t }\n\t }\n\t }, {\n\t key: '_processTileData',\n\t value: function _processTileData(data) {\n\t var _this3 = this;\n\t\n\t // console.time(this._tile);\n\t\n\t var GeoJSONClass = !this._options.workers ? _GeoJSONLayer.geoJSONLayer : _GeoJSONWorkerLayer.geoJSONWorkerLayer;\n\t\n\t // Using this creates a huge amount of memory due to the quantity of tiles\n\t this._geojsonLayer = GeoJSONClass(data, this._options);\n\t this._geojsonLayer.addTo(this._world).then(function () {\n\t // TODO: This never seems to be called on worker layers. Find out why.\n\t if (_this3.isAborted()) {\n\t // this._geojsonLayer._aborted = true;\n\t // this._geojsonLayer = null;\n\t return;\n\t }\n\t\n\t // TODO: This is a hack to stop old tile meshes hanging around. Fix or\n\t // move to somewhere more robust.\n\t //\n\t // Could potentially just overwrite mesh on first index each time\n\t //\n\t // This makes some worker tiles to not appear properly – showing the\n\t // points mesh but not the polygon mesh, etc.\n\t //\n\t // Only do this for non-worker layers for now as it seems to cause issues\n\t // with worker tiles showing for a moment and then disappearing forever\n\t if (!_this3._options.workers) {\n\t _this3.destroyMesh(_this3._mesh);\n\t }\n\t\n\t // TOSO: Work out if the picking mesh needs destroying here\n\t // this.destroyMesh(this._pickingMesh);\n\t\n\t _this3._mesh.add(_this3._geojsonLayer._object3D);\n\t _this3._pickingMesh = _this3._geojsonLayer._pickingMesh;\n\t\n\t // Free the GeoJSON memory as we don't need it\n\t //\n\t // TODO: This should probably be a method within GeoJSONLayer\n\t if (_this3._geojsonLayer._geojson) {\n\t _this3._geojsonLayer._geojson = null;\n\t }\n\t\n\t // TODO: Fix or store shadow canvas stuff and get rid of this code\n\t // Draw footprint on shadow canvas\n\t //\n\t // TODO: Disabled for the time-being until it can be sped up / moved to\n\t // a worker\n\t // this._addShadow(coordinates);\n\t\n\t // Output shadow canvas\n\t\n\t // TODO: Disabled for the time-being until it can be sped up / moved to\n\t // a worker\n\t\n\t // var texture = new THREE.Texture(this._shadowCanvas);\n\t //\n\t // // Silky smooth images when tilted\n\t // texture.magFilter = THREE.LinearFilter;\n\t // texture.minFilter = THREE.LinearMipMapLinearFilter;\n\t //\n\t // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n\t // texture.anisotropy = 4;\n\t //\n\t // texture.needsUpdate = true;\n\t //\n\t // var material;\n\t // if (!this._world._environment._skybox) {\n\t // material = new THREE.MeshBasicMaterial({\n\t // map: texture,\n\t // transparent: true,\n\t // depthWrite: false\n\t // });\n\t // } else {\n\t // material = new THREE.MeshStandardMaterial({\n\t // map: texture,\n\t // transparent: true,\n\t // depthWrite: false\n\t // });\n\t // material.roughness = 1;\n\t // material.metalness = 0.1;\n\t // material.envMap = this._world._environment._skybox.getRenderTarget();\n\t // }\n\t //\n\t // var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n\t // var mesh = new THREE.Mesh(geom, material);\n\t //\n\t // mesh.castShadow = false;\n\t // mesh.receiveShadow = false;\n\t // mesh.renderOrder = 1;\n\t //\n\t // mesh.rotation.x = -90 * Math.PI / 180;\n\t //\n\t // this._mesh.add(mesh);\n\t\n\t _this3._ready = true;\n\t // console.timeEnd(this._tile);\n\t })['catch'](function () {});\n\t }\n\t }, {\n\t key: '_abortRequest',\n\t value: function _abortRequest() {\n\t if (!this._request && !this._options.workers || this._ready) {\n\t return;\n\t }\n\t\n\t this._aborted = true;\n\t\n\t if (this._request) {\n\t this._request.abort();\n\t }\n\t }\n\t }]);\n\t\n\t return GeoJSONTile;\n\t})(_Tile3['default']);\n\t\n\texports['default'] = GeoJSONTile;\n\t\n\tvar noNew = function noNew(quadcode, path, layer, options) {\n\t return new GeoJSONTile(quadcode, path, layer, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.geoJSONTile = noNew;\n\n/***/ },\n/* 72 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Consider adopting GeoJSON CSS\n\t// http://wiki.openstreetmap.org/wiki/Geojson_CSS\n\t\n\t// TODO: Allow interaction to be defined per-layer to save on resources\n\t//\n\t// For example, only allow polygons to be interactive via a polygonInteractive\n\t// option\n\t\n\tvar _LayerGroup2 = __webpack_require__(54);\n\t\n\tvar _LayerGroup3 = _interopRequireDefault(_LayerGroup2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _reqwest = __webpack_require__(73);\n\t\n\tvar _reqwest2 = _interopRequireDefault(_reqwest);\n\t\n\tvar _utilGeoJSON = __webpack_require__(75);\n\t\n\tvar _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON);\n\t\n\tvar _utilBuffer = __webpack_require__(81);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _geometryPolygonLayer = __webpack_require__(84);\n\t\n\tvar _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer);\n\t\n\tvar _geometryPolylineLayer = __webpack_require__(85);\n\t\n\tvar _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer);\n\t\n\tvar _geometryPointLayer = __webpack_require__(86);\n\t\n\tvar _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer);\n\t\n\tvar GeoJSONLayer = (function (_LayerGroup) {\n\t _inherits(GeoJSONLayer, _LayerGroup);\n\t\n\t function GeoJSONLayer(geojson, options) {\n\t _classCallCheck(this, GeoJSONLayer);\n\t\n\t var defaults = {\n\t output: false,\n\t interactive: false,\n\t topojson: false,\n\t filter: null,\n\t onEachFeature: null,\n\t polygonMaterial: null,\n\t onPolygonMesh: null,\n\t onPolygonBufferAttributes: null,\n\t polylineMaterial: null,\n\t onPolylineMesh: null,\n\t onPolylineBufferAttributes: null,\n\t pointGeometry: null,\n\t pointMaterial: null,\n\t onPointMesh: null,\n\t style: _utilGeoJSON2['default'].defaultStyle,\n\t keepFeatures: true\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (typeof options.style === 'function') {\n\t _options.style = options.style;\n\t } else {\n\t _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);\n\t }\n\t\n\t _get(Object.getPrototypeOf(GeoJSONLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._geojson = geojson;\n\t }\n\t\n\t _createClass(GeoJSONLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (this.isOutput()) {\n\t this._pickingMesh = new THREE.Object3D();\n\t this.addToPicking(this._pickingMesh);\n\t }\n\t\n\t // Request data from URL if needed\n\t if (typeof this._geojson === 'string') {\n\t return this._requestData(this._geojson);\n\t } else {\n\t // Process and add GeoJSON to layer\n\t return this._processData(this._geojson);\n\t }\n\t }\n\t }, {\n\t key: '_requestData',\n\t value: function _requestData(url) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._request = (0, _reqwest2['default'])({\n\t url: url,\n\t type: 'json',\n\t crossOrigin: true\n\t }).then(function (res) {\n\t // Clear request reference\n\t _this._request = null;\n\t _this._processData(res).then(function () {\n\t resolve(_this);\n\t });\n\t })['catch'](function (err) {\n\t console.error(err);\n\t\n\t // Clear request reference\n\t _this._request = null;\n\t\n\t reject(err);\n\t });\n\t });\n\t }\n\t\n\t // TODO: Wrap into a helper method so this isn't duplicated in the tiled\n\t // GeoJSON output layer\n\t //\n\t // Need to be careful as to not make it impossible to fork this off into a\n\t // worker script at a later stage\n\t }, {\n\t key: '_processData',\n\t value: function _processData(data) {\n\t var _this2 = this;\n\t\n\t return new Promise(function (resolve) {\n\t // Collects features into a single FeatureCollection\n\t //\n\t // Also converts TopoJSON to GeoJSON if instructed\n\t _this2._geojson = _utilGeoJSON2['default'].collectFeatures(data, _this2._options.topojson);\n\t\n\t // TODO: Check that GeoJSON is valid / usable\n\t\n\t var features = _this2._geojson.features;\n\t\n\t // Run filter, if provided\n\t if (_this2._options.filter) {\n\t features = _this2._geojson.features.filter(_this2._options.filter);\n\t }\n\t\n\t var defaults = {};\n\t\n\t // Assume that a style won't be set per feature\n\t var style = _this2._options.style;\n\t\n\t var layerPromises = [];\n\t\n\t var options;\n\t features.forEach(function (feature) {\n\t // Get per-feature style object, if provided\n\t if (typeof _this2._options.style === 'function') {\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _this2._options.style(feature));\n\t }\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, {\n\t // If merging feature layers, stop them outputting themselves\n\t // If not, let feature layers output themselves to the world\n\t output: !_this2.isOutput(),\n\t interactive: _this2._options.interactive,\n\t style: style\n\t });\n\t\n\t var layer = _this2._featureToLayer(feature, options);\n\t\n\t if (!layer) {\n\t return;\n\t }\n\t\n\t // Sometimes you don't want to store a reference to the feature\n\t //\n\t // For example, to save memory when being used by tile layers\n\t if (_this2._options.keepFeatures) {\n\t layer.feature = feature;\n\t }\n\t\n\t // If defined, call a function for each feature\n\t //\n\t // This is commonly used for adding event listeners from the user script\n\t if (_this2._options.onEachFeature) {\n\t _this2._options.onEachFeature(feature, layer);\n\t }\n\t\n\t // TODO: Make this a promise array and only continue on completion\n\t layerPromises.push(_this2.addLayer(layer));\n\t });\n\t\n\t Promise.all(layerPromises).then(function (results) {\n\t // If merging layers do that now, otherwise skip as the geometry layers\n\t // should have already outputted themselves\n\t if (!_this2.isOutput()) {\n\t resolve();\n\t return;\n\t }\n\t\n\t // From here on we can assume that we want to merge the layers\n\t\n\t var polygonAttributes = [];\n\t var polygonOutlineAttributes = [];\n\t var polygonAttributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3\n\t };\n\t var polygonFlat = true;\n\t\n\t var polylineAttributes = [];\n\t var polylineAttributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t var polylineFlat = true;\n\t\n\t var pointAttributes = [];\n\t var pointAttributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3\n\t };\n\t var pointFlat = true;\n\t\n\t _this2._layers.forEach(function (layer) {\n\t if (layer instanceof _geometryPolygonLayer2['default']) {\n\t polygonAttributes.push(layer.getBufferAttributes());\n\t\n\t var outlineBufferAttributes = layer.getOutlineBufferAttributes();\n\t if (outlineBufferAttributes) {\n\t polygonOutlineAttributes.push(outlineBufferAttributes);\n\t }\n\t\n\t if (polygonFlat && !layer.isFlat()) {\n\t polygonFlat = false;\n\t }\n\t\n\t if (_this2._options.interactive) {\n\t polygonAttributeLengths.pickingIds = 1;\n\t }\n\t } else if (layer instanceof _geometryPolylineLayer2['default']) {\n\t polylineAttributes.push(layer.getBufferAttributes());\n\t\n\t if (polylineFlat && !layer.isFlat()) {\n\t polylineFlat = false;\n\t }\n\t\n\t if (_this2._options.interactive) {\n\t polylineAttributeLengths.pickingIds = 1;\n\t }\n\t } else if (layer instanceof _geometryPointLayer2['default']) {\n\t pointAttributes.push(layer.getBufferAttributes());\n\t\n\t if (pointFlat && !layer.isFlat()) {\n\t pointFlat = false;\n\t }\n\t\n\t if (_this2._options.interactive) {\n\t pointAttributeLengths.pickingIds = 1;\n\t }\n\t }\n\t });\n\t\n\t var style;\n\t\n\t if (polygonAttributes.length > 0) {\n\t var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes);\n\t\n\t var mergedPolygonOutlineAttributes;\n\t if (polygonOutlineAttributes.length > 0) {\n\t mergedPolygonOutlineAttributes = _utilBuffer2['default'].mergeAttributes(polygonOutlineAttributes);\n\t }\n\t\n\t style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this2._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat).then(function (result) {\n\t _this2._polygonMesh = result.mesh;\n\t _this2.add(_this2._polygonMesh);\n\t\n\t if (mergedPolygonOutlineAttributes) {\n\t style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t if (style.outlineRenderOrder !== undefined) {\n\t style.lineRenderOrder = style.outlineRenderOrder;\n\t } else {\n\t style.lineRenderOrder = style.renderOrder ? style.renderOrder + 1 : 4;\n\t }\n\t\n\t if (style.outlineWidth) {\n\t style.lineWidth = style.outlineWidth;\n\t }\n\t\n\t _this2._setPolylineMesh(mergedPolygonOutlineAttributes, polylineAttributeLengths, style, true).then(function (result) {\n\t _this2.add(result.mesh);\n\t });\n\t }\n\t\n\t if (result.pickingMesh) {\n\t _this2._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t if (polylineAttributes.length > 0) {\n\t var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes);\n\t\n\t style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this2._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then(function (result) {\n\t _this2._polylineMesh = result.mesh;\n\t _this2.add(_this2._polylineMesh);\n\t\n\t if (result.pickingMesh) {\n\t _this2._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t if (pointAttributes.length > 0) {\n\t var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes);\n\t\n\t style = typeof _this2._options.style === 'function' ? _this2._options.style(_this2._geojson.features[0]) : _this2._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this2._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then(function (result) {\n\t _this2._pointMesh = result.mesh;\n\t _this2.add(_this2._pointMesh);\n\t\n\t if (result.pickingMesh) {\n\t _this2._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t // Clean up layers\n\t //\n\t // TODO: Are there ever situations where the unmerged buffer attributes\n\t // and coordinates would still be required?\n\t _this2._layers.forEach(function (layer) {\n\t layer.clearBufferAttributes();\n\t layer.clearCoordinates();\n\t });\n\t\n\t resolve();\n\t });\n\t });\n\t }\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // TODO: Probably remove this and call static method directly as it's just a proxy\n\t }, {\n\t key: '_setPolygonMesh',\n\t value: function _setPolygonMesh(attributes, attributeLengths, style, flat) {\n\t return _geometryPolygonLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n\t }\n\t }, {\n\t key: '_setPolylineMesh',\n\t value: function _setPolylineMesh(attributes, attributeLengths, style, flat) {\n\t return _geometryPolylineLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options);\n\t }\n\t }, {\n\t key: '_setPointMesh',\n\t value: function _setPointMesh(attributes, attributeLengths, style, flat) {\n\t return _geometryPointLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options);\n\t }\n\t\n\t // TODO: Support all GeoJSON geometry types\n\t }, {\n\t key: '_featureToLayer',\n\t value: function _featureToLayer(feature, options) {\n\t var geometry = feature.geometry;\n\t var coordinates = geometry.coordinates ? geometry.coordinates : null;\n\t\n\t if (!coordinates || !geometry) {\n\t return;\n\t }\n\t\n\t if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n\t // Get material instance to use for polygon, if provided\n\t if (typeof this._options.polygonMaterial === 'function') {\n\t options.polygonMaterial = this._options.polygonMaterial(feature);\n\t }\n\t\n\t if (typeof this._options.onPolygonMesh === 'function') {\n\t options.onPolygonMesh = this._options.onPolygonMesh;\n\t }\n\t\n\t // Pass onBufferAttributes callback, if defined\n\t if (typeof this._options.onPolygonBufferAttributes === 'function') {\n\t options.onBufferAttributes = this._options.onPolygonBufferAttributes;\n\t }\n\t\n\t return new _geometryPolygonLayer2['default'](coordinates, options);\n\t }\n\t\n\t if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n\t // Get material instance to use for line, if provided\n\t if (typeof this._options.lineMaterial === 'function') {\n\t options.lineMaterial = this._options.lineMaterial(feature);\n\t }\n\t\n\t if (typeof this._options.onPolylineMesh === 'function') {\n\t options.onPolylineMesh = this._options.onPolylineMesh;\n\t }\n\t\n\t // Pass onBufferAttributes callback, if defined\n\t if (typeof this._options.onPolylineBufferAttributes === 'function') {\n\t options.onBufferAttributes = this._options.onPolylineBufferAttributes;\n\t }\n\t\n\t return new _geometryPolylineLayer2['default'](coordinates, options);\n\t }\n\t\n\t if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n\t // Get geometry object to use for point, if provided\n\t if (typeof this._options.pointGeometry === 'function') {\n\t options.pointGeometry = this._options.pointGeometry(feature);\n\t }\n\t\n\t // Get material instance to use for point, if provided\n\t if (typeof this._options.pointMaterial === 'function') {\n\t options.pointMaterial = this._options.pointMaterial(feature);\n\t }\n\t\n\t if (typeof this._options.onPointMesh === 'function') {\n\t options.onPointMesh = this._options.onPointMesh;\n\t }\n\t\n\t return new _geometryPointLayer2['default'](coordinates, options);\n\t }\n\t }\n\t }, {\n\t key: '_abortRequest',\n\t value: function _abortRequest() {\n\t if (!this._request) {\n\t return;\n\t }\n\t\n\t this._request.abort();\n\t }\n\t\n\t // Destroy the layers and remove them from the scene and memory\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Cancel any pending requests\n\t this._abortRequest();\n\t\n\t // Clear request reference\n\t this._request = null;\n\t\n\t this._geojson = null;\n\t\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t if (this._polygonMesh) {\n\t this._polygonMesh = null;\n\t }\n\t\n\t if (this._polylineMesh) {\n\t this._polylineMesh = null;\n\t }\n\t\n\t if (this._pointMesh) {\n\t this._pointMesh = null;\n\t }\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(GeoJSONLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }]);\n\t\n\t return GeoJSONLayer;\n\t})(_LayerGroup3['default']);\n\t\n\texports['default'] = GeoJSONLayer;\n\t\n\tvar noNew = function noNew(geojson, options) {\n\t return new GeoJSONLayer(geojson, options);\n\t};\n\t\n\texports.geoJSONLayer = noNew;\n\n/***/ },\n/* 73 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar __WEBPACK_AMD_DEFINE_FACTORY__, __WEBPACK_AMD_DEFINE_RESULT__;/*!\n\t * Reqwest! A general purpose XHR connection manager\n\t * license MIT (c) Dustin Diaz 2015\n\t * https://github.com/ded/reqwest\n\t */\n\t\n\t!function (name, context, definition) {\n\t if (typeof module != 'undefined' && module.exports) module.exports = definition()\n\t else if (true) !(__WEBPACK_AMD_DEFINE_FACTORY__ = (definition), __WEBPACK_AMD_DEFINE_RESULT__ = (typeof __WEBPACK_AMD_DEFINE_FACTORY__ === 'function' ? (__WEBPACK_AMD_DEFINE_FACTORY__.call(exports, __webpack_require__, exports, module)) : __WEBPACK_AMD_DEFINE_FACTORY__), __WEBPACK_AMD_DEFINE_RESULT__ !== undefined && (module.exports = __WEBPACK_AMD_DEFINE_RESULT__))\n\t else context[name] = definition()\n\t}('reqwest', this, function () {\n\t\n\t var context = this\n\t\n\t if ('window' in context) {\n\t var doc = document\n\t , byTag = 'getElementsByTagName'\n\t , head = doc[byTag]('head')[0]\n\t } else {\n\t var XHR2\n\t try {\n\t XHR2 = __webpack_require__(74)\n\t } catch (ex) {\n\t throw new Error('Peer dependency `xhr2` required! Please npm install xhr2')\n\t }\n\t }\n\t\n\t\n\t var httpsRe = /^http/\n\t , protocolRe = /(^\\w+):\\/\\//\n\t , twoHundo = /^(20\\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\n\t , readyState = 'readyState'\n\t , contentType = 'Content-Type'\n\t , requestedWith = 'X-Requested-With'\n\t , uniqid = 0\n\t , callbackPrefix = 'reqwest_' + (+new Date())\n\t , lastValue // data stored by the most recent JSONP callback\n\t , xmlHttpRequest = 'XMLHttpRequest'\n\t , xDomainRequest = 'XDomainRequest'\n\t , noop = function () {}\n\t\n\t , isArray = typeof Array.isArray == 'function'\n\t ? Array.isArray\n\t : function (a) {\n\t return a instanceof Array\n\t }\n\t\n\t , defaultHeaders = {\n\t 'contentType': 'application/x-www-form-urlencoded'\n\t , 'requestedWith': xmlHttpRequest\n\t , 'accept': {\n\t '*': 'text/javascript, text/html, application/xml, text/xml, */*'\n\t , 'xml': 'application/xml, text/xml'\n\t , 'html': 'text/html'\n\t , 'text': 'text/plain'\n\t , 'json': 'application/json, text/javascript'\n\t , 'js': 'application/javascript, text/javascript'\n\t }\n\t }\n\t\n\t , xhr = function(o) {\n\t // is it x-domain\n\t if (o['crossOrigin'] === true) {\n\t var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null\n\t if (xhr && 'withCredentials' in xhr) {\n\t return xhr\n\t } else if (context[xDomainRequest]) {\n\t return new XDomainRequest()\n\t } else {\n\t throw new Error('Browser does not support cross-origin requests')\n\t }\n\t } else if (context[xmlHttpRequest]) {\n\t return new XMLHttpRequest()\n\t } else if (XHR2) {\n\t return new XHR2()\n\t } else {\n\t return new ActiveXObject('Microsoft.XMLHTTP')\n\t }\n\t }\n\t , globalSetupOptions = {\n\t dataFilter: function (data) {\n\t return data\n\t }\n\t }\n\t\n\t function succeed(r) {\n\t var protocol = protocolRe.exec(r.url)\n\t protocol = (protocol && protocol[1]) || context.location.protocol\n\t return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response\n\t }\n\t\n\t function handleReadyState(r, success, error) {\n\t return function () {\n\t // use _aborted to mitigate against IE err c00c023f\n\t // (can't read props on aborted request objects)\n\t if (r._aborted) return error(r.request)\n\t if (r._timedOut) return error(r.request, 'Request is aborted: timeout')\n\t if (r.request && r.request[readyState] == 4) {\n\t r.request.onreadystatechange = noop\n\t if (succeed(r)) success(r.request)\n\t else\n\t error(r.request)\n\t }\n\t }\n\t }\n\t\n\t function setHeaders(http, o) {\n\t var headers = o['headers'] || {}\n\t , h\n\t\n\t headers['Accept'] = headers['Accept']\n\t || defaultHeaders['accept'][o['type']]\n\t || defaultHeaders['accept']['*']\n\t\n\t var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData);\n\t // breaks cross-origin requests with legacy browsers\n\t if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']\n\t if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']\n\t for (h in headers)\n\t headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])\n\t }\n\t\n\t function setCredentials(http, o) {\n\t if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n\t http.withCredentials = !!o['withCredentials']\n\t }\n\t }\n\t\n\t function generalCallback(data) {\n\t lastValue = data\n\t }\n\t\n\t function urlappend (url, s) {\n\t return url + (/\\?/.test(url) ? '&' : '?') + s\n\t }\n\t\n\t function handleJsonp(o, fn, err, url) {\n\t var reqId = uniqid++\n\t , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key\n\t , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)\n\t , cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)')\n\t , match = url.match(cbreg)\n\t , script = doc.createElement('script')\n\t , loaded = 0\n\t , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1\n\t\n\t if (match) {\n\t if (match[3] === '?') {\n\t url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name\n\t } else {\n\t cbval = match[3] // provided callback func name\n\t }\n\t } else {\n\t url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em\n\t }\n\t\n\t context[cbval] = generalCallback\n\t\n\t script.type = 'text/javascript'\n\t script.src = url\n\t script.async = true\n\t if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n\t // need this for IE due to out-of-order onreadystatechange(), binding script\n\t // execution to an event listener gives us control over when the script\n\t // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n\t script.htmlFor = script.id = '_reqwest_' + reqId\n\t }\n\t\n\t script.onload = script.onreadystatechange = function () {\n\t if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {\n\t return false\n\t }\n\t script.onload = script.onreadystatechange = null\n\t script.onclick && script.onclick()\n\t // Call the user callback with the last value stored and clean up values and scripts.\n\t fn(lastValue)\n\t lastValue = undefined\n\t head.removeChild(script)\n\t loaded = 1\n\t }\n\t\n\t // Add the script to the DOM head\n\t head.appendChild(script)\n\t\n\t // Enable JSONP timeout\n\t return {\n\t abort: function () {\n\t script.onload = script.onreadystatechange = null\n\t err({}, 'Request is aborted: timeout', {})\n\t lastValue = undefined\n\t head.removeChild(script)\n\t loaded = 1\n\t }\n\t }\n\t }\n\t\n\t function getRequest(fn, err) {\n\t var o = this.o\n\t , method = (o['method'] || 'GET').toUpperCase()\n\t , url = typeof o === 'string' ? o : o['url']\n\t // convert non-string objects to query-string form unless o['processData'] is false\n\t , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')\n\t ? reqwest.toQueryString(o['data'])\n\t : (o['data'] || null)\n\t , http\n\t , sendWait = false\n\t\n\t // if we're working on a GET request and we have data then we should append\n\t // query string to end of URL and not post data\n\t if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n\t url = urlappend(url, data)\n\t data = null\n\t }\n\t\n\t if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)\n\t\n\t // get the xhr from the factory if passed\n\t // if the factory returns null, fall-back to ours\n\t http = (o.xhr && o.xhr(o)) || xhr(o)\n\t\n\t http.open(method, url, o['async'] === false ? false : true)\n\t setHeaders(http, o)\n\t setCredentials(http, o)\n\t if (context[xDomainRequest] && http instanceof context[xDomainRequest]) {\n\t http.onload = fn\n\t http.onerror = err\n\t // NOTE: see\n\t // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e\n\t http.onprogress = function() {}\n\t sendWait = true\n\t } else {\n\t http.onreadystatechange = handleReadyState(this, fn, err)\n\t }\n\t o['before'] && o['before'](http)\n\t if (sendWait) {\n\t setTimeout(function () {\n\t http.send(data)\n\t }, 200)\n\t } else {\n\t http.send(data)\n\t }\n\t return http\n\t }\n\t\n\t function Reqwest(o, fn) {\n\t this.o = o\n\t this.fn = fn\n\t\n\t init.apply(this, arguments)\n\t }\n\t\n\t function setType(header) {\n\t // json, javascript, text/plain, text/html, xml\n\t if (header === null) return undefined; //In case of no content-type.\n\t if (header.match('json')) return 'json'\n\t if (header.match('javascript')) return 'js'\n\t if (header.match('text')) return 'html'\n\t if (header.match('xml')) return 'xml'\n\t }\n\t\n\t function init(o, fn) {\n\t\n\t this.url = typeof o == 'string' ? o : o['url']\n\t this.timeout = null\n\t\n\t // whether request has been fulfilled for purpose\n\t // of tracking the Promises\n\t this._fulfilled = false\n\t // success handlers\n\t this._successHandler = function(){}\n\t this._fulfillmentHandlers = []\n\t // error handlers\n\t this._errorHandlers = []\n\t // complete (both success and fail) handlers\n\t this._completeHandlers = []\n\t this._erred = false\n\t this._responseArgs = {}\n\t\n\t var self = this\n\t\n\t fn = fn || function () {}\n\t\n\t if (o['timeout']) {\n\t this.timeout = setTimeout(function () {\n\t timedOut()\n\t }, o['timeout'])\n\t }\n\t\n\t if (o['success']) {\n\t this._successHandler = function () {\n\t o['success'].apply(o, arguments)\n\t }\n\t }\n\t\n\t if (o['error']) {\n\t this._errorHandlers.push(function () {\n\t o['error'].apply(o, arguments)\n\t })\n\t }\n\t\n\t if (o['complete']) {\n\t this._completeHandlers.push(function () {\n\t o['complete'].apply(o, arguments)\n\t })\n\t }\n\t\n\t function complete (resp) {\n\t o['timeout'] && clearTimeout(self.timeout)\n\t self.timeout = null\n\t while (self._completeHandlers.length > 0) {\n\t self._completeHandlers.shift()(resp)\n\t }\n\t }\n\t\n\t function success (resp) {\n\t var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE\n\t resp = (type !== 'jsonp') ? self.request : resp\n\t // use global data filter on response text\n\t var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)\n\t , r = filteredResponse\n\t try {\n\t resp.responseText = r\n\t } catch (e) {\n\t // can't assign this in IE<=8, just ignore\n\t }\n\t if (r) {\n\t switch (type) {\n\t case 'json':\n\t try {\n\t resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')')\n\t } catch (err) {\n\t return error(resp, 'Could not parse JSON in response', err)\n\t }\n\t break\n\t case 'js':\n\t resp = eval(r)\n\t break\n\t case 'html':\n\t resp = r\n\t break\n\t case 'xml':\n\t resp = resp.responseXML\n\t && resp.responseXML.parseError // IE trololo\n\t && resp.responseXML.parseError.errorCode\n\t && resp.responseXML.parseError.reason\n\t ? null\n\t : resp.responseXML\n\t break\n\t }\n\t }\n\t\n\t self._responseArgs.resp = resp\n\t self._fulfilled = true\n\t fn(resp)\n\t self._successHandler(resp)\n\t while (self._fulfillmentHandlers.length > 0) {\n\t resp = self._fulfillmentHandlers.shift()(resp)\n\t }\n\t\n\t complete(resp)\n\t }\n\t\n\t function timedOut() {\n\t self._timedOut = true\n\t self.request.abort()\n\t }\n\t\n\t function error(resp, msg, t) {\n\t resp = self.request\n\t self._responseArgs.resp = resp\n\t self._responseArgs.msg = msg\n\t self._responseArgs.t = t\n\t self._erred = true\n\t while (self._errorHandlers.length > 0) {\n\t self._errorHandlers.shift()(resp, msg, t)\n\t }\n\t complete(resp)\n\t }\n\t\n\t this.request = getRequest.call(this, success, error)\n\t }\n\t\n\t Reqwest.prototype = {\n\t abort: function () {\n\t this._aborted = true\n\t this.request.abort()\n\t }\n\t\n\t , retry: function () {\n\t init.call(this, this.o, this.fn)\n\t }\n\t\n\t /**\n\t * Small deviation from the Promises A CommonJs specification\n\t * http://wiki.commonjs.org/wiki/Promises/A\n\t */\n\t\n\t /**\n\t * `then` will execute upon successful requests\n\t */\n\t , then: function (success, fail) {\n\t success = success || function () {}\n\t fail = fail || function () {}\n\t if (this._fulfilled) {\n\t this._responseArgs.resp = success(this._responseArgs.resp)\n\t } else if (this._erred) {\n\t fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n\t } else {\n\t this._fulfillmentHandlers.push(success)\n\t this._errorHandlers.push(fail)\n\t }\n\t return this\n\t }\n\t\n\t /**\n\t * `always` will execute whether the request succeeds or fails\n\t */\n\t , always: function (fn) {\n\t if (this._fulfilled || this._erred) {\n\t fn(this._responseArgs.resp)\n\t } else {\n\t this._completeHandlers.push(fn)\n\t }\n\t return this\n\t }\n\t\n\t /**\n\t * `fail` will execute when the request fails\n\t */\n\t , fail: function (fn) {\n\t if (this._erred) {\n\t fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n\t } else {\n\t this._errorHandlers.push(fn)\n\t }\n\t return this\n\t }\n\t , 'catch': function (fn) {\n\t return this.fail(fn)\n\t }\n\t }\n\t\n\t function reqwest(o, fn) {\n\t return new Reqwest(o, fn)\n\t }\n\t\n\t // normalize newline variants according to spec -> CRLF\n\t function normalize(s) {\n\t return s ? s.replace(/\\r?\\n/g, '\\r\\n') : ''\n\t }\n\t\n\t function serial(el, cb) {\n\t var n = el.name\n\t , t = el.tagName.toLowerCase()\n\t , optCb = function (o) {\n\t // IE gives value=\"\" even where there is no value attribute\n\t // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273\n\t if (o && !o['disabled'])\n\t cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))\n\t }\n\t , ch, ra, val, i\n\t\n\t // don't serialize elements that are disabled or without a name\n\t if (el.disabled || !n) return\n\t\n\t switch (t) {\n\t case 'input':\n\t if (!/reset|button|image|file/i.test(el.type)) {\n\t ch = /checkbox/i.test(el.type)\n\t ra = /radio/i.test(el.type)\n\t val = el.value\n\t // WebKit gives us \"\" instead of \"on\" if a checkbox has no value, so correct it here\n\t ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))\n\t }\n\t break\n\t case 'textarea':\n\t cb(n, normalize(el.value))\n\t break\n\t case 'select':\n\t if (el.type.toLowerCase() === 'select-one') {\n\t optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)\n\t } else {\n\t for (i = 0; el.length && i < el.length; i++) {\n\t el.options[i].selected && optCb(el.options[i])\n\t }\n\t }\n\t break\n\t }\n\t }\n\t\n\t // collect up all form elements found from the passed argument elements all\n\t // the way down to child elements; pass a '' or form fields.\n\t // called with 'this'=callback to use for serial() on each element\n\t function eachFormElement() {\n\t var cb = this\n\t , e, i\n\t , serializeSubtags = function (e, tags) {\n\t var i, j, fa\n\t for (i = 0; i < tags.length; i++) {\n\t fa = e[byTag](tags[i])\n\t for (j = 0; j < fa.length; j++) serial(fa[j], cb)\n\t }\n\t }\n\t\n\t for (i = 0; i < arguments.length; i++) {\n\t e = arguments[i]\n\t if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)\n\t serializeSubtags(e, [ 'input', 'select', 'textarea' ])\n\t }\n\t }\n\t\n\t // standard query string style serialization\n\t function serializeQueryString() {\n\t return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))\n\t }\n\t\n\t // { 'name': 'value', ... } style serialization\n\t function serializeHash() {\n\t var hash = {}\n\t eachFormElement.apply(function (name, value) {\n\t if (name in hash) {\n\t hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])\n\t hash[name].push(value)\n\t } else hash[name] = value\n\t }, arguments)\n\t return hash\n\t }\n\t\n\t // [ { name: 'name', value: 'value' }, ... ] style serialization\n\t reqwest.serializeArray = function () {\n\t var arr = []\n\t eachFormElement.apply(function (name, value) {\n\t arr.push({name: name, value: value})\n\t }, arguments)\n\t return arr\n\t }\n\t\n\t reqwest.serialize = function () {\n\t if (arguments.length === 0) return ''\n\t var opt, fn\n\t , args = Array.prototype.slice.call(arguments, 0)\n\t\n\t opt = args.pop()\n\t opt && opt.nodeType && args.push(opt) && (opt = null)\n\t opt && (opt = opt.type)\n\t\n\t if (opt == 'map') fn = serializeHash\n\t else if (opt == 'array') fn = reqwest.serializeArray\n\t else fn = serializeQueryString\n\t\n\t return fn.apply(null, args)\n\t }\n\t\n\t reqwest.toQueryString = function (o, trad) {\n\t var prefix, i\n\t , traditional = trad || false\n\t , s = []\n\t , enc = encodeURIComponent\n\t , add = function (key, value) {\n\t // If value is a function, invoke it and return its value\n\t value = ('function' === typeof value) ? value() : (value == null ? '' : value)\n\t s[s.length] = enc(key) + '=' + enc(value)\n\t }\n\t // If an array was passed in, assume that it is an array of form elements.\n\t if (isArray(o)) {\n\t for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])\n\t } else {\n\t // If traditional, encode the \"old\" way (the way 1.3.2 or older\n\t // did it), otherwise encode params recursively.\n\t for (prefix in o) {\n\t if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)\n\t }\n\t }\n\t\n\t // spaces should be + according to spec\n\t return s.join('&').replace(/%20/g, '+')\n\t }\n\t\n\t function buildParams(prefix, obj, traditional, add) {\n\t var name, i, v\n\t , rbracket = /\\[\\]$/\n\t\n\t if (isArray(obj)) {\n\t // Serialize array item.\n\t for (i = 0; obj && i < obj.length; i++) {\n\t v = obj[i]\n\t if (traditional || rbracket.test(prefix)) {\n\t // Treat each array item as a scalar.\n\t add(prefix, v)\n\t } else {\n\t buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)\n\t }\n\t }\n\t } else if (obj && obj.toString() === '[object Object]') {\n\t // Serialize object item.\n\t for (name in obj) {\n\t buildParams(prefix + '[' + name + ']', obj[name], traditional, add)\n\t }\n\t\n\t } else {\n\t // Serialize scalar item.\n\t add(prefix, obj)\n\t }\n\t }\n\t\n\t reqwest.getcallbackPrefix = function () {\n\t return callbackPrefix\n\t }\n\t\n\t // jQuery and Zepto compatibility, differences can be remapped here so you can call\n\t // .ajax.compat(options, callback)\n\t reqwest.compat = function (o, fn) {\n\t if (o) {\n\t o['type'] && (o['method'] = o['type']) && delete o['type']\n\t o['dataType'] && (o['type'] = o['dataType'])\n\t o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']\n\t o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])\n\t }\n\t return new Reqwest(o, fn)\n\t }\n\t\n\t reqwest.ajaxSetup = function (options) {\n\t options = options || {}\n\t for (var k in options) {\n\t globalSetupOptions[k] = options[k]\n\t }\n\t }\n\t\n\t return reqwest\n\t});\n\n\n/***/ },\n/* 74 */\n/***/ function(module, exports) {\n\n\t/* (ignored) */\n\n/***/ },\n/* 75 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireWildcard(obj) { if (obj && obj.__esModule) { return obj; } else { var newObj = {}; if (obj != null) { for (var key in obj) { if (Object.prototype.hasOwnProperty.call(obj, key)) newObj[key] = obj[key]; } } newObj['default'] = obj; return newObj; } }\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * GeoJSON helpers for handling data and generating objects\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _topojson2 = __webpack_require__(76);\n\t\n\tvar topojson = _interopRequireWildcard(_topojson2);\n\t\n\tvar _geojsonMerge = __webpack_require__(77);\n\t\n\tvar _geojsonMerge2 = _interopRequireDefault(_geojsonMerge);\n\t\n\tvar _earcut = __webpack_require__(79);\n\t\n\tvar _earcut2 = _interopRequireDefault(_earcut);\n\t\n\tvar _extrudePolygon = __webpack_require__(80);\n\t\n\tvar _extrudePolygon2 = _interopRequireDefault(_extrudePolygon);\n\t\n\t// TODO: Make it so height can be per-coordinate / point but connected together\n\t// as a linestring (eg. GPS points with an elevation at each point)\n\t//\n\t// This isn't really valid GeoJSON so perhaps something best left to an external\n\t// component for now, until a better approach can be considered\n\t//\n\t// See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html\n\t\n\t// Light and dark colours used for poor-mans AO gradient on object sides\n\tvar light = new _three2['default'].Color(0xffffff);\n\tvar shadow = new _three2['default'].Color(0x666666);\n\t\n\tvar GeoJSON = (function () {\n\t var defaultStyle = {\n\t color: '#ffffff',\n\t outline: false,\n\t outlineColor: '#000000',\n\t transparent: false,\n\t opacity: 1,\n\t blending: _three2['default'].NormalBlending,\n\t height: 0,\n\t lineOpacity: 1,\n\t lineTransparent: false,\n\t lineColor: '#ffffff',\n\t lineWidth: 1,\n\t lineBlending: _three2['default'].NormalBlending\n\t };\n\t\n\t // Attempts to merge together multiple GeoJSON Features or FeatureCollections\n\t // into a single FeatureCollection\n\t var collectFeatures = function collectFeatures(data, _topojson) {\n\t var collections = [];\n\t\n\t if (_topojson) {\n\t // TODO: Allow TopoJSON objects to be overridden as an option\n\t\n\t // If not overridden, merge all features from all objects\n\t for (var tk in data.objects) {\n\t collections.push(topojson.feature(data, data.objects[tk]));\n\t }\n\t\n\t return (0, _geojsonMerge2['default'])(collections);\n\t } else {\n\t // If root doesn't have a type then let's see if there are features in the\n\t // next step down\n\t if (!data.type) {\n\t // TODO: Allow GeoJSON objects to be overridden as an option\n\t\n\t // If not overridden, merge all features from all objects\n\t for (var gk in data) {\n\t if (!data[gk].type) {\n\t continue;\n\t }\n\t\n\t collections.push(data[gk]);\n\t }\n\t\n\t return (0, _geojsonMerge2['default'])(collections);\n\t } else if (Array.isArray(data)) {\n\t return (0, _geojsonMerge2['default'])(data);\n\t } else {\n\t return data;\n\t }\n\t }\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var lineStringAttributes = function lineStringAttributes(coordinates, colour, height) {\n\t var _coords = [];\n\t var _colours = [];\n\t\n\t var nextCoord;\n\t\n\t // Connect coordinate with the next to make a pair\n\t //\n\t // LineSegments requires pairs of vertices so repeat the last point if\n\t // there's an odd number of vertices\n\t coordinates.forEach(function (coordinate, index) {\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _coords.push([coordinate[0], height, coordinate[1]]);\n\t\n\t nextCoord = coordinates[index + 1] ? coordinates[index + 1] : coordinate;\n\t\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _coords.push([nextCoord[0], height, nextCoord[1]]);\n\t });\n\t\n\t return {\n\t vertices: _coords,\n\t colours: _colours\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var multiLineStringAttributes = function multiLineStringAttributes(coordinates, colour, height) {\n\t var _coords = [];\n\t var _colours = [];\n\t\n\t var result;\n\t coordinates.forEach(function (coordinate) {\n\t result = lineStringAttributes(coordinate, colour, height);\n\t\n\t result.vertices.forEach(function (coord) {\n\t _coords.push(coord);\n\t });\n\t\n\t result.colours.forEach(function (colour) {\n\t _colours.push(colour);\n\t });\n\t });\n\t\n\t return {\n\t vertices: _coords,\n\t colours: _colours\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var polygonAttributes = function polygonAttributes(coordinates, colour, height) {\n\t var earcutData = _toEarcut(coordinates);\n\t\n\t var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions);\n\t\n\t var groupedVertices = [];\n\t for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) {\n\t groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions));\n\t }\n\t\n\t var extruded = (0, _extrudePolygon2['default'])(groupedVertices, faces, {\n\t bottom: 0,\n\t top: height\n\t });\n\t\n\t var topColor = colour.clone().multiply(light);\n\t var bottomColor = colour.clone().multiply(shadow);\n\t\n\t var _vertices = extruded.positions;\n\t var _faces = [];\n\t var _colours = [];\n\t\n\t var _colour;\n\t extruded.top.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t\n\t var allFlat = true;\n\t\n\t if (extruded.sides) {\n\t if (allFlat) {\n\t allFlat = false;\n\t }\n\t\n\t // Set up colours for every vertex with poor-mans AO on the sides\n\t extruded.sides.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t // First face is always bottom-bottom-top\n\t if (fi % 2 === 0) {\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t // Reverse winding for the second face\n\t // top-top-bottom\n\t } else {\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t }\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t }\n\t\n\t // Skip bottom as there's no point rendering it\n\t // allFaces.push(extruded.faces);\n\t\n\t return {\n\t vertices: _vertices,\n\t faces: _faces,\n\t colours: _colours,\n\t flat: allFlat\n\t };\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var _toEarcut = function _toEarcut(data) {\n\t var dim = data[0][0].length;\n\t var result = { vertices: [], holes: [], dimensions: dim };\n\t var holeIndex = 0;\n\t\n\t for (var i = 0; i < data.length; i++) {\n\t for (var j = 0; j < data[i].length; j++) {\n\t for (var d = 0; d < dim; d++) {\n\t result.vertices.push(data[i][j][d]);\n\t }\n\t }\n\t if (i > 0) {\n\t holeIndex += data[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t\n\t return result;\n\t };\n\t\n\t // TODO: This is only used by GeoJSONTile so either roll it into that or\n\t // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n\t var _triangulate = function _triangulate(contour, holes, dim) {\n\t // console.time('earcut');\n\t\n\t var faces = (0, _earcut2['default'])(contour, holes, dim);\n\t var result = [];\n\t\n\t for (i = 0, il = faces.length; i < il; i += 3) {\n\t result.push(faces.slice(i, i + 3));\n\t }\n\t\n\t // console.timeEnd('earcut');\n\t\n\t return result;\n\t };\n\t\n\t return {\n\t defaultStyle: defaultStyle,\n\t collectFeatures: collectFeatures,\n\t lineStringAttributes: lineStringAttributes,\n\t multiLineStringAttributes: multiLineStringAttributes,\n\t polygonAttributes: polygonAttributes\n\t };\n\t})();\n\t\n\texports['default'] = GeoJSON;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 76 */\n/***/ function(module, exports, __webpack_require__) {\n\n\t(function (global, factory) {\n\t true ? factory(exports) :\n\t typeof define === 'function' && define.amd ? define(['exports'], factory) :\n\t (factory((global.topojson = global.topojson || {})));\n\t}(this, (function (exports) { 'use strict';\n\t\n\tfunction noop() {}\n\t\n\tfunction transformAbsolute(transform) {\n\t if (!transform) return noop;\n\t var x0,\n\t y0,\n\t kx = transform.scale[0],\n\t ky = transform.scale[1],\n\t dx = transform.translate[0],\n\t dy = transform.translate[1];\n\t return function(point, i) {\n\t if (!i) x0 = y0 = 0;\n\t point[0] = (x0 += point[0]) * kx + dx;\n\t point[1] = (y0 += point[1]) * ky + dy;\n\t };\n\t}\n\t\n\tfunction transformRelative(transform) {\n\t if (!transform) return noop;\n\t var x0,\n\t y0,\n\t kx = transform.scale[0],\n\t ky = transform.scale[1],\n\t dx = transform.translate[0],\n\t dy = transform.translate[1];\n\t return function(point, i) {\n\t if (!i) x0 = y0 = 0;\n\t var x1 = Math.round((point[0] - dx) / kx),\n\t y1 = Math.round((point[1] - dy) / ky);\n\t point[0] = x1 - x0;\n\t point[1] = y1 - y0;\n\t x0 = x1;\n\t y0 = y1;\n\t };\n\t}\n\t\n\tfunction reverse(array, n) {\n\t var t, j = array.length, i = j - n;\n\t while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n\t}\n\t\n\tfunction bisect(a, x) {\n\t var lo = 0, hi = a.length;\n\t while (lo < hi) {\n\t var mid = lo + hi >>> 1;\n\t if (a[mid] < x) lo = mid + 1;\n\t else hi = mid;\n\t }\n\t return lo;\n\t}\n\t\n\tfunction feature(topology, o) {\n\t return o.type === \"GeometryCollection\" ? {\n\t type: \"FeatureCollection\",\n\t features: o.geometries.map(function(o) { return feature$1(topology, o); })\n\t } : feature$1(topology, o);\n\t}\n\t\n\tfunction feature$1(topology, o) {\n\t var f = {\n\t type: \"Feature\",\n\t id: o.id,\n\t properties: o.properties || {},\n\t geometry: object(topology, o)\n\t };\n\t if (o.id == null) delete f.id;\n\t return f;\n\t}\n\t\n\tfunction object(topology, o) {\n\t var absolute = transformAbsolute(topology.transform),\n\t arcs = topology.arcs;\n\t\n\t function arc(i, points) {\n\t if (points.length) points.pop();\n\t for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {\n\t points.push(p = a[k].slice());\n\t absolute(p, k);\n\t }\n\t if (i < 0) reverse(points, n);\n\t }\n\t\n\t function point(p) {\n\t p = p.slice();\n\t absolute(p, 0);\n\t return p;\n\t }\n\t\n\t function line(arcs) {\n\t var points = [];\n\t for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n\t if (points.length < 2) points.push(points[0].slice());\n\t return points;\n\t }\n\t\n\t function ring(arcs) {\n\t var points = line(arcs);\n\t while (points.length < 4) points.push(points[0].slice());\n\t return points;\n\t }\n\t\n\t function polygon(arcs) {\n\t return arcs.map(ring);\n\t }\n\t\n\t function geometry(o) {\n\t var t = o.type;\n\t return t === \"GeometryCollection\" ? {type: t, geometries: o.geometries.map(geometry)}\n\t : t in geometryType ? {type: t, coordinates: geometryType[t](o)}\n\t : null;\n\t }\n\t\n\t var geometryType = {\n\t Point: function(o) { return point(o.coordinates); },\n\t MultiPoint: function(o) { return o.coordinates.map(point); },\n\t LineString: function(o) { return line(o.arcs); },\n\t MultiLineString: function(o) { return o.arcs.map(line); },\n\t Polygon: function(o) { return polygon(o.arcs); },\n\t MultiPolygon: function(o) { return o.arcs.map(polygon); }\n\t };\n\t\n\t return geometry(o);\n\t}\n\t\n\tfunction stitchArcs(topology, arcs) {\n\t var stitchedArcs = {},\n\t fragmentByStart = {},\n\t fragmentByEnd = {},\n\t fragments = [],\n\t emptyIndex = -1;\n\t\n\t // Stitch empty arcs first, since they may be subsumed by other arcs.\n\t arcs.forEach(function(i, j) {\n\t var arc = topology.arcs[i < 0 ? ~i : i], t;\n\t if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n\t t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n\t }\n\t });\n\t\n\t arcs.forEach(function(i) {\n\t var e = ends(i),\n\t start = e[0],\n\t end = e[1],\n\t f, g;\n\t\n\t if (f = fragmentByEnd[start]) {\n\t delete fragmentByEnd[f.end];\n\t f.push(i);\n\t f.end = end;\n\t if (g = fragmentByStart[end]) {\n\t delete fragmentByStart[g.start];\n\t var fg = g === f ? f : f.concat(g);\n\t fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n\t } else {\n\t fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n\t }\n\t } else if (f = fragmentByStart[end]) {\n\t delete fragmentByStart[f.start];\n\t f.unshift(i);\n\t f.start = start;\n\t if (g = fragmentByEnd[start]) {\n\t delete fragmentByEnd[g.end];\n\t var gf = g === f ? f : g.concat(f);\n\t fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n\t } else {\n\t fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n\t }\n\t } else {\n\t f = [i];\n\t fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n\t }\n\t });\n\t\n\t function ends(i) {\n\t var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n\t if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n\t else p1 = arc[arc.length - 1];\n\t return i < 0 ? [p1, p0] : [p0, p1];\n\t }\n\t\n\t function flush(fragmentByEnd, fragmentByStart) {\n\t for (var k in fragmentByEnd) {\n\t var f = fragmentByEnd[k];\n\t delete fragmentByStart[f.start];\n\t delete f.start;\n\t delete f.end;\n\t f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n\t fragments.push(f);\n\t }\n\t }\n\t\n\t flush(fragmentByEnd, fragmentByStart);\n\t flush(fragmentByStart, fragmentByEnd);\n\t arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\t\n\t return fragments;\n\t}\n\t\n\tfunction mesh(topology) {\n\t return object(topology, meshArcs.apply(this, arguments));\n\t}\n\t\n\tfunction meshArcs(topology, o, filter) {\n\t var arcs = [];\n\t\n\t function arc(i) {\n\t var j = i < 0 ? ~i : i;\n\t (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n\t }\n\t\n\t function line(arcs) {\n\t arcs.forEach(arc);\n\t }\n\t\n\t function polygon(arcs) {\n\t arcs.forEach(line);\n\t }\n\t\n\t function geometry(o) {\n\t if (o.type === \"GeometryCollection\") o.geometries.forEach(geometry);\n\t else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);\n\t }\n\t\n\t if (arguments.length > 1) {\n\t var geomsByArc = [],\n\t geom;\n\t\n\t var geometryType = {\n\t LineString: line,\n\t MultiLineString: polygon,\n\t Polygon: polygon,\n\t MultiPolygon: function(arcs) { arcs.forEach(polygon); }\n\t };\n\t\n\t geometry(o);\n\t\n\t geomsByArc.forEach(arguments.length < 3\n\t ? function(geoms) { arcs.push(geoms[0].i); }\n\t : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n\t } else {\n\t for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);\n\t }\n\t\n\t return {type: \"MultiLineString\", arcs: stitchArcs(topology, arcs)};\n\t}\n\t\n\tfunction cartesianTriangleArea(triangle) {\n\t var a = triangle[0], b = triangle[1], c = triangle[2];\n\t return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));\n\t}\n\t\n\tfunction ring(ring) {\n\t var i = -1,\n\t n = ring.length,\n\t a,\n\t b = ring[n - 1],\n\t area = 0;\n\t\n\t while (++i < n) {\n\t a = b;\n\t b = ring[i];\n\t area += a[0] * b[1] - a[1] * b[0];\n\t }\n\t\n\t return area / 2;\n\t}\n\t\n\tfunction merge(topology) {\n\t return object(topology, mergeArcs.apply(this, arguments));\n\t}\n\t\n\tfunction mergeArcs(topology, objects) {\n\t var polygonsByArc = {},\n\t polygons = [],\n\t components = [];\n\t\n\t objects.forEach(function(o) {\n\t if (o.type === \"Polygon\") register(o.arcs);\n\t else if (o.type === \"MultiPolygon\") o.arcs.forEach(register);\n\t });\n\t\n\t function register(polygon) {\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n\t });\n\t });\n\t polygons.push(polygon);\n\t }\n\t\n\t function area(ring$$) {\n\t return Math.abs(ring(object(topology, {type: \"Polygon\", arcs: [ring$$]}).coordinates[0]));\n\t }\n\t\n\t polygons.forEach(function(polygon) {\n\t if (!polygon._) {\n\t var component = [],\n\t neighbors = [polygon];\n\t polygon._ = 1;\n\t components.push(component);\n\t while (polygon = neighbors.pop()) {\n\t component.push(polygon);\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n\t if (!polygon._) {\n\t polygon._ = 1;\n\t neighbors.push(polygon);\n\t }\n\t });\n\t });\n\t });\n\t }\n\t }\n\t });\n\t\n\t polygons.forEach(function(polygon) {\n\t delete polygon._;\n\t });\n\t\n\t return {\n\t type: \"MultiPolygon\",\n\t arcs: components.map(function(polygons) {\n\t var arcs = [], n;\n\t\n\t // Extract the exterior (unique) arcs.\n\t polygons.forEach(function(polygon) {\n\t polygon.forEach(function(ring$$) {\n\t ring$$.forEach(function(arc) {\n\t if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n\t arcs.push(arc);\n\t }\n\t });\n\t });\n\t });\n\t\n\t // Stitch the arcs into one or more rings.\n\t arcs = stitchArcs(topology, arcs);\n\t\n\t // If more than one ring is returned,\n\t // at most one of these rings can be the exterior;\n\t // choose the one with the greatest absolute area.\n\t if ((n = arcs.length) > 1) {\n\t for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n\t if ((ki = area(arcs[i])) > k) {\n\t t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n\t }\n\t }\n\t }\n\t\n\t return arcs;\n\t })\n\t };\n\t}\n\t\n\tfunction neighbors(objects) {\n\t var indexesByArc = {}, // arc index -> array of object indexes\n\t neighbors = objects.map(function() { return []; });\n\t\n\t function line(arcs, i) {\n\t arcs.forEach(function(a) {\n\t if (a < 0) a = ~a;\n\t var o = indexesByArc[a];\n\t if (o) o.push(i);\n\t else indexesByArc[a] = [i];\n\t });\n\t }\n\t\n\t function polygon(arcs, i) {\n\t arcs.forEach(function(arc) { line(arc, i); });\n\t }\n\t\n\t function geometry(o, i) {\n\t if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n\t else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n\t }\n\t\n\t var geometryType = {\n\t LineString: line,\n\t MultiLineString: polygon,\n\t Polygon: polygon,\n\t MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n\t };\n\t\n\t objects.forEach(geometry);\n\t\n\t for (var i in indexesByArc) {\n\t for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n\t for (var k = j + 1; k < m; ++k) {\n\t var ij = indexes[j], ik = indexes[k], n;\n\t if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);\n\t if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);\n\t }\n\t }\n\t }\n\t\n\t return neighbors;\n\t}\n\t\n\tfunction compareArea(a, b) {\n\t return a[1][2] - b[1][2];\n\t}\n\t\n\tfunction minAreaHeap() {\n\t var heap = {},\n\t array = [],\n\t size = 0;\n\t\n\t heap.push = function(object) {\n\t up(array[object._ = size] = object, size++);\n\t return size;\n\t };\n\t\n\t heap.pop = function() {\n\t if (size <= 0) return;\n\t var removed = array[0], object;\n\t if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);\n\t return removed;\n\t };\n\t\n\t heap.remove = function(removed) {\n\t var i = removed._, object;\n\t if (array[i] !== removed) return; // invalid request\n\t if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);\n\t return i;\n\t };\n\t\n\t function up(object, i) {\n\t while (i > 0) {\n\t var j = ((i + 1) >> 1) - 1,\n\t parent = array[j];\n\t if (compareArea(object, parent) >= 0) break;\n\t array[parent._ = i] = parent;\n\t array[object._ = i = j] = object;\n\t }\n\t }\n\t\n\t function down(object, i) {\n\t while (true) {\n\t var r = (i + 1) << 1,\n\t l = r - 1,\n\t j = i,\n\t child = array[j];\n\t if (l < size && compareArea(array[l], child) < 0) child = array[j = l];\n\t if (r < size && compareArea(array[r], child) < 0) child = array[j = r];\n\t if (j === i) break;\n\t array[child._ = i] = child;\n\t array[object._ = i = j] = object;\n\t }\n\t }\n\t\n\t return heap;\n\t}\n\t\n\tfunction presimplify(topology, triangleArea) {\n\t var absolute = transformAbsolute(topology.transform),\n\t relative = transformRelative(topology.transform),\n\t heap = minAreaHeap();\n\t\n\t if (!triangleArea) triangleArea = cartesianTriangleArea;\n\t\n\t topology.arcs.forEach(function(arc) {\n\t var triangles = [],\n\t maxArea = 0,\n\t triangle,\n\t i,\n\t n,\n\t p;\n\t\n\t // To store each point’s effective area, we create a new array rather than\n\t // extending the passed-in point to workaround a Chrome/V8 bug (getting\n\t // stuck in smi mode). For midpoints, the initial effective area of\n\t // Infinity will be computed in the next step.\n\t for (i = 0, n = arc.length; i < n; ++i) {\n\t p = arc[i];\n\t absolute(arc[i] = [p[0], p[1], Infinity], i);\n\t }\n\t\n\t for (i = 1, n = arc.length - 1; i < n; ++i) {\n\t triangle = arc.slice(i - 1, i + 2);\n\t triangle[1][2] = triangleArea(triangle);\n\t triangles.push(triangle);\n\t heap.push(triangle);\n\t }\n\t\n\t for (i = 0, n = triangles.length; i < n; ++i) {\n\t triangle = triangles[i];\n\t triangle.previous = triangles[i - 1];\n\t triangle.next = triangles[i + 1];\n\t }\n\t\n\t while (triangle = heap.pop()) {\n\t var previous = triangle.previous,\n\t next = triangle.next;\n\t\n\t // If the area of the current point is less than that of the previous point\n\t // to be eliminated, use the latter's area instead. This ensures that the\n\t // current point cannot be eliminated without eliminating previously-\n\t // eliminated points.\n\t if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;\n\t else maxArea = triangle[1][2];\n\t\n\t if (previous) {\n\t previous.next = next;\n\t previous[2] = triangle[2];\n\t update(previous);\n\t }\n\t\n\t if (next) {\n\t next.previous = previous;\n\t next[0] = triangle[0];\n\t update(next);\n\t }\n\t }\n\t\n\t arc.forEach(relative);\n\t });\n\t\n\t function update(triangle) {\n\t heap.remove(triangle);\n\t triangle[1][2] = triangleArea(triangle);\n\t heap.push(triangle);\n\t }\n\t\n\t return topology;\n\t}\n\t\n\tvar version = \"1.6.27\";\n\t\n\texports.version = version;\n\texports.mesh = mesh;\n\texports.meshArcs = meshArcs;\n\texports.merge = merge;\n\texports.mergeArcs = mergeArcs;\n\texports.feature = feature;\n\texports.neighbors = neighbors;\n\texports.presimplify = presimplify;\n\t\n\tObject.defineProperty(exports, '__esModule', { value: true });\n\t\n\t})));\n\n/***/ },\n/* 77 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tvar normalize = __webpack_require__(78);\n\t\n\tmodule.exports = function(inputs) {\n\t return {\n\t type: 'FeatureCollection',\n\t features: inputs.reduce(function(memo, input) {\n\t return memo.concat(normalize(input).features);\n\t }, [])\n\t };\n\t};\n\n\n/***/ },\n/* 78 */\n/***/ function(module, exports) {\n\n\tmodule.exports = normalize;\n\t\n\tvar types = {\n\t Point: 'geometry',\n\t MultiPoint: 'geometry',\n\t LineString: 'geometry',\n\t MultiLineString: 'geometry',\n\t Polygon: 'geometry',\n\t MultiPolygon: 'geometry',\n\t GeometryCollection: 'geometry',\n\t Feature: 'feature',\n\t FeatureCollection: 'featurecollection'\n\t};\n\t\n\t/**\n\t * Normalize a GeoJSON feature into a FeatureCollection.\n\t *\n\t * @param {object} gj geojson data\n\t * @returns {object} normalized geojson data\n\t */\n\tfunction normalize(gj) {\n\t if (!gj || !gj.type) return null;\n\t var type = types[gj.type];\n\t if (!type) return null;\n\t\n\t if (type === 'geometry') {\n\t return {\n\t type: 'FeatureCollection',\n\t features: [{\n\t type: 'Feature',\n\t properties: {},\n\t geometry: gj\n\t }]\n\t };\n\t } else if (type === 'feature') {\n\t return {\n\t type: 'FeatureCollection',\n\t features: [gj]\n\t };\n\t } else if (type === 'featurecollection') {\n\t return gj;\n\t }\n\t}\n\n\n/***/ },\n/* 79 */\n/***/ function(module, exports) {\n\n\t'use strict';\n\t\n\tmodule.exports = earcut;\n\t\n\tfunction earcut(data, holeIndices, dim) {\n\t\n\t dim = dim || 2;\n\t\n\t var hasHoles = holeIndices && holeIndices.length,\n\t outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n\t outerNode = linkedList(data, 0, outerLen, dim, true),\n\t triangles = [];\n\t\n\t if (!outerNode) return triangles;\n\t\n\t var minX, minY, maxX, maxY, x, y, size;\n\t\n\t if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\t\n\t // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n\t if (data.length > 80 * dim) {\n\t minX = maxX = data[0];\n\t minY = maxY = data[1];\n\t\n\t for (var i = dim; i < outerLen; i += dim) {\n\t x = data[i];\n\t y = data[i + 1];\n\t if (x < minX) minX = x;\n\t if (y < minY) minY = y;\n\t if (x > maxX) maxX = x;\n\t if (y > maxY) maxY = y;\n\t }\n\t\n\t // minX, minY and size are later used to transform coords into integers for z-order calculation\n\t size = Math.max(maxX - minX, maxY - minY);\n\t }\n\t\n\t earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\t\n\t return triangles;\n\t}\n\t\n\t// create a circular doubly linked list from polygon points in the specified winding order\n\tfunction linkedList(data, start, end, dim, clockwise) {\n\t var i, last;\n\t\n\t if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n\t for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n\t } else {\n\t for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n\t }\n\t\n\t if (last && equals(last, last.next)) {\n\t removeNode(last);\n\t last = last.next;\n\t }\n\t\n\t return last;\n\t}\n\t\n\t// eliminate colinear or duplicate points\n\tfunction filterPoints(start, end) {\n\t if (!start) return start;\n\t if (!end) end = start;\n\t\n\t var p = start,\n\t again;\n\t do {\n\t again = false;\n\t\n\t if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n\t removeNode(p);\n\t p = end = p.prev;\n\t if (p === p.next) return null;\n\t again = true;\n\t\n\t } else {\n\t p = p.next;\n\t }\n\t } while (again || p !== end);\n\t\n\t return end;\n\t}\n\t\n\t// main ear slicing loop which triangulates a polygon (given as a linked list)\n\tfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n\t if (!ear) return;\n\t\n\t // interlink polygon nodes in z-order\n\t if (!pass && size) indexCurve(ear, minX, minY, size);\n\t\n\t var stop = ear,\n\t prev, next;\n\t\n\t // iterate through ears, slicing them one by one\n\t while (ear.prev !== ear.next) {\n\t prev = ear.prev;\n\t next = ear.next;\n\t\n\t if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n\t // cut off the triangle\n\t triangles.push(prev.i / dim);\n\t triangles.push(ear.i / dim);\n\t triangles.push(next.i / dim);\n\t\n\t removeNode(ear);\n\t\n\t // skipping the next vertice leads to less sliver triangles\n\t ear = next.next;\n\t stop = next.next;\n\t\n\t continue;\n\t }\n\t\n\t ear = next;\n\t\n\t // if we looped through the whole remaining polygon and can't find any more ears\n\t if (ear === stop) {\n\t // try filtering points and slicing again\n\t if (!pass) {\n\t earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\t\n\t // if this didn't work, try curing all small self-intersections locally\n\t } else if (pass === 1) {\n\t ear = cureLocalIntersections(ear, triangles, dim);\n\t earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\t\n\t // as a last resort, try splitting the remaining polygon into two\n\t } else if (pass === 2) {\n\t splitEarcut(ear, triangles, dim, minX, minY, size);\n\t }\n\t\n\t break;\n\t }\n\t }\n\t}\n\t\n\t// check whether a polygon node forms a valid ear with adjacent nodes\n\tfunction isEar(ear) {\n\t var a = ear.prev,\n\t b = ear,\n\t c = ear.next;\n\t\n\t if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\t\n\t // now make sure we don't have other points inside the potential ear\n\t var p = ear.next.next;\n\t\n\t while (p !== ear.prev) {\n\t if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.next;\n\t }\n\t\n\t return true;\n\t}\n\t\n\tfunction isEarHashed(ear, minX, minY, size) {\n\t var a = ear.prev,\n\t b = ear,\n\t c = ear.next;\n\t\n\t if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\t\n\t // triangle bbox; min & max are calculated like this for speed\n\t var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n\t minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n\t maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n\t maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\t\n\t // z-order range for the current triangle bbox;\n\t var minZ = zOrder(minTX, minTY, minX, minY, size),\n\t maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\t\n\t // first look for points inside the triangle in increasing z-order\n\t var p = ear.nextZ;\n\t\n\t while (p && p.z <= maxZ) {\n\t if (p !== ear.prev && p !== ear.next &&\n\t pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.nextZ;\n\t }\n\t\n\t // then look for points in decreasing z-order\n\t p = ear.prevZ;\n\t\n\t while (p && p.z >= minZ) {\n\t if (p !== ear.prev && p !== ear.next &&\n\t pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n\t area(p.prev, p, p.next) >= 0) return false;\n\t p = p.prevZ;\n\t }\n\t\n\t return true;\n\t}\n\t\n\t// go through all polygon nodes and cure small local self-intersections\n\tfunction cureLocalIntersections(start, triangles, dim) {\n\t var p = start;\n\t do {\n\t var a = p.prev,\n\t b = p.next.next;\n\t\n\t if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\t\n\t triangles.push(a.i / dim);\n\t triangles.push(p.i / dim);\n\t triangles.push(b.i / dim);\n\t\n\t // remove two nodes involved\n\t removeNode(p);\n\t removeNode(p.next);\n\t\n\t p = start = b;\n\t }\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t return p;\n\t}\n\t\n\t// try splitting polygon into two and triangulate them independently\n\tfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n\t // look for a valid diagonal that divides the polygon into two\n\t var a = start;\n\t do {\n\t var b = a.next.next;\n\t while (b !== a.prev) {\n\t if (a.i !== b.i && isValidDiagonal(a, b)) {\n\t // split the polygon in two by the diagonal\n\t var c = splitPolygon(a, b);\n\t\n\t // filter colinear points around the cuts\n\t a = filterPoints(a, a.next);\n\t c = filterPoints(c, c.next);\n\t\n\t // run earcut on each half\n\t earcutLinked(a, triangles, dim, minX, minY, size);\n\t earcutLinked(c, triangles, dim, minX, minY, size);\n\t return;\n\t }\n\t b = b.next;\n\t }\n\t a = a.next;\n\t } while (a !== start);\n\t}\n\t\n\t// link every hole into the outer loop, producing a single-ring polygon without holes\n\tfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n\t var queue = [],\n\t i, len, start, end, list;\n\t\n\t for (i = 0, len = holeIndices.length; i < len; i++) {\n\t start = holeIndices[i] * dim;\n\t end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n\t list = linkedList(data, start, end, dim, false);\n\t if (list === list.next) list.steiner = true;\n\t queue.push(getLeftmost(list));\n\t }\n\t\n\t queue.sort(compareX);\n\t\n\t // process holes from left to right\n\t for (i = 0; i < queue.length; i++) {\n\t eliminateHole(queue[i], outerNode);\n\t outerNode = filterPoints(outerNode, outerNode.next);\n\t }\n\t\n\t return outerNode;\n\t}\n\t\n\tfunction compareX(a, b) {\n\t return a.x - b.x;\n\t}\n\t\n\t// find a bridge between vertices that connects hole with an outer ring and and link it\n\tfunction eliminateHole(hole, outerNode) {\n\t outerNode = findHoleBridge(hole, outerNode);\n\t if (outerNode) {\n\t var b = splitPolygon(outerNode, hole);\n\t filterPoints(b, b.next);\n\t }\n\t}\n\t\n\t// David Eberly's algorithm for finding a bridge between hole and outer polygon\n\tfunction findHoleBridge(hole, outerNode) {\n\t var p = outerNode,\n\t hx = hole.x,\n\t hy = hole.y,\n\t qx = -Infinity,\n\t m;\n\t\n\t // find a segment intersected by a ray from the hole's leftmost point to the left;\n\t // segment's endpoint with lesser x will be potential connection point\n\t do {\n\t if (hy <= p.y && hy >= p.next.y) {\n\t var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n\t if (x <= hx && x > qx) {\n\t qx = x;\n\t if (x === hx) {\n\t if (hy === p.y) return p;\n\t if (hy === p.next.y) return p.next;\n\t }\n\t m = p.x < p.next.x ? p : p.next;\n\t }\n\t }\n\t p = p.next;\n\t } while (p !== outerNode);\n\t\n\t if (!m) return null;\n\t\n\t if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint\n\t\n\t // look for points inside the triangle of hole point, segment intersection and endpoint;\n\t // if there are no points found, we have a valid connection;\n\t // otherwise choose the point of the minimum angle with the ray as connection point\n\t\n\t var stop = m,\n\t mx = m.x,\n\t my = m.y,\n\t tanMin = Infinity,\n\t tan;\n\t\n\t p = m.next;\n\t\n\t while (p !== stop) {\n\t if (hx >= p.x && p.x >= mx &&\n\t pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\t\n\t tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\t\n\t if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n\t m = p;\n\t tanMin = tan;\n\t }\n\t }\n\t\n\t p = p.next;\n\t }\n\t\n\t return m;\n\t}\n\t\n\t// interlink polygon nodes in z-order\n\tfunction indexCurve(start, minX, minY, size) {\n\t var p = start;\n\t do {\n\t if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n\t p.prevZ = p.prev;\n\t p.nextZ = p.next;\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t p.prevZ.nextZ = null;\n\t p.prevZ = null;\n\t\n\t sortLinked(p);\n\t}\n\t\n\t// Simon Tatham's linked list merge sort algorithm\n\t// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\n\tfunction sortLinked(list) {\n\t var i, p, q, e, tail, numMerges, pSize, qSize,\n\t inSize = 1;\n\t\n\t do {\n\t p = list;\n\t list = null;\n\t tail = null;\n\t numMerges = 0;\n\t\n\t while (p) {\n\t numMerges++;\n\t q = p;\n\t pSize = 0;\n\t for (i = 0; i < inSize; i++) {\n\t pSize++;\n\t q = q.nextZ;\n\t if (!q) break;\n\t }\n\t\n\t qSize = inSize;\n\t\n\t while (pSize > 0 || (qSize > 0 && q)) {\n\t\n\t if (pSize === 0) {\n\t e = q;\n\t q = q.nextZ;\n\t qSize--;\n\t } else if (qSize === 0 || !q) {\n\t e = p;\n\t p = p.nextZ;\n\t pSize--;\n\t } else if (p.z <= q.z) {\n\t e = p;\n\t p = p.nextZ;\n\t pSize--;\n\t } else {\n\t e = q;\n\t q = q.nextZ;\n\t qSize--;\n\t }\n\t\n\t if (tail) tail.nextZ = e;\n\t else list = e;\n\t\n\t e.prevZ = tail;\n\t tail = e;\n\t }\n\t\n\t p = q;\n\t }\n\t\n\t tail.nextZ = null;\n\t inSize *= 2;\n\t\n\t } while (numMerges > 1);\n\t\n\t return list;\n\t}\n\t\n\t// z-order of a point given coords and size of the data bounding box\n\tfunction zOrder(x, y, minX, minY, size) {\n\t // coords are transformed into non-negative 15-bit integer range\n\t x = 32767 * (x - minX) / size;\n\t y = 32767 * (y - minY) / size;\n\t\n\t x = (x | (x << 8)) & 0x00FF00FF;\n\t x = (x | (x << 4)) & 0x0F0F0F0F;\n\t x = (x | (x << 2)) & 0x33333333;\n\t x = (x | (x << 1)) & 0x55555555;\n\t\n\t y = (y | (y << 8)) & 0x00FF00FF;\n\t y = (y | (y << 4)) & 0x0F0F0F0F;\n\t y = (y | (y << 2)) & 0x33333333;\n\t y = (y | (y << 1)) & 0x55555555;\n\t\n\t return x | (y << 1);\n\t}\n\t\n\t// find the leftmost node of a polygon ring\n\tfunction getLeftmost(start) {\n\t var p = start,\n\t leftmost = start;\n\t do {\n\t if (p.x < leftmost.x) leftmost = p;\n\t p = p.next;\n\t } while (p !== start);\n\t\n\t return leftmost;\n\t}\n\t\n\t// check if a point lies within a convex triangle\n\tfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n\t return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n\t (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n\t (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n\t}\n\t\n\t// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\n\tfunction isValidDiagonal(a, b) {\n\t return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n\t locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n\t}\n\t\n\t// signed area of a triangle\n\tfunction area(p, q, r) {\n\t return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n\t}\n\t\n\t// check if two points are equal\n\tfunction equals(p1, p2) {\n\t return p1.x === p2.x && p1.y === p2.y;\n\t}\n\t\n\t// check if two segments intersect\n\tfunction intersects(p1, q1, p2, q2) {\n\t if ((equals(p1, q1) && equals(p2, q2)) ||\n\t (equals(p1, q2) && equals(p2, q1))) return true;\n\t return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n\t area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n\t}\n\t\n\t// check if a polygon diagonal intersects any polygon segments\n\tfunction intersectsPolygon(a, b) {\n\t var p = a;\n\t do {\n\t if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n\t intersects(p, p.next, a, b)) return true;\n\t p = p.next;\n\t } while (p !== a);\n\t\n\t return false;\n\t}\n\t\n\t// check if a polygon diagonal is locally inside the polygon\n\tfunction locallyInside(a, b) {\n\t return area(a.prev, a, a.next) < 0 ?\n\t area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n\t area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n\t}\n\t\n\t// check if the middle point of a polygon diagonal is inside the polygon\n\tfunction middleInside(a, b) {\n\t var p = a,\n\t inside = false,\n\t px = (a.x + b.x) / 2,\n\t py = (a.y + b.y) / 2;\n\t do {\n\t if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n\t inside = !inside;\n\t p = p.next;\n\t } while (p !== a);\n\t\n\t return inside;\n\t}\n\t\n\t// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n\t// if one belongs to the outer ring and another to a hole, it merges it into a single ring\n\tfunction splitPolygon(a, b) {\n\t var a2 = new Node(a.i, a.x, a.y),\n\t b2 = new Node(b.i, b.x, b.y),\n\t an = a.next,\n\t bp = b.prev;\n\t\n\t a.next = b;\n\t b.prev = a;\n\t\n\t a2.next = an;\n\t an.prev = a2;\n\t\n\t b2.next = a2;\n\t a2.prev = b2;\n\t\n\t bp.next = b2;\n\t b2.prev = bp;\n\t\n\t return b2;\n\t}\n\t\n\t// create a node and optionally link it with previous one (in a circular doubly linked list)\n\tfunction insertNode(i, x, y, last) {\n\t var p = new Node(i, x, y);\n\t\n\t if (!last) {\n\t p.prev = p;\n\t p.next = p;\n\t\n\t } else {\n\t p.next = last.next;\n\t p.prev = last;\n\t last.next.prev = p;\n\t last.next = p;\n\t }\n\t return p;\n\t}\n\t\n\tfunction removeNode(p) {\n\t p.next.prev = p.prev;\n\t p.prev.next = p.next;\n\t\n\t if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n\t if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n\t}\n\t\n\tfunction Node(i, x, y) {\n\t // vertice index in coordinates array\n\t this.i = i;\n\t\n\t // vertex coordinates\n\t this.x = x;\n\t this.y = y;\n\t\n\t // previous and next vertice nodes in a polygon ring\n\t this.prev = null;\n\t this.next = null;\n\t\n\t // z-order curve value\n\t this.z = null;\n\t\n\t // previous and next nodes in z-order\n\t this.prevZ = null;\n\t this.nextZ = null;\n\t\n\t // indicates whether this is a steiner point\n\t this.steiner = false;\n\t}\n\t\n\t// return a percentage difference between the polygon area and its triangulation area;\n\t// used to verify correctness of triangulation\n\tearcut.deviation = function (data, holeIndices, dim, triangles) {\n\t var hasHoles = holeIndices && holeIndices.length;\n\t var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\t\n\t var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n\t if (hasHoles) {\n\t for (var i = 0, len = holeIndices.length; i < len; i++) {\n\t var start = holeIndices[i] * dim;\n\t var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n\t polygonArea -= Math.abs(signedArea(data, start, end, dim));\n\t }\n\t }\n\t\n\t var trianglesArea = 0;\n\t for (i = 0; i < triangles.length; i += 3) {\n\t var a = triangles[i] * dim;\n\t var b = triangles[i + 1] * dim;\n\t var c = triangles[i + 2] * dim;\n\t trianglesArea += Math.abs(\n\t (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n\t (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n\t }\n\t\n\t return polygonArea === 0 && trianglesArea === 0 ? 0 :\n\t Math.abs((trianglesArea - polygonArea) / polygonArea);\n\t};\n\t\n\tfunction signedArea(data, start, end, dim) {\n\t var sum = 0;\n\t for (var i = start, j = end - dim; i < end; i += dim) {\n\t sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n\t j = i;\n\t }\n\t return sum;\n\t}\n\t\n\t// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\n\tearcut.flatten = function (data) {\n\t var dim = data[0][0].length,\n\t result = {vertices: [], holes: [], dimensions: dim},\n\t holeIndex = 0;\n\t\n\t for (var i = 0; i < data.length; i++) {\n\t for (var j = 0; j < data[i].length; j++) {\n\t for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n\t }\n\t if (i > 0) {\n\t holeIndex += data[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t return result;\n\t};\n\n\n/***/ },\n/* 80 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * Extrude a polygon given its vertices and triangulated faces\n\t *\n\t * Based on:\n\t * https://github.com/freeman-lab/extrude\n\t */\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar extrudePolygon = function extrudePolygon(points, faces, _options) {\n\t var defaults = {\n\t top: 1,\n\t bottom: 0,\n\t closed: true\n\t };\n\t\n\t var options = (0, _lodashAssign2['default'])({}, defaults, _options);\n\t\n\t var n = points.length;\n\t var positions;\n\t var cells;\n\t var topCells;\n\t var bottomCells;\n\t var sideCells;\n\t\n\t // If bottom and top values are identical then return the flat shape\n\t options.top === options.bottom ? flat() : full();\n\t\n\t function flat() {\n\t positions = points.map(function (p) {\n\t return [p[0], options.top, p[1]];\n\t });\n\t cells = faces;\n\t topCells = faces;\n\t }\n\t\n\t function full() {\n\t positions = [];\n\t points.forEach(function (p) {\n\t positions.push([p[0], options.top, p[1]]);\n\t });\n\t points.forEach(function (p) {\n\t positions.push([p[0], options.bottom, p[1]]);\n\t });\n\t\n\t cells = [];\n\t for (var i = 0; i < n; i++) {\n\t if (i === n - 1) {\n\t cells.push([i + n, n, i]);\n\t cells.push([0, i, n]);\n\t } else {\n\t cells.push([i + n, i + n + 1, i]);\n\t cells.push([i + 1, i, i + n + 1]);\n\t }\n\t }\n\t\n\t sideCells = [].concat(cells);\n\t\n\t if (options.closed) {\n\t var top = faces;\n\t var bottom = top.map(function (p) {\n\t return p.map(function (v) {\n\t return v + n;\n\t });\n\t });\n\t bottom = bottom.map(function (p) {\n\t return [p[0], p[2], p[1]];\n\t });\n\t cells = cells.concat(top).concat(bottom);\n\t\n\t topCells = top;\n\t bottomCells = bottom;\n\t }\n\t }\n\t\n\t return {\n\t positions: positions,\n\t faces: cells,\n\t top: topCells,\n\t bottom: bottomCells,\n\t sides: sideCells\n\t };\n\t};\n\t\n\texports['default'] = extrudePolygon;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 81 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t/*\n\t * BufferGeometry helpers\n\t */\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar Buffer = (function () {\n\t // Merge TypedArrays of the same type\n\t // Returns merged array as well as indexes for splitting the array\n\t var mergeFloat32Arrays = function mergeFloat32Arrays(arrays) {\n\t var size = 0;\n\t var map = new Int32Array(arrays.length * 2);\n\t\n\t var lastIndex = 0;\n\t var length;\n\t\n\t // Find size of each array\n\t arrays.forEach(function (_array, index) {\n\t length = _array.length;\n\t size += length;\n\t map.set([lastIndex, lastIndex + length], index * 2);\n\t lastIndex += length;\n\t });\n\t\n\t // Create a new array of total size\n\t var mergedArray = new Float32Array(size);\n\t\n\t // Add each array to the new array\n\t arrays.forEach(function (_array, index) {\n\t mergedArray.set(_array, map[index * 2]);\n\t });\n\t\n\t return [mergedArray, map];\n\t };\n\t\n\t var splitFloat32Array = function splitFloat32Array(data) {\n\t var arr = data[0];\n\t var map = data[1];\n\t\n\t var start;\n\t var arrays = [];\n\t\n\t // Iterate over map\n\t for (var i = 0; i < map.length / 2; i++) {\n\t start = i * 2;\n\t arrays.push(arr.subarray(map[start], map[start + 1]));\n\t }\n\t\n\t return arrays;\n\t };\n\t\n\t // TODO: Create a generic method that can work for any typed array\n\t var mergeUint8Arrays = function mergeUint8Arrays(arrays) {\n\t var size = 0;\n\t var map = new Int32Array(arrays.length * 2);\n\t\n\t var lastIndex = 0;\n\t var length;\n\t\n\t // Find size of each array\n\t arrays.forEach(function (_array, index) {\n\t length = _array.length;\n\t size += length;\n\t map.set([lastIndex, lastIndex + length], index * 2);\n\t lastIndex += length;\n\t });\n\t\n\t // Create a new array of total size\n\t var mergedArray = new Uint8Array(size);\n\t\n\t // Add each array to the new array\n\t arrays.forEach(function (_array, index) {\n\t mergedArray.set(_array, map[index * 2]);\n\t });\n\t\n\t return [mergedArray, map];\n\t };\n\t\n\t // TODO: Dedupe with splitFloat32Array\n\t var splitUint8Array = function splitUint8Array(data) {\n\t var arr = data[0];\n\t var map = data[1];\n\t\n\t var start;\n\t var arrays = [];\n\t\n\t // Iterate over map\n\t for (var i = 0; i < map.length / 2; i++) {\n\t start = i * 2;\n\t arrays.push(arr.subarray(map[start], map[start + 1]));\n\t }\n\t\n\t return arrays;\n\t };\n\t\n\t // Merge multiple attribute objects into a single attribute object\n\t //\n\t // Attribute objects must all use the same attribute keys\n\t var mergeAttributes = function mergeAttributes(attributes) {\n\t var lengths = {};\n\t\n\t // Find array lengths\n\t attributes.forEach(function (_attributes) {\n\t for (var k in _attributes) {\n\t if (!lengths[k]) {\n\t lengths[k] = 0;\n\t }\n\t\n\t lengths[k] += _attributes[k].length;\n\t }\n\t });\n\t\n\t var mergedAttributes = {};\n\t\n\t // Set up arrays to merge into\n\t for (var k in lengths) {\n\t mergedAttributes[k] = new Float32Array(lengths[k]);\n\t }\n\t\n\t var lastLengths = {};\n\t\n\t attributes.forEach(function (_attributes) {\n\t for (var k in _attributes) {\n\t if (!lastLengths[k]) {\n\t lastLengths[k] = 0;\n\t }\n\t\n\t mergedAttributes[k].set(_attributes[k], lastLengths[k]);\n\t\n\t lastLengths[k] += _attributes[k].length;\n\t }\n\t });\n\t\n\t return mergedAttributes;\n\t };\n\t\n\t var createLineGeometry = function createLineGeometry(lines, offset) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t var vertices = new Float32Array(lines.verticesCount * 3);\n\t var colours = new Float32Array(lines.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (lines.pickingIds) {\n\t // One component per vertex (1)\n\t pickingIds = new Float32Array(lines.verticesCount);\n\t }\n\t\n\t var _vertices;\n\t var _colour;\n\t var _pickingId;\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < lines.vertices.length; i++) {\n\t _vertices = lines.vertices[i];\n\t _colour = lines.colours[i];\n\t\n\t if (pickingIds) {\n\t _pickingId = lines.pickingIds[i];\n\t }\n\t\n\t for (var j = 0; j < _vertices.length; j++) {\n\t var ax = _vertices[j][0] + offset.x;\n\t var ay = _vertices[j][1];\n\t var az = _vertices[j][2] + offset.y;\n\t\n\t var c1 = _colour[j];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t }\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3));\n\t\n\t if (pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t return geometry;\n\t };\n\t\n\t // TODO: Make picking IDs optional\n\t var createGeometry = function createGeometry(attributes, offset) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t // Three components per vertex per face (3 x 3 = 9)\n\t var vertices = new Float32Array(attributes.facesCount * 9);\n\t var normals = new Float32Array(attributes.facesCount * 9);\n\t var colours = new Float32Array(attributes.facesCount * 9);\n\t\n\t var pickingIds;\n\t if (attributes.pickingIds) {\n\t // One component per vertex per face (1 x 3 = 3)\n\t pickingIds = new Float32Array(attributes.facesCount * 3);\n\t }\n\t\n\t var pA = new _three2['default'].Vector3();\n\t var pB = new _three2['default'].Vector3();\n\t var pC = new _three2['default'].Vector3();\n\t\n\t var cb = new _three2['default'].Vector3();\n\t var ab = new _three2['default'].Vector3();\n\t\n\t var index;\n\t var _faces;\n\t var _vertices;\n\t var _colour;\n\t var _pickingId;\n\t var lastIndex = 0;\n\t for (var i = 0; i < attributes.faces.length; i++) {\n\t _faces = attributes.faces[i];\n\t _vertices = attributes.vertices[i];\n\t _colour = attributes.colours[i];\n\t\n\t if (pickingIds) {\n\t _pickingId = attributes.pickingIds[i];\n\t }\n\t\n\t for (var j = 0; j < _faces.length; j++) {\n\t // Array of vertex indexes for the face\n\t index = _faces[j][0];\n\t\n\t var ax = _vertices[index][0] + offset.x;\n\t var ay = _vertices[index][1];\n\t var az = _vertices[index][2] + offset.y;\n\t\n\t var c1 = _colour[j][0];\n\t\n\t index = _faces[j][1];\n\t\n\t var bx = _vertices[index][0] + offset.x;\n\t var by = _vertices[index][1];\n\t var bz = _vertices[index][2] + offset.y;\n\t\n\t var c2 = _colour[j][1];\n\t\n\t index = _faces[j][2];\n\t\n\t var cx = _vertices[index][0] + offset.x;\n\t var cy = _vertices[index][1];\n\t var cz = _vertices[index][2] + offset.y;\n\t\n\t var c3 = _colour[j][2];\n\t\n\t // Flat face normals\n\t // From: http://threejs.org/examples/webgl_buffergeometry.html\n\t pA.set(ax, ay, az);\n\t pB.set(bx, by, bz);\n\t pC.set(cx, cy, cz);\n\t\n\t cb.subVectors(pC, pB);\n\t ab.subVectors(pA, pB);\n\t cb.cross(ab);\n\t\n\t cb.normalize();\n\t\n\t var nx = cb.x;\n\t var ny = cb.y;\n\t var nz = cb.z;\n\t\n\t vertices[lastIndex * 9 + 0] = ax;\n\t vertices[lastIndex * 9 + 1] = ay;\n\t vertices[lastIndex * 9 + 2] = az;\n\t\n\t normals[lastIndex * 9 + 0] = nx;\n\t normals[lastIndex * 9 + 1] = ny;\n\t normals[lastIndex * 9 + 2] = nz;\n\t\n\t colours[lastIndex * 9 + 0] = c1[0];\n\t colours[lastIndex * 9 + 1] = c1[1];\n\t colours[lastIndex * 9 + 2] = c1[2];\n\t\n\t vertices[lastIndex * 9 + 3] = bx;\n\t vertices[lastIndex * 9 + 4] = by;\n\t vertices[lastIndex * 9 + 5] = bz;\n\t\n\t normals[lastIndex * 9 + 3] = nx;\n\t normals[lastIndex * 9 + 4] = ny;\n\t normals[lastIndex * 9 + 5] = nz;\n\t\n\t colours[lastIndex * 9 + 3] = c2[0];\n\t colours[lastIndex * 9 + 4] = c2[1];\n\t colours[lastIndex * 9 + 5] = c2[2];\n\t\n\t vertices[lastIndex * 9 + 6] = cx;\n\t vertices[lastIndex * 9 + 7] = cy;\n\t vertices[lastIndex * 9 + 8] = cz;\n\t\n\t normals[lastIndex * 9 + 6] = nx;\n\t normals[lastIndex * 9 + 7] = ny;\n\t normals[lastIndex * 9 + 8] = nz;\n\t\n\t colours[lastIndex * 9 + 6] = c3[0];\n\t colours[lastIndex * 9 + 7] = c3[1];\n\t colours[lastIndex * 9 + 8] = c3[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex * 3 + 0] = _pickingId;\n\t pickingIds[lastIndex * 3 + 1] = _pickingId;\n\t pickingIds[lastIndex * 3 + 2] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t }\n\t\n\t // itemSize = 3 because there are 3 values (components) per vertex\n\t geometry.addAttribute('position', new _three2['default'].BufferAttribute(vertices, 3));\n\t geometry.addAttribute('normal', new _three2['default'].BufferAttribute(normals, 3));\n\t geometry.addAttribute('color', new _three2['default'].BufferAttribute(colours, 3));\n\t\n\t if (pickingIds) {\n\t geometry.addAttribute('pickingId', new _three2['default'].BufferAttribute(pickingIds, 1));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t return geometry;\n\t };\n\t\n\t var textEncoder = new TextEncoder('utf-8');\n\t var textDecoder = new TextDecoder('utf-8');\n\t\n\t var stringToUint8Array = function stringToUint8Array(str) {\n\t return textEncoder.encode(str);\n\t };\n\t\n\t var uint8ArrayToString = function uint8ArrayToString(ab) {\n\t return textDecoder.decode(ab);\n\t };\n\t\n\t return {\n\t mergeFloat32Arrays: mergeFloat32Arrays,\n\t splitFloat32Array: splitFloat32Array,\n\t mergeUint8Arrays: mergeUint8Arrays,\n\t splitUint8Array: splitUint8Array,\n\t mergeAttributes: mergeAttributes,\n\t createLineGeometry: createLineGeometry,\n\t createGeometry: createGeometry,\n\t stringToUint8Array: stringToUint8Array,\n\t uint8ArrayToString: uint8ArrayToString\n\t };\n\t})();\n\t\n\texports['default'] = Buffer;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 82 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _PickingShader = __webpack_require__(83);\n\t\n\tvar _PickingShader2 = _interopRequireDefault(_PickingShader);\n\t\n\t// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\t\n\tvar PickingMaterial = function PickingMaterial() {\n\t _three2['default'].ShaderMaterial.call(this, {\n\t uniforms: {\n\t size: {\n\t type: 'f',\n\t value: 0.01\n\t },\n\t scale: {\n\t type: 'f',\n\t value: 400\n\t }\n\t },\n\t // attributes: ['position', 'id'],\n\t vertexShader: _PickingShader2['default'].vertexShader,\n\t fragmentShader: _PickingShader2['default'].fragmentShader\n\t });\n\t\n\t this.linePadding = 2;\n\t};\n\t\n\tPickingMaterial.prototype = Object.create(_three2['default'].ShaderMaterial.prototype);\n\t\n\tPickingMaterial.prototype.constructor = PickingMaterial;\n\t\n\tPickingMaterial.prototype.setPointSize = function (size) {\n\t this.uniforms.size.value = size;\n\t};\n\t\n\tPickingMaterial.prototype.setPointScale = function (scale) {\n\t this.uniforms.scale.value = scale;\n\t};\n\t\n\texports['default'] = PickingMaterial;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 83 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t\tvalue: true\n\t});\n\t// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\t\n\tvar PickingShader = {\n\t\tvertexShader: ['attribute float pickingId;',\n\t\t// '',\n\t\t// 'uniform float size;',\n\t\t// 'uniform float scale;',\n\t\t'', 'varying vec4 worldId;', '', 'void main() {', ' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',\n\t\t// ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );',\n\t\t' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);', ' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);', ' worldId = vec4(a,1);', ' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );', '}'].join('\\n'),\n\t\n\t\tfragmentShader: ['#ifdef GL_ES\\n', 'precision highp float;\\n', '#endif\\n', '', 'varying vec4 worldId;', '', 'void main() {', ' gl_FragColor = worldId;', '}'].join('\\n')\n\t};\n\t\n\texports['default'] = PickingShader;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 84 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\t// TODO: Allow _setBufferAttributes to use a custom function passed in to\n\t// generate a custom mesh\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoGeo = __webpack_require__(6);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _earcut2 = __webpack_require__(79);\n\t\n\tvar _earcut3 = _interopRequireDefault(_earcut2);\n\t\n\tvar _utilExtrudePolygon = __webpack_require__(80);\n\t\n\tvar _utilExtrudePolygon2 = _interopRequireDefault(_utilExtrudePolygon);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(81);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PolygonLayer = (function (_Layer) {\n\t _inherits(PolygonLayer, _Layer);\n\t\n\t function PolygonLayer(coordinates, options) {\n\t _classCallCheck(this, PolygonLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t polygonMaterial: null,\n\t onPolygonMesh: null,\n\t onBufferAttributes: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t color: '#ffffff',\n\t transparent: false,\n\t opacity: 1,\n\t blending: _three2['default'].NormalBlending,\n\t height: 0\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PolygonLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of polygons so it's easy to support\n\t // MultiPolygon features (a single polygon would be a MultiPolygon with a\n\t // single polygon in the array)\n\t this._coordinates = PolygonLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t }\n\t\n\t _createClass(PolygonLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._setCoordinates();\n\t\n\t if (_this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (_this.isOutput()) {\n\t _this._pickingMesh = new _three2['default'].Object3D();\n\t _this.addToPicking(_this._pickingMesh);\n\t }\n\t\n\t _this._setPickingId();\n\t _this._addPickingEvents();\n\t }\n\t\n\t PolygonLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) {\n\t _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes);\n\t\n\t if (result.outlineAttributes.length > 0) {\n\t _this._outlineBufferAttributes = _utilBuffer2['default'].mergeAttributes(result.outlineAttributes);\n\t }\n\t\n\t _this._flat = result.flat;\n\t\n\t if (_this.isOutput()) {\n\t var attributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3,\n\t tops: 1\n\t };\n\t\n\t if (_this._options.interactive) {\n\t attributeLengths.pickingIds = 1;\n\t }\n\t\n\t var style = _this._options.style;\n\t\n\t // Set mesh if not merging elsewhere\n\t PolygonLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) {\n\t // Output mesh\n\t _this.add(result.mesh);\n\t\n\t if (result.pickingMesh) {\n\t _this._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t result.attributes = null;\n\t result.outlineAttributes = null;\n\t result = null;\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Return center of polygon as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t //\n\t // TODO: Find proper center position instead of returning first coordinate\n\t // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return polygon bounds in geographic coordinates\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this2 = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this2.emit('click', _this2, point2d, point3d, intersects);\n\t });\n\t }\n\t\n\t // Create and store reference to THREE.BufferAttribute data for this layer\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t }, {\n\t key: 'getOutlineBufferAttributes',\n\t value: function getOutlineBufferAttributes() {\n\t return this._outlineBufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t this._outlineBufferAttributes = null;\n\t }\n\t\n\t // Threshold angle is currently in rads\n\t }, {\n\t key: 'clearCoordinates',\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t }, {\n\t key: '_setCoordinates',\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates[0][0][0];\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var point;\n\t return this._coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (latlon) {\n\t point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * point.x;\n\t _this3._offset.y = -1 * point.y;\n\t\n\t _this3._options.pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t });\n\t }\n\t\n\t // Convert coordinates array to something earcut can understand\n\t }, {\n\t key: 'isFlat',\n\t\n\t // Returns true if the polygon is flat (has no height)\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiPolygon GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t\n\t // TODO: Make sure this is cleaning everything\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PolygonLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'SetBufferAttributes',\n\t value: function SetBufferAttributes(coordinates, options) {\n\t return new Promise(function (resolve) {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (options.style.height && options.style.height !== 0) {\n\t height = _geoGeo2['default'].metresToWorld(options.style.height, options.pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(options.style.color);\n\t\n\t // Light and dark colours used for poor-mans AO gradient on object sides\n\t var light = new _three2['default'].Color(0xffffff);\n\t var shadow = new _three2['default'].Color(0x666666);\n\t\n\t var flat = true;\n\t\n\t var outlineAttributes = [];\n\t\n\t // For each polygon\n\t var attributes = coordinates.map(function (_coordinates) {\n\t // Convert coordinates to earcut format\n\t var _earcut = PolygonLayer.ToEarcut(_coordinates);\n\t\n\t // Triangulate faces using earcut\n\t var faces = PolygonLayer.Triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions);\n\t\n\t var groupedVertices = [];\n\t for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) {\n\t groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions));\n\t }\n\t\n\t var extruded = (0, _utilExtrudePolygon2['default'])(groupedVertices, faces, {\n\t bottom: 0,\n\t top: height\n\t });\n\t\n\t var topColor = colour.clone().multiply(light);\n\t var bottomColor = colour.clone().multiply(shadow);\n\t\n\t var _vertices = extruded.positions;\n\t var _faces = [];\n\t var _colours = [];\n\t var _tops = [];\n\t\n\t var _colour;\n\t extruded.top.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t _colour.push([colour.r, colour.g, colour.b]);\n\t\n\t _tops.push([true, true, true]);\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t\n\t if (extruded.sides) {\n\t flat = false;\n\t\n\t // Set up colours for every vertex with poor-mans AO on the sides\n\t extruded.sides.forEach(function (face, fi) {\n\t _colour = [];\n\t\n\t // First face is always bottom-bottom-top\n\t if (fi % 2 === 0) {\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t\n\t _tops.push([false, false, true]);\n\t // Reverse winding for the second face\n\t // top-top-bottom\n\t } else {\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([topColor.r, topColor.g, topColor.b]);\n\t _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\t\n\t _tops.push([true, true, false]);\n\t }\n\t\n\t _faces.push(face);\n\t _colours.push(_colour);\n\t });\n\t }\n\t\n\t // Skip bottom as there's no point rendering it\n\t // allFaces.push(extruded.faces);\n\t\n\t var polygon = {\n\t vertices: _vertices,\n\t faces: _faces,\n\t colours: _colours,\n\t tops: _tops,\n\t facesCount: _faces.length\n\t };\n\t\n\t if (options.style.outline) {\n\t var outlineColour = new _three2['default'].Color();\n\t outlineColour.set(options.style.outlineColor || 0x000000);\n\t\n\t outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour));\n\t }\n\t\n\t if (options.interactive && options.pickingId) {\n\t // Inject picking ID\n\t polygon.pickingId = options.pickingId;\n\t }\n\t\n\t // Convert polygon representation to proper attribute arrays\n\t return PolygonLayer.ToAttributes(polygon);\n\t });\n\t\n\t resolve({\n\t attributes: attributes,\n\t outlineAttributes: outlineAttributes,\n\t flat: flat\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'Set2DOutline',\n\t value: function Set2DOutline(coordinates, colour) {\n\t var _vertices = [];\n\t\n\t coordinates.forEach(function (ring) {\n\t var _ring = ring.map(function (coordinate) {\n\t return [coordinate.x, 0, coordinate.y];\n\t });\n\t\n\t // Add in duplicate vertices for line segments to work\n\t var verticeCount = _ring.length;\n\t var first = true;\n\t while (--verticeCount) {\n\t if (first || verticeCount === 0) {\n\t first = false;\n\t continue;\n\t }\n\t\n\t _ring.splice(verticeCount + 1, 0, _ring[verticeCount]);\n\t }\n\t\n\t _vertices = _vertices.concat(_ring);\n\t });\n\t\n\t _colour = [colour.r, colour.g, colour.b];\n\t\n\t var vertices = new Float32Array(_vertices.length * 3);\n\t var colours = new Float32Array(_vertices.length * 3);\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _vertices.length; i++) {\n\t var ax = _vertices[i][0];\n\t var ay = _vertices[i][1];\n\t var az = _vertices[i][2];\n\t\n\t var c1 = _colour;\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t positions: vertices,\n\t colors: colours\n\t };\n\t\n\t return attributes;\n\t }\n\t }, {\n\t key: 'SetMesh',\n\t value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t for (var key in attributes) {\n\t geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key]));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (options.polygonMaterial && options.polygonMaterial instanceof _three2['default'].Material) {\n\t material = options.polygonMaterial;\n\t } else if (!skybox) {\n\t material = new _three2['default'].MeshPhongMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t side: _three2['default'].BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t side: _three2['default'].BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof options.onPolygonMesh === 'function') {\n\t mesh = options.onPolygonMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t mesh.receiveShadow = true;\n\t }\n\t\n\t if (flat) {\n\t material.depthWrite = false;\n\t\n\t var renderOrder = style.renderOrder !== undefined ? style.renderOrder : 3;\n\t mesh.renderOrder = renderOrder;\n\t }\n\t\n\t if (options.interactive) {\n\t material = new _enginePickingMaterial2['default']();\n\t material.side = _three2['default'].BackSide;\n\t\n\t var pickingMesh = new _three2['default'].Mesh(geometry, material);\n\t }\n\t\n\t return Promise.resolve({\n\t mesh: mesh,\n\t pickingMesh: pickingMesh\n\t });\n\t }\n\t }, {\n\t key: 'ToEarcut',\n\t value: function ToEarcut(coordinates) {\n\t var dim = 2;\n\t var result = { vertices: [], holes: [], dimensions: dim };\n\t var holeIndex = 0;\n\t\n\t for (var i = 0; i < coordinates.length; i++) {\n\t for (var j = 0; j < coordinates[i].length; j++) {\n\t // for (var d = 0; d < dim; d++) {\n\t result.vertices.push(coordinates[i][j].x);\n\t result.vertices.push(coordinates[i][j].y);\n\t // }\n\t }\n\t if (i > 0) {\n\t holeIndex += coordinates[i - 1].length;\n\t result.holes.push(holeIndex);\n\t }\n\t }\n\t\n\t return result;\n\t }\n\t\n\t // Triangulate earcut-based input using earcut\n\t }, {\n\t key: 'Triangulate',\n\t value: function Triangulate(contour, holes, dim) {\n\t // console.time('earcut');\n\t\n\t var faces = (0, _earcut3['default'])(contour, holes, dim);\n\t var result = [];\n\t\n\t for (i = 0, il = faces.length; i < il; i += 3) {\n\t result.push(faces.slice(i, i + 3));\n\t }\n\t\n\t // console.timeEnd('earcut');\n\t\n\t return result;\n\t }\n\t\n\t // Transform polygon representation into attribute arrays that can be used by\n\t // THREE.BufferGeometry\n\t //\n\t // TODO: Can this be simplified? It's messy and huge\n\t }, {\n\t key: 'ToAttributes',\n\t value: function ToAttributes(polygon) {\n\t // Three components per vertex per face (3 x 3 = 9)\n\t var positions = new Float32Array(polygon.facesCount * 9);\n\t var normals = new Float32Array(polygon.facesCount * 9);\n\t var colours = new Float32Array(polygon.facesCount * 9);\n\t\n\t // One component per vertex per face (1 x 3 = 3)\n\t var tops = new Float32Array(polygon.facesCount * 3);\n\t\n\t var pickingIds;\n\t if (polygon.pickingId) {\n\t // One component per vertex per face (1 x 3 = 3)\n\t pickingIds = new Float32Array(polygon.facesCount * 3);\n\t }\n\t\n\t var pA = new _three2['default'].Vector3();\n\t var pB = new _three2['default'].Vector3();\n\t var pC = new _three2['default'].Vector3();\n\t\n\t var cb = new _three2['default'].Vector3();\n\t var ab = new _three2['default'].Vector3();\n\t\n\t var index;\n\t\n\t var _faces = polygon.faces;\n\t var _vertices = polygon.vertices;\n\t var _colour = polygon.colours;\n\t var _tops = polygon.tops;\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = polygon.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _faces.length; i++) {\n\t // Array of vertex indexes for the face\n\t index = _faces[i][0];\n\t\n\t var ax = _vertices[index][0];\n\t var ay = _vertices[index][1];\n\t var az = _vertices[index][2];\n\t\n\t var c1 = _colour[i][0];\n\t var t1 = _tops[i][0];\n\t\n\t index = _faces[i][1];\n\t\n\t var bx = _vertices[index][0];\n\t var by = _vertices[index][1];\n\t var bz = _vertices[index][2];\n\t\n\t var c2 = _colour[i][1];\n\t var t2 = _tops[i][1];\n\t\n\t index = _faces[i][2];\n\t\n\t var cx = _vertices[index][0];\n\t var cy = _vertices[index][1];\n\t var cz = _vertices[index][2];\n\t\n\t var c3 = _colour[i][2];\n\t var t3 = _tops[i][2];\n\t\n\t // Flat face normals\n\t // From: http://threejs.org/examples/webgl_buffergeometry.html\n\t pA.set(ax, ay, az);\n\t pB.set(bx, by, bz);\n\t pC.set(cx, cy, cz);\n\t\n\t cb.subVectors(pC, pB);\n\t ab.subVectors(pA, pB);\n\t cb.cross(ab);\n\t\n\t cb.normalize();\n\t\n\t var nx = cb.x;\n\t var ny = cb.y;\n\t var nz = cb.z;\n\t\n\t positions[lastIndex * 9 + 0] = ax;\n\t positions[lastIndex * 9 + 1] = ay;\n\t positions[lastIndex * 9 + 2] = az;\n\t\n\t normals[lastIndex * 9 + 0] = nx;\n\t normals[lastIndex * 9 + 1] = ny;\n\t normals[lastIndex * 9 + 2] = nz;\n\t\n\t colours[lastIndex * 9 + 0] = c1[0];\n\t colours[lastIndex * 9 + 1] = c1[1];\n\t colours[lastIndex * 9 + 2] = c1[2];\n\t\n\t positions[lastIndex * 9 + 3] = bx;\n\t positions[lastIndex * 9 + 4] = by;\n\t positions[lastIndex * 9 + 5] = bz;\n\t\n\t normals[lastIndex * 9 + 3] = nx;\n\t normals[lastIndex * 9 + 4] = ny;\n\t normals[lastIndex * 9 + 5] = nz;\n\t\n\t colours[lastIndex * 9 + 3] = c2[0];\n\t colours[lastIndex * 9 + 4] = c2[1];\n\t colours[lastIndex * 9 + 5] = c2[2];\n\t\n\t positions[lastIndex * 9 + 6] = cx;\n\t positions[lastIndex * 9 + 7] = cy;\n\t positions[lastIndex * 9 + 8] = cz;\n\t\n\t normals[lastIndex * 9 + 6] = nx;\n\t normals[lastIndex * 9 + 7] = ny;\n\t normals[lastIndex * 9 + 8] = nz;\n\t\n\t colours[lastIndex * 9 + 6] = c3[0];\n\t colours[lastIndex * 9 + 7] = c3[1];\n\t colours[lastIndex * 9 + 8] = c3[2];\n\t\n\t tops[lastIndex * 3 + 0] = t1;\n\t tops[lastIndex * 3 + 1] = t2;\n\t tops[lastIndex * 3 + 2] = t3;\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex * 3 + 0] = _pickingId;\n\t pickingIds[lastIndex * 3 + 1] = _pickingId;\n\t pickingIds[lastIndex * 3 + 2] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t positions: positions,\n\t normals: normals,\n\t colors: colours,\n\t tops: tops\n\t };\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t }, {\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0][0][0]);\n\t }\n\t }]);\n\t\n\t return PolygonLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PolygonLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PolygonLayer(coordinates, options);\n\t};\n\t\n\texports.polygonLayer = noNew;\n\n/***/ },\n/* 85 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Provide alternative output using tubes and splines / curves\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\t// TODO: Allow _setBufferAttributes to use a custom function passed in to\n\t// generate a custom mesh\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoGeo = __webpack_require__(6);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(81);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar PolylineLayer = (function (_Layer) {\n\t _inherits(PolylineLayer, _Layer);\n\t\n\t function PolylineLayer(coordinates, options) {\n\t _classCallCheck(this, PolylineLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t polylineMaterial: null,\n\t onPolylineMesh: null,\n\t onBufferAttributes: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t lineOpacity: 1,\n\t lineTransparent: false,\n\t lineColor: '#ffffff',\n\t lineWidth: 1,\n\t lineBlending: _three2['default'].NormalBlending\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PolylineLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of lines so it's easy to support\n\t // MultiLineString features (a single line would be a MultiLineString with a\n\t // single line in the array)\n\t this._coordinates = PolylineLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t // Polyline features are always flat (for now at least)\n\t this._flat = true;\n\t }\n\t\n\t _createClass(PolylineLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._setCoordinates();\n\t\n\t if (_this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (_this.isOutput()) {\n\t _this._pickingMesh = new _three2['default'].Object3D();\n\t _this.addToPicking(_this._pickingMesh);\n\t }\n\t\n\t _this._setPickingId();\n\t _this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t PolylineLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) {\n\t _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes);\n\t _this._flat = result.flat;\n\t\n\t var attributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t\n\t if (_this._options.interactive) {\n\t attributeLengths.pickingIds = 1;\n\t }\n\t\n\t if (_this.isOutput()) {\n\t var style = _this._options.style;\n\t\n\t // Set mesh if not merging elsewhere\n\t PolylineLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options).then(function (result) {\n\t // Output mesh\n\t _this.add(result.mesh);\n\t\n\t if (result.pickingMesh) {\n\t _this._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t result.attributes = null;\n\t result = null;\n\t\n\t resolve(_this);\n\t });\n\t });\n\t }\n\t\n\t // Return center of polyline as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t //\n\t // TODO: Find proper center position instead of returning first coordinate\n\t // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return line bounds in geographic coordinates\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this2 = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this2.emit('click', _this2, point2d, point3d, intersects);\n\t });\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t }, {\n\t key: '_setCoordinates',\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates[0][0];\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var point;\n\t return this._coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (latlon) {\n\t point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * point.x;\n\t _this3._offset.y = -1 * point.y;\n\t\n\t _this3._options.pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'isFlat',\n\t\n\t // Returns true if the line is flat (has no height)\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiLineString GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PolylineLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'SetBufferAttributes',\n\t value: function SetBufferAttributes(coordinates, options) {\n\t return new Promise(function (resolve) {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (options.style.lineHeight) {\n\t height = _geoGeo2['default'].metresToWorld(options.style.lineHeight, options.pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(options.style.lineColor);\n\t\n\t var flat = true;\n\t\n\t // For each line\n\t var attributes = coordinates.map(function (_projectedCoordinates) {\n\t var _vertices = [];\n\t var _colours = [];\n\t\n\t // Connect coordinate with the next to make a pair\n\t //\n\t // LineSegments requires pairs of vertices so repeat the last point if\n\t // there's an odd number of vertices\n\t var nextCoord;\n\t _projectedCoordinates.forEach(function (coordinate, index) {\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _vertices.push([coordinate.x, height, coordinate.y]);\n\t\n\t nextCoord = _projectedCoordinates[index + 1] ? _projectedCoordinates[index + 1] : coordinate;\n\t\n\t _colours.push([colour.r, colour.g, colour.b]);\n\t _vertices.push([nextCoord.x, height, nextCoord.y]);\n\t });\n\t\n\t var line = {\n\t vertices: _vertices,\n\t colours: _colours,\n\t verticesCount: _vertices.length\n\t };\n\t\n\t if (options.interactive && options.pickingId) {\n\t // Inject picking ID\n\t line.pickingId = options.pickingId;\n\t }\n\t\n\t // Convert line representation to proper attribute arrays\n\t return PolylineLayer.ToAttributes(line);\n\t });\n\t\n\t resolve({\n\t attributes: attributes,\n\t flat: flat\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'SetMesh',\n\t value: function SetMesh(attributes, attributeLengths, flat, style, options) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t for (var key in attributes) {\n\t geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key]));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (options.polylineMaterial && options.polylineMaterial instanceof _three2['default'].Material) {\n\t material = options.polylineMaterial;\n\t } else {\n\t material = new _three2['default'].LineBasicMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t linewidth: style.lineWidth,\n\t transparent: style.lineTransparent,\n\t opacity: style.lineOpacity,\n\t blending: style.lineBlending\n\t });\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof options.onPolylineMesh === 'function') {\n\t mesh = options.onPolylineMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].LineSegments(geometry, material);\n\t\n\t if (style.lineRenderOrder !== undefined) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = style.lineRenderOrder;\n\t }\n\t\n\t mesh.castShadow = true;\n\t // mesh.receiveShadow = true;\n\t }\n\t\n\t if (options.interactive) {\n\t material = new _enginePickingMaterial2['default']();\n\t // material.side = THREE.BackSide;\n\t\n\t // Make the line wider / easier to pick\n\t material.linewidth = style.lineWidth + material.linePadding;\n\t\n\t var pickingMesh = new _three2['default'].LineSegments(geometry, material);\n\t }\n\t\n\t return Promise.resolve({\n\t mesh: mesh,\n\t pickingMesh: pickingMesh\n\t });\n\t }\n\t }, {\n\t key: 'ToAttributes',\n\t value: function ToAttributes(line) {\n\t // Three components per vertex\n\t var vertices = new Float32Array(line.verticesCount * 3);\n\t var colours = new Float32Array(line.verticesCount * 3);\n\t\n\t var pickingIds;\n\t if (line.pickingId) {\n\t // One component per vertex\n\t pickingIds = new Float32Array(line.verticesCount);\n\t }\n\t\n\t var _vertices = line.vertices;\n\t var _colour = line.colours;\n\t\n\t var _pickingId;\n\t if (pickingIds) {\n\t _pickingId = line.pickingId;\n\t }\n\t\n\t var lastIndex = 0;\n\t\n\t for (var i = 0; i < _vertices.length; i++) {\n\t var ax = _vertices[i][0];\n\t var ay = _vertices[i][1];\n\t var az = _vertices[i][2];\n\t\n\t var c1 = _colour[i];\n\t\n\t vertices[lastIndex * 3 + 0] = ax;\n\t vertices[lastIndex * 3 + 1] = ay;\n\t vertices[lastIndex * 3 + 2] = az;\n\t\n\t colours[lastIndex * 3 + 0] = c1[0];\n\t colours[lastIndex * 3 + 1] = c1[1];\n\t colours[lastIndex * 3 + 2] = c1[2];\n\t\n\t if (pickingIds) {\n\t pickingIds[lastIndex] = _pickingId;\n\t }\n\t\n\t lastIndex++;\n\t }\n\t\n\t var attributes = {\n\t positions: vertices,\n\t colors: colours\n\t };\n\t\n\t if (pickingIds) {\n\t attributes.pickingIds = pickingIds;\n\t }\n\t\n\t return attributes;\n\t }\n\t }, {\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0][0]);\n\t }\n\t }]);\n\t\n\t return PolylineLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PolylineLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PolylineLayer(coordinates, options);\n\t};\n\t\n\texports.polylineLayer = noNew;\n\n/***/ },\n/* 86 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\t// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\t\n\t// TODO: Look at ways to drop unneeded references to array buffers, etc to\n\t// reduce memory footprint\n\t\n\t// TODO: Point features may be using custom models / meshes and so an approach\n\t// needs to be found to allow these to be brokwn down into buffer attributes for\n\t// merging\n\t//\n\t// Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry\n\t// and pull out the attributes\n\t\n\t// TODO: Support sprite objects using textures\n\t\n\t// TODO: Provide option to billboard geometry so it always faces the camera\n\t\n\t// TODO: Support dynamic updating / hiding / animation of geometry\n\t//\n\t// This could be pretty hard as it's all packed away within BufferGeometry and\n\t// may even be merged by another layer (eg. GeoJSONLayer)\n\t//\n\t// How much control should this layer support? Perhaps a different or custom\n\t// layer would be better suited for animation, for example.\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _three = __webpack_require__(10);\n\t\n\tvar _three2 = _interopRequireDefault(_three);\n\t\n\tvar _geoGeo = __webpack_require__(6);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\tvar _utilBuffer = __webpack_require__(81);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _PolygonLayer = __webpack_require__(84);\n\t\n\tvar _PolygonLayer2 = _interopRequireDefault(_PolygonLayer);\n\t\n\tvar PointLayer = (function (_Layer) {\n\t _inherits(PointLayer, _Layer);\n\t\n\t function PointLayer(coordinates, options) {\n\t _classCallCheck(this, PointLayer);\n\t\n\t var defaults = {\n\t output: true,\n\t interactive: false,\n\t // THREE.Geometry or THREE.BufferGeometry to use for point output\n\t pointGeometry: null,\n\t // Custom material override\n\t //\n\t // TODO: Should this be in the style object?\n\t pointMaterial: null,\n\t onPointMesh: null,\n\t // This default style is separate to Util.GeoJSON.defaultStyle\n\t style: {\n\t pointColor: '#ff0000'\n\t }\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(PointLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t // Return coordinates as array of points so it's easy to support\n\t // MultiPoint features (a single point would be a MultiPoint with a\n\t // single point in the array)\n\t this._coordinates = PointLayer.isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t this._flat = false;\n\t }\n\t\n\t _createClass(PointLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t _this._setCoordinates();\n\t\n\t if (_this._options.interactive) {\n\t // Only add to picking mesh if this layer is controlling output\n\t //\n\t // Otherwise, assume another component will eventually add a mesh to\n\t // the picking scene\n\t if (_this.isOutput()) {\n\t _this._pickingMesh = new _three2['default'].Object3D();\n\t _this.addToPicking(_this._pickingMesh);\n\t }\n\t\n\t _this._setPickingId();\n\t _this._addPickingEvents();\n\t }\n\t\n\t // Store geometry representation as instances of THREE.BufferAttribute\n\t PointLayer.SetBufferAttributes(_this._projectedCoordinates, _this._options).then(function (result) {\n\t _this._bufferAttributes = _utilBuffer2['default'].mergeAttributes(result.attributes);\n\t _this._flat = result.flat;\n\t\n\t var attributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3\n\t };\n\t\n\t if (_this._options.interactive) {\n\t attributeLengths.pickingIds = 1;\n\t }\n\t\n\t if (_this.isOutput()) {\n\t var style = _this._options.style;\n\t\n\t // Set mesh if not merging elsewhere\n\t // TODO: Dedupe with PolygonLayer as they are identical\n\t PointLayer.SetMesh(_this._bufferAttributes, attributeLengths, _this._flat, style, _this._options, _this._world._environment._skybox).then(function (result) {\n\t // Output mesh\n\t _this.add(result.mesh);\n\t\n\t if (result.pickingMesh) {\n\t _this._pickingMesh.add(result.pickingMesh);\n\t }\n\t });\n\t }\n\t\n\t result.attributes = null;\n\t result = null;\n\t\n\t resolve(_this);\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // Return center of point as a LatLon\n\t //\n\t // This is used for things like placing popups / UI elements on the layer\n\t }, {\n\t key: 'getCenter',\n\t value: function getCenter() {\n\t return this._center;\n\t }\n\t\n\t // Return point bounds in geographic coordinates\n\t //\n\t // While not useful for single points, it could be useful for MultiPoint\n\t //\n\t // TODO: Implement getBounds()\n\t }, {\n\t key: 'getBounds',\n\t value: function getBounds() {}\n\t\n\t // Get unique ID for picking interaction\n\t }, {\n\t key: '_setPickingId',\n\t value: function _setPickingId() {\n\t this._pickingId = this.getPickingId();\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPickingEvents',\n\t value: function _addPickingEvents() {\n\t var _this2 = this;\n\t\n\t // TODO: Find a way to properly remove this listener on destroy\n\t this._world.on('pick-' + this._pickingId, function (point2d, point3d, intersects) {\n\t // Re-emit click event from the layer\n\t _this2.emit('click', _this2, point2d, point3d, intersects);\n\t });\n\t }\n\t }, {\n\t key: 'getBufferAttributes',\n\t value: function getBufferAttributes() {\n\t return this._bufferAttributes;\n\t }\n\t\n\t // Used by external components to clear some memory when the attributes\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the attributes here after merging them\n\t // using something like the GeoJSONLayer\n\t }, {\n\t key: 'clearBufferAttributes',\n\t value: function clearBufferAttributes() {\n\t this._bufferAttributes = null;\n\t }\n\t\n\t // Used by external components to clear some memory when the coordinates\n\t // are no longer required to be stored in this layer\n\t //\n\t // For example, you would want to clear the coordinates here after this\n\t // layer is merged in something like the GeoJSONLayer\n\t }, {\n\t key: 'clearCoordinates',\n\t value: function clearCoordinates() {\n\t this._coordinates = null;\n\t this._projectedCoordinates = null;\n\t }\n\t }, {\n\t key: '_setCoordinates',\n\t\n\t // Convert and project coordinates\n\t //\n\t // TODO: Calculate bounds\n\t value: function _setCoordinates() {\n\t this._bounds = [];\n\t this._coordinates = this._convertCoordinates(this._coordinates);\n\t\n\t this._projectedBounds = [];\n\t this._projectedCoordinates = this._projectCoordinates();\n\t\n\t this._center = this._coordinates;\n\t }\n\t\n\t // Recursively convert input coordinates into LatLon objects\n\t //\n\t // Calculate geographic bounds at the same time\n\t //\n\t // TODO: Calculate geographic bounds\n\t }, {\n\t key: '_convertCoordinates',\n\t value: function _convertCoordinates(coordinates) {\n\t return coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t }\n\t\n\t // Recursively project coordinates into world positions\n\t //\n\t // Calculate world bounds, offset and pointScale at the same time\n\t //\n\t // TODO: Calculate world bounds\n\t }, {\n\t key: '_projectCoordinates',\n\t value: function _projectCoordinates() {\n\t var _this3 = this;\n\t\n\t var _point;\n\t return this._coordinates.map(function (latlon) {\n\t _point = _this3._world.latLonToPoint(latlon);\n\t\n\t // TODO: Is offset ever being used or needed?\n\t if (!_this3._offset) {\n\t _this3._offset = (0, _geoPoint.point)(0, 0);\n\t _this3._offset.x = -1 * _point.x;\n\t _this3._offset.y = -1 * _point.y;\n\t\n\t _this3._options.pointScale = _this3._world.pointScale(latlon);\n\t }\n\t\n\t return _point;\n\t });\n\t }\n\t\n\t // Returns true if the line is flat (has no height)\n\t }, {\n\t key: 'isFlat',\n\t value: function isFlat() {\n\t return this._flat;\n\t }\n\t\n\t // Returns true if coordinates refer to a single geometry\n\t //\n\t // For example, not coordinates for a MultiPoint GeoJSON feature\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t if (this._pickingMesh) {\n\t // TODO: Properly dispose of picking mesh\n\t this._pickingMesh = null;\n\t }\n\t\n\t this.clearCoordinates();\n\t this.clearBufferAttributes();\n\t\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(PointLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'SetBufferAttributes',\n\t value: function SetBufferAttributes(coordinates, options) {\n\t return new Promise(function (resolve) {\n\t var height = 0;\n\t\n\t // Convert height into world units\n\t if (options.style.pointHeight) {\n\t height = _geoGeo2['default'].metresToWorld(options.style.pointHeight, options.pointScale);\n\t }\n\t\n\t var colour = new _three2['default'].Color();\n\t colour.set(options.style.pointColor);\n\t\n\t // Use default geometry if none has been provided or the provided geometry\n\t // isn't valid\n\t if (!options.pointGeometry || !options.pointGeometry instanceof _three2['default'].Geometry || !options.pointGeometry instanceof _three2['default'].BufferGeometry) {\n\t // Debug geometry for points is a thin bar\n\t //\n\t // TODO: Allow point geometry to be customised / overridden\n\t var geometryWidth = _geoGeo2['default'].metresToWorld(25, options.pointScale);\n\t var geometryHeight = _geoGeo2['default'].metresToWorld(200, options.pointScale);\n\t var _geometry = new _three2['default'].BoxGeometry(geometryWidth, geometryHeight, geometryWidth);\n\t\n\t // Shift geometry up so it sits on the ground\n\t _geometry.translate(0, geometryHeight * 0.5, 0);\n\t\n\t // Pull attributes out of debug geometry\n\t geometry = new _three2['default'].BufferGeometry().fromGeometry(_geometry);\n\t } else {\n\t if (options.geometry instanceof _three2['default'].BufferGeometry) {\n\t geometry = options.pointGeometry;\n\t } else {\n\t geometry = new _three2['default'].BufferGeometry().fromGeometry(options.pointGeometry);\n\t }\n\t }\n\t\n\t var attributes = coordinates.map(function (coordinate) {\n\t var _vertices = [];\n\t var _normals = [];\n\t var _colours = [];\n\t\n\t var _geometry = geometry.clone();\n\t _geometry.translate(coordinate.x, height, coordinate.y);\n\t\n\t var _vertices = _geometry.attributes.position.clone().array;\n\t var _normals = _geometry.attributes.normal.clone().array;\n\t var _colours = _geometry.attributes.color.clone().array;\n\t\n\t for (var i = 0; i < _colours.length; i += 3) {\n\t _colours[i] = colour.r;\n\t _colours[i + 1] = colour.g;\n\t _colours[i + 2] = colour.b;\n\t }\n\t\n\t var _point = {\n\t positions: _vertices,\n\t normals: _normals,\n\t colors: _colours\n\t };\n\t\n\t if (options.interactive && options.pickingId) {\n\t // Inject picking ID\n\t _point.pickingId = options.pickingId;\n\t }\n\t\n\t return _point;\n\t });\n\t\n\t resolve({\n\t attributes: attributes,\n\t flat: false\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'SetMesh',\n\t value: function SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n\t var geometry = new _three2['default'].BufferGeometry();\n\t\n\t for (var key in attributes) {\n\t geometry.addAttribute(key.slice(0, -1), new _three2['default'].BufferAttribute(attributes[key], attributeLengths[key]));\n\t }\n\t\n\t geometry.computeBoundingBox();\n\t\n\t var material;\n\t if (options.pointMaterial && options.pointMaterial instanceof _three2['default'].Material) {\n\t material = options.pointMaterial;\n\t } else if (!skybox) {\n\t material = new _three2['default'].MeshPhongMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t // side: THREE.BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t } else {\n\t material = new _three2['default'].MeshStandardMaterial({\n\t vertexColors: _three2['default'].VertexColors,\n\t // side: THREE.BackSide,\n\t transparent: style.transparent,\n\t opacity: style.opacity,\n\t blending: style.blending\n\t });\n\t material.roughness = 1;\n\t material.metalness = 0.1;\n\t material.envMapIntensity = 3;\n\t material.envMap = skybox.getRenderTarget();\n\t }\n\t\n\t var mesh;\n\t\n\t // Pass mesh through callback, if defined\n\t if (typeof options.onPolygonMesh === 'function') {\n\t mesh = options.onPolygonMesh(geometry, material);\n\t } else {\n\t mesh = new _three2['default'].Mesh(geometry, material);\n\t\n\t mesh.castShadow = true;\n\t mesh.receiveShadow = true;\n\t }\n\t\n\t if (flat) {\n\t material.depthWrite = false;\n\t mesh.renderOrder = 4;\n\t }\n\t\n\t if (options.interactive) {\n\t material = new _enginePickingMaterial2['default']();\n\t material.side = _three2['default'].BackSide;\n\t\n\t var pickingMesh = new _three2['default'].Mesh(geometry, material);\n\t }\n\t\n\t return Promise.resolve({\n\t mesh: mesh,\n\t pickingMesh: pickingMesh\n\t });\n\t }\n\t }, {\n\t key: 'isSingle',\n\t value: function isSingle(coordinates) {\n\t return !Array.isArray(coordinates[0]);\n\t }\n\t }]);\n\t\n\t return PointLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = PointLayer;\n\t\n\tvar noNew = function noNew(coordinates, options) {\n\t return new PointLayer(coordinates, options);\n\t};\n\t\n\texports.pointLayer = noNew;\n\n/***/ },\n/* 87 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _slicedToArray = (function () { function sliceIterator(arr, i) { var _arr = []; var _n = true; var _d = false; var _e = undefined; try { for (var _i = arr[Symbol.iterator](), _s; !(_n = (_s = _i.next()).done); _n = true) { _arr.push(_s.value); if (i && _arr.length === i) break; } } catch (err) { _d = true; _e = err; } finally { try { if (!_n && _i['return']) _i['return'](); } finally { if (_d) throw _e; } } return _arr; } return function (arr, i) { if (Array.isArray(arr)) { return arr; } else if (Symbol.iterator in Object(arr)) { return sliceIterator(arr, i); } else { throw new TypeError('Invalid attempt to destructure non-iterable instance'); } }; })();\n\t\n\tvar _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; }; })();\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _Layer2 = __webpack_require__(34);\n\t\n\tvar _Layer3 = _interopRequireDefault(_Layer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar _reqwest = __webpack_require__(73);\n\t\n\tvar _reqwest2 = _interopRequireDefault(_reqwest);\n\t\n\tvar _utilGeoJSON = __webpack_require__(75);\n\t\n\tvar _utilGeoJSON2 = _interopRequireDefault(_utilGeoJSON);\n\t\n\tvar _utilWorker = __webpack_require__(46);\n\t\n\tvar _utilWorker2 = _interopRequireDefault(_utilWorker);\n\t\n\tvar _utilBuffer = __webpack_require__(81);\n\t\n\tvar _utilBuffer2 = _interopRequireDefault(_utilBuffer);\n\t\n\tvar _utilStringify = __webpack_require__(88);\n\t\n\tvar _utilStringify2 = _interopRequireDefault(_utilStringify);\n\t\n\tvar _geometryPolygonLayer = __webpack_require__(84);\n\t\n\tvar _geometryPolygonLayer2 = _interopRequireDefault(_geometryPolygonLayer);\n\t\n\tvar _geometryPolylineLayer = __webpack_require__(85);\n\t\n\tvar _geometryPolylineLayer2 = _interopRequireDefault(_geometryPolylineLayer);\n\t\n\tvar _geometryPointLayer = __webpack_require__(86);\n\t\n\tvar _geometryPointLayer2 = _interopRequireDefault(_geometryPointLayer);\n\t\n\tvar _geoLatLon = __webpack_require__(7);\n\t\n\tvar _geoPoint = __webpack_require__(8);\n\t\n\tvar _geoGeo = __webpack_require__(6);\n\t\n\tvar _geoGeo2 = _interopRequireDefault(_geoGeo);\n\t\n\tvar _enginePickingMaterial = __webpack_require__(82);\n\t\n\tvar _enginePickingMaterial2 = _interopRequireDefault(_enginePickingMaterial);\n\t\n\t// TODO: Allow filter method to be run inside a worker to improve performance\n\t// TODO: Allow onEachFeature method to be run inside a worker to improve performance\n\t\n\tvar GeoJSONWorkerLayer = (function (_Layer) {\n\t _inherits(GeoJSONWorkerLayer, _Layer);\n\t\n\t function GeoJSONWorkerLayer(geojson, options) {\n\t _classCallCheck(this, GeoJSONWorkerLayer);\n\t\n\t var defaults = {\n\t topojson: false,\n\t style: _utilGeoJSON2['default'].defaultStyle,\n\t onEachFeature: null,\n\t onEachFeatureWorker: null,\n\t onAddAttributes: null,\n\t interactive: false,\n\t pointGeometry: null,\n\t onClick: null,\n\t headers: {}\n\t };\n\t\n\t var _options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t if (typeof options.style === 'object') {\n\t _options.style = (0, _lodashAssign2['default'])({}, defaults.style, options.style);\n\t }\n\t\n\t _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'constructor', this).call(this, _options);\n\t\n\t this._aborted = false;\n\t this._geojson = geojson;\n\t }\n\t\n\t _createClass(GeoJSONWorkerLayer, [{\n\t key: '_onAdd',\n\t value: function _onAdd(world) {\n\t if (this._options.interactive) {\n\t // Worker layer always controls output to add a picking mesh\n\t this._pickingMesh = new THREE.Object3D();\n\t }\n\t\n\t // Process GeoJSON\n\t return this._process(this._geojson);\n\t }\n\t\n\t // Use workers to request and process GeoJSON, returning data structure\n\t // containing geometry and any supplementary data for output\n\t }, {\n\t key: '_process',\n\t value: function _process(_geojson) {\n\t var _this = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var style = _this._options.style;\n\t\n\t // TODO: Convert to buffer and use transferrable objects\n\t if (typeof _this._options.style === 'function') {\n\t style = _utilStringify2['default'].functionToString(_this._options.style);\n\t }\n\t\n\t var pointGeometry = _this._options.pointGeometry;\n\t\n\t // TODO: Convert to buffer and use transferrable objects\n\t if (typeof _this._options.pointGeometry === 'function') {\n\t pointGeometry = _utilStringify2['default'].functionToString(_this._options.pointGeometry);\n\t }\n\t\n\t var geojson = _geojson;\n\t var transferrables = [];\n\t\n\t if (typeof geojson !== 'string') {\n\t _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(geojson));\n\t transferrables.push(geojson.buffer);\n\t _this._execWorker(geojson, _this._options.topojson, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t } else if (typeof _this._options.filter === 'function' || typeof _this._options.onEachFeature === 'function') {\n\t GeoJSONWorkerLayer.RequestGeoJSON(geojson).then(function (res) {\n\t // if (this._aborted) {\n\t // resolve();\n\t // return;\n\t // }\n\t\n\t var fc = _utilGeoJSON2['default'].collectFeatures(res, _this._options.topojson);\n\t var features = fc.features;\n\t\n\t // Run filter, if provided\n\t if (_this._options.filter) {\n\t fc.features = features.filter(_this._options.filter);\n\t }\n\t\n\t if (_this._options.onEachFeature) {\n\t var feature;\n\t for (var i = 0; i < features.length; i++) {\n\t feature = features[i];\n\t _this._options.onEachFeature(feature);\n\t };\n\t }\n\t\n\t _this._geojson = geojson = _utilBuffer2['default'].stringToUint8Array(JSON.stringify(fc));\n\t transferrables.push(geojson.buffer);\n\t\n\t _this._execWorker(geojson, false, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t } else {\n\t _this._execWorker(geojson, _this._options.topojson, _this._options.headers, _this._world._originPoint, style, _this._options.interactive, pointGeometry, transferrables).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t }\n\t });\n\t }\n\t }, {\n\t key: '_execWorker',\n\t value: function _execWorker(geojson, topojson, headers, originPoint, style, interactive, pointGeometry, transferrables) {\n\t var _this2 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t console.time('Worker round trip');\n\t\n\t _utilWorker2['default'].exec('GeoJSONWorkerLayer.Process', [geojson, topojson, headers, originPoint, style, interactive, pointGeometry], transferrables).then(function (results) {\n\t console.timeEnd('Worker round trip');\n\t\n\t // if (this._aborted) {\n\t // resolve();\n\t // return;\n\t // }\n\t\n\t var processPromises = [];\n\t\n\t if (results.polygons) {\n\t processPromises.push(_this2._processPolygonResults(results.polygons));\n\t }\n\t\n\t if (results.polylines) {\n\t processPromises.push(_this2._processPolylineResults(results.polylines));\n\t }\n\t\n\t if (results.points) {\n\t processPromises.push(_this2._processPointResults(results.points));\n\t }\n\t\n\t if (processPromises.length > 0) {\n\t Promise.all(processPromises).then(function () {\n\t resolve();\n\t })['catch'](reject);\n\t } else {\n\t resolve();\n\t }\n\t });\n\t });\n\t }\n\t\n\t // TODO: Dedupe with polyline method\n\t }, {\n\t key: '_processPolygonResults',\n\t value: function _processPolygonResults(results) {\n\t var _this3 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions);\n\t var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals);\n\t var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors);\n\t var splitTops = _utilBuffer2['default'].splitFloat32Array(results.attributes.tops);\n\t\n\t var splitOutlinePositions;\n\t var splitOutlineColors;\n\t\n\t if (results.outlineAttributes) {\n\t splitOutlinePositions = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.positions);\n\t splitOutlineColors = _utilBuffer2['default'].splitFloat32Array(results.outlineAttributes.colors);\n\t }\n\t\n\t var splitProperties;\n\t if (results.properties) {\n\t splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties);\n\t }\n\t\n\t var flats = results.flats;\n\t\n\t var objects = [];\n\t var outlineObjects = [];\n\t\n\t var obj;\n\t var pickingId;\n\t var pickingIds;\n\t var properties;\n\t\n\t var polygonAttributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3,\n\t tops: 1\n\t };\n\t\n\t var polygonOutlineAttributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t\n\t for (var i = 0; i < splitPositions.length; i++) {\n\t if (splitProperties && splitProperties[i]) {\n\t properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i]));\n\t } else {\n\t properties = {};\n\t }\n\t\n\t // WORKERS: obj.attributes should actually an array of polygons for\n\t // the feature, though the current logic isn't aware of that\n\t obj = {\n\t attributes: [{\n\t positions: splitPositions[i],\n\t normals: splitNormals[i],\n\t colors: splitColors[i],\n\t tops: splitTops[i]\n\t }],\n\t properties: properties,\n\t flat: flats[i]\n\t };\n\t\n\t // WORKERS: If interactive, generate unique ID for each feature, create\n\t // the buffer attributes and set up event listeners\n\t if (_this3._options.interactive) {\n\t pickingId = _this3.getPickingId();\n\t\n\t pickingIds = new Float32Array(splitPositions[i].length / 3);\n\t pickingIds.fill(pickingId);\n\t\n\t obj.attributes[0].pickingIds = pickingIds;\n\t\n\t polygonAttributeLengths.pickingIds = 1;\n\t\n\t _this3._addPicking(pickingId, properties);\n\t }\n\t\n\t // TODO: Make this specific to polygon attributes\n\t if (typeof _this3._options.onAddAttributes === 'function') {\n\t var customAttributes = _this3._options.onAddAttributes(obj.attributes[0], properties);\n\t var customAttribute;\n\t for (var key in customAttributes) {\n\t customAttribute = customAttributes[key];\n\t obj.attributes[0][key] = customAttribute.value;\n\t polygonAttributeLengths[key] = customAttribute.length;\n\t }\n\t }\n\t\n\t objects.push(obj);\n\t }\n\t\n\t for (var i = 0; i < splitOutlinePositions.length; i++) {\n\t obj = {\n\t attributes: [{\n\t positions: splitOutlinePositions[i],\n\t colors: splitOutlineColors[i]\n\t }],\n\t flat: true\n\t };\n\t\n\t outlineObjects.push(obj);\n\t }\n\t\n\t var polygonAttributes = [];\n\t var polygonOutlineAttributes = [];\n\t\n\t var polygonFlat = true;\n\t\n\t for (var i = 0; i < objects.length; i++) {\n\t obj = objects[i];\n\t\n\t // TODO: Work out why obj.flat is rarely set to something other than\n\t // true or false. Potentially undefined.\n\t if (polygonFlat && obj.flat === false) {\n\t polygonFlat = false;\n\t }\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t polygonAttributes.push(bufferAttributes);\n\t };\n\t\n\t for (var i = 0; i < outlineObjects.length; i++) {\n\t obj = outlineObjects[i];\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t polygonOutlineAttributes.push(bufferAttributes);\n\t };\n\t\n\t var outputPromises = [];\n\t\n\t var style;\n\t\n\t if (polygonAttributes.length > 0) {\n\t var mergedPolygonAttributes = _utilBuffer2['default'].mergeAttributes(polygonAttributes);\n\t\n\t // TODO: Make this work when style is a function per feature\n\t style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t outputPromises.push(_this3._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat));\n\t }\n\t\n\t if (polygonOutlineAttributes.length > 0) {\n\t var mergedPolygonOutlineAttributes = _utilBuffer2['default'].mergeAttributes(polygonOutlineAttributes);\n\t\n\t style = typeof _this3._options.style === 'function' ? _this3._options.style(objects[0]) : _this3._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t if (style.outlineRenderOrder !== undefined) {\n\t style.lineRenderOrder = style.outlineRenderOrder;\n\t } else {\n\t style.lineRenderOrder = style.renderOrder ? style.renderOrder + 1 : 4;\n\t }\n\t\n\t if (style.outlineWidth) {\n\t style.lineWidth = style.outlineWidth;\n\t }\n\t\n\t outputPromises.push(_this3._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true));\n\t }\n\t\n\t Promise.all(outputPromises).then(function (results) {\n\t var _results = _slicedToArray(results, 2);\n\t\n\t var polygonResult = _results[0];\n\t var outlineResult = _results[1];\n\t\n\t if (polygonResult) {\n\t _this3._polygonMesh = polygonResult.mesh;\n\t _this3.add(_this3._polygonMesh);\n\t\n\t if (polygonResult.pickingMesh) {\n\t _this3._pickingMesh.add(polygonResult.pickingMesh);\n\t }\n\t }\n\t\n\t if (outlineResult) {\n\t _this3.add(outlineResult.mesh);\n\t }\n\t\n\t resolve();\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // TODO: Dedupe with polygon method\n\t }, {\n\t key: '_processPolylineResults',\n\t value: function _processPolylineResults(results) {\n\t var _this4 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions);\n\t var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors);\n\t\n\t var splitProperties;\n\t if (results.properties) {\n\t splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties);\n\t }\n\t\n\t var flats = results.flats;\n\t\n\t var objects = [];\n\t var obj;\n\t var pickingId;\n\t var pickingIds;\n\t var properties;\n\t\n\t var polylineAttributeLengths = {\n\t positions: 3,\n\t colors: 3\n\t };\n\t\n\t for (var i = 0; i < splitPositions.length; i++) {\n\t if (splitProperties && splitProperties[i]) {\n\t properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i]));\n\t } else {\n\t properties = {};\n\t }\n\t\n\t // WORKERS: obj.attributes should actually an array of polygons for\n\t // the feature, though the current logic isn't aware of that\n\t obj = {\n\t attributes: [{\n\t positions: splitPositions[i],\n\t colors: splitColors[i]\n\t }],\n\t properties: properties,\n\t flat: flats[i]\n\t };\n\t\n\t // WORKERS: If interactive, generate unique ID for each feature, create\n\t // the buffer attributes and set up event listeners\n\t if (_this4._options.interactive) {\n\t pickingId = _this4.getPickingId();\n\t\n\t pickingIds = new Float32Array(splitPositions[i].length / 3);\n\t pickingIds.fill(pickingId);\n\t\n\t obj.attributes[0].pickingIds = pickingIds;\n\t\n\t polylineAttributeLengths.pickingIds = 1;\n\t\n\t _this4._addPicking(pickingId, properties);\n\t }\n\t\n\t // TODO: Make this specific to polyline attributes\n\t if (typeof _this4._options.onAddAttributes === 'function') {\n\t var customAttributes = _this4._options.onAddAttributes(obj.attributes[0], properties);\n\t var customAttribute;\n\t for (var key in customAttributes) {\n\t customAttribute = customAttributes[key];\n\t obj.attributes[0][key] = customAttribute.value;\n\t polylineAttributeLengths[key] = customAttribute.length;\n\t }\n\t }\n\t\n\t objects.push(obj);\n\t }\n\t\n\t var polylineAttributes = [];\n\t\n\t var polylineFlat = true;\n\t\n\t for (var i = 0; i < objects.length; i++) {\n\t obj = objects[i];\n\t\n\t if (polylineFlat && !obj.flat) {\n\t polylineFlat = false;\n\t }\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t polylineAttributes.push(bufferAttributes);\n\t };\n\t\n\t if (polylineAttributes.length > 0) {\n\t var mergedPolylineAttributes = _utilBuffer2['default'].mergeAttributes(polylineAttributes);\n\t\n\t // TODO: Make this work when style is a function per feature\n\t var style = typeof _this4._options.style === 'function' ? _this4._options.style(objects[0]) : _this4._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this4._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then(function (result) {\n\t _this4._polylineMesh = result.mesh;\n\t _this4.add(_this4._polylineMesh);\n\t\n\t if (result.pickingMesh) {\n\t _this4._pickingMesh.add(result.pickingMesh);\n\t }\n\t\n\t resolve();\n\t })['catch'](reject);\n\t } else {\n\t resolve();\n\t }\n\t });\n\t }\n\t }, {\n\t key: '_processPointResults',\n\t value: function _processPointResults(results) {\n\t var _this5 = this;\n\t\n\t return new Promise(function (resolve, reject) {\n\t var splitPositions = _utilBuffer2['default'].splitFloat32Array(results.attributes.positions);\n\t var splitNormals = _utilBuffer2['default'].splitFloat32Array(results.attributes.normals);\n\t var splitColors = _utilBuffer2['default'].splitFloat32Array(results.attributes.colors);\n\t\n\t var splitProperties;\n\t if (results.properties) {\n\t splitProperties = _utilBuffer2['default'].splitUint8Array(results.properties);\n\t }\n\t\n\t var flats = results.flats;\n\t\n\t var objects = [];\n\t var obj;\n\t var pickingId;\n\t var pickingIds;\n\t var properties;\n\t\n\t var pointAttributeLengths = {\n\t positions: 3,\n\t normals: 3,\n\t colors: 3\n\t };\n\t\n\t for (var i = 0; i < splitPositions.length; i++) {\n\t if (splitProperties && splitProperties[i]) {\n\t properties = JSON.parse(_utilBuffer2['default'].uint8ArrayToString(splitProperties[i]));\n\t } else {\n\t properties = {};\n\t }\n\t\n\t // WORKERS: obj.attributes should actually an array of polygons for\n\t // the feature, though the current logic isn't aware of that\n\t obj = {\n\t attributes: [{\n\t positions: splitPositions[i],\n\t normals: splitNormals[i],\n\t colors: splitColors[i]\n\t }],\n\t properties: properties,\n\t flat: flats[i]\n\t };\n\t\n\t // WORKERS: If interactive, generate unique ID for each feature, create\n\t // the buffer attributes and set up event listeners\n\t if (_this5._options.interactive) {\n\t pickingId = _this5.getPickingId();\n\t\n\t pickingIds = new Float32Array(splitPositions[i].length / 3);\n\t pickingIds.fill(pickingId);\n\t\n\t obj.attributes[0].pickingIds = pickingIds;\n\t\n\t pointAttributeLengths.pickingIds = 1;\n\t\n\t _this5._addPicking(pickingId, properties);\n\t }\n\t\n\t // TODO: Make this specific to polygon attributes\n\t if (typeof _this5._options.onAddAttributes === 'function') {\n\t var customAttributes = _this5._options.onAddAttributes(obj.attributes[0], properties);\n\t var customAttribute;\n\t for (var key in customAttributes) {\n\t customAttribute = customAttributes[key];\n\t obj.attributes[0][key] = customAttribute.value;\n\t pointAttributeLengths[key] = customAttribute.length;\n\t }\n\t }\n\t\n\t objects.push(obj);\n\t }\n\t\n\t var pointAttributes = [];\n\t\n\t var pointFlat = true;\n\t\n\t for (var i = 0; i < objects.length; i++) {\n\t obj = objects[i];\n\t\n\t if (pointFlat && !obj.flat) {\n\t pointFlat = false;\n\t }\n\t\n\t var bufferAttributes = _utilBuffer2['default'].mergeAttributes(obj.attributes);\n\t pointAttributes.push(bufferAttributes);\n\t };\n\t\n\t if (pointAttributes.length > 0) {\n\t var mergedPointAttributes = _utilBuffer2['default'].mergeAttributes(pointAttributes);\n\t\n\t // TODO: Make this work when style is a function per feature\n\t var style = typeof _this5._options.style === 'function' ? _this5._options.style(objects[0]) : _this5._options.style;\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, style);\n\t\n\t _this5._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then(function (result) {\n\t _this5._pointMesh = result.mesh;\n\t _this5.add(_this5._pointMesh);\n\t\n\t if (result.pickingMesh) {\n\t _this5._pickingMesh.add(result.pickingMesh);\n\t }\n\t\n\t resolve();\n\t })['catch'](reject);\n\t } else {\n\t resolve();\n\t }\n\t });\n\t }\n\t\n\t // TODO: At some point this needs to return all the features to the main thread\n\t // so it can generate meshes and output to the scene, as well as perhaps creating\n\t // individual layers / components for each feature to track things like picking\n\t // and properties\n\t //\n\t // TODO: Find a way so the origin point isn't needed to be passed in as it\n\t // feels a bit messy and against the idea of a static Geo class\n\t //\n\t // TODO: Support passing custom geometry for point layers\n\t }, {\n\t key: '_setPolygonMesh',\n\t\n\t // Create and store mesh from buffer attributes\n\t //\n\t // Could make this an abstract method for each geometry layer\n\t value: function _setPolygonMesh(attributes, attributeLengths, style, flat) {\n\t if (!this._world) {\n\t return Promise.reject();\n\t }\n\t\n\t return _geometryPolygonLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n\t }\n\t }, {\n\t key: '_setPolylineMesh',\n\t value: function _setPolylineMesh(attributes, attributeLengths, style, flat) {\n\t if (!this._world) {\n\t return Promise.reject();\n\t }\n\t\n\t return _geometryPolylineLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options);\n\t }\n\t }, {\n\t key: '_setPointMesh',\n\t value: function _setPointMesh(attributes, attributeLengths, style, flat) {\n\t if (!this._world) {\n\t return Promise.reject();\n\t }\n\t\n\t return _geometryPointLayer2['default'].SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n\t }\n\t\n\t // Set up and re-emit interaction events\n\t }, {\n\t key: '_addPicking',\n\t value: function _addPicking(pickingId, properties) {\n\t var _this6 = this;\n\t\n\t this._world.on('pick-click-' + pickingId, function (pickingId, point2d, point3d, intersects) {\n\t _this6._world.emit('click', _this6, properties, point2d, point3d);\n\t });\n\t\n\t this._world.on('pick-hover-' + pickingId, function (pickingId, point2d, point3d, intersects) {\n\t _this6._world.emit('hover', _this6, properties, point2d, point3d);\n\t });\n\t }\n\t\n\t // TODO: Finish cleanup\n\t }, {\n\t key: 'destroy',\n\t value: function destroy() {\n\t // Run common destruction logic from parent\n\t _get(Object.getPrototypeOf(GeoJSONWorkerLayer.prototype), 'destroy', this).call(this);\n\t }\n\t }], [{\n\t key: 'Process',\n\t value: function Process(geojson, topojson, headers, originPoint, _style, _properties, _pointGeometry) {\n\t return new Promise(function (resolve, reject) {\n\t GeoJSONWorkerLayer.ProcessGeoJSON(geojson, headers).then(function (res) {\n\t // Collects features into a single FeatureCollection\n\t //\n\t // Also converts TopoJSON to GeoJSON if instructed\n\t var geojson = _utilGeoJSON2['default'].collectFeatures(res, topojson);\n\t\n\t // TODO: Check that GeoJSON is valid / usable\n\t\n\t var features = geojson.features;\n\t\n\t // TODO: Run filter, if provided (must be static)\n\t\n\t var pointScale;\n\t var polygons = [];\n\t var polylines = [];\n\t var points = [];\n\t\n\t // Deserialise style function if provided\n\t if (typeof _style === 'string') {\n\t _style = _utilStringify2['default'].stringToFunction(_style);\n\t }\n\t\n\t // Assume that a style won't be set per feature\n\t var style = _style;\n\t\n\t var pointGeometry;\n\t // Deserialise pointGeometry function if provided\n\t if (typeof _pointGeometry === 'string') {\n\t pointGeometry = _utilStringify2['default'].stringToFunction(_pointGeometry);\n\t }\n\t\n\t var feature;\n\t for (var i = 0; i < features.length; i++) {\n\t feature = features[i];\n\t\n\t var geometry = feature.geometry;\n\t var coordinates = geometry.coordinates ? geometry.coordinates : null;\n\t\n\t if (!coordinates || !geometry) {\n\t return;\n\t }\n\t\n\t // Get per-feature style object, if provided\n\t if (typeof _style === 'function') {\n\t style = (0, _lodashAssign2['default'])({}, _utilGeoJSON2['default'].defaultStyle, _style(feature));\n\t // console.log(feature, style);\n\t }\n\t\n\t if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n\t coordinates = _geometryPolygonLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t var converted = coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t });\n\t\n\t var point;\n\t var projected = converted.map(function (_coordinates) {\n\t return _coordinates.map(function (ring) {\n\t return ring.map(function (latlon) {\n\t point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint);\n\t\n\t if (!pointScale) {\n\t pointScale = _geoGeo2['default'].pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t });\n\t\n\t var polygon = {\n\t projected: projected,\n\t options: {\n\t pointScale: pointScale,\n\t style: style\n\t }\n\t };\n\t\n\t if (_properties) {\n\t polygon.properties = feature.properties;\n\t }\n\t\n\t polygons.push(polygon);\n\t }\n\t\n\t if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n\t coordinates = _geometryPolylineLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t var converted = coordinates.map(function (_coordinates) {\n\t return _coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t });\n\t\n\t var point;\n\t var projected = converted.map(function (_coordinates) {\n\t return _coordinates.map(function (latlon) {\n\t point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint);\n\t\n\t if (!pointScale) {\n\t pointScale = _geoGeo2['default'].pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t });\n\t\n\t var polyline = {\n\t projected: projected,\n\t options: {\n\t pointScale: pointScale,\n\t style: style\n\t }\n\t };\n\t\n\t if (_properties) {\n\t polyline.properties = feature.properties;\n\t }\n\t\n\t polylines.push(polyline);\n\t }\n\t\n\t if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n\t coordinates = _geometryPointLayer2['default'].isSingle(coordinates) ? [coordinates] : coordinates;\n\t\n\t var converted = coordinates.map(function (coordinate) {\n\t return (0, _geoLatLon.latLon)(coordinate[1], coordinate[0]);\n\t });\n\t\n\t var point;\n\t var projected = converted.map(function (latlon) {\n\t point = _geoGeo2['default'].latLonToPoint(latlon)._subtract(originPoint);\n\t\n\t if (!pointScale) {\n\t pointScale = _geoGeo2['default'].pointScale(latlon);\n\t }\n\t\n\t return point;\n\t });\n\t\n\t var point = {\n\t projected: projected,\n\t options: {\n\t pointGeometry: pointGeometry(feature),\n\t pointScale: pointScale,\n\t style: style\n\t }\n\t };\n\t\n\t if (_properties) {\n\t point.properties = feature.properties;\n\t }\n\t\n\t points.push(point);\n\t }\n\t };\n\t\n\t var polygonBufferPromises = [];\n\t var polylineBufferPromises = [];\n\t var pointBufferPromises = [];\n\t\n\t var polygon;\n\t for (var i = 0; i < polygons.length; i++) {\n\t polygon = polygons[i];\n\t polygonBufferPromises.push(_geometryPolygonLayer2['default'].SetBufferAttributes(polygon.projected, polygon.options));\n\t };\n\t\n\t var polyline;\n\t for (var i = 0; i < polylines.length; i++) {\n\t polyline = polylines[i];\n\t polylineBufferPromises.push(_geometryPolylineLayer2['default'].SetBufferAttributes(polyline.projected, polyline.options));\n\t };\n\t\n\t var point;\n\t for (var i = 0; i < points.length; i++) {\n\t point = points[i];\n\t pointBufferPromises.push(_geometryPointLayer2['default'].SetBufferAttributes(point.projected, point.options));\n\t };\n\t\n\t var data = {};\n\t var transferrables = [];\n\t\n\t // TODO: Make this work with polylines too\n\t // TODO: Make this so it's not a nest of promises\n\t GeoJSONWorkerLayer.ProcessPolygons(polygonBufferPromises, polygons, _properties).then(function (result) {\n\t data.polygons = result.data;\n\t transferrables = transferrables.concat(result.transferrables);\n\t\n\t GeoJSONWorkerLayer.ProcessPolylines(polylineBufferPromises, polylines, _properties).then(function (result) {\n\t data.polylines = result.data;\n\t transferrables = transferrables.concat(result.transferrables);\n\t\n\t GeoJSONWorkerLayer.ProcessPoints(pointBufferPromises, points, _properties).then(function (result) {\n\t data.points = result.data;\n\t transferrables = transferrables.concat(result.transferrables);\n\t\n\t resolve({\n\t data: data,\n\t transferrables: transferrables\n\t });\n\t });\n\t });\n\t });\n\t });\n\t });\n\t }\n\t }, {\n\t key: 'ProcessPolygons',\n\t value: function ProcessPolygons(polygonPromises, polygons, _properties) {\n\t return new Promise(function (resolve, reject) {\n\t Promise.all(polygonPromises).then(function (results) {\n\t var transferrables = [];\n\t\n\t var positions = [];\n\t var normals = [];\n\t var colors = [];\n\t var tops = [];\n\t\n\t var outlinePositions = [];\n\t var outlineColors = [];\n\t\n\t var properties = [];\n\t\n\t var flats = [];\n\t var polygon;\n\t\n\t var result;\n\t for (var i = 0; i < results.length; i++) {\n\t result = results[i];\n\t\n\t polygon = polygons[i];\n\t\n\t // WORKERS: Making this a typed array will speed up transfer time\n\t // As things stand this adds on a few milliseconds\n\t flats.push(result.flat);\n\t\n\t // WORKERS: result.attributes is actually an array of polygons for each\n\t // feature, though the current logic isn't keeping these all together\n\t\n\t var attributes;\n\t for (var j = 0; j < result.attributes.length; j++) {\n\t attributes = result.attributes[j];\n\t\n\t positions.push(attributes.positions);\n\t normals.push(attributes.normals);\n\t colors.push(attributes.colors);\n\t tops.push(attributes.tops);\n\t\n\t if (_properties) {\n\t properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties)));\n\t }\n\t };\n\t\n\t var outlineAttributes;\n\t for (var j = 0; j < result.outlineAttributes.length; j++) {\n\t outlineAttributes = result.outlineAttributes[j];\n\t\n\t outlinePositions.push(outlineAttributes.positions);\n\t outlineColors.push(outlineAttributes.colors);\n\t };\n\t };\n\t\n\t var mergedAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(positions),\n\t normals: _utilBuffer2['default'].mergeFloat32Arrays(normals),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(colors),\n\t tops: _utilBuffer2['default'].mergeFloat32Arrays(tops)\n\t };\n\t\n\t var mergedOutlineAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(outlinePositions),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(outlineColors)\n\t };\n\t\n\t transferrables.push(mergedAttributes.positions[0].buffer);\n\t transferrables.push(mergedAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.normals[0].buffer);\n\t transferrables.push(mergedAttributes.normals[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.colors[0].buffer);\n\t transferrables.push(mergedAttributes.colors[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.tops[0].buffer);\n\t transferrables.push(mergedAttributes.tops[1].buffer);\n\t\n\t transferrables.push(mergedOutlineAttributes.positions[0].buffer);\n\t transferrables.push(mergedOutlineAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedOutlineAttributes.colors[0].buffer);\n\t transferrables.push(mergedOutlineAttributes.colors[1].buffer);\n\t\n\t var mergedProperties;\n\t if (_properties) {\n\t mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties);\n\t\n\t transferrables.push(mergedProperties[0].buffer);\n\t transferrables.push(mergedProperties[1].buffer);\n\t }\n\t\n\t var output = {\n\t attributes: mergedAttributes,\n\t outlineAttributes: mergedOutlineAttributes,\n\t flats: flats\n\t };\n\t\n\t if (_properties) {\n\t output.properties = mergedProperties;\n\t }\n\t\n\t // TODO: Also return GeoJSON features that can be mapped to objects on\n\t // the main thread. Allow user to provide filter / toggles to only return\n\t // properties from the GeoJSON that they need (eg. don't return geometry,\n\t // or don't return properties.height)\n\t resolve({\n\t data: output,\n\t transferrables: transferrables\n\t });\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'ProcessPolylines',\n\t value: function ProcessPolylines(polylinePromises, polylines, _properties) {\n\t return new Promise(function (resolve, reject) {\n\t Promise.all(polylinePromises).then(function (results) {\n\t var transferrables = [];\n\t\n\t var positions = [];\n\t var colors = [];\n\t\n\t var properties = [];\n\t\n\t var flats = [];\n\t var polyline;\n\t\n\t var result;\n\t for (var i = 0; i < results.length; i++) {\n\t result = results[i];\n\t\n\t polyline = polylines[i];\n\t\n\t // WORKERS: Making this a typed array will speed up transfer time\n\t // As things stand this adds on a few milliseconds\n\t flats.push(result.flat);\n\t\n\t // WORKERS: result.attributes is actually an array of polygons for each\n\t // feature, though the current logic isn't keeping these all together\n\t\n\t var attributes;\n\t for (var j = 0; j < result.attributes.length; j++) {\n\t attributes = result.attributes[j];\n\t\n\t positions.push(attributes.positions);\n\t colors.push(attributes.colors);\n\t\n\t if (_properties) {\n\t properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polyline.properties)));\n\t }\n\t };\n\t };\n\t\n\t var mergedAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(positions),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(colors)\n\t };\n\t\n\t transferrables.push(mergedAttributes.positions[0].buffer);\n\t transferrables.push(mergedAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.colors[0].buffer);\n\t transferrables.push(mergedAttributes.colors[1].buffer);\n\t\n\t var mergedProperties;\n\t if (_properties) {\n\t mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties);\n\t\n\t transferrables.push(mergedProperties[0].buffer);\n\t transferrables.push(mergedProperties[1].buffer);\n\t }\n\t\n\t var output = {\n\t attributes: mergedAttributes,\n\t flats: flats\n\t };\n\t\n\t if (_properties) {\n\t output.properties = mergedProperties;\n\t }\n\t\n\t // TODO: Also return GeoJSON features that can be mapped to objects on\n\t // the main thread. Allow user to provide filter / toggles to only return\n\t // properties from the GeoJSON that they need (eg. don't return geometry,\n\t // or don't return properties.height)\n\t resolve({\n\t data: output,\n\t transferrables: transferrables\n\t });\n\t })['catch'](reject);\n\t });\n\t }\n\t\n\t // TODO: Dedupe with ProcessPolygons as they are identical\n\t }, {\n\t key: 'ProcessPoints',\n\t value: function ProcessPoints(pointPromises, points, _properties) {\n\t return new Promise(function (resolve, reject) {\n\t Promise.all(pointPromises).then(function (results) {\n\t var transferrables = [];\n\t\n\t var positions = [];\n\t var normals = [];\n\t var colors = [];\n\t\n\t var properties = [];\n\t\n\t var flats = [];\n\t var point;\n\t\n\t var result;\n\t for (var i = 0; i < results.length; i++) {\n\t result = results[i];\n\t\n\t point = points[i];\n\t\n\t // WORKERS: Making this a typed array will speed up transfer time\n\t // As things stand this adds on a few milliseconds\n\t flats.push(result.flat);\n\t\n\t // WORKERS: result.attributes is actually an array of polygons for each\n\t // feature, though the current logic isn't keeping these all together\n\t\n\t var attributes;\n\t for (var j = 0; j < result.attributes.length; j++) {\n\t attributes = result.attributes[j];\n\t\n\t positions.push(attributes.positions);\n\t normals.push(attributes.normals);\n\t colors.push(attributes.colors);\n\t\n\t if (_properties) {\n\t properties.push(_utilBuffer2['default'].stringToUint8Array(JSON.stringify(polygon.properties)));\n\t }\n\t };\n\t };\n\t\n\t var mergedAttributes = {\n\t positions: _utilBuffer2['default'].mergeFloat32Arrays(positions),\n\t normals: _utilBuffer2['default'].mergeFloat32Arrays(normals),\n\t colors: _utilBuffer2['default'].mergeFloat32Arrays(colors)\n\t };\n\t\n\t transferrables.push(mergedAttributes.positions[0].buffer);\n\t transferrables.push(mergedAttributes.positions[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.normals[0].buffer);\n\t transferrables.push(mergedAttributes.normals[1].buffer);\n\t\n\t transferrables.push(mergedAttributes.colors[0].buffer);\n\t transferrables.push(mergedAttributes.colors[1].buffer);\n\t\n\t var mergedProperties;\n\t if (_properties) {\n\t mergedProperties = _utilBuffer2['default'].mergeUint8Arrays(properties);\n\t\n\t transferrables.push(mergedProperties[0].buffer);\n\t transferrables.push(mergedProperties[1].buffer);\n\t }\n\t\n\t var output = {\n\t attributes: mergedAttributes,\n\t flats: flats\n\t };\n\t\n\t if (_properties) {\n\t output.properties = mergedProperties;\n\t }\n\t\n\t // TODO: Also return GeoJSON features that can be mapped to objects on\n\t // the main thread. Allow user to provide filter / toggles to only return\n\t // properties from the GeoJSON that they need (eg. don't return geometry,\n\t // or don't return properties.height)\n\t resolve({\n\t data: output,\n\t transferrables: transferrables\n\t });\n\t })['catch'](reject);\n\t });\n\t }\n\t }, {\n\t key: 'ProcessGeoJSON',\n\t value: function ProcessGeoJSON(geojson, headers) {\n\t if (typeof geojson === 'string') {\n\t return GeoJSONWorkerLayer.RequestGeoJSON(geojson, headers);\n\t } else {\n\t return Promise.resolve(JSON.parse(_utilBuffer2['default'].uint8ArrayToString(geojson)));\n\t }\n\t }\n\t }, {\n\t key: 'RequestGeoJSON',\n\t value: function RequestGeoJSON(path, headers) {\n\t return (0, _reqwest2['default'])({\n\t url: path,\n\t type: 'json',\n\t crossOrigin: true,\n\t headers: headers\n\t });\n\t }\n\t }]);\n\t\n\t return GeoJSONWorkerLayer;\n\t})(_Layer3['default']);\n\t\n\texports['default'] = GeoJSONWorkerLayer;\n\t\n\tvar noNew = function noNew(geojson, options) {\n\t return new GeoJSONWorkerLayer(geojson, options);\n\t};\n\t\n\texports.geoJSONWorkerLayer = noNew;\n\n/***/ },\n/* 88 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\tvar Stringify = (function () {\n\t var functionToString = function functionToString(f) {\n\t return f.toString();\n\t };\n\t\n\t // Based on https://github.com/tangrams/tangram/blob/2a31893c814cf15d5077f87ffa10af20160716b9/src/utils/utils.js#L245\n\t var stringToFunction = function stringToFunction(str) {\n\t if (typeof str === 'string' && str.match(/^\\s*function\\s*\\w*\\s*\\([\\s\\S]*\\)\\s*\\{[\\s\\S]*\\}/m) != null) {\n\t var f;\n\t\n\t try {\n\t eval('f = ' + str);\n\t return f;\n\t } catch (err) {\n\t return str;\n\t }\n\t }\n\t };\n\t\n\t return {\n\t functionToString: functionToString,\n\t stringToFunction: stringToFunction\n\t };\n\t})();\n\t\n\texports['default'] = Stringify;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 89 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _GeoJSONTileLayer2 = __webpack_require__(70);\n\t\n\tvar _GeoJSONTileLayer3 = _interopRequireDefault(_GeoJSONTileLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar TopoJSONTileLayer = (function (_GeoJSONTileLayer) {\n\t _inherits(TopoJSONTileLayer, _GeoJSONTileLayer);\n\t\n\t function TopoJSONTileLayer(path, options) {\n\t _classCallCheck(this, TopoJSONTileLayer);\n\t\n\t var defaults = {\n\t topojson: true\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TopoJSONTileLayer.prototype), 'constructor', this).call(this, path, options);\n\t }\n\t\n\t return TopoJSONTileLayer;\n\t})(_GeoJSONTileLayer3['default']);\n\t\n\texports['default'] = TopoJSONTileLayer;\n\t\n\tvar noNew = function noNew(path, options) {\n\t return new TopoJSONTileLayer(path, options);\n\t};\n\t\n\texports.topoJSONTileLayer = noNew;\n\n/***/ },\n/* 90 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _GeoJSONLayer2 = __webpack_require__(72);\n\t\n\tvar _GeoJSONLayer3 = _interopRequireDefault(_GeoJSONLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar TopoJSONLayer = (function (_GeoJSONLayer) {\n\t _inherits(TopoJSONLayer, _GeoJSONLayer);\n\t\n\t function TopoJSONLayer(topojson, options) {\n\t _classCallCheck(this, TopoJSONLayer);\n\t\n\t var defaults = {\n\t topojson: true\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TopoJSONLayer.prototype), 'constructor', this).call(this, topojson, options);\n\t }\n\t\n\t return TopoJSONLayer;\n\t})(_GeoJSONLayer3['default']);\n\t\n\texports['default'] = TopoJSONLayer;\n\t\n\tvar noNew = function noNew(topojson, options) {\n\t return new TopoJSONLayer(topojson, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.topoJSONLayer = noNew;\n\n/***/ },\n/* 91 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tvar _get = function get(_x, _x2, _x3) { var _again = true; _function: while (_again) { var object = _x, property = _x2, receiver = _x3; _again = false; if (object === null) object = Function.prototype; var desc = Object.getOwnPropertyDescriptor(object, property); if (desc === undefined) { var parent = Object.getPrototypeOf(object); if (parent === null) { return undefined; } else { _x = parent; _x2 = property; _x3 = receiver; _again = true; desc = parent = undefined; continue _function; } } else if ('value' in desc) { return desc.value; } else { var getter = desc.get; if (getter === undefined) { return undefined; } return getter.call(receiver); } } };\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\tfunction _classCallCheck(instance, Constructor) { if (!(instance instanceof Constructor)) { throw new TypeError('Cannot call a class as a function'); } }\n\t\n\tfunction _inherits(subClass, superClass) { if (typeof superClass !== 'function' && superClass !== null) { throw new TypeError('Super expression must either be null or a function, not ' + typeof superClass); } subClass.prototype = Object.create(superClass && superClass.prototype, { constructor: { value: subClass, enumerable: false, writable: true, configurable: true } }); if (superClass) Object.setPrototypeOf ? Object.setPrototypeOf(subClass, superClass) : subClass.__proto__ = superClass; }\n\t\n\tvar _GeoJSONWorkerLayer2 = __webpack_require__(87);\n\t\n\tvar _GeoJSONWorkerLayer3 = _interopRequireDefault(_GeoJSONWorkerLayer2);\n\t\n\tvar _lodashAssign = __webpack_require__(3);\n\t\n\tvar _lodashAssign2 = _interopRequireDefault(_lodashAssign);\n\t\n\tvar TopoJSONWorkerLayer = (function (_GeoJSONWorkerLayer) {\n\t _inherits(TopoJSONWorkerLayer, _GeoJSONWorkerLayer);\n\t\n\t function TopoJSONWorkerLayer(topojson, options) {\n\t _classCallCheck(this, TopoJSONWorkerLayer);\n\t\n\t var defaults = {\n\t topojson: true\n\t };\n\t\n\t options = (0, _lodashAssign2['default'])({}, defaults, options);\n\t\n\t _get(Object.getPrototypeOf(TopoJSONWorkerLayer.prototype), 'constructor', this).call(this, topojson, options);\n\t }\n\t\n\t return TopoJSONWorkerLayer;\n\t})(_GeoJSONWorkerLayer3['default']);\n\t\n\texports['default'] = TopoJSONWorkerLayer;\n\t\n\tvar noNew = function noNew(topojson, options) {\n\t return new TopoJSONWorkerLayer(topojson, options);\n\t};\n\t\n\t// Initialise without requiring new keyword\n\texports.topoJSONWorkerLayer = noNew;\n\n/***/ },\n/* 92 */\n/***/ function(module, exports, __webpack_require__) {\n\n\tObject.defineProperty(exports, '__esModule', {\n\t value: true\n\t});\n\t\n\tfunction _interopRequireDefault(obj) { return obj && obj.__esModule ? obj : { 'default': obj }; }\n\t\n\t// TODO: A lot of these utils don't need to be in separate, tiny files\n\t\n\tvar _wrapNum = __webpack_require__(93);\n\t\n\tvar _wrapNum2 = _interopRequireDefault(_wrapNum);\n\t\n\tvar _extrudePolygon = __webpack_require__(80);\n\t\n\tvar _extrudePolygon2 = _interopRequireDefault(_extrudePolygon);\n\t\n\tvar _GeoJSON = __webpack_require__(75);\n\t\n\tvar _GeoJSON2 = _interopRequireDefault(_GeoJSON);\n\t\n\tvar _Buffer = __webpack_require__(81);\n\t\n\tvar _Buffer2 = _interopRequireDefault(_Buffer);\n\t\n\tvar _Worker = __webpack_require__(46);\n\t\n\tvar _Worker2 = _interopRequireDefault(_Worker);\n\t\n\tvar _Stringify = __webpack_require__(88);\n\t\n\tvar _Stringify2 = _interopRequireDefault(_Stringify);\n\t\n\tvar Util = {};\n\t\n\tUtil.wrapNum = _wrapNum2['default'];\n\tUtil.extrudePolygon = _extrudePolygon2['default'];\n\tUtil.GeoJSON = _GeoJSON2['default'];\n\tUtil.Buffer = _Buffer2['default'];\n\tUtil.Worker = _Worker2['default'];\n\tUtil.Stringify = _Stringify2['default'];\n\t\n\texports['default'] = Util;\n\tmodule.exports = exports['default'];\n\n/***/ },\n/* 93 */\n/***/ function(module, exports) {\n\n\tObject.defineProperty(exports, \"__esModule\", {\n\t value: true\n\t});\n\t/*\n\t * Wrap the given number to lie within a certain range (eg. longitude)\n\t *\n\t * Based on:\n\t * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js\n\t */\n\t\n\tvar wrapNum = function wrapNum(x, range, includeMax) {\n\t var max = range[1];\n\t var min = range[0];\n\t var d = max - min;\n\t return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\n\t};\n\t\n\texports[\"default\"] = wrapNum;\n\tmodule.exports = exports[\"default\"];\n\n/***/ }\n/******/ ])\n});\n;"," \t// The module cache\n \tvar installedModules = {};\n\n \t// The require function\n \tfunction __webpack_require__(moduleId) {\n\n \t\t// Check if module is in cache\n \t\tif(installedModules[moduleId])\n \t\t\treturn installedModules[moduleId].exports;\n\n \t\t// Create a new module (and put it into the cache)\n \t\tvar module = installedModules[moduleId] = {\n \t\t\texports: {},\n \t\t\tid: moduleId,\n \t\t\tloaded: false\n \t\t};\n\n \t\t// Execute the module function\n \t\tmodules[moduleId].call(module.exports, module, module.exports, __webpack_require__);\n\n \t\t// Flag the module as loaded\n \t\tmodule.loaded = true;\n\n \t\t// Return the exports of the module\n \t\treturn module.exports;\n \t}\n\n\n \t// expose the modules object (__webpack_modules__)\n \t__webpack_require__.m = modules;\n\n \t// expose the module cache\n \t__webpack_require__.c = installedModules;\n\n \t// __webpack_public_path__\n \t__webpack_require__.p = \"\";\n\n \t// Load entry module and return exports\n \treturn __webpack_require__(0);\n\n\n\n/** WEBPACK FOOTER **\n ** webpack/bootstrap 64490f947fe5779175f4\n **/","import World, {world} from './World';\nimport Controls from './controls/index';\n\nimport Geo from './geo/Geo.js';\n\nimport Layer, {layer} from './layer/Layer';\nimport LayerGroup, {layerGroup} from './layer/LayerGroup';\nimport EnvironmentLayer, {environmentLayer} from './layer/environment/EnvironmentLayer';\nimport ImageTileLayer, {imageTileLayer} from './layer/tile/ImageTileLayer';\nimport GeoJSONTileLayer, {geoJSONTileLayer} from './layer/tile/GeoJSONTileLayer';\nimport TopoJSONTileLayer, {topoJSONTileLayer} from './layer/tile/TopoJSONTileLayer';\nimport GeoJSONTile, {geoJSONTile} from './layer/tile/GeoJSONTile';\nimport GeoJSONLayer, {geoJSONLayer} from './layer/GeoJSONLayer';\nimport TopoJSONLayer, {topoJSONLayer} from './layer/TopoJSONLayer';\nimport GeoJSONWorkerLayer, {geoJSONWorkerLayer} from './layer/GeoJSONWorkerLayer';\nimport TopoJSONWorkerLayer, {topoJSONWorkerLayer} from './layer/TopoJSONWorkerLayer';\nimport PolygonLayer, {polygonLayer} from './layer/geometry/PolygonLayer';\nimport PolylineLayer, {polylineLayer} from './layer/geometry/PolylineLayer';\nimport PointLayer, {pointLayer} from './layer/geometry/PointLayer';\n\nimport Point, {point} from './geo/Point';\nimport LatLon, {latLon} from './geo/LatLon';\n\nimport PickingMaterial from './engine/PickingMaterial';\n\nimport Util from './util/index';\n\nconst VIZI = {\n version: '0.3',\n\n // Public API\n World: World,\n world: world,\n Controls: Controls,\n Geo: Geo,\n Layer: Layer,\n layer: layer,\n EnvironmentLayer: EnvironmentLayer,\n environmentLayer: environmentLayer,\n ImageTileLayer: ImageTileLayer,\n imageTileLayer: imageTileLayer,\n GeoJSONTileLayer: GeoJSONTileLayer,\n geoJSONTileLayer: geoJSONTileLayer,\n GeoJSONTile: GeoJSONTile,\n geoJSONTile: geoJSONTile,\n TopoJSONTileLayer: TopoJSONTileLayer,\n topoJSONTileLayer: topoJSONTileLayer,\n GeoJSONLayer: GeoJSONLayer,\n geoJSONLayer: geoJSONLayer,\n TopoJSONLayer: TopoJSONLayer,\n topoJSONLayer: topoJSONLayer,\n GeoJSONWorkerLayer: GeoJSONWorkerLayer,\n geoJSONWorkerLayer: geoJSONWorkerLayer,\n TopoJSONWorkerLayer: TopoJSONWorkerLayer,\n topoJSONWorkerLayer: topoJSONWorkerLayer,\n PolygonLayer: PolygonLayer,\n polygonLayer: polygonLayer,\n PolylineLayer: PolylineLayer,\n polylineLayer: polylineLayer,\n PointLayer: PointLayer,\n pointLayer: pointLayer,\n Point: Point,\n point: point,\n LatLon: LatLon,\n latLon: latLon,\n PickingMaterial: PickingMaterial,\n Util: Util\n};\n\nexport default VIZI;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vizicities.js\n **/","import EventEmitter from 'eventemitter3';\nimport extend from 'lodash.assign';\nimport Geo from './geo/Geo';\nimport {point as Point} from './geo/Point';\nimport {latLon as LatLon} from './geo/LatLon';\nimport Engine from './engine/Engine';\nimport EnvironmentLayer from './layer/environment/EnvironmentLayer';\nimport Worker from './util/Worker';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// Pretty much any event someone using ViziCities would need will be emitted or\n// proxied by World (eg. render events, etc)\n\nclass World extends EventEmitter {\n constructor(domId, options) {\n super();\n\n var defaults = {\n skybox: false,\n postProcessing: false\n };\n\n this.options = extend({}, defaults, options);\n\n this._layers = [];\n this._controls = [];\n\n this._initContainer(domId);\n this._initAttribution();\n this._initEngine();\n\n this._initEnvironment().then(() => {\n this._initEvents();\n\n this._pause = false;\n\n // Kick off the update and render loop\n this._update();\n });\n }\n\n createWorkers(maxWorkers, workerScript) {\n return Worker.createWorkers(maxWorkers, workerScript);\n }\n\n _initContainer(domId) {\n this._container = document.getElementById(domId);\n }\n\n _initAttribution() {\n var message = 'ViziCities | Attribution';\n\n var element = document.createElement('div');\n element.classList.add('vizicities-attribution');\n\n var additionalElem = document.createElement('div');\n additionalElem.id = 'attribution-container';\n\n element.innerHTML = message;\n element.appendChild(additionalElem);\n\n this._container.appendChild(element);\n\n document.getElementById('show-attr').addEventListener('click', function(e) {\n e.currentTarget.parentNode.classList.toggle('is-visible');\n });\n }\n\n _initEngine() {\n this._engine = new Engine(this._container, this);\n\n // Engine events\n //\n // Consider proxying these through events on World for public access\n // this._engine.on('preRender', () => {});\n // this._engine.on('postRender', () => {});\n }\n\n _initEnvironment() {\n // Not sure if I want to keep this as a private API\n //\n // Makes sense to allow others to customise their environment so perhaps\n // add some method of disable / overriding the environment settings\n this._environment = new EnvironmentLayer({\n skybox: this.options.skybox\n });\n\n return this._environment.addTo(this);\n }\n\n _initEvents() {\n this.on('controlsMoveEnd', this._onControlsMoveEnd);\n }\n\n _onControlsMoveEnd(point) {\n var _point = Point(point.x, point.z);\n this._resetView(this.pointToLatLon(_point), _point);\n }\n\n // Reset world view\n _resetView(latlon, point) {\n this.emit('preResetView');\n\n this._moveStart();\n this._move(latlon, point);\n this._moveEnd();\n\n this.emit('postResetView');\n }\n\n _moveStart() {\n this.emit('moveStart');\n }\n\n _move(latlon, point) {\n this._lastPosition = latlon;\n this.emit('move', latlon, point);\n }\n _moveEnd() {\n this.emit('moveEnd');\n }\n\n _update() {\n if (this._pause) {\n return;\n }\n\n var delta = this._engine.clock.getDelta();\n\n // Once _update is called it will run forever, for now\n window.requestAnimationFrame(this._update.bind(this));\n\n // Update controls\n this._controls.forEach(controls => {\n controls.update(delta);\n });\n\n this.emit('preUpdate', delta);\n this._engine.update(delta);\n this.emit('postUpdate', delta);\n }\n\n _addAttribution(id, message) {\n var container = document.getElementById('attribution-container');\n\n var span = document.createElement('p');\n span.dataset.layer = id;\n span.innerHTML = message;\n\n container.appendChild(span);\n }\n\n _removeAttribution(id) {\n var elem = document.querySelectorAll('#attribution-container [data-layer=\"' + id + '\"]')[0];\n elem.remove();\n }\n\n // Set world view\n setView(latlon) {\n // Store initial geographic coordinate for the [0,0,0] world position\n //\n // The origin point doesn't move in three.js / 3D space so only set it once\n // here instead of every time _resetView is called\n //\n // If it was updated every time then coorindates would shift over time and\n // would be out of place / context with previously-placed points (0,0 would\n // refer to a different point each time)\n this._originLatlon = latlon;\n this._originPoint = this.project(latlon);\n\n this._resetView(latlon);\n return this;\n }\n\n // Return world geographic position\n getPosition() {\n return this._lastPosition;\n }\n\n // Transform geographic coordinate to world point\n //\n // This doesn't take into account the origin offset\n //\n // For example, this takes a geographic coordinate and returns a point\n // relative to the origin point of the projection (not the world)\n project(latlon) {\n return Geo.latLonToPoint(LatLon(latlon));\n }\n\n // Transform world point to geographic coordinate\n //\n // This doesn't take into account the origin offset\n //\n // For example, this takes a point relative to the origin point of the\n // projection (not the world) and returns a geographic coordinate\n unproject(point) {\n return Geo.pointToLatLon(Point(point));\n }\n\n // Takes into account the origin offset\n //\n // For example, this takes a geographic coordinate and returns a point\n // relative to the three.js / 3D origin (0,0)\n latLonToPoint(latlon) {\n var projectedPoint = this.project(LatLon(latlon));\n return projectedPoint._subtract(this._originPoint);\n }\n\n // Takes into account the origin offset\n //\n // For example, this takes a point relative to the three.js / 3D origin (0,0)\n // and returns the exact geographic coordinate at that point\n pointToLatLon(point) {\n var projectedPoint = Point(point).add(this._originPoint);\n return this.unproject(projectedPoint);\n }\n\n // Return pointscale for a given geographic coordinate\n pointScale(latlon, accurate) {\n return Geo.pointScale(latlon, accurate);\n }\n\n // Convert from real meters to world units\n //\n // TODO: Would be nice not to have to pass in a pointscale here\n metresToWorld(metres, pointScale, zoom) {\n return Geo.metresToWorld(metres, pointScale, zoom);\n }\n\n // Convert from real meters to world units\n //\n // TODO: Would be nice not to have to pass in a pointscale here\n worldToMetres(worldUnits, pointScale, zoom) {\n return Geo.worldToMetres(worldUnits, pointScale, zoom);\n }\n\n // Unsure if it's a good idea to expose this here for components like\n // GridLayer to use (eg. to keep track of a frustum)\n getCamera() {\n return this._engine._camera;\n }\n\n addLayer(layer) {\n // Is is right to assume that there will always be some other layer\n // managing layers with output set to false?\n this._layers.push(layer);\n\n if (layer.isOutput() && layer.isOutputToScene()) {\n // Could move this into Layer but it'll do here for now\n this._engine._scene.add(layer._object3D);\n this._engine._domScene3D.add(layer._domObject3D);\n this._engine._domScene2D.add(layer._domObject2D);\n }\n\n return new Promise((resolve, reject) => {\n layer._addToWorld(this).then(() => {\n if (layer._options.attribution) {\n this._addAttribution(layer._options.id, layer._options.attribution);\n }\n\n // TODO: Consider moving this so it doesn't fire for layers that are\n // actually managed by a parent layer (eg. tiles)\n this.emit('layerAdded', layer);\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Remove layer from world and scene but don't destroy it entirely\n removeLayer(layer) {\n var layerIndex = this._layers.indexOf(layer);\n\n if (layerIndex > -1) {\n // Remove from this._layers\n this._layers.splice(layerIndex, 1);\n };\n\n if (layer.isOutput() && layer.isOutputToScene()) {\n this._engine._scene.remove(layer._object3D);\n this._engine._domScene3D.remove(layer._domObject3D);\n this._engine._domScene2D.remove(layer._domObject2D);\n }\n\n this.emit('layerRemoved');\n\n return Promise.resolve(this);\n }\n\n addControls(controls) {\n controls._addToWorld(this);\n\n this._controls.push(controls);\n\n this.emit('controlsAdded', controls);\n\n return Promise.resolve(this);\n }\n\n // Remove controls from world but don't destroy them entirely\n removeControls(controls) {\n var controlsIndex = this._controls.indexOf(controlsIndex);\n\n if (controlsIndex > -1) {\n this._controls.splice(controlsIndex, 1);\n };\n\n this.emit('controlsRemoved', controls);\n\n return Promise.resolve(this);\n }\n\n stop() {\n this._pause = true;\n }\n\n start() {\n this._pause = false;\n this._update();\n }\n\n // Destroys the world(!) and removes it from the scene and memory\n //\n // TODO: World out why so much three.js stuff is left in the heap after this\n destroy() {\n this.stop();\n\n // Remove listeners\n this.off('controlsMoveEnd', this._onControlsMoveEnd);\n\n var i;\n\n // Remove all controls\n var controls;\n for (i = this._controls.length - 1; i >= 0; i--) {\n controls = this._controls[0];\n this.removeControls(controls);\n controls.destroy();\n };\n\n // Remove all layers\n var layer;\n for (i = this._layers.length - 1; i >= 0; i--) {\n layer = this._layers[0];\n this.removeLayer(layer);\n layer.destroy();\n };\n\n // Environment layer is removed with the other layers\n this._environment = null;\n\n this._engine.destroy();\n this._engine = null;\n\n // Clean the container / remove the canvas\n while (this._container.firstChild) {\n this._container.removeChild(this._container.firstChild);\n }\n\n this._container = null;\n }\n}\n\nexport default World;\n\nvar noNew = function(domId, options) {\n return new World(domId, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as world};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/World.js\n **/","'use strict';\n\nvar has = Object.prototype.hasOwnProperty;\n\n//\n// We store our EE objects in a plain object whose properties are event names.\n// If `Object.create(null)` is not supported we prefix the event names with a\n// `~` to make sure that the built-in object properties are not overridden or\n// used as an attack vector.\n// We also assume that `Object.create(null)` is available when the event name\n// is an ES6 Symbol.\n//\nvar prefix = typeof Object.create !== 'function' ? '~' : false;\n\n/**\n * Representation of a single EventEmitter function.\n *\n * @param {Function} fn Event handler to be called.\n * @param {Mixed} context Context for function execution.\n * @param {Boolean} [once=false] Only emit once\n * @api private\n */\nfunction EE(fn, context, once) {\n this.fn = fn;\n this.context = context;\n this.once = once || false;\n}\n\n/**\n * Minimal EventEmitter interface that is molded against the Node.js\n * EventEmitter interface.\n *\n * @constructor\n * @api public\n */\nfunction EventEmitter() { /* Nothing to set */ }\n\n/**\n * Hold the assigned EventEmitters by name.\n *\n * @type {Object}\n * @private\n */\nEventEmitter.prototype._events = undefined;\n\n/**\n * Return an array listing the events for which the emitter has registered\n * listeners.\n *\n * @returns {Array}\n * @api public\n */\nEventEmitter.prototype.eventNames = function eventNames() {\n var events = this._events\n , names = []\n , name;\n\n if (!events) return names;\n\n for (name in events) {\n if (has.call(events, name)) names.push(prefix ? name.slice(1) : name);\n }\n\n if (Object.getOwnPropertySymbols) {\n return names.concat(Object.getOwnPropertySymbols(events));\n }\n\n return names;\n};\n\n/**\n * Return a list of assigned event listeners.\n *\n * @param {String} event The events that should be listed.\n * @param {Boolean} exists We only need to know if there are listeners.\n * @returns {Array|Boolean}\n * @api public\n */\nEventEmitter.prototype.listeners = function listeners(event, exists) {\n var evt = prefix ? prefix + event : event\n , available = this._events && this._events[evt];\n\n if (exists) return !!available;\n if (!available) return [];\n if (available.fn) return [available.fn];\n\n for (var i = 0, l = available.length, ee = new Array(l); i < l; i++) {\n ee[i] = available[i].fn;\n }\n\n return ee;\n};\n\n/**\n * Emit an event to all registered event listeners.\n *\n * @param {String} event The name of the event.\n * @returns {Boolean} Indication if we've emitted an event.\n * @api public\n */\nEventEmitter.prototype.emit = function emit(event, a1, a2, a3, a4, a5) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events || !this._events[evt]) return false;\n\n var listeners = this._events[evt]\n , len = arguments.length\n , args\n , i;\n\n if ('function' === typeof listeners.fn) {\n if (listeners.once) this.removeListener(event, listeners.fn, undefined, true);\n\n switch (len) {\n case 1: return listeners.fn.call(listeners.context), true;\n case 2: return listeners.fn.call(listeners.context, a1), true;\n case 3: return listeners.fn.call(listeners.context, a1, a2), true;\n case 4: return listeners.fn.call(listeners.context, a1, a2, a3), true;\n case 5: return listeners.fn.call(listeners.context, a1, a2, a3, a4), true;\n case 6: return listeners.fn.call(listeners.context, a1, a2, a3, a4, a5), true;\n }\n\n for (i = 1, args = new Array(len -1); i < len; i++) {\n args[i - 1] = arguments[i];\n }\n\n listeners.fn.apply(listeners.context, args);\n } else {\n var length = listeners.length\n , j;\n\n for (i = 0; i < length; i++) {\n if (listeners[i].once) this.removeListener(event, listeners[i].fn, undefined, true);\n\n switch (len) {\n case 1: listeners[i].fn.call(listeners[i].context); break;\n case 2: listeners[i].fn.call(listeners[i].context, a1); break;\n case 3: listeners[i].fn.call(listeners[i].context, a1, a2); break;\n default:\n if (!args) for (j = 1, args = new Array(len -1); j < len; j++) {\n args[j - 1] = arguments[j];\n }\n\n listeners[i].fn.apply(listeners[i].context, args);\n }\n }\n }\n\n return true;\n};\n\n/**\n * Register a new EventListener for the given event.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} [context=this] The context of the function.\n * @api public\n */\nEventEmitter.prototype.on = function on(event, fn, context) {\n var listener = new EE(fn, context || this)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events) this._events = prefix ? {} : Object.create(null);\n if (!this._events[evt]) this._events[evt] = listener;\n else {\n if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [\n this._events[evt], listener\n ];\n }\n\n return this;\n};\n\n/**\n * Add an EventListener that's only called once.\n *\n * @param {String} event Name of the event.\n * @param {Function} fn Callback function.\n * @param {Mixed} [context=this] The context of the function.\n * @api public\n */\nEventEmitter.prototype.once = function once(event, fn, context) {\n var listener = new EE(fn, context || this, true)\n , evt = prefix ? prefix + event : event;\n\n if (!this._events) this._events = prefix ? {} : Object.create(null);\n if (!this._events[evt]) this._events[evt] = listener;\n else {\n if (!this._events[evt].fn) this._events[evt].push(listener);\n else this._events[evt] = [\n this._events[evt], listener\n ];\n }\n\n return this;\n};\n\n/**\n * Remove event listeners.\n *\n * @param {String} event The event we want to remove.\n * @param {Function} fn The listener that we need to find.\n * @param {Mixed} context Only remove listeners matching this context.\n * @param {Boolean} once Only remove once listeners.\n * @api public\n */\nEventEmitter.prototype.removeListener = function removeListener(event, fn, context, once) {\n var evt = prefix ? prefix + event : event;\n\n if (!this._events || !this._events[evt]) return this;\n\n var listeners = this._events[evt]\n , events = [];\n\n if (fn) {\n if (listeners.fn) {\n if (\n listeners.fn !== fn\n || (once && !listeners.once)\n || (context && listeners.context !== context)\n ) {\n events.push(listeners);\n }\n } else {\n for (var i = 0, length = listeners.length; i < length; i++) {\n if (\n listeners[i].fn !== fn\n || (once && !listeners[i].once)\n || (context && listeners[i].context !== context)\n ) {\n events.push(listeners[i]);\n }\n }\n }\n }\n\n //\n // Reset the array, or remove it completely if we have no more listeners.\n //\n if (events.length) {\n this._events[evt] = events.length === 1 ? events[0] : events;\n } else {\n delete this._events[evt];\n }\n\n return this;\n};\n\n/**\n * Remove all listeners or only the listeners for the specified event.\n *\n * @param {String} event The event want to remove all listeners for.\n * @api public\n */\nEventEmitter.prototype.removeAllListeners = function removeAllListeners(event) {\n if (!this._events) return this;\n\n if (event) delete this._events[prefix ? prefix + event : event];\n else this._events = prefix ? {} : Object.create(null);\n\n return this;\n};\n\n//\n// Alias methods names because people roll like that.\n//\nEventEmitter.prototype.off = EventEmitter.prototype.removeListener;\nEventEmitter.prototype.addListener = EventEmitter.prototype.on;\n\n//\n// This function doesn't apply anymore.\n//\nEventEmitter.prototype.setMaxListeners = function setMaxListeners() {\n return this;\n};\n\n//\n// Expose the prefix.\n//\nEventEmitter.prefixed = prefix;\n\n//\n// Expose the module.\n//\nif ('undefined' !== typeof module) {\n module.exports = EventEmitter;\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/eventemitter3/index.js\n ** module id = 2\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\nvar keys = require('lodash.keys'),\n rest = require('lodash.rest');\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/** Detect if properties shadowing those on `Object.prototype` are non-enumerable. */\nvar nonEnumShadows = !propertyIsEnumerable.call({ 'valueOf': 1 }, 'valueOf');\n\n/**\n * Assigns `value` to `key` of `object` if the existing value is not equivalent\n * using [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * for equality comparisons.\n *\n * @private\n * @param {Object} object The object to modify.\n * @param {string} key The key of the property to assign.\n * @param {*} value The value to assign.\n */\nfunction assignValue(object, key, value) {\n var objValue = object[key];\n if (!(hasOwnProperty.call(object, key) && eq(objValue, value)) ||\n (value === undefined && !(key in object))) {\n object[key] = value;\n }\n}\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Copies properties of `source` to `object`.\n *\n * @private\n * @param {Object} source The object to copy properties from.\n * @param {Array} props The property identifiers to copy.\n * @param {Object} [object={}] The object to copy properties to.\n * @param {Function} [customizer] The function to customize copied values.\n * @returns {Object} Returns `object`.\n */\nfunction copyObject(source, props, object, customizer) {\n object || (object = {});\n\n var index = -1,\n length = props.length;\n\n while (++index < length) {\n var key = props[index];\n\n var newValue = customizer\n ? customizer(object[key], source[key], key, object, source)\n : source[key];\n\n assignValue(object, key, newValue);\n }\n return object;\n}\n\n/**\n * Creates a function like `_.assign`.\n *\n * @private\n * @param {Function} assigner The function to assign values.\n * @returns {Function} Returns the new assigner function.\n */\nfunction createAssigner(assigner) {\n return rest(function(object, sources) {\n var index = -1,\n length = sources.length,\n customizer = length > 1 ? sources[length - 1] : undefined,\n guard = length > 2 ? sources[2] : undefined;\n\n customizer = (assigner.length > 3 && typeof customizer == 'function')\n ? (length--, customizer)\n : undefined;\n\n if (guard && isIterateeCall(sources[0], sources[1], guard)) {\n customizer = length < 3 ? undefined : customizer;\n length = 1;\n }\n object = Object(object);\n while (++index < length) {\n var source = sources[index];\n if (source) {\n assigner(object, source, index, customizer);\n }\n }\n return object;\n });\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if the given arguments are from an iteratee call.\n *\n * @private\n * @param {*} value The potential iteratee value argument.\n * @param {*} index The potential iteratee index or key argument.\n * @param {*} object The potential iteratee object argument.\n * @returns {boolean} Returns `true` if the arguments are from an iteratee call,\n * else `false`.\n */\nfunction isIterateeCall(value, index, object) {\n if (!isObject(object)) {\n return false;\n }\n var type = typeof index;\n if (type == 'number'\n ? (isArrayLike(object) && isIndex(index, object.length))\n : (type == 'string' && index in object)\n ) {\n return eq(object[index], value);\n }\n return false;\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Performs a\n * [`SameValueZero`](http://ecma-international.org/ecma-262/6.0/#sec-samevaluezero)\n * comparison between two values to determine if they are equivalent.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to compare.\n * @param {*} other The other value to compare.\n * @returns {boolean} Returns `true` if the values are equivalent, else `false`.\n * @example\n *\n * var object = { 'user': 'fred' };\n * var other = { 'user': 'fred' };\n *\n * _.eq(object, object);\n * // => true\n *\n * _.eq(object, other);\n * // => false\n *\n * _.eq('a', 'a');\n * // => true\n *\n * _.eq('a', Object('a'));\n * // => false\n *\n * _.eq(NaN, NaN);\n * // => true\n */\nfunction eq(value, other) {\n return value === other || (value !== value && other !== other);\n}\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Assigns own enumerable string keyed properties of source objects to the\n * destination object. Source objects are applied from left to right.\n * Subsequent sources overwrite property assignments of previous sources.\n *\n * **Note:** This method mutates `object` and is loosely based on\n * [`Object.assign`](https://mdn.io/Object/assign).\n *\n * @static\n * @memberOf _\n * @since 0.10.0\n * @category Object\n * @param {Object} object The destination object.\n * @param {...Object} [sources] The source objects.\n * @returns {Object} Returns `object`.\n * @see _.assignIn\n * @example\n *\n * function Foo() {\n * this.c = 3;\n * }\n *\n * function Bar() {\n * this.e = 5;\n * }\n *\n * Foo.prototype.d = 4;\n * Bar.prototype.f = 6;\n *\n * _.assign({ 'a': 1 }, new Foo, new Bar);\n * // => { 'a': 1, 'c': 3, 'e': 5 }\n */\nvar assign = createAssigner(function(object, source) {\n if (nonEnumShadows || isPrototype(source) || isArrayLike(source)) {\n copyObject(source, keys(source), object);\n return;\n }\n for (var key in source) {\n if (hasOwnProperty.call(source, key)) {\n assignValue(object, key, source[key]);\n }\n }\n});\n\nmodule.exports = assign;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.assign/index.js\n ** module id = 3\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as references for various `Number` constants. */\nvar MAX_SAFE_INTEGER = 9007199254740991;\n\n/** `Object#toString` result references. */\nvar argsTag = '[object Arguments]',\n funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n stringTag = '[object String]';\n\n/** Used to detect unsigned integer values. */\nvar reIsUint = /^(?:0|[1-9]\\d*)$/;\n\n/**\n * The base implementation of `_.times` without support for iteratee shorthands\n * or max array length checks.\n *\n * @private\n * @param {number} n The number of times to invoke `iteratee`.\n * @param {Function} iteratee The function invoked per iteration.\n * @returns {Array} Returns the array of results.\n */\nfunction baseTimes(n, iteratee) {\n var index = -1,\n result = Array(n);\n\n while (++index < n) {\n result[index] = iteratee(index);\n }\n return result;\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/** Used to check objects for own properties. */\nvar hasOwnProperty = objectProto.hasOwnProperty;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/** Built-in value references. */\nvar propertyIsEnumerable = objectProto.propertyIsEnumerable;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeGetPrototype = Object.getPrototypeOf,\n nativeKeys = Object.keys;\n\n/**\n * The base implementation of `_.has` without support for deep paths.\n *\n * @private\n * @param {Object} object The object to query.\n * @param {Array|string} key The key to check.\n * @returns {boolean} Returns `true` if `key` exists, else `false`.\n */\nfunction baseHas(object, key) {\n // Avoid a bug in IE 10-11 where objects with a [[Prototype]] of `null`,\n // that are composed entirely of index properties, return `false` for\n // `hasOwnProperty` checks of them.\n return hasOwnProperty.call(object, key) ||\n (typeof object == 'object' && key in object && getPrototype(object) === null);\n}\n\n/**\n * The base implementation of `_.keys` which doesn't skip the constructor\n * property of prototypes or treat sparse arrays as dense.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n */\nfunction baseKeys(object) {\n return nativeKeys(Object(object));\n}\n\n/**\n * The base implementation of `_.property` without support for deep paths.\n *\n * @private\n * @param {string} key The key of the property to get.\n * @returns {Function} Returns the new accessor function.\n */\nfunction baseProperty(key) {\n return function(object) {\n return object == null ? undefined : object[key];\n };\n}\n\n/**\n * Gets the \"length\" property value of `object`.\n *\n * **Note:** This function is used to avoid a\n * [JIT bug](https://bugs.webkit.org/show_bug.cgi?id=142792) that affects\n * Safari on at least iOS 8.1-8.3 ARM64.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {*} Returns the \"length\" value.\n */\nvar getLength = baseProperty('length');\n\n/**\n * Gets the `[[Prototype]]` of `value`.\n *\n * @private\n * @param {*} value The value to query.\n * @returns {null|Object} Returns the `[[Prototype]]`.\n */\nfunction getPrototype(value) {\n return nativeGetPrototype(Object(value));\n}\n\n/**\n * Creates an array of index keys for `object` values of arrays,\n * `arguments` objects, and strings, otherwise `null` is returned.\n *\n * @private\n * @param {Object} object The object to query.\n * @returns {Array|null} Returns index keys, else `null`.\n */\nfunction indexKeys(object) {\n var length = object ? object.length : undefined;\n if (isLength(length) &&\n (isArray(object) || isString(object) || isArguments(object))) {\n return baseTimes(length, String);\n }\n return null;\n}\n\n/**\n * Checks if `value` is a valid array-like index.\n *\n * @private\n * @param {*} value The value to check.\n * @param {number} [length=MAX_SAFE_INTEGER] The upper bounds of a valid index.\n * @returns {boolean} Returns `true` if `value` is a valid index, else `false`.\n */\nfunction isIndex(value, length) {\n length = length == null ? MAX_SAFE_INTEGER : length;\n return !!length &&\n (typeof value == 'number' || reIsUint.test(value)) &&\n (value > -1 && value % 1 == 0 && value < length);\n}\n\n/**\n * Checks if `value` is likely a prototype object.\n *\n * @private\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a prototype, else `false`.\n */\nfunction isPrototype(value) {\n var Ctor = value && value.constructor,\n proto = (typeof Ctor == 'function' && Ctor.prototype) || objectProto;\n\n return value === proto;\n}\n\n/**\n * Checks if `value` is likely an `arguments` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArguments(function() { return arguments; }());\n * // => true\n *\n * _.isArguments([1, 2, 3]);\n * // => false\n */\nfunction isArguments(value) {\n // Safari 8.1 incorrectly makes `arguments.callee` enumerable in strict mode.\n return isArrayLikeObject(value) && hasOwnProperty.call(value, 'callee') &&\n (!propertyIsEnumerable.call(value, 'callee') || objectToString.call(value) == argsTag);\n}\n\n/**\n * Checks if `value` is classified as an `Array` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @type {Function}\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isArray([1, 2, 3]);\n * // => true\n *\n * _.isArray(document.body.children);\n * // => false\n *\n * _.isArray('abc');\n * // => false\n *\n * _.isArray(_.noop);\n * // => false\n */\nvar isArray = Array.isArray;\n\n/**\n * Checks if `value` is array-like. A value is considered array-like if it's\n * not a function and has a `value.length` that's an integer greater than or\n * equal to `0` and less than or equal to `Number.MAX_SAFE_INTEGER`.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is array-like, else `false`.\n * @example\n *\n * _.isArrayLike([1, 2, 3]);\n * // => true\n *\n * _.isArrayLike(document.body.children);\n * // => true\n *\n * _.isArrayLike('abc');\n * // => true\n *\n * _.isArrayLike(_.noop);\n * // => false\n */\nfunction isArrayLike(value) {\n return value != null && isLength(getLength(value)) && !isFunction(value);\n}\n\n/**\n * This method is like `_.isArrayLike` except that it also checks if `value`\n * is an object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an array-like object,\n * else `false`.\n * @example\n *\n * _.isArrayLikeObject([1, 2, 3]);\n * // => true\n *\n * _.isArrayLikeObject(document.body.children);\n * // => true\n *\n * _.isArrayLikeObject('abc');\n * // => false\n *\n * _.isArrayLikeObject(_.noop);\n * // => false\n */\nfunction isArrayLikeObject(value) {\n return isObjectLike(value) && isArrayLike(value);\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is a valid array-like length.\n *\n * **Note:** This function is loosely based on\n * [`ToLength`](http://ecma-international.org/ecma-262/6.0/#sec-tolength).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is a valid length,\n * else `false`.\n * @example\n *\n * _.isLength(3);\n * // => true\n *\n * _.isLength(Number.MIN_VALUE);\n * // => false\n *\n * _.isLength(Infinity);\n * // => false\n *\n * _.isLength('3');\n * // => false\n */\nfunction isLength(value) {\n return typeof value == 'number' &&\n value > -1 && value % 1 == 0 && value <= MAX_SAFE_INTEGER;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `String` primitive or object.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isString('abc');\n * // => true\n *\n * _.isString(1);\n * // => false\n */\nfunction isString(value) {\n return typeof value == 'string' ||\n (!isArray(value) && isObjectLike(value) && objectToString.call(value) == stringTag);\n}\n\n/**\n * Creates an array of the own enumerable property names of `object`.\n *\n * **Note:** Non-object values are coerced to objects. See the\n * [ES spec](http://ecma-international.org/ecma-262/6.0/#sec-object.keys)\n * for more details.\n *\n * @static\n * @since 0.1.0\n * @memberOf _\n * @category Object\n * @param {Object} object The object to query.\n * @returns {Array} Returns the array of property names.\n * @example\n *\n * function Foo() {\n * this.a = 1;\n * this.b = 2;\n * }\n *\n * Foo.prototype.c = 3;\n *\n * _.keys(new Foo);\n * // => ['a', 'b'] (iteration order is not guaranteed)\n *\n * _.keys('hi');\n * // => ['0', '1']\n */\nfunction keys(object) {\n var isProto = isPrototype(object);\n if (!(isProto || isArrayLike(object))) {\n return baseKeys(object);\n }\n var indexes = indexKeys(object),\n skipIndexes = !!indexes,\n result = indexes || [],\n length = result.length;\n\n for (var key in object) {\n if (baseHas(object, key) &&\n !(skipIndexes && (key == 'length' || isIndex(key, length))) &&\n !(isProto && key == 'constructor')) {\n result.push(key);\n }\n }\n return result;\n}\n\nmodule.exports = keys;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.keys/index.js\n ** module id = 4\n ** module chunks = 0\n **/","/**\n * lodash (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar INFINITY = 1 / 0,\n MAX_INTEGER = 1.7976931348623157e+308,\n NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/**\n * A faster alternative to `Function#apply`, this function invokes `func`\n * with the `this` binding of `thisArg` and the arguments of `args`.\n *\n * @private\n * @param {Function} func The function to invoke.\n * @param {*} thisArg The `this` binding of `func`.\n * @param {Array} args The arguments to invoke `func` with.\n * @returns {*} Returns the result of `func`.\n */\nfunction apply(func, thisArg, args) {\n var length = args.length;\n switch (length) {\n case 0: return func.call(thisArg);\n case 1: return func.call(thisArg, args[0]);\n case 2: return func.call(thisArg, args[0], args[1]);\n case 3: return func.call(thisArg, args[0], args[1], args[2]);\n }\n return func.apply(thisArg, args);\n}\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max;\n\n/**\n * Creates a function that invokes `func` with the `this` binding of the\n * created function and arguments from `start` and beyond provided as\n * an array.\n *\n * **Note:** This method is based on the\n * [rest parameter](https://mdn.io/rest_parameters).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Function\n * @param {Function} func The function to apply a rest parameter to.\n * @param {number} [start=func.length-1] The start position of the rest parameter.\n * @returns {Function} Returns the new function.\n * @example\n *\n * var say = _.rest(function(what, names) {\n * return what + ' ' + _.initial(names).join(', ') +\n * (_.size(names) > 1 ? ', & ' : '') + _.last(names);\n * });\n *\n * say('hello', 'fred', 'barney', 'pebbles');\n * // => 'hello fred, barney, & pebbles'\n */\nfunction rest(func, start) {\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n start = nativeMax(start === undefined ? (func.length - 1) : toInteger(start), 0);\n return function() {\n var args = arguments,\n index = -1,\n length = nativeMax(args.length - start, 0),\n array = Array(length);\n\n while (++index < length) {\n array[index] = args[start + index];\n }\n switch (start) {\n case 0: return func.call(this, array);\n case 1: return func.call(this, args[0], array);\n case 2: return func.call(this, args[0], args[1], array);\n }\n var otherArgs = Array(start + 1);\n index = -1;\n while (++index < start) {\n otherArgs[index] = args[index];\n }\n otherArgs[start] = array;\n return apply(func, this, otherArgs);\n };\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a finite number.\n *\n * @static\n * @memberOf _\n * @since 4.12.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted number.\n * @example\n *\n * _.toFinite(3.2);\n * // => 3.2\n *\n * _.toFinite(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toFinite(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toFinite('3.2');\n * // => 3.2\n */\nfunction toFinite(value) {\n if (!value) {\n return value === 0 ? value : 0;\n }\n value = toNumber(value);\n if (value === INFINITY || value === -INFINITY) {\n var sign = (value < 0 ? -1 : 1);\n return sign * MAX_INTEGER;\n }\n return value === value ? value : 0;\n}\n\n/**\n * Converts `value` to an integer.\n *\n * **Note:** This function is loosely based on\n * [`ToInteger`](http://www.ecma-international.org/ecma-262/6.0/#sec-tointeger).\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to convert.\n * @returns {number} Returns the converted integer.\n * @example\n *\n * _.toInteger(3.2);\n * // => 3\n *\n * _.toInteger(Number.MIN_VALUE);\n * // => 0\n *\n * _.toInteger(Infinity);\n * // => 1.7976931348623157e+308\n *\n * _.toInteger('3.2');\n * // => 3\n */\nfunction toInteger(value) {\n var result = toFinite(value),\n remainder = result % 1;\n\n return result === result ? (remainder ? result - remainder : result) : 0;\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3.2);\n * // => 3.2\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3.2');\n * // => 3.2\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = isFunction(value.valueOf) ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = rest;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.rest/index.js\n ** module id = 5\n ** module chunks = 0\n **/","import {latLon as LatLon} from './LatLon';\nimport {point as Point} from './Point';\n\nvar Geo = {};\n\n// Radius / WGS84 semi-major axis\nGeo.R = 6378137;\nGeo.MAX_LATITUDE = 85.0511287798;\n\n// WGS84 eccentricity\nGeo.ECC = 0.081819191;\nGeo.ECC2 = 0.081819191 * 0.081819191;\n\nGeo.project = function(latlon) {\n var d = Math.PI / 180;\n var max = Geo.MAX_LATITUDE;\n var lat = Math.max(Math.min(max, latlon.lat), -max);\n var sin = Math.sin(lat * d);\n\n return Point(\n Geo.R * latlon.lon * d,\n Geo.R * Math.log((1 + sin) / (1 - sin)) / 2\n );\n},\n\nGeo.unproject = function(point) {\n var d = 180 / Math.PI;\n\n return LatLon(\n (2 * Math.atan(Math.exp(point.y / Geo.R)) - (Math.PI / 2)) * d,\n point.x * d / Geo.R\n );\n};\n\n// Converts geo coords to pixel / WebGL ones\n// This just reverses the Y axis to match WebGL\nGeo.latLonToPoint = function(latlon) {\n var projected = Geo.project(latlon);\n projected.y *= -1;\n\n return projected;\n};\n\n// Converts pixel / WebGL coords to geo coords\n// This just reverses the Y axis to match WebGL\nGeo.pointToLatLon = function(point) {\n var _point = Point(point.x, point.y * -1);\n return Geo.unproject(_point);\n};\n\n// Scale factor for converting between real metres and projected metres\n//\n// projectedMetres = realMetres * pointScale\n// realMetres = projectedMetres / pointScale\n//\n// Accurate scale factor uses proper Web Mercator scaling\n// See pg.9: http://www.hydrometronics.com/downloads/Web%20Mercator%20-%20Non-Conformal,%20Non-Mercator%20(notes).pdf\n// See: http://jsfiddle.net/robhawkes/yws924cf/\nGeo.pointScale = function(latlon, accurate) {\n var rad = Math.PI / 180;\n\n var k;\n\n if (!accurate) {\n k = 1 / Math.cos(latlon.lat * rad);\n\n // [scaleX, scaleY]\n return [k, k];\n } else {\n var lat = latlon.lat * rad;\n var lon = latlon.lon * rad;\n\n var a = Geo.R;\n\n var sinLat = Math.sin(lat);\n var sinLat2 = sinLat * sinLat;\n\n var cosLat = Math.cos(lat);\n\n // Radius meridian\n var p = a * (1 - Geo.ECC2) / Math.pow(1 - Geo.ECC2 * sinLat2, 3 / 2);\n\n // Radius prime meridian\n var v = a / Math.sqrt(1 - Geo.ECC2 * sinLat2);\n\n // Scale N/S\n var h = (a / p) / cosLat;\n\n // Scale E/W\n k = (a / v) / cosLat;\n\n // [scaleX, scaleY]\n return [k, h];\n }\n};\n\n// Convert real metres to projected units\n//\n// Latitude scale is chosen because it fluctuates more than longitude\nGeo.metresToProjected = function(metres, pointScale) {\n return metres * pointScale[1];\n};\n\n// Convert projected units to real metres\n//\n// Latitude scale is chosen because it fluctuates more than longitude\nGeo.projectedToMetres = function(projectedUnits, pointScale) {\n return projectedUnits / pointScale[1];\n};\n\n// Convert real metres to a value in world (WebGL) units\nGeo.metresToWorld = function(metres, pointScale) {\n // Transform metres to projected metres using the latitude point scale\n //\n // Latitude scale is chosen because it fluctuates more than longitude\n var projectedMetres = Geo.metresToProjected(metres, pointScale);\n\n var scale = Geo.scale();\n\n // Scale projected metres\n var scaledMetres = (scale * projectedMetres);\n\n return scaledMetres;\n};\n\n// Convert world (WebGL) units to a value in real metres\nGeo.worldToMetres = function(worldUnits, pointScale) {\n var scale = Geo.scale();\n\n var projectedUnits = worldUnits / scale;\n var realMetres = Geo.projectedToMetres(projectedUnits, pointScale);\n\n return realMetres;\n};\n\n// If zoom is provided, returns the map width in pixels for a given zoom\n// Else, provides fixed scale value\nGeo.scale = function(zoom) {\n // If zoom is provided then return scale based on map tile zoom\n if (zoom >= 0) {\n return 256 * Math.pow(2, zoom);\n // Else, return fixed scale value to expand projected coordinates from\n // their 0 to 1 range into something more practical\n } else {\n return 1;\n }\n};\n\n// Returns zoom level for a given scale value\n// This only works with a scale value that is based on map pixel width\nGeo.zoom = function(scale) {\n return Math.log(scale / 256) / Math.LN2;\n};\n\n// Distance between two geographical points using spherical law of cosines\n// approximation or Haversine\n//\n// See: http://www.movable-type.co.uk/scripts/latlong.html\nGeo.distance = function(latlon1, latlon2, accurate) {\n var rad = Math.PI / 180;\n\n var lat1;\n var lat2;\n\n var a;\n\n if (!accurate) {\n lat1 = latlon1.lat * rad;\n lat2 = latlon2.lat * rad;\n\n a = Math.sin(lat1) * Math.sin(lat2) + Math.cos(lat1) * Math.cos(lat2) * Math.cos((latlon2.lon - latlon1.lon) * rad);\n\n return Geo.R * Math.acos(Math.min(a, 1));\n } else {\n lat1 = latlon1.lat * rad;\n lat2 = latlon2.lat * rad;\n\n var lon1 = latlon1.lon * rad;\n var lon2 = latlon2.lon * rad;\n\n var deltaLat = lat2 - lat1;\n var deltaLon = lon2 - lon1;\n\n var halfDeltaLat = deltaLat / 2;\n var halfDeltaLon = deltaLon / 2;\n\n a = Math.sin(halfDeltaLat) * Math.sin(halfDeltaLat) + Math.cos(lat1) * Math.cos(lat2) * Math.sin(halfDeltaLon) * Math.sin(halfDeltaLon);\n\n var c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a));\n\n return Geo.R * c;\n }\n};\n\nGeo.bounds = (function() {\n var d = Geo.R * Math.PI;\n return [[-d, -d], [d, d]];\n})();\n\nexport default Geo;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/Geo.js\n **/","/*\n * LatLon is a helper class for ensuring consistent geographic coordinates.\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/geo/LatLng.js\n */\n\nclass LatLon {\n constructor(lat, lon, alt) {\n if (isNaN(lat) || isNaN(lon)) {\n throw new Error('Invalid LatLon object: (' + lat + ', ' + lon + ')');\n }\n\n this.lat = +lat;\n this.lon = +lon;\n\n if (alt !== undefined) {\n this.alt = +alt;\n }\n }\n\n clone() {\n return new LatLon(this.lat, this.lon, this.alt);\n }\n}\n\nexport default LatLon;\n\n// Accepts (LatLon), ([lat, lon, alt]), ([lat, lon]) and (lat, lon, alt)\n// Also converts between lng and lon\nvar noNew = function(a, b, c) {\n if (a instanceof LatLon) {\n return a;\n }\n if (Array.isArray(a) && typeof a[0] !== 'object') {\n if (a.length === 3) {\n return new LatLon(a[0], a[1], a[2]);\n }\n if (a.length === 2) {\n return new LatLon(a[0], a[1]);\n }\n return null;\n }\n if (a === undefined || a === null) {\n return a;\n }\n if (typeof a === 'object' && 'lat' in a) {\n return new LatLon(a.lat, 'lng' in a ? a.lng : a.lon, a.alt);\n }\n if (b === undefined) {\n return null;\n }\n return new LatLon(a, b, c);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as latLon};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/LatLon.js\n **/","/*\n * Point is a helper class for ensuring consistent world positions.\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/geo/Point.js\n */\n\nclass Point {\n constructor(x, y, round) {\n this.x = (round ? Math.round(x) : x);\n this.y = (round ? Math.round(y) : y);\n }\n\n clone() {\n return new Point(this.x, this.y);\n }\n\n // Non-destructive\n add(point) {\n return this.clone()._add(_point(point));\n }\n\n // Destructive\n _add(point) {\n this.x += point.x;\n this.y += point.y;\n return this;\n }\n\n // Non-destructive\n subtract(point) {\n return this.clone()._subtract(_point(point));\n }\n\n // Destructive\n _subtract(point) {\n this.x -= point.x;\n this.y -= point.y;\n return this;\n }\n}\n\nexport default Point;\n\n// Accepts (point), ([x, y]) and (x, y, round)\nvar _point = function(x, y, round) {\n if (x instanceof Point) {\n return x;\n }\n if (Array.isArray(x)) {\n return new Point(x[0], x[1]);\n }\n if (x === undefined || x === null) {\n return x;\n }\n return new Point(x, y, round);\n};\n\n// Initialise without requiring new keyword\nexport {_point as point};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/geo/Point.js\n **/","import EventEmitter from 'eventemitter3';\nimport THREE from 'three';\nimport Scene from './Scene';\nimport DOMScene3D from './DOMScene3D';\nimport DOMScene2D from './DOMScene2D';\nimport Renderer from './Renderer';\nimport DOMRenderer3D from './DOMRenderer3D';\nimport DOMRenderer2D from './DOMRenderer2D';\nimport Camera from './Camera';\nimport Picking from './Picking';\nimport EffectComposer from './EffectComposer';\nimport RenderPass from '../vendor/RenderPass';\nimport ShaderPass from '../vendor/ShaderPass';\nimport CopyShader from '../vendor/CopyShader';\nimport HorizontalTiltShiftShader from '../vendor/HorizontalTiltShiftShader';\nimport VerticalTiltShiftShader from '../vendor/VerticalTiltShiftShader';\nimport FXAAShader from '../vendor/FXAAShader';\n\nclass Engine extends EventEmitter {\n constructor(container, world) {\n console.log('Init Engine');\n\n super();\n\n this._world = world;\n\n this._scene = Scene;\n this._domScene3D = DOMScene3D;\n this._domScene2D = DOMScene2D;\n\n var antialias = (this._world.options.postProcessing) ? false : true;\n this._renderer = Renderer(container, antialias);\n this._domRenderer3D = DOMRenderer3D(container);\n this._domRenderer2D = DOMRenderer2D(container);\n\n this._camera = Camera(container);\n\n this._container = container;\n\n // TODO: Make this optional\n this._picking = Picking(this._world, this._renderer, this._camera);\n\n this.clock = new THREE.Clock();\n\n this._frustum = new THREE.Frustum();\n\n if (this._world.options.postProcessing) {\n this._initPostProcessing();\n }\n }\n\n // TODO: Set up composer to automatically resize on viewport change\n // TODO: Update passes that rely on width / height on resize\n // TODO: Merge default passes into a single shader / pass for performance\n _initPostProcessing() {\n var renderPass = new RenderPass(this._scene, this._camera);\n\n // TODO: Look at using @mattdesl's optimised FXAA shader\n // https://github.com/mattdesl/three-shader-fxaa\n var fxaaPass = new ShaderPass(FXAAShader);\n\n var hblurPass = new ShaderPass(HorizontalTiltShiftShader);\n var vblurPass = new ShaderPass(VerticalTiltShiftShader);\n var bluriness = 5;\n\n hblurPass.uniforms.r.value = vblurPass.uniforms.r.value = 0.6;\n\n var copyPass = new ShaderPass(CopyShader);\n copyPass.renderToScreen = true;\n\n this._composer = EffectComposer(this._renderer, this._container);\n\n this._composer.addPass(renderPass);\n this._composer.addPass(fxaaPass);\n this._composer.addPass(hblurPass);\n this._composer.addPass(vblurPass);\n this._composer.addPass(copyPass);\n\n var self = this;\n var updatePostProcessingSize = function() {\n var width = self._container.clientWidth;\n var height = self._container.clientHeight;\n\n // TODO: Re-enable this when perf issues can be solved\n //\n // Rendering double the resolution of the screen can be really slow\n // var pixelRatio = window.devicePixelRatio;\n var pixelRatio = 1;\n\n fxaaPass.uniforms.resolution.value.set(1 / (width * pixelRatio), 1 / (height * pixelRatio));\n\n hblurPass.uniforms.h.value = bluriness / (width * pixelRatio);\n vblurPass.uniforms.v.value = bluriness / (height * pixelRatio);\n };\n\n updatePostProcessingSize();\n window.addEventListener('resize', updatePostProcessingSize, false);\n }\n\n update(delta) {\n this.emit('preRender');\n\n if (this._world.options.postProcessing) {\n this._composer.render(delta);\n } else {\n this._renderer.render(this._scene, this._camera);\n }\n\n // Render picking scene\n // this._renderer.render(this._picking._pickingScene, this._camera);\n\n // Render DOM scenes\n this._domRenderer3D.render(this._domScene3D, this._camera);\n this._domRenderer2D.render(this._domScene2D, this._camera);\n\n this.emit('postRender');\n }\n\n destroy() {\n // Remove any remaining objects from scene\n var child;\n for (var i = this._scene.children.length - 1; i >= 0; i--) {\n child = this._scene.children[i];\n\n if (!child) {\n continue;\n }\n\n this._scene.remove(child);\n\n if (child.geometry) {\n // Dispose of mesh and materials\n child.geometry.dispose();\n child.geometry = null;\n }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n };\n\n for (var i = this._domScene3D.children.length - 1; i >= 0; i--) {\n child = this._domScene3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this._domScene3D.remove(child);\n };\n\n for (var i = this._domScene2D.children.length - 1; i >= 0; i--) {\n child = this._domScene2D.children[i];\n\n if (!child) {\n continue;\n }\n\n this._domScene2D.remove(child);\n };\n\n this._picking.destroy();\n this._picking = null;\n\n this._world = null;\n this._scene = null;\n this._domScene3D = null;\n this._domScene2D = null;\n\n this._composer = null;\n this._renderer = null;\n\n this._domRenderer3D = null;\n this._domRenderer2D = null;\n this._camera = null;\n this._clock = null;\n this._frustum = null;\n }\n}\n\nexport default Engine;\n\n// // Initialise without requiring new keyword\n// export default function(container, world) {\n// return new Engine(container, world);\n// };\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Engine.js\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_10__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"THREE\"\n ** module id = 10\n ** module chunks = 0\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n\n // TODO: Re-enable when this works with the skybox\n // scene.fog = new THREE.Fog(0xffffff, 1, 15000);\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Scene.js\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMScene3D.js\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.scene\n\nexport default (function() {\n var scene = new THREE.Scene();\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMScene2D.js\n **/","import THREE from 'three';\nimport Scene from './Scene';\n\n// This can only be accessed from Engine.renderer if you want to reference the\n// same scene in multiple places\n\nexport default function(container, antialias) {\n var renderer = new THREE.WebGLRenderer({\n antialias: antialias\n\n // Enabling this removes a lot of z-index intersecting but it also removes\n // shadows due to a bug in three.js\n //\n // See: https://github.com/mrdoob/three.js/issues/7815\n // logarithmicDepthBuffer: true\n });\n\n // TODO: Re-enable when this works with the skybox\n // renderer.setClearColor(Scene.fog.color, 1);\n\n renderer.setClearColor(0xffffff, 1);\n\n // TODO: Re-enable this when perf issues can be solved\n //\n // Rendering double the resolution of the screen can be really slow\n // var pixelRatio = window.devicePixelRatio;\n var pixelRatio = 1;\n\n renderer.setPixelRatio(pixelRatio);\n\n // Gamma settings make things look nicer\n renderer.gammaInput = true;\n renderer.gammaOutput = true;\n\n renderer.shadowMap.enabled = true;\n\n // TODO: Work out which of the shadowmap types is best\n // https://github.com/mrdoob/three.js/blob/r56/src/Three.js#L107\n // renderer.shadowMap.type = THREE.PCFSoftShadowMap;\n\n // TODO: Check that leaving this as default (CullFrontFace) is right\n // renderer.shadowMap.cullFace = THREE.CullFaceBack;\n\n container.appendChild(renderer.domElement);\n\n var updateSize = function() {\n renderer.setSize(container.clientWidth, container.clientHeight);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return renderer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Renderer.js\n **/","import THREE from 'three';\nimport {CSS3DRenderer} from '../vendor/CSS3DRenderer';\nimport DOMScene3D from './DOMScene3D';\n\n// This can only be accessed from Engine.renderer if you want to reference the\n// same scene in multiple places\n\nexport default function(container) {\n var renderer = new CSS3DRenderer();\n\n renderer.domElement.style.position = 'absolute';\n renderer.domElement.style.top = 0;\n\n container.appendChild(renderer.domElement);\n\n var updateSize = function() {\n renderer.setSize(container.clientWidth, container.clientHeight);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return renderer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMRenderer3D.js\n **/","// jscs:disable\n/* eslint-disable */\n\n/**\n * Based on http://www.emagix.net/academic/mscs-project/item/camera-sync-with-css3-and-webgl-threejs\n * @author mrdoob / http://mrdoob.com/\n */\n\nimport THREE from 'three';\n\nvar CSS3DObject = function ( element ) {\n\n\tTHREE.Object3D.call( this );\n\n\tthis.element = element;\n\tthis.element.style.position = 'absolute';\n\n\tthis.addEventListener( 'removed', function ( event ) {\n\n\t\tif ( this.element.parentNode !== null ) {\n\n\t\t\tthis.element.parentNode.removeChild( this.element );\n\n\t\t}\n\n\t} );\n\n};\n\nCSS3DObject.prototype = Object.create( THREE.Object3D.prototype );\nCSS3DObject.prototype.constructor = CSS3DObject;\n\nvar CSS3DSprite = function ( element ) {\n\n\tCSS3DObject.call( this, element );\n\n};\n\nCSS3DSprite.prototype = Object.create( CSS3DObject.prototype );\nCSS3DSprite.prototype.constructor = CSS3DSprite;\n\n//\n\nvar CSS3DRenderer = function () {\n\n\tconsole.log( 'THREE.CSS3DRenderer', THREE.REVISION );\n\n\tvar _width, _height;\n\tvar _widthHalf, _heightHalf;\n\n\tvar matrix = new THREE.Matrix4();\n\n\tvar cache = {\n\t\tcamera: { fov: 0, style: '' },\n\t\tobjects: {}\n\t};\n\n\tvar domElement = document.createElement( 'div' );\n\tdomElement.style.overflow = 'hidden';\n\n\tdomElement.style.WebkitTransformStyle = 'preserve-3d';\n\tdomElement.style.MozTransformStyle = 'preserve-3d';\n\tdomElement.style.oTransformStyle = 'preserve-3d';\n\tdomElement.style.transformStyle = 'preserve-3d';\n\n\tthis.domElement = domElement;\n\n\tvar cameraElement = document.createElement( 'div' );\n\n\tcameraElement.style.WebkitTransformStyle = 'preserve-3d';\n\tcameraElement.style.MozTransformStyle = 'preserve-3d';\n\tcameraElement.style.oTransformStyle = 'preserve-3d';\n\tcameraElement.style.transformStyle = 'preserve-3d';\n\n\tdomElement.appendChild( cameraElement );\n\n\tthis.setClearColor = function () {};\n\n\tthis.getSize = function() {\n\n\t\treturn {\n\t\t\twidth: _width,\n\t\t\theight: _height\n\t\t};\n\n\t};\n\n\tthis.setSize = function ( width, height ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_widthHalf = _width / 2;\n\t\t_heightHalf = _height / 2;\n\n\t\tdomElement.style.width = width + 'px';\n\t\tdomElement.style.height = height + 'px';\n\n\t\tcameraElement.style.width = width + 'px';\n\t\tcameraElement.style.height = height + 'px';\n\n\t};\n\n\tvar epsilon = function ( value ) {\n\n\t\treturn Math.abs( value ) < Number.EPSILON ? 0 : value;\n\n\t};\n\n\tvar getCameraCSSMatrix = function ( matrix ) {\n\n\t\tvar elements = matrix.elements;\n\n\t\treturn 'matrix3d(' +\n\t\t\tepsilon( elements[ 0 ] ) + ',' +\n\t\t\tepsilon( - elements[ 1 ] ) + ',' +\n\t\t\tepsilon( elements[ 2 ] ) + ',' +\n\t\t\tepsilon( elements[ 3 ] ) + ',' +\n\t\t\tepsilon( elements[ 4 ] ) + ',' +\n\t\t\tepsilon( - elements[ 5 ] ) + ',' +\n\t\t\tepsilon( elements[ 6 ] ) + ',' +\n\t\t\tepsilon( elements[ 7 ] ) + ',' +\n\t\t\tepsilon( elements[ 8 ] ) + ',' +\n\t\t\tepsilon( - elements[ 9 ] ) + ',' +\n\t\t\tepsilon( elements[ 10 ] ) + ',' +\n\t\t\tepsilon( elements[ 11 ] ) + ',' +\n\t\t\tepsilon( elements[ 12 ] ) + ',' +\n\t\t\tepsilon( - elements[ 13 ] ) + ',' +\n\t\t\tepsilon( elements[ 14 ] ) + ',' +\n\t\t\tepsilon( elements[ 15 ] ) +\n\t\t')';\n\n\t};\n\n\tvar getObjectCSSMatrix = function ( matrix ) {\n\n\t\tvar elements = matrix.elements;\n\n\t\treturn 'translate3d(-50%,-50%,0) matrix3d(' +\n\t\t\tepsilon( elements[ 0 ] ) + ',' +\n\t\t\tepsilon( elements[ 1 ] ) + ',' +\n\t\t\tepsilon( elements[ 2 ] ) + ',' +\n\t\t\tepsilon( elements[ 3 ] ) + ',' +\n\t\t\tepsilon( - elements[ 4 ] ) + ',' +\n\t\t\tepsilon( - elements[ 5 ] ) + ',' +\n\t\t\tepsilon( - elements[ 6 ] ) + ',' +\n\t\t\tepsilon( - elements[ 7 ] ) + ',' +\n\t\t\tepsilon( elements[ 8 ] ) + ',' +\n\t\t\tepsilon( elements[ 9 ] ) + ',' +\n\t\t\tepsilon( elements[ 10 ] ) + ',' +\n\t\t\tepsilon( elements[ 11 ] ) + ',' +\n\t\t\tepsilon( elements[ 12 ] ) + ',' +\n\t\t\tepsilon( elements[ 13 ] ) + ',' +\n\t\t\tepsilon( elements[ 14 ] ) + ',' +\n\t\t\tepsilon( elements[ 15 ] ) +\n\t\t')';\n\n\t};\n\n\tvar renderObject = function ( object, camera ) {\n\n\t\tif ( object instanceof CSS3DObject ) {\n\n\t\t\tvar style;\n\n\t\t\tif ( object instanceof CSS3DSprite ) {\n\n\t\t\t\t// http://swiftcoder.wordpress.com/2008/11/25/constructing-a-billboard-matrix/\n\n\t\t\t\tmatrix.copy( camera.matrixWorldInverse );\n\t\t\t\tmatrix.transpose();\n\t\t\t\tmatrix.copyPosition( object.matrixWorld );\n\t\t\t\tmatrix.scale( object.scale );\n\n\t\t\t\tmatrix.elements[ 3 ] = 0;\n\t\t\t\tmatrix.elements[ 7 ] = 0;\n\t\t\t\tmatrix.elements[ 11 ] = 0;\n\t\t\t\tmatrix.elements[ 15 ] = 1;\n\n\t\t\t\tstyle = getObjectCSSMatrix( matrix );\n\n\t\t\t} else {\n\n\t\t\t\tstyle = getObjectCSSMatrix( object.matrixWorld );\n\n\t\t\t}\n\n\t\t\tvar element = object.element;\n\t\t\tvar cachedStyle = cache.objects[ object.id ];\n\n\t\t\tif ( cachedStyle === undefined || cachedStyle !== style ) {\n\n\t\t\t\telement.style.WebkitTransform = style;\n\t\t\t\telement.style.MozTransform = style;\n\t\t\t\telement.style.oTransform = style;\n\t\t\t\telement.style.transform = style;\n\n\t\t\t\tcache.objects[ object.id ] = style;\n\n\t\t\t}\n\n\t\t\tif ( element.parentNode !== cameraElement ) {\n\n\t\t\t\tcameraElement.appendChild( element );\n\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( var i = 0, l = object.children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( object.children[ i ], camera );\n\n\t\t}\n\n\t};\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tvar fov = 0.5 / Math.tan( THREE.Math.degToRad( camera.fov * 0.5 ) ) * _height;\n\n\t\tif ( cache.camera.fov !== fov ) {\n\n\t\t\tdomElement.style.WebkitPerspective = fov + 'px';\n\t\t\tdomElement.style.MozPerspective = fov + 'px';\n\t\t\tdomElement.style.oPerspective = fov + 'px';\n\t\t\tdomElement.style.perspective = fov + 'px';\n\n\t\t\tcache.camera.fov = fov;\n\n\t\t}\n\n\t\tscene.updateMatrixWorld();\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\tvar style = 'translate3d(0,0,' + fov + 'px)' + getCameraCSSMatrix( camera.matrixWorldInverse ) +\n\t\t\t' translate3d(' + _widthHalf + 'px,' + _heightHalf + 'px, 0)';\n\n\t\tif ( cache.camera.style !== style ) {\n\n\t\t\tcameraElement.style.WebkitTransform = style;\n\t\t\tcameraElement.style.MozTransform = style;\n\t\t\tcameraElement.style.oTransform = style;\n\t\t\tcameraElement.style.transform = style;\n\n\t\t\tcache.camera.style = style;\n\n\t\t}\n\n\t\trenderObject( scene, camera );\n\n\t};\n\n};\n\nexport {CSS3DObject as CSS3DObject};\nexport {CSS3DSprite as CSS3DSprite};\nexport {CSS3DRenderer as CSS3DRenderer};\n\nTHREE.CSS3DObject = CSS3DObject;\nTHREE.CSS3DSprite = CSS3DSprite;\nTHREE.CSS3DRenderer = CSS3DRenderer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CSS3DRenderer.js\n **/","import THREE from 'three';\nimport {CSS2DRenderer} from '../vendor/CSS2DRenderer';\nimport DOMScene2D from './DOMScene2D';\n\n// This can only be accessed from Engine.renderer if you want to reference the\n// same scene in multiple places\n\nexport default function(container) {\n var renderer = new CSS2DRenderer();\n\n renderer.domElement.style.position = 'absolute';\n renderer.domElement.style.top = 0;\n\n container.appendChild(renderer.domElement);\n\n var updateSize = function() {\n renderer.setSize(container.clientWidth, container.clientHeight);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return renderer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/DOMRenderer2D.js\n **/","// jscs:disable\n/* eslint-disable */\n\n/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nimport THREE from 'three';\n\nvar CSS2DObject = function ( element ) {\n\n\tTHREE.Object3D.call( this );\n\n\tthis.element = element;\n\tthis.element.style.position = 'absolute';\n\n\tthis.addEventListener( 'removed', function ( event ) {\n\n\t\tif ( this.element.parentNode !== null ) {\n\n\t\t\tthis.element.parentNode.removeChild( this.element );\n\n\t\t}\n\n\t} );\n\n};\n\nCSS2DObject.prototype = Object.create( THREE.Object3D.prototype );\nCSS2DObject.prototype.constructor = CSS2DObject;\n\n//\n\nvar CSS2DRenderer = function () {\n\n\tconsole.log( 'THREE.CSS2DRenderer', THREE.REVISION );\n\n\tvar _width, _height;\n\tvar _widthHalf, _heightHalf;\n\n\tvar vector = new THREE.Vector3();\n\tvar viewMatrix = new THREE.Matrix4();\n\tvar viewProjectionMatrix = new THREE.Matrix4();\n\n\tvar frustum = new THREE.Frustum();\n\n\tvar domElement = document.createElement( 'div' );\n\tdomElement.style.overflow = 'hidden';\n\n\tthis.domElement = domElement;\n\n\tthis.setSize = function ( width, height ) {\n\n\t\t_width = width;\n\t\t_height = height;\n\n\t\t_widthHalf = _width / 2;\n\t\t_heightHalf = _height / 2;\n\n\t\tdomElement.style.width = width + 'px';\n\t\tdomElement.style.height = height + 'px';\n\n\t};\n\n\tvar renderObject = function ( object, camera ) {\n\n\t\tif ( object instanceof CSS2DObject ) {\n\n\t\t\tvector.setFromMatrixPosition( object.matrixWorld );\n\t\t\tvector.applyProjection( viewProjectionMatrix );\n\n\t\t\tvar element = object.element;\n\t\t\tvar style = 'translate(-50%,-50%) translate(' + ( vector.x * _widthHalf + _widthHalf ) + 'px,' + ( - vector.y * _heightHalf + _heightHalf ) + 'px)';\n\n\t\t\telement.style.WebkitTransform = style;\n\t\t\telement.style.MozTransform = style;\n\t\t\telement.style.oTransform = style;\n\t\t\telement.style.transform = style;\n\n\t\t\tif ( element.parentNode !== domElement ) {\n\n\t\t\t\tdomElement.appendChild( element );\n\n\t\t\t}\n\n\t\t\t// Hide if outside view frustum\n\t\t\tif (!frustum.containsPoint(object.position)) {\n\t\t\t\telement.style.display = 'none';\n\t\t\t} else {\n\t\t\t\telement.style.display = 'block';\n\t\t\t}\n\n\t\t}\n\n\t\tfor ( var i = 0, l = object.children.length; i < l; i ++ ) {\n\n\t\t\trenderObject( object.children[ i ], camera );\n\n\t\t}\n\n\t};\n\n\tthis.render = function ( scene, camera ) {\n\n\t\tscene.updateMatrixWorld();\n\n\t\tif ( camera.parent === null ) camera.updateMatrixWorld();\n\n\t\tcamera.matrixWorldInverse.getInverse( camera.matrixWorld );\n\n\t\tviewMatrix.copy( camera.matrixWorldInverse.getInverse( camera.matrixWorld ) );\n\t\tviewProjectionMatrix.multiplyMatrices( camera.projectionMatrix, viewMatrix );\n\n\t\tfrustum.setFromMatrix( new THREE.Matrix4().multiplyMatrices( camera.projectionMatrix, camera.matrixWorldInverse ) );\n\n\t\trenderObject( scene, camera );\n\n\t};\n\n};\n\nexport {CSS2DObject as CSS2DObject};\nexport {CSS2DRenderer as CSS2DRenderer};\n\nTHREE.CSS2DObject = CSS2DObject;\nTHREE.CSS2DRenderer = CSS2DRenderer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CSS2DRenderer.js\n **/","import THREE from 'three';\n\n// This can only be accessed from Engine.camera if you want to reference the\n// same scene in multiple places\n\n// TODO: Ensure that FOV looks natural on all aspect ratios\n// http://stackoverflow.com/q/26655930/997339\n\nexport default function(container) {\n var camera = new THREE.PerspectiveCamera(45, 1, 1, 2000000);\n camera.position.y = 4000;\n camera.position.z = 4000;\n\n var updateSize = function() {\n camera.aspect = container.clientWidth / container.clientHeight;\n camera.updateProjectionMatrix();\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return camera;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Camera.js\n **/","import THREE from 'three';\nimport {point as Point} from '../geo/Point';\nimport PickingScene from './PickingScene';\nimport throttle from 'lodash.throttle';\n\n// TODO: Look into a way of setting this up without passing in a renderer and\n// camera from the engine\n\n// TODO: Add a basic indicator on or around the mouse pointer when it is over\n// something pickable / clickable\n//\n// A simple transparent disc or ring at the mouse point should work to start, or\n// even just changing the cursor to the CSS 'pointer' style\n//\n// Probably want this on mousemove with a throttled update as not to spam the\n// picking method\n//\n// Relies upon the picking method not redrawing the scene every call due to\n// the way TileLayer invalidates the picking scene\n\nvar nextId = 1;\n\nclass Picking {\n constructor(world, renderer, camera) {\n this._world = world;\n this._renderer = renderer;\n this._camera = camera;\n\n this._raycaster = new THREE.Raycaster();\n\n // TODO: Match this with the line width used in the picking layers\n this._raycaster.linePrecision = 3;\n\n this._pickingScene = PickingScene;\n this._pickingTexture = new THREE.WebGLRenderTarget();\n this._pickingTexture.texture.minFilter = THREE.LinearFilter;\n this._pickingTexture.texture.generateMipmaps = false;\n\n this._nextId = 1;\n\n this._resizeTexture();\n this._initEvents();\n }\n\n _initEvents() {\n this._resizeHandler = this._resizeTexture.bind(this);\n window.addEventListener('resize', this._resizeHandler, false);\n\n this._throttledMouseMoveHandler = throttle(this._onMouseMove.bind(this), 50);\n this._mouseUpHandler = this._onMouseUp.bind(this);\n this._world._container.addEventListener('mouseup', this._mouseUpHandler, false);\n this._world._container.addEventListener('mousemove', this._throttledMouseMoveHandler, false);\n\n this._world.on('move', this._onWorldMove, this);\n }\n\n _onMouseUp(event) {\n // Only react to main button click\n if (event.button !== 0) {\n return;\n }\n\n var point = Point(event.clientX - this._world._container.offsetLeft, event.clientY - this._world._container.offsetTop);\n\n var normalisedPoint = Point(0, 0);\n normalisedPoint.x = (point.x / this._width) * 2 - 1;\n normalisedPoint.y = -(point.y / this._height) * 2 + 1;\n\n this._pick(point, normalisedPoint);\n }\n\n _onMouseMove(event) {\n var point = Point(event.clientX - this._world._container.offsetLeft, event.clientY - this._world._container.offsetTop);\n\n var normalisedPoint = Point(0, 0);\n normalisedPoint.x = (point.x / this._width) * 2 - 1;\n normalisedPoint.y = -(point.y / this._height) * 2 + 1;\n\n this._pick(point, normalisedPoint, true);\n }\n\n _onWorldMove() {\n this._needUpdate = true;\n }\n\n // TODO: Ensure this doesn't get out of sync issue with the renderer resize\n _resizeTexture() {\n var size = this._renderer.getSize();\n\n this._width = size.width;\n this._height = size.height;\n\n this._pickingTexture.setSize(this._width, this._height);\n this._pixelBuffer = new Uint8Array(4 * this._width * this._height);\n\n this._needUpdate = true;\n }\n\n // TODO: Make this only re-draw the scene if both an update is needed and the\n // camera has moved since the last update\n //\n // Otherwise it re-draws the scene on every click due to the way LOD updates\n // work in TileLayer – spamming this.add() and this.remove()\n //\n // TODO: Pause updates during map move / orbit / zoom as this is unlikely to\n // be a point in time where the user cares for picking functionality\n _update() {\n if (this._needUpdate) {\n var texture = this._pickingTexture;\n\n this._renderer.render(this._pickingScene, this._camera, this._pickingTexture);\n\n // Read the rendering texture\n this._renderer.readRenderTargetPixels(texture, 0, 0, texture.width, texture.height, this._pixelBuffer);\n\n this._needUpdate = false;\n }\n }\n\n _pick(point, normalisedPoint, hover) {\n this._update();\n\n var index = point.x + (this._pickingTexture.height - point.y) * this._pickingTexture.width;\n\n // Interpret the pixel as an ID\n var id = (this._pixelBuffer[index * 4 + 2] * 255 * 255) + (this._pixelBuffer[index * 4 + 1] * 255) + (this._pixelBuffer[index * 4 + 0]);\n\n // Skip if ID is 16646655 (white) as the background returns this\n if (id === 16646655) {\n if (hover) {\n this._world.emit('pick-hover-reset');\n } else {\n this._world.emit('pick-click-reset');\n }\n\n return;\n }\n\n this._raycaster.setFromCamera(normalisedPoint, this._camera);\n\n // Perform ray intersection on picking scene\n //\n // TODO: Only perform intersection test on the relevant picking mesh\n var intersects = this._raycaster.intersectObjects(this._pickingScene.children, true);\n\n var _point2d = point.clone();\n\n var _point3d;\n if (intersects.length > 0) {\n _point3d = intersects[0].point.clone();\n }\n\n // Pass along as much data as possible for now until we know more about how\n // people use the picking API and what the returned data should be\n //\n // TODO: Look into the leak potential for passing so much by reference here\n // this._world.emit('pick', id, _point2d, _point3d, intersects);\n // this._world.emit('pick-' + id, _point2d, _point3d, intersects);\n\n if (hover) {\n this._world.emit('pick-hover', id, _point2d, _point3d, intersects);\n this._world.emit('pick-hover-' + id, _point2d, _point3d, intersects);\n } else {\n this._world.emit('pick-click', id, _point2d, _point3d, intersects);\n this._world.emit('pick-click-' + id, _point2d, _point3d, intersects);\n }\n }\n\n // Add mesh to picking scene\n //\n // Picking ID should already be added as an attribute\n add(mesh) {\n this._pickingScene.add(mesh);\n this._needUpdate = true;\n }\n\n // Remove mesh from picking scene\n remove(mesh) {\n this._pickingScene.remove(mesh);\n this._needUpdate = true;\n }\n\n // Returns next ID to use for picking\n getNextId() {\n return nextId++;\n }\n\n destroy() {\n // TODO: Find a way to properly remove these listeners as they stay\n // active at the moment\n window.removeEventListener('resize', this._resizeHandler, false);\n this._world._container.removeEventListener('mouseup', this._mouseUpHandler, false);\n this._world._container.removeEventListener('mousemove', this._throttledMouseMoveHandler, false);\n\n this._world.off('move', this._onWorldMove);\n\n if (this._pickingScene.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._pickingScene.children.length - 1; i >= 0; i--) {\n child = this._pickingScene.children[i];\n\n if (!child) {\n continue;\n }\n\n this._pickingScene.remove(child);\n\n // Probably not a good idea to dispose of geometry due to it being\n // shared with the non-picking scene\n // if (child.geometry) {\n // // Dispose of mesh and materials\n // child.geometry.dispose();\n // child.geometry = null;\n // }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n }\n }\n\n this._pickingScene = null;\n this._pickingTexture = null;\n this._pixelBuffer = null;\n\n this._world = null;\n this._renderer = null;\n this._camera = null;\n }\n}\n\n// Initialise without requiring new keyword\nexport default function(world, renderer, camera) {\n return new Picking(world, renderer, camera);\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/Picking.js\n **/","import THREE from 'three';\n\n// This can be imported from anywhere and will still reference the same scene,\n// though there is a helper reference in Engine.pickingScene\n\nexport default (function() {\n var scene = new THREE.Scene();\n return scene;\n})();\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingScene.js\n **/","/**\n * lodash 4.0.1 (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright 2012-2016 The Dojo Foundation \n * Based on Underscore.js 1.8.3 \n * Copyright 2009-2016 Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n * Available under MIT license \n */\nvar debounce = require('lodash.debounce');\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/**\n * Creates a throttled function that only invokes `func` at most once per\n * every `wait` milliseconds. The throttled function comes with a `cancel`\n * method to cancel delayed `func` invocations and a `flush` method to\n * immediately invoke them. Provide an options object to indicate whether\n * `func` should be invoked on the leading and/or trailing edge of the `wait`\n * timeout. The `func` is invoked with the last arguments provided to the\n * throttled function. Subsequent calls to the throttled function return the\n * result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the throttled function is\n * invoked more than once during the `wait` timeout.\n *\n * See [David Corbacho's article](http://drupalmotion.com/article/debounce-and-throttle-visual-explanation)\n * for details over the differences between `_.throttle` and `_.debounce`.\n *\n * @static\n * @memberOf _\n * @category Function\n * @param {Function} func The function to throttle.\n * @param {number} [wait=0] The number of milliseconds to throttle invocations to.\n * @param {Object} [options] The options object.\n * @param {boolean} [options.leading=true] Specify invoking on the leading\n * edge of the timeout.\n * @param {boolean} [options.trailing=true] Specify invoking on the trailing\n * edge of the timeout.\n * @returns {Function} Returns the new throttled function.\n * @example\n *\n * // Avoid excessively updating the position while scrolling.\n * jQuery(window).on('scroll', _.throttle(updatePosition, 100));\n *\n * // Invoke `renewToken` when the click event is fired, but not more than once every 5 minutes.\n * var throttled = _.throttle(renewToken, 300000, { 'trailing': false });\n * jQuery(element).on('click', throttled);\n *\n * // Cancel the trailing throttled invocation.\n * jQuery(window).on('popstate', throttled.cancel);\n */\nfunction throttle(func, wait, options) {\n var leading = true,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n if (isObject(options)) {\n leading = 'leading' in options ? !!options.leading : leading;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n return debounce(func, wait, {\n 'leading': leading,\n 'maxWait': wait,\n 'trailing': trailing\n });\n}\n\n/**\n * Checks if `value` is the [language type](https://es5.github.io/#x8) of `Object`.\n * (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\nmodule.exports = throttle;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.throttle/index.js\n ** module id = 22\n ** module chunks = 0\n **/","/**\n * lodash 4.0.6 (Custom Build) \n * Build: `lodash modularize exports=\"npm\" -o ./`\n * Copyright jQuery Foundation and other contributors \n * Released under MIT license \n * Based on Underscore.js 1.8.3 \n * Copyright Jeremy Ashkenas, DocumentCloud and Investigative Reporters & Editors\n */\n\n/** Used as the `TypeError` message for \"Functions\" methods. */\nvar FUNC_ERROR_TEXT = 'Expected a function';\n\n/** Used as references for various `Number` constants. */\nvar NAN = 0 / 0;\n\n/** `Object#toString` result references. */\nvar funcTag = '[object Function]',\n genTag = '[object GeneratorFunction]',\n symbolTag = '[object Symbol]';\n\n/** Used to match leading and trailing whitespace. */\nvar reTrim = /^\\s+|\\s+$/g;\n\n/** Used to detect bad signed hexadecimal string values. */\nvar reIsBadHex = /^[-+]0x[0-9a-f]+$/i;\n\n/** Used to detect binary string values. */\nvar reIsBinary = /^0b[01]+$/i;\n\n/** Used to detect octal string values. */\nvar reIsOctal = /^0o[0-7]+$/i;\n\n/** Built-in method references without a dependency on `root`. */\nvar freeParseInt = parseInt;\n\n/** Used for built-in method references. */\nvar objectProto = Object.prototype;\n\n/**\n * Used to resolve the\n * [`toStringTag`](http://ecma-international.org/ecma-262/6.0/#sec-object.prototype.tostring)\n * of values.\n */\nvar objectToString = objectProto.toString;\n\n/* Built-in method references for those with the same name as other `lodash` methods. */\nvar nativeMax = Math.max,\n nativeMin = Math.min;\n\n/**\n * Gets the timestamp of the number of milliseconds that have elapsed since\n * the Unix epoch (1 January 1970 00:00:00 UTC).\n *\n * @static\n * @memberOf _\n * @since 2.4.0\n * @type {Function}\n * @category Date\n * @returns {number} Returns the timestamp.\n * @example\n *\n * _.defer(function(stamp) {\n * console.log(_.now() - stamp);\n * }, _.now());\n * // => Logs the number of milliseconds it took for the deferred function to be invoked.\n */\nvar now = Date.now;\n\n/**\n * Creates a debounced function that delays invoking `func` until after `wait`\n * milliseconds have elapsed since the last time the debounced function was\n * invoked. The debounced function comes with a `cancel` method to cancel\n * delayed `func` invocations and a `flush` method to immediately invoke them.\n * Provide an options object to indicate whether `func` should be invoked on\n * the leading and/or trailing edge of the `wait` timeout. The `func` is invoked\n * with the last arguments provided to the debounced function. Subsequent calls\n * to the debounced function return the result of the last `func` invocation.\n *\n * **Note:** If `leading` and `trailing` options are `true`, `func` is invoked\n * on the trailing edge of the timeout only if the debounced function is\n * invoked more than once during the `wait` timeout.\n *\n * See [David Corbacho's article](https://css-tricks.com/debouncing-throttling-explained-examples/)\n * for details over the differences between `_.debounce` and `_.throttle`.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Function\n * @param {Function} func The function to debounce.\n * @param {number} [wait=0] The number of milliseconds to delay.\n * @param {Object} [options={}] The options object.\n * @param {boolean} [options.leading=false]\n * Specify invoking on the leading edge of the timeout.\n * @param {number} [options.maxWait]\n * The maximum time `func` is allowed to be delayed before it's invoked.\n * @param {boolean} [options.trailing=true]\n * Specify invoking on the trailing edge of the timeout.\n * @returns {Function} Returns the new debounced function.\n * @example\n *\n * // Avoid costly calculations while the window size is in flux.\n * jQuery(window).on('resize', _.debounce(calculateLayout, 150));\n *\n * // Invoke `sendMail` when clicked, debouncing subsequent calls.\n * jQuery(element).on('click', _.debounce(sendMail, 300, {\n * 'leading': true,\n * 'trailing': false\n * }));\n *\n * // Ensure `batchLog` is invoked once after 1 second of debounced calls.\n * var debounced = _.debounce(batchLog, 250, { 'maxWait': 1000 });\n * var source = new EventSource('/stream');\n * jQuery(source).on('message', debounced);\n *\n * // Cancel the trailing debounced invocation.\n * jQuery(window).on('popstate', debounced.cancel);\n */\nfunction debounce(func, wait, options) {\n var lastArgs,\n lastThis,\n maxWait,\n result,\n timerId,\n lastCallTime = 0,\n lastInvokeTime = 0,\n leading = false,\n maxing = false,\n trailing = true;\n\n if (typeof func != 'function') {\n throw new TypeError(FUNC_ERROR_TEXT);\n }\n wait = toNumber(wait) || 0;\n if (isObject(options)) {\n leading = !!options.leading;\n maxing = 'maxWait' in options;\n maxWait = maxing ? nativeMax(toNumber(options.maxWait) || 0, wait) : maxWait;\n trailing = 'trailing' in options ? !!options.trailing : trailing;\n }\n\n function invokeFunc(time) {\n var args = lastArgs,\n thisArg = lastThis;\n\n lastArgs = lastThis = undefined;\n lastInvokeTime = time;\n result = func.apply(thisArg, args);\n return result;\n }\n\n function leadingEdge(time) {\n // Reset any `maxWait` timer.\n lastInvokeTime = time;\n // Start the timer for the trailing edge.\n timerId = setTimeout(timerExpired, wait);\n // Invoke the leading edge.\n return leading ? invokeFunc(time) : result;\n }\n\n function remainingWait(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime,\n result = wait - timeSinceLastCall;\n\n return maxing ? nativeMin(result, maxWait - timeSinceLastInvoke) : result;\n }\n\n function shouldInvoke(time) {\n var timeSinceLastCall = time - lastCallTime,\n timeSinceLastInvoke = time - lastInvokeTime;\n\n // Either this is the first call, activity has stopped and we're at the\n // trailing edge, the system time has gone backwards and we're treating\n // it as the trailing edge, or we've hit the `maxWait` limit.\n return (!lastCallTime || (timeSinceLastCall >= wait) ||\n (timeSinceLastCall < 0) || (maxing && timeSinceLastInvoke >= maxWait));\n }\n\n function timerExpired() {\n var time = now();\n if (shouldInvoke(time)) {\n return trailingEdge(time);\n }\n // Restart the timer.\n timerId = setTimeout(timerExpired, remainingWait(time));\n }\n\n function trailingEdge(time) {\n clearTimeout(timerId);\n timerId = undefined;\n\n // Only invoke if we have `lastArgs` which means `func` has been\n // debounced at least once.\n if (trailing && lastArgs) {\n return invokeFunc(time);\n }\n lastArgs = lastThis = undefined;\n return result;\n }\n\n function cancel() {\n if (timerId !== undefined) {\n clearTimeout(timerId);\n }\n lastCallTime = lastInvokeTime = 0;\n lastArgs = lastThis = timerId = undefined;\n }\n\n function flush() {\n return timerId === undefined ? result : trailingEdge(now());\n }\n\n function debounced() {\n var time = now(),\n isInvoking = shouldInvoke(time);\n\n lastArgs = arguments;\n lastThis = this;\n lastCallTime = time;\n\n if (isInvoking) {\n if (timerId === undefined) {\n return leadingEdge(lastCallTime);\n }\n if (maxing) {\n // Handle invocations in a tight loop.\n clearTimeout(timerId);\n timerId = setTimeout(timerExpired, wait);\n return invokeFunc(lastCallTime);\n }\n }\n if (timerId === undefined) {\n timerId = setTimeout(timerExpired, wait);\n }\n return result;\n }\n debounced.cancel = cancel;\n debounced.flush = flush;\n return debounced;\n}\n\n/**\n * Checks if `value` is classified as a `Function` object.\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isFunction(_);\n * // => true\n *\n * _.isFunction(/abc/);\n * // => false\n */\nfunction isFunction(value) {\n // The use of `Object#toString` avoids issues with the `typeof` operator\n // in Safari 8 which returns 'object' for typed array and weak map constructors,\n // and PhantomJS 1.9 which returns 'function' for `NodeList` instances.\n var tag = isObject(value) ? objectToString.call(value) : '';\n return tag == funcTag || tag == genTag;\n}\n\n/**\n * Checks if `value` is the\n * [language type](http://www.ecma-international.org/ecma-262/6.0/#sec-ecmascript-language-types)\n * of `Object`. (e.g. arrays, functions, objects, regexes, `new Number(0)`, and `new String('')`)\n *\n * @static\n * @memberOf _\n * @since 0.1.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is an object, else `false`.\n * @example\n *\n * _.isObject({});\n * // => true\n *\n * _.isObject([1, 2, 3]);\n * // => true\n *\n * _.isObject(_.noop);\n * // => true\n *\n * _.isObject(null);\n * // => false\n */\nfunction isObject(value) {\n var type = typeof value;\n return !!value && (type == 'object' || type == 'function');\n}\n\n/**\n * Checks if `value` is object-like. A value is object-like if it's not `null`\n * and has a `typeof` result of \"object\".\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is object-like, else `false`.\n * @example\n *\n * _.isObjectLike({});\n * // => true\n *\n * _.isObjectLike([1, 2, 3]);\n * // => true\n *\n * _.isObjectLike(_.noop);\n * // => false\n *\n * _.isObjectLike(null);\n * // => false\n */\nfunction isObjectLike(value) {\n return !!value && typeof value == 'object';\n}\n\n/**\n * Checks if `value` is classified as a `Symbol` primitive or object.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to check.\n * @returns {boolean} Returns `true` if `value` is correctly classified,\n * else `false`.\n * @example\n *\n * _.isSymbol(Symbol.iterator);\n * // => true\n *\n * _.isSymbol('abc');\n * // => false\n */\nfunction isSymbol(value) {\n return typeof value == 'symbol' ||\n (isObjectLike(value) && objectToString.call(value) == symbolTag);\n}\n\n/**\n * Converts `value` to a number.\n *\n * @static\n * @memberOf _\n * @since 4.0.0\n * @category Lang\n * @param {*} value The value to process.\n * @returns {number} Returns the number.\n * @example\n *\n * _.toNumber(3);\n * // => 3\n *\n * _.toNumber(Number.MIN_VALUE);\n * // => 5e-324\n *\n * _.toNumber(Infinity);\n * // => Infinity\n *\n * _.toNumber('3');\n * // => 3\n */\nfunction toNumber(value) {\n if (typeof value == 'number') {\n return value;\n }\n if (isSymbol(value)) {\n return NAN;\n }\n if (isObject(value)) {\n var other = isFunction(value.valueOf) ? value.valueOf() : value;\n value = isObject(other) ? (other + '') : other;\n }\n if (typeof value != 'string') {\n return value === 0 ? value : +value;\n }\n value = value.replace(reTrim, '');\n var isBinary = reIsBinary.test(value);\n return (isBinary || reIsOctal.test(value))\n ? freeParseInt(value.slice(2), isBinary ? 2 : 8)\n : (reIsBadHex.test(value) ? NAN : +value);\n}\n\nmodule.exports = debounce;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lodash.debounce/index.js\n ** module id = 23\n ** module chunks = 0\n **/","import THREE from 'three';\nimport EffectComposer from '../vendor/EffectComposer';\n\nexport default function(renderer, container) {\n var composer = new EffectComposer(renderer);\n\n var updateSize = function() {\n // TODO: Re-enable this when perf issues can be solved\n //\n // Rendering double the resolution of the screen can be really slow\n // var pixelRatio = window.devicePixelRatio;\n var pixelRatio = 1;\n\n composer.setSize(container.clientWidth * pixelRatio, container.clientHeight * pixelRatio);\n };\n\n window.addEventListener('resize', updateSize, false);\n updateSize();\n\n return composer;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/EffectComposer.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\nimport CopyShader from './CopyShader';\nimport ShaderPass from './ShaderPass';\nimport MaskPass, {ClearMaskPass} from './MaskPass';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar EffectComposer = function ( renderer, renderTarget ) {\n\n\tthis.renderer = renderer;\n\n\tif ( renderTarget === undefined ) {\n\n\t\tvar pixelRatio = renderer.getPixelRatio();\n\n\t\tvar width = Math.floor( renderer.context.canvas.width / pixelRatio ) || 1;\n\t\tvar height = Math.floor( renderer.context.canvas.height / pixelRatio ) || 1;\n\t\tvar parameters = { minFilter: THREE.LinearFilter, magFilter: THREE.LinearFilter, format: THREE.RGBAFormat, stencilBuffer: false };\n\n\t\trenderTarget = new THREE.WebGLRenderTarget( width, height, parameters );\n\n\t}\n\n\tthis.renderTarget1 = renderTarget;\n\tthis.renderTarget2 = renderTarget.clone();\n\n\tthis.writeBuffer = this.renderTarget1;\n\tthis.readBuffer = this.renderTarget2;\n\n\tthis.passes = [];\n\n\tif ( CopyShader === undefined )\n\t\tconsole.error( \"EffectComposer relies on THREE.CopyShader\" );\n\n\tthis.copyPass = new ShaderPass( CopyShader );\n\n};\n\nEffectComposer.prototype = {\n\n\tswapBuffers: function() {\n\n\t\tvar tmp = this.readBuffer;\n\t\tthis.readBuffer = this.writeBuffer;\n\t\tthis.writeBuffer = tmp;\n\n\t},\n\n\taddPass: function ( pass ) {\n\n\t\tthis.passes.push( pass );\n\n\t},\n\n\tinsertPass: function ( pass, index ) {\n\n\t\tthis.passes.splice( index, 0, pass );\n\n\t},\n\n\trender: function ( delta ) {\n\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\n\t\tvar maskActive = false;\n\n\t\tvar pass, i, il = this.passes.length;\n\n\t\tfor ( i = 0; i < il; i ++ ) {\n\n\t\t\tpass = this.passes[ i ];\n\n\t\t\tif ( ! pass.enabled ) continue;\n\n\t\t\tpass.render( this.renderer, this.writeBuffer, this.readBuffer, delta, maskActive );\n\n\t\t\tif ( pass.needsSwap ) {\n\n\t\t\t\tif ( maskActive ) {\n\n\t\t\t\t\tvar context = this.renderer.context;\n\n\t\t\t\t\tcontext.stencilFunc( context.NOTEQUAL, 1, 0xffffffff );\n\n\t\t\t\t\tthis.copyPass.render( this.renderer, this.writeBuffer, this.readBuffer, delta );\n\n\t\t\t\t\tcontext.stencilFunc( context.EQUAL, 1, 0xffffffff );\n\n\t\t\t\t}\n\n\t\t\t\tthis.swapBuffers();\n\n\t\t\t}\n\n\t\t\tif ( pass instanceof MaskPass ) {\n\n\t\t\t\tmaskActive = true;\n\n\t\t\t} else if ( pass instanceof ClearMaskPass ) {\n\n\t\t\t\tmaskActive = false;\n\n\t\t\t}\n\n\t\t}\n\n\t},\n\n\treset: function ( renderTarget ) {\n\n\t\tif ( renderTarget === undefined ) {\n\n\t\t\trenderTarget = this.renderTarget1.clone();\n\n\t\t\tvar pixelRatio = this.renderer.getPixelRatio();\n\n\t\t\trenderTarget.setSize(\n\t\t\t\tMath.floor( this.renderer.context.canvas.width / pixelRatio ),\n\t\t\t\tMath.floor( this.renderer.context.canvas.height / pixelRatio )\n\t\t\t);\n\n\t\t}\n\n\t\tthis.renderTarget1.dispose();\n\t\tthis.renderTarget1 = renderTarget;\n\t\tthis.renderTarget2.dispose();\n\t\tthis.renderTarget2 = renderTarget.clone();\n\n\t\tthis.writeBuffer = this.renderTarget1;\n\t\tthis.readBuffer = this.renderTarget2;\n\n\t},\n\n\tsetSize: function ( width, height ) {\n\n\t\tthis.renderTarget1.setSize( width, height );\n\t\tthis.renderTarget2.setSize( width, height );\n\n\t}\n\n};\n\nexport default EffectComposer;\nTHREE.EffectComposer = EffectComposer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/EffectComposer.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Full-screen textured quad shader\n */\n\nvar CopyShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"opacity\": { type: \"f\", value: 1.0 }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vUv = uv;\",\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform float opacity;\",\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec4 texel = texture2D( tDiffuse, vUv );\",\n\t\t\t\"gl_FragColor = opacity * texel;\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default CopyShader;\nTHREE.CopyShader = CopyShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/CopyShader.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar ShaderPass = function( shader, textureID ) {\n\n\tthis.textureID = ( textureID !== undefined ) ? textureID : \"tDiffuse\";\n\n\tif ( shader instanceof THREE.ShaderMaterial ) {\n\n\t\tthis.uniforms = shader.uniforms;\n\n\t\tthis.material = shader;\n\n\t}\n\telse if ( shader ) {\n\n\t\tthis.uniforms = THREE.UniformsUtils.clone( shader.uniforms );\n\n\t\tthis.material = new THREE.ShaderMaterial( {\n\n\t\t\tdefines: shader.defines || {},\n\t\t\tuniforms: this.uniforms,\n\t\t\tvertexShader: shader.vertexShader,\n\t\t\tfragmentShader: shader.fragmentShader\n\n\t\t} );\n\n\t}\n\n\tthis.renderToScreen = false;\n\n\tthis.enabled = true;\n\tthis.needsSwap = true;\n\tthis.clear = false;\n\n\n\tthis.camera = new THREE.OrthographicCamera( - 1, 1, 1, - 1, 0, 1 );\n\tthis.scene = new THREE.Scene();\n\n\tthis.quad = new THREE.Mesh( new THREE.PlaneBufferGeometry( 2, 2 ), null );\n\tthis.scene.add( this.quad );\n\n};\n\nShaderPass.prototype = {\n\n\trender: function( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tif ( this.uniforms[ this.textureID ] ) {\n\n\t\t\tthis.uniforms[ this.textureID ].value = readBuffer;\n\n\t\t}\n\n\t\tthis.quad.material = this.material;\n\n\t\tif ( this.renderToScreen ) {\n\n\t\t\trenderer.render( this.scene, this.camera );\n\n\t\t} else {\n\n\t\t\trenderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n\t\t}\n\n\t}\n\n};\n\nexport default ShaderPass;\nTHREE.ShaderPass = ShaderPass;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/ShaderPass.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar MaskPass = function ( scene, camera ) {\n\n\tthis.scene = scene;\n\tthis.camera = camera;\n\n\tthis.enabled = true;\n\tthis.clear = true;\n\tthis.needsSwap = false;\n\n\tthis.inverse = false;\n\n};\n\nMaskPass.prototype = {\n\n\trender: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tvar context = renderer.context;\n\n\t\t// don't update color or depth\n\n\t\tcontext.colorMask( false, false, false, false );\n\t\tcontext.depthMask( false );\n\n\t\t// set up stencil\n\n\t\tvar writeValue, clearValue;\n\n\t\tif ( this.inverse ) {\n\n\t\t\twriteValue = 0;\n\t\t\tclearValue = 1;\n\n\t\t} else {\n\n\t\t\twriteValue = 1;\n\t\t\tclearValue = 0;\n\n\t\t}\n\n\t\tcontext.enable( context.STENCIL_TEST );\n\t\tcontext.stencilOp( context.REPLACE, context.REPLACE, context.REPLACE );\n\t\tcontext.stencilFunc( context.ALWAYS, writeValue, 0xffffffff );\n\t\tcontext.clearStencil( clearValue );\n\n\t\t// draw into the stencil buffer\n\n\t\trenderer.render( this.scene, this.camera, readBuffer, this.clear );\n\t\trenderer.render( this.scene, this.camera, writeBuffer, this.clear );\n\n\t\t// re-enable update of color and depth\n\n\t\tcontext.colorMask( true, true, true, true );\n\t\tcontext.depthMask( true );\n\n\t\t// only render where stencil is set to 1\n\n\t\tcontext.stencilFunc( context.EQUAL, 1, 0xffffffff ); // draw if == 1\n\t\tcontext.stencilOp( context.KEEP, context.KEEP, context.KEEP );\n\n\t}\n\n};\n\n\nvar ClearMaskPass = function () {\n\n\tthis.enabled = true;\n\n};\n\nClearMaskPass.prototype = {\n\n\trender: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tvar context = renderer.context;\n\n\t\tcontext.disable( context.STENCIL_TEST );\n\n\t}\n\n};\n\nexport default MaskPass;\nexport {ClearMaskPass as ClearMaskPass};\n\nTHREE.MaskPass = MaskPass;\nTHREE.ClearMaskPass = ClearMaskPass;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/MaskPass.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n */\n\nvar RenderPass = function ( scene, camera, overrideMaterial, clearColor, clearAlpha ) {\n\n\tthis.scene = scene;\n\tthis.camera = camera;\n\n\tthis.overrideMaterial = overrideMaterial;\n\n\tthis.clearColor = clearColor;\n\tthis.clearAlpha = ( clearAlpha !== undefined ) ? clearAlpha : 1;\n\n\tthis.oldClearColor = new THREE.Color();\n\tthis.oldClearAlpha = 1;\n\n\tthis.enabled = true;\n\tthis.clear = true;\n\tthis.needsSwap = false;\n\n};\n\nRenderPass.prototype = {\n\n\trender: function ( renderer, writeBuffer, readBuffer, delta ) {\n\n\t\tthis.scene.overrideMaterial = this.overrideMaterial;\n\n\t\tif ( this.clearColor ) {\n\n\t\t\tthis.oldClearColor.copy( renderer.getClearColor() );\n\t\t\tthis.oldClearAlpha = renderer.getClearAlpha();\n\n\t\t\trenderer.setClearColor( this.clearColor, this.clearAlpha );\n\n\t\t}\n\n\t\trenderer.render( this.scene, this.camera, readBuffer, this.clear );\n\n\t\tif ( this.clearColor ) {\n\n\t\t\trenderer.setClearColor( this.oldClearColor, this.oldClearAlpha );\n\n\t\t}\n\n\t\tthis.scene.overrideMaterial = null;\n\n\t}\n\n};\n\nexport default RenderPass;\nTHREE.RenderPass = RenderPass;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/RenderPass.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n *\n * - 9 samples per pass\n * - standard deviation 2.7\n * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n * - \"r\" parameter control where \"focused\" horizontal line lies\n */\n\nvar HorizontalTiltShiftShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"h\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\"r\": { type: \"f\", value: 0.35 }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vUv = uv;\",\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\t\t\"uniform float h;\",\n\t\t\"uniform float r;\",\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec4 sum = vec4( 0.0 );\",\n\n\t\t\t\"float hh = h * abs( r - vUv.y );\",\n\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 4.0 * hh, vUv.y ) ) * 0.051;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 3.0 * hh, vUv.y ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 2.0 * hh, vUv.y ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x - 1.0 * hh, vUv.y ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 1.0 * hh, vUv.y ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 2.0 * hh, vUv.y ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 3.0 * hh, vUv.y ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x + 4.0 * hh, vUv.y ) ) * 0.051;\",\n\n\t\t\t\"gl_FragColor = sum;\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default HorizontalTiltShiftShader;\nTHREE.HorizontalTiltShiftShader = HorizontalTiltShiftShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/HorizontalTiltShiftShader.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n *\n * Simple fake tilt-shift effect, modulating two pass Gaussian blur (see above) by vertical position\n *\n * - 9 samples per pass\n * - standard deviation 2.7\n * - \"h\" and \"v\" parameters should be set to \"1 / width\" and \"1 / height\"\n * - \"r\" parameter control where \"focused\" horizontal line lies\n */\n\nvar VerticalTiltShiftShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"v\": { type: \"f\", value: 1.0 / 512.0 },\n\t\t\"r\": { type: \"f\", value: 0.35 }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vUv = uv;\",\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\t\t\"uniform float v;\",\n\t\t\"uniform float r;\",\n\n\t\t\"varying vec2 vUv;\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec4 sum = vec4( 0.0 );\",\n\n\t\t\t\"float vv = v * abs( r - vUv.y );\",\n\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 4.0 * vv ) ) * 0.051;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 3.0 * vv ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 2.0 * vv ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y - 1.0 * vv ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y ) ) * 0.1633;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 1.0 * vv ) ) * 0.1531;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 2.0 * vv ) ) * 0.12245;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 3.0 * vv ) ) * 0.0918;\",\n\t\t\t\"sum += texture2D( tDiffuse, vec2( vUv.x, vUv.y + 4.0 * vv ) ) * 0.051;\",\n\n\t\t\t\"gl_FragColor = sum;\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default VerticalTiltShiftShader;\nTHREE.VerticalTiltShiftShader = VerticalTiltShiftShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/VerticalTiltShiftShader.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author alteredq / http://alteredqualia.com/\n * @author davidedc / http://www.sketchpatch.net/\n *\n * NVIDIA FXAA by Timothy Lottes\n * http://timothylottes.blogspot.com/2011/06/fxaa3-source-released.html\n * - WebGL port by @supereggbert\n * http://www.glge.org/demos/fxaa/\n */\n\nvar FXAAShader = {\n\n\tuniforms: {\n\n\t\t\"tDiffuse\": { type: \"t\", value: null },\n\t\t\"resolution\": { type: \"v2\", value: new THREE.Vector2( 1 / 1024, 1 / 512 ) }\n\n\t},\n\n\tvertexShader: [\n\n\t\t\"void main() {\",\n\n\t\t\t\"gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" ),\n\n\tfragmentShader: [\n\n\t\t\"uniform sampler2D tDiffuse;\",\n\t\t\"uniform vec2 resolution;\",\n\n\t\t\"#define FXAA_REDUCE_MIN (1.0/128.0)\",\n\t\t\"#define FXAA_REDUCE_MUL (1.0/8.0)\",\n\t\t\"#define FXAA_SPAN_MAX 8.0\",\n\n\t\t\"void main() {\",\n\n\t\t\t\"vec3 rgbNW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, -1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec3 rgbNE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, -1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec3 rgbSW = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( -1.0, 1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec3 rgbSE = texture2D( tDiffuse, ( gl_FragCoord.xy + vec2( 1.0, 1.0 ) ) * resolution ).xyz;\",\n\t\t\t\"vec4 rgbaM = texture2D( tDiffuse, gl_FragCoord.xy * resolution );\",\n\t\t\t\"vec3 rgbM = rgbaM.xyz;\",\n\t\t\t\"vec3 luma = vec3( 0.299, 0.587, 0.114 );\",\n\n\t\t\t\"float lumaNW = dot( rgbNW, luma );\",\n\t\t\t\"float lumaNE = dot( rgbNE, luma );\",\n\t\t\t\"float lumaSW = dot( rgbSW, luma );\",\n\t\t\t\"float lumaSE = dot( rgbSE, luma );\",\n\t\t\t\"float lumaM = dot( rgbM, luma );\",\n\t\t\t\"float lumaMin = min( lumaM, min( min( lumaNW, lumaNE ), min( lumaSW, lumaSE ) ) );\",\n\t\t\t\"float lumaMax = max( lumaM, max( max( lumaNW, lumaNE) , max( lumaSW, lumaSE ) ) );\",\n\n\t\t\t\"vec2 dir;\",\n\t\t\t\"dir.x = -((lumaNW + lumaNE) - (lumaSW + lumaSE));\",\n\t\t\t\"dir.y = ((lumaNW + lumaSW) - (lumaNE + lumaSE));\",\n\n\t\t\t\"float dirReduce = max( ( lumaNW + lumaNE + lumaSW + lumaSE ) * ( 0.25 * FXAA_REDUCE_MUL ), FXAA_REDUCE_MIN );\",\n\n\t\t\t\"float rcpDirMin = 1.0 / ( min( abs( dir.x ), abs( dir.y ) ) + dirReduce );\",\n\t\t\t\"dir = min( vec2( FXAA_SPAN_MAX, FXAA_SPAN_MAX),\",\n\t\t\t\t \"max( vec2(-FXAA_SPAN_MAX, -FXAA_SPAN_MAX),\",\n\t\t\t\t\t\t\"dir * rcpDirMin)) * resolution;\",\n\t\t\t\"vec4 rgbA = (1.0/2.0) * (\",\n \t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (1.0/3.0 - 0.5)) +\",\n\t\t\t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (2.0/3.0 - 0.5)));\",\n \t\t\"vec4 rgbB = rgbA * (1.0/2.0) + (1.0/4.0) * (\",\n\t\t\t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (0.0/3.0 - 0.5)) +\",\n \t\t\"texture2D(tDiffuse, gl_FragCoord.xy * resolution + dir * (3.0/3.0 - 0.5)));\",\n \t\t\"float lumaB = dot(rgbB, vec4(luma, 0.0));\",\n\n\t\t\t\"if ( ( lumaB < lumaMin ) || ( lumaB > lumaMax ) ) {\",\n\n\t\t\t\t\"gl_FragColor = rgbA;\",\n\n\t\t\t\"} else {\",\n\t\t\t\t\"gl_FragColor = rgbB;\",\n\n\t\t\t\"}\",\n\n\t\t\"}\"\n\n\t].join( \"\\n\" )\n\n};\n\nexport default FXAAShader;\nTHREE.FXAAShader = FXAAShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/FXAAShader.js\n **/","import Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Skybox from './Skybox';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\nclass EnvironmentLayer extends Layer {\n constructor(options) {\n var defaults = {\n skybox: false\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n }\n\n _onAdd() {\n this._initLights();\n\n if (this._options.skybox) {\n this._initSkybox();\n }\n\n // this._initGrid();\n\n return Promise.resolve(this);\n }\n\n // Not fleshed out or thought through yet\n //\n // Lights could potentially be put it their own 'layer' to keep this class\n // much simpler and less messy\n _initLights() {\n // Position doesn't really matter (the angle is important), however it's\n // used here so the helpers look more natural.\n\n if (!this._options.skybox) {\n var directionalLight = new THREE.DirectionalLight(0xffffff, 1);\n directionalLight.position.x = 10000;\n directionalLight.position.y = 10000;\n directionalLight.position.z = 10000;\n\n // TODO: Get shadows working in non-PBR scenes\n\n // directionalLight.castShadow = true;\n //\n // var d = 100;\n // directionalLight.shadow.camera.left = -d;\n // directionalLight.shadow.camera.right = d;\n // directionalLight.shadow.camera.top = d;\n // directionalLight.shadow.camera.bottom = -d;\n //\n // directionalLight.shadow.camera.near = 10;\n // directionalLight.shadow.camera.far = 100;\n //\n // // TODO: Need to dial in on a good shadowmap size\n // directionalLight.shadow.mapSize.width = 2048;\n // directionalLight.shadow.mapSize.height = 2048;\n //\n // // directionalLight.shadowBias = -0.0010;\n // // directionalLight.shadow.darkness = 0.15;\n\n var directionalLight2 = new THREE.DirectionalLight(0xffffff, 0.5);\n directionalLight2.position.x = -10000;\n directionalLight2.position.y = 10000;\n directionalLight2.position.z = 0;\n\n var directionalLight3 = new THREE.DirectionalLight(0xffffff, 0.5);\n directionalLight3.position.x = 10000;\n directionalLight3.position.y = 10000;\n directionalLight3.position.z = -10000;\n\n this.add(directionalLight);\n this.add(directionalLight2);\n this.add(directionalLight3);\n\n // var helper = new THREE.DirectionalLightHelper(directionalLight, 10);\n // var helper2 = new THREE.DirectionalLightHelper(directionalLight2, 10);\n // var helper3 = new THREE.DirectionalLightHelper(directionalLight3, 10);\n //\n // this.add(helper);\n // this.add(helper2);\n // this.add(helper3);\n } else {\n // Directional light that will be projected from the sun\n this._skyboxLight = new THREE.DirectionalLight(0xffffff, 1);\n\n this._skyboxLight.castShadow = true;\n\n var d = 10000;\n this._skyboxLight.shadow.camera.left = -d;\n this._skyboxLight.shadow.camera.right = d;\n this._skyboxLight.shadow.camera.top = d;\n this._skyboxLight.shadow.camera.bottom = -d;\n\n this._skyboxLight.shadow.camera.near = 10000;\n this._skyboxLight.shadow.camera.far = 70000;\n\n // TODO: Need to dial in on a good shadowmap size\n this._skyboxLight.shadow.mapSize.width = 2048;\n this._skyboxLight.shadow.mapSize.height = 2048;\n\n // this._skyboxLight.shadowBias = -0.0010;\n // this._skyboxLight.shadow.darkness = 0.15;\n\n // this._object3D.add(new THREE.CameraHelper(this._skyboxLight.shadow.camera));\n\n this.add(this._skyboxLight);\n }\n }\n\n _initSkybox() {\n this._skybox = new Skybox(this._world, this._skyboxLight);\n this.add(this._skybox._mesh);\n }\n\n // Add grid helper for context during initial development\n _initGrid() {\n var size = 4000;\n var step = 100;\n\n var gridHelper = new THREE.GridHelper(size, step);\n this.add(gridHelper);\n }\n\n // Clean up environment\n destroy() {\n this._skyboxLight = null;\n\n this.remove(this._skybox._mesh);\n this._skybox.destroy();\n this._skybox = null;\n\n super.destroy();\n }\n}\n\nexport default EnvironmentLayer;\n\nvar noNew = function(options) {\n return new EnvironmentLayer(options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as environmentLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/environment/EnvironmentLayer.js\n **/","import EventEmitter from 'eventemitter3';\nimport extend from 'lodash.assign';\nimport shortid from 'shortid';\nimport THREE from 'three';\nimport Scene from '../engine/Scene';\nimport {CSS3DObject} from '../vendor/CSS3DRenderer';\nimport {CSS2DObject} from '../vendor/CSS2DRenderer';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Need a single move method that handles moving all the various object\n// layers so that the DOM layers stay in sync with the 3D layer\n\n// TODO: Double check that objects within the _object3D Object3D parent are frustum\n// culled even if the layer position stays at the default (0,0,0) and the child\n// objects are positioned much further away\n//\n// Or does the layer being at (0,0,0) prevent the child objects from being\n// culled because the layer parent is effectively always in view even if the\n// child is actually out of camera\n\nclass Layer extends EventEmitter {\n constructor(options) {\n super();\n\n var defaults = {\n id: shortid.generate(),\n output: true,\n outputToScene: true\n };\n\n this._options = extend({}, defaults, options);\n\n if (this.isOutput()) {\n this._object3D = new THREE.Object3D();\n\n this._dom3D = document.createElement('div');\n this._domObject3D = new CSS3DObject(this._dom3D);\n\n this._dom2D = document.createElement('div');\n this._domObject2D = new CSS2DObject(this._dom2D);\n }\n }\n\n // Add THREE object directly to layer\n add(object) {\n this._object3D.add(object);\n }\n\n // Remove THREE object from to layer\n remove(object) {\n this._object3D.remove(object);\n }\n\n addDOM3D(object) {\n this._domObject3D.add(object);\n }\n\n removeDOM3D(object) {\n this._domObject3D.remove(object);\n }\n\n addDOM2D(object) {\n this._domObject2D.add(object);\n }\n\n removeDOM2D(object) {\n this._domObject2D.remove(object);\n }\n\n // Add layer to world instance and store world reference\n addTo(world) {\n return world.addLayer(this);\n }\n\n // Internal method called by World.addLayer to actually add the layer\n _addToWorld(world) {\n this._world = world;\n\n return new Promise((resolve, reject) => {\n this._onAdd(world).then(() => {\n this.emit('added');\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Must return a promise\n _onAdd(world) {\n return Promise.resolve(this);\n }\n\n getPickingId() {\n if (this._world._engine._picking) {\n return this._world._engine._picking.getNextId();\n }\n\n return false;\n }\n\n // TODO: Tidy this up and don't access so many private properties to work\n addToPicking(object) {\n if (!this._world._engine._picking) {\n return;\n }\n\n this._world._engine._picking.add(object);\n }\n\n removeFromPicking(object) {\n if (!this._world._engine._picking) {\n return;\n }\n\n this._world._engine._picking.remove(object);\n }\n\n isOutput() {\n return this._options.output;\n }\n\n isOutputToScene() {\n return this._options.outputToScene;\n }\n\n // TODO: Also hide any attached DOM layers\n hide() {\n this._object3D.visible = false;\n\n if (this._pickingMesh) {\n this._pickingMesh.visible = false;\n }\n }\n\n // TODO: Also show any attached DOM layers\n show() {\n this._object3D.visible = true;\n\n if (this._pickingMesh) {\n this._pickingMesh.visible = true;\n }\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n if (this._object3D && this._object3D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._object3D.children.length - 1; i >= 0; i--) {\n child = this._object3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.remove(child);\n\n if (child.geometry) {\n // Dispose of mesh and materials\n child.geometry.dispose();\n child.geometry = null;\n }\n\n if (child.material) {\n if (child.material.map) {\n child.material.map.dispose();\n child.material.map = null;\n }\n\n child.material.dispose();\n child.material = null;\n }\n }\n }\n\n if (this._domObject3D && this._domObject3D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._domObject3D.children.length - 1; i >= 0; i--) {\n child = this._domObject3D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.removeDOM3D(child);\n }\n }\n\n if (this._domObject2D && this._domObject2D.children) {\n // Remove everything else in the layer\n var child;\n for (var i = this._domObject2D.children.length - 1; i >= 0; i--) {\n child = this._domObject2D.children[i];\n\n if (!child) {\n continue;\n }\n\n this.removeDOM2D(child);\n }\n }\n\n this._domObject3D = null;\n this._domObject2D = null;\n\n this._world = null;\n this._object3D = null;\n }\n}\n\nexport default Layer;\n\nvar noNew = function(options) {\n return new Layer(options);\n};\n\nexport {noNew as layer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/Layer.js\n **/","'use strict';\nmodule.exports = require('./lib/index');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/index.js\n ** module id = 35\n ** module chunks = 0\n **/","'use strict';\n\nvar alphabet = require('./alphabet');\nvar encode = require('./encode');\nvar decode = require('./decode');\nvar isValid = require('./is-valid');\n\n// Ignore all milliseconds before a certain time to reduce the size of the date entropy without sacrificing uniqueness.\n// This number should be updated every year or so to keep the generated id short.\n// To regenerate `new Date() - 0` and bump the version. Always bump the version!\nvar REDUCE_TIME = 1459707606518;\n\n// don't change unless we change the algos or REDUCE_TIME\n// must be an integer and less than 16\nvar version = 6;\n\n// if you are using cluster or multiple servers use this to make each instance\n// has a unique value for worker\n// Note: I don't know if this is automatically set when using third\n// party cluster solutions such as pm2.\nvar clusterWorkerId = require('./util/cluster-worker-id') || 0;\n\n// Counter is used when shortid is called multiple times in one second.\nvar counter;\n\n// Remember the last time shortid was called in case counter is needed.\nvar previousSeconds;\n\n/**\n * Generate unique id\n * Returns string id\n */\nfunction generate() {\n\n var str = '';\n\n var seconds = Math.floor((Date.now() - REDUCE_TIME) * 0.001);\n\n if (seconds === previousSeconds) {\n counter++;\n } else {\n counter = 0;\n previousSeconds = seconds;\n }\n\n str = str + encode(alphabet.lookup, version);\n str = str + encode(alphabet.lookup, clusterWorkerId);\n if (counter > 0) {\n str = str + encode(alphabet.lookup, counter);\n }\n str = str + encode(alphabet.lookup, seconds);\n\n return str;\n}\n\n\n/**\n * Set the seed.\n * Highly recommended if you don't want people to try to figure out your id schema.\n * exposed as shortid.seed(int)\n * @param seed Integer value to seed the random alphabet. ALWAYS USE THE SAME SEED or you might get overlaps.\n */\nfunction seed(seedValue) {\n alphabet.seed(seedValue);\n return module.exports;\n}\n\n/**\n * Set the cluster worker or machine id\n * exposed as shortid.worker(int)\n * @param workerId worker must be positive integer. Number less than 16 is recommended.\n * returns shortid module so it can be chained.\n */\nfunction worker(workerId) {\n clusterWorkerId = workerId;\n return module.exports;\n}\n\n/**\n *\n * sets new characters to use in the alphabet\n * returns the shuffled alphabet\n */\nfunction characters(newCharacters) {\n if (newCharacters !== undefined) {\n alphabet.characters(newCharacters);\n }\n\n return alphabet.shuffled();\n}\n\n\n// Export all other functions as properties of the generate function\nmodule.exports = generate;\nmodule.exports.generate = generate;\nmodule.exports.seed = seed;\nmodule.exports.worker = worker;\nmodule.exports.characters = characters;\nmodule.exports.decode = decode;\nmodule.exports.isValid = isValid;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/index.js\n ** module id = 36\n ** module chunks = 0\n **/","'use strict';\n\nvar randomFromSeed = require('./random/random-from-seed');\n\nvar ORIGINAL = '0123456789abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ_-';\nvar alphabet;\nvar previousSeed;\n\nvar shuffled;\n\nfunction reset() {\n shuffled = false;\n}\n\nfunction setCharacters(_alphabet_) {\n if (!_alphabet_) {\n if (alphabet !== ORIGINAL) {\n alphabet = ORIGINAL;\n reset();\n }\n return;\n }\n\n if (_alphabet_ === alphabet) {\n return;\n }\n\n if (_alphabet_.length !== ORIGINAL.length) {\n throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. You submitted ' + _alphabet_.length + ' characters: ' + _alphabet_);\n }\n\n var unique = _alphabet_.split('').filter(function(item, ind, arr){\n return ind !== arr.lastIndexOf(item);\n });\n\n if (unique.length) {\n throw new Error('Custom alphabet for shortid must be ' + ORIGINAL.length + ' unique characters. These characters were not unique: ' + unique.join(', '));\n }\n\n alphabet = _alphabet_;\n reset();\n}\n\nfunction characters(_alphabet_) {\n setCharacters(_alphabet_);\n return alphabet;\n}\n\nfunction setSeed(seed) {\n randomFromSeed.seed(seed);\n if (previousSeed !== seed) {\n reset();\n previousSeed = seed;\n }\n}\n\nfunction shuffle() {\n if (!alphabet) {\n setCharacters(ORIGINAL);\n }\n\n var sourceArray = alphabet.split('');\n var targetArray = [];\n var r = randomFromSeed.nextValue();\n var characterIndex;\n\n while (sourceArray.length > 0) {\n r = randomFromSeed.nextValue();\n characterIndex = Math.floor(r * sourceArray.length);\n targetArray.push(sourceArray.splice(characterIndex, 1)[0]);\n }\n return targetArray.join('');\n}\n\nfunction getShuffled() {\n if (shuffled) {\n return shuffled;\n }\n shuffled = shuffle();\n return shuffled;\n}\n\n/**\n * lookup shuffled letter\n * @param index\n * @returns {string}\n */\nfunction lookup(index) {\n var alphabetShuffled = getShuffled();\n return alphabetShuffled[index];\n}\n\nmodule.exports = {\n characters: characters,\n seed: setSeed,\n lookup: lookup,\n shuffled: getShuffled\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/alphabet.js\n ** module id = 37\n ** module chunks = 0\n **/","'use strict';\n\n// Found this seed-based random generator somewhere\n// Based on The Central Randomizer 1.3 (C) 1997 by Paul Houle (houle@msc.cornell.edu)\n\nvar seed = 1;\n\n/**\n * return a random number based on a seed\n * @param seed\n * @returns {number}\n */\nfunction getNextValue() {\n seed = (seed * 9301 + 49297) % 233280;\n return seed/(233280.0);\n}\n\nfunction setSeed(_seed_) {\n seed = _seed_;\n}\n\nmodule.exports = {\n nextValue: getNextValue,\n seed: setSeed\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/random/random-from-seed.js\n ** module id = 38\n ** module chunks = 0\n **/","'use strict';\n\nvar randomByte = require('./random/random-byte');\n\nfunction encode(lookup, number) {\n var loopCounter = 0;\n var done;\n\n var str = '';\n\n while (!done) {\n str = str + lookup( ( (number >> (4 * loopCounter)) & 0x0f ) | randomByte() );\n done = number < (Math.pow(16, loopCounter + 1 ) );\n loopCounter++;\n }\n return str;\n}\n\nmodule.exports = encode;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/encode.js\n ** module id = 39\n ** module chunks = 0\n **/","'use strict';\n\nvar crypto = typeof window === 'object' && (window.crypto || window.msCrypto); // IE 11 uses window.msCrypto\n\nfunction randomByte() {\n if (!crypto || !crypto.getRandomValues) {\n return Math.floor(Math.random() * 256) & 0x30;\n }\n var dest = new Uint8Array(1);\n crypto.getRandomValues(dest);\n return dest[0] & 0x30;\n}\n\nmodule.exports = randomByte;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/random/random-byte-browser.js\n ** module id = 40\n ** module chunks = 0\n **/","'use strict';\nvar alphabet = require('./alphabet');\n\n/**\n * Decode the id to get the version and worker\n * Mainly for debugging and testing.\n * @param id - the shortid-generated id.\n */\nfunction decode(id) {\n var characters = alphabet.shuffled();\n return {\n version: characters.indexOf(id.substr(0, 1)) & 0x0f,\n worker: characters.indexOf(id.substr(1, 1)) & 0x0f\n };\n}\n\nmodule.exports = decode;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/decode.js\n ** module id = 41\n ** module chunks = 0\n **/","'use strict';\nvar alphabet = require('./alphabet');\n\nfunction isShortId(id) {\n if (!id || typeof id !== 'string' || id.length < 6 ) {\n return false;\n }\n\n var characters = alphabet.characters();\n var len = id.length;\n for(var i = 0; i < len;i++) {\n if (characters.indexOf(id[i]) === -1) {\n return false;\n }\n }\n return true;\n}\n\nmodule.exports = isShortId;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/is-valid.js\n ** module id = 42\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = 0;\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/shortid/lib/util/cluster-worker-id-browser.js\n ** module id = 43\n ** module chunks = 0\n **/","import THREE from 'three';\nimport Sky from './Sky';\nimport throttle from 'lodash.throttle';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\nvar cubemap = {\n vertexShader: [\n\t\t'varying vec3 vPosition;',\n\t\t'void main() {',\n\t\t\t'vPosition = position;',\n\t\t\t'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\t\t'}'\n\t].join('\\n'),\n\n fragmentShader: [\n 'uniform samplerCube cubemap;',\n 'varying vec3 vPosition;',\n\n 'void main() {',\n 'gl_FragColor = textureCube(cubemap, normalize(vPosition));',\n '}'\n ].join('\\n')\n};\n\nclass Skybox {\n constructor(world, light) {\n this._world = world;\n this._light = light;\n\n this._settings = {\n distance: 38000,\n turbidity: 10,\n reileigh: 2,\n mieCoefficient: 0.005,\n mieDirectionalG: 0.8,\n luminance: 1,\n // 0.48 is a cracking dusk / sunset\n // 0.4 is a beautiful early-morning / late-afternoon\n // 0.2 is a nice day time\n inclination: 0.48, // Elevation / inclination\n azimuth: 0.25, // Facing front\n };\n\n this._initSkybox();\n this._updateUniforms();\n this._initEvents();\n }\n\n _initEvents() {\n // Throttled to 1 per 100ms\n this._throttledWorldUpdate = throttle(this._update, 100);\n this._world.on('preUpdate', this._throttledWorldUpdate, this);\n }\n\n _initSkybox() {\n // Cube camera for skybox\n this._cubeCamera = new THREE.CubeCamera(1, 20000000, 128);\n\n // Cube material\n var cubeTarget = this._cubeCamera.renderTarget;\n\n // Add Sky Mesh\n this._sky = new Sky();\n this._skyScene = new THREE.Scene();\n this._skyScene.add(this._sky.mesh);\n\n // Add Sun Helper\n this._sunSphere = new THREE.Mesh(\n new THREE.SphereBufferGeometry(2000, 16, 8),\n new THREE.MeshBasicMaterial({\n color: 0xffffff\n })\n );\n\n // TODO: This isn't actually visible because it's not added to the layer\n // this._sunSphere.visible = true;\n\n var skyboxUniforms = {\n cubemap: { type: 't', value: cubeTarget }\n };\n\n var skyboxMat = new THREE.ShaderMaterial({\n uniforms: skyboxUniforms,\n vertexShader: cubemap.vertexShader,\n fragmentShader: cubemap.fragmentShader,\n side: THREE.BackSide\n });\n\n this._mesh = new THREE.Mesh(new THREE.BoxGeometry(1900000, 1900000, 1900000), skyboxMat);\n\n this._updateSkybox = true;\n }\n\n _updateUniforms() {\n var settings = this._settings;\n var uniforms = this._sky.uniforms;\n uniforms.turbidity.value = settings.turbidity;\n uniforms.reileigh.value = settings.reileigh;\n uniforms.luminance.value = settings.luminance;\n uniforms.mieCoefficient.value = settings.mieCoefficient;\n uniforms.mieDirectionalG.value = settings.mieDirectionalG;\n\n var theta = Math.PI * (settings.inclination - 0.5);\n var phi = 2 * Math.PI * (settings.azimuth - 0.5);\n\n this._sunSphere.position.x = settings.distance * Math.cos(phi);\n this._sunSphere.position.y = settings.distance * Math.sin(phi) * Math.sin(theta);\n this._sunSphere.position.z = settings.distance * Math.sin(phi) * Math.cos(theta);\n\n // Move directional light to sun position\n this._light.position.copy(this._sunSphere.position);\n\n this._sky.uniforms.sunPosition.value.copy(this._sunSphere.position);\n }\n\n _update(delta) {\n if (this._updateSkybox) {\n this._updateSkybox = false;\n } else {\n return;\n }\n\n // if (!this._angle) {\n // this._angle = 0;\n // }\n //\n // // Animate inclination\n // this._angle += Math.PI * delta;\n // this._settings.inclination = 0.5 * (Math.sin(this._angle) / 2 + 0.5);\n\n // Update light intensity depending on elevation of sun (day to night)\n this._light.intensity = 1 - 0.95 * (this._settings.inclination / 0.5);\n\n // // console.log(delta, this._angle, this._settings.inclination);\n //\n // TODO: Only do this when the uniforms have been changed\n this._updateUniforms();\n\n // TODO: Only do this when the cubemap has actually changed\n this._cubeCamera.updateCubeMap(this._world._engine._renderer, this._skyScene);\n }\n\n getRenderTarget() {\n return this._cubeCamera.renderTarget;\n }\n\n setInclination(inclination) {\n this._settings.inclination = inclination;\n this._updateSkybox = true;\n }\n\n // Destroy the skybox and remove it from memory\n destroy() {\n this._world.off('preUpdate', this._throttledWorldUpdate);\n this._throttledWorldUpdate = null;\n\n this._world = null;\n this._light = null;\n\n this._cubeCamera = null;\n\n this._sky.mesh.geometry.dispose();\n this._sky.mesh.geometry = null;\n\n if (this._sky.mesh.material.map) {\n this._sky.mesh.material.map.dispose();\n this._sky.mesh.material.map = null;\n }\n\n this._sky.mesh.material.dispose();\n this._sky.mesh.material = null;\n\n this._sky.mesh = null;\n this._sky = null;\n\n this._skyScene = null;\n\n this._sunSphere.geometry.dispose();\n this._sunSphere.geometry = null;\n\n if (this._sunSphere.material.map) {\n this._sunSphere.material.map.dispose();\n this._sunSphere.material.map = null;\n }\n\n this._sunSphere.material.dispose();\n this._sunSphere.material = null;\n\n this._sunSphere = null;\n\n this._mesh.geometry.dispose();\n this._mesh.geometry = null;\n\n if (this._mesh.material.map) {\n this._mesh.material.map.dispose();\n this._mesh.material.map = null;\n }\n\n this._mesh.material.dispose();\n this._mesh.material = null;\n }\n}\n\nexport default Skybox;\n\nvar noNew = function(world, light) {\n return new Skybox(world, light);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as skybox};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/environment/Skybox.js\n **/","// jscs:disable\n/*eslint eqeqeq:0*/\n\n/**\n * @author zz85 / https://github.com/zz85\n *\n * Based on 'A Practical Analytic Model for Daylight'\n * aka The Preetham Model, the de facto standard analytic skydome model\n * http://www.cs.utah.edu/~shirley/papers/sunsky/sunsky.pdf\n *\n * First implemented by Simon Wallner\n * http://www.simonwallner.at/projects/atmospheric-scattering\n *\n * Improved by Martin Upitis\n * http://blenderartists.org/forum/showthread.php?245954-preethams-sky-impementation-HDR\n *\n * Three.js integration by zz85 http://twitter.com/blurspline\n*/\n\nimport THREE from 'three';\n\nTHREE.ShaderLib[ 'sky' ] = {\n\n\tuniforms: {\n\n\t\tluminance:\t { type: 'f', value: 1 },\n\t\tturbidity:\t { type: 'f', value: 2 },\n\t\treileigh:\t { type: 'f', value: 1 },\n\t\tmieCoefficient:\t { type: 'f', value: 0.005 },\n\t\tmieDirectionalG: { type: 'f', value: 0.8 },\n\t\tsunPosition: \t { type: 'v3', value: new THREE.Vector3() }\n\n\t},\n\n\tvertexShader: [\n\n\t\t'varying vec3 vWorldPosition;',\n\n\t\t'void main() {',\n\n\t\t\t'vec4 worldPosition = modelMatrix * vec4( position, 1.0 );',\n\t\t\t'vWorldPosition = worldPosition.xyz;',\n\n\t\t\t'gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\n\t\t'}',\n\n\t].join( '\\n' ),\n\n\tfragmentShader: [\n\n\t\t'uniform sampler2D skySampler;',\n\t\t'uniform vec3 sunPosition;',\n\t\t'varying vec3 vWorldPosition;',\n\n\t\t'vec3 cameraPos = vec3(0., 0., 0.);',\n\t\t'// uniform sampler2D sDiffuse;',\n\t\t'// const float turbidity = 10.0; //',\n\t\t'// const float reileigh = 2.; //',\n\t\t'// const float luminance = 1.0; //',\n\t\t'// const float mieCoefficient = 0.005;',\n\t\t'// const float mieDirectionalG = 0.8;',\n\n\t\t'uniform float luminance;',\n\t\t'uniform float turbidity;',\n\t\t'uniform float reileigh;',\n\t\t'uniform float mieCoefficient;',\n\t\t'uniform float mieDirectionalG;',\n\n\t\t'// constants for atmospheric scattering',\n\t\t'const float e = 2.71828182845904523536028747135266249775724709369995957;',\n\t\t'const float pi = 3.141592653589793238462643383279502884197169;',\n\n\t\t'const float n = 1.0003; // refractive index of air',\n\t\t'const float N = 2.545E25; // number of molecules per unit volume for air at',\n\t\t\t\t\t\t\t\t'// 288.15K and 1013mb (sea level -45 celsius)',\n\t\t'const float pn = 0.035;\t// depolatization factor for standard air',\n\n\t\t'// wavelength of used primaries, according to preetham',\n\t\t'const vec3 lambda = vec3(680E-9, 550E-9, 450E-9);',\n\n\t\t'// mie stuff',\n\t\t'// K coefficient for the primaries',\n\t\t'const vec3 K = vec3(0.686, 0.678, 0.666);',\n\t\t'const float v = 4.0;',\n\n\t\t'// optical length at zenith for molecules',\n\t\t'const float rayleighZenithLength = 8.4E3;',\n\t\t'const float mieZenithLength = 1.25E3;',\n\t\t'const vec3 up = vec3(0.0, 1.0, 0.0);',\n\n\t\t'const float EE = 1000.0;',\n\t\t'const float sunAngularDiameterCos = 0.999956676946448443553574619906976478926848692873900859324;',\n\t\t'// 66 arc seconds -> degrees, and the cosine of that',\n\n\t\t'// earth shadow hack',\n\t\t'const float cutoffAngle = pi/1.95;',\n\t\t'const float steepness = 1.5;',\n\n\n\t\t'vec3 totalRayleigh(vec3 lambda)',\n\t\t'{',\n\t\t\t'return (8.0 * pow(pi, 3.0) * pow(pow(n, 2.0) - 1.0, 2.0) * (6.0 + 3.0 * pn)) / (3.0 * N * pow(lambda, vec3(4.0)) * (6.0 - 7.0 * pn));',\n\t\t'}',\n\n\t\t// see http://blenderartists.org/forum/showthread.php?321110-Shaders-and-Skybox-madness\n\t\t'// A simplied version of the total Reayleigh scattering to works on browsers that use ANGLE',\n\t\t'vec3 simplifiedRayleigh()',\n\t\t'{',\n\t\t\t'return 0.0005 / vec3(94, 40, 18);',\n\t\t\t// return 0.00054532832366 / (3.0 * 2.545E25 * pow(vec3(680E-9, 550E-9, 450E-9), vec3(4.0)) * 6.245);\n\t\t'}',\n\n\t\t'float rayleighPhase(float cosTheta)',\n\t\t'{\t ',\n\t\t\t'return (3.0 / (16.0*pi)) * (1.0 + pow(cosTheta, 2.0));',\n\t\t'//\treturn (1.0 / (3.0*pi)) * (1.0 + pow(cosTheta, 2.0));',\n\t\t'//\treturn (3.0 / 4.0) * (1.0 + pow(cosTheta, 2.0));',\n\t\t'}',\n\n\t\t'vec3 totalMie(vec3 lambda, vec3 K, float T)',\n\t\t'{',\n\t\t\t'float c = (0.2 * T ) * 10E-18;',\n\t\t\t'return 0.434 * c * pi * pow((2.0 * pi) / lambda, vec3(v - 2.0)) * K;',\n\t\t'}',\n\n\t\t'float hgPhase(float cosTheta, float g)',\n\t\t'{',\n\t\t\t'return (1.0 / (4.0*pi)) * ((1.0 - pow(g, 2.0)) / pow(1.0 - 2.0*g*cosTheta + pow(g, 2.0), 1.5));',\n\t\t'}',\n\n\t\t'float sunIntensity(float zenithAngleCos)',\n\t\t'{',\n\t\t\t'return EE * max(0.0, 1.0 - exp(-((cutoffAngle - acos(zenithAngleCos))/steepness)));',\n\t\t'}',\n\n\t\t'// float logLuminance(vec3 c)',\n\t\t'// {',\n\t\t'// \treturn log(c.r * 0.2126 + c.g * 0.7152 + c.b * 0.0722);',\n\t\t'// }',\n\n\t\t'// Filmic ToneMapping http://filmicgames.com/archives/75',\n\t\t'float A = 0.15;',\n\t\t'float B = 0.50;',\n\t\t'float C = 0.10;',\n\t\t'float D = 0.20;',\n\t\t'float E = 0.02;',\n\t\t'float F = 0.30;',\n\t\t'float W = 1000.0;',\n\n\t\t'vec3 Uncharted2Tonemap(vec3 x)',\n\t\t'{',\n\t\t 'return ((x*(A*x+C*B)+D*E)/(x*(A*x+B)+D*F))-E/F;',\n\t\t'}',\n\n\n\t\t'void main() ',\n\t\t'{',\n\t\t\t'float sunfade = 1.0-clamp(1.0-exp((sunPosition.y/450000.0)),0.0,1.0);',\n\n\t\t\t'// luminance = 1.0 ;// vWorldPosition.y / 450000. + 0.5; //sunPosition.y / 450000. * 1. + 0.5;',\n\n\t\t\t '// gl_FragColor = vec4(sunfade, sunfade, sunfade, 1.0);',\n\n\t\t\t'float reileighCoefficient = reileigh - (1.0* (1.0-sunfade));',\n\n\t\t\t'vec3 sunDirection = normalize(sunPosition);',\n\n\t\t\t'float sunE = sunIntensity(dot(sunDirection, up));',\n\n\t\t\t'// extinction (absorbtion + out scattering) ',\n\t\t\t'// rayleigh coefficients',\n\n\t\t\t// 'vec3 betaR = totalRayleigh(lambda) * reileighCoefficient;',\n\t\t\t'vec3 betaR = simplifiedRayleigh() * reileighCoefficient;',\n\n\t\t\t'// mie coefficients',\n\t\t\t'vec3 betaM = totalMie(lambda, K, turbidity) * mieCoefficient;',\n\n\t\t\t'// optical length',\n\t\t\t'// cutoff angle at 90 to avoid singularity in next formula.',\n\t\t\t'float zenithAngle = acos(max(0.0, dot(up, normalize(vWorldPosition - cameraPos))));',\n\t\t\t'float sR = rayleighZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));',\n\t\t\t'float sM = mieZenithLength / (cos(zenithAngle) + 0.15 * pow(93.885 - ((zenithAngle * 180.0) / pi), -1.253));',\n\n\n\n\t\t\t'// combined extinction factor\t',\n\t\t\t'vec3 Fex = exp(-(betaR * sR + betaM * sM));',\n\n\t\t\t'// in scattering',\n\t\t\t'float cosTheta = dot(normalize(vWorldPosition - cameraPos), sunDirection);',\n\n\t\t\t'float rPhase = rayleighPhase(cosTheta*0.5+0.5);',\n\t\t\t'vec3 betaRTheta = betaR * rPhase;',\n\n\t\t\t'float mPhase = hgPhase(cosTheta, mieDirectionalG);',\n\t\t\t'vec3 betaMTheta = betaM * mPhase;',\n\n\n\t\t\t'vec3 Lin = pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * (1.0 - Fex),vec3(1.5));',\n\t\t\t'Lin *= mix(vec3(1.0),pow(sunE * ((betaRTheta + betaMTheta) / (betaR + betaM)) * Fex,vec3(1.0/2.0)),clamp(pow(1.0-dot(up, sunDirection),5.0),0.0,1.0));',\n\n\t\t\t'//nightsky',\n\t\t\t'vec3 direction = normalize(vWorldPosition - cameraPos);',\n\t\t\t'float theta = acos(direction.y); // elevation --> y-axis, [-pi/2, pi/2]',\n\t\t\t'float phi = atan(direction.z, direction.x); // azimuth --> x-axis [-pi/2, pi/2]',\n\t\t\t'vec2 uv = vec2(phi, theta) / vec2(2.0*pi, pi) + vec2(0.5, 0.0);',\n\t\t\t'// vec3 L0 = texture2D(skySampler, uv).rgb+0.1 * Fex;',\n\t\t\t'vec3 L0 = vec3(0.1) * Fex;',\n\n\t\t\t'// composition + solar disc',\n\t\t\t'//if (cosTheta > sunAngularDiameterCos)',\n\t\t\t'float sundisk = smoothstep(sunAngularDiameterCos,sunAngularDiameterCos+0.00002,cosTheta);',\n\t\t\t'// if (normalize(vWorldPosition - cameraPos).y>0.0)',\n\t\t\t'L0 += (sunE * 19000.0 * Fex)*sundisk;',\n\n\n\t\t\t'vec3 whiteScale = 1.0/Uncharted2Tonemap(vec3(W));',\n\n\t\t\t'vec3 texColor = (Lin+L0); ',\n\t\t\t'texColor *= 0.04 ;',\n\t\t\t'texColor += vec3(0.0,0.001,0.0025)*0.3;',\n\n\t\t\t'float g_fMaxLuminance = 1.0;',\n\t\t\t'float fLumScaled = 0.1 / luminance; ',\n\t\t\t'float fLumCompressed = (fLumScaled * (1.0 + (fLumScaled / (g_fMaxLuminance * g_fMaxLuminance)))) / (1.0 + fLumScaled); ',\n\n\t\t\t'float ExposureBias = fLumCompressed;',\n\n\t\t\t'vec3 curr = Uncharted2Tonemap((log2(2.0/pow(luminance,4.0)))*texColor);',\n\t\t\t'vec3 color = curr*whiteScale;',\n\n\t\t\t'vec3 retColor = pow(color,vec3(1.0/(1.2+(1.2*sunfade))));',\n\n\n\t\t\t'gl_FragColor.rgb = retColor;',\n\n\t\t\t'gl_FragColor.a = 1.0;',\n\t\t'}',\n\n\t].join( '\\n' )\n\n};\n\nvar Sky = function () {\n\n\tvar skyShader = THREE.ShaderLib[ 'sky' ];\n\tvar skyUniforms = THREE.UniformsUtils.clone( skyShader.uniforms );\n\n\tvar skyMat = new THREE.ShaderMaterial( {\n\t\tfragmentShader: skyShader.fragmentShader,\n\t\tvertexShader: skyShader.vertexShader,\n\t\tuniforms: skyUniforms,\n\t\tside: THREE.BackSide\n\t} );\n\n\tvar skyGeo = new THREE.SphereBufferGeometry( 450000, 32, 15 );\n\tvar skyMesh = new THREE.Mesh( skyGeo, skyMat );\n\n\n\t// Expose variables\n\tthis.mesh = skyMesh;\n\tthis.uniforms = skyUniforms;\n\n};\n\nexport default Sky;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/environment/Sky.js\n **/","import WorkerPool from './WorkerPool';\n\nvar Worker = (function() {\n var _maxWorkers = 2;\n var pool;\n\n var createWorkers = function(maxWorkers, workerScript) {\n pool = new WorkerPool({\n numThreads: (maxWorkers) ? maxWorkers : _maxWorkers,\n workerScript: (workerScript) ? workerScript : 'vizicities-worker.js'\n });\n\n return pool.createWorkers();\n };\n\n var exec = function(method, args, transferrables) {\n return pool.exec(method, args, transferrables);\n };\n\n return {\n createWorkers: createWorkers,\n exec: exec\n };\n})();\n\nexport default Worker;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Worker.js\n **/","import WorkerPoolWorker from './WorkerPoolWorker';\n\nconst DEBUG = false;\n\nclass WorkerPool {\n constructor(options) {\n this.numThreads = options.numThreads || 2;\n this.workerScript = options.workerScript;\n\n this.workers = [];\n this.tasks = [];\n }\n\n createWorkers() {\n return new Promise((resolve, reject) => {\n var workerPromises = [];\n\n for (var i = 0; i < this.numThreads; i++) {\n workerPromises.push(this.createWorker());\n }\n\n Promise.all(workerPromises).then(() => {\n if (DEBUG) { console.log('All workers ready', performance.now()); }\n resolve();\n }).catch(reject);\n });\n }\n\n createWorker() {\n return new Promise((resolve, reject) => {\n // Initialise worker\n var worker = new WorkerPoolWorker({\n workerScript: this.workerScript\n });\n\n // Start worker and wait for it to be ready\n return worker.start().then(() => {\n if (DEBUG) { console.log('Worker ready', performance.now()); }\n\n // Add worker to pool\n this.workers.push(worker);\n\n resolve();\n }).catch(reject);\n });\n }\n\n getFreeWorker() {\n return this.workers.find((worker) => {\n return !worker.busy;\n });\n }\n\n // Execute task on a worker\n exec(method, args, transferrables) {\n var deferred = Promise.deferred();\n\n // Create task\n var task = {\n method: method,\n args: args,\n transferrables: transferrables,\n deferred: deferred\n };\n\n // Add task to queue\n this.tasks.push(task);\n\n // Trigger task processing\n this.processTasks();\n\n // Return task promise\n return task.deferred.promise;\n }\n\n processTasks() {\n if (DEBUG) { console.log('Processing tasks'); }\n\n if (this.tasks.length === 0) {\n return;\n }\n\n // Find free worker\n var worker = this.getFreeWorker();\n\n if (!worker) {\n if (DEBUG) { console.log('No workers free'); }\n return;\n }\n\n // Get oldest task\n var task = this.tasks.shift();\n\n // Execute task on worker\n worker.exec(task.method, task.args, task.transferrables).then((result) => {\n // Trigger task processing\n this.processTasks();\n\n // Return result in deferred task promise\n task.deferred.resolve(result);\n });\n }\n}\n\nexport default WorkerPool;\n\n// Quick shim to create deferred native promises\nPromise.deferred = function() {\n var result = {};\n\n result.promise = new Promise((resolve, reject) => {\n result.resolve = resolve;\n result.reject = reject;\n });\n\n return result;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/WorkerPool.js\n **/","const DEBUG = false;\n\nclass WorkerPoolWorker {\n constructor(options) {\n this.workerScript = options.workerScript;\n\n this.ready = false;\n this.busy = false;\n this.deferred = null;\n }\n\n start() {\n return new Promise((resolve, reject) => {\n this.worker = new Worker(this.workerScript);\n\n var onStartup = (event) => {\n if (!event.data || event.data.type !== 'startup') {\n reject();\n return;\n }\n\n this.ready = true;\n\n // Remove temporary message handler\n this.worker.removeEventListener('message', onStartup);\n\n // Set up listener to respond to normal events now\n this.worker.addEventListener('message', (event) => {\n this.onMessage(event);\n });\n\n // Resolve once worker is ready\n resolve();\n };\n\n // Set up temporary event listener for warmup\n this.worker.addEventListener('message', onStartup);\n });\n }\n\n exec(method, args, transferrables) {\n if (DEBUG) { console.log('Execute', method, args, transferrables); }\n\n var deferred = Promise.deferred();\n\n this.busy = true;\n this.deferred = deferred;\n\n this.worker.postMessage({\n method: method,\n args: args\n }, transferrables);\n\n return deferred.promise;\n }\n\n onMessage(event) {\n console.log('Message received from worker', performance.now());\n\n this.busy = false;\n\n if (!event.data || event.data.type === 'error' || event.data.type !== 'result') {\n this.deferred.reject(event.data.payload);\n return;\n }\n\n this.deferred.resolve(event.data.payload);\n }\n}\n\nexport default WorkerPoolWorker;\n\n// Quick shim to create deferred native promises\nPromise.deferred = function() {\n var result = {};\n\n result.promise = new Promise((resolve, reject) => {\n result.resolve = resolve;\n result.reject = reject;\n });\n\n return result;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/WorkerPoolWorker.js\n **/","import Orbit, {orbit} from './Controls.Orbit';\n\nconst Controls = {\n Orbit: Orbit,\n orbit, orbit\n};\n\nexport default Controls;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/controls/index.js\n **/","import EventEmitter from 'eventemitter3';\nimport THREE from 'three';\nimport OrbitControls from '../vendor/OrbitControls';\nimport TweenLite from 'TweenLite';\n\nclass Orbit extends EventEmitter {\n constructor() {\n super();\n\n // Prevent animation from pausing when tab is inactive\n TweenLite.lagSmoothing(0);\n }\n\n // Proxy control events\n //\n // There's currently no distinction between pan, orbit and zoom events\n _initEvents() {\n this._controls.addEventListener('start', (event) => {\n this._world.emit('controlsMoveStart', event.target.target);\n });\n\n this._controls.addEventListener('change', (event) => {\n this._world.emit('controlsMove', event.target.target);\n });\n\n this._controls.addEventListener('end', (event) => {\n this._world.emit('controlsMoveEnd', event.target.target);\n });\n }\n\n // Moving the camera along the [x,y,z] axis based on a target position\n panTo(point, animate) {}\n panBy(pointDelta, animate) {}\n\n // Zooming the camera in and out\n zoomTo(metres, animate) {}\n zoomBy(metresDelta, animate) {}\n\n // Force camera to look at something other than the target\n lookAt(point, animate) {}\n\n // Make camera look at the target\n lookAtTarget() {}\n\n // Tilt (up and down)\n tiltTo(angle, animate) {}\n tiltBy(angleDelta, animate) {}\n\n // Rotate (left and right)\n rotateTo(angle, animate) {}\n rotateBy(angleDelta, animate) {}\n\n // Fly to the given point, animating pan and tilt/rotation to final position\n // with nice zoom out and in\n //\n // TODO: Calling flyTo a second time before the previous animation has\n // completed should immediately start the new animation from wherever the\n // previous one has got to\n //\n // TODO: Long-distance pans should prevent the quadtree grid from trying to\n // update by not firing the control update events every frame until the\n // pan velocity calms down a bit\n //\n // TODO: Long-distance plans should zoom out further\n //\n // TODO: Return a promise?\n flyToPoint(point, duration, zoom) {\n // Animation time in seconds\n var animationTime = duration || 2;\n\n this._flyTarget = new THREE.Vector3(point.x, 0, point.y);\n\n // Calculate delta from current position to fly target\n var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);\n\n this._flyTween = new TweenLite(\n {\n x: 0,\n z: 0,\n // zoom: 0,\n prev: {\n x: 0,\n z: 0\n }\n },\n animationTime,\n {\n x: diff.x,\n z: diff.z,\n // zoom: 1,\n onUpdate: function(tween) {\n var controls = this._controls;\n\n // Work out difference since last frame\n var deltaX = tween.target.x - tween.target.prev.x;\n var deltaZ = tween.target.z - tween.target.prev.z;\n\n // Move some fraction toward the target point\n controls.panLeft(deltaX, controls.object.matrix);\n controls.panUp(deltaZ, controls.object.matrix);\n\n tween.target.prev.x = tween.target.x;\n tween.target.prev.z = tween.target.z;\n\n // console.log(Math.sin((tween.target.zoom - 0.5) * Math.PI));\n\n // TODO: Get zoom to dolly in and out on pan\n // controls.object.zoom -= Math.sin((tween.target.zoom - 0.5) * Math.PI);\n // controls.object.updateProjectionMatrix();\n },\n onComplete: function(tween) {\n // console.log(`Arrived at flyTarget`);\n this._flyTarget = null;\n },\n onUpdateParams: ['{self}'],\n onCompleteParams: ['{self}'],\n callbackScope: this,\n ease: Power1.easeInOut\n }\n );\n\n if (!zoom) {\n return;\n }\n\n var zoomTime = animationTime / 2;\n\n this._zoomTweenIn = new TweenLite(\n {\n zoom: 0\n },\n zoomTime,\n {\n zoom: 1,\n onUpdate: function(tween) {\n var controls = this._controls;\n controls.dollyIn(1 - 0.01 * tween.target.zoom);\n },\n onComplete: function(tween) {},\n onUpdateParams: ['{self}'],\n onCompleteParams: ['{self}'],\n callbackScope: this,\n ease: Power1.easeInOut\n }\n );\n\n this._zoomTweenOut = new TweenLite(\n {\n zoom: 0\n },\n zoomTime,\n {\n zoom: 1,\n delay: zoomTime,\n onUpdate: function(tween) {\n var controls = this._controls;\n controls.dollyOut(0.99 + 0.01 * tween.target.zoom);\n },\n onComplete: function(tween) {},\n onUpdateParams: ['{self}'],\n onCompleteParams: ['{self}'],\n callbackScope: this,\n ease: Power1.easeInOut\n }\n );\n }\n\n // TODO: Return a promise?\n flyToLatLon(latlon, duration, noZoom) {\n var point = this._world.latLonToPoint(latlon);\n this.flyToPoint(point, duration, noZoom);\n }\n\n // TODO: Make this animate over a user-defined period of time\n //\n // Perhaps use TweenMax for now and implement as a more lightweight solution\n // later on once it all works\n // _animateFlyTo(delta) {\n // var controls = this._controls;\n //\n // // this._controls.panLeft(50, controls._controls.object.matrix);\n // // this._controls.panUp(50, controls._controls.object.matrix);\n // // this._controls.dollyIn(this._controls.getZoomScale());\n // // this._controls.dollyOut(this._controls.getZoomScale());\n //\n // // Calculate delta from current position to fly target\n // var diff = new THREE.Vector3().subVectors(this._controls.target, this._flyTarget);\n //\n // // 1000 units per second\n // var speed = 1000 * (delta / 1000);\n //\n // // Remove fly target after arrival and snap to target\n // if (diff.length() < 0.01) {\n // console.log(`Arrived at flyTarget`);\n // this._flyTarget = null;\n // speed = 1;\n // }\n //\n // // Move some fraction toward the target point\n // controls.panLeft(diff.x * speed, controls.object.matrix);\n // controls.panUp(diff.z * speed, controls.object.matrix);\n // }\n\n // Proxy to OrbitControls.update()\n update(delta) {\n this._controls.update(delta);\n }\n\n // Add controls to world instance and store world reference\n addTo(world) {\n return world.addControls(this);\n }\n\n // Internal method called by World.addControls to actually add the controls\n _addToWorld(world) {\n this._world = world;\n\n // TODO: Override panLeft and panUp methods to prevent panning on Y axis\n // See: http://stackoverflow.com/a/26188674/997339\n this._controls = new OrbitControls(world._engine._camera, world._container);\n\n // Disable keys for now as no events are fired for them anyway\n this._controls.keys = false;\n\n // 89 degrees\n this._controls.maxPolarAngle = 1.5533;\n\n // this._controls.enableDamping = true;\n // this._controls.dampingFactor = 0.25;\n\n this._initEvents();\n\n // TODO: Remove now that this is a promise?\n this.emit('added');\n\n return Promise.resolve(this);\n }\n\n // Destroys the controls and removes them from memory\n destroy() {\n // TODO: Remove event listeners\n\n this._controls.dispose();\n\n this._world = null;\n this._controls = null;\n }\n}\n\nexport default Orbit;\n\nvar noNew = function() {\n return new Orbit();\n};\n\n// Initialise without requiring new keyword\nexport {noNew as orbit};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/controls/Controls.Orbit.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\nimport Hammer from 'hammerjs';\n\n/**\n * @author qiao / https://github.com/qiao\n * @author mrdoob / http://mrdoob.com\n * @author alteredq / http://alteredqualia.com/\n * @author WestLangley / http://github.com/WestLangley\n * @author erich666 / http://erichaines.com\n */\n\n// This set of controls performs orbiting, dollying (zooming), and panning.\n// Unlike TrackballControls, it maintains the \"up\" direction object.up (+Y by default).\n//\n// Orbit - left mouse / touch: one finger move\n// Zoom - middle mouse, or mousewheel / touch: two finger spread or squish\n// Pan - right mouse, or arrow keys / touch: three finter swipe\n\nvar OrbitControls = function ( object, domElement ) {\n\n\tthis.object = object;\n\n\tthis.domElement = ( domElement !== undefined ) ? domElement : document;\n\n\t// Set to false to disable this control\n\tthis.enabled = true;\n\n\t// \"target\" sets the location of focus, where the object orbits around\n\tthis.target = new THREE.Vector3();\n\n\t// How far you can dolly in and out ( PerspectiveCamera only )\n\tthis.minDistance = 0;\n\tthis.maxDistance = Infinity;\n\n\t// How far you can zoom in and out ( OrthographicCamera only )\n\tthis.minZoom = 0;\n\tthis.maxZoom = Infinity;\n\n\t// How far you can orbit vertically, upper and lower limits.\n\t// Range is 0 to Math.PI radians.\n\tthis.minPolarAngle = 0; // radians\n\tthis.maxPolarAngle = Math.PI; // radians\n\n\t// How far you can orbit horizontally, upper and lower limits.\n\t// If set, must be a sub-interval of the interval [ - Math.PI, Math.PI ].\n\tthis.minAzimuthAngle = - Infinity; // radians\n\tthis.maxAzimuthAngle = Infinity; // radians\n\n\t// Set to true to enable damping (inertia)\n\t// If damping is enabled, you must call controls.update() in your animation loop\n\tthis.enableDamping = false;\n\tthis.dampingFactor = 0.25;\n\n\t// This option actually enables dollying in and out; left as \"zoom\" for backwards compatibility.\n\t// Set to false to disable zooming\n\tthis.enableZoom = true;\n\tthis.zoomSpeed = 1.0;\n\n\t// Set to false to disable rotating\n\tthis.enableRotate = true;\n\tthis.rotateSpeed = 1.0;\n\n\t// Set to false to disable panning\n\tthis.enablePan = true;\n\tthis.keyPanSpeed = 7.0;\t// pixels moved per arrow key push\n\n\t// Set to true to automatically rotate around the target\n\t// If auto-rotate is enabled, you must call controls.update() in your animation loop\n\tthis.autoRotate = false;\n\tthis.autoRotateSpeed = 2.0; // 30 seconds per round when fps is 60\n\n\t// Set to false to disable use of the keys\n\tthis.enableKeys = true;\n\n\t// The four arrow keys\n\tthis.keys = { LEFT: 37, UP: 38, RIGHT: 39, BOTTOM: 40 };\n\n\t// Mouse buttons\n\tthis.mouseButtons = { ORBIT: THREE.MOUSE.LEFT, ZOOM: THREE.MOUSE.MIDDLE, PAN: THREE.MOUSE.RIGHT };\n\n\t// for reset\n\tthis.target0 = this.target.clone();\n\tthis.position0 = this.object.position.clone();\n\tthis.zoom0 = this.object.zoom;\n\n\t//\n\t// public methods\n\t//\n\n\tthis.getPolarAngle = function () {\n\n\t\treturn phi;\n\n\t};\n\n\tthis.getAzimuthalAngle = function () {\n\n\t\treturn theta;\n\n\t};\n\n\tthis.reset = function () {\n\n\t\tscope.target.copy( scope.target0 );\n\t\tscope.object.position.copy( scope.position0 );\n\t\tscope.object.zoom = scope.zoom0;\n\n\t\tscope.object.updateProjectionMatrix();\n\t\tscope.dispatchEvent( changeEvent );\n\n\t\tscope.update();\n\n\t\tstate = STATE.NONE;\n\n\t};\n\n\t// this method is exposed, but perhaps it would be better if we can make it private...\n\tthis.update = function() {\n\n\t\tvar offset = new THREE.Vector3();\n\n\t\t// so camera.up is the orbit axis\n\t\tvar quat = new THREE.Quaternion().setFromUnitVectors( object.up, new THREE.Vector3( 0, 1, 0 ) );\n\t\tvar quatInverse = quat.clone().inverse();\n\n\t\tvar lastPosition = new THREE.Vector3();\n\t\tvar lastQuaternion = new THREE.Quaternion();\n\n\t\treturn function () {\n\n\t\t\tvar position = scope.object.position;\n\n\t\t\toffset.copy( position ).sub( scope.target );\n\n\t\t\t// rotate offset to \"y-axis-is-up\" space\n\t\t\toffset.applyQuaternion( quat );\n\n\t\t\t// angle from z-axis around y-axis\n\n\t\t\ttheta = Math.atan2( offset.x, offset.z );\n\n\t\t\t// angle from y-axis\n\n\t\t\tphi = Math.atan2( Math.sqrt( offset.x * offset.x + offset.z * offset.z ), offset.y );\n\n\t\t\tif ( scope.autoRotate && state === STATE.NONE ) {\n\n\t\t\t\trotateLeft( getAutoRotationAngle() );\n\n\t\t\t}\n\n\t\t\ttheta += thetaDelta;\n\t\t\tphi += phiDelta;\n\n\t\t\t// restrict theta to be between desired limits\n\t\t\ttheta = Math.max( scope.minAzimuthAngle, Math.min( scope.maxAzimuthAngle, theta ) );\n\n\t\t\t// restrict phi to be between desired limits\n\t\t\tphi = Math.max( scope.minPolarAngle, Math.min( scope.maxPolarAngle, phi ) );\n\n\t\t\t// restrict phi to be betwee EPS and PI-EPS\n\t\t\tphi = Math.max( EPS, Math.min( Math.PI - EPS, phi ) );\n\n\t\t\tvar radius = offset.length() * scale;\n\n\t\t\t// restrict radius to be between desired limits\n\t\t\tradius = Math.max( scope.minDistance, Math.min( scope.maxDistance, radius ) );\n\n\t\t\t// move target to panned location\n\t\t\tscope.target.add( panOffset );\n\n\t\t\toffset.x = radius * Math.sin( phi ) * Math.sin( theta );\n\t\t\toffset.y = radius * Math.cos( phi );\n\t\t\toffset.z = radius * Math.sin( phi ) * Math.cos( theta );\n\n\t\t\t// rotate offset back to \"camera-up-vector-is-up\" space\n\t\t\toffset.applyQuaternion( quatInverse );\n\n\t\t\tposition.copy( scope.target ).add( offset );\n\n\t\t\tscope.object.lookAt( scope.target );\n\n\t\t\tif ( scope.enableDamping === true ) {\n\n\t\t\t\tthetaDelta *= ( 1 - scope.dampingFactor );\n\t\t\t\tphiDelta *= ( 1 - scope.dampingFactor );\n\n\t\t\t} else {\n\n\t\t\t\tthetaDelta = 0;\n\t\t\t\tphiDelta = 0;\n\n\t\t\t}\n\n\t\t\tscale = 1;\n\t\t\tpanOffset.set( 0, 0, 0 );\n\n\t\t\t// update condition is:\n\t\t\t// min(camera displacement, camera rotation in radians)^2 > EPS\n\t\t\t// using small-angle approximation cos(x/2) = 1 - x^2 / 8\n\n\t\t\tif ( zoomChanged ||\n\t\t\t\tlastPosition.distanceToSquared( scope.object.position ) > EPS ||\n\t\t\t\t8 * ( 1 - lastQuaternion.dot( scope.object.quaternion ) ) > EPS ) {\n\n\t\t\t\tscope.dispatchEvent( changeEvent );\n\n\t\t\t\tlastPosition.copy( scope.object.position );\n\t\t\t\tlastQuaternion.copy( scope.object.quaternion );\n\t\t\t\tzoomChanged = false;\n\n\t\t\t\treturn true;\n\n\t\t\t}\n\n\t\t\treturn false;\n\n\t\t};\n\n\t}();\n\n\tthis.dispose = function() {\n\n\t\tscope.domElement.removeEventListener( 'contextmenu', onContextMenu, false );\n\t\tscope.domElement.removeEventListener( 'mousedown', onMouseDown, false );\n\t\tscope.domElement.removeEventListener( 'mousewheel', onMouseWheel, false );\n\t\tscope.domElement.removeEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox\n\n\t\tscope.domElement.removeEventListener( 'touchstart', onTouchStart, false );\n\t\tscope.domElement.removeEventListener( 'touchend', onTouchEnd, false );\n\t\tscope.domElement.removeEventListener( 'touchmove', onTouchMove, false );\n\n\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\t\tdocument.removeEventListener( 'mouseout', onMouseUp, false );\n\n\t\twindow.removeEventListener( 'keydown', onKeyDown, false );\n\n\t\t//scope.dispatchEvent( { type: 'dispose' } ); // should this be added here?\n\n\t};\n\n\t//\n\t// internals\n\t//\n\n\tvar scope = this;\n\n\tvar changeEvent = { type: 'change' };\n\tvar startEvent = { type: 'start' };\n\tvar endEvent = { type: 'end' };\n\n\tvar STATE = { NONE : - 1, ROTATE : 0, DOLLY : 1, PAN : 2, TOUCH_ROTATE : 3, TOUCH_DOLLY : 4, TOUCH_PAN : 5 };\n\n\tvar state = STATE.NONE;\n\n\tvar EPS = 0.000001;\n\n\t// current position in spherical coordinates\n\tvar theta;\n\tvar phi;\n\n\tvar phiDelta = 0;\n\tvar thetaDelta = 0;\n\tvar scale = 1;\n\tvar panOffset = new THREE.Vector3();\n\tvar zoomChanged = false;\n\n\tvar rotateStart = new THREE.Vector2();\n\tvar rotateEnd = new THREE.Vector2();\n\tvar rotateDelta = new THREE.Vector2();\n\n\tvar panStart = new THREE.Vector2();\n\tvar panEnd = new THREE.Vector2();\n\tvar panDelta = new THREE.Vector2();\n\n\tvar dollyStart = new THREE.Vector2();\n\tvar dollyEnd = new THREE.Vector2();\n\tvar dollyDelta = new THREE.Vector2();\n\n\tfunction getAutoRotationAngle() {\n\n\t\treturn 2 * Math.PI / 60 / 60 * scope.autoRotateSpeed;\n\n\t}\n\n\tfunction getZoomScale() {\n\n\t\treturn Math.pow( 0.95, scope.zoomSpeed );\n\n\t}\n\n\tfunction rotateLeft( angle ) {\n\n\t\tthetaDelta -= angle;\n\n\t}\n\n\tfunction rotateUp( angle ) {\n\n\t\tphiDelta -= angle;\n\n\t}\n\n\tvar panLeft = function() {\n\n\t\tvar v = new THREE.Vector3();\n\n\t\t// return function panLeft( distance, objectMatrix ) {\n //\n\t\t// \tvar te = objectMatrix.elements;\n //\n\t\t// \t// get X column of objectMatrix\n\t\t// \tv.set( te[ 0 ], te[ 1 ], te[ 2 ] );\n //\n\t\t// \tv.multiplyScalar( - distance );\n //\n\t\t// \tpanOffset.add( v );\n //\n\t\t// };\n\n // Fixed panning to x/y plane\n return function panLeft(distance, objectMatrix) {\n\t var te = objectMatrix.elements;\n\t // var adjDist = distance / Math.cos(phi);\n\n\t v.set(te[ 0 ], 0, te[ 2 ]);\n\t v.multiplyScalar(-distance);\n\n\t panOffset.add(v);\n\t };\n\n\t}();\n\n // Fixed panning to x/y plane\n\tvar panUp = function() {\n\n\t\tvar v = new THREE.Vector3();\n\n\t\t// return function panUp( distance, objectMatrix ) {\n //\n\t\t// \tvar te = objectMatrix.elements;\n //\n\t\t// \t// get Y column of objectMatrix\n\t\t// \tv.set( te[ 4 ], te[ 5 ], te[ 6 ] );\n //\n\t\t// \tv.multiplyScalar( distance );\n //\n\t\t// \tpanOffset.add( v );\n //\n\t\t// };\n\n return function panUp(distance, objectMatrix) {\n\t var te = objectMatrix.elements;\n\t var adjDist = distance / Math.cos(phi);\n\n\t v.set(te[ 4 ], 0, te[ 6 ]);\n\t v.multiplyScalar(adjDist);\n\n\t panOffset.add(v);\n\t };\n\n\t}();\n\n\t// deltaX and deltaY are in pixels; right and down are positive\n\tvar pan = function() {\n\n\t\tvar offset = new THREE.Vector3();\n\n\t\treturn function( deltaX, deltaY ) {\n\n\t\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\t\t// perspective\n\t\t\t\tvar position = scope.object.position;\n\t\t\t\toffset.copy( position ).sub( scope.target );\n\t\t\t\tvar targetDistance = offset.length();\n\n\t\t\t\t// half of the fov is center to top of screen\n\t\t\t\ttargetDistance *= Math.tan( ( scope.object.fov / 2 ) * Math.PI / 180.0 );\n\n\t\t\t\t// we actually don't use screenWidth, since perspective camera is fixed to screen height\n\t\t\t\tpanLeft( 2 * deltaX * targetDistance / element.clientHeight, scope.object.matrix );\n\t\t\t\tpanUp( 2 * deltaY * targetDistance / element.clientHeight, scope.object.matrix );\n\n\t\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\t\t// orthographic\n\t\t\t\tpanLeft( deltaX * ( scope.object.right - scope.object.left ) / element.clientWidth, scope.object.matrix );\n\t\t\t\tpanUp( deltaY * ( scope.object.top - scope.object.bottom ) / element.clientHeight, scope.object.matrix );\n\n\t\t\t} else {\n\n\t\t\t\t// camera neither orthographic nor perspective\n\t\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - pan disabled.' );\n\t\t\t\tscope.enablePan = false;\n\n\t\t\t}\n\n\t\t};\n\n\t}();\n\n\tfunction dollyIn( dollyScale ) {\n\n\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\tscale /= dollyScale;\n\n\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom * dollyScale ) );\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tzoomChanged = true;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\tscope.enableZoom = false;\n\n\t\t}\n\n\t}\n\n\tfunction dollyOut( dollyScale ) {\n\n\t\tif ( scope.object instanceof THREE.PerspectiveCamera ) {\n\n\t\t\tscale *= dollyScale;\n\n\t\t} else if ( scope.object instanceof THREE.OrthographicCamera ) {\n\n\t\t\tscope.object.zoom = Math.max( scope.minZoom, Math.min( scope.maxZoom, scope.object.zoom / dollyScale ) );\n\t\t\tscope.object.updateProjectionMatrix();\n\t\t\tzoomChanged = true;\n\n\t\t} else {\n\n\t\t\tconsole.warn( 'WARNING: OrbitControls.js encountered an unknown camera type - dolly/zoom disabled.' );\n\t\t\tscope.enableZoom = false;\n\n\t\t}\n\n\t}\n\n\t//\n\t// event callbacks - update the object state\n\t//\n\n\tfunction handleMouseDownRotate( event ) {\n\n\t\t//console.log( 'handleMouseDownRotate' );\n\n\t\trotateStart.set( event.clientX, event.clientY );\n\n\t}\n\n\tfunction handleMouseDownDolly( event ) {\n\n\t\t//console.log( 'handleMouseDownDolly' );\n\n\t\tdollyStart.set( event.clientX, event.clientY );\n\n\t}\n\n\tfunction handleMouseDownPan( event ) {\n\n\t\t//console.log( 'handleMouseDownPan' );\n\n\t\tpanStart.set( event.clientX, event.clientY );\n\n\t}\n\n\tfunction handleMouseMoveRotate( event ) {\n\n\t\t//console.log( 'handleMouseMoveRotate' );\n\n\t\trotateEnd.set( event.clientX, event.clientY );\n\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t// rotating across whole screen goes 360 degrees around\n\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\trotateStart.copy( rotateEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleMouseMoveDolly( event ) {\n\n\t\t//console.log( 'handleMouseMoveDolly' );\n\n\t\tdollyEnd.set( event.clientX, event.clientY );\n\n\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\tdollyIn( getZoomScale() );\n\n\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\tdollyOut( getZoomScale() );\n\n\t\t}\n\n\t\tdollyStart.copy( dollyEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleMouseMovePan( event ) {\n\n\t\t//console.log( 'handleMouseMovePan' );\n\n\t\tpanEnd.set( event.clientX, event.clientY );\n\n\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\tpan( panDelta.x, panDelta.y );\n\n\t\tpanStart.copy( panEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleMouseUp( event ) {\n\n\t\t//console.log( 'handleMouseUp' );\n\n\t}\n\n\tfunction handleMouseWheel( event ) {\n\n\t\t//console.log( 'handleMouseWheel' );\n\n\t\tvar delta = 0;\n\n\t\tif ( event.wheelDelta !== undefined ) {\n\n\t\t\t// WebKit / Opera / Explorer 9\n\n\t\t\tdelta = event.wheelDelta;\n\n\t\t} else if ( event.detail !== undefined ) {\n\n\t\t\t// Firefox\n\n\t\t\tdelta = - event.detail;\n\n\t\t}\n\n\t\tif ( delta > 0 ) {\n\n\t\t\tdollyOut( getZoomScale() );\n\n\t\t} else if ( delta < 0 ) {\n\n\t\t\tdollyIn( getZoomScale() );\n\n\t\t}\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleKeyDown( event ) {\n\n\t\t//console.log( 'handleKeyDown' );\n\n\t\tswitch ( event.keyCode ) {\n\n\t\t\tcase scope.keys.UP:\n\t\t\t\tpan( 0, scope.keyPanSpeed );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.BOTTOM:\n\t\t\t\tpan( 0, - scope.keyPanSpeed );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.LEFT:\n\t\t\t\tpan( scope.keyPanSpeed, 0 );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t\tcase scope.keys.RIGHT:\n\t\t\t\tpan( - scope.keyPanSpeed, 0 );\n\t\t\t\tscope.update();\n\t\t\t\tbreak;\n\n\t\t}\n\n\t}\n\n\tfunction handleTouchStartRotate( event ) {\n\n\t\t//console.log( 'handleTouchStartRotate' );\n\n\t\trotateStart.set( event.pointers[ 0 ].pageX, event.pointers[ 0 ].pageY );\n\n\t}\n\n\tfunction handleTouchStartDolly( event ) {\n\n\t\t//console.log( 'handleTouchStartDolly' );\n\n\t\tvar dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\tvar dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\n\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\tdollyStart.set( 0, distance );\n\n\t}\n\n\tfunction handleTouchStartPan( event ) {\n\n\t\t//console.log( 'handleTouchStartPan' );\n\n\t\tpanStart.set( event.deltaX, event.deltaY );\n\n\t}\n\n\tfunction handleTouchMoveRotate( event ) {\n\n\t\t//console.log( 'handleTouchMoveRotate' );\n\n\t\trotateEnd.set( event.pointers[ 0 ].pageX, event.pointers[ 0 ].pageY );\n\t\trotateDelta.subVectors( rotateEnd, rotateStart );\n\n\t\tvar element = scope.domElement === document ? scope.domElement.body : scope.domElement;\n\n\t\t// rotating across whole screen goes 360 degrees around\n\t\trotateLeft( 2 * Math.PI * rotateDelta.x / element.clientWidth * scope.rotateSpeed );\n\n\t\t// rotating up and down along whole screen attempts to go 360, but limited to 180\n\t\trotateUp( 2 * Math.PI * rotateDelta.y / element.clientHeight * scope.rotateSpeed );\n\n\t\trotateStart.copy( rotateEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleTouchMoveDolly( event ) {\n\n\t\t//console.log( 'handleTouchMoveDolly' );\n\n\t\tvar dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\tvar dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\n\t\tvar distance = Math.sqrt( dx * dx + dy * dy );\n\n\t\tdollyEnd.set( 0, distance );\n\n\t\tdollyDelta.subVectors( dollyEnd, dollyStart );\n\n\t\tif ( dollyDelta.y > 0 ) {\n\n\t\t\tdollyOut( getZoomScale() );\n\n\t\t} else if ( dollyDelta.y < 0 ) {\n\n\t\t\tdollyIn( getZoomScale() );\n\n\t\t}\n\n\t\tdollyStart.copy( dollyEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleTouchMovePan( event ) {\n\n\t\t//console.log( 'handleTouchMovePan' );\n\n\t\tpanEnd.set( event.deltaX, event.deltaY );\n\n\t\tpanDelta.subVectors( panEnd, panStart );\n\n\t\tpan( panDelta.x, panDelta.y );\n\n\t\tpanStart.copy( panEnd );\n\n\t\tscope.update();\n\n\t}\n\n\tfunction handleTouchEnd( event ) {\n\n\t\t//console.log( 'handleTouchEnd' );\n\n\t}\n\n\t//\n\t// event handlers - FSM: listen for events and reset state\n\t//\n\n\tfunction onMouseDown( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\n\t\tif ( event.button === scope.mouseButtons.ORBIT ) {\n\n\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\thandleMouseDownRotate( event );\n\n\t\t\tstate = STATE.ROTATE;\n\n\t\t} else if ( event.button === scope.mouseButtons.ZOOM ) {\n\n\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\thandleMouseDownDolly( event );\n\n\t\t\tstate = STATE.DOLLY;\n\n\t\t} else if ( event.button === scope.mouseButtons.PAN ) {\n\n\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\thandleMouseDownPan( event );\n\n\t\t\tstate = STATE.PAN;\n\n\t\t}\n\n\t\tif ( state !== STATE.NONE ) {\n\n\t\t\tdocument.addEventListener( 'mousemove', onMouseMove, false );\n\t\t\tdocument.addEventListener( 'mouseup', onMouseUp, false );\n\t\t\tdocument.addEventListener( 'mouseout', onMouseUp, false );\n\n\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t}\n\n\t}\n\n\tfunction onMouseMove( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\n\t\tif ( state === STATE.ROTATE ) {\n\n\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\thandleMouseMoveRotate( event );\n\n\t\t} else if ( state === STATE.DOLLY ) {\n\n\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\thandleMouseMoveDolly( event );\n\n\t\t} else if ( state === STATE.PAN ) {\n\n\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\thandleMouseMovePan( event );\n\n\t\t}\n\n\t}\n\n\tfunction onMouseUp( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\thandleMouseUp( event );\n\n\t\tdocument.removeEventListener( 'mousemove', onMouseMove, false );\n\t\tdocument.removeEventListener( 'mouseup', onMouseUp, false );\n\t\tdocument.removeEventListener( 'mouseout', onMouseUp, false );\n\n\t\tscope.dispatchEvent( endEvent );\n\n\t\tstate = STATE.NONE;\n\n\t}\n\n\tfunction onMouseWheel( event ) {\n\n\t\tif ( scope.enabled === false || scope.enableZoom === false || state !== STATE.NONE ) return;\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\thandleMouseWheel( event );\n\n\t\tscope.dispatchEvent( startEvent ); // not sure why these are here...\n\t\tscope.dispatchEvent( endEvent );\n\n\t}\n\n\tfunction onKeyDown( event ) {\n\n\t\tif ( scope.enabled === false || scope.enableKeys === false || scope.enablePan === false ) return;\n\n\t\thandleKeyDown( event );\n\n\t}\n\n\tfunction onTouchStart( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tswitch ( event.touches.length ) {\n\n\t\t\tcase 1:\t// one-fingered touch: rotate\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\t\thandleTouchStartRotate( event );\n\n\t\t\t\tstate = STATE.TOUCH_ROTATE;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 2:\t// two-fingered touch: dolly\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\n\t\t\t\thandleTouchStartDolly( event );\n\n\t\t\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\t\t\tbreak;\n\n\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\n\t\t\t\thandleTouchStartPan( event );\n\n\t\t\t\tstate = STATE.TOUCH_PAN;\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t\tif ( state !== STATE.NONE ) {\n\n\t\t\tscope.dispatchEvent( startEvent );\n\n\t\t}\n\n\t}\n\n\tfunction onTouchMove( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\tevent.preventDefault();\n\t\tevent.stopPropagation();\n\n\t\tswitch ( event.touches.length ) {\n\n\t\t\tcase 1: // one-fingered touch: rotate\n\n\t\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\t\thandleTouchMoveRotate( event );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 2: // two-fingered touch: dolly\n\n\t\t\t\tif ( scope.enableZoom === false ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\t\t\thandleTouchMoveDolly( event );\n\n\t\t\t\tbreak;\n\n\t\t\tcase 3: // three-fingered touch: pan\n\n\t\t\t\tif ( scope.enablePan === false ) return;\n\t\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\t\thandleTouchMovePan( event );\n\n\t\t\t\tbreak;\n\n\t\t\tdefault:\n\n\t\t\t\tstate = STATE.NONE;\n\n\t\t}\n\n\t}\n\n\tfunction onTouchEnd( event ) {\n\n\t\tif ( scope.enabled === false ) return;\n\n\t\thandleTouchEnd( event );\n\n\t\tscope.dispatchEvent( endEvent );\n\n\t\tstate = STATE.NONE;\n\n\t}\n\n\tfunction onContextMenu( event ) {\n\n\t\tevent.preventDefault();\n\n\t}\n\n\t//\n\n\tscope.domElement.addEventListener( 'contextmenu', onContextMenu, false );\n\n\tscope.domElement.addEventListener( 'mousedown', onMouseDown, false );\n\tscope.domElement.addEventListener( 'mousewheel', onMouseWheel, false );\n\tscope.domElement.addEventListener( 'MozMousePixelScroll', onMouseWheel, false ); // firefox\n\n\t// scope.domElement.addEventListener( 'touchstart', onTouchStart, false );\n\t// scope.domElement.addEventListener( 'touchend', onTouchEnd, false );\n\t// scope.domElement.addEventListener( 'touchmove', onTouchMove, false );\n\n\tscope.hammer = new Hammer(scope.domElement);\n\n\tscope.hammer.get('pan').set({\n\t\tpointers: 0,\n\t\tdirection: Hammer.DIRECTION_ALL\n\t});\n\n\tscope.hammer.get('pinch').set({\n\t\tenable: true,\n\t\tthreshold: 0.1\n\t});\n\n\tscope.hammer.on('panstart', function(event) {\n\t\tif (scope.enabled === false) {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tif (event.pointers.length === 1) {\n\t\t\tif (scope.enablePan === false) {\n\t\t\t\treturn;\n\t\t\t}\n\n\t\t\thandleTouchStartPan(event);\n\t\t\t// panStart.set(event.deltaX, event.deltaY);\n\n\t\t\tstate = STATE.TOUCH_PAN;\n\t\t} else if (event.pointers.length === 2) {\n\t\t\tif ( scope.enableRotate === false ) return;\n\n\t\t\thandleTouchStartRotate( event );\n\n\t\t\tstate = STATE.TOUCH_ROTATE;\n\t\t}\n\n\t\tif (state !== STATE.NONE) {\n\t\t\tscope.dispatchEvent(startEvent);\n\t\t}\n\t});\n\n\tscope.hammer.on('panend', function(event) {\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tonTouchEnd(event);\n\t});\n\n\tscope.hammer.on('panmove', function(event) {\n\t\tif ( scope.enabled === false ) return;\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\t// event.preventDefault();\n\t\t// event.stopPropagation();\n\n\t\tif (event.pointers.length === 1) {\n\t\t\tif ( scope.enablePan === false ) return;\n\t\t\tif ( state !== STATE.TOUCH_PAN ) return; // is this needed?...\n\n\t\t\thandleTouchMovePan( event );\n\n\t\t\t// panEnd.set( event.deltaX, event.deltaY );\n\t\t\t//\n\t\t\t// panDelta.subVectors( panEnd, panStart );\n\t\t\t//\n\t\t\t// pan( panDelta.x, panDelta.y );\n\t\t\t//\n\t\t\t// panStart.copy( panEnd );\n\t\t\t//\n\t\t\t// scope.update();\n\t\t} else if (event.pointers.length === 2) {\n\t\t\tif ( scope.enableRotate === false ) return;\n\t\t\tif ( state !== STATE.TOUCH_ROTATE ) return; // is this needed?...\n\n\t\t\thandleTouchMoveRotate( event );\n\t\t}\n\t});\n\n\tscope.hammer.on('pinchstart', function(event) {\n\t\tif ( scope.enabled === false ) return;\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tif ( scope.enableZoom === false ) return;\n\n\t\thandleTouchStartDolly( event );\n\n\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t//\n\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t//\n\t\t// dollyStart.set( 0, distance );\n\t\t//\n\t\tstate = STATE.TOUCH_DOLLY;\n\n\t\tif (state !== STATE.NONE) {\n\t\t\tscope.dispatchEvent(startEvent);\n\t\t}\n\t});\n\n\tscope.hammer.on('pinchend', function(event) {\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\tonTouchEnd(event);\n\t});\n\n\tscope.hammer.on('pinchmove', function(event) {\n\t\tif ( scope.enabled === false ) return;\n\n\t\tif (event.pointerType === 'mouse') {\n\t\t\treturn;\n\t\t}\n\n\t\t// event.preventDefault();\n\t\t// event.stopPropagation();\n\n\t\tif ( scope.enableZoom === false ) return;\n\t\tif ( state !== STATE.TOUCH_DOLLY ) return; // is this needed?...\n\n\t\thandleTouchMoveDolly( event );\n\n\t\t// var dx = event.pointers[ 0 ].pageX - event.pointers[ 1 ].pageX;\n\t\t// var dy = event.pointers[ 0 ].pageY - event.pointers[ 1 ].pageY;\n\t\t//\n\t\t// var distance = Math.sqrt( dx * dx + dy * dy );\n\t\t//\n\t\t// dollyEnd.set( 0, distance );\n\t\t//\n\t\t// dollyDelta.subVectors( dollyEnd, dollyStart );\n\t\t//\n\t\t// if ( dollyDelta.y > 0 ) {\n\t\t//\n\t\t// \tdollyOut( getZoomScale() );\n\t\t//\n\t\t// } else if ( dollyDelta.y < 0 ) {\n\t\t//\n\t\t// \tdollyIn( getZoomScale() );\n\t\t//\n\t\t// }\n\t\t//\n\t\t// dollyStart.copy( dollyEnd );\n\t\t//\n\t\t// scope.update();\n\t});\n\n\twindow.addEventListener( 'keydown', onKeyDown, false );\n\n\t// Expose controls methods for programmatic control\n\tthis.panLeft = panLeft;\n\tthis.panUp = panUp;\n\tthis.pan = pan;\n\tthis.dollyIn = dollyIn;\n\tthis.dollyOut = dollyOut;\n\tthis.getZoomScale = getZoomScale;\n\tthis.rotateLeft = rotateLeft;\n\tthis.rotateUp = rotateUp;\n\n\t// force an update at start\n\n\tthis.update();\n\n};\n\nOrbitControls.prototype = Object.create( THREE.EventDispatcher.prototype );\nOrbitControls.prototype.constructor = THREE.OrbitControls;\n\nObject.defineProperties( OrbitControls.prototype, {\n\n\tcenter: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .center has been renamed to .target' );\n\t\t\treturn this.target;\n\n\t\t}\n\n\t},\n\n\t// backward compatibility\n\n\tnoZoom: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\treturn ! this.enableZoom;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noZoom has been deprecated. Use .enableZoom instead.' );\n\t\t\tthis.enableZoom = ! value;\n\n\t\t}\n\n\t},\n\n\tnoRotate: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\treturn ! this.enableRotate;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noRotate has been deprecated. Use .enableRotate instead.' );\n\t\t\tthis.enableRotate = ! value;\n\n\t\t}\n\n\t},\n\n\tnoPan: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\treturn ! this.enablePan;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noPan has been deprecated. Use .enablePan instead.' );\n\t\t\tthis.enablePan = ! value;\n\n\t\t}\n\n\t},\n\n\tnoKeys: {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\treturn ! this.enableKeys;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .noKeys has been deprecated. Use .enableKeys instead.' );\n\t\t\tthis.enableKeys = ! value;\n\n\t\t}\n\n\t},\n\n\tstaticMoving : {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\treturn ! this.constraint.enableDamping;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .staticMoving has been deprecated. Use .enableDamping instead.' );\n\t\t\tthis.constraint.enableDamping = ! value;\n\n\t\t}\n\n\t},\n\n\tdynamicDampingFactor : {\n\n\t\tget: function () {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\treturn this.constraint.dampingFactor;\n\n\t\t},\n\n\t\tset: function ( value ) {\n\n\t\t\tconsole.warn( 'THREE.OrbitControls: .dynamicDampingFactor has been renamed. Use .dampingFactor instead.' );\n\t\t\tthis.constraint.dampingFactor = value;\n\n\t\t}\n\n\t}\n\n} );\n\nexport default OrbitControls;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/OrbitControls.js\n **/","/*! Hammer.JS - v2.0.7 - 2016-04-22\n * http://hammerjs.github.io/\n *\n * Copyright (c) 2016 Jorik Tangelder;\n * Licensed under the MIT license */\n(function(window, document, exportName, undefined) {\n 'use strict';\n\nvar VENDOR_PREFIXES = ['', 'webkit', 'Moz', 'MS', 'ms', 'o'];\nvar TEST_ELEMENT = document.createElement('div');\n\nvar TYPE_FUNCTION = 'function';\n\nvar round = Math.round;\nvar abs = Math.abs;\nvar now = Date.now;\n\n/**\n * set a timeout with a given scope\n * @param {Function} fn\n * @param {Number} timeout\n * @param {Object} context\n * @returns {number}\n */\nfunction setTimeoutContext(fn, timeout, context) {\n return setTimeout(bindFn(fn, context), timeout);\n}\n\n/**\n * if the argument is an array, we want to execute the fn on each entry\n * if it aint an array we don't want to do a thing.\n * this is used by all the methods that accept a single and array argument.\n * @param {*|Array} arg\n * @param {String} fn\n * @param {Object} [context]\n * @returns {Boolean}\n */\nfunction invokeArrayArg(arg, fn, context) {\n if (Array.isArray(arg)) {\n each(arg, context[fn], context);\n return true;\n }\n return false;\n}\n\n/**\n * walk objects and arrays\n * @param {Object} obj\n * @param {Function} iterator\n * @param {Object} context\n */\nfunction each(obj, iterator, context) {\n var i;\n\n if (!obj) {\n return;\n }\n\n if (obj.forEach) {\n obj.forEach(iterator, context);\n } else if (obj.length !== undefined) {\n i = 0;\n while (i < obj.length) {\n iterator.call(context, obj[i], i, obj);\n i++;\n }\n } else {\n for (i in obj) {\n obj.hasOwnProperty(i) && iterator.call(context, obj[i], i, obj);\n }\n }\n}\n\n/**\n * wrap a method with a deprecation warning and stack trace\n * @param {Function} method\n * @param {String} name\n * @param {String} message\n * @returns {Function} A new function wrapping the supplied method.\n */\nfunction deprecate(method, name, message) {\n var deprecationMessage = 'DEPRECATED METHOD: ' + name + '\\n' + message + ' AT \\n';\n return function() {\n var e = new Error('get-stack-trace');\n var stack = e && e.stack ? e.stack.replace(/^[^\\(]+?[\\n$]/gm, '')\n .replace(/^\\s+at\\s+/gm, '')\n .replace(/^Object.\\s*\\(/gm, '{anonymous}()@') : 'Unknown Stack Trace';\n\n var log = window.console && (window.console.warn || window.console.log);\n if (log) {\n log.call(window.console, deprecationMessage, stack);\n }\n return method.apply(this, arguments);\n };\n}\n\n/**\n * extend object.\n * means that properties in dest will be overwritten by the ones in src.\n * @param {Object} target\n * @param {...Object} objects_to_assign\n * @returns {Object} target\n */\nvar assign;\nif (typeof Object.assign !== 'function') {\n assign = function assign(target) {\n if (target === undefined || target === null) {\n throw new TypeError('Cannot convert undefined or null to object');\n }\n\n var output = Object(target);\n for (var index = 1; index < arguments.length; index++) {\n var source = arguments[index];\n if (source !== undefined && source !== null) {\n for (var nextKey in source) {\n if (source.hasOwnProperty(nextKey)) {\n output[nextKey] = source[nextKey];\n }\n }\n }\n }\n return output;\n };\n} else {\n assign = Object.assign;\n}\n\n/**\n * extend object.\n * means that properties in dest will be overwritten by the ones in src.\n * @param {Object} dest\n * @param {Object} src\n * @param {Boolean} [merge=false]\n * @returns {Object} dest\n */\nvar extend = deprecate(function extend(dest, src, merge) {\n var keys = Object.keys(src);\n var i = 0;\n while (i < keys.length) {\n if (!merge || (merge && dest[keys[i]] === undefined)) {\n dest[keys[i]] = src[keys[i]];\n }\n i++;\n }\n return dest;\n}, 'extend', 'Use `assign`.');\n\n/**\n * merge the values from src in the dest.\n * means that properties that exist in dest will not be overwritten by src\n * @param {Object} dest\n * @param {Object} src\n * @returns {Object} dest\n */\nvar merge = deprecate(function merge(dest, src) {\n return extend(dest, src, true);\n}, 'merge', 'Use `assign`.');\n\n/**\n * simple class inheritance\n * @param {Function} child\n * @param {Function} base\n * @param {Object} [properties]\n */\nfunction inherit(child, base, properties) {\n var baseP = base.prototype,\n childP;\n\n childP = child.prototype = Object.create(baseP);\n childP.constructor = child;\n childP._super = baseP;\n\n if (properties) {\n assign(childP, properties);\n }\n}\n\n/**\n * simple function bind\n * @param {Function} fn\n * @param {Object} context\n * @returns {Function}\n */\nfunction bindFn(fn, context) {\n return function boundFn() {\n return fn.apply(context, arguments);\n };\n}\n\n/**\n * let a boolean value also be a function that must return a boolean\n * this first item in args will be used as the context\n * @param {Boolean|Function} val\n * @param {Array} [args]\n * @returns {Boolean}\n */\nfunction boolOrFn(val, args) {\n if (typeof val == TYPE_FUNCTION) {\n return val.apply(args ? args[0] || undefined : undefined, args);\n }\n return val;\n}\n\n/**\n * use the val2 when val1 is undefined\n * @param {*} val1\n * @param {*} val2\n * @returns {*}\n */\nfunction ifUndefined(val1, val2) {\n return (val1 === undefined) ? val2 : val1;\n}\n\n/**\n * addEventListener with multiple events at once\n * @param {EventTarget} target\n * @param {String} types\n * @param {Function} handler\n */\nfunction addEventListeners(target, types, handler) {\n each(splitStr(types), function(type) {\n target.addEventListener(type, handler, false);\n });\n}\n\n/**\n * removeEventListener with multiple events at once\n * @param {EventTarget} target\n * @param {String} types\n * @param {Function} handler\n */\nfunction removeEventListeners(target, types, handler) {\n each(splitStr(types), function(type) {\n target.removeEventListener(type, handler, false);\n });\n}\n\n/**\n * find if a node is in the given parent\n * @method hasParent\n * @param {HTMLElement} node\n * @param {HTMLElement} parent\n * @return {Boolean} found\n */\nfunction hasParent(node, parent) {\n while (node) {\n if (node == parent) {\n return true;\n }\n node = node.parentNode;\n }\n return false;\n}\n\n/**\n * small indexOf wrapper\n * @param {String} str\n * @param {String} find\n * @returns {Boolean} found\n */\nfunction inStr(str, find) {\n return str.indexOf(find) > -1;\n}\n\n/**\n * split string on whitespace\n * @param {String} str\n * @returns {Array} words\n */\nfunction splitStr(str) {\n return str.trim().split(/\\s+/g);\n}\n\n/**\n * find if a array contains the object using indexOf or a simple polyFill\n * @param {Array} src\n * @param {String} find\n * @param {String} [findByKey]\n * @return {Boolean|Number} false when not found, or the index\n */\nfunction inArray(src, find, findByKey) {\n if (src.indexOf && !findByKey) {\n return src.indexOf(find);\n } else {\n var i = 0;\n while (i < src.length) {\n if ((findByKey && src[i][findByKey] == find) || (!findByKey && src[i] === find)) {\n return i;\n }\n i++;\n }\n return -1;\n }\n}\n\n/**\n * convert array-like objects to real arrays\n * @param {Object} obj\n * @returns {Array}\n */\nfunction toArray(obj) {\n return Array.prototype.slice.call(obj, 0);\n}\n\n/**\n * unique array with objects based on a key (like 'id') or just by the array's value\n * @param {Array} src [{id:1},{id:2},{id:1}]\n * @param {String} [key]\n * @param {Boolean} [sort=False]\n * @returns {Array} [{id:1},{id:2}]\n */\nfunction uniqueArray(src, key, sort) {\n var results = [];\n var values = [];\n var i = 0;\n\n while (i < src.length) {\n var val = key ? src[i][key] : src[i];\n if (inArray(values, val) < 0) {\n results.push(src[i]);\n }\n values[i] = val;\n i++;\n }\n\n if (sort) {\n if (!key) {\n results = results.sort();\n } else {\n results = results.sort(function sortUniqueArray(a, b) {\n return a[key] > b[key];\n });\n }\n }\n\n return results;\n}\n\n/**\n * get the prefixed property\n * @param {Object} obj\n * @param {String} property\n * @returns {String|Undefined} prefixed\n */\nfunction prefixed(obj, property) {\n var prefix, prop;\n var camelProp = property[0].toUpperCase() + property.slice(1);\n\n var i = 0;\n while (i < VENDOR_PREFIXES.length) {\n prefix = VENDOR_PREFIXES[i];\n prop = (prefix) ? prefix + camelProp : property;\n\n if (prop in obj) {\n return prop;\n }\n i++;\n }\n return undefined;\n}\n\n/**\n * get a unique id\n * @returns {number} uniqueId\n */\nvar _uniqueId = 1;\nfunction uniqueId() {\n return _uniqueId++;\n}\n\n/**\n * get the window object of an element\n * @param {HTMLElement} element\n * @returns {DocumentView|Window}\n */\nfunction getWindowForElement(element) {\n var doc = element.ownerDocument || element;\n return (doc.defaultView || doc.parentWindow || window);\n}\n\nvar MOBILE_REGEX = /mobile|tablet|ip(ad|hone|od)|android/i;\n\nvar SUPPORT_TOUCH = ('ontouchstart' in window);\nvar SUPPORT_POINTER_EVENTS = prefixed(window, 'PointerEvent') !== undefined;\nvar SUPPORT_ONLY_TOUCH = SUPPORT_TOUCH && MOBILE_REGEX.test(navigator.userAgent);\n\nvar INPUT_TYPE_TOUCH = 'touch';\nvar INPUT_TYPE_PEN = 'pen';\nvar INPUT_TYPE_MOUSE = 'mouse';\nvar INPUT_TYPE_KINECT = 'kinect';\n\nvar COMPUTE_INTERVAL = 25;\n\nvar INPUT_START = 1;\nvar INPUT_MOVE = 2;\nvar INPUT_END = 4;\nvar INPUT_CANCEL = 8;\n\nvar DIRECTION_NONE = 1;\nvar DIRECTION_LEFT = 2;\nvar DIRECTION_RIGHT = 4;\nvar DIRECTION_UP = 8;\nvar DIRECTION_DOWN = 16;\n\nvar DIRECTION_HORIZONTAL = DIRECTION_LEFT | DIRECTION_RIGHT;\nvar DIRECTION_VERTICAL = DIRECTION_UP | DIRECTION_DOWN;\nvar DIRECTION_ALL = DIRECTION_HORIZONTAL | DIRECTION_VERTICAL;\n\nvar PROPS_XY = ['x', 'y'];\nvar PROPS_CLIENT_XY = ['clientX', 'clientY'];\n\n/**\n * create new input type manager\n * @param {Manager} manager\n * @param {Function} callback\n * @returns {Input}\n * @constructor\n */\nfunction Input(manager, callback) {\n var self = this;\n this.manager = manager;\n this.callback = callback;\n this.element = manager.element;\n this.target = manager.options.inputTarget;\n\n // smaller wrapper around the handler, for the scope and the enabled state of the manager,\n // so when disabled the input events are completely bypassed.\n this.domHandler = function(ev) {\n if (boolOrFn(manager.options.enable, [manager])) {\n self.handler(ev);\n }\n };\n\n this.init();\n\n}\n\nInput.prototype = {\n /**\n * should handle the inputEvent data and trigger the callback\n * @virtual\n */\n handler: function() { },\n\n /**\n * bind the events\n */\n init: function() {\n this.evEl && addEventListeners(this.element, this.evEl, this.domHandler);\n this.evTarget && addEventListeners(this.target, this.evTarget, this.domHandler);\n this.evWin && addEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n },\n\n /**\n * unbind the events\n */\n destroy: function() {\n this.evEl && removeEventListeners(this.element, this.evEl, this.domHandler);\n this.evTarget && removeEventListeners(this.target, this.evTarget, this.domHandler);\n this.evWin && removeEventListeners(getWindowForElement(this.element), this.evWin, this.domHandler);\n }\n};\n\n/**\n * create new input type manager\n * called by the Manager constructor\n * @param {Hammer} manager\n * @returns {Input}\n */\nfunction createInputInstance(manager) {\n var Type;\n var inputClass = manager.options.inputClass;\n\n if (inputClass) {\n Type = inputClass;\n } else if (SUPPORT_POINTER_EVENTS) {\n Type = PointerEventInput;\n } else if (SUPPORT_ONLY_TOUCH) {\n Type = TouchInput;\n } else if (!SUPPORT_TOUCH) {\n Type = MouseInput;\n } else {\n Type = TouchMouseInput;\n }\n return new (Type)(manager, inputHandler);\n}\n\n/**\n * handle input events\n * @param {Manager} manager\n * @param {String} eventType\n * @param {Object} input\n */\nfunction inputHandler(manager, eventType, input) {\n var pointersLen = input.pointers.length;\n var changedPointersLen = input.changedPointers.length;\n var isFirst = (eventType & INPUT_START && (pointersLen - changedPointersLen === 0));\n var isFinal = (eventType & (INPUT_END | INPUT_CANCEL) && (pointersLen - changedPointersLen === 0));\n\n input.isFirst = !!isFirst;\n input.isFinal = !!isFinal;\n\n if (isFirst) {\n manager.session = {};\n }\n\n // source event is the normalized value of the domEvents\n // like 'touchstart, mouseup, pointerdown'\n input.eventType = eventType;\n\n // compute scale, rotation etc\n computeInputData(manager, input);\n\n // emit secret event\n manager.emit('hammer.input', input);\n\n manager.recognize(input);\n manager.session.prevInput = input;\n}\n\n/**\n * extend the data with some usable properties like scale, rotate, velocity etc\n * @param {Object} manager\n * @param {Object} input\n */\nfunction computeInputData(manager, input) {\n var session = manager.session;\n var pointers = input.pointers;\n var pointersLength = pointers.length;\n\n // store the first input to calculate the distance and direction\n if (!session.firstInput) {\n session.firstInput = simpleCloneInputData(input);\n }\n\n // to compute scale and rotation we need to store the multiple touches\n if (pointersLength > 1 && !session.firstMultiple) {\n session.firstMultiple = simpleCloneInputData(input);\n } else if (pointersLength === 1) {\n session.firstMultiple = false;\n }\n\n var firstInput = session.firstInput;\n var firstMultiple = session.firstMultiple;\n var offsetCenter = firstMultiple ? firstMultiple.center : firstInput.center;\n\n var center = input.center = getCenter(pointers);\n input.timeStamp = now();\n input.deltaTime = input.timeStamp - firstInput.timeStamp;\n\n input.angle = getAngle(offsetCenter, center);\n input.distance = getDistance(offsetCenter, center);\n\n computeDeltaXY(session, input);\n input.offsetDirection = getDirection(input.deltaX, input.deltaY);\n\n var overallVelocity = getVelocity(input.deltaTime, input.deltaX, input.deltaY);\n input.overallVelocityX = overallVelocity.x;\n input.overallVelocityY = overallVelocity.y;\n input.overallVelocity = (abs(overallVelocity.x) > abs(overallVelocity.y)) ? overallVelocity.x : overallVelocity.y;\n\n input.scale = firstMultiple ? getScale(firstMultiple.pointers, pointers) : 1;\n input.rotation = firstMultiple ? getRotation(firstMultiple.pointers, pointers) : 0;\n\n input.maxPointers = !session.prevInput ? input.pointers.length : ((input.pointers.length >\n session.prevInput.maxPointers) ? input.pointers.length : session.prevInput.maxPointers);\n\n computeIntervalInputData(session, input);\n\n // find the correct target\n var target = manager.element;\n if (hasParent(input.srcEvent.target, target)) {\n target = input.srcEvent.target;\n }\n input.target = target;\n}\n\nfunction computeDeltaXY(session, input) {\n var center = input.center;\n var offset = session.offsetDelta || {};\n var prevDelta = session.prevDelta || {};\n var prevInput = session.prevInput || {};\n\n if (input.eventType === INPUT_START || prevInput.eventType === INPUT_END) {\n prevDelta = session.prevDelta = {\n x: prevInput.deltaX || 0,\n y: prevInput.deltaY || 0\n };\n\n offset = session.offsetDelta = {\n x: center.x,\n y: center.y\n };\n }\n\n input.deltaX = prevDelta.x + (center.x - offset.x);\n input.deltaY = prevDelta.y + (center.y - offset.y);\n}\n\n/**\n * velocity is calculated every x ms\n * @param {Object} session\n * @param {Object} input\n */\nfunction computeIntervalInputData(session, input) {\n var last = session.lastInterval || input,\n deltaTime = input.timeStamp - last.timeStamp,\n velocity, velocityX, velocityY, direction;\n\n if (input.eventType != INPUT_CANCEL && (deltaTime > COMPUTE_INTERVAL || last.velocity === undefined)) {\n var deltaX = input.deltaX - last.deltaX;\n var deltaY = input.deltaY - last.deltaY;\n\n var v = getVelocity(deltaTime, deltaX, deltaY);\n velocityX = v.x;\n velocityY = v.y;\n velocity = (abs(v.x) > abs(v.y)) ? v.x : v.y;\n direction = getDirection(deltaX, deltaY);\n\n session.lastInterval = input;\n } else {\n // use latest velocity info if it doesn't overtake a minimum period\n velocity = last.velocity;\n velocityX = last.velocityX;\n velocityY = last.velocityY;\n direction = last.direction;\n }\n\n input.velocity = velocity;\n input.velocityX = velocityX;\n input.velocityY = velocityY;\n input.direction = direction;\n}\n\n/**\n * create a simple clone from the input used for storage of firstInput and firstMultiple\n * @param {Object} input\n * @returns {Object} clonedInputData\n */\nfunction simpleCloneInputData(input) {\n // make a simple copy of the pointers because we will get a reference if we don't\n // we only need clientXY for the calculations\n var pointers = [];\n var i = 0;\n while (i < input.pointers.length) {\n pointers[i] = {\n clientX: round(input.pointers[i].clientX),\n clientY: round(input.pointers[i].clientY)\n };\n i++;\n }\n\n return {\n timeStamp: now(),\n pointers: pointers,\n center: getCenter(pointers),\n deltaX: input.deltaX,\n deltaY: input.deltaY\n };\n}\n\n/**\n * get the center of all the pointers\n * @param {Array} pointers\n * @return {Object} center contains `x` and `y` properties\n */\nfunction getCenter(pointers) {\n var pointersLength = pointers.length;\n\n // no need to loop when only one touch\n if (pointersLength === 1) {\n return {\n x: round(pointers[0].clientX),\n y: round(pointers[0].clientY)\n };\n }\n\n var x = 0, y = 0, i = 0;\n while (i < pointersLength) {\n x += pointers[i].clientX;\n y += pointers[i].clientY;\n i++;\n }\n\n return {\n x: round(x / pointersLength),\n y: round(y / pointersLength)\n };\n}\n\n/**\n * calculate the velocity between two points. unit is in px per ms.\n * @param {Number} deltaTime\n * @param {Number} x\n * @param {Number} y\n * @return {Object} velocity `x` and `y`\n */\nfunction getVelocity(deltaTime, x, y) {\n return {\n x: x / deltaTime || 0,\n y: y / deltaTime || 0\n };\n}\n\n/**\n * get the direction between two points\n * @param {Number} x\n * @param {Number} y\n * @return {Number} direction\n */\nfunction getDirection(x, y) {\n if (x === y) {\n return DIRECTION_NONE;\n }\n\n if (abs(x) >= abs(y)) {\n return x < 0 ? DIRECTION_LEFT : DIRECTION_RIGHT;\n }\n return y < 0 ? DIRECTION_UP : DIRECTION_DOWN;\n}\n\n/**\n * calculate the absolute distance between two points\n * @param {Object} p1 {x, y}\n * @param {Object} p2 {x, y}\n * @param {Array} [props] containing x and y keys\n * @return {Number} distance\n */\nfunction getDistance(p1, p2, props) {\n if (!props) {\n props = PROPS_XY;\n }\n var x = p2[props[0]] - p1[props[0]],\n y = p2[props[1]] - p1[props[1]];\n\n return Math.sqrt((x * x) + (y * y));\n}\n\n/**\n * calculate the angle between two coordinates\n * @param {Object} p1\n * @param {Object} p2\n * @param {Array} [props] containing x and y keys\n * @return {Number} angle\n */\nfunction getAngle(p1, p2, props) {\n if (!props) {\n props = PROPS_XY;\n }\n var x = p2[props[0]] - p1[props[0]],\n y = p2[props[1]] - p1[props[1]];\n return Math.atan2(y, x) * 180 / Math.PI;\n}\n\n/**\n * calculate the rotation degrees between two pointersets\n * @param {Array} start array of pointers\n * @param {Array} end array of pointers\n * @return {Number} rotation\n */\nfunction getRotation(start, end) {\n return getAngle(end[1], end[0], PROPS_CLIENT_XY) + getAngle(start[1], start[0], PROPS_CLIENT_XY);\n}\n\n/**\n * calculate the scale factor between two pointersets\n * no scale is 1, and goes down to 0 when pinched together, and bigger when pinched out\n * @param {Array} start array of pointers\n * @param {Array} end array of pointers\n * @return {Number} scale\n */\nfunction getScale(start, end) {\n return getDistance(end[0], end[1], PROPS_CLIENT_XY) / getDistance(start[0], start[1], PROPS_CLIENT_XY);\n}\n\nvar MOUSE_INPUT_MAP = {\n mousedown: INPUT_START,\n mousemove: INPUT_MOVE,\n mouseup: INPUT_END\n};\n\nvar MOUSE_ELEMENT_EVENTS = 'mousedown';\nvar MOUSE_WINDOW_EVENTS = 'mousemove mouseup';\n\n/**\n * Mouse events input\n * @constructor\n * @extends Input\n */\nfunction MouseInput() {\n this.evEl = MOUSE_ELEMENT_EVENTS;\n this.evWin = MOUSE_WINDOW_EVENTS;\n\n this.pressed = false; // mousedown state\n\n Input.apply(this, arguments);\n}\n\ninherit(MouseInput, Input, {\n /**\n * handle mouse events\n * @param {Object} ev\n */\n handler: function MEhandler(ev) {\n var eventType = MOUSE_INPUT_MAP[ev.type];\n\n // on start we want to have the left mouse button down\n if (eventType & INPUT_START && ev.button === 0) {\n this.pressed = true;\n }\n\n if (eventType & INPUT_MOVE && ev.which !== 1) {\n eventType = INPUT_END;\n }\n\n // mouse must be down\n if (!this.pressed) {\n return;\n }\n\n if (eventType & INPUT_END) {\n this.pressed = false;\n }\n\n this.callback(this.manager, eventType, {\n pointers: [ev],\n changedPointers: [ev],\n pointerType: INPUT_TYPE_MOUSE,\n srcEvent: ev\n });\n }\n});\n\nvar POINTER_INPUT_MAP = {\n pointerdown: INPUT_START,\n pointermove: INPUT_MOVE,\n pointerup: INPUT_END,\n pointercancel: INPUT_CANCEL,\n pointerout: INPUT_CANCEL\n};\n\n// in IE10 the pointer types is defined as an enum\nvar IE10_POINTER_TYPE_ENUM = {\n 2: INPUT_TYPE_TOUCH,\n 3: INPUT_TYPE_PEN,\n 4: INPUT_TYPE_MOUSE,\n 5: INPUT_TYPE_KINECT // see https://twitter.com/jacobrossi/status/480596438489890816\n};\n\nvar POINTER_ELEMENT_EVENTS = 'pointerdown';\nvar POINTER_WINDOW_EVENTS = 'pointermove pointerup pointercancel';\n\n// IE10 has prefixed support, and case-sensitive\nif (window.MSPointerEvent && !window.PointerEvent) {\n POINTER_ELEMENT_EVENTS = 'MSPointerDown';\n POINTER_WINDOW_EVENTS = 'MSPointerMove MSPointerUp MSPointerCancel';\n}\n\n/**\n * Pointer events input\n * @constructor\n * @extends Input\n */\nfunction PointerEventInput() {\n this.evEl = POINTER_ELEMENT_EVENTS;\n this.evWin = POINTER_WINDOW_EVENTS;\n\n Input.apply(this, arguments);\n\n this.store = (this.manager.session.pointerEvents = []);\n}\n\ninherit(PointerEventInput, Input, {\n /**\n * handle mouse events\n * @param {Object} ev\n */\n handler: function PEhandler(ev) {\n var store = this.store;\n var removePointer = false;\n\n var eventTypeNormalized = ev.type.toLowerCase().replace('ms', '');\n var eventType = POINTER_INPUT_MAP[eventTypeNormalized];\n var pointerType = IE10_POINTER_TYPE_ENUM[ev.pointerType] || ev.pointerType;\n\n var isTouch = (pointerType == INPUT_TYPE_TOUCH);\n\n // get index of the event in the store\n var storeIndex = inArray(store, ev.pointerId, 'pointerId');\n\n // start and mouse must be down\n if (eventType & INPUT_START && (ev.button === 0 || isTouch)) {\n if (storeIndex < 0) {\n store.push(ev);\n storeIndex = store.length - 1;\n }\n } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n removePointer = true;\n }\n\n // it not found, so the pointer hasn't been down (so it's probably a hover)\n if (storeIndex < 0) {\n return;\n }\n\n // update the event in the store\n store[storeIndex] = ev;\n\n this.callback(this.manager, eventType, {\n pointers: store,\n changedPointers: [ev],\n pointerType: pointerType,\n srcEvent: ev\n });\n\n if (removePointer) {\n // remove from the store\n store.splice(storeIndex, 1);\n }\n }\n});\n\nvar SINGLE_TOUCH_INPUT_MAP = {\n touchstart: INPUT_START,\n touchmove: INPUT_MOVE,\n touchend: INPUT_END,\n touchcancel: INPUT_CANCEL\n};\n\nvar SINGLE_TOUCH_TARGET_EVENTS = 'touchstart';\nvar SINGLE_TOUCH_WINDOW_EVENTS = 'touchstart touchmove touchend touchcancel';\n\n/**\n * Touch events input\n * @constructor\n * @extends Input\n */\nfunction SingleTouchInput() {\n this.evTarget = SINGLE_TOUCH_TARGET_EVENTS;\n this.evWin = SINGLE_TOUCH_WINDOW_EVENTS;\n this.started = false;\n\n Input.apply(this, arguments);\n}\n\ninherit(SingleTouchInput, Input, {\n handler: function TEhandler(ev) {\n var type = SINGLE_TOUCH_INPUT_MAP[ev.type];\n\n // should we handle the touch events?\n if (type === INPUT_START) {\n this.started = true;\n }\n\n if (!this.started) {\n return;\n }\n\n var touches = normalizeSingleTouches.call(this, ev, type);\n\n // when done, reset the started state\n if (type & (INPUT_END | INPUT_CANCEL) && touches[0].length - touches[1].length === 0) {\n this.started = false;\n }\n\n this.callback(this.manager, type, {\n pointers: touches[0],\n changedPointers: touches[1],\n pointerType: INPUT_TYPE_TOUCH,\n srcEvent: ev\n });\n }\n});\n\n/**\n * @this {TouchInput}\n * @param {Object} ev\n * @param {Number} type flag\n * @returns {undefined|Array} [all, changed]\n */\nfunction normalizeSingleTouches(ev, type) {\n var all = toArray(ev.touches);\n var changed = toArray(ev.changedTouches);\n\n if (type & (INPUT_END | INPUT_CANCEL)) {\n all = uniqueArray(all.concat(changed), 'identifier', true);\n }\n\n return [all, changed];\n}\n\nvar TOUCH_INPUT_MAP = {\n touchstart: INPUT_START,\n touchmove: INPUT_MOVE,\n touchend: INPUT_END,\n touchcancel: INPUT_CANCEL\n};\n\nvar TOUCH_TARGET_EVENTS = 'touchstart touchmove touchend touchcancel';\n\n/**\n * Multi-user touch events input\n * @constructor\n * @extends Input\n */\nfunction TouchInput() {\n this.evTarget = TOUCH_TARGET_EVENTS;\n this.targetIds = {};\n\n Input.apply(this, arguments);\n}\n\ninherit(TouchInput, Input, {\n handler: function MTEhandler(ev) {\n var type = TOUCH_INPUT_MAP[ev.type];\n var touches = getTouches.call(this, ev, type);\n if (!touches) {\n return;\n }\n\n this.callback(this.manager, type, {\n pointers: touches[0],\n changedPointers: touches[1],\n pointerType: INPUT_TYPE_TOUCH,\n srcEvent: ev\n });\n }\n});\n\n/**\n * @this {TouchInput}\n * @param {Object} ev\n * @param {Number} type flag\n * @returns {undefined|Array} [all, changed]\n */\nfunction getTouches(ev, type) {\n var allTouches = toArray(ev.touches);\n var targetIds = this.targetIds;\n\n // when there is only one touch, the process can be simplified\n if (type & (INPUT_START | INPUT_MOVE) && allTouches.length === 1) {\n targetIds[allTouches[0].identifier] = true;\n return [allTouches, allTouches];\n }\n\n var i,\n targetTouches,\n changedTouches = toArray(ev.changedTouches),\n changedTargetTouches = [],\n target = this.target;\n\n // get target touches from touches\n targetTouches = allTouches.filter(function(touch) {\n return hasParent(touch.target, target);\n });\n\n // collect touches\n if (type === INPUT_START) {\n i = 0;\n while (i < targetTouches.length) {\n targetIds[targetTouches[i].identifier] = true;\n i++;\n }\n }\n\n // filter changed touches to only contain touches that exist in the collected target ids\n i = 0;\n while (i < changedTouches.length) {\n if (targetIds[changedTouches[i].identifier]) {\n changedTargetTouches.push(changedTouches[i]);\n }\n\n // cleanup removed touches\n if (type & (INPUT_END | INPUT_CANCEL)) {\n delete targetIds[changedTouches[i].identifier];\n }\n i++;\n }\n\n if (!changedTargetTouches.length) {\n return;\n }\n\n return [\n // merge targetTouches with changedTargetTouches so it contains ALL touches, including 'end' and 'cancel'\n uniqueArray(targetTouches.concat(changedTargetTouches), 'identifier', true),\n changedTargetTouches\n ];\n}\n\n/**\n * Combined touch and mouse input\n *\n * Touch has a higher priority then mouse, and while touching no mouse events are allowed.\n * This because touch devices also emit mouse events while doing a touch.\n *\n * @constructor\n * @extends Input\n */\n\nvar DEDUP_TIMEOUT = 2500;\nvar DEDUP_DISTANCE = 25;\n\nfunction TouchMouseInput() {\n Input.apply(this, arguments);\n\n var handler = bindFn(this.handler, this);\n this.touch = new TouchInput(this.manager, handler);\n this.mouse = new MouseInput(this.manager, handler);\n\n this.primaryTouch = null;\n this.lastTouches = [];\n}\n\ninherit(TouchMouseInput, Input, {\n /**\n * handle mouse and touch events\n * @param {Hammer} manager\n * @param {String} inputEvent\n * @param {Object} inputData\n */\n handler: function TMEhandler(manager, inputEvent, inputData) {\n var isTouch = (inputData.pointerType == INPUT_TYPE_TOUCH),\n isMouse = (inputData.pointerType == INPUT_TYPE_MOUSE);\n\n if (isMouse && inputData.sourceCapabilities && inputData.sourceCapabilities.firesTouchEvents) {\n return;\n }\n\n // when we're in a touch event, record touches to de-dupe synthetic mouse event\n if (isTouch) {\n recordTouches.call(this, inputEvent, inputData);\n } else if (isMouse && isSyntheticEvent.call(this, inputData)) {\n return;\n }\n\n this.callback(manager, inputEvent, inputData);\n },\n\n /**\n * remove the event listeners\n */\n destroy: function destroy() {\n this.touch.destroy();\n this.mouse.destroy();\n }\n});\n\nfunction recordTouches(eventType, eventData) {\n if (eventType & INPUT_START) {\n this.primaryTouch = eventData.changedPointers[0].identifier;\n setLastTouch.call(this, eventData);\n } else if (eventType & (INPUT_END | INPUT_CANCEL)) {\n setLastTouch.call(this, eventData);\n }\n}\n\nfunction setLastTouch(eventData) {\n var touch = eventData.changedPointers[0];\n\n if (touch.identifier === this.primaryTouch) {\n var lastTouch = {x: touch.clientX, y: touch.clientY};\n this.lastTouches.push(lastTouch);\n var lts = this.lastTouches;\n var removeLastTouch = function() {\n var i = lts.indexOf(lastTouch);\n if (i > -1) {\n lts.splice(i, 1);\n }\n };\n setTimeout(removeLastTouch, DEDUP_TIMEOUT);\n }\n}\n\nfunction isSyntheticEvent(eventData) {\n var x = eventData.srcEvent.clientX, y = eventData.srcEvent.clientY;\n for (var i = 0; i < this.lastTouches.length; i++) {\n var t = this.lastTouches[i];\n var dx = Math.abs(x - t.x), dy = Math.abs(y - t.y);\n if (dx <= DEDUP_DISTANCE && dy <= DEDUP_DISTANCE) {\n return true;\n }\n }\n return false;\n}\n\nvar PREFIXED_TOUCH_ACTION = prefixed(TEST_ELEMENT.style, 'touchAction');\nvar NATIVE_TOUCH_ACTION = PREFIXED_TOUCH_ACTION !== undefined;\n\n// magical touchAction value\nvar TOUCH_ACTION_COMPUTE = 'compute';\nvar TOUCH_ACTION_AUTO = 'auto';\nvar TOUCH_ACTION_MANIPULATION = 'manipulation'; // not implemented\nvar TOUCH_ACTION_NONE = 'none';\nvar TOUCH_ACTION_PAN_X = 'pan-x';\nvar TOUCH_ACTION_PAN_Y = 'pan-y';\nvar TOUCH_ACTION_MAP = getTouchActionProps();\n\n/**\n * Touch Action\n * sets the touchAction property or uses the js alternative\n * @param {Manager} manager\n * @param {String} value\n * @constructor\n */\nfunction TouchAction(manager, value) {\n this.manager = manager;\n this.set(value);\n}\n\nTouchAction.prototype = {\n /**\n * set the touchAction value on the element or enable the polyfill\n * @param {String} value\n */\n set: function(value) {\n // find out the touch-action by the event handlers\n if (value == TOUCH_ACTION_COMPUTE) {\n value = this.compute();\n }\n\n if (NATIVE_TOUCH_ACTION && this.manager.element.style && TOUCH_ACTION_MAP[value]) {\n this.manager.element.style[PREFIXED_TOUCH_ACTION] = value;\n }\n this.actions = value.toLowerCase().trim();\n },\n\n /**\n * just re-set the touchAction value\n */\n update: function() {\n this.set(this.manager.options.touchAction);\n },\n\n /**\n * compute the value for the touchAction property based on the recognizer's settings\n * @returns {String} value\n */\n compute: function() {\n var actions = [];\n each(this.manager.recognizers, function(recognizer) {\n if (boolOrFn(recognizer.options.enable, [recognizer])) {\n actions = actions.concat(recognizer.getTouchAction());\n }\n });\n return cleanTouchActions(actions.join(' '));\n },\n\n /**\n * this method is called on each input cycle and provides the preventing of the browser behavior\n * @param {Object} input\n */\n preventDefaults: function(input) {\n var srcEvent = input.srcEvent;\n var direction = input.offsetDirection;\n\n // if the touch action did prevented once this session\n if (this.manager.session.prevented) {\n srcEvent.preventDefault();\n return;\n }\n\n var actions = this.actions;\n var hasNone = inStr(actions, TOUCH_ACTION_NONE) && !TOUCH_ACTION_MAP[TOUCH_ACTION_NONE];\n var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_Y];\n var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X) && !TOUCH_ACTION_MAP[TOUCH_ACTION_PAN_X];\n\n if (hasNone) {\n //do not prevent defaults if this is a tap gesture\n\n var isTapPointer = input.pointers.length === 1;\n var isTapMovement = input.distance < 2;\n var isTapTouchTime = input.deltaTime < 250;\n\n if (isTapPointer && isTapMovement && isTapTouchTime) {\n return;\n }\n }\n\n if (hasPanX && hasPanY) {\n // `pan-x pan-y` means browser handles all scrolling/panning, do not prevent\n return;\n }\n\n if (hasNone ||\n (hasPanY && direction & DIRECTION_HORIZONTAL) ||\n (hasPanX && direction & DIRECTION_VERTICAL)) {\n return this.preventSrc(srcEvent);\n }\n },\n\n /**\n * call preventDefault to prevent the browser's default behavior (scrolling in most cases)\n * @param {Object} srcEvent\n */\n preventSrc: function(srcEvent) {\n this.manager.session.prevented = true;\n srcEvent.preventDefault();\n }\n};\n\n/**\n * when the touchActions are collected they are not a valid value, so we need to clean things up. *\n * @param {String} actions\n * @returns {*}\n */\nfunction cleanTouchActions(actions) {\n // none\n if (inStr(actions, TOUCH_ACTION_NONE)) {\n return TOUCH_ACTION_NONE;\n }\n\n var hasPanX = inStr(actions, TOUCH_ACTION_PAN_X);\n var hasPanY = inStr(actions, TOUCH_ACTION_PAN_Y);\n\n // if both pan-x and pan-y are set (different recognizers\n // for different directions, e.g. horizontal pan but vertical swipe?)\n // we need none (as otherwise with pan-x pan-y combined none of these\n // recognizers will work, since the browser would handle all panning\n if (hasPanX && hasPanY) {\n return TOUCH_ACTION_NONE;\n }\n\n // pan-x OR pan-y\n if (hasPanX || hasPanY) {\n return hasPanX ? TOUCH_ACTION_PAN_X : TOUCH_ACTION_PAN_Y;\n }\n\n // manipulation\n if (inStr(actions, TOUCH_ACTION_MANIPULATION)) {\n return TOUCH_ACTION_MANIPULATION;\n }\n\n return TOUCH_ACTION_AUTO;\n}\n\nfunction getTouchActionProps() {\n if (!NATIVE_TOUCH_ACTION) {\n return false;\n }\n var touchMap = {};\n var cssSupports = window.CSS && window.CSS.supports;\n ['auto', 'manipulation', 'pan-y', 'pan-x', 'pan-x pan-y', 'none'].forEach(function(val) {\n\n // If css.supports is not supported but there is native touch-action assume it supports\n // all values. This is the case for IE 10 and 11.\n touchMap[val] = cssSupports ? window.CSS.supports('touch-action', val) : true;\n });\n return touchMap;\n}\n\n/**\n * Recognizer flow explained; *\n * All recognizers have the initial state of POSSIBLE when a input session starts.\n * The definition of a input session is from the first input until the last input, with all it's movement in it. *\n * Example session for mouse-input: mousedown -> mousemove -> mouseup\n *\n * On each recognizing cycle (see Manager.recognize) the .recognize() method is executed\n * which determines with state it should be.\n *\n * If the recognizer has the state FAILED, CANCELLED or RECOGNIZED (equals ENDED), it is reset to\n * POSSIBLE to give it another change on the next cycle.\n *\n * Possible\n * |\n * +-----+---------------+\n * | |\n * +-----+-----+ |\n * | | |\n * Failed Cancelled |\n * +-------+------+\n * | |\n * Recognized Began\n * |\n * Changed\n * |\n * Ended/Recognized\n */\nvar STATE_POSSIBLE = 1;\nvar STATE_BEGAN = 2;\nvar STATE_CHANGED = 4;\nvar STATE_ENDED = 8;\nvar STATE_RECOGNIZED = STATE_ENDED;\nvar STATE_CANCELLED = 16;\nvar STATE_FAILED = 32;\n\n/**\n * Recognizer\n * Every recognizer needs to extend from this class.\n * @constructor\n * @param {Object} options\n */\nfunction Recognizer(options) {\n this.options = assign({}, this.defaults, options || {});\n\n this.id = uniqueId();\n\n this.manager = null;\n\n // default is enable true\n this.options.enable = ifUndefined(this.options.enable, true);\n\n this.state = STATE_POSSIBLE;\n\n this.simultaneous = {};\n this.requireFail = [];\n}\n\nRecognizer.prototype = {\n /**\n * @virtual\n * @type {Object}\n */\n defaults: {},\n\n /**\n * set options\n * @param {Object} options\n * @return {Recognizer}\n */\n set: function(options) {\n assign(this.options, options);\n\n // also update the touchAction, in case something changed about the directions/enabled state\n this.manager && this.manager.touchAction.update();\n return this;\n },\n\n /**\n * recognize simultaneous with an other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n recognizeWith: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'recognizeWith', this)) {\n return this;\n }\n\n var simultaneous = this.simultaneous;\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n if (!simultaneous[otherRecognizer.id]) {\n simultaneous[otherRecognizer.id] = otherRecognizer;\n otherRecognizer.recognizeWith(this);\n }\n return this;\n },\n\n /**\n * drop the simultaneous link. it doesnt remove the link on the other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n dropRecognizeWith: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'dropRecognizeWith', this)) {\n return this;\n }\n\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n delete this.simultaneous[otherRecognizer.id];\n return this;\n },\n\n /**\n * recognizer can only run when an other is failing\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n requireFailure: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'requireFailure', this)) {\n return this;\n }\n\n var requireFail = this.requireFail;\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n if (inArray(requireFail, otherRecognizer) === -1) {\n requireFail.push(otherRecognizer);\n otherRecognizer.requireFailure(this);\n }\n return this;\n },\n\n /**\n * drop the requireFailure link. it does not remove the link on the other recognizer.\n * @param {Recognizer} otherRecognizer\n * @returns {Recognizer} this\n */\n dropRequireFailure: function(otherRecognizer) {\n if (invokeArrayArg(otherRecognizer, 'dropRequireFailure', this)) {\n return this;\n }\n\n otherRecognizer = getRecognizerByNameIfManager(otherRecognizer, this);\n var index = inArray(this.requireFail, otherRecognizer);\n if (index > -1) {\n this.requireFail.splice(index, 1);\n }\n return this;\n },\n\n /**\n * has require failures boolean\n * @returns {boolean}\n */\n hasRequireFailures: function() {\n return this.requireFail.length > 0;\n },\n\n /**\n * if the recognizer can recognize simultaneous with an other recognizer\n * @param {Recognizer} otherRecognizer\n * @returns {Boolean}\n */\n canRecognizeWith: function(otherRecognizer) {\n return !!this.simultaneous[otherRecognizer.id];\n },\n\n /**\n * You should use `tryEmit` instead of `emit` directly to check\n * that all the needed recognizers has failed before emitting.\n * @param {Object} input\n */\n emit: function(input) {\n var self = this;\n var state = this.state;\n\n function emit(event) {\n self.manager.emit(event, input);\n }\n\n // 'panstart' and 'panmove'\n if (state < STATE_ENDED) {\n emit(self.options.event + stateStr(state));\n }\n\n emit(self.options.event); // simple 'eventName' events\n\n if (input.additionalEvent) { // additional event(panleft, panright, pinchin, pinchout...)\n emit(input.additionalEvent);\n }\n\n // panend and pancancel\n if (state >= STATE_ENDED) {\n emit(self.options.event + stateStr(state));\n }\n },\n\n /**\n * Check that all the require failure recognizers has failed,\n * if true, it emits a gesture event,\n * otherwise, setup the state to FAILED.\n * @param {Object} input\n */\n tryEmit: function(input) {\n if (this.canEmit()) {\n return this.emit(input);\n }\n // it's failing anyway\n this.state = STATE_FAILED;\n },\n\n /**\n * can we emit?\n * @returns {boolean}\n */\n canEmit: function() {\n var i = 0;\n while (i < this.requireFail.length) {\n if (!(this.requireFail[i].state & (STATE_FAILED | STATE_POSSIBLE))) {\n return false;\n }\n i++;\n }\n return true;\n },\n\n /**\n * update the recognizer\n * @param {Object} inputData\n */\n recognize: function(inputData) {\n // make a new copy of the inputData\n // so we can change the inputData without messing up the other recognizers\n var inputDataClone = assign({}, inputData);\n\n // is is enabled and allow recognizing?\n if (!boolOrFn(this.options.enable, [this, inputDataClone])) {\n this.reset();\n this.state = STATE_FAILED;\n return;\n }\n\n // reset when we've reached the end\n if (this.state & (STATE_RECOGNIZED | STATE_CANCELLED | STATE_FAILED)) {\n this.state = STATE_POSSIBLE;\n }\n\n this.state = this.process(inputDataClone);\n\n // the recognizer has recognized a gesture\n // so trigger an event\n if (this.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED | STATE_CANCELLED)) {\n this.tryEmit(inputDataClone);\n }\n },\n\n /**\n * return the state of the recognizer\n * the actual recognizing happens in this method\n * @virtual\n * @param {Object} inputData\n * @returns {Const} STATE\n */\n process: function(inputData) { }, // jshint ignore:line\n\n /**\n * return the preferred touch-action\n * @virtual\n * @returns {Array}\n */\n getTouchAction: function() { },\n\n /**\n * called when the gesture isn't allowed to recognize\n * like when another is being recognized or it is disabled\n * @virtual\n */\n reset: function() { }\n};\n\n/**\n * get a usable string, used as event postfix\n * @param {Const} state\n * @returns {String} state\n */\nfunction stateStr(state) {\n if (state & STATE_CANCELLED) {\n return 'cancel';\n } else if (state & STATE_ENDED) {\n return 'end';\n } else if (state & STATE_CHANGED) {\n return 'move';\n } else if (state & STATE_BEGAN) {\n return 'start';\n }\n return '';\n}\n\n/**\n * direction cons to string\n * @param {Const} direction\n * @returns {String}\n */\nfunction directionStr(direction) {\n if (direction == DIRECTION_DOWN) {\n return 'down';\n } else if (direction == DIRECTION_UP) {\n return 'up';\n } else if (direction == DIRECTION_LEFT) {\n return 'left';\n } else if (direction == DIRECTION_RIGHT) {\n return 'right';\n }\n return '';\n}\n\n/**\n * get a recognizer by name if it is bound to a manager\n * @param {Recognizer|String} otherRecognizer\n * @param {Recognizer} recognizer\n * @returns {Recognizer}\n */\nfunction getRecognizerByNameIfManager(otherRecognizer, recognizer) {\n var manager = recognizer.manager;\n if (manager) {\n return manager.get(otherRecognizer);\n }\n return otherRecognizer;\n}\n\n/**\n * This recognizer is just used as a base for the simple attribute recognizers.\n * @constructor\n * @extends Recognizer\n */\nfunction AttrRecognizer() {\n Recognizer.apply(this, arguments);\n}\n\ninherit(AttrRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof AttrRecognizer\n */\n defaults: {\n /**\n * @type {Number}\n * @default 1\n */\n pointers: 1\n },\n\n /**\n * Used to check if it the recognizer receives valid input, like input.distance > 10.\n * @memberof AttrRecognizer\n * @param {Object} input\n * @returns {Boolean} recognized\n */\n attrTest: function(input) {\n var optionPointers = this.options.pointers;\n return optionPointers === 0 || input.pointers.length === optionPointers;\n },\n\n /**\n * Process the input and return the state for the recognizer\n * @memberof AttrRecognizer\n * @param {Object} input\n * @returns {*} State\n */\n process: function(input) {\n var state = this.state;\n var eventType = input.eventType;\n\n var isRecognized = state & (STATE_BEGAN | STATE_CHANGED);\n var isValid = this.attrTest(input);\n\n // on cancel input and we've recognized before, return STATE_CANCELLED\n if (isRecognized && (eventType & INPUT_CANCEL || !isValid)) {\n return state | STATE_CANCELLED;\n } else if (isRecognized || isValid) {\n if (eventType & INPUT_END) {\n return state | STATE_ENDED;\n } else if (!(state & STATE_BEGAN)) {\n return STATE_BEGAN;\n }\n return state | STATE_CHANGED;\n }\n return STATE_FAILED;\n }\n});\n\n/**\n * Pan\n * Recognized when the pointer is down and moved in the allowed direction.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction PanRecognizer() {\n AttrRecognizer.apply(this, arguments);\n\n this.pX = null;\n this.pY = null;\n}\n\ninherit(PanRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof PanRecognizer\n */\n defaults: {\n event: 'pan',\n threshold: 10,\n pointers: 1,\n direction: DIRECTION_ALL\n },\n\n getTouchAction: function() {\n var direction = this.options.direction;\n var actions = [];\n if (direction & DIRECTION_HORIZONTAL) {\n actions.push(TOUCH_ACTION_PAN_Y);\n }\n if (direction & DIRECTION_VERTICAL) {\n actions.push(TOUCH_ACTION_PAN_X);\n }\n return actions;\n },\n\n directionTest: function(input) {\n var options = this.options;\n var hasMoved = true;\n var distance = input.distance;\n var direction = input.direction;\n var x = input.deltaX;\n var y = input.deltaY;\n\n // lock to axis?\n if (!(direction & options.direction)) {\n if (options.direction & DIRECTION_HORIZONTAL) {\n direction = (x === 0) ? DIRECTION_NONE : (x < 0) ? DIRECTION_LEFT : DIRECTION_RIGHT;\n hasMoved = x != this.pX;\n distance = Math.abs(input.deltaX);\n } else {\n direction = (y === 0) ? DIRECTION_NONE : (y < 0) ? DIRECTION_UP : DIRECTION_DOWN;\n hasMoved = y != this.pY;\n distance = Math.abs(input.deltaY);\n }\n }\n input.direction = direction;\n return hasMoved && distance > options.threshold && direction & options.direction;\n },\n\n attrTest: function(input) {\n return AttrRecognizer.prototype.attrTest.call(this, input) &&\n (this.state & STATE_BEGAN || (!(this.state & STATE_BEGAN) && this.directionTest(input)));\n },\n\n emit: function(input) {\n\n this.pX = input.deltaX;\n this.pY = input.deltaY;\n\n var direction = directionStr(input.direction);\n\n if (direction) {\n input.additionalEvent = this.options.event + direction;\n }\n this._super.emit.call(this, input);\n }\n});\n\n/**\n * Pinch\n * Recognized when two or more pointers are moving toward (zoom-in) or away from each other (zoom-out).\n * @constructor\n * @extends AttrRecognizer\n */\nfunction PinchRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(PinchRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof PinchRecognizer\n */\n defaults: {\n event: 'pinch',\n threshold: 0,\n pointers: 2\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_NONE];\n },\n\n attrTest: function(input) {\n return this._super.attrTest.call(this, input) &&\n (Math.abs(input.scale - 1) > this.options.threshold || this.state & STATE_BEGAN);\n },\n\n emit: function(input) {\n if (input.scale !== 1) {\n var inOut = input.scale < 1 ? 'in' : 'out';\n input.additionalEvent = this.options.event + inOut;\n }\n this._super.emit.call(this, input);\n }\n});\n\n/**\n * Press\n * Recognized when the pointer is down for x ms without any movement.\n * @constructor\n * @extends Recognizer\n */\nfunction PressRecognizer() {\n Recognizer.apply(this, arguments);\n\n this._timer = null;\n this._input = null;\n}\n\ninherit(PressRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof PressRecognizer\n */\n defaults: {\n event: 'press',\n pointers: 1,\n time: 251, // minimal time of the pointer to be pressed\n threshold: 9 // a minimal movement is ok, but keep it low\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_AUTO];\n },\n\n process: function(input) {\n var options = this.options;\n var validPointers = input.pointers.length === options.pointers;\n var validMovement = input.distance < options.threshold;\n var validTime = input.deltaTime > options.time;\n\n this._input = input;\n\n // we only allow little movement\n // and we've reached an end event, so a tap is possible\n if (!validMovement || !validPointers || (input.eventType & (INPUT_END | INPUT_CANCEL) && !validTime)) {\n this.reset();\n } else if (input.eventType & INPUT_START) {\n this.reset();\n this._timer = setTimeoutContext(function() {\n this.state = STATE_RECOGNIZED;\n this.tryEmit();\n }, options.time, this);\n } else if (input.eventType & INPUT_END) {\n return STATE_RECOGNIZED;\n }\n return STATE_FAILED;\n },\n\n reset: function() {\n clearTimeout(this._timer);\n },\n\n emit: function(input) {\n if (this.state !== STATE_RECOGNIZED) {\n return;\n }\n\n if (input && (input.eventType & INPUT_END)) {\n this.manager.emit(this.options.event + 'up', input);\n } else {\n this._input.timeStamp = now();\n this.manager.emit(this.options.event, this._input);\n }\n }\n});\n\n/**\n * Rotate\n * Recognized when two or more pointer are moving in a circular motion.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction RotateRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(RotateRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof RotateRecognizer\n */\n defaults: {\n event: 'rotate',\n threshold: 0,\n pointers: 2\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_NONE];\n },\n\n attrTest: function(input) {\n return this._super.attrTest.call(this, input) &&\n (Math.abs(input.rotation) > this.options.threshold || this.state & STATE_BEGAN);\n }\n});\n\n/**\n * Swipe\n * Recognized when the pointer is moving fast (velocity), with enough distance in the allowed direction.\n * @constructor\n * @extends AttrRecognizer\n */\nfunction SwipeRecognizer() {\n AttrRecognizer.apply(this, arguments);\n}\n\ninherit(SwipeRecognizer, AttrRecognizer, {\n /**\n * @namespace\n * @memberof SwipeRecognizer\n */\n defaults: {\n event: 'swipe',\n threshold: 10,\n velocity: 0.3,\n direction: DIRECTION_HORIZONTAL | DIRECTION_VERTICAL,\n pointers: 1\n },\n\n getTouchAction: function() {\n return PanRecognizer.prototype.getTouchAction.call(this);\n },\n\n attrTest: function(input) {\n var direction = this.options.direction;\n var velocity;\n\n if (direction & (DIRECTION_HORIZONTAL | DIRECTION_VERTICAL)) {\n velocity = input.overallVelocity;\n } else if (direction & DIRECTION_HORIZONTAL) {\n velocity = input.overallVelocityX;\n } else if (direction & DIRECTION_VERTICAL) {\n velocity = input.overallVelocityY;\n }\n\n return this._super.attrTest.call(this, input) &&\n direction & input.offsetDirection &&\n input.distance > this.options.threshold &&\n input.maxPointers == this.options.pointers &&\n abs(velocity) > this.options.velocity && input.eventType & INPUT_END;\n },\n\n emit: function(input) {\n var direction = directionStr(input.offsetDirection);\n if (direction) {\n this.manager.emit(this.options.event + direction, input);\n }\n\n this.manager.emit(this.options.event, input);\n }\n});\n\n/**\n * A tap is ecognized when the pointer is doing a small tap/click. Multiple taps are recognized if they occur\n * between the given interval and position. The delay option can be used to recognize multi-taps without firing\n * a single tap.\n *\n * The eventData from the emitted event contains the property `tapCount`, which contains the amount of\n * multi-taps being recognized.\n * @constructor\n * @extends Recognizer\n */\nfunction TapRecognizer() {\n Recognizer.apply(this, arguments);\n\n // previous time and center,\n // used for tap counting\n this.pTime = false;\n this.pCenter = false;\n\n this._timer = null;\n this._input = null;\n this.count = 0;\n}\n\ninherit(TapRecognizer, Recognizer, {\n /**\n * @namespace\n * @memberof PinchRecognizer\n */\n defaults: {\n event: 'tap',\n pointers: 1,\n taps: 1,\n interval: 300, // max time between the multi-tap taps\n time: 250, // max time of the pointer to be down (like finger on the screen)\n threshold: 9, // a minimal movement is ok, but keep it low\n posThreshold: 10 // a multi-tap can be a bit off the initial position\n },\n\n getTouchAction: function() {\n return [TOUCH_ACTION_MANIPULATION];\n },\n\n process: function(input) {\n var options = this.options;\n\n var validPointers = input.pointers.length === options.pointers;\n var validMovement = input.distance < options.threshold;\n var validTouchTime = input.deltaTime < options.time;\n\n this.reset();\n\n if ((input.eventType & INPUT_START) && (this.count === 0)) {\n return this.failTimeout();\n }\n\n // we only allow little movement\n // and we've reached an end event, so a tap is possible\n if (validMovement && validTouchTime && validPointers) {\n if (input.eventType != INPUT_END) {\n return this.failTimeout();\n }\n\n var validInterval = this.pTime ? (input.timeStamp - this.pTime < options.interval) : true;\n var validMultiTap = !this.pCenter || getDistance(this.pCenter, input.center) < options.posThreshold;\n\n this.pTime = input.timeStamp;\n this.pCenter = input.center;\n\n if (!validMultiTap || !validInterval) {\n this.count = 1;\n } else {\n this.count += 1;\n }\n\n this._input = input;\n\n // if tap count matches we have recognized it,\n // else it has began recognizing...\n var tapCount = this.count % options.taps;\n if (tapCount === 0) {\n // no failing requirements, immediately trigger the tap event\n // or wait as long as the multitap interval to trigger\n if (!this.hasRequireFailures()) {\n return STATE_RECOGNIZED;\n } else {\n this._timer = setTimeoutContext(function() {\n this.state = STATE_RECOGNIZED;\n this.tryEmit();\n }, options.interval, this);\n return STATE_BEGAN;\n }\n }\n }\n return STATE_FAILED;\n },\n\n failTimeout: function() {\n this._timer = setTimeoutContext(function() {\n this.state = STATE_FAILED;\n }, this.options.interval, this);\n return STATE_FAILED;\n },\n\n reset: function() {\n clearTimeout(this._timer);\n },\n\n emit: function() {\n if (this.state == STATE_RECOGNIZED) {\n this._input.tapCount = this.count;\n this.manager.emit(this.options.event, this._input);\n }\n }\n});\n\n/**\n * Simple way to create a manager with a default set of recognizers.\n * @param {HTMLElement} element\n * @param {Object} [options]\n * @constructor\n */\nfunction Hammer(element, options) {\n options = options || {};\n options.recognizers = ifUndefined(options.recognizers, Hammer.defaults.preset);\n return new Manager(element, options);\n}\n\n/**\n * @const {string}\n */\nHammer.VERSION = '2.0.7';\n\n/**\n * default settings\n * @namespace\n */\nHammer.defaults = {\n /**\n * set if DOM events are being triggered.\n * But this is slower and unused by simple implementations, so disabled by default.\n * @type {Boolean}\n * @default false\n */\n domEvents: false,\n\n /**\n * The value for the touchAction property/fallback.\n * When set to `compute` it will magically set the correct value based on the added recognizers.\n * @type {String}\n * @default compute\n */\n touchAction: TOUCH_ACTION_COMPUTE,\n\n /**\n * @type {Boolean}\n * @default true\n */\n enable: true,\n\n /**\n * EXPERIMENTAL FEATURE -- can be removed/changed\n * Change the parent input target element.\n * If Null, then it is being set the to main element.\n * @type {Null|EventTarget}\n * @default null\n */\n inputTarget: null,\n\n /**\n * force an input class\n * @type {Null|Function}\n * @default null\n */\n inputClass: null,\n\n /**\n * Default recognizer setup when calling `Hammer()`\n * When creating a new Manager these will be skipped.\n * @type {Array}\n */\n preset: [\n // RecognizerClass, options, [recognizeWith, ...], [requireFailure, ...]\n [RotateRecognizer, {enable: false}],\n [PinchRecognizer, {enable: false}, ['rotate']],\n [SwipeRecognizer, {direction: DIRECTION_HORIZONTAL}],\n [PanRecognizer, {direction: DIRECTION_HORIZONTAL}, ['swipe']],\n [TapRecognizer],\n [TapRecognizer, {event: 'doubletap', taps: 2}, ['tap']],\n [PressRecognizer]\n ],\n\n /**\n * Some CSS properties can be used to improve the working of Hammer.\n * Add them to this method and they will be set when creating a new Manager.\n * @namespace\n */\n cssProps: {\n /**\n * Disables text selection to improve the dragging gesture. Mainly for desktop browsers.\n * @type {String}\n * @default 'none'\n */\n userSelect: 'none',\n\n /**\n * Disable the Windows Phone grippers when pressing an element.\n * @type {String}\n * @default 'none'\n */\n touchSelect: 'none',\n\n /**\n * Disables the default callout shown when you touch and hold a touch target.\n * On iOS, when you touch and hold a touch target such as a link, Safari displays\n * a callout containing information about the link. This property allows you to disable that callout.\n * @type {String}\n * @default 'none'\n */\n touchCallout: 'none',\n\n /**\n * Specifies whether zooming is enabled. Used by IE10>\n * @type {String}\n * @default 'none'\n */\n contentZooming: 'none',\n\n /**\n * Specifies that an entire element should be draggable instead of its contents. Mainly for desktop browsers.\n * @type {String}\n * @default 'none'\n */\n userDrag: 'none',\n\n /**\n * Overrides the highlight color shown when the user taps a link or a JavaScript\n * clickable element in iOS. This property obeys the alpha value, if specified.\n * @type {String}\n * @default 'rgba(0,0,0,0)'\n */\n tapHighlightColor: 'rgba(0,0,0,0)'\n }\n};\n\nvar STOP = 1;\nvar FORCED_STOP = 2;\n\n/**\n * Manager\n * @param {HTMLElement} element\n * @param {Object} [options]\n * @constructor\n */\nfunction Manager(element, options) {\n this.options = assign({}, Hammer.defaults, options || {});\n\n this.options.inputTarget = this.options.inputTarget || element;\n\n this.handlers = {};\n this.session = {};\n this.recognizers = [];\n this.oldCssProps = {};\n\n this.element = element;\n this.input = createInputInstance(this);\n this.touchAction = new TouchAction(this, this.options.touchAction);\n\n toggleCssProps(this, true);\n\n each(this.options.recognizers, function(item) {\n var recognizer = this.add(new (item[0])(item[1]));\n item[2] && recognizer.recognizeWith(item[2]);\n item[3] && recognizer.requireFailure(item[3]);\n }, this);\n}\n\nManager.prototype = {\n /**\n * set options\n * @param {Object} options\n * @returns {Manager}\n */\n set: function(options) {\n assign(this.options, options);\n\n // Options that need a little more setup\n if (options.touchAction) {\n this.touchAction.update();\n }\n if (options.inputTarget) {\n // Clean up existing event listeners and reinitialize\n this.input.destroy();\n this.input.target = options.inputTarget;\n this.input.init();\n }\n return this;\n },\n\n /**\n * stop recognizing for this session.\n * This session will be discarded, when a new [input]start event is fired.\n * When forced, the recognizer cycle is stopped immediately.\n * @param {Boolean} [force]\n */\n stop: function(force) {\n this.session.stopped = force ? FORCED_STOP : STOP;\n },\n\n /**\n * run the recognizers!\n * called by the inputHandler function on every movement of the pointers (touches)\n * it walks through all the recognizers and tries to detect the gesture that is being made\n * @param {Object} inputData\n */\n recognize: function(inputData) {\n var session = this.session;\n if (session.stopped) {\n return;\n }\n\n // run the touch-action polyfill\n this.touchAction.preventDefaults(inputData);\n\n var recognizer;\n var recognizers = this.recognizers;\n\n // this holds the recognizer that is being recognized.\n // so the recognizer's state needs to be BEGAN, CHANGED, ENDED or RECOGNIZED\n // if no recognizer is detecting a thing, it is set to `null`\n var curRecognizer = session.curRecognizer;\n\n // reset when the last recognizer is recognized\n // or when we're in a new session\n if (!curRecognizer || (curRecognizer && curRecognizer.state & STATE_RECOGNIZED)) {\n curRecognizer = session.curRecognizer = null;\n }\n\n var i = 0;\n while (i < recognizers.length) {\n recognizer = recognizers[i];\n\n // find out if we are allowed try to recognize the input for this one.\n // 1. allow if the session is NOT forced stopped (see the .stop() method)\n // 2. allow if we still haven't recognized a gesture in this session, or the this recognizer is the one\n // that is being recognized.\n // 3. allow if the recognizer is allowed to run simultaneous with the current recognized recognizer.\n // this can be setup with the `recognizeWith()` method on the recognizer.\n if (session.stopped !== FORCED_STOP && ( // 1\n !curRecognizer || recognizer == curRecognizer || // 2\n recognizer.canRecognizeWith(curRecognizer))) { // 3\n recognizer.recognize(inputData);\n } else {\n recognizer.reset();\n }\n\n // if the recognizer has been recognizing the input as a valid gesture, we want to store this one as the\n // current active recognizer. but only if we don't already have an active recognizer\n if (!curRecognizer && recognizer.state & (STATE_BEGAN | STATE_CHANGED | STATE_ENDED)) {\n curRecognizer = session.curRecognizer = recognizer;\n }\n i++;\n }\n },\n\n /**\n * get a recognizer by its event name.\n * @param {Recognizer|String} recognizer\n * @returns {Recognizer|Null}\n */\n get: function(recognizer) {\n if (recognizer instanceof Recognizer) {\n return recognizer;\n }\n\n var recognizers = this.recognizers;\n for (var i = 0; i < recognizers.length; i++) {\n if (recognizers[i].options.event == recognizer) {\n return recognizers[i];\n }\n }\n return null;\n },\n\n /**\n * add a recognizer to the manager\n * existing recognizers with the same event name will be removed\n * @param {Recognizer} recognizer\n * @returns {Recognizer|Manager}\n */\n add: function(recognizer) {\n if (invokeArrayArg(recognizer, 'add', this)) {\n return this;\n }\n\n // remove existing\n var existing = this.get(recognizer.options.event);\n if (existing) {\n this.remove(existing);\n }\n\n this.recognizers.push(recognizer);\n recognizer.manager = this;\n\n this.touchAction.update();\n return recognizer;\n },\n\n /**\n * remove a recognizer by name or instance\n * @param {Recognizer|String} recognizer\n * @returns {Manager}\n */\n remove: function(recognizer) {\n if (invokeArrayArg(recognizer, 'remove', this)) {\n return this;\n }\n\n recognizer = this.get(recognizer);\n\n // let's make sure this recognizer exists\n if (recognizer) {\n var recognizers = this.recognizers;\n var index = inArray(recognizers, recognizer);\n\n if (index !== -1) {\n recognizers.splice(index, 1);\n this.touchAction.update();\n }\n }\n\n return this;\n },\n\n /**\n * bind event\n * @param {String} events\n * @param {Function} handler\n * @returns {EventEmitter} this\n */\n on: function(events, handler) {\n if (events === undefined) {\n return;\n }\n if (handler === undefined) {\n return;\n }\n\n var handlers = this.handlers;\n each(splitStr(events), function(event) {\n handlers[event] = handlers[event] || [];\n handlers[event].push(handler);\n });\n return this;\n },\n\n /**\n * unbind event, leave emit blank to remove all handlers\n * @param {String} events\n * @param {Function} [handler]\n * @returns {EventEmitter} this\n */\n off: function(events, handler) {\n if (events === undefined) {\n return;\n }\n\n var handlers = this.handlers;\n each(splitStr(events), function(event) {\n if (!handler) {\n delete handlers[event];\n } else {\n handlers[event] && handlers[event].splice(inArray(handlers[event], handler), 1);\n }\n });\n return this;\n },\n\n /**\n * emit event to the listeners\n * @param {String} event\n * @param {Object} data\n */\n emit: function(event, data) {\n // we also want to trigger dom events\n if (this.options.domEvents) {\n triggerDomEvent(event, data);\n }\n\n // no handlers, so skip it all\n var handlers = this.handlers[event] && this.handlers[event].slice();\n if (!handlers || !handlers.length) {\n return;\n }\n\n data.type = event;\n data.preventDefault = function() {\n data.srcEvent.preventDefault();\n };\n\n var i = 0;\n while (i < handlers.length) {\n handlers[i](data);\n i++;\n }\n },\n\n /**\n * destroy the manager and unbinds all events\n * it doesn't unbind dom events, that is the user own responsibility\n */\n destroy: function() {\n this.element && toggleCssProps(this, false);\n\n this.handlers = {};\n this.session = {};\n this.input.destroy();\n this.element = null;\n }\n};\n\n/**\n * add/remove the css properties as defined in manager.options.cssProps\n * @param {Manager} manager\n * @param {Boolean} add\n */\nfunction toggleCssProps(manager, add) {\n var element = manager.element;\n if (!element.style) {\n return;\n }\n var prop;\n each(manager.options.cssProps, function(value, name) {\n prop = prefixed(element.style, name);\n if (add) {\n manager.oldCssProps[prop] = element.style[prop];\n element.style[prop] = value;\n } else {\n element.style[prop] = manager.oldCssProps[prop] || '';\n }\n });\n if (!add) {\n manager.oldCssProps = {};\n }\n}\n\n/**\n * trigger dom event\n * @param {String} event\n * @param {Object} data\n */\nfunction triggerDomEvent(event, data) {\n var gestureEvent = document.createEvent('Event');\n gestureEvent.initEvent(event, true, true);\n gestureEvent.gesture = data;\n data.target.dispatchEvent(gestureEvent);\n}\n\nassign(Hammer, {\n INPUT_START: INPUT_START,\n INPUT_MOVE: INPUT_MOVE,\n INPUT_END: INPUT_END,\n INPUT_CANCEL: INPUT_CANCEL,\n\n STATE_POSSIBLE: STATE_POSSIBLE,\n STATE_BEGAN: STATE_BEGAN,\n STATE_CHANGED: STATE_CHANGED,\n STATE_ENDED: STATE_ENDED,\n STATE_RECOGNIZED: STATE_RECOGNIZED,\n STATE_CANCELLED: STATE_CANCELLED,\n STATE_FAILED: STATE_FAILED,\n\n DIRECTION_NONE: DIRECTION_NONE,\n DIRECTION_LEFT: DIRECTION_LEFT,\n DIRECTION_RIGHT: DIRECTION_RIGHT,\n DIRECTION_UP: DIRECTION_UP,\n DIRECTION_DOWN: DIRECTION_DOWN,\n DIRECTION_HORIZONTAL: DIRECTION_HORIZONTAL,\n DIRECTION_VERTICAL: DIRECTION_VERTICAL,\n DIRECTION_ALL: DIRECTION_ALL,\n\n Manager: Manager,\n Input: Input,\n TouchAction: TouchAction,\n\n TouchInput: TouchInput,\n MouseInput: MouseInput,\n PointerEventInput: PointerEventInput,\n TouchMouseInput: TouchMouseInput,\n SingleTouchInput: SingleTouchInput,\n\n Recognizer: Recognizer,\n AttrRecognizer: AttrRecognizer,\n Tap: TapRecognizer,\n Pan: PanRecognizer,\n Swipe: SwipeRecognizer,\n Pinch: PinchRecognizer,\n Rotate: RotateRecognizer,\n Press: PressRecognizer,\n\n on: addEventListeners,\n off: removeEventListeners,\n each: each,\n merge: merge,\n extend: extend,\n assign: assign,\n inherit: inherit,\n bindFn: bindFn,\n prefixed: prefixed\n});\n\n// this prevents errors when Hammer is loaded in the presence of an AMD\n// style loader but by script tag, not by the loader.\nvar freeGlobal = (typeof window !== 'undefined' ? window : (typeof self !== 'undefined' ? self : {})); // jshint ignore:line\nfreeGlobal.Hammer = Hammer;\n\nif (typeof define === 'function' && define.amd) {\n define(function() {\n return Hammer;\n });\n} else if (typeof module != 'undefined' && module.exports) {\n module.exports = Hammer;\n} else {\n window[exportName] = Hammer;\n}\n\n})(window, document, 'Hammer');\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/hammerjs/hammer.js\n ** module id = 52\n ** module chunks = 0\n **/","module.exports = __WEBPACK_EXTERNAL_MODULE_53__;\n\n\n/*****************\n ** WEBPACK FOOTER\n ** external \"TweenLite\"\n ** module id = 53\n ** module chunks = 0\n **/","import Layer from './Layer';\nimport extend from 'lodash.assign';\n\nclass LayerGroup extends Layer {\n constructor(options) {\n var defaults = {\n output: false\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n this._layers = [];\n }\n\n addLayer(layer) {\n this._layers.push(layer);\n return this._world.addLayer(layer);\n }\n\n removeLayer(layer) {\n var layerIndex = this._layers.indexOf(layer);\n\n if (layerIndex > -1) {\n // Remove from this._layers\n this._layers.splice(layerIndex, 1);\n };\n\n this._world.removeLayer(layer);\n }\n\n _onAdd(world) {\n return Promise.resolve(this);\n }\n\n // Destroy the layers and remove them from the scene and memory\n destroy() {\n // TODO: Sometimes this is already null, find out why\n if (this._layers) {\n for (var i = 0; i < this._layers.length; i++) {\n this._layers[i].destroy();\n }\n\n this._layers = null;\n }\n\n super.destroy();\n }\n}\n\nexport default LayerGroup;\n\nvar noNew = function(options) {\n return new LayerGroup(options);\n};\n\nexport {noNew as layerGroup};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/LayerGroup.js\n **/","import TileLayer from './TileLayer';\nimport ImageTile from './ImageTile';\nimport ImageTileLayerBaseMaterial from './ImageTileLayerBaseMaterial';\nimport throttle from 'lodash.throttle';\nimport THREE from 'three';\nimport extend from 'lodash.assign';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// DONE: Find a way to avoid the flashing caused by the gap between old tiles\n// being removed and the new tiles being ready for display\n//\n// DONE: Simplest first step for MVP would be to give each tile mesh the colour\n// of the basemap ground so it blends in a little more, or have a huge ground\n// plane underneath all the tiles that shows through between tile updates.\n//\n// Could keep the old tiles around until the new ones are ready, though they'd\n// probably need to be layered in a way so the old tiles don't overlap new ones,\n// which is similar to how Leaflet approaches this (it has 2 layers)\n//\n// Could keep the tile from the previous quadtree level visible until all 4\n// tiles at the new / current level have finished loading and are displayed.\n// Perhaps by keeping a map of tiles by quadcode and a boolean for each of the\n// child quadcodes showing whether they are loaded and in view. If all true then\n// remove the parent tile, otherwise keep it on a lower layer.\n\n// TODO: Load and display a base layer separate to the LOD grid that is at a low\n// resolution – used as a backup / background to fill in empty areas / distance\n\n// DONE: Fix the issue where some tiles just don't load, or at least the texture\n// never shows up – tends to happen if you quickly zoom in / out past it while\n// it's still loading, leaving a blank space\n\n// TODO: Optimise the request of many image tiles – look at how Leaflet and\n// OpenWebGlobe approach this (eg. batching, queues, etc)\n\n// TODO: Cancel pending tile requests if they get removed from view before they\n// reach a ready state (eg. cancel image requests, etc). Need to ensure that the\n// images are re-requested when the tile is next in scene (even if from cache)\n\n// TODO: Consider not performing an LOD calculation on every frame, instead only\n// on move end so panning, orbiting and zooming stays smooth. Otherwise it's\n// possible for performance to tank if you pan, orbit or zoom rapidly while all\n// the LOD calculations are being made and new tiles requested.\n//\n// Pending tiles should continue to be requested and output to the scene on each\n// frame, but no new LOD calculations should be made.\n\n// This tile layer both updates the quadtree and outputs tiles on every frame\n// (throttled to some amount)\n//\n// This is because the computational complexity of image tiles is generally low\n// and so there isn't much jank when running these calculations and outputs in\n// realtime\n//\n// The benefit to doing this is that the underlying map layer continues to\n// refresh and update during movement, which is an arguably better experience\n\nclass ImageTileLayer extends TileLayer {\n constructor(path, options) {\n var defaults = {\n distance: 300000\n };\n\n options = extend({}, defaults, options);\n\n super(options);\n\n this._path = path;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n super._onAdd(world).then(() => {\n // TODO: Removed because it causes depth buffer intersection issues\n // with layer on top for some reason. Need to work out why and fix.\n //\n // Add base layer\n // var geom = new THREE.PlaneBufferGeometry(2000000, 2000000, 1);\n\n // var baseMaterial;\n // if (this._world._environment._skybox) {\n // baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3', this._world._environment._skybox.getRenderTarget());\n // } else {\n // baseMaterial = ImageTileLayerBaseMaterial('#f5f5f3');\n // }\n\n // var mesh = new THREE.Mesh(geom, baseMaterial);\n\n // // Setting this causes a depth-buffer intersection issue on the\n // // all-the-things example\n // // mesh.renderOrder = -1;\n\n // mesh.rotation.x = -90 * Math.PI / 180;\n\n // // TODO: It might be overkill to receive a shadow on the base layer as it's\n // // rarely seen (good to have if performance difference is negligible)\n // mesh.receiveShadow = true;\n\n // this._baseLayer = mesh;\n // this.add(mesh);\n\n // Trigger initial quadtree calculation on the next frame\n //\n // TODO: This is a hack to ensure the camera is all set up - a better\n // solution should be found\n setTimeout(() => {\n this._calculateLOD();\n this._initEvents();\n }, 0);\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n _initEvents() {\n // Run LOD calculations based on render calls\n //\n // Throttled to 1 LOD calculation per 100ms\n this._throttledWorldUpdate = throttle(this._onWorldUpdate, 100);\n\n this._world.on('preUpdate', this._throttledWorldUpdate, this);\n // this._world.on('move', this._onWorldMove, this);\n }\n\n _onWorldUpdate() {\n this._calculateLOD();\n this._outputTiles();\n }\n\n _onWorldMove(latlon, point) {\n this._moveBaseLayer(point);\n }\n\n _moveBaseLayer(point) {\n this._baseLayer.position.x = point.x;\n this._baseLayer.position.z = point.y;\n }\n\n _createTile(quadcode, layer) {\n return new ImageTile(quadcode, this._path, layer);\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n this._world.off('preUpdate', this._throttledWorldUpdate);\n this._world.off('move', this._onWorldMove);\n\n this._throttledWorldUpdate = null;\n\n // Dispose of mesh and materials\n this._baseLayer.geometry.dispose();\n this._baseLayer.geometry = null;\n\n if (this._baseLayer.material.map) {\n this._baseLayer.material.map.dispose();\n this._baseLayer.material.map = null;\n }\n\n this._baseLayer.material.dispose();\n this._baseLayer.material = null;\n\n this._baseLayer = null;\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default ImageTileLayer;\n\nvar noNew = function(path, options) {\n return new ImageTileLayer(path, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as imageTileLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/ImageTileLayer.js\n **/","import Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport TileCache from './TileCache';\nimport THREE from 'three';\n\n// TODO: Consider removing picking from TileLayer instances as there aren't\n// (m)any situations where it would be practical\n//\n// For example, how would you even know what picking IDs to listen to and what\n// to do with them?\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Consider keeping a single TileLayer / LOD instance running by default\n// that keeps a standard LOD grid for other layers to utilise, rather than\n// having to create their own, unique LOD grid and duplicate calculations when\n// they're going to use the same grid setup anyway\n//\n// It still makes sense to be able to have a custom LOD grid for some layers as\n// they may want to customise things, maybe not even using a quadtree at all!\n//\n// Perhaps it makes sense to split out the quadtree stuff into a singleton and\n// pass in the necessary parameters each time for the calculation step.\n//\n// Either way, it seems silly to force layers to have to create a new LOD grid\n// each time and create extra, duplicated processing every frame.\n\n// TODO: Allow passing in of options to define min/max LOD and a distance to use\n// for culling tiles beyond that distance.\n\n// DONE: Prevent tiles from being loaded if they are further than a certain\n// distance from the camera and are unlikely to be seen anyway\n\n// TODO: Avoid performing LOD calculation when it isn't required. For example,\n// when nothing has changed since the last frame and there are no tiles to be\n// loaded or in need of rendering\n\n// TODO: Only remove tiles from the layer that aren't to be rendered in the\n// current frame – it seems excessive to remove all tiles and re-add them on\n// every single frame, even if it's just array manipulation\n\n// TODO: Fix LOD calculation so min and max LOD can be changed without causing\n// problems (eg. making min above 5 causes all sorts of issues)\n\n// TODO: Reuse THREE objects where possible instead of creating new instances\n// on every LOD calculation\n\n// TODO: Consider not using THREE or LatLon / Point objects in LOD calculations\n// to avoid creating unnecessary memory for garbage collection\n\n// TODO: Prioritise loading of tiles at highest level in the quadtree (those\n// closest to the camera) so visual inconsistancies during loading are minimised\n\nclass TileLayer extends Layer {\n constructor(options) {\n var defaults = {\n picking: false,\n maxCache: 1000,\n maxLOD: 18\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n this._destroy = false;\n\n this._tileCache = new TileCache(this._options.maxCache, tile => {\n this._destroyTile(tile);\n });\n\n // List of tiles from the previous LOD calculation\n this._tileList = [];\n\n // TODO: Work out why changing the minLOD causes loads of issues\n this._minLOD = 3;\n this._maxLOD = this._options.maxLOD;\n\n this._frustum = new THREE.Frustum();\n this._tiles = new THREE.Object3D();\n this._tilesPicking = new THREE.Object3D();\n }\n\n _onAdd(world) {\n this.addToPicking(this._tilesPicking);\n this.add(this._tiles);\n\n return Promise.resolve();\n }\n\n _updateFrustum() {\n var camera = this._world.getCamera();\n var projScreenMatrix = new THREE.Matrix4();\n projScreenMatrix.multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse);\n\n this._frustum.setFromMatrix(camera.projectionMatrix);\n this._frustum.setFromMatrix(new THREE.Matrix4().multiplyMatrices(camera.projectionMatrix, camera.matrixWorldInverse));\n }\n\n _tileInFrustum(tile) {\n var bounds = tile.getBounds();\n return this._frustum.intersectsBox(new THREE.Box3(new THREE.Vector3(bounds[0], 0, bounds[3]), new THREE.Vector3(bounds[2], 0, bounds[1])));\n }\n\n // Update and output tiles from the previous LOD checklist\n _outputTiles() {\n if (!this._tiles || this._destroy) {\n return;\n }\n\n // Remove all tiles from layer\n this._removeTiles();\n\n // Add / re-add tiles\n this._tileList.forEach(tile => {\n // Are the mesh and texture ready?\n //\n // If yes, continue\n // If no, skip\n if (!tile.isReady()) {\n return;\n }\n\n // Add tile to layer (and to scene) if not already there\n this._tiles.add(tile.getMesh());\n\n if (tile.getPickingMesh()) {\n this._tilesPicking.add(tile.getPickingMesh());\n }\n });\n\n // Emit event notifying of new tiles\n this.emit('tilesList', this._tileList.map((tile) => tile));\n }\n\n // Works out tiles in the view frustum and stores them in an array\n //\n // Does not output the tiles, deferring this to _outputTiles()\n _calculateLOD() {\n if (this._stop || !this._world || this._destroy) {\n return;\n }\n\n // var start = performance.now();\n\n var camera = this._world.getCamera();\n\n // 1. Update and retrieve camera frustum\n this._updateFrustum(this._frustum, camera);\n\n // 2. Add the four root items of the quadtree to a check list\n var checkList = this._checklist;\n checkList = [];\n checkList.push(this._requestTile('0', this));\n checkList.push(this._requestTile('1', this));\n checkList.push(this._requestTile('2', this));\n checkList.push(this._requestTile('3', this));\n\n // 3. Call Divide, passing in the check list\n this._divide(checkList);\n\n // // 4. Remove all tiles from layer\n //\n // Moved to _outputTiles() for now\n // this._removeTiles();\n\n // Order tile-list by zoom so nearest tiles are requested first\n checkList.sort((a, b) => {\n return a._quadcode.length < b._quadcode.length;\n });\n\n // 5. Filter the tiles remaining in the check list\n var tileList = checkList.filter((tile, index) => {\n // Skip tile if it's not in the current view frustum\n if (!this._tileInFrustum(tile)) {\n return false;\n }\n\n if (this._options.distance && this._options.distance > 0) {\n // TODO: Can probably speed this up\n var center = tile.getCenter();\n var dist = (new THREE.Vector3(center[0], 0, center[1])).sub(camera.position).length();\n\n // Manual distance limit to cut down on tiles so far away\n if (dist > this._options.distance) {\n return false;\n }\n }\n\n // Does the tile have a mesh?\n //\n // If yes, continue\n // If no, generate tile mesh, request texture and skip\n if (!tile.getMesh() || tile.isAborted()) {\n tile.requestTileAsync();\n }\n\n return true;\n\n // Are the mesh and texture ready?\n //\n // If yes, continue\n // If no, skip\n // if (!tile.isReady()) {\n // return;\n // }\n //\n // // Add tile to layer (and to scene)\n // this._tiles.add(tile.getMesh());\n });\n\n // Get list of tiles that were in the previous update but not the\n // current one (for aborting requests, etc)\n var missingTiles = this._tileList.filter((item) => {\n return !tileList.includes(item);\n });\n\n // Abort tiles that are no longer in view\n missingTiles.forEach((tile) => tile._abortRequest());\n\n this._tileList = tileList;\n\n // console.log(performance.now() - start);\n }\n\n _divide(checkList) {\n var count = 0;\n var currentItem;\n var quadcode;\n\n // 1. Loop until count equals check list length\n while (count != checkList.length) {\n currentItem = checkList[count];\n quadcode = currentItem.getQuadcode();\n\n // 2. Increase count and continue loop if quadcode equals max LOD / zoom\n if (currentItem.length === this._maxLOD) {\n count++;\n continue;\n }\n\n // 3. Else, calculate screen-space error metric for quadcode\n if (this._screenSpaceError(currentItem)) {\n // 4. If error is sufficient...\n\n // 4a. Remove parent item from the check list\n checkList.splice(count, 1);\n\n // 4b. Add 4 child items to the check list\n checkList.push(this._requestTile(quadcode + '0', this));\n checkList.push(this._requestTile(quadcode + '1', this));\n checkList.push(this._requestTile(quadcode + '2', this));\n checkList.push(this._requestTile(quadcode + '3', this));\n\n // 4d. Continue the loop without increasing count\n continue;\n } else {\n // 5. Else, increase count and continue loop\n count++;\n }\n }\n }\n\n _screenSpaceError(tile) {\n var minDepth = this._minLOD;\n var maxDepth = this._maxLOD;\n\n var quadcode = tile.getQuadcode();\n\n var camera = this._world.getCamera();\n\n // Tweak this value to refine specific point that each quad is subdivided\n //\n // It's used to multiple the dimensions of the tile sides before\n // comparing against the tile distance from camera\n var quality = 3.0;\n\n // 1. Return false if quadcode length equals maxDepth (stop dividing)\n if (quadcode.length === maxDepth) {\n return false;\n }\n\n // 2. Return true if quadcode length is less than minDepth\n if (quadcode.length < minDepth) {\n return true;\n }\n\n // 3. Return false if quadcode bounds are not in view frustum\n if (!this._tileInFrustum(tile)) {\n return false;\n }\n\n var center = tile.getCenter();\n\n // 4. Calculate screen-space error metric\n // TODO: Use closest distance to one of the 4 tile corners\n var dist = (new THREE.Vector3(center[0], 0, center[1])).sub(camera.position).length();\n\n var error = quality * tile.getSide() / dist;\n\n // 5. Return true if error is greater than 1.0, else return false\n return (error > 1.0);\n }\n\n _removeTiles() {\n if (!this._tiles || !this._tiles.children) {\n return;\n }\n\n for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n this._tiles.remove(this._tiles.children[i]);\n }\n\n if (!this._tilesPicking || !this._tilesPicking.children) {\n return;\n }\n\n for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n this._tilesPicking.remove(this._tilesPicking.children[i]);\n }\n }\n\n // Return a new tile instance\n _createTile(quadcode, layer) {}\n\n // Get a cached tile or request a new one if not in cache\n _requestTile(quadcode, layer) {\n var tile = this._tileCache.getTile(quadcode);\n\n if (!tile) {\n // Set up a brand new tile\n tile = this._createTile(quadcode, layer);\n\n // Add tile to cache, though it won't be ready yet as the data is being\n // requested from various places asynchronously\n this._tileCache.setTile(quadcode, tile);\n }\n\n return tile;\n }\n\n _destroyTile(tile) {\n // Remove tile from scene\n this._tiles.remove(tile.getMesh());\n\n // Delete any references to the tile within this component\n\n // Call destory on tile instance\n tile.destroy();\n }\n\n show() {\n this._stop = false;\n\n if (this._tilesPicking) {\n this._tilesPicking.visible = true;\n }\n\n this._calculateLOD();\n super.show();\n }\n\n hide() {\n this._stop = true;\n\n if (this._tilesPicking) {\n this._tilesPicking.visible = false;\n }\n\n super.hide();\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n this._destroy = true;\n\n if (this._tiles.children) {\n // Remove all tiles\n for (var i = this._tiles.children.length - 1; i >= 0; i--) {\n this._tiles.remove(this._tiles.children[i]);\n }\n }\n\n // Remove tile from picking scene\n this.removeFromPicking(this._tilesPicking);\n\n if (this._tilesPicking.children) {\n // Remove all tiles\n for (var i = this._tilesPicking.children.length - 1; i >= 0; i--) {\n this._tilesPicking.remove(this._tilesPicking.children[i]);\n }\n }\n\n this._tileCache.destroy();\n this._tileCache = null;\n\n this._tiles = null;\n this._tilesPicking = null;\n this._frustum = null;\n\n super.destroy();\n }\n}\n\nexport default TileLayer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/TileLayer.js\n **/","import LRUCache from 'lru-cache';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// This process is based on a similar approach taken by OpenWebGlobe\n// See: https://github.com/OpenWebGlobe/WebViewer/blob/master/source/core/globecache.js\n\nclass TileCache {\n constructor(cacheLimit, onDestroyTile) {\n this._cache = LRUCache({\n max: cacheLimit,\n dispose: (key, tile) => {\n onDestroyTile(tile);\n }\n });\n }\n\n // Returns true if all specified tile providers are ready to be used\n // Otherwise, returns false\n isReady() {\n return false;\n }\n\n // Get a cached tile without requesting a new one\n getTile(quadcode) {\n return this._cache.get(quadcode);\n }\n\n // Add tile to cache\n setTile(quadcode, tile) {\n this._cache.set(quadcode, tile);\n }\n\n // Destroy the cache and remove it from memory\n //\n // TODO: Call destroy method on items in cache\n destroy() {\n this._cache.reset();\n this._cache = null;\n }\n}\n\nexport default TileCache;\n\nvar noNew = function(cacheLimit, onDestroyTile) {\n return new TileCache(cacheLimit, onDestroyTile);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as tileCache};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/TileCache.js\n **/","module.exports = LRUCache\n\n// This will be a proper iterable 'Map' in engines that support it,\n// or a fakey-fake PseudoMap in older versions.\nvar Map = require('pseudomap')\nvar util = require('util')\n\n// A linked list to keep track of recently-used-ness\nvar Yallist = require('yallist')\n\n// use symbols if possible, otherwise just _props\nvar symbols = {}\nvar hasSymbol = typeof Symbol === 'function'\nvar makeSymbol\n/* istanbul ignore if */\nif (hasSymbol) {\n makeSymbol = function (key) {\n return Symbol.for(key)\n }\n} else {\n makeSymbol = function (key) {\n return '_' + key\n }\n}\n\nfunction priv (obj, key, val) {\n var sym\n if (symbols[key]) {\n sym = symbols[key]\n } else {\n sym = makeSymbol(key)\n symbols[key] = sym\n }\n if (arguments.length === 2) {\n return obj[sym]\n } else {\n obj[sym] = val\n return val\n }\n}\n\nfunction naiveLength () { return 1 }\n\n// lruList is a yallist where the head is the youngest\n// item, and the tail is the oldest. the list contains the Hit\n// objects as the entries.\n// Each Hit object has a reference to its Yallist.Node. This\n// never changes.\n//\n// cache is a Map (or PseudoMap) that matches the keys to\n// the Yallist.Node object.\nfunction LRUCache (options) {\n if (!(this instanceof LRUCache)) {\n return new LRUCache(options)\n }\n\n if (typeof options === 'number') {\n options = { max: options }\n }\n\n if (!options) {\n options = {}\n }\n\n var max = priv(this, 'max', options.max)\n // Kind of weird to have a default max of Infinity, but oh well.\n if (!max ||\n !(typeof max === 'number') ||\n max <= 0) {\n priv(this, 'max', Infinity)\n }\n\n var lc = options.length || naiveLength\n if (typeof lc !== 'function') {\n lc = naiveLength\n }\n priv(this, 'lengthCalculator', lc)\n\n priv(this, 'allowStale', options.stale || false)\n priv(this, 'maxAge', options.maxAge || 0)\n priv(this, 'dispose', options.dispose)\n this.reset()\n}\n\n// resize the cache when the max changes.\nObject.defineProperty(LRUCache.prototype, 'max', {\n set: function (mL) {\n if (!mL || !(typeof mL === 'number') || mL <= 0) {\n mL = Infinity\n }\n priv(this, 'max', mL)\n trim(this)\n },\n get: function () {\n return priv(this, 'max')\n },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'allowStale', {\n set: function (allowStale) {\n priv(this, 'allowStale', !!allowStale)\n },\n get: function () {\n return priv(this, 'allowStale')\n },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'maxAge', {\n set: function (mA) {\n if (!mA || !(typeof mA === 'number') || mA < 0) {\n mA = 0\n }\n priv(this, 'maxAge', mA)\n trim(this)\n },\n get: function () {\n return priv(this, 'maxAge')\n },\n enumerable: true\n})\n\n// resize the cache when the lengthCalculator changes.\nObject.defineProperty(LRUCache.prototype, 'lengthCalculator', {\n set: function (lC) {\n if (typeof lC !== 'function') {\n lC = naiveLength\n }\n if (lC !== priv(this, 'lengthCalculator')) {\n priv(this, 'lengthCalculator', lC)\n priv(this, 'length', 0)\n priv(this, 'lruList').forEach(function (hit) {\n hit.length = priv(this, 'lengthCalculator').call(this, hit.value, hit.key)\n priv(this, 'length', priv(this, 'length') + hit.length)\n }, this)\n }\n trim(this)\n },\n get: function () { return priv(this, 'lengthCalculator') },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'length', {\n get: function () { return priv(this, 'length') },\n enumerable: true\n})\n\nObject.defineProperty(LRUCache.prototype, 'itemCount', {\n get: function () { return priv(this, 'lruList').length },\n enumerable: true\n})\n\nLRUCache.prototype.rforEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = priv(this, 'lruList').tail; walker !== null;) {\n var prev = walker.prev\n forEachStep(this, fn, walker, thisp)\n walker = prev\n }\n}\n\nfunction forEachStep (self, fn, node, thisp) {\n var hit = node.value\n if (isStale(self, hit)) {\n del(self, node)\n if (!priv(self, 'allowStale')) {\n hit = undefined\n }\n }\n if (hit) {\n fn.call(thisp, hit.value, hit.key, self)\n }\n}\n\nLRUCache.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = priv(this, 'lruList').head; walker !== null;) {\n var next = walker.next\n forEachStep(this, fn, walker, thisp)\n walker = next\n }\n}\n\nLRUCache.prototype.keys = function () {\n return priv(this, 'lruList').toArray().map(function (k) {\n return k.key\n }, this)\n}\n\nLRUCache.prototype.values = function () {\n return priv(this, 'lruList').toArray().map(function (k) {\n return k.value\n }, this)\n}\n\nLRUCache.prototype.reset = function () {\n if (priv(this, 'dispose') &&\n priv(this, 'lruList') &&\n priv(this, 'lruList').length) {\n priv(this, 'lruList').forEach(function (hit) {\n priv(this, 'dispose').call(this, hit.key, hit.value)\n }, this)\n }\n\n priv(this, 'cache', new Map()) // hash of items by key\n priv(this, 'lruList', new Yallist()) // list of items in order of use recency\n priv(this, 'length', 0) // length of items in the list\n}\n\nLRUCache.prototype.dump = function () {\n return priv(this, 'lruList').map(function (hit) {\n if (!isStale(this, hit)) {\n return {\n k: hit.key,\n v: hit.value,\n e: hit.now + (hit.maxAge || 0)\n }\n }\n }, this).toArray().filter(function (h) {\n return h\n })\n}\n\nLRUCache.prototype.dumpLru = function () {\n return priv(this, 'lruList')\n}\n\nLRUCache.prototype.inspect = function (n, opts) {\n var str = 'LRUCache {'\n var extras = false\n\n var as = priv(this, 'allowStale')\n if (as) {\n str += '\\n allowStale: true'\n extras = true\n }\n\n var max = priv(this, 'max')\n if (max && max !== Infinity) {\n if (extras) {\n str += ','\n }\n str += '\\n max: ' + util.inspect(max, opts)\n extras = true\n }\n\n var maxAge = priv(this, 'maxAge')\n if (maxAge) {\n if (extras) {\n str += ','\n }\n str += '\\n maxAge: ' + util.inspect(maxAge, opts)\n extras = true\n }\n\n var lc = priv(this, 'lengthCalculator')\n if (lc && lc !== naiveLength) {\n if (extras) {\n str += ','\n }\n str += '\\n length: ' + util.inspect(priv(this, 'length'), opts)\n extras = true\n }\n\n var didFirst = false\n priv(this, 'lruList').forEach(function (item) {\n if (didFirst) {\n str += ',\\n '\n } else {\n if (extras) {\n str += ',\\n'\n }\n didFirst = true\n str += '\\n '\n }\n var key = util.inspect(item.key).split('\\n').join('\\n ')\n var val = { value: item.value }\n if (item.maxAge !== maxAge) {\n val.maxAge = item.maxAge\n }\n if (lc !== naiveLength) {\n val.length = item.length\n }\n if (isStale(this, item)) {\n val.stale = true\n }\n\n val = util.inspect(val, opts).split('\\n').join('\\n ')\n str += key + ' => ' + val\n })\n\n if (didFirst || extras) {\n str += '\\n'\n }\n str += '}'\n\n return str\n}\n\nLRUCache.prototype.set = function (key, value, maxAge) {\n maxAge = maxAge || priv(this, 'maxAge')\n\n var now = maxAge ? Date.now() : 0\n var len = priv(this, 'lengthCalculator').call(this, value, key)\n\n if (priv(this, 'cache').has(key)) {\n if (len > priv(this, 'max')) {\n del(this, priv(this, 'cache').get(key))\n return false\n }\n\n var node = priv(this, 'cache').get(key)\n var item = node.value\n\n // dispose of the old one before overwriting\n if (priv(this, 'dispose')) {\n priv(this, 'dispose').call(this, key, item.value)\n }\n\n item.now = now\n item.maxAge = maxAge\n item.value = value\n priv(this, 'length', priv(this, 'length') + (len - item.length))\n item.length = len\n this.get(key)\n trim(this)\n return true\n }\n\n var hit = new Entry(key, value, len, now, maxAge)\n\n // oversized objects fall out of cache automatically.\n if (hit.length > priv(this, 'max')) {\n if (priv(this, 'dispose')) {\n priv(this, 'dispose').call(this, key, value)\n }\n return false\n }\n\n priv(this, 'length', priv(this, 'length') + hit.length)\n priv(this, 'lruList').unshift(hit)\n priv(this, 'cache').set(key, priv(this, 'lruList').head)\n trim(this)\n return true\n}\n\nLRUCache.prototype.has = function (key) {\n if (!priv(this, 'cache').has(key)) return false\n var hit = priv(this, 'cache').get(key).value\n if (isStale(this, hit)) {\n return false\n }\n return true\n}\n\nLRUCache.prototype.get = function (key) {\n return get(this, key, true)\n}\n\nLRUCache.prototype.peek = function (key) {\n return get(this, key, false)\n}\n\nLRUCache.prototype.pop = function () {\n var node = priv(this, 'lruList').tail\n if (!node) return null\n del(this, node)\n return node.value\n}\n\nLRUCache.prototype.del = function (key) {\n del(this, priv(this, 'cache').get(key))\n}\n\nLRUCache.prototype.load = function (arr) {\n // reset the cache\n this.reset()\n\n var now = Date.now()\n // A previous serialized cache has the most recent items first\n for (var l = arr.length - 1; l >= 0; l--) {\n var hit = arr[l]\n var expiresAt = hit.e || 0\n if (expiresAt === 0) {\n // the item was created without expiration in a non aged cache\n this.set(hit.k, hit.v)\n } else {\n var maxAge = expiresAt - now\n // dont add already expired items\n if (maxAge > 0) {\n this.set(hit.k, hit.v, maxAge)\n }\n }\n }\n}\n\nLRUCache.prototype.prune = function () {\n var self = this\n priv(this, 'cache').forEach(function (value, key) {\n get(self, key, false)\n })\n}\n\nfunction get (self, key, doUse) {\n var node = priv(self, 'cache').get(key)\n if (node) {\n var hit = node.value\n if (isStale(self, hit)) {\n del(self, node)\n if (!priv(self, 'allowStale')) hit = undefined\n } else {\n if (doUse) {\n priv(self, 'lruList').unshiftNode(node)\n }\n }\n if (hit) hit = hit.value\n }\n return hit\n}\n\nfunction isStale (self, hit) {\n if (!hit || (!hit.maxAge && !priv(self, 'maxAge'))) {\n return false\n }\n var stale = false\n var diff = Date.now() - hit.now\n if (hit.maxAge) {\n stale = diff > hit.maxAge\n } else {\n stale = priv(self, 'maxAge') && (diff > priv(self, 'maxAge'))\n }\n return stale\n}\n\nfunction trim (self) {\n if (priv(self, 'length') > priv(self, 'max')) {\n for (var walker = priv(self, 'lruList').tail;\n priv(self, 'length') > priv(self, 'max') && walker !== null;) {\n // We know that we're about to delete this one, and also\n // what the next least recently used key will be, so just\n // go ahead and set it now.\n var prev = walker.prev\n del(self, walker)\n walker = prev\n }\n }\n}\n\nfunction del (self, node) {\n if (node) {\n var hit = node.value\n if (priv(self, 'dispose')) {\n priv(self, 'dispose').call(this, hit.key, hit.value)\n }\n priv(self, 'length', priv(self, 'length') - hit.length)\n priv(self, 'cache').delete(hit.key)\n priv(self, 'lruList').removeNode(node)\n }\n}\n\n// classy, since V8 prefers predictable objects.\nfunction Entry (key, value, length, now, maxAge) {\n this.key = key\n this.value = value\n this.length = length\n this.now = now\n this.maxAge = maxAge || 0\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/lru-cache/lib/lru-cache.js\n ** module id = 58\n ** module chunks = 0\n **/","if (process.env.npm_package_name === 'pseudomap' &&\n process.env.npm_lifecycle_script === 'test')\n process.env.TEST_PSEUDOMAP = 'true'\n\nif (typeof Map === 'function' && !process.env.TEST_PSEUDOMAP) {\n module.exports = Map\n} else {\n module.exports = require('./pseudomap')\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/pseudomap/map.js\n ** module id = 59\n ** module chunks = 0\n **/","// shim for using process in browser\n\nvar process = module.exports = {};\n\n// cached from whatever global is present so that test runners that stub it\n// don't break things. But we need to wrap it in a try catch in case it is\n// wrapped in strict mode code which doesn't define any globals. It's inside a\n// function because try/catches deoptimize in certain engines.\n\nvar cachedSetTimeout;\nvar cachedClearTimeout;\n\n(function () {\n try {\n cachedSetTimeout = setTimeout;\n } catch (e) {\n cachedSetTimeout = function () {\n throw new Error('setTimeout is not defined');\n }\n }\n try {\n cachedClearTimeout = clearTimeout;\n } catch (e) {\n cachedClearTimeout = function () {\n throw new Error('clearTimeout is not defined');\n }\n }\n} ())\nvar queue = [];\nvar draining = false;\nvar currentQueue;\nvar queueIndex = -1;\n\nfunction cleanUpNextTick() {\n if (!draining || !currentQueue) {\n return;\n }\n draining = false;\n if (currentQueue.length) {\n queue = currentQueue.concat(queue);\n } else {\n queueIndex = -1;\n }\n if (queue.length) {\n drainQueue();\n }\n}\n\nfunction drainQueue() {\n if (draining) {\n return;\n }\n var timeout = cachedSetTimeout(cleanUpNextTick);\n draining = true;\n\n var len = queue.length;\n while(len) {\n currentQueue = queue;\n queue = [];\n while (++queueIndex < len) {\n if (currentQueue) {\n currentQueue[queueIndex].run();\n }\n }\n queueIndex = -1;\n len = queue.length;\n }\n currentQueue = null;\n draining = false;\n cachedClearTimeout(timeout);\n}\n\nprocess.nextTick = function (fun) {\n var args = new Array(arguments.length - 1);\n if (arguments.length > 1) {\n for (var i = 1; i < arguments.length; i++) {\n args[i - 1] = arguments[i];\n }\n }\n queue.push(new Item(fun, args));\n if (queue.length === 1 && !draining) {\n cachedSetTimeout(drainQueue, 0);\n }\n};\n\n// v8 likes predictible objects\nfunction Item(fun, array) {\n this.fun = fun;\n this.array = array;\n}\nItem.prototype.run = function () {\n this.fun.apply(null, this.array);\n};\nprocess.title = 'browser';\nprocess.browser = true;\nprocess.env = {};\nprocess.argv = [];\nprocess.version = ''; // empty string to avoid regexp issues\nprocess.versions = {};\n\nfunction noop() {}\n\nprocess.on = noop;\nprocess.addListener = noop;\nprocess.once = noop;\nprocess.off = noop;\nprocess.removeListener = noop;\nprocess.removeAllListeners = noop;\nprocess.emit = noop;\n\nprocess.binding = function (name) {\n throw new Error('process.binding is not supported');\n};\n\nprocess.cwd = function () { return '/' };\nprocess.chdir = function (dir) {\n throw new Error('process.chdir is not supported');\n};\nprocess.umask = function() { return 0; };\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/process/browser.js\n ** module id = 60\n ** module chunks = 0\n **/","var hasOwnProperty = Object.prototype.hasOwnProperty\n\nmodule.exports = PseudoMap\n\nfunction PseudoMap (set) {\n if (!(this instanceof PseudoMap)) // whyyyyyyy\n throw new TypeError(\"Constructor PseudoMap requires 'new'\")\n\n this.clear()\n\n if (set) {\n if ((set instanceof PseudoMap) ||\n (typeof Map === 'function' && set instanceof Map))\n set.forEach(function (value, key) {\n this.set(key, value)\n }, this)\n else if (Array.isArray(set))\n set.forEach(function (kv) {\n this.set(kv[0], kv[1])\n }, this)\n else\n throw new TypeError('invalid argument')\n }\n}\n\nPseudoMap.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n Object.keys(this._data).forEach(function (k) {\n if (k !== 'size')\n fn.call(thisp, this._data[k].value, this._data[k].key)\n }, this)\n}\n\nPseudoMap.prototype.has = function (k) {\n return !!find(this._data, k)\n}\n\nPseudoMap.prototype.get = function (k) {\n var res = find(this._data, k)\n return res && res.value\n}\n\nPseudoMap.prototype.set = function (k, v) {\n set(this._data, k, v)\n}\n\nPseudoMap.prototype.delete = function (k) {\n var res = find(this._data, k)\n if (res) {\n delete this._data[res._index]\n this._data.size--\n }\n}\n\nPseudoMap.prototype.clear = function () {\n var data = Object.create(null)\n data.size = 0\n\n Object.defineProperty(this, '_data', {\n value: data,\n enumerable: false,\n configurable: true,\n writable: false\n })\n}\n\nObject.defineProperty(PseudoMap.prototype, 'size', {\n get: function () {\n return this._data.size\n },\n set: function (n) {},\n enumerable: true,\n configurable: true\n})\n\nPseudoMap.prototype.values =\nPseudoMap.prototype.keys =\nPseudoMap.prototype.entries = function () {\n throw new Error('iterators are not implemented in this version')\n}\n\n// Either identical, or both NaN\nfunction same (a, b) {\n return a === b || a !== a && b !== b\n}\n\nfunction Entry (k, v, i) {\n this.key = k\n this.value = v\n this._index = i\n}\n\nfunction find (data, k) {\n for (var i = 0, s = '_' + k, key = s;\n hasOwnProperty.call(data, key);\n key = s + i++) {\n if (same(data[key].key, k))\n return data[key]\n }\n}\n\nfunction set (data, k, v) {\n for (var i = 0, s = '_' + k, key = s;\n hasOwnProperty.call(data, key);\n key = s + i++) {\n if (same(data[key].key, k)) {\n data[key].value = v\n return\n }\n }\n data.size++\n data[key] = new Entry(k, v, key)\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/pseudomap/pseudomap.js\n ** module id = 61\n ** module chunks = 0\n **/","// Copyright Joyent, Inc. and other Node contributors.\n//\n// Permission is hereby granted, free of charge, to any person obtaining a\n// copy of this software and associated documentation files (the\n// \"Software\"), to deal in the Software without restriction, including\n// without limitation the rights to use, copy, modify, merge, publish,\n// distribute, sublicense, and/or sell copies of the Software, and to permit\n// persons to whom the Software is furnished to do so, subject to the\n// following conditions:\n//\n// The above copyright notice and this permission notice shall be included\n// in all copies or substantial portions of the Software.\n//\n// THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS\n// OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF\n// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN\n// NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM,\n// DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR\n// OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE\n// USE OR OTHER DEALINGS IN THE SOFTWARE.\n\nvar formatRegExp = /%[sdj%]/g;\nexports.format = function(f) {\n if (!isString(f)) {\n var objects = [];\n for (var i = 0; i < arguments.length; i++) {\n objects.push(inspect(arguments[i]));\n }\n return objects.join(' ');\n }\n\n var i = 1;\n var args = arguments;\n var len = args.length;\n var str = String(f).replace(formatRegExp, function(x) {\n if (x === '%%') return '%';\n if (i >= len) return x;\n switch (x) {\n case '%s': return String(args[i++]);\n case '%d': return Number(args[i++]);\n case '%j':\n try {\n return JSON.stringify(args[i++]);\n } catch (_) {\n return '[Circular]';\n }\n default:\n return x;\n }\n });\n for (var x = args[i]; i < len; x = args[++i]) {\n if (isNull(x) || !isObject(x)) {\n str += ' ' + x;\n } else {\n str += ' ' + inspect(x);\n }\n }\n return str;\n};\n\n\n// Mark that a method should not be used.\n// Returns a modified function which warns once by default.\n// If --no-deprecation is set, then it is a no-op.\nexports.deprecate = function(fn, msg) {\n // Allow for deprecating things in the process of starting up.\n if (isUndefined(global.process)) {\n return function() {\n return exports.deprecate(fn, msg).apply(this, arguments);\n };\n }\n\n if (process.noDeprecation === true) {\n return fn;\n }\n\n var warned = false;\n function deprecated() {\n if (!warned) {\n if (process.throwDeprecation) {\n throw new Error(msg);\n } else if (process.traceDeprecation) {\n console.trace(msg);\n } else {\n console.error(msg);\n }\n warned = true;\n }\n return fn.apply(this, arguments);\n }\n\n return deprecated;\n};\n\n\nvar debugs = {};\nvar debugEnviron;\nexports.debuglog = function(set) {\n if (isUndefined(debugEnviron))\n debugEnviron = process.env.NODE_DEBUG || '';\n set = set.toUpperCase();\n if (!debugs[set]) {\n if (new RegExp('\\\\b' + set + '\\\\b', 'i').test(debugEnviron)) {\n var pid = process.pid;\n debugs[set] = function() {\n var msg = exports.format.apply(exports, arguments);\n console.error('%s %d: %s', set, pid, msg);\n };\n } else {\n debugs[set] = function() {};\n }\n }\n return debugs[set];\n};\n\n\n/**\n * Echos the value of a value. Trys to print the value out\n * in the best way possible given the different types.\n *\n * @param {Object} obj The object to print out.\n * @param {Object} opts Optional options object that alters the output.\n */\n/* legacy: obj, showHidden, depth, colors*/\nfunction inspect(obj, opts) {\n // default options\n var ctx = {\n seen: [],\n stylize: stylizeNoColor\n };\n // legacy...\n if (arguments.length >= 3) ctx.depth = arguments[2];\n if (arguments.length >= 4) ctx.colors = arguments[3];\n if (isBoolean(opts)) {\n // legacy...\n ctx.showHidden = opts;\n } else if (opts) {\n // got an \"options\" object\n exports._extend(ctx, opts);\n }\n // set default options\n if (isUndefined(ctx.showHidden)) ctx.showHidden = false;\n if (isUndefined(ctx.depth)) ctx.depth = 2;\n if (isUndefined(ctx.colors)) ctx.colors = false;\n if (isUndefined(ctx.customInspect)) ctx.customInspect = true;\n if (ctx.colors) ctx.stylize = stylizeWithColor;\n return formatValue(ctx, obj, ctx.depth);\n}\nexports.inspect = inspect;\n\n\n// http://en.wikipedia.org/wiki/ANSI_escape_code#graphics\ninspect.colors = {\n 'bold' : [1, 22],\n 'italic' : [3, 23],\n 'underline' : [4, 24],\n 'inverse' : [7, 27],\n 'white' : [37, 39],\n 'grey' : [90, 39],\n 'black' : [30, 39],\n 'blue' : [34, 39],\n 'cyan' : [36, 39],\n 'green' : [32, 39],\n 'magenta' : [35, 39],\n 'red' : [31, 39],\n 'yellow' : [33, 39]\n};\n\n// Don't use 'blue' not visible on cmd.exe\ninspect.styles = {\n 'special': 'cyan',\n 'number': 'yellow',\n 'boolean': 'yellow',\n 'undefined': 'grey',\n 'null': 'bold',\n 'string': 'green',\n 'date': 'magenta',\n // \"name\": intentionally not styling\n 'regexp': 'red'\n};\n\n\nfunction stylizeWithColor(str, styleType) {\n var style = inspect.styles[styleType];\n\n if (style) {\n return '\\u001b[' + inspect.colors[style][0] + 'm' + str +\n '\\u001b[' + inspect.colors[style][1] + 'm';\n } else {\n return str;\n }\n}\n\n\nfunction stylizeNoColor(str, styleType) {\n return str;\n}\n\n\nfunction arrayToHash(array) {\n var hash = {};\n\n array.forEach(function(val, idx) {\n hash[val] = true;\n });\n\n return hash;\n}\n\n\nfunction formatValue(ctx, value, recurseTimes) {\n // Provide a hook for user-specified inspect functions.\n // Check that value is an object with an inspect function on it\n if (ctx.customInspect &&\n value &&\n isFunction(value.inspect) &&\n // Filter out the util module, it's inspect function is special\n value.inspect !== exports.inspect &&\n // Also filter out any prototype objects using the circular check.\n !(value.constructor && value.constructor.prototype === value)) {\n var ret = value.inspect(recurseTimes, ctx);\n if (!isString(ret)) {\n ret = formatValue(ctx, ret, recurseTimes);\n }\n return ret;\n }\n\n // Primitive types cannot have properties\n var primitive = formatPrimitive(ctx, value);\n if (primitive) {\n return primitive;\n }\n\n // Look up the keys of the object.\n var keys = Object.keys(value);\n var visibleKeys = arrayToHash(keys);\n\n if (ctx.showHidden) {\n keys = Object.getOwnPropertyNames(value);\n }\n\n // IE doesn't make error fields non-enumerable\n // http://msdn.microsoft.com/en-us/library/ie/dww52sbt(v=vs.94).aspx\n if (isError(value)\n && (keys.indexOf('message') >= 0 || keys.indexOf('description') >= 0)) {\n return formatError(value);\n }\n\n // Some type of object without properties can be shortcutted.\n if (keys.length === 0) {\n if (isFunction(value)) {\n var name = value.name ? ': ' + value.name : '';\n return ctx.stylize('[Function' + name + ']', 'special');\n }\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n }\n if (isDate(value)) {\n return ctx.stylize(Date.prototype.toString.call(value), 'date');\n }\n if (isError(value)) {\n return formatError(value);\n }\n }\n\n var base = '', array = false, braces = ['{', '}'];\n\n // Make Array say that they are Array\n if (isArray(value)) {\n array = true;\n braces = ['[', ']'];\n }\n\n // Make functions say that they are functions\n if (isFunction(value)) {\n var n = value.name ? ': ' + value.name : '';\n base = ' [Function' + n + ']';\n }\n\n // Make RegExps say that they are RegExps\n if (isRegExp(value)) {\n base = ' ' + RegExp.prototype.toString.call(value);\n }\n\n // Make dates with properties first say the date\n if (isDate(value)) {\n base = ' ' + Date.prototype.toUTCString.call(value);\n }\n\n // Make error with message first say the error\n if (isError(value)) {\n base = ' ' + formatError(value);\n }\n\n if (keys.length === 0 && (!array || value.length == 0)) {\n return braces[0] + base + braces[1];\n }\n\n if (recurseTimes < 0) {\n if (isRegExp(value)) {\n return ctx.stylize(RegExp.prototype.toString.call(value), 'regexp');\n } else {\n return ctx.stylize('[Object]', 'special');\n }\n }\n\n ctx.seen.push(value);\n\n var output;\n if (array) {\n output = formatArray(ctx, value, recurseTimes, visibleKeys, keys);\n } else {\n output = keys.map(function(key) {\n return formatProperty(ctx, value, recurseTimes, visibleKeys, key, array);\n });\n }\n\n ctx.seen.pop();\n\n return reduceToSingleString(output, base, braces);\n}\n\n\nfunction formatPrimitive(ctx, value) {\n if (isUndefined(value))\n return ctx.stylize('undefined', 'undefined');\n if (isString(value)) {\n var simple = '\\'' + JSON.stringify(value).replace(/^\"|\"$/g, '')\n .replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"') + '\\'';\n return ctx.stylize(simple, 'string');\n }\n if (isNumber(value))\n return ctx.stylize('' + value, 'number');\n if (isBoolean(value))\n return ctx.stylize('' + value, 'boolean');\n // For some reason typeof null is \"object\", so special case here.\n if (isNull(value))\n return ctx.stylize('null', 'null');\n}\n\n\nfunction formatError(value) {\n return '[' + Error.prototype.toString.call(value) + ']';\n}\n\n\nfunction formatArray(ctx, value, recurseTimes, visibleKeys, keys) {\n var output = [];\n for (var i = 0, l = value.length; i < l; ++i) {\n if (hasOwnProperty(value, String(i))) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n String(i), true));\n } else {\n output.push('');\n }\n }\n keys.forEach(function(key) {\n if (!key.match(/^\\d+$/)) {\n output.push(formatProperty(ctx, value, recurseTimes, visibleKeys,\n key, true));\n }\n });\n return output;\n}\n\n\nfunction formatProperty(ctx, value, recurseTimes, visibleKeys, key, array) {\n var name, str, desc;\n desc = Object.getOwnPropertyDescriptor(value, key) || { value: value[key] };\n if (desc.get) {\n if (desc.set) {\n str = ctx.stylize('[Getter/Setter]', 'special');\n } else {\n str = ctx.stylize('[Getter]', 'special');\n }\n } else {\n if (desc.set) {\n str = ctx.stylize('[Setter]', 'special');\n }\n }\n if (!hasOwnProperty(visibleKeys, key)) {\n name = '[' + key + ']';\n }\n if (!str) {\n if (ctx.seen.indexOf(desc.value) < 0) {\n if (isNull(recurseTimes)) {\n str = formatValue(ctx, desc.value, null);\n } else {\n str = formatValue(ctx, desc.value, recurseTimes - 1);\n }\n if (str.indexOf('\\n') > -1) {\n if (array) {\n str = str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n').substr(2);\n } else {\n str = '\\n' + str.split('\\n').map(function(line) {\n return ' ' + line;\n }).join('\\n');\n }\n }\n } else {\n str = ctx.stylize('[Circular]', 'special');\n }\n }\n if (isUndefined(name)) {\n if (array && key.match(/^\\d+$/)) {\n return str;\n }\n name = JSON.stringify('' + key);\n if (name.match(/^\"([a-zA-Z_][a-zA-Z_0-9]*)\"$/)) {\n name = name.substr(1, name.length - 2);\n name = ctx.stylize(name, 'name');\n } else {\n name = name.replace(/'/g, \"\\\\'\")\n .replace(/\\\\\"/g, '\"')\n .replace(/(^\"|\"$)/g, \"'\");\n name = ctx.stylize(name, 'string');\n }\n }\n\n return name + ': ' + str;\n}\n\n\nfunction reduceToSingleString(output, base, braces) {\n var numLinesEst = 0;\n var length = output.reduce(function(prev, cur) {\n numLinesEst++;\n if (cur.indexOf('\\n') >= 0) numLinesEst++;\n return prev + cur.replace(/\\u001b\\[\\d\\d?m/g, '').length + 1;\n }, 0);\n\n if (length > 60) {\n return braces[0] +\n (base === '' ? '' : base + '\\n ') +\n ' ' +\n output.join(',\\n ') +\n ' ' +\n braces[1];\n }\n\n return braces[0] + base + ' ' + output.join(', ') + ' ' + braces[1];\n}\n\n\n// NOTE: These type checking functions intentionally don't use `instanceof`\n// because it is fragile and can be easily faked with `Object.create()`.\nfunction isArray(ar) {\n return Array.isArray(ar);\n}\nexports.isArray = isArray;\n\nfunction isBoolean(arg) {\n return typeof arg === 'boolean';\n}\nexports.isBoolean = isBoolean;\n\nfunction isNull(arg) {\n return arg === null;\n}\nexports.isNull = isNull;\n\nfunction isNullOrUndefined(arg) {\n return arg == null;\n}\nexports.isNullOrUndefined = isNullOrUndefined;\n\nfunction isNumber(arg) {\n return typeof arg === 'number';\n}\nexports.isNumber = isNumber;\n\nfunction isString(arg) {\n return typeof arg === 'string';\n}\nexports.isString = isString;\n\nfunction isSymbol(arg) {\n return typeof arg === 'symbol';\n}\nexports.isSymbol = isSymbol;\n\nfunction isUndefined(arg) {\n return arg === void 0;\n}\nexports.isUndefined = isUndefined;\n\nfunction isRegExp(re) {\n return isObject(re) && objectToString(re) === '[object RegExp]';\n}\nexports.isRegExp = isRegExp;\n\nfunction isObject(arg) {\n return typeof arg === 'object' && arg !== null;\n}\nexports.isObject = isObject;\n\nfunction isDate(d) {\n return isObject(d) && objectToString(d) === '[object Date]';\n}\nexports.isDate = isDate;\n\nfunction isError(e) {\n return isObject(e) &&\n (objectToString(e) === '[object Error]' || e instanceof Error);\n}\nexports.isError = isError;\n\nfunction isFunction(arg) {\n return typeof arg === 'function';\n}\nexports.isFunction = isFunction;\n\nfunction isPrimitive(arg) {\n return arg === null ||\n typeof arg === 'boolean' ||\n typeof arg === 'number' ||\n typeof arg === 'string' ||\n typeof arg === 'symbol' || // ES6 symbol\n typeof arg === 'undefined';\n}\nexports.isPrimitive = isPrimitive;\n\nexports.isBuffer = require('./support/isBuffer');\n\nfunction objectToString(o) {\n return Object.prototype.toString.call(o);\n}\n\n\nfunction pad(n) {\n return n < 10 ? '0' + n.toString(10) : n.toString(10);\n}\n\n\nvar months = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep',\n 'Oct', 'Nov', 'Dec'];\n\n// 26 Feb 16:19:34\nfunction timestamp() {\n var d = new Date();\n var time = [pad(d.getHours()),\n pad(d.getMinutes()),\n pad(d.getSeconds())].join(':');\n return [d.getDate(), months[d.getMonth()], time].join(' ');\n}\n\n\n// log is just a thin wrapper to console.log that prepends a timestamp\nexports.log = function() {\n console.log('%s - %s', timestamp(), exports.format.apply(exports, arguments));\n};\n\n\n/**\n * Inherit the prototype methods from one constructor into another.\n *\n * The Function.prototype.inherits from lang.js rewritten as a standalone\n * function (not on Function.prototype). NOTE: If this file is to be loaded\n * during bootstrapping this function needs to be rewritten using some native\n * functions as prototype setup using normal JavaScript does not work as\n * expected during bootstrapping (see mirror.js in r114903).\n *\n * @param {function} ctor Constructor function which needs to inherit the\n * prototype.\n * @param {function} superCtor Constructor function to inherit prototype from.\n */\nexports.inherits = require('inherits');\n\nexports._extend = function(origin, add) {\n // Don't do anything if add isn't an object\n if (!add || !isObject(add)) return origin;\n\n var keys = Object.keys(add);\n var i = keys.length;\n while (i--) {\n origin[keys[i]] = add[keys[i]];\n }\n return origin;\n};\n\nfunction hasOwnProperty(obj, prop) {\n return Object.prototype.hasOwnProperty.call(obj, prop);\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/util/util.js\n ** module id = 62\n ** module chunks = 0\n **/","module.exports = function isBuffer(arg) {\n return arg && typeof arg === 'object'\n && typeof arg.copy === 'function'\n && typeof arg.fill === 'function'\n && typeof arg.readUInt8 === 'function';\n}\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/util/support/isBufferBrowser.js\n ** module id = 63\n ** module chunks = 0\n **/","if (typeof Object.create === 'function') {\n // implementation from standard node.js 'util' module\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n ctor.prototype = Object.create(superCtor.prototype, {\n constructor: {\n value: ctor,\n enumerable: false,\n writable: true,\n configurable: true\n }\n });\n };\n} else {\n // old school shim for old browsers\n module.exports = function inherits(ctor, superCtor) {\n ctor.super_ = superCtor\n var TempCtor = function () {}\n TempCtor.prototype = superCtor.prototype\n ctor.prototype = new TempCtor()\n ctor.prototype.constructor = ctor\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/inherits/inherits_browser.js\n ** module id = 64\n ** module chunks = 0\n **/","module.exports = Yallist\n\nYallist.Node = Node\nYallist.create = Yallist\n\nfunction Yallist (list) {\n var self = this\n if (!(self instanceof Yallist)) {\n self = new Yallist()\n }\n\n self.tail = null\n self.head = null\n self.length = 0\n\n if (list && typeof list.forEach === 'function') {\n list.forEach(function (item) {\n self.push(item)\n })\n } else if (arguments.length > 0) {\n for (var i = 0, l = arguments.length; i < l; i++) {\n self.push(arguments[i])\n }\n }\n\n return self\n}\n\nYallist.prototype.removeNode = function (node) {\n if (node.list !== this) {\n throw new Error('removing node which does not belong to this list')\n }\n\n var next = node.next\n var prev = node.prev\n\n if (next) {\n next.prev = prev\n }\n\n if (prev) {\n prev.next = next\n }\n\n if (node === this.head) {\n this.head = next\n }\n if (node === this.tail) {\n this.tail = prev\n }\n\n node.list.length --\n node.next = null\n node.prev = null\n node.list = null\n}\n\nYallist.prototype.unshiftNode = function (node) {\n if (node === this.head) {\n return\n }\n\n if (node.list) {\n node.list.removeNode(node)\n }\n\n var head = this.head\n node.list = this\n node.next = head\n if (head) {\n head.prev = node\n }\n\n this.head = node\n if (!this.tail) {\n this.tail = node\n }\n this.length ++\n}\n\nYallist.prototype.pushNode = function (node) {\n if (node === this.tail) {\n return\n }\n\n if (node.list) {\n node.list.removeNode(node)\n }\n\n var tail = this.tail\n node.list = this\n node.prev = tail\n if (tail) {\n tail.next = node\n }\n\n this.tail = node\n if (!this.head) {\n this.head = node\n }\n this.length ++\n}\n\nYallist.prototype.push = function () {\n for (var i = 0, l = arguments.length; i < l; i++) {\n push(this, arguments[i])\n }\n return this.length\n}\n\nYallist.prototype.unshift = function () {\n for (var i = 0, l = arguments.length; i < l; i++) {\n unshift(this, arguments[i])\n }\n return this.length\n}\n\nYallist.prototype.pop = function () {\n if (!this.tail)\n return undefined\n\n var res = this.tail.value\n this.tail = this.tail.prev\n this.tail.next = null\n this.length --\n return res\n}\n\nYallist.prototype.shift = function () {\n if (!this.head)\n return undefined\n\n var res = this.head.value\n this.head = this.head.next\n this.head.prev = null\n this.length --\n return res\n}\n\nYallist.prototype.forEach = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = this.head, i = 0; walker !== null; i++) {\n fn.call(thisp, walker.value, i, this)\n walker = walker.next\n }\n}\n\nYallist.prototype.forEachReverse = function (fn, thisp) {\n thisp = thisp || this\n for (var walker = this.tail, i = this.length - 1; walker !== null; i--) {\n fn.call(thisp, walker.value, i, this)\n walker = walker.prev\n }\n}\n\nYallist.prototype.get = function (n) {\n for (var i = 0, walker = this.head; walker !== null && i < n; i++) {\n // abort out of the list early if we hit a cycle\n walker = walker.next\n }\n if (i === n && walker !== null) {\n return walker.value\n }\n}\n\nYallist.prototype.getReverse = function (n) {\n for (var i = 0, walker = this.tail; walker !== null && i < n; i++) {\n // abort out of the list early if we hit a cycle\n walker = walker.prev\n }\n if (i === n && walker !== null) {\n return walker.value\n }\n}\n\nYallist.prototype.map = function (fn, thisp) {\n thisp = thisp || this\n var res = new Yallist()\n for (var walker = this.head; walker !== null; ) {\n res.push(fn.call(thisp, walker.value, this))\n walker = walker.next\n }\n return res\n}\n\nYallist.prototype.mapReverse = function (fn, thisp) {\n thisp = thisp || this\n var res = new Yallist()\n for (var walker = this.tail; walker !== null;) {\n res.push(fn.call(thisp, walker.value, this))\n walker = walker.prev\n }\n return res\n}\n\nYallist.prototype.reduce = function (fn, initial) {\n var acc\n var walker = this.head\n if (arguments.length > 1) {\n acc = initial\n } else if (this.head) {\n walker = this.head.next\n acc = this.head.value\n } else {\n throw new TypeError('Reduce of empty list with no initial value')\n }\n\n for (var i = 0; walker !== null; i++) {\n acc = fn(acc, walker.value, i)\n walker = walker.next\n }\n\n return acc\n}\n\nYallist.prototype.reduceReverse = function (fn, initial) {\n var acc\n var walker = this.tail\n if (arguments.length > 1) {\n acc = initial\n } else if (this.tail) {\n walker = this.tail.prev\n acc = this.tail.value\n } else {\n throw new TypeError('Reduce of empty list with no initial value')\n }\n\n for (var i = this.length - 1; walker !== null; i--) {\n acc = fn(acc, walker.value, i)\n walker = walker.prev\n }\n\n return acc\n}\n\nYallist.prototype.toArray = function () {\n var arr = new Array(this.length)\n for (var i = 0, walker = this.head; walker !== null; i++) {\n arr[i] = walker.value\n walker = walker.next\n }\n return arr\n}\n\nYallist.prototype.toArrayReverse = function () {\n var arr = new Array(this.length)\n for (var i = 0, walker = this.tail; walker !== null; i++) {\n arr[i] = walker.value\n walker = walker.prev\n }\n return arr\n}\n\nYallist.prototype.slice = function (from, to) {\n to = to || this.length\n if (to < 0) {\n to += this.length\n }\n from = from || 0\n if (from < 0) {\n from += this.length\n }\n var ret = new Yallist()\n if (to < from || to < 0) {\n return ret\n }\n if (from < 0) {\n from = 0\n }\n if (to > this.length) {\n to = this.length\n }\n for (var i = 0, walker = this.head; walker !== null && i < from; i++) {\n walker = walker.next\n }\n for (; walker !== null && i < to; i++, walker = walker.next) {\n ret.push(walker.value)\n }\n return ret\n}\n\nYallist.prototype.sliceReverse = function (from, to) {\n to = to || this.length\n if (to < 0) {\n to += this.length\n }\n from = from || 0\n if (from < 0) {\n from += this.length\n }\n var ret = new Yallist()\n if (to < from || to < 0) {\n return ret\n }\n if (from < 0) {\n from = 0\n }\n if (to > this.length) {\n to = this.length\n }\n for (var i = this.length, walker = this.tail; walker !== null && i > to; i--) {\n walker = walker.prev\n }\n for (; walker !== null && i > from; i--, walker = walker.prev) {\n ret.push(walker.value)\n }\n return ret\n}\n\nYallist.prototype.reverse = function () {\n var head = this.head\n var tail = this.tail\n for (var walker = head; walker !== null; walker = walker.prev) {\n var p = walker.prev\n walker.prev = walker.next\n walker.next = p\n }\n this.head = tail\n this.tail = head\n return this\n}\n\nfunction push (self, item) {\n self.tail = new Node(item, self.tail, null, self)\n if (!self.head) {\n self.head = self.tail\n }\n self.length ++\n}\n\nfunction unshift (self, item) {\n self.head = new Node(item, null, self.head, self)\n if (!self.tail) {\n self.tail = self.head\n }\n self.length ++\n}\n\nfunction Node (value, prev, next, list) {\n if (!(this instanceof Node)) {\n return new Node(value, prev, next, list)\n }\n\n this.list = list\n this.value = value\n\n if (prev) {\n prev.next = this\n this.prev = prev\n } else {\n this.prev = null\n }\n\n if (next) {\n next.prev = this\n this.next = next\n } else {\n this.next = null\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/yallist/yallist.js\n ** module id = 65\n ** module chunks = 0\n **/","import Tile from './Tile';\nimport BoxHelper from '../../vendor/BoxHelper';\nimport THREE from 'three';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\nclass ImageTile extends Tile {\n constructor(quadcode, path, layer) {\n super(quadcode, path, layer);\n }\n\n // Request data for the tile\n requestTileAsync() {\n // Making this asynchronous really speeds up the LOD framerate\n setTimeout(() => {\n if (!this._mesh) {\n this._mesh = this._createMesh();\n }\n\n this._requestTile();\n }, 0);\n }\n\n destroy() {\n // Cancel any pending requests\n this._abortRequest();\n\n // Clear image reference\n this._image = null;\n\n super.destroy();\n }\n\n _createMesh() {\n // Something went wrong and the tile\n //\n // Possibly removed by the cache before loaded\n if (!this._center) {\n return;\n }\n\n var mesh = new THREE.Object3D();\n var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n\n var material;\n if (!this._world._environment._skybox) {\n material = new THREE.MeshBasicMaterial({\n depthWrite: false\n });\n\n // var material = new THREE.MeshPhongMaterial({\n // depthWrite: false\n // });\n } else {\n // Other MeshStandardMaterial settings\n //\n // material.envMapIntensity will change the amount of colour reflected(?)\n // from the environment map – can be greater than 1 for more intensity\n\n material = new THREE.MeshStandardMaterial({\n depthWrite: false\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMap = this._world._environment._skybox.getRenderTarget();\n }\n\n var localMesh = new THREE.Mesh(geom, material);\n localMesh.rotation.x = -90 * Math.PI / 180;\n\n localMesh.receiveShadow = true;\n\n // Setting this causes a depth-buffer intersection issue on the\n // all-the-things example\n // localMesh.renderOrder = 2;\n\n mesh.add(localMesh);\n\n // Setting this causes a depth-buffer intersection issue on the\n // all-the-things example\n // mesh.renderOrder = 2;\n\n mesh.position.x = this._center[0];\n mesh.position.z = this._center[1];\n\n // var box = new BoxHelper(localMesh);\n // mesh.add(box);\n //\n // mesh.add(this._createDebugMesh());\n\n return mesh;\n }\n\n _createDebugMesh() {\n var canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n\n var context = canvas.getContext('2d');\n context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n context.fillStyle = '#ff0000';\n context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\n var texture = new THREE.Texture(canvas);\n\n // Silky smooth images when tilted\n texture.magFilter = THREE.LinearFilter;\n texture.minFilter = THREE.LinearMipMapLinearFilter;\n\n // TODO: Set this to renderer.getMaxAnisotropy() / 4\n texture.anisotropy = 4;\n\n texture.needsUpdate = true;\n\n var material = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n depthWrite: false\n });\n\n var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n var mesh = new THREE.Mesh(geom, material);\n\n mesh.rotation.x = -90 * Math.PI / 180;\n mesh.position.y = 0.1;\n\n return mesh;\n }\n\n _requestTile() {\n var urlParams = {\n x: this._tile[0],\n y: this._tile[1],\n z: this._tile[2]\n };\n\n var url = this._getTileURL(urlParams);\n\n var image = document.createElement('img');\n\n this._aborted = false;\n\n image.addEventListener('load', event => {\n if (this.isAborted()) {\n return;\n }\n\n var texture = new THREE.Texture();\n\n texture.image = image;\n texture.needsUpdate = true;\n\n // Silky smooth images when tilted\n texture.magFilter = THREE.LinearFilter;\n texture.minFilter = THREE.LinearMipMapLinearFilter;\n\n // TODO: Set this to renderer.getMaxAnisotropy() / 4\n texture.anisotropy = 4;\n\n texture.needsUpdate = true;\n\n // Something went wrong and the tile or its material is missing\n //\n // Possibly removed by the cache before the image loaded\n if (!this._mesh || !this._mesh.children[0] || !this._mesh.children[0].material) {\n return;\n }\n\n this._mesh.children[0].material.map = texture;\n this._mesh.children[0].material.needsUpdate = true;\n\n this._texture = texture;\n this._ready = true;\n }, false);\n\n // image.addEventListener('progress', event => {}, false);\n // image.addEventListener('error', event => {}, false);\n\n image.crossOrigin = '';\n\n // Load image\n image.src = url;\n\n this._image = image;\n }\n\n _abortRequest() {\n if (!this._image || this._ready) {\n return;\n }\n\n this._aborted = true;\n\n this._image.src = '';\n }\n}\n\nexport default ImageTile;\n\nvar noNew = function(quadcode, path, layer) {\n return new ImageTile(quadcode, path, layer);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as imageTile};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/ImageTile.js\n **/","import {point as Point} from '../../geo/Point';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport THREE from 'three';\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// Manages a single tile and its layers\n\nvar r2d = 180 / Math.PI;\n\nvar tileURLRegex = /\\{([szxy])\\}/g;\n\nclass Tile {\n constructor(quadcode, path, layer) {\n this._layer = layer;\n this._world = layer._world;\n this._quadcode = quadcode;\n this._path = path;\n\n this._ready = false;\n this._aborted = false;\n\n this._tile = this._quadcodeToTile(quadcode);\n\n // Bottom-left and top-right bounds in WGS84 coordinates\n this._boundsLatLon = this._tileBoundsWGS84(this._tile);\n\n // Bottom-left and top-right bounds in world coordinates\n this._boundsWorld = this._tileBoundsFromWGS84(this._boundsLatLon);\n\n // Tile center in world coordinates\n this._center = this._boundsToCenter(this._boundsWorld);\n\n // Tile center in projected coordinates\n this._centerLatlon = this._world.pointToLatLon(Point(this._center[0], this._center[1]));\n\n // Length of a tile side in world coorindates\n this._side = this._getSide(this._boundsWorld);\n\n // Point scale for tile (for unit conversion)\n this._pointScale = this._world.pointScale(this._centerLatlon);\n }\n\n // Returns true if the tile mesh and texture are ready to be used\n // Otherwise, returns false\n isReady() {\n return this._ready;\n }\n\n isAborted() {\n return this._aborted;\n }\n\n // Request data for the tile\n requestTileAsync() {}\n\n getQuadcode() {\n return this._quadcode;\n }\n\n getBounds() {\n return this._boundsWorld;\n }\n\n getCenter() {\n return this._center;\n }\n\n getSide() {\n return this._side;\n }\n\n getMesh() {\n return this._mesh;\n }\n\n getPickingMesh() {\n return this._pickingMesh;\n }\n\n // Destroys the tile and removes it from the layer and memory\n //\n // Ensure that this leaves no trace of the tile – no textures, no meshes,\n // nothing in memory or the GPU\n destroy() {\n // console.log('Destroying tile', this._quadcode);\n\n // Delete reference to layer and world\n this._layer = null;\n this._world = null;\n\n // Delete location references\n this._boundsLatLon = null;\n this._boundsWorld = null;\n this._center = null;\n\n // Done if no mesh\n if (!this._mesh && !this._pickingMesh) {\n return;\n }\n\n this.destroyMesh(this._mesh);\n this.destroyMesh(this._pickingMesh);\n\n this._mesh = null;\n this._pickingMesh = null;\n }\n\n destroyMesh(mesh, dispose = true) {\n if (mesh) {\n if (mesh.children) {\n mesh.children.forEach((child) => {\n mesh.remove(child);\n this.destroyMesh(child);\n });\n }\n\n if (dispose) {\n if (mesh.geometry) {\n mesh.geometry.dispose();\n mesh.geometry = null;\n }\n\n if (mesh.material) {\n if (mesh.material.map) {\n mesh.material.map.dispose();\n mesh.material.map = null;\n }\n\n mesh.material.dispose();\n mesh.material = null;\n }\n }\n }\n }\n\n _createMesh() {}\n _createDebugMesh() {}\n\n _getTileURL(urlParams) {\n if (!urlParams.s) {\n // Default to a random choice of a, b or c\n urlParams.s = String.fromCharCode(97 + Math.floor(Math.random() * 3));\n }\n\n tileURLRegex.lastIndex = 0;\n return this._path.replace(tileURLRegex, function(value, key) {\n // Replace with paramter, otherwise keep existing value\n return urlParams[key];\n });\n }\n\n // Convert from quadcode to TMS tile coordinates\n _quadcodeToTile(quadcode) {\n var x = 0;\n var y = 0;\n var z = quadcode.length;\n\n for (var i = z; i > 0; i--) {\n var mask = 1 << (i - 1);\n var q = +quadcode[z - i];\n if (q === 1) {\n x |= mask;\n }\n if (q === 2) {\n y |= mask;\n }\n if (q === 3) {\n x |= mask;\n y |= mask;\n }\n }\n\n return [x, y, z];\n }\n\n // Convert WGS84 tile bounds to world coordinates\n _tileBoundsFromWGS84(boundsWGS84) {\n var sw = this._layer._world.latLonToPoint(LatLon(boundsWGS84[1], boundsWGS84[0]));\n var ne = this._layer._world.latLonToPoint(LatLon(boundsWGS84[3], boundsWGS84[2]));\n\n return [sw.x, sw.y, ne.x, ne.y];\n }\n\n // Get tile bounds in WGS84 coordinates\n _tileBoundsWGS84(tile) {\n var e = this._tile2lon(tile[0] + 1, tile[2]);\n var w = this._tile2lon(tile[0], tile[2]);\n var s = this._tile2lat(tile[1] + 1, tile[2]);\n var n = this._tile2lat(tile[1], tile[2]);\n return [w, s, e, n];\n }\n\n _tile2lon(x, z) {\n return x / Math.pow(2, z) * 360 - 180;\n }\n\n _tile2lat(y, z) {\n var n = Math.PI - 2 * Math.PI * y / Math.pow(2, z);\n return r2d * Math.atan(0.5 * (Math.exp(n) - Math.exp(-n)));\n }\n\n _boundsToCenter(bounds) {\n var x = bounds[0] + (bounds[2] - bounds[0]) / 2;\n var y = bounds[1] + (bounds[3] - bounds[1]) / 2;\n\n return [x, y];\n }\n\n _getSide(bounds) {\n return (new THREE.Vector3(bounds[0], 0, bounds[3])).sub(new THREE.Vector3(bounds[0], 0, bounds[1])).length();\n }\n}\n\nexport default Tile;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/Tile.js\n **/","// jscs:disable\n/* eslint-disable */\n\nimport THREE from 'three';\n\n/**\n * @author mrdoob / http://mrdoob.com/\n */\n\nBoxHelper = function ( object ) {\n\n\tvar indices = new Uint16Array( [ 0, 1, 1, 2, 2, 3, 3, 0, 4, 5, 5, 6, 6, 7, 7, 4, 0, 4, 1, 5, 2, 6, 3, 7 ] );\n\tvar positions = new Float32Array( 8 * 3 );\n\n\tvar geometry = new THREE.BufferGeometry();\n\tgeometry.setIndex( new THREE.BufferAttribute( indices, 1 ) );\n\tgeometry.addAttribute( 'position', new THREE.BufferAttribute( positions, 3 ) );\n\n\tTHREE.LineSegments.call( this, geometry, new THREE.LineBasicMaterial( { linewidth: 2, color: 0xff0000 } ) );\n\n\tif ( object !== undefined ) {\n\n\t\tthis.update( object );\n\n\t}\n\n};\n\nBoxHelper.prototype = Object.create( THREE.LineSegments.prototype );\nBoxHelper.prototype.constructor = BoxHelper;\n\nBoxHelper.prototype.update = ( function () {\n\n\tvar box = new THREE.Box3();\n\n\treturn function ( object ) {\n\n\t\tbox.setFromObject( object );\n\n\t\tif ( box.isEmpty() ) return;\n\n\t\tvar min = box.min;\n\t\tvar max = box.max;\n\n\t\t/*\n\t\t 5____4\n\t\t1/___0/|\n\t\t| 6__|_7\n\t\t2/___3/\n\n\t\t0: max.x, max.y, max.z\n\t\t1: min.x, max.y, max.z\n\t\t2: min.x, min.y, max.z\n\t\t3: max.x, min.y, max.z\n\t\t4: max.x, max.y, min.z\n\t\t5: min.x, max.y, min.z\n\t\t6: min.x, min.y, min.z\n\t\t7: max.x, min.y, min.z\n\t\t*/\n\n\t\tvar position = this.geometry.attributes.position;\n\t\tvar array = position.array;\n\n\t\tarray[ 0 ] = max.x; array[ 1 ] = max.y; array[ 2 ] = max.z;\n\t\tarray[ 3 ] = min.x; array[ 4 ] = max.y; array[ 5 ] = max.z;\n\t\tarray[ 6 ] = min.x; array[ 7 ] = min.y; array[ 8 ] = max.z;\n\t\tarray[ 9 ] = max.x; array[ 10 ] = min.y; array[ 11 ] = max.z;\n\t\tarray[ 12 ] = max.x; array[ 13 ] = max.y; array[ 14 ] = min.z;\n\t\tarray[ 15 ] = min.x; array[ 16 ] = max.y; array[ 17 ] = min.z;\n\t\tarray[ 18 ] = min.x; array[ 19 ] = min.y; array[ 20 ] = min.z;\n\t\tarray[ 21 ] = max.x; array[ 22 ] = min.y; array[ 23 ] = min.z;\n\n\t\tposition.needsUpdate = true;\n\n\t\tthis.geometry.computeBoundingSphere();\n\n\t};\n\n} )();\n\nexport default BoxHelper;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/vendor/BoxHelper.js\n **/","import THREE from 'three';\n\nexport default function(colour, skyboxTarget) {\n var canvas = document.createElement('canvas');\n canvas.width = 1;\n canvas.height = 1;\n\n var context = canvas.getContext('2d');\n context.fillStyle = colour;\n context.fillRect(0, 0, canvas.width, canvas.height);\n // context.strokeStyle = '#D0D0CF';\n // context.strokeRect(0, 0, canvas.width, canvas.height);\n\n var texture = new THREE.Texture(canvas);\n\n // // Silky smooth images when tilted\n // texture.magFilter = THREE.LinearFilter;\n // texture.minFilter = THREE.LinearMipMapLinearFilter;\n // //\n // // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n // texture.anisotropy = 4;\n\n // texture.wrapS = THREE.RepeatWrapping;\n // texture.wrapT = THREE.RepeatWrapping;\n // texture.repeat.set(segments, segments);\n\n texture.needsUpdate = true;\n\n var material;\n\n if (!skyboxTarget) {\n material = new THREE.MeshBasicMaterial({\n map: texture,\n depthWrite: false\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n map: texture,\n depthWrite: false\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMap = skyboxTarget;\n }\n\n return material;\n};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/ImageTileLayerBaseMaterial.js\n **/","import TileLayer from './TileLayer';\nimport extend from 'lodash.assign';\nimport GeoJSONTile from './GeoJSONTile';\nimport throttle from 'lodash.throttle';\nimport THREE from 'three';\n\n// TODO: Offer on-the-fly slicing of static, non-tile-based GeoJSON files into a\n// tile grid using geojson-vt\n//\n// See: https://github.com/mapbox/geojson-vt\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Consider pausing per-frame output during movement so there's little to\n// no jank caused by previous tiles still processing\n\n// This tile layer only updates the quadtree after world movement has occurred\n//\n// Tiles from previous quadtree updates are updated and outputted every frame\n// (or at least every frame, throttled to some amount)\n//\n// This is because the complexity of TopoJSON tiles requires a lot of processing\n// and so makes movement janky if updates occur every frame – only updating\n// after movement means frame drops are less obvious due to heavy processing\n// occurring while the view is generally stationary\n//\n// The downside is that until new tiles are requested and outputted you will\n// see blank spaces as you orbit and move around\n//\n// An added benefit is that it dramatically reduces the number of tiles being\n// requested over a period of time and the time it takes to go from request to\n// screen output\n//\n// It may be possible to perform these updates per-frame once Web Worker\n// processing is added\n\nclass GeoJSONTileLayer extends TileLayer {\n constructor(path, options) {\n var defaults = {\n maxLOD: 14,\n distance: 30000,\n workers: false\n };\n\n options = extend({}, defaults, options);\n\n super(options);\n\n this.defaults = defaults;\n\n this._path = path;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n super._onAdd(world).then(() => {\n // Trigger initial quadtree calculation on the next frame\n //\n // TODO: This is a hack to ensure the camera is all set up - a better\n // solution should be found\n setTimeout(() => {\n this._calculateLOD();\n this._initEvents();\n }, 0);\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n _initEvents() {\n // Run LOD calculations based on render calls\n //\n // Throttled to 1 LOD calculation per 100ms\n this._throttledWorldUpdate = throttle(this._onWorldUpdate, 100);\n\n this._world.on('preUpdate', this._throttledWorldUpdate, this);\n this._world.on('move', this._onWorldMove, this);\n this._world.on('controlsMove', this._onControlsMove, this);\n }\n\n // Update and output tiles each frame (throttled)\n _onWorldUpdate() {\n if (this._pauseOutput || this._disableOutput) {\n return;\n }\n\n this._outputTiles();\n }\n\n // Update tiles grid after world move, but don't output them\n _onWorldMove(latlon, point) {\n if (this._disableOutput) {\n return;\n }\n\n this._pauseOutput = false;\n this._calculateLOD();\n }\n\n // Pause updates during control movement for less visual jank\n _onControlsMove() {\n if (this._disableOutput) {\n return;\n }\n\n this._pauseOutput = true;\n }\n\n _createTile(quadcode, layer) {\n var newOptions = extend({}, this.defaults, this._options, {\n outputToScene: false\n });\n\n delete newOptions.attribution;\n\n return new GeoJSONTile(quadcode, this._path, layer, newOptions);\n }\n\n hide() {\n this._pauseOutput = true;\n super.hide();\n }\n\n show() {\n this._pauseOutput = false;\n super.show();\n }\n\n // Destroys the layer and removes it from the scene and memory\n destroy() {\n this._world.off('preUpdate', this._throttledWorldUpdate);\n this._world.off('move', this._onWorldMove);\n\n this._throttledWorldUpdate = null;\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default GeoJSONTileLayer;\n\nvar noNew = function(path, options) {\n return new GeoJSONTileLayer(path, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as geoJSONTileLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/GeoJSONTileLayer.js\n **/","import Tile from './Tile';\nimport {geoJSONLayer as GeoJSONLayer} from '../GeoJSONLayer';\nimport {geoJSONWorkerLayer as GeoJSONWorkerLayer} from '../GeoJSONWorkerLayer';\nimport BoxHelper from '../../vendor/BoxHelper';\nimport THREE from 'three';\nimport reqwest from 'reqwest';\nimport {point as Point} from '../../geo/Point';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport extend from 'lodash.assign';\n// import Offset from 'polygon-offset';\nimport GeoJSON from '../../util/GeoJSON';\nimport Buffer from '../../util/Buffer';\nimport PickingMaterial from '../../engine/PickingMaterial';\n\n// TODO: Map picking IDs to some reference within the tile data / geometry so\n// that something useful can be done when an object is picked / clicked on\n\n// TODO: Make sure nothing is left behind in the heap after calling destroy()\n\n// TODO: Perform tile request and processing in a Web Worker\n//\n// Use Operative (https://github.com/padolsey/operative)\n//\n// Would it make sense to have the worker functionality defined in a static\n// method so it only gets initialised once and not on every tile instance?\n//\n// Otherwise, worker processing logic would have to go in the tile layer so not\n// to waste loads of time setting up a brand new worker with three.js for each\n// tile every single time.\n//\n// Unsure of the best way to get three.js and VIZI into the worker\n//\n// Would need to set up a CRS / projection identical to the world instance\n//\n// Is it possible to bypass requirements on external script by having multiple\n// simple worker methods that each take enough inputs to perform a single task\n// without requiring VIZI or three.js? So long as the heaviest logic is done in\n// the worker and transferrable objects are used then it should be better than\n// nothing. Would probably still need things like earcut...\n//\n// After all, the three.js logic and object creation will still need to be\n// done on the main thread regardless so the worker should try to do as much as\n// possible with as few dependencies as possible.\n//\n// Have a look at how this is done in Tangram before implementing anything as\n// the approach there is pretty similar and robust.\n\nclass GeoJSONTile extends Tile {\n constructor(quadcode, path, layer, options) {\n super(quadcode, path, layer);\n\n this._defaultStyle = GeoJSON.defaultStyle;\n\n var defaults = {\n workers: false,\n output: true,\n outputToScene: false,\n interactive: false,\n topojson: false,\n filter: null,\n onEachFeature: null,\n polygonMaterial: null,\n onPolygonMesh: null,\n onPolygonBufferAttributes: null,\n polylineMaterial: null,\n onPolylineMesh: null,\n onPolylineBufferAttributes: null,\n pointGeometry: null,\n pointMaterial: null,\n onPointMesh: null,\n style: GeoJSON.defaultStyle,\n keepFeatures: false\n };\n\n var _options = extend({}, defaults, options);\n\n if (typeof options.style === 'function') {\n _options.style = options.style;\n } else {\n _options.style = extend({}, defaults.style, options.style);\n }\n\n this._options = _options;\n }\n\n // Request data for the tile\n requestTileAsync() {\n // Making this asynchronous really speeds up the LOD framerate\n setTimeout(() => {\n if (!this._mesh) {\n this._mesh = this._createMesh();\n // this._shadowCanvas = this._createShadowCanvas();\n }\n\n this._requestTile();\n }, 0);\n }\n\n // TODO: Destroy GeoJSONLayer\n destroy() {\n // Cancel any pending requests\n this._abortRequest();\n\n // Clear request reference\n this._request = null;\n\n if (this._geojsonLayer) {\n this._geojsonLayer.destroy();\n this._geojsonLayer = null;\n }\n\n this._mesh = null;\n\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n\n super.destroy();\n }\n\n _createMesh() {\n // Something went wrong and the tile\n //\n // Possibly removed by the cache before loaded\n if (!this._center) {\n return;\n }\n\n var mesh = new THREE.Object3D();\n // mesh.add(this._createDebugMesh());\n\n return mesh;\n }\n\n _createDebugMesh() {\n var canvas = document.createElement('canvas');\n canvas.width = 256;\n canvas.height = 256;\n\n var context = canvas.getContext('2d');\n context.font = 'Bold 20px Helvetica Neue, Verdana, Arial';\n context.fillStyle = '#ff0000';\n context.fillText(this._quadcode, 20, canvas.width / 2 - 5);\n context.fillText(this._tile.toString(), 20, canvas.width / 2 + 25);\n\n var texture = new THREE.Texture(canvas);\n\n // Silky smooth images when tilted\n texture.magFilter = THREE.LinearFilter;\n texture.minFilter = THREE.LinearMipMapLinearFilter;\n\n // TODO: Set this to renderer.getMaxAnisotropy() / 4\n texture.anisotropy = 4;\n\n texture.needsUpdate = true;\n\n var material = new THREE.MeshBasicMaterial({\n map: texture,\n transparent: true,\n depthWrite: false\n });\n\n var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n var mesh = new THREE.Mesh(geom, material);\n\n mesh.rotation.x = -90 * Math.PI / 180;\n mesh.position.y = 0.1;\n\n return mesh;\n }\n\n // _createShadowCanvas() {\n // var canvas = document.createElement('canvas');\n //\n // // Rendered at a low resolution and later scaled up for a low-quality blur\n // canvas.width = 512;\n // canvas.height = 512;\n //\n // return canvas;\n // }\n\n // _addShadow(coordinates) {\n // var ctx = this._shadowCanvas.getContext('2d');\n // var width = this._shadowCanvas.width;\n // var height = this._shadowCanvas.height;\n //\n // var _coords;\n // var _offset;\n // var offset = new Offset();\n //\n // // Transform coordinates to shadowCanvas space and draw on canvas\n // coordinates.forEach((ring, index) => {\n // ctx.beginPath();\n //\n // _coords = ring.map(coord => {\n // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n // return [xFrac * width, yFrac * height];\n // });\n //\n // if (index > 0) {\n // _offset = _coords;\n // } else {\n // _offset = offset.data(_coords).padding(1.3);\n // }\n //\n // // TODO: This is super flaky and crashes the browser if run on anything\n // // put the outer ring (potentially due to winding)\n // _offset.forEach((coord, index) => {\n // // var xFrac = (coord[0] - this._boundsWorld[0]) / this._side;\n // // var yFrac = (coord[1] - this._boundsWorld[3]) / this._side;\n //\n // if (index === 0) {\n // ctx.moveTo(coord[0], coord[1]);\n // } else {\n // ctx.lineTo(coord[0], coord[1]);\n // }\n // });\n //\n // ctx.closePath();\n // });\n //\n // ctx.fillStyle = 'rgba(80, 80, 80, 0.7)';\n // ctx.fill();\n // }\n\n _requestTile() {\n var urlParams = {\n x: this._tile[0],\n y: this._tile[1],\n z: this._tile[2]\n };\n\n var url = this._getTileURL(urlParams);\n\n this._aborted = false;\n\n if (!this._options.workers) {\n this._request = reqwest({\n url: url,\n type: 'json',\n crossOrigin: true,\n headers: this._options.headers\n }).then(res => {\n // Clear request reference\n this._request = null;\n this._processTileData(res);\n }).catch(err => {\n // Clear request reference\n this._request = null;\n });\n } else {\n this._processTileData(url);\n }\n }\n\n _processTileData(data) {\n // console.time(this._tile);\n\n var GeoJSONClass = (!this._options.workers) ? GeoJSONLayer : GeoJSONWorkerLayer;\n\n // Using this creates a huge amount of memory due to the quantity of tiles\n this._geojsonLayer = GeoJSONClass(data, this._options);\n this._geojsonLayer.addTo(this._world).then(() => {\n // TODO: This never seems to be called on worker layers. Find out why.\n if (this.isAborted()) {\n // this._geojsonLayer._aborted = true;\n // this._geojsonLayer = null;\n return;\n }\n\n // TODO: This is a hack to stop old tile meshes hanging around. Fix or\n // move to somewhere more robust.\n //\n // Could potentially just overwrite mesh on first index each time\n //\n // This makes some worker tiles to not appear properly – showing the\n // points mesh but not the polygon mesh, etc.\n //\n // Only do this for non-worker layers for now as it seems to cause issues\n // with worker tiles showing for a moment and then disappearing forever\n if (!this._options.workers) {\n this.destroyMesh(this._mesh);\n }\n\n // TOSO: Work out if the picking mesh needs destroying here\n // this.destroyMesh(this._pickingMesh);\n\n this._mesh.add(this._geojsonLayer._object3D);\n this._pickingMesh = this._geojsonLayer._pickingMesh;\n\n // Free the GeoJSON memory as we don't need it\n //\n // TODO: This should probably be a method within GeoJSONLayer\n if (this._geojsonLayer._geojson) {\n this._geojsonLayer._geojson = null;\n }\n\n // TODO: Fix or store shadow canvas stuff and get rid of this code\n // Draw footprint on shadow canvas\n //\n // TODO: Disabled for the time-being until it can be sped up / moved to\n // a worker\n // this._addShadow(coordinates);\n\n // Output shadow canvas\n\n // TODO: Disabled for the time-being until it can be sped up / moved to\n // a worker\n\n // var texture = new THREE.Texture(this._shadowCanvas);\n //\n // // Silky smooth images when tilted\n // texture.magFilter = THREE.LinearFilter;\n // texture.minFilter = THREE.LinearMipMapLinearFilter;\n //\n // // TODO: Set this to renderer.getMaxAnisotropy() / 4\n // texture.anisotropy = 4;\n //\n // texture.needsUpdate = true;\n //\n // var material;\n // if (!this._world._environment._skybox) {\n // material = new THREE.MeshBasicMaterial({\n // map: texture,\n // transparent: true,\n // depthWrite: false\n // });\n // } else {\n // material = new THREE.MeshStandardMaterial({\n // map: texture,\n // transparent: true,\n // depthWrite: false\n // });\n // material.roughness = 1;\n // material.metalness = 0.1;\n // material.envMap = this._world._environment._skybox.getRenderTarget();\n // }\n //\n // var geom = new THREE.PlaneBufferGeometry(this._side, this._side, 1);\n // var mesh = new THREE.Mesh(geom, material);\n //\n // mesh.castShadow = false;\n // mesh.receiveShadow = false;\n // mesh.renderOrder = 1;\n //\n // mesh.rotation.x = -90 * Math.PI / 180;\n //\n // this._mesh.add(mesh);\n\n this._ready = true;\n // console.timeEnd(this._tile);\n }).catch(() => {});\n }\n\n _abortRequest() {\n if ((!this._request && !this._options.workers) || this._ready) {\n return;\n }\n\n this._aborted = true;\n\n if (this._request) {\n this._request.abort();\n }\n }\n}\n\nexport default GeoJSONTile;\n\nvar noNew = function(quadcode, path, layer, options) {\n return new GeoJSONTile(quadcode, path, layer, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as geoJSONTile};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/GeoJSONTile.js\n **/","// TODO: Consider adopting GeoJSON CSS\n// http://wiki.openstreetmap.org/wiki/Geojson_CSS\n\n// TODO: Allow interaction to be defined per-layer to save on resources\n//\n// For example, only allow polygons to be interactive via a polygonInteractive\n// option\n\nimport LayerGroup from './LayerGroup';\nimport extend from 'lodash.assign';\nimport reqwest from 'reqwest';\nimport GeoJSON from '../util/GeoJSON';\nimport Buffer from '../util/Buffer';\nimport PickingMaterial from '../engine/PickingMaterial';\nimport PolygonLayer from './geometry/PolygonLayer';\nimport PolylineLayer from './geometry/PolylineLayer';\nimport PointLayer from './geometry/PointLayer';\n\nclass GeoJSONLayer extends LayerGroup {\n constructor(geojson, options) {\n var defaults = {\n output: false,\n interactive: false,\n topojson: false,\n filter: null,\n onEachFeature: null,\n polygonMaterial: null,\n onPolygonMesh: null,\n onPolygonBufferAttributes: null,\n polylineMaterial: null,\n onPolylineMesh: null,\n onPolylineBufferAttributes: null,\n pointGeometry: null,\n pointMaterial: null,\n onPointMesh: null,\n style: GeoJSON.defaultStyle,\n keepFeatures: true\n };\n\n var _options = extend({}, defaults, options);\n\n if (typeof options.style === 'function') {\n _options.style = options.style;\n } else {\n _options.style = extend({}, defaults.style, options.style);\n }\n\n super(_options);\n\n this._geojson = geojson;\n }\n\n _onAdd(world) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n // Request data from URL if needed\n if (typeof this._geojson === 'string') {\n return this._requestData(this._geojson);\n } else {\n // Process and add GeoJSON to layer\n return this._processData(this._geojson);\n }\n }\n\n _requestData(url) {\n return new Promise((resolve, reject) => {\n this._request = reqwest({\n url: url,\n type: 'json',\n crossOrigin: true\n }).then(res => {\n // Clear request reference\n this._request = null;\n this._processData(res).then(() => {\n resolve(this);\n });\n }).catch(err => {\n console.error(err);\n\n // Clear request reference\n this._request = null;\n\n reject(err);\n });\n });\n }\n\n // TODO: Wrap into a helper method so this isn't duplicated in the tiled\n // GeoJSON output layer\n //\n // Need to be careful as to not make it impossible to fork this off into a\n // worker script at a later stage\n _processData(data) {\n return new Promise((resolve) => {\n // Collects features into a single FeatureCollection\n //\n // Also converts TopoJSON to GeoJSON if instructed\n this._geojson = GeoJSON.collectFeatures(data, this._options.topojson);\n\n // TODO: Check that GeoJSON is valid / usable\n\n var features = this._geojson.features;\n\n // Run filter, if provided\n if (this._options.filter) {\n features = this._geojson.features.filter(this._options.filter);\n }\n\n var defaults = {};\n\n // Assume that a style won't be set per feature\n var style = this._options.style;\n\n var layerPromises = [];\n\n var options;\n features.forEach(feature => {\n // Get per-feature style object, if provided\n if (typeof this._options.style === 'function') {\n style = extend({}, GeoJSON.defaultStyle, this._options.style(feature));\n }\n\n options = extend({}, defaults, {\n // If merging feature layers, stop them outputting themselves\n // If not, let feature layers output themselves to the world\n output: !this.isOutput(),\n interactive: this._options.interactive,\n style: style\n });\n\n var layer = this._featureToLayer(feature, options);\n\n if (!layer) {\n return;\n }\n\n // Sometimes you don't want to store a reference to the feature\n //\n // For example, to save memory when being used by tile layers\n if (this._options.keepFeatures) {\n layer.feature = feature;\n }\n\n // If defined, call a function for each feature\n //\n // This is commonly used for adding event listeners from the user script\n if (this._options.onEachFeature) {\n this._options.onEachFeature(feature, layer);\n }\n\n // TODO: Make this a promise array and only continue on completion\n layerPromises.push(this.addLayer(layer));\n });\n\n Promise.all(layerPromises).then((results) => {\n // If merging layers do that now, otherwise skip as the geometry layers\n // should have already outputted themselves\n if (!this.isOutput()) {\n resolve();\n return;\n }\n\n // From here on we can assume that we want to merge the layers\n\n var polygonAttributes = [];\n var polygonOutlineAttributes = [];\n var polygonAttributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3\n };\n var polygonFlat = true;\n\n var polylineAttributes = [];\n var polylineAttributeLengths = {\n positions: 3,\n colors: 3\n };\n var polylineFlat = true;\n\n var pointAttributes = [];\n var pointAttributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3\n };\n var pointFlat = true;\n\n this._layers.forEach(layer => {\n if (layer instanceof PolygonLayer) {\n polygonAttributes.push(layer.getBufferAttributes());\n\n var outlineBufferAttributes = layer.getOutlineBufferAttributes();\n if (outlineBufferAttributes) {\n polygonOutlineAttributes.push(outlineBufferAttributes);\n }\n\n if (polygonFlat && !layer.isFlat()) {\n polygonFlat = false;\n }\n\n if (this._options.interactive) {\n polygonAttributeLengths.pickingIds = 1;\n }\n } else if (layer instanceof PolylineLayer) {\n polylineAttributes.push(layer.getBufferAttributes());\n\n if (polylineFlat && !layer.isFlat()) {\n polylineFlat = false;\n }\n\n if (this._options.interactive) {\n polylineAttributeLengths.pickingIds = 1;\n }\n } else if (layer instanceof PointLayer) {\n pointAttributes.push(layer.getBufferAttributes());\n\n if (pointFlat && !layer.isFlat()) {\n pointFlat = false;\n }\n\n if (this._options.interactive) {\n pointAttributeLengths.pickingIds = 1;\n }\n }\n });\n\n var style;\n\n if (polygonAttributes.length > 0) {\n var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);\n\n var mergedPolygonOutlineAttributes;\n if (polygonOutlineAttributes.length > 0) {\n mergedPolygonOutlineAttributes = Buffer.mergeAttributes(polygonOutlineAttributes);\n }\n\n style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat).then((result) => {\n this._polygonMesh = result.mesh;\n this.add(this._polygonMesh);\n\n if (mergedPolygonOutlineAttributes) {\n style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n if (style.outlineRenderOrder !== undefined) {\n style.lineRenderOrder = style.outlineRenderOrder;\n } else {\n style.lineRenderOrder = (style.renderOrder) ? style.renderOrder + 1 : 4;\n }\n\n if (style.outlineWidth) {\n style.lineWidth = style.outlineWidth;\n }\n\n this._setPolylineMesh(mergedPolygonOutlineAttributes, polylineAttributeLengths, style, true).then((result) => {\n this.add(result.mesh);\n });\n }\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n if (polylineAttributes.length > 0) {\n var mergedPolylineAttributes = Buffer.mergeAttributes(polylineAttributes);\n\n style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then((result) => {\n this._polylineMesh = result.mesh;\n this.add(this._polylineMesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n if (pointAttributes.length > 0) {\n var mergedPointAttributes = Buffer.mergeAttributes(pointAttributes);\n\n style = (typeof this._options.style === 'function') ? this._options.style(this._geojson.features[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then((result) => {\n this._pointMesh = result.mesh;\n this.add(this._pointMesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n // Clean up layers\n //\n // TODO: Are there ever situations where the unmerged buffer attributes\n // and coordinates would still be required?\n this._layers.forEach(layer => {\n layer.clearBufferAttributes();\n layer.clearCoordinates();\n });\n\n resolve();\n });\n });\n }\n\n // Create and store mesh from buffer attributes\n //\n // TODO: Probably remove this and call static method directly as it's just a proxy\n _setPolygonMesh(attributes, attributeLengths, style, flat) {\n return PolygonLayer.SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n }\n\n _setPolylineMesh(attributes, attributeLengths, style, flat) {\n return PolylineLayer.SetMesh(attributes, attributeLengths, flat, style, this._options);\n }\n\n _setPointMesh(attributes, attributeLengths, style, flat) {\n return PointLayer.SetMesh(attributes, attributeLengths, flat, style, this._options);\n }\n\n // TODO: Support all GeoJSON geometry types\n _featureToLayer(feature, options) {\n var geometry = feature.geometry;\n var coordinates = (geometry.coordinates) ? geometry.coordinates : null;\n\n if (!coordinates || !geometry) {\n return;\n }\n\n if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n // Get material instance to use for polygon, if provided\n if (typeof this._options.polygonMaterial === 'function') {\n options.polygonMaterial = this._options.polygonMaterial(feature);\n }\n\n if (typeof this._options.onPolygonMesh === 'function') {\n options.onPolygonMesh = this._options.onPolygonMesh;\n }\n\n // Pass onBufferAttributes callback, if defined\n if (typeof this._options.onPolygonBufferAttributes === 'function') {\n options.onBufferAttributes = this._options.onPolygonBufferAttributes;\n }\n\n return new PolygonLayer(coordinates, options);\n }\n\n if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n // Get material instance to use for line, if provided\n if (typeof this._options.lineMaterial === 'function') {\n options.lineMaterial = this._options.lineMaterial(feature);\n }\n\n if (typeof this._options.onPolylineMesh === 'function') {\n options.onPolylineMesh = this._options.onPolylineMesh;\n }\n\n // Pass onBufferAttributes callback, if defined\n if (typeof this._options.onPolylineBufferAttributes === 'function') {\n options.onBufferAttributes = this._options.onPolylineBufferAttributes;\n }\n\n return new PolylineLayer(coordinates, options);\n }\n\n if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n // Get geometry object to use for point, if provided\n if (typeof this._options.pointGeometry === 'function') {\n options.pointGeometry = this._options.pointGeometry(feature);\n }\n\n // Get material instance to use for point, if provided\n if (typeof this._options.pointMaterial === 'function') {\n options.pointMaterial = this._options.pointMaterial(feature);\n }\n\n if (typeof this._options.onPointMesh === 'function') {\n options.onPointMesh = this._options.onPointMesh;\n }\n\n return new PointLayer(coordinates, options);\n }\n }\n\n _abortRequest() {\n if (!this._request) {\n return;\n }\n\n this._request.abort();\n }\n\n // Destroy the layers and remove them from the scene and memory\n destroy() {\n // Cancel any pending requests\n this._abortRequest();\n\n // Clear request reference\n this._request = null;\n\n this._geojson = null;\n\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n if (this._polygonMesh) {\n this._polygonMesh = null;\n }\n\n if (this._polylineMesh) {\n this._polylineMesh = null;\n }\n\n if (this._pointMesh) {\n this._pointMesh = null;\n }\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default GeoJSONLayer;\n\nvar noNew = function(geojson, options) {\n return new GeoJSONLayer(geojson, options);\n};\n\nexport {noNew as geoJSONLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/GeoJSONLayer.js\n **/","/*!\n * Reqwest! A general purpose XHR connection manager\n * license MIT (c) Dustin Diaz 2015\n * https://github.com/ded/reqwest\n */\n\n!function (name, context, definition) {\n if (typeof module != 'undefined' && module.exports) module.exports = definition()\n else if (typeof define == 'function' && define.amd) define(definition)\n else context[name] = definition()\n}('reqwest', this, function () {\n\n var context = this\n\n if ('window' in context) {\n var doc = document\n , byTag = 'getElementsByTagName'\n , head = doc[byTag]('head')[0]\n } else {\n var XHR2\n try {\n XHR2 = require('xhr2')\n } catch (ex) {\n throw new Error('Peer dependency `xhr2` required! Please npm install xhr2')\n }\n }\n\n\n var httpsRe = /^http/\n , protocolRe = /(^\\w+):\\/\\//\n , twoHundo = /^(20\\d|1223)$/ //http://stackoverflow.com/questions/10046972/msie-returns-status-code-of-1223-for-ajax-request\n , readyState = 'readyState'\n , contentType = 'Content-Type'\n , requestedWith = 'X-Requested-With'\n , uniqid = 0\n , callbackPrefix = 'reqwest_' + (+new Date())\n , lastValue // data stored by the most recent JSONP callback\n , xmlHttpRequest = 'XMLHttpRequest'\n , xDomainRequest = 'XDomainRequest'\n , noop = function () {}\n\n , isArray = typeof Array.isArray == 'function'\n ? Array.isArray\n : function (a) {\n return a instanceof Array\n }\n\n , defaultHeaders = {\n 'contentType': 'application/x-www-form-urlencoded'\n , 'requestedWith': xmlHttpRequest\n , 'accept': {\n '*': 'text/javascript, text/html, application/xml, text/xml, */*'\n , 'xml': 'application/xml, text/xml'\n , 'html': 'text/html'\n , 'text': 'text/plain'\n , 'json': 'application/json, text/javascript'\n , 'js': 'application/javascript, text/javascript'\n }\n }\n\n , xhr = function(o) {\n // is it x-domain\n if (o['crossOrigin'] === true) {\n var xhr = context[xmlHttpRequest] ? new XMLHttpRequest() : null\n if (xhr && 'withCredentials' in xhr) {\n return xhr\n } else if (context[xDomainRequest]) {\n return new XDomainRequest()\n } else {\n throw new Error('Browser does not support cross-origin requests')\n }\n } else if (context[xmlHttpRequest]) {\n return new XMLHttpRequest()\n } else if (XHR2) {\n return new XHR2()\n } else {\n return new ActiveXObject('Microsoft.XMLHTTP')\n }\n }\n , globalSetupOptions = {\n dataFilter: function (data) {\n return data\n }\n }\n\n function succeed(r) {\n var protocol = protocolRe.exec(r.url)\n protocol = (protocol && protocol[1]) || context.location.protocol\n return httpsRe.test(protocol) ? twoHundo.test(r.request.status) : !!r.request.response\n }\n\n function handleReadyState(r, success, error) {\n return function () {\n // use _aborted to mitigate against IE err c00c023f\n // (can't read props on aborted request objects)\n if (r._aborted) return error(r.request)\n if (r._timedOut) return error(r.request, 'Request is aborted: timeout')\n if (r.request && r.request[readyState] == 4) {\n r.request.onreadystatechange = noop\n if (succeed(r)) success(r.request)\n else\n error(r.request)\n }\n }\n }\n\n function setHeaders(http, o) {\n var headers = o['headers'] || {}\n , h\n\n headers['Accept'] = headers['Accept']\n || defaultHeaders['accept'][o['type']]\n || defaultHeaders['accept']['*']\n\n var isAFormData = typeof FormData !== 'undefined' && (o['data'] instanceof FormData);\n // breaks cross-origin requests with legacy browsers\n if (!o['crossOrigin'] && !headers[requestedWith]) headers[requestedWith] = defaultHeaders['requestedWith']\n if (!headers[contentType] && !isAFormData) headers[contentType] = o['contentType'] || defaultHeaders['contentType']\n for (h in headers)\n headers.hasOwnProperty(h) && 'setRequestHeader' in http && http.setRequestHeader(h, headers[h])\n }\n\n function setCredentials(http, o) {\n if (typeof o['withCredentials'] !== 'undefined' && typeof http.withCredentials !== 'undefined') {\n http.withCredentials = !!o['withCredentials']\n }\n }\n\n function generalCallback(data) {\n lastValue = data\n }\n\n function urlappend (url, s) {\n return url + (/\\?/.test(url) ? '&' : '?') + s\n }\n\n function handleJsonp(o, fn, err, url) {\n var reqId = uniqid++\n , cbkey = o['jsonpCallback'] || 'callback' // the 'callback' key\n , cbval = o['jsonpCallbackName'] || reqwest.getcallbackPrefix(reqId)\n , cbreg = new RegExp('((^|\\\\?|&)' + cbkey + ')=([^&]+)')\n , match = url.match(cbreg)\n , script = doc.createElement('script')\n , loaded = 0\n , isIE10 = navigator.userAgent.indexOf('MSIE 10.0') !== -1\n\n if (match) {\n if (match[3] === '?') {\n url = url.replace(cbreg, '$1=' + cbval) // wildcard callback func name\n } else {\n cbval = match[3] // provided callback func name\n }\n } else {\n url = urlappend(url, cbkey + '=' + cbval) // no callback details, add 'em\n }\n\n context[cbval] = generalCallback\n\n script.type = 'text/javascript'\n script.src = url\n script.async = true\n if (typeof script.onreadystatechange !== 'undefined' && !isIE10) {\n // need this for IE due to out-of-order onreadystatechange(), binding script\n // execution to an event listener gives us control over when the script\n // is executed. See http://jaubourg.net/2010/07/loading-script-as-onclick-handler-of.html\n script.htmlFor = script.id = '_reqwest_' + reqId\n }\n\n script.onload = script.onreadystatechange = function () {\n if ((script[readyState] && script[readyState] !== 'complete' && script[readyState] !== 'loaded') || loaded) {\n return false\n }\n script.onload = script.onreadystatechange = null\n script.onclick && script.onclick()\n // Call the user callback with the last value stored and clean up values and scripts.\n fn(lastValue)\n lastValue = undefined\n head.removeChild(script)\n loaded = 1\n }\n\n // Add the script to the DOM head\n head.appendChild(script)\n\n // Enable JSONP timeout\n return {\n abort: function () {\n script.onload = script.onreadystatechange = null\n err({}, 'Request is aborted: timeout', {})\n lastValue = undefined\n head.removeChild(script)\n loaded = 1\n }\n }\n }\n\n function getRequest(fn, err) {\n var o = this.o\n , method = (o['method'] || 'GET').toUpperCase()\n , url = typeof o === 'string' ? o : o['url']\n // convert non-string objects to query-string form unless o['processData'] is false\n , data = (o['processData'] !== false && o['data'] && typeof o['data'] !== 'string')\n ? reqwest.toQueryString(o['data'])\n : (o['data'] || null)\n , http\n , sendWait = false\n\n // if we're working on a GET request and we have data then we should append\n // query string to end of URL and not post data\n if ((o['type'] == 'jsonp' || method == 'GET') && data) {\n url = urlappend(url, data)\n data = null\n }\n\n if (o['type'] == 'jsonp') return handleJsonp(o, fn, err, url)\n\n // get the xhr from the factory if passed\n // if the factory returns null, fall-back to ours\n http = (o.xhr && o.xhr(o)) || xhr(o)\n\n http.open(method, url, o['async'] === false ? false : true)\n setHeaders(http, o)\n setCredentials(http, o)\n if (context[xDomainRequest] && http instanceof context[xDomainRequest]) {\n http.onload = fn\n http.onerror = err\n // NOTE: see\n // http://social.msdn.microsoft.com/Forums/en-US/iewebdevelopment/thread/30ef3add-767c-4436-b8a9-f1ca19b4812e\n http.onprogress = function() {}\n sendWait = true\n } else {\n http.onreadystatechange = handleReadyState(this, fn, err)\n }\n o['before'] && o['before'](http)\n if (sendWait) {\n setTimeout(function () {\n http.send(data)\n }, 200)\n } else {\n http.send(data)\n }\n return http\n }\n\n function Reqwest(o, fn) {\n this.o = o\n this.fn = fn\n\n init.apply(this, arguments)\n }\n\n function setType(header) {\n // json, javascript, text/plain, text/html, xml\n if (header === null) return undefined; //In case of no content-type.\n if (header.match('json')) return 'json'\n if (header.match('javascript')) return 'js'\n if (header.match('text')) return 'html'\n if (header.match('xml')) return 'xml'\n }\n\n function init(o, fn) {\n\n this.url = typeof o == 'string' ? o : o['url']\n this.timeout = null\n\n // whether request has been fulfilled for purpose\n // of tracking the Promises\n this._fulfilled = false\n // success handlers\n this._successHandler = function(){}\n this._fulfillmentHandlers = []\n // error handlers\n this._errorHandlers = []\n // complete (both success and fail) handlers\n this._completeHandlers = []\n this._erred = false\n this._responseArgs = {}\n\n var self = this\n\n fn = fn || function () {}\n\n if (o['timeout']) {\n this.timeout = setTimeout(function () {\n timedOut()\n }, o['timeout'])\n }\n\n if (o['success']) {\n this._successHandler = function () {\n o['success'].apply(o, arguments)\n }\n }\n\n if (o['error']) {\n this._errorHandlers.push(function () {\n o['error'].apply(o, arguments)\n })\n }\n\n if (o['complete']) {\n this._completeHandlers.push(function () {\n o['complete'].apply(o, arguments)\n })\n }\n\n function complete (resp) {\n o['timeout'] && clearTimeout(self.timeout)\n self.timeout = null\n while (self._completeHandlers.length > 0) {\n self._completeHandlers.shift()(resp)\n }\n }\n\n function success (resp) {\n var type = o['type'] || resp && setType(resp.getResponseHeader('Content-Type')) // resp can be undefined in IE\n resp = (type !== 'jsonp') ? self.request : resp\n // use global data filter on response text\n var filteredResponse = globalSetupOptions.dataFilter(resp.responseText, type)\n , r = filteredResponse\n try {\n resp.responseText = r\n } catch (e) {\n // can't assign this in IE<=8, just ignore\n }\n if (r) {\n switch (type) {\n case 'json':\n try {\n resp = context.JSON ? context.JSON.parse(r) : eval('(' + r + ')')\n } catch (err) {\n return error(resp, 'Could not parse JSON in response', err)\n }\n break\n case 'js':\n resp = eval(r)\n break\n case 'html':\n resp = r\n break\n case 'xml':\n resp = resp.responseXML\n && resp.responseXML.parseError // IE trololo\n && resp.responseXML.parseError.errorCode\n && resp.responseXML.parseError.reason\n ? null\n : resp.responseXML\n break\n }\n }\n\n self._responseArgs.resp = resp\n self._fulfilled = true\n fn(resp)\n self._successHandler(resp)\n while (self._fulfillmentHandlers.length > 0) {\n resp = self._fulfillmentHandlers.shift()(resp)\n }\n\n complete(resp)\n }\n\n function timedOut() {\n self._timedOut = true\n self.request.abort()\n }\n\n function error(resp, msg, t) {\n resp = self.request\n self._responseArgs.resp = resp\n self._responseArgs.msg = msg\n self._responseArgs.t = t\n self._erred = true\n while (self._errorHandlers.length > 0) {\n self._errorHandlers.shift()(resp, msg, t)\n }\n complete(resp)\n }\n\n this.request = getRequest.call(this, success, error)\n }\n\n Reqwest.prototype = {\n abort: function () {\n this._aborted = true\n this.request.abort()\n }\n\n , retry: function () {\n init.call(this, this.o, this.fn)\n }\n\n /**\n * Small deviation from the Promises A CommonJs specification\n * http://wiki.commonjs.org/wiki/Promises/A\n */\n\n /**\n * `then` will execute upon successful requests\n */\n , then: function (success, fail) {\n success = success || function () {}\n fail = fail || function () {}\n if (this._fulfilled) {\n this._responseArgs.resp = success(this._responseArgs.resp)\n } else if (this._erred) {\n fail(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n } else {\n this._fulfillmentHandlers.push(success)\n this._errorHandlers.push(fail)\n }\n return this\n }\n\n /**\n * `always` will execute whether the request succeeds or fails\n */\n , always: function (fn) {\n if (this._fulfilled || this._erred) {\n fn(this._responseArgs.resp)\n } else {\n this._completeHandlers.push(fn)\n }\n return this\n }\n\n /**\n * `fail` will execute when the request fails\n */\n , fail: function (fn) {\n if (this._erred) {\n fn(this._responseArgs.resp, this._responseArgs.msg, this._responseArgs.t)\n } else {\n this._errorHandlers.push(fn)\n }\n return this\n }\n , 'catch': function (fn) {\n return this.fail(fn)\n }\n }\n\n function reqwest(o, fn) {\n return new Reqwest(o, fn)\n }\n\n // normalize newline variants according to spec -> CRLF\n function normalize(s) {\n return s ? s.replace(/\\r?\\n/g, '\\r\\n') : ''\n }\n\n function serial(el, cb) {\n var n = el.name\n , t = el.tagName.toLowerCase()\n , optCb = function (o) {\n // IE gives value=\"\" even where there is no value attribute\n // 'specified' ref: http://www.w3.org/TR/DOM-Level-3-Core/core.html#ID-862529273\n if (o && !o['disabled'])\n cb(n, normalize(o['attributes']['value'] && o['attributes']['value']['specified'] ? o['value'] : o['text']))\n }\n , ch, ra, val, i\n\n // don't serialize elements that are disabled or without a name\n if (el.disabled || !n) return\n\n switch (t) {\n case 'input':\n if (!/reset|button|image|file/i.test(el.type)) {\n ch = /checkbox/i.test(el.type)\n ra = /radio/i.test(el.type)\n val = el.value\n // WebKit gives us \"\" instead of \"on\" if a checkbox has no value, so correct it here\n ;(!(ch || ra) || el.checked) && cb(n, normalize(ch && val === '' ? 'on' : val))\n }\n break\n case 'textarea':\n cb(n, normalize(el.value))\n break\n case 'select':\n if (el.type.toLowerCase() === 'select-one') {\n optCb(el.selectedIndex >= 0 ? el.options[el.selectedIndex] : null)\n } else {\n for (i = 0; el.length && i < el.length; i++) {\n el.options[i].selected && optCb(el.options[i])\n }\n }\n break\n }\n }\n\n // collect up all form elements found from the passed argument elements all\n // the way down to child elements; pass a '' or form fields.\n // called with 'this'=callback to use for serial() on each element\n function eachFormElement() {\n var cb = this\n , e, i\n , serializeSubtags = function (e, tags) {\n var i, j, fa\n for (i = 0; i < tags.length; i++) {\n fa = e[byTag](tags[i])\n for (j = 0; j < fa.length; j++) serial(fa[j], cb)\n }\n }\n\n for (i = 0; i < arguments.length; i++) {\n e = arguments[i]\n if (/input|select|textarea/i.test(e.tagName)) serial(e, cb)\n serializeSubtags(e, [ 'input', 'select', 'textarea' ])\n }\n }\n\n // standard query string style serialization\n function serializeQueryString() {\n return reqwest.toQueryString(reqwest.serializeArray.apply(null, arguments))\n }\n\n // { 'name': 'value', ... } style serialization\n function serializeHash() {\n var hash = {}\n eachFormElement.apply(function (name, value) {\n if (name in hash) {\n hash[name] && !isArray(hash[name]) && (hash[name] = [hash[name]])\n hash[name].push(value)\n } else hash[name] = value\n }, arguments)\n return hash\n }\n\n // [ { name: 'name', value: 'value' }, ... ] style serialization\n reqwest.serializeArray = function () {\n var arr = []\n eachFormElement.apply(function (name, value) {\n arr.push({name: name, value: value})\n }, arguments)\n return arr\n }\n\n reqwest.serialize = function () {\n if (arguments.length === 0) return ''\n var opt, fn\n , args = Array.prototype.slice.call(arguments, 0)\n\n opt = args.pop()\n opt && opt.nodeType && args.push(opt) && (opt = null)\n opt && (opt = opt.type)\n\n if (opt == 'map') fn = serializeHash\n else if (opt == 'array') fn = reqwest.serializeArray\n else fn = serializeQueryString\n\n return fn.apply(null, args)\n }\n\n reqwest.toQueryString = function (o, trad) {\n var prefix, i\n , traditional = trad || false\n , s = []\n , enc = encodeURIComponent\n , add = function (key, value) {\n // If value is a function, invoke it and return its value\n value = ('function' === typeof value) ? value() : (value == null ? '' : value)\n s[s.length] = enc(key) + '=' + enc(value)\n }\n // If an array was passed in, assume that it is an array of form elements.\n if (isArray(o)) {\n for (i = 0; o && i < o.length; i++) add(o[i]['name'], o[i]['value'])\n } else {\n // If traditional, encode the \"old\" way (the way 1.3.2 or older\n // did it), otherwise encode params recursively.\n for (prefix in o) {\n if (o.hasOwnProperty(prefix)) buildParams(prefix, o[prefix], traditional, add)\n }\n }\n\n // spaces should be + according to spec\n return s.join('&').replace(/%20/g, '+')\n }\n\n function buildParams(prefix, obj, traditional, add) {\n var name, i, v\n , rbracket = /\\[\\]$/\n\n if (isArray(obj)) {\n // Serialize array item.\n for (i = 0; obj && i < obj.length; i++) {\n v = obj[i]\n if (traditional || rbracket.test(prefix)) {\n // Treat each array item as a scalar.\n add(prefix, v)\n } else {\n buildParams(prefix + '[' + (typeof v === 'object' ? i : '') + ']', v, traditional, add)\n }\n }\n } else if (obj && obj.toString() === '[object Object]') {\n // Serialize object item.\n for (name in obj) {\n buildParams(prefix + '[' + name + ']', obj[name], traditional, add)\n }\n\n } else {\n // Serialize scalar item.\n add(prefix, obj)\n }\n }\n\n reqwest.getcallbackPrefix = function () {\n return callbackPrefix\n }\n\n // jQuery and Zepto compatibility, differences can be remapped here so you can call\n // .ajax.compat(options, callback)\n reqwest.compat = function (o, fn) {\n if (o) {\n o['type'] && (o['method'] = o['type']) && delete o['type']\n o['dataType'] && (o['type'] = o['dataType'])\n o['jsonpCallback'] && (o['jsonpCallbackName'] = o['jsonpCallback']) && delete o['jsonpCallback']\n o['jsonp'] && (o['jsonpCallback'] = o['jsonp'])\n }\n return new Reqwest(o, fn)\n }\n\n reqwest.ajaxSetup = function (options) {\n options = options || {}\n for (var k in options) {\n globalSetupOptions[k] = options[k]\n }\n }\n\n return reqwest\n});\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/reqwest/reqwest.js\n ** module id = 73\n ** module chunks = 0\n **/","/*\n * GeoJSON helpers for handling data and generating objects\n */\n\nimport THREE from 'three';\nimport * as topojson from 'topojson';\nimport geojsonMerge from 'geojson-merge';\nimport earcut from 'earcut';\nimport extrudePolygon from './extrudePolygon';\n\n// TODO: Make it so height can be per-coordinate / point but connected together\n// as a linestring (eg. GPS points with an elevation at each point)\n//\n// This isn't really valid GeoJSON so perhaps something best left to an external\n// component for now, until a better approach can be considered\n//\n// See: http://lists.geojson.org/pipermail/geojson-geojson.org/2009-June/000489.html\n\n// Light and dark colours used for poor-mans AO gradient on object sides\nvar light = new THREE.Color(0xffffff);\nvar shadow = new THREE.Color(0x666666);\n\nvar GeoJSON = (function() {\n var defaultStyle = {\n color: '#ffffff',\n outline: false,\n outlineColor: '#000000',\n transparent: false,\n opacity: 1,\n blending: THREE.NormalBlending,\n height: 0,\n lineOpacity: 1,\n lineTransparent: false,\n lineColor: '#ffffff',\n lineWidth: 1,\n lineBlending: THREE.NormalBlending\n };\n\n // Attempts to merge together multiple GeoJSON Features or FeatureCollections\n // into a single FeatureCollection\n var collectFeatures = function(data, _topojson) {\n var collections = [];\n\n if (_topojson) {\n // TODO: Allow TopoJSON objects to be overridden as an option\n\n // If not overridden, merge all features from all objects\n for (var tk in data.objects) {\n collections.push(topojson.feature(data, data.objects[tk]));\n }\n\n return geojsonMerge(collections);\n } else {\n // If root doesn't have a type then let's see if there are features in the\n // next step down\n if (!data.type) {\n // TODO: Allow GeoJSON objects to be overridden as an option\n\n // If not overridden, merge all features from all objects\n for (var gk in data) {\n if (!data[gk].type) {\n continue;\n }\n\n collections.push(data[gk]);\n }\n\n return geojsonMerge(collections);\n } else if (Array.isArray(data)) {\n return geojsonMerge(data);\n } else {\n return data;\n }\n }\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var lineStringAttributes = function(coordinates, colour, height) {\n var _coords = [];\n var _colours = [];\n\n var nextCoord;\n\n // Connect coordinate with the next to make a pair\n //\n // LineSegments requires pairs of vertices so repeat the last point if\n // there's an odd number of vertices\n coordinates.forEach((coordinate, index) => {\n _colours.push([colour.r, colour.g, colour.b]);\n _coords.push([coordinate[0], height, coordinate[1]]);\n\n nextCoord = (coordinates[index + 1]) ? coordinates[index + 1] : coordinate;\n\n _colours.push([colour.r, colour.g, colour.b]);\n _coords.push([nextCoord[0], height, nextCoord[1]]);\n });\n\n return {\n vertices: _coords,\n colours: _colours\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var multiLineStringAttributes = function(coordinates, colour, height) {\n var _coords = [];\n var _colours = [];\n\n var result;\n coordinates.forEach(coordinate => {\n result = lineStringAttributes(coordinate, colour, height);\n\n result.vertices.forEach(coord => {\n _coords.push(coord);\n });\n\n result.colours.forEach(colour => {\n _colours.push(colour);\n });\n });\n\n return {\n vertices: _coords,\n colours: _colours\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var polygonAttributes = function(coordinates, colour, height) {\n var earcutData = _toEarcut(coordinates);\n\n var faces = _triangulate(earcutData.vertices, earcutData.holes, earcutData.dimensions);\n\n var groupedVertices = [];\n for (i = 0, il = earcutData.vertices.length; i < il; i += earcutData.dimensions) {\n groupedVertices.push(earcutData.vertices.slice(i, i + earcutData.dimensions));\n }\n\n var extruded = extrudePolygon(groupedVertices, faces, {\n bottom: 0,\n top: height\n });\n\n var topColor = colour.clone().multiply(light);\n var bottomColor = colour.clone().multiply(shadow);\n\n var _vertices = extruded.positions;\n var _faces = [];\n var _colours = [];\n\n var _colour;\n extruded.top.forEach((face, fi) => {\n _colour = [];\n\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n\n _faces.push(face);\n _colours.push(_colour);\n });\n\n var allFlat = true;\n\n if (extruded.sides) {\n if (allFlat) {\n allFlat = false;\n }\n\n // Set up colours for every vertex with poor-mans AO on the sides\n extruded.sides.forEach((face, fi) => {\n _colour = [];\n\n // First face is always bottom-bottom-top\n if (fi % 2 === 0) {\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n // Reverse winding for the second face\n // top-top-bottom\n } else {\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n }\n\n _faces.push(face);\n _colours.push(_colour);\n });\n }\n\n // Skip bottom as there's no point rendering it\n // allFaces.push(extruded.faces);\n\n return {\n vertices: _vertices,\n faces: _faces,\n colours: _colours,\n flat: allFlat\n };\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var _toEarcut = function(data) {\n var dim = data[0][0].length;\n var result = {vertices: [], holes: [], dimensions: dim};\n var holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) {\n result.vertices.push(data[i][j][d]);\n }\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n\n return result;\n };\n\n // TODO: This is only used by GeoJSONTile so either roll it into that or\n // update GeoJSONTile to use the new GeoJSONLayer or geometry layers\n var _triangulate = function(contour, holes, dim) {\n // console.time('earcut');\n\n var faces = earcut(contour, holes, dim);\n var result = [];\n\n for (i = 0, il = faces.length; i < il; i += 3) {\n result.push(faces.slice(i, i + 3));\n }\n\n // console.timeEnd('earcut');\n\n return result;\n };\n\n return {\n defaultStyle: defaultStyle,\n collectFeatures: collectFeatures,\n lineStringAttributes: lineStringAttributes,\n multiLineStringAttributes: multiLineStringAttributes,\n polygonAttributes: polygonAttributes\n };\n})();\n\nexport default GeoJSON;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/GeoJSON.js\n **/","(function (global, factory) {\n typeof exports === 'object' && typeof module !== 'undefined' ? factory(exports) :\n typeof define === 'function' && define.amd ? define(['exports'], factory) :\n (factory((global.topojson = global.topojson || {})));\n}(this, (function (exports) { 'use strict';\n\nfunction noop() {}\n\nfunction transformAbsolute(transform) {\n if (!transform) return noop;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n point[0] = (x0 += point[0]) * kx + dx;\n point[1] = (y0 += point[1]) * ky + dy;\n };\n}\n\nfunction transformRelative(transform) {\n if (!transform) return noop;\n var x0,\n y0,\n kx = transform.scale[0],\n ky = transform.scale[1],\n dx = transform.translate[0],\n dy = transform.translate[1];\n return function(point, i) {\n if (!i) x0 = y0 = 0;\n var x1 = Math.round((point[0] - dx) / kx),\n y1 = Math.round((point[1] - dy) / ky);\n point[0] = x1 - x0;\n point[1] = y1 - y0;\n x0 = x1;\n y0 = y1;\n };\n}\n\nfunction reverse(array, n) {\n var t, j = array.length, i = j - n;\n while (i < --j) t = array[i], array[i++] = array[j], array[j] = t;\n}\n\nfunction bisect(a, x) {\n var lo = 0, hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (a[mid] < x) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n}\n\nfunction feature(topology, o) {\n return o.type === \"GeometryCollection\" ? {\n type: \"FeatureCollection\",\n features: o.geometries.map(function(o) { return feature$1(topology, o); })\n } : feature$1(topology, o);\n}\n\nfunction feature$1(topology, o) {\n var f = {\n type: \"Feature\",\n id: o.id,\n properties: o.properties || {},\n geometry: object(topology, o)\n };\n if (o.id == null) delete f.id;\n return f;\n}\n\nfunction object(topology, o) {\n var absolute = transformAbsolute(topology.transform),\n arcs = topology.arcs;\n\n function arc(i, points) {\n if (points.length) points.pop();\n for (var a = arcs[i < 0 ? ~i : i], k = 0, n = a.length, p; k < n; ++k) {\n points.push(p = a[k].slice());\n absolute(p, k);\n }\n if (i < 0) reverse(points, n);\n }\n\n function point(p) {\n p = p.slice();\n absolute(p, 0);\n return p;\n }\n\n function line(arcs) {\n var points = [];\n for (var i = 0, n = arcs.length; i < n; ++i) arc(arcs[i], points);\n if (points.length < 2) points.push(points[0].slice());\n return points;\n }\n\n function ring(arcs) {\n var points = line(arcs);\n while (points.length < 4) points.push(points[0].slice());\n return points;\n }\n\n function polygon(arcs) {\n return arcs.map(ring);\n }\n\n function geometry(o) {\n var t = o.type;\n return t === \"GeometryCollection\" ? {type: t, geometries: o.geometries.map(geometry)}\n : t in geometryType ? {type: t, coordinates: geometryType[t](o)}\n : null;\n }\n\n var geometryType = {\n Point: function(o) { return point(o.coordinates); },\n MultiPoint: function(o) { return o.coordinates.map(point); },\n LineString: function(o) { return line(o.arcs); },\n MultiLineString: function(o) { return o.arcs.map(line); },\n Polygon: function(o) { return polygon(o.arcs); },\n MultiPolygon: function(o) { return o.arcs.map(polygon); }\n };\n\n return geometry(o);\n}\n\nfunction stitchArcs(topology, arcs) {\n var stitchedArcs = {},\n fragmentByStart = {},\n fragmentByEnd = {},\n fragments = [],\n emptyIndex = -1;\n\n // Stitch empty arcs first, since they may be subsumed by other arcs.\n arcs.forEach(function(i, j) {\n var arc = topology.arcs[i < 0 ? ~i : i], t;\n if (arc.length < 3 && !arc[1][0] && !arc[1][1]) {\n t = arcs[++emptyIndex], arcs[emptyIndex] = i, arcs[j] = t;\n }\n });\n\n arcs.forEach(function(i) {\n var e = ends(i),\n start = e[0],\n end = e[1],\n f, g;\n\n if (f = fragmentByEnd[start]) {\n delete fragmentByEnd[f.end];\n f.push(i);\n f.end = end;\n if (g = fragmentByStart[end]) {\n delete fragmentByStart[g.start];\n var fg = g === f ? f : f.concat(g);\n fragmentByStart[fg.start = f.start] = fragmentByEnd[fg.end = g.end] = fg;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else if (f = fragmentByStart[end]) {\n delete fragmentByStart[f.start];\n f.unshift(i);\n f.start = start;\n if (g = fragmentByEnd[start]) {\n delete fragmentByEnd[g.end];\n var gf = g === f ? f : g.concat(f);\n fragmentByStart[gf.start = g.start] = fragmentByEnd[gf.end = f.end] = gf;\n } else {\n fragmentByStart[f.start] = fragmentByEnd[f.end] = f;\n }\n } else {\n f = [i];\n fragmentByStart[f.start = start] = fragmentByEnd[f.end = end] = f;\n }\n });\n\n function ends(i) {\n var arc = topology.arcs[i < 0 ? ~i : i], p0 = arc[0], p1;\n if (topology.transform) p1 = [0, 0], arc.forEach(function(dp) { p1[0] += dp[0], p1[1] += dp[1]; });\n else p1 = arc[arc.length - 1];\n return i < 0 ? [p1, p0] : [p0, p1];\n }\n\n function flush(fragmentByEnd, fragmentByStart) {\n for (var k in fragmentByEnd) {\n var f = fragmentByEnd[k];\n delete fragmentByStart[f.start];\n delete f.start;\n delete f.end;\n f.forEach(function(i) { stitchedArcs[i < 0 ? ~i : i] = 1; });\n fragments.push(f);\n }\n }\n\n flush(fragmentByEnd, fragmentByStart);\n flush(fragmentByStart, fragmentByEnd);\n arcs.forEach(function(i) { if (!stitchedArcs[i < 0 ? ~i : i]) fragments.push([i]); });\n\n return fragments;\n}\n\nfunction mesh(topology) {\n return object(topology, meshArcs.apply(this, arguments));\n}\n\nfunction meshArcs(topology, o, filter) {\n var arcs = [];\n\n function arc(i) {\n var j = i < 0 ? ~i : i;\n (geomsByArc[j] || (geomsByArc[j] = [])).push({i: i, g: geom});\n }\n\n function line(arcs) {\n arcs.forEach(arc);\n }\n\n function polygon(arcs) {\n arcs.forEach(line);\n }\n\n function geometry(o) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(geometry);\n else if (o.type in geometryType) geom = o, geometryType[o.type](o.arcs);\n }\n\n if (arguments.length > 1) {\n var geomsByArc = [],\n geom;\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs) { arcs.forEach(polygon); }\n };\n\n geometry(o);\n\n geomsByArc.forEach(arguments.length < 3\n ? function(geoms) { arcs.push(geoms[0].i); }\n : function(geoms) { if (filter(geoms[0].g, geoms[geoms.length - 1].g)) arcs.push(geoms[0].i); });\n } else {\n for (var i = 0, n = topology.arcs.length; i < n; ++i) arcs.push(i);\n }\n\n return {type: \"MultiLineString\", arcs: stitchArcs(topology, arcs)};\n}\n\nfunction cartesianTriangleArea(triangle) {\n var a = triangle[0], b = triangle[1], c = triangle[2];\n return Math.abs((a[0] - c[0]) * (b[1] - a[1]) - (a[0] - b[0]) * (c[1] - a[1]));\n}\n\nfunction ring(ring) {\n var i = -1,\n n = ring.length,\n a,\n b = ring[n - 1],\n area = 0;\n\n while (++i < n) {\n a = b;\n b = ring[i];\n area += a[0] * b[1] - a[1] * b[0];\n }\n\n return area / 2;\n}\n\nfunction merge(topology) {\n return object(topology, mergeArcs.apply(this, arguments));\n}\n\nfunction mergeArcs(topology, objects) {\n var polygonsByArc = {},\n polygons = [],\n components = [];\n\n objects.forEach(function(o) {\n if (o.type === \"Polygon\") register(o.arcs);\n else if (o.type === \"MultiPolygon\") o.arcs.forEach(register);\n });\n\n function register(polygon) {\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n (polygonsByArc[arc = arc < 0 ? ~arc : arc] || (polygonsByArc[arc] = [])).push(polygon);\n });\n });\n polygons.push(polygon);\n }\n\n function area(ring$$) {\n return Math.abs(ring(object(topology, {type: \"Polygon\", arcs: [ring$$]}).coordinates[0]));\n }\n\n polygons.forEach(function(polygon) {\n if (!polygon._) {\n var component = [],\n neighbors = [polygon];\n polygon._ = 1;\n components.push(component);\n while (polygon = neighbors.pop()) {\n component.push(polygon);\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n polygonsByArc[arc < 0 ? ~arc : arc].forEach(function(polygon) {\n if (!polygon._) {\n polygon._ = 1;\n neighbors.push(polygon);\n }\n });\n });\n });\n }\n }\n });\n\n polygons.forEach(function(polygon) {\n delete polygon._;\n });\n\n return {\n type: \"MultiPolygon\",\n arcs: components.map(function(polygons) {\n var arcs = [], n;\n\n // Extract the exterior (unique) arcs.\n polygons.forEach(function(polygon) {\n polygon.forEach(function(ring$$) {\n ring$$.forEach(function(arc) {\n if (polygonsByArc[arc < 0 ? ~arc : arc].length < 2) {\n arcs.push(arc);\n }\n });\n });\n });\n\n // Stitch the arcs into one or more rings.\n arcs = stitchArcs(topology, arcs);\n\n // If more than one ring is returned,\n // at most one of these rings can be the exterior;\n // choose the one with the greatest absolute area.\n if ((n = arcs.length) > 1) {\n for (var i = 1, k = area(arcs[0]), ki, t; i < n; ++i) {\n if ((ki = area(arcs[i])) > k) {\n t = arcs[0], arcs[0] = arcs[i], arcs[i] = t, k = ki;\n }\n }\n }\n\n return arcs;\n })\n };\n}\n\nfunction neighbors(objects) {\n var indexesByArc = {}, // arc index -> array of object indexes\n neighbors = objects.map(function() { return []; });\n\n function line(arcs, i) {\n arcs.forEach(function(a) {\n if (a < 0) a = ~a;\n var o = indexesByArc[a];\n if (o) o.push(i);\n else indexesByArc[a] = [i];\n });\n }\n\n function polygon(arcs, i) {\n arcs.forEach(function(arc) { line(arc, i); });\n }\n\n function geometry(o, i) {\n if (o.type === \"GeometryCollection\") o.geometries.forEach(function(o) { geometry(o, i); });\n else if (o.type in geometryType) geometryType[o.type](o.arcs, i);\n }\n\n var geometryType = {\n LineString: line,\n MultiLineString: polygon,\n Polygon: polygon,\n MultiPolygon: function(arcs, i) { arcs.forEach(function(arc) { polygon(arc, i); }); }\n };\n\n objects.forEach(geometry);\n\n for (var i in indexesByArc) {\n for (var indexes = indexesByArc[i], m = indexes.length, j = 0; j < m; ++j) {\n for (var k = j + 1; k < m; ++k) {\n var ij = indexes[j], ik = indexes[k], n;\n if ((n = neighbors[ij])[i = bisect(n, ik)] !== ik) n.splice(i, 0, ik);\n if ((n = neighbors[ik])[i = bisect(n, ij)] !== ij) n.splice(i, 0, ij);\n }\n }\n }\n\n return neighbors;\n}\n\nfunction compareArea(a, b) {\n return a[1][2] - b[1][2];\n}\n\nfunction minAreaHeap() {\n var heap = {},\n array = [],\n size = 0;\n\n heap.push = function(object) {\n up(array[object._ = size] = object, size++);\n return size;\n };\n\n heap.pop = function() {\n if (size <= 0) return;\n var removed = array[0], object;\n if (--size > 0) object = array[size], down(array[object._ = 0] = object, 0);\n return removed;\n };\n\n heap.remove = function(removed) {\n var i = removed._, object;\n if (array[i] !== removed) return; // invalid request\n if (i !== --size) object = array[size], (compareArea(object, removed) < 0 ? up : down)(array[object._ = i] = object, i);\n return i;\n };\n\n function up(object, i) {\n while (i > 0) {\n var j = ((i + 1) >> 1) - 1,\n parent = array[j];\n if (compareArea(object, parent) >= 0) break;\n array[parent._ = i] = parent;\n array[object._ = i = j] = object;\n }\n }\n\n function down(object, i) {\n while (true) {\n var r = (i + 1) << 1,\n l = r - 1,\n j = i,\n child = array[j];\n if (l < size && compareArea(array[l], child) < 0) child = array[j = l];\n if (r < size && compareArea(array[r], child) < 0) child = array[j = r];\n if (j === i) break;\n array[child._ = i] = child;\n array[object._ = i = j] = object;\n }\n }\n\n return heap;\n}\n\nfunction presimplify(topology, triangleArea) {\n var absolute = transformAbsolute(topology.transform),\n relative = transformRelative(topology.transform),\n heap = minAreaHeap();\n\n if (!triangleArea) triangleArea = cartesianTriangleArea;\n\n topology.arcs.forEach(function(arc) {\n var triangles = [],\n maxArea = 0,\n triangle,\n i,\n n,\n p;\n\n // To store each point’s effective area, we create a new array rather than\n // extending the passed-in point to workaround a Chrome/V8 bug (getting\n // stuck in smi mode). For midpoints, the initial effective area of\n // Infinity will be computed in the next step.\n for (i = 0, n = arc.length; i < n; ++i) {\n p = arc[i];\n absolute(arc[i] = [p[0], p[1], Infinity], i);\n }\n\n for (i = 1, n = arc.length - 1; i < n; ++i) {\n triangle = arc.slice(i - 1, i + 2);\n triangle[1][2] = triangleArea(triangle);\n triangles.push(triangle);\n heap.push(triangle);\n }\n\n for (i = 0, n = triangles.length; i < n; ++i) {\n triangle = triangles[i];\n triangle.previous = triangles[i - 1];\n triangle.next = triangles[i + 1];\n }\n\n while (triangle = heap.pop()) {\n var previous = triangle.previous,\n next = triangle.next;\n\n // If the area of the current point is less than that of the previous point\n // to be eliminated, use the latter's area instead. This ensures that the\n // current point cannot be eliminated without eliminating previously-\n // eliminated points.\n if (triangle[1][2] < maxArea) triangle[1][2] = maxArea;\n else maxArea = triangle[1][2];\n\n if (previous) {\n previous.next = next;\n previous[2] = triangle[2];\n update(previous);\n }\n\n if (next) {\n next.previous = previous;\n next[0] = triangle[0];\n update(next);\n }\n }\n\n arc.forEach(relative);\n });\n\n function update(triangle) {\n heap.remove(triangle);\n triangle[1][2] = triangleArea(triangle);\n heap.push(triangle);\n }\n\n return topology;\n}\n\nvar version = \"1.6.27\";\n\nexports.version = version;\nexports.mesh = mesh;\nexports.meshArcs = meshArcs;\nexports.merge = merge;\nexports.mergeArcs = mergeArcs;\nexports.feature = feature;\nexports.neighbors = neighbors;\nexports.presimplify = presimplify;\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\n})));\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/topojson/build/topojson.js\n ** module id = 76\n ** module chunks = 0\n **/","var normalize = require('geojson-normalize');\n\nmodule.exports = function(inputs) {\n return {\n type: 'FeatureCollection',\n features: inputs.reduce(function(memo, input) {\n return memo.concat(normalize(input).features);\n }, [])\n };\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/geojson-merge/index.js\n ** module id = 77\n ** module chunks = 0\n **/","module.exports = normalize;\n\nvar types = {\n Point: 'geometry',\n MultiPoint: 'geometry',\n LineString: 'geometry',\n MultiLineString: 'geometry',\n Polygon: 'geometry',\n MultiPolygon: 'geometry',\n GeometryCollection: 'geometry',\n Feature: 'feature',\n FeatureCollection: 'featurecollection'\n};\n\n/**\n * Normalize a GeoJSON feature into a FeatureCollection.\n *\n * @param {object} gj geojson data\n * @returns {object} normalized geojson data\n */\nfunction normalize(gj) {\n if (!gj || !gj.type) return null;\n var type = types[gj.type];\n if (!type) return null;\n\n if (type === 'geometry') {\n return {\n type: 'FeatureCollection',\n features: [{\n type: 'Feature',\n properties: {},\n geometry: gj\n }]\n };\n } else if (type === 'feature') {\n return {\n type: 'FeatureCollection',\n features: [gj]\n };\n } else if (type === 'featurecollection') {\n return gj;\n }\n}\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/geojson-normalize/index.js\n ** module id = 78\n ** module chunks = 0\n **/","'use strict';\n\nmodule.exports = earcut;\n\nfunction earcut(data, holeIndices, dim) {\n\n dim = dim || 2;\n\n var hasHoles = holeIndices && holeIndices.length,\n outerLen = hasHoles ? holeIndices[0] * dim : data.length,\n outerNode = linkedList(data, 0, outerLen, dim, true),\n triangles = [];\n\n if (!outerNode) return triangles;\n\n var minX, minY, maxX, maxY, x, y, size;\n\n if (hasHoles) outerNode = eliminateHoles(data, holeIndices, outerNode, dim);\n\n // if the shape is not too simple, we'll use z-order curve hash later; calculate polygon bbox\n if (data.length > 80 * dim) {\n minX = maxX = data[0];\n minY = maxY = data[1];\n\n for (var i = dim; i < outerLen; i += dim) {\n x = data[i];\n y = data[i + 1];\n if (x < minX) minX = x;\n if (y < minY) minY = y;\n if (x > maxX) maxX = x;\n if (y > maxY) maxY = y;\n }\n\n // minX, minY and size are later used to transform coords into integers for z-order calculation\n size = Math.max(maxX - minX, maxY - minY);\n }\n\n earcutLinked(outerNode, triangles, dim, minX, minY, size);\n\n return triangles;\n}\n\n// create a circular doubly linked list from polygon points in the specified winding order\nfunction linkedList(data, start, end, dim, clockwise) {\n var i, last;\n\n if (clockwise === (signedArea(data, start, end, dim) > 0)) {\n for (i = start; i < end; i += dim) last = insertNode(i, data[i], data[i + 1], last);\n } else {\n for (i = end - dim; i >= start; i -= dim) last = insertNode(i, data[i], data[i + 1], last);\n }\n\n if (last && equals(last, last.next)) {\n removeNode(last);\n last = last.next;\n }\n\n return last;\n}\n\n// eliminate colinear or duplicate points\nfunction filterPoints(start, end) {\n if (!start) return start;\n if (!end) end = start;\n\n var p = start,\n again;\n do {\n again = false;\n\n if (!p.steiner && (equals(p, p.next) || area(p.prev, p, p.next) === 0)) {\n removeNode(p);\n p = end = p.prev;\n if (p === p.next) return null;\n again = true;\n\n } else {\n p = p.next;\n }\n } while (again || p !== end);\n\n return end;\n}\n\n// main ear slicing loop which triangulates a polygon (given as a linked list)\nfunction earcutLinked(ear, triangles, dim, minX, minY, size, pass) {\n if (!ear) return;\n\n // interlink polygon nodes in z-order\n if (!pass && size) indexCurve(ear, minX, minY, size);\n\n var stop = ear,\n prev, next;\n\n // iterate through ears, slicing them one by one\n while (ear.prev !== ear.next) {\n prev = ear.prev;\n next = ear.next;\n\n if (size ? isEarHashed(ear, minX, minY, size) : isEar(ear)) {\n // cut off the triangle\n triangles.push(prev.i / dim);\n triangles.push(ear.i / dim);\n triangles.push(next.i / dim);\n\n removeNode(ear);\n\n // skipping the next vertice leads to less sliver triangles\n ear = next.next;\n stop = next.next;\n\n continue;\n }\n\n ear = next;\n\n // if we looped through the whole remaining polygon and can't find any more ears\n if (ear === stop) {\n // try filtering points and slicing again\n if (!pass) {\n earcutLinked(filterPoints(ear), triangles, dim, minX, minY, size, 1);\n\n // if this didn't work, try curing all small self-intersections locally\n } else if (pass === 1) {\n ear = cureLocalIntersections(ear, triangles, dim);\n earcutLinked(ear, triangles, dim, minX, minY, size, 2);\n\n // as a last resort, try splitting the remaining polygon into two\n } else if (pass === 2) {\n splitEarcut(ear, triangles, dim, minX, minY, size);\n }\n\n break;\n }\n }\n}\n\n// check whether a polygon node forms a valid ear with adjacent nodes\nfunction isEar(ear) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // now make sure we don't have other points inside the potential ear\n var p = ear.next.next;\n\n while (p !== ear.prev) {\n if (pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.next;\n }\n\n return true;\n}\n\nfunction isEarHashed(ear, minX, minY, size) {\n var a = ear.prev,\n b = ear,\n c = ear.next;\n\n if (area(a, b, c) >= 0) return false; // reflex, can't be an ear\n\n // triangle bbox; min & max are calculated like this for speed\n var minTX = a.x < b.x ? (a.x < c.x ? a.x : c.x) : (b.x < c.x ? b.x : c.x),\n minTY = a.y < b.y ? (a.y < c.y ? a.y : c.y) : (b.y < c.y ? b.y : c.y),\n maxTX = a.x > b.x ? (a.x > c.x ? a.x : c.x) : (b.x > c.x ? b.x : c.x),\n maxTY = a.y > b.y ? (a.y > c.y ? a.y : c.y) : (b.y > c.y ? b.y : c.y);\n\n // z-order range for the current triangle bbox;\n var minZ = zOrder(minTX, minTY, minX, minY, size),\n maxZ = zOrder(maxTX, maxTY, minX, minY, size);\n\n // first look for points inside the triangle in increasing z-order\n var p = ear.nextZ;\n\n while (p && p.z <= maxZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.nextZ;\n }\n\n // then look for points in decreasing z-order\n p = ear.prevZ;\n\n while (p && p.z >= minZ) {\n if (p !== ear.prev && p !== ear.next &&\n pointInTriangle(a.x, a.y, b.x, b.y, c.x, c.y, p.x, p.y) &&\n area(p.prev, p, p.next) >= 0) return false;\n p = p.prevZ;\n }\n\n return true;\n}\n\n// go through all polygon nodes and cure small local self-intersections\nfunction cureLocalIntersections(start, triangles, dim) {\n var p = start;\n do {\n var a = p.prev,\n b = p.next.next;\n\n if (!equals(a, b) && intersects(a, p, p.next, b) && locallyInside(a, b) && locallyInside(b, a)) {\n\n triangles.push(a.i / dim);\n triangles.push(p.i / dim);\n triangles.push(b.i / dim);\n\n // remove two nodes involved\n removeNode(p);\n removeNode(p.next);\n\n p = start = b;\n }\n p = p.next;\n } while (p !== start);\n\n return p;\n}\n\n// try splitting polygon into two and triangulate them independently\nfunction splitEarcut(start, triangles, dim, minX, minY, size) {\n // look for a valid diagonal that divides the polygon into two\n var a = start;\n do {\n var b = a.next.next;\n while (b !== a.prev) {\n if (a.i !== b.i && isValidDiagonal(a, b)) {\n // split the polygon in two by the diagonal\n var c = splitPolygon(a, b);\n\n // filter colinear points around the cuts\n a = filterPoints(a, a.next);\n c = filterPoints(c, c.next);\n\n // run earcut on each half\n earcutLinked(a, triangles, dim, minX, minY, size);\n earcutLinked(c, triangles, dim, minX, minY, size);\n return;\n }\n b = b.next;\n }\n a = a.next;\n } while (a !== start);\n}\n\n// link every hole into the outer loop, producing a single-ring polygon without holes\nfunction eliminateHoles(data, holeIndices, outerNode, dim) {\n var queue = [],\n i, len, start, end, list;\n\n for (i = 0, len = holeIndices.length; i < len; i++) {\n start = holeIndices[i] * dim;\n end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n list = linkedList(data, start, end, dim, false);\n if (list === list.next) list.steiner = true;\n queue.push(getLeftmost(list));\n }\n\n queue.sort(compareX);\n\n // process holes from left to right\n for (i = 0; i < queue.length; i++) {\n eliminateHole(queue[i], outerNode);\n outerNode = filterPoints(outerNode, outerNode.next);\n }\n\n return outerNode;\n}\n\nfunction compareX(a, b) {\n return a.x - b.x;\n}\n\n// find a bridge between vertices that connects hole with an outer ring and and link it\nfunction eliminateHole(hole, outerNode) {\n outerNode = findHoleBridge(hole, outerNode);\n if (outerNode) {\n var b = splitPolygon(outerNode, hole);\n filterPoints(b, b.next);\n }\n}\n\n// David Eberly's algorithm for finding a bridge between hole and outer polygon\nfunction findHoleBridge(hole, outerNode) {\n var p = outerNode,\n hx = hole.x,\n hy = hole.y,\n qx = -Infinity,\n m;\n\n // find a segment intersected by a ray from the hole's leftmost point to the left;\n // segment's endpoint with lesser x will be potential connection point\n do {\n if (hy <= p.y && hy >= p.next.y) {\n var x = p.x + (hy - p.y) * (p.next.x - p.x) / (p.next.y - p.y);\n if (x <= hx && x > qx) {\n qx = x;\n if (x === hx) {\n if (hy === p.y) return p;\n if (hy === p.next.y) return p.next;\n }\n m = p.x < p.next.x ? p : p.next;\n }\n }\n p = p.next;\n } while (p !== outerNode);\n\n if (!m) return null;\n\n if (hx === qx) return m.prev; // hole touches outer segment; pick lower endpoint\n\n // look for points inside the triangle of hole point, segment intersection and endpoint;\n // if there are no points found, we have a valid connection;\n // otherwise choose the point of the minimum angle with the ray as connection point\n\n var stop = m,\n mx = m.x,\n my = m.y,\n tanMin = Infinity,\n tan;\n\n p = m.next;\n\n while (p !== stop) {\n if (hx >= p.x && p.x >= mx &&\n pointInTriangle(hy < my ? hx : qx, hy, mx, my, hy < my ? qx : hx, hy, p.x, p.y)) {\n\n tan = Math.abs(hy - p.y) / (hx - p.x); // tangential\n\n if ((tan < tanMin || (tan === tanMin && p.x > m.x)) && locallyInside(p, hole)) {\n m = p;\n tanMin = tan;\n }\n }\n\n p = p.next;\n }\n\n return m;\n}\n\n// interlink polygon nodes in z-order\nfunction indexCurve(start, minX, minY, size) {\n var p = start;\n do {\n if (p.z === null) p.z = zOrder(p.x, p.y, minX, minY, size);\n p.prevZ = p.prev;\n p.nextZ = p.next;\n p = p.next;\n } while (p !== start);\n\n p.prevZ.nextZ = null;\n p.prevZ = null;\n\n sortLinked(p);\n}\n\n// Simon Tatham's linked list merge sort algorithm\n// http://www.chiark.greenend.org.uk/~sgtatham/algorithms/listsort.html\nfunction sortLinked(list) {\n var i, p, q, e, tail, numMerges, pSize, qSize,\n inSize = 1;\n\n do {\n p = list;\n list = null;\n tail = null;\n numMerges = 0;\n\n while (p) {\n numMerges++;\n q = p;\n pSize = 0;\n for (i = 0; i < inSize; i++) {\n pSize++;\n q = q.nextZ;\n if (!q) break;\n }\n\n qSize = inSize;\n\n while (pSize > 0 || (qSize > 0 && q)) {\n\n if (pSize === 0) {\n e = q;\n q = q.nextZ;\n qSize--;\n } else if (qSize === 0 || !q) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else if (p.z <= q.z) {\n e = p;\n p = p.nextZ;\n pSize--;\n } else {\n e = q;\n q = q.nextZ;\n qSize--;\n }\n\n if (tail) tail.nextZ = e;\n else list = e;\n\n e.prevZ = tail;\n tail = e;\n }\n\n p = q;\n }\n\n tail.nextZ = null;\n inSize *= 2;\n\n } while (numMerges > 1);\n\n return list;\n}\n\n// z-order of a point given coords and size of the data bounding box\nfunction zOrder(x, y, minX, minY, size) {\n // coords are transformed into non-negative 15-bit integer range\n x = 32767 * (x - minX) / size;\n y = 32767 * (y - minY) / size;\n\n x = (x | (x << 8)) & 0x00FF00FF;\n x = (x | (x << 4)) & 0x0F0F0F0F;\n x = (x | (x << 2)) & 0x33333333;\n x = (x | (x << 1)) & 0x55555555;\n\n y = (y | (y << 8)) & 0x00FF00FF;\n y = (y | (y << 4)) & 0x0F0F0F0F;\n y = (y | (y << 2)) & 0x33333333;\n y = (y | (y << 1)) & 0x55555555;\n\n return x | (y << 1);\n}\n\n// find the leftmost node of a polygon ring\nfunction getLeftmost(start) {\n var p = start,\n leftmost = start;\n do {\n if (p.x < leftmost.x) leftmost = p;\n p = p.next;\n } while (p !== start);\n\n return leftmost;\n}\n\n// check if a point lies within a convex triangle\nfunction pointInTriangle(ax, ay, bx, by, cx, cy, px, py) {\n return (cx - px) * (ay - py) - (ax - px) * (cy - py) >= 0 &&\n (ax - px) * (by - py) - (bx - px) * (ay - py) >= 0 &&\n (bx - px) * (cy - py) - (cx - px) * (by - py) >= 0;\n}\n\n// check if a diagonal between two polygon nodes is valid (lies in polygon interior)\nfunction isValidDiagonal(a, b) {\n return a.next.i !== b.i && a.prev.i !== b.i && !intersectsPolygon(a, b) &&\n locallyInside(a, b) && locallyInside(b, a) && middleInside(a, b);\n}\n\n// signed area of a triangle\nfunction area(p, q, r) {\n return (q.y - p.y) * (r.x - q.x) - (q.x - p.x) * (r.y - q.y);\n}\n\n// check if two points are equal\nfunction equals(p1, p2) {\n return p1.x === p2.x && p1.y === p2.y;\n}\n\n// check if two segments intersect\nfunction intersects(p1, q1, p2, q2) {\n if ((equals(p1, q1) && equals(p2, q2)) ||\n (equals(p1, q2) && equals(p2, q1))) return true;\n return area(p1, q1, p2) > 0 !== area(p1, q1, q2) > 0 &&\n area(p2, q2, p1) > 0 !== area(p2, q2, q1) > 0;\n}\n\n// check if a polygon diagonal intersects any polygon segments\nfunction intersectsPolygon(a, b) {\n var p = a;\n do {\n if (p.i !== a.i && p.next.i !== a.i && p.i !== b.i && p.next.i !== b.i &&\n intersects(p, p.next, a, b)) return true;\n p = p.next;\n } while (p !== a);\n\n return false;\n}\n\n// check if a polygon diagonal is locally inside the polygon\nfunction locallyInside(a, b) {\n return area(a.prev, a, a.next) < 0 ?\n area(a, b, a.next) >= 0 && area(a, a.prev, b) >= 0 :\n area(a, b, a.prev) < 0 || area(a, a.next, b) < 0;\n}\n\n// check if the middle point of a polygon diagonal is inside the polygon\nfunction middleInside(a, b) {\n var p = a,\n inside = false,\n px = (a.x + b.x) / 2,\n py = (a.y + b.y) / 2;\n do {\n if (((p.y > py) !== (p.next.y > py)) && (px < (p.next.x - p.x) * (py - p.y) / (p.next.y - p.y) + p.x))\n inside = !inside;\n p = p.next;\n } while (p !== a);\n\n return inside;\n}\n\n// link two polygon vertices with a bridge; if the vertices belong to the same ring, it splits polygon into two;\n// if one belongs to the outer ring and another to a hole, it merges it into a single ring\nfunction splitPolygon(a, b) {\n var a2 = new Node(a.i, a.x, a.y),\n b2 = new Node(b.i, b.x, b.y),\n an = a.next,\n bp = b.prev;\n\n a.next = b;\n b.prev = a;\n\n a2.next = an;\n an.prev = a2;\n\n b2.next = a2;\n a2.prev = b2;\n\n bp.next = b2;\n b2.prev = bp;\n\n return b2;\n}\n\n// create a node and optionally link it with previous one (in a circular doubly linked list)\nfunction insertNode(i, x, y, last) {\n var p = new Node(i, x, y);\n\n if (!last) {\n p.prev = p;\n p.next = p;\n\n } else {\n p.next = last.next;\n p.prev = last;\n last.next.prev = p;\n last.next = p;\n }\n return p;\n}\n\nfunction removeNode(p) {\n p.next.prev = p.prev;\n p.prev.next = p.next;\n\n if (p.prevZ) p.prevZ.nextZ = p.nextZ;\n if (p.nextZ) p.nextZ.prevZ = p.prevZ;\n}\n\nfunction Node(i, x, y) {\n // vertice index in coordinates array\n this.i = i;\n\n // vertex coordinates\n this.x = x;\n this.y = y;\n\n // previous and next vertice nodes in a polygon ring\n this.prev = null;\n this.next = null;\n\n // z-order curve value\n this.z = null;\n\n // previous and next nodes in z-order\n this.prevZ = null;\n this.nextZ = null;\n\n // indicates whether this is a steiner point\n this.steiner = false;\n}\n\n// return a percentage difference between the polygon area and its triangulation area;\n// used to verify correctness of triangulation\nearcut.deviation = function (data, holeIndices, dim, triangles) {\n var hasHoles = holeIndices && holeIndices.length;\n var outerLen = hasHoles ? holeIndices[0] * dim : data.length;\n\n var polygonArea = Math.abs(signedArea(data, 0, outerLen, dim));\n if (hasHoles) {\n for (var i = 0, len = holeIndices.length; i < len; i++) {\n var start = holeIndices[i] * dim;\n var end = i < len - 1 ? holeIndices[i + 1] * dim : data.length;\n polygonArea -= Math.abs(signedArea(data, start, end, dim));\n }\n }\n\n var trianglesArea = 0;\n for (i = 0; i < triangles.length; i += 3) {\n var a = triangles[i] * dim;\n var b = triangles[i + 1] * dim;\n var c = triangles[i + 2] * dim;\n trianglesArea += Math.abs(\n (data[a] - data[c]) * (data[b + 1] - data[a + 1]) -\n (data[a] - data[b]) * (data[c + 1] - data[a + 1]));\n }\n\n return polygonArea === 0 && trianglesArea === 0 ? 0 :\n Math.abs((trianglesArea - polygonArea) / polygonArea);\n};\n\nfunction signedArea(data, start, end, dim) {\n var sum = 0;\n for (var i = start, j = end - dim; i < end; i += dim) {\n sum += (data[j] - data[i]) * (data[i + 1] + data[j + 1]);\n j = i;\n }\n return sum;\n}\n\n// turn a polygon in a multi-dimensional array form (e.g. as in GeoJSON) into a form Earcut accepts\nearcut.flatten = function (data) {\n var dim = data[0][0].length,\n result = {vertices: [], holes: [], dimensions: dim},\n holeIndex = 0;\n\n for (var i = 0; i < data.length; i++) {\n for (var j = 0; j < data[i].length; j++) {\n for (var d = 0; d < dim; d++) result.vertices.push(data[i][j][d]);\n }\n if (i > 0) {\n holeIndex += data[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n return result;\n};\n\n\n\n/*****************\n ** WEBPACK FOOTER\n ** ./~/earcut/src/earcut.js\n ** module id = 79\n ** module chunks = 0\n **/","/*\n * Extrude a polygon given its vertices and triangulated faces\n *\n * Based on:\n * https://github.com/freeman-lab/extrude\n */\n\nimport extend from 'lodash.assign';\n\nvar extrudePolygon = function(points, faces, _options) {\n var defaults = {\n top: 1,\n bottom: 0,\n closed: true\n };\n\n var options = extend({}, defaults, _options);\n\n var n = points.length;\n var positions;\n var cells;\n var topCells;\n var bottomCells;\n var sideCells;\n\n // If bottom and top values are identical then return the flat shape\n (options.top === options.bottom) ? flat() : full();\n\n function flat() {\n positions = points.map(function(p) { return [p[0], options.top, p[1]]; });\n cells = faces;\n topCells = faces;\n }\n\n function full() {\n positions = [];\n points.forEach(function(p) { positions.push([p[0], options.top, p[1]]); });\n points.forEach(function(p) { positions.push([p[0], options.bottom, p[1]]); });\n\n cells = [];\n for (var i = 0; i < n; i++) {\n if (i === (n - 1)) {\n cells.push([i + n, n, i]);\n cells.push([0, i, n]);\n } else {\n cells.push([i + n, i + n + 1, i]);\n cells.push([i + 1, i, i + n + 1]);\n }\n }\n\n sideCells = [].concat(cells);\n\n if (options.closed) {\n var top = faces;\n var bottom = top.map(function(p) { return p.map(function(v) { return v + n; }); });\n bottom = bottom.map(function(p) { return [p[0], p[2], p[1]]; });\n cells = cells.concat(top).concat(bottom);\n\n topCells = top;\n bottomCells = bottom;\n }\n }\n\n return {\n positions: positions,\n faces: cells,\n top: topCells,\n bottom: bottomCells,\n sides: sideCells\n };\n};\n\nexport default extrudePolygon;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/extrudePolygon.js\n **/","/*\n * BufferGeometry helpers\n */\n\nimport THREE from 'three';\n\nvar Buffer = (function() {\n // Merge TypedArrays of the same type\n // Returns merged array as well as indexes for splitting the array\n var mergeFloat32Arrays = function(arrays) {\n var size = 0;\n var map = new Int32Array(arrays.length * 2);\n\n var lastIndex = 0;\n var length;\n\n // Find size of each array\n arrays.forEach((_array, index) => {\n length = _array.length;\n size += length;\n map.set([lastIndex, lastIndex + length], index * 2);\n lastIndex += length;\n });\n\n // Create a new array of total size\n var mergedArray = new Float32Array(size);\n\n // Add each array to the new array\n arrays.forEach((_array, index) => {\n mergedArray.set(_array, map[index * 2]);\n });\n\n return [\n mergedArray,\n map\n ];\n };\n\n var splitFloat32Array = function(data) {\n var arr = data[0];\n var map = data[1];\n\n var start;\n var arrays = [];\n\n // Iterate over map\n for (var i = 0; i < map.length / 2; i++) {\n start = i * 2;\n arrays.push(arr.subarray(map[start], map[start + 1]));\n }\n\n return arrays;\n };\n\n // TODO: Create a generic method that can work for any typed array\n var mergeUint8Arrays = function(arrays) {\n var size = 0;\n var map = new Int32Array(arrays.length * 2);\n\n var lastIndex = 0;\n var length;\n\n // Find size of each array\n arrays.forEach((_array, index) => {\n length = _array.length;\n size += length;\n map.set([lastIndex, lastIndex + length], index * 2);\n lastIndex += length;\n });\n\n // Create a new array of total size\n var mergedArray = new Uint8Array(size);\n\n // Add each array to the new array\n arrays.forEach((_array, index) => {\n mergedArray.set(_array, map[index * 2]);\n });\n\n return [\n mergedArray,\n map\n ];\n };\n\n // TODO: Dedupe with splitFloat32Array\n var splitUint8Array = function(data) {\n var arr = data[0];\n var map = data[1];\n\n var start;\n var arrays = [];\n\n // Iterate over map\n for (var i = 0; i < map.length / 2; i++) {\n start = i * 2;\n arrays.push(arr.subarray(map[start], map[start + 1]));\n }\n\n return arrays;\n };\n\n // Merge multiple attribute objects into a single attribute object\n //\n // Attribute objects must all use the same attribute keys\n var mergeAttributes = function(attributes) {\n var lengths = {};\n\n // Find array lengths\n attributes.forEach(_attributes => {\n for (var k in _attributes) {\n if (!lengths[k]) {\n lengths[k] = 0;\n }\n\n lengths[k] += _attributes[k].length;\n }\n });\n\n var mergedAttributes = {};\n\n // Set up arrays to merge into\n for (var k in lengths) {\n mergedAttributes[k] = new Float32Array(lengths[k]);\n }\n\n var lastLengths = {};\n\n attributes.forEach(_attributes => {\n for (var k in _attributes) {\n if (!lastLengths[k]) {\n lastLengths[k] = 0;\n }\n\n mergedAttributes[k].set(_attributes[k], lastLengths[k]);\n\n lastLengths[k] += _attributes[k].length;\n }\n });\n\n return mergedAttributes;\n };\n\n var createLineGeometry = function(lines, offset) {\n var geometry = new THREE.BufferGeometry();\n\n var vertices = new Float32Array(lines.verticesCount * 3);\n var colours = new Float32Array(lines.verticesCount * 3);\n\n var pickingIds;\n if (lines.pickingIds) {\n // One component per vertex (1)\n pickingIds = new Float32Array(lines.verticesCount);\n }\n\n var _vertices;\n var _colour;\n var _pickingId;\n\n var lastIndex = 0;\n\n for (var i = 0; i < lines.vertices.length; i++) {\n _vertices = lines.vertices[i];\n _colour = lines.colours[i];\n\n if (pickingIds) {\n _pickingId = lines.pickingIds[i];\n }\n\n for (var j = 0; j < _vertices.length; j++) {\n var ax = _vertices[j][0] + offset.x;\n var ay = _vertices[j][1];\n var az = _vertices[j][2] + offset.y;\n\n var c1 = _colour[j];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n }\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(colours, 3));\n\n if (pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n return geometry;\n };\n\n // TODO: Make picking IDs optional\n var createGeometry = function(attributes, offset) {\n var geometry = new THREE.BufferGeometry();\n\n // Three components per vertex per face (3 x 3 = 9)\n var vertices = new Float32Array(attributes.facesCount * 9);\n var normals = new Float32Array(attributes.facesCount * 9);\n var colours = new Float32Array(attributes.facesCount * 9);\n\n var pickingIds;\n if (attributes.pickingIds) {\n // One component per vertex per face (1 x 3 = 3)\n pickingIds = new Float32Array(attributes.facesCount * 3);\n }\n\n var pA = new THREE.Vector3();\n var pB = new THREE.Vector3();\n var pC = new THREE.Vector3();\n\n var cb = new THREE.Vector3();\n var ab = new THREE.Vector3();\n\n var index;\n var _faces;\n var _vertices;\n var _colour;\n var _pickingId;\n var lastIndex = 0;\n for (var i = 0; i < attributes.faces.length; i++) {\n _faces = attributes.faces[i];\n _vertices = attributes.vertices[i];\n _colour = attributes.colours[i];\n\n if (pickingIds) {\n _pickingId = attributes.pickingIds[i];\n }\n\n for (var j = 0; j < _faces.length; j++) {\n // Array of vertex indexes for the face\n index = _faces[j][0];\n\n var ax = _vertices[index][0] + offset.x;\n var ay = _vertices[index][1];\n var az = _vertices[index][2] + offset.y;\n\n var c1 = _colour[j][0];\n\n index = _faces[j][1];\n\n var bx = _vertices[index][0] + offset.x;\n var by = _vertices[index][1];\n var bz = _vertices[index][2] + offset.y;\n\n var c2 = _colour[j][1];\n\n index = _faces[j][2];\n\n var cx = _vertices[index][0] + offset.x;\n var cy = _vertices[index][1];\n var cz = _vertices[index][2] + offset.y;\n\n var c3 = _colour[j][2];\n\n // Flat face normals\n // From: http://threejs.org/examples/webgl_buffergeometry.html\n pA.set(ax, ay, az);\n pB.set(bx, by, bz);\n pC.set(cx, cy, cz);\n\n cb.subVectors(pC, pB);\n ab.subVectors(pA, pB);\n cb.cross(ab);\n\n cb.normalize();\n\n var nx = cb.x;\n var ny = cb.y;\n var nz = cb.z;\n\n vertices[lastIndex * 9 + 0] = ax;\n vertices[lastIndex * 9 + 1] = ay;\n vertices[lastIndex * 9 + 2] = az;\n\n normals[lastIndex * 9 + 0] = nx;\n normals[lastIndex * 9 + 1] = ny;\n normals[lastIndex * 9 + 2] = nz;\n\n colours[lastIndex * 9 + 0] = c1[0];\n colours[lastIndex * 9 + 1] = c1[1];\n colours[lastIndex * 9 + 2] = c1[2];\n\n vertices[lastIndex * 9 + 3] = bx;\n vertices[lastIndex * 9 + 4] = by;\n vertices[lastIndex * 9 + 5] = bz;\n\n normals[lastIndex * 9 + 3] = nx;\n normals[lastIndex * 9 + 4] = ny;\n normals[lastIndex * 9 + 5] = nz;\n\n colours[lastIndex * 9 + 3] = c2[0];\n colours[lastIndex * 9 + 4] = c2[1];\n colours[lastIndex * 9 + 5] = c2[2];\n\n vertices[lastIndex * 9 + 6] = cx;\n vertices[lastIndex * 9 + 7] = cy;\n vertices[lastIndex * 9 + 8] = cz;\n\n normals[lastIndex * 9 + 6] = nx;\n normals[lastIndex * 9 + 7] = ny;\n normals[lastIndex * 9 + 8] = nz;\n\n colours[lastIndex * 9 + 6] = c3[0];\n colours[lastIndex * 9 + 7] = c3[1];\n colours[lastIndex * 9 + 8] = c3[2];\n\n if (pickingIds) {\n pickingIds[lastIndex * 3 + 0] = _pickingId;\n pickingIds[lastIndex * 3 + 1] = _pickingId;\n pickingIds[lastIndex * 3 + 2] = _pickingId;\n }\n\n lastIndex++;\n }\n }\n\n // itemSize = 3 because there are 3 values (components) per vertex\n geometry.addAttribute('position', new THREE.BufferAttribute(vertices, 3));\n geometry.addAttribute('normal', new THREE.BufferAttribute(normals, 3));\n geometry.addAttribute('color', new THREE.BufferAttribute(colours, 3));\n\n if (pickingIds) {\n geometry.addAttribute('pickingId', new THREE.BufferAttribute(pickingIds, 1));\n }\n\n geometry.computeBoundingBox();\n\n return geometry;\n };\n\n var textEncoder = new TextEncoder('utf-8');\n var textDecoder = new TextDecoder('utf-8');\n\n var stringToUint8Array = function(str) {\n return textEncoder.encode(str);\n };\n\n var uint8ArrayToString = function(ab) {\n return textDecoder.decode(ab);\n };\n\n return {\n mergeFloat32Arrays: mergeFloat32Arrays,\n splitFloat32Array: splitFloat32Array,\n mergeUint8Arrays: mergeUint8Arrays,\n splitUint8Array: splitUint8Array,\n mergeAttributes: mergeAttributes,\n createLineGeometry: createLineGeometry,\n createGeometry: createGeometry,\n stringToUint8Array: stringToUint8Array,\n uint8ArrayToString: uint8ArrayToString\n };\n})();\n\nexport default Buffer;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Buffer.js\n **/","import THREE from 'three';\nimport PickingShader from './PickingShader';\n\n// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\nvar PickingMaterial = function() {\n THREE.ShaderMaterial.call(this, {\n uniforms: {\n size: {\n type: 'f',\n value: 0.01,\n },\n scale: {\n type: 'f',\n value: 400,\n }\n },\n // attributes: ['position', 'id'],\n vertexShader: PickingShader.vertexShader,\n fragmentShader: PickingShader.fragmentShader\n });\n\n this.linePadding = 2;\n};\n\nPickingMaterial.prototype = Object.create(THREE.ShaderMaterial.prototype);\n\nPickingMaterial.prototype.constructor = PickingMaterial;\n\nPickingMaterial.prototype.setPointSize = function(size) {\n this.uniforms.size.value = size;\n};\n\nPickingMaterial.prototype.setPointScale = function(scale) {\n this.uniforms.scale.value = scale;\n};\n\nexport default PickingMaterial;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingMaterial.js\n **/","// FROM: https://github.com/brianxu/GPUPicker/blob/master/GPUPicker.js\n\nvar PickingShader = {\n vertexShader: [\n\t\t'attribute float pickingId;',\n\t\t// '',\n\t\t// 'uniform float size;',\n\t\t// 'uniform float scale;',\n\t\t'',\n\t\t'varying vec4 worldId;',\n\t\t'',\n\t\t'void main() {',\n\t\t' vec4 mvPosition = modelViewMatrix * vec4( position, 1.0 );',\n\t\t// ' gl_PointSize = size * ( scale / length( mvPosition.xyz ) );',\n\t\t' vec3 a = fract(vec3(1.0/255.0, 1.0/(255.0*255.0), 1.0/(255.0*255.0*255.0)) * pickingId);',\n\t\t' a -= a.xxy * vec3(0.0, 1.0/255.0, 1.0/255.0);',\n\t\t' worldId = vec4(a,1);',\n\t\t' gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );',\n\t\t'}'\n\t].join('\\n'),\n\n fragmentShader: [\n\t\t'#ifdef GL_ES\\n',\n\t\t'precision highp float;\\n',\n\t\t'#endif\\n',\n\t\t'',\n\t\t'varying vec4 worldId;',\n\t\t'',\n\t\t'void main() {',\n\t\t' gl_FragColor = worldId;',\n\t\t'}'\n\t].join('\\n')\n};\n\nexport default PickingShader;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/engine/PickingShader.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\n// TODO: Allow _setBufferAttributes to use a custom function passed in to\n// generate a custom mesh\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Geo from '../../geo/Geo';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport earcut from 'earcut';\nimport extrudePolygon from '../../util/extrudePolygon';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PolygonLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n polygonMaterial: null,\n onPolygonMesh: null,\n onBufferAttributes: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n color: '#ffffff',\n transparent: false,\n opacity: 1,\n blending: THREE.NormalBlending,\n height: 0\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of polygons so it's easy to support\n // MultiPolygon features (a single polygon would be a MultiPolygon with a\n // single polygon in the array)\n this._coordinates = (PolygonLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n PolygonLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {\n this._bufferAttributes = Buffer.mergeAttributes(result.attributes);\n\n if (result.outlineAttributes.length > 0) {\n this._outlineBufferAttributes = Buffer.mergeAttributes(result.outlineAttributes);\n }\n\n this._flat = result.flat;\n\n if (this.isOutput()) {\n var attributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3,\n tops: 1\n };\n\n if (this._options.interactive) {\n attributeLengths.pickingIds = 1;\n }\n\n var style = this._options.style;\n\n // Set mesh if not merging elsewhere\n PolygonLayer.SetMesh(this._bufferAttributes, attributeLengths, this._flat, style, this._options, this._world._environment._skybox).then((result) => {\n // Output mesh\n this.add(result.mesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n result.attributes = null;\n result.outlineAttributes = null;\n result = null;\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Return center of polygon as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n //\n // TODO: Find proper center position instead of returning first coordinate\n // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polygon.js#L15\n getCenter() {\n return this._center;\n }\n\n // Return polygon bounds in geographic coordinates\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n // Create and store reference to THREE.BufferAttribute data for this layer\n static SetBufferAttributes(coordinates, options) {\n return new Promise((resolve) => {\n var height = 0;\n\n // Convert height into world units\n if (options.style.height && options.style.height !== 0) {\n height = Geo.metresToWorld(options.style.height, options.pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(options.style.color);\n\n // Light and dark colours used for poor-mans AO gradient on object sides\n var light = new THREE.Color(0xffffff);\n var shadow = new THREE.Color(0x666666);\n\n var flat = true;\n\n var outlineAttributes = [];\n\n // For each polygon\n var attributes = coordinates.map(_coordinates => {\n // Convert coordinates to earcut format\n var _earcut = PolygonLayer.ToEarcut(_coordinates);\n\n // Triangulate faces using earcut\n var faces = PolygonLayer.Triangulate(_earcut.vertices, _earcut.holes, _earcut.dimensions);\n\n var groupedVertices = [];\n for (i = 0, il = _earcut.vertices.length; i < il; i += _earcut.dimensions) {\n groupedVertices.push(_earcut.vertices.slice(i, i + _earcut.dimensions));\n }\n\n var extruded = extrudePolygon(groupedVertices, faces, {\n bottom: 0,\n top: height\n });\n\n var topColor = colour.clone().multiply(light);\n var bottomColor = colour.clone().multiply(shadow);\n\n var _vertices = extruded.positions;\n var _faces = [];\n var _colours = [];\n var _tops = [];\n\n var _colour;\n extruded.top.forEach((face, fi) => {\n _colour = [];\n\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n _colour.push([colour.r, colour.g, colour.b]);\n\n _tops.push([true, true, true]);\n\n _faces.push(face);\n _colours.push(_colour);\n });\n\n if (extruded.sides) {\n flat = false;\n\n // Set up colours for every vertex with poor-mans AO on the sides\n extruded.sides.forEach((face, fi) => {\n _colour = [];\n\n // First face is always bottom-bottom-top\n if (fi % 2 === 0) {\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n\n _tops.push([false, false, true]);\n // Reverse winding for the second face\n // top-top-bottom\n } else {\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([topColor.r, topColor.g, topColor.b]);\n _colour.push([bottomColor.r, bottomColor.g, bottomColor.b]);\n\n _tops.push([true, true, false]);\n }\n\n _faces.push(face);\n _colours.push(_colour);\n });\n }\n\n // Skip bottom as there's no point rendering it\n // allFaces.push(extruded.faces);\n\n var polygon = {\n vertices: _vertices,\n faces: _faces,\n colours: _colours,\n tops: _tops,\n facesCount: _faces.length\n };\n\n if (options.style.outline) {\n var outlineColour = new THREE.Color();\n outlineColour.set(options.style.outlineColor || 0x000000);\n\n outlineAttributes.push(PolygonLayer.Set2DOutline(_coordinates, outlineColour));\n }\n\n if (options.interactive && options.pickingId) {\n // Inject picking ID\n polygon.pickingId = options.pickingId;\n }\n\n // Convert polygon representation to proper attribute arrays\n return PolygonLayer.ToAttributes(polygon);\n });\n\n resolve({\n attributes: attributes,\n outlineAttributes: outlineAttributes,\n flat: flat\n });\n });\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n getOutlineBufferAttributes() {\n return this._outlineBufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n this._outlineBufferAttributes = null;\n }\n\n // Threshold angle is currently in rads\n static Set2DOutline(coordinates, colour) {\n var _vertices = [];\n\n coordinates.forEach((ring) => {\n var _ring = ring.map((coordinate) => {\n return [coordinate.x, 0, coordinate.y];\n });\n\n // Add in duplicate vertices for line segments to work\n var verticeCount = _ring.length;\n var first = true;\n while (--verticeCount) {\n if (first || verticeCount === 0) {\n first = false;\n continue;\n }\n\n _ring.splice(verticeCount + 1, 0, _ring[verticeCount]);\n }\n\n _vertices = _vertices.concat(_ring);\n });\n\n _colour = [colour.r, colour.g, colour.b];\n\n var vertices = new Float32Array(_vertices.length * 3);\n var colours = new Float32Array(_vertices.length * 3);\n\n var lastIndex = 0;\n\n for (var i = 0; i < _vertices.length; i++) {\n var ax = _vertices[i][0];\n var ay = _vertices[i][1];\n var az = _vertices[i][2];\n\n var c1 = _colour;\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n lastIndex++;\n }\n\n var attributes = {\n positions: vertices,\n colors: colours\n };\n\n return attributes;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n static SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n var geometry = new THREE.BufferGeometry();\n\n for (var key in attributes) {\n geometry.addAttribute(key.slice(0, -1), new THREE.BufferAttribute(attributes[key], attributeLengths[key]));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (options.polygonMaterial && options.polygonMaterial instanceof THREE.Material) {\n material = options.polygonMaterial;\n } else if (!skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors,\n side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof options.onPolygonMesh === 'function') {\n mesh = options.onPolygonMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n }\n\n if (flat) {\n material.depthWrite = false;\n\n var renderOrder = (style.renderOrder !== undefined) ? style.renderOrder : 3;\n mesh.renderOrder = renderOrder;\n }\n\n if (options.interactive) {\n material = new PickingMaterial();\n material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n }\n\n return Promise.resolve({\n mesh: mesh,\n pickingMesh: pickingMesh\n });\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates[0][0][0];\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var point;\n return this._coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(latlon => {\n point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * point.x;\n this._offset.y = -1 * point.y;\n\n this._options.pointScale = this._world.pointScale(latlon);\n }\n\n return point;\n });\n });\n });\n }\n\n // Convert coordinates array to something earcut can understand\n static ToEarcut(coordinates) {\n var dim = 2;\n var result = {vertices: [], holes: [], dimensions: dim};\n var holeIndex = 0;\n\n for (var i = 0; i < coordinates.length; i++) {\n for (var j = 0; j < coordinates[i].length; j++) {\n // for (var d = 0; d < dim; d++) {\n result.vertices.push(coordinates[i][j].x);\n result.vertices.push(coordinates[i][j].y);\n // }\n }\n if (i > 0) {\n holeIndex += coordinates[i - 1].length;\n result.holes.push(holeIndex);\n }\n }\n\n return result;\n }\n\n // Triangulate earcut-based input using earcut\n static Triangulate(contour, holes, dim) {\n // console.time('earcut');\n\n var faces = earcut(contour, holes, dim);\n var result = [];\n\n for (i = 0, il = faces.length; i < il; i += 3) {\n result.push(faces.slice(i, i + 3));\n }\n\n // console.timeEnd('earcut');\n\n return result;\n }\n\n // Transform polygon representation into attribute arrays that can be used by\n // THREE.BufferGeometry\n //\n // TODO: Can this be simplified? It's messy and huge\n static ToAttributes(polygon) {\n // Three components per vertex per face (3 x 3 = 9)\n var positions = new Float32Array(polygon.facesCount * 9);\n var normals = new Float32Array(polygon.facesCount * 9);\n var colours = new Float32Array(polygon.facesCount * 9);\n\n // One component per vertex per face (1 x 3 = 3)\n var tops = new Float32Array(polygon.facesCount * 3);\n\n var pickingIds;\n if (polygon.pickingId) {\n // One component per vertex per face (1 x 3 = 3)\n pickingIds = new Float32Array(polygon.facesCount * 3);\n }\n\n var pA = new THREE.Vector3();\n var pB = new THREE.Vector3();\n var pC = new THREE.Vector3();\n\n var cb = new THREE.Vector3();\n var ab = new THREE.Vector3();\n\n var index;\n\n var _faces = polygon.faces;\n var _vertices = polygon.vertices;\n var _colour = polygon.colours;\n var _tops = polygon.tops;\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = polygon.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _faces.length; i++) {\n // Array of vertex indexes for the face\n index = _faces[i][0];\n\n var ax = _vertices[index][0];\n var ay = _vertices[index][1];\n var az = _vertices[index][2];\n\n var c1 = _colour[i][0];\n var t1 = _tops[i][0];\n\n index = _faces[i][1];\n\n var bx = _vertices[index][0];\n var by = _vertices[index][1];\n var bz = _vertices[index][2];\n\n var c2 = _colour[i][1];\n var t2 = _tops[i][1];\n\n index = _faces[i][2];\n\n var cx = _vertices[index][0];\n var cy = _vertices[index][1];\n var cz = _vertices[index][2];\n\n var c3 = _colour[i][2];\n var t3 = _tops[i][2];\n\n // Flat face normals\n // From: http://threejs.org/examples/webgl_buffergeometry.html\n pA.set(ax, ay, az);\n pB.set(bx, by, bz);\n pC.set(cx, cy, cz);\n\n cb.subVectors(pC, pB);\n ab.subVectors(pA, pB);\n cb.cross(ab);\n\n cb.normalize();\n\n var nx = cb.x;\n var ny = cb.y;\n var nz = cb.z;\n\n positions[lastIndex * 9 + 0] = ax;\n positions[lastIndex * 9 + 1] = ay;\n positions[lastIndex * 9 + 2] = az;\n\n normals[lastIndex * 9 + 0] = nx;\n normals[lastIndex * 9 + 1] = ny;\n normals[lastIndex * 9 + 2] = nz;\n\n colours[lastIndex * 9 + 0] = c1[0];\n colours[lastIndex * 9 + 1] = c1[1];\n colours[lastIndex * 9 + 2] = c1[2];\n\n positions[lastIndex * 9 + 3] = bx;\n positions[lastIndex * 9 + 4] = by;\n positions[lastIndex * 9 + 5] = bz;\n\n normals[lastIndex * 9 + 3] = nx;\n normals[lastIndex * 9 + 4] = ny;\n normals[lastIndex * 9 + 5] = nz;\n\n colours[lastIndex * 9 + 3] = c2[0];\n colours[lastIndex * 9 + 4] = c2[1];\n colours[lastIndex * 9 + 5] = c2[2];\n\n positions[lastIndex * 9 + 6] = cx;\n positions[lastIndex * 9 + 7] = cy;\n positions[lastIndex * 9 + 8] = cz;\n\n normals[lastIndex * 9 + 6] = nx;\n normals[lastIndex * 9 + 7] = ny;\n normals[lastIndex * 9 + 8] = nz;\n\n colours[lastIndex * 9 + 6] = c3[0];\n colours[lastIndex * 9 + 7] = c3[1];\n colours[lastIndex * 9 + 8] = c3[2];\n\n tops[lastIndex * 3 + 0] = t1;\n tops[lastIndex * 3 + 1] = t2;\n tops[lastIndex * 3 + 2] = t3;\n\n if (pickingIds) {\n pickingIds[lastIndex * 3 + 0] = _pickingId;\n pickingIds[lastIndex * 3 + 1] = _pickingId;\n pickingIds[lastIndex * 3 + 2] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n positions: positions,\n normals: normals,\n colors: colours,\n tops: tops\n };\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the polygon is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiPolygon GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0][0][0]);\n }\n\n // TODO: Make sure this is cleaning everything\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PolygonLayer;\n\nvar noNew = function(coordinates, options) {\n return new PolygonLayer(coordinates, options);\n};\n\nexport {noNew as polygonLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PolygonLayer.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Provide alternative output using tubes and splines / curves\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\n// TODO: Allow _setBufferAttributes to use a custom function passed in to\n// generate a custom mesh\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Geo from '../../geo/Geo';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\n\nclass PolylineLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n polylineMaterial: null,\n onPolylineMesh: null,\n onBufferAttributes: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n lineOpacity: 1,\n lineTransparent: false,\n lineColor: '#ffffff',\n lineWidth: 1,\n lineBlending: THREE.NormalBlending\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of lines so it's easy to support\n // MultiLineString features (a single line would be a MultiLineString with a\n // single line in the array)\n this._coordinates = (PolylineLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n // Polyline features are always flat (for now at least)\n this._flat = true;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n PolylineLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {\n this._bufferAttributes = Buffer.mergeAttributes(result.attributes);\n this._flat = result.flat;\n\n var attributeLengths = {\n positions: 3,\n colors: 3\n };\n\n if (this._options.interactive) {\n attributeLengths.pickingIds = 1;\n }\n\n if (this.isOutput()) {\n var style = this._options.style;\n\n // Set mesh if not merging elsewhere\n PolylineLayer.SetMesh(this._bufferAttributes, attributeLengths, this._flat, style, this._options).then((result) => {\n // Output mesh\n this.add(result.mesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n result.attributes = null;\n result = null;\n\n resolve(this);\n });\n });\n }\n\n // Return center of polyline as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n //\n // TODO: Find proper center position instead of returning first coordinate\n // SEE: https://github.com/Leaflet/Leaflet/blob/master/src/layer/vector/Polyline.js#L59\n getCenter() {\n return this._center;\n }\n\n // Return line bounds in geographic coordinates\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n static SetBufferAttributes(coordinates, options) {\n return new Promise((resolve) => {\n var height = 0;\n\n // Convert height into world units\n if (options.style.lineHeight) {\n height = Geo.metresToWorld(options.style.lineHeight, options.pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(options.style.lineColor);\n\n var flat = true;\n\n // For each line\n var attributes = coordinates.map(_projectedCoordinates => {\n var _vertices = [];\n var _colours = [];\n\n // Connect coordinate with the next to make a pair\n //\n // LineSegments requires pairs of vertices so repeat the last point if\n // there's an odd number of vertices\n var nextCoord;\n _projectedCoordinates.forEach((coordinate, index) => {\n _colours.push([colour.r, colour.g, colour.b]);\n _vertices.push([coordinate.x, height, coordinate.y]);\n\n nextCoord = (_projectedCoordinates[index + 1]) ? _projectedCoordinates[index + 1] : coordinate;\n\n _colours.push([colour.r, colour.g, colour.b]);\n _vertices.push([nextCoord.x, height, nextCoord.y]);\n });\n\n var line = {\n vertices: _vertices,\n colours: _colours,\n verticesCount: _vertices.length\n };\n\n if (options.interactive && options.pickingId) {\n // Inject picking ID\n line.pickingId = options.pickingId;\n }\n\n // Convert line representation to proper attribute arrays\n return PolylineLayer.ToAttributes(line);\n });\n\n resolve({\n attributes: attributes,\n flat: flat\n });\n });\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n static SetMesh(attributes, attributeLengths, flat, style, options) {\n var geometry = new THREE.BufferGeometry();\n\n for (var key in attributes) {\n geometry.addAttribute(key.slice(0, -1), new THREE.BufferAttribute(attributes[key], attributeLengths[key]));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (options.polylineMaterial && options.polylineMaterial instanceof THREE.Material) {\n material = options.polylineMaterial;\n } else {\n material = new THREE.LineBasicMaterial({\n vertexColors: THREE.VertexColors,\n linewidth: style.lineWidth,\n transparent: style.lineTransparent,\n opacity: style.lineOpacity,\n blending: style.lineBlending\n });\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof options.onPolylineMesh === 'function') {\n mesh = options.onPolylineMesh(geometry, material);\n } else {\n mesh = new THREE.LineSegments(geometry, material);\n\n if (style.lineRenderOrder !== undefined) {\n material.depthWrite = false;\n mesh.renderOrder = style.lineRenderOrder;\n }\n\n mesh.castShadow = true;\n // mesh.receiveShadow = true;\n }\n\n if (options.interactive) {\n material = new PickingMaterial();\n // material.side = THREE.BackSide;\n\n // Make the line wider / easier to pick\n material.linewidth = style.lineWidth + material.linePadding;\n\n var pickingMesh = new THREE.LineSegments(geometry, material);\n }\n\n return Promise.resolve({\n mesh: mesh,\n pickingMesh: pickingMesh\n });\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates[0][0];\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(_coordinates => {\n return _coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var point;\n return this._coordinates.map(_coordinates => {\n return _coordinates.map(latlon => {\n point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * point.x;\n this._offset.y = -1 * point.y;\n\n this._options.pointScale = this._world.pointScale(latlon);\n }\n\n return point;\n });\n });\n }\n\n static ToAttributes(line) {\n // Three components per vertex\n var vertices = new Float32Array(line.verticesCount * 3);\n var colours = new Float32Array(line.verticesCount * 3);\n\n var pickingIds;\n if (line.pickingId) {\n // One component per vertex\n pickingIds = new Float32Array(line.verticesCount);\n }\n\n var _vertices = line.vertices;\n var _colour = line.colours;\n\n var _pickingId;\n if (pickingIds) {\n _pickingId = line.pickingId;\n }\n\n var lastIndex = 0;\n\n for (var i = 0; i < _vertices.length; i++) {\n var ax = _vertices[i][0];\n var ay = _vertices[i][1];\n var az = _vertices[i][2];\n\n var c1 = _colour[i];\n\n vertices[lastIndex * 3 + 0] = ax;\n vertices[lastIndex * 3 + 1] = ay;\n vertices[lastIndex * 3 + 2] = az;\n\n colours[lastIndex * 3 + 0] = c1[0];\n colours[lastIndex * 3 + 1] = c1[1];\n colours[lastIndex * 3 + 2] = c1[2];\n\n if (pickingIds) {\n pickingIds[lastIndex] = _pickingId;\n }\n\n lastIndex++;\n }\n\n var attributes = {\n positions: vertices,\n colors: colours\n };\n\n if (pickingIds) {\n attributes.pickingIds = pickingIds;\n }\n\n return attributes;\n }\n\n // Returns true if the line is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiLineString GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0][0]);\n }\n\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PolylineLayer;\n\nvar noNew = function(coordinates, options) {\n return new PolylineLayer(coordinates, options);\n};\n\nexport {noNew as polylineLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PolylineLayer.js\n **/","// TODO: Move duplicated logic between geometry layrs into GeometryLayer\n\n// TODO: Look at ways to drop unneeded references to array buffers, etc to\n// reduce memory footprint\n\n// TODO: Point features may be using custom models / meshes and so an approach\n// needs to be found to allow these to be brokwn down into buffer attributes for\n// merging\n//\n// Can probably use fromGeometry() or setFromObject() from THREE.BufferGeometry\n// and pull out the attributes\n\n// TODO: Support sprite objects using textures\n\n// TODO: Provide option to billboard geometry so it always faces the camera\n\n// TODO: Support dynamic updating / hiding / animation of geometry\n//\n// This could be pretty hard as it's all packed away within BufferGeometry and\n// may even be merged by another layer (eg. GeoJSONLayer)\n//\n// How much control should this layer support? Perhaps a different or custom\n// layer would be better suited for animation, for example.\n\nimport Layer from '../Layer';\nimport extend from 'lodash.assign';\nimport THREE from 'three';\nimport Geo from '../../geo/Geo';\nimport {latLon as LatLon} from '../../geo/LatLon';\nimport {point as Point} from '../../geo/Point';\nimport PickingMaterial from '../../engine/PickingMaterial';\nimport Buffer from '../../util/Buffer';\nimport PolygonLayer from './PolygonLayer';\n\nclass PointLayer extends Layer {\n constructor(coordinates, options) {\n var defaults = {\n output: true,\n interactive: false,\n // THREE.Geometry or THREE.BufferGeometry to use for point output\n pointGeometry: null,\n // Custom material override\n //\n // TODO: Should this be in the style object?\n pointMaterial: null,\n onPointMesh: null,\n // This default style is separate to Util.GeoJSON.defaultStyle\n style: {\n pointColor: '#ff0000'\n }\n };\n\n var _options = extend({}, defaults, options);\n\n super(_options);\n\n // Return coordinates as array of points so it's easy to support\n // MultiPoint features (a single point would be a MultiPoint with a\n // single point in the array)\n this._coordinates = (PointLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n this._flat = false;\n }\n\n _onAdd(world) {\n return new Promise((resolve, reject) => {\n this._setCoordinates();\n\n if (this._options.interactive) {\n // Only add to picking mesh if this layer is controlling output\n //\n // Otherwise, assume another component will eventually add a mesh to\n // the picking scene\n if (this.isOutput()) {\n this._pickingMesh = new THREE.Object3D();\n this.addToPicking(this._pickingMesh);\n }\n\n this._setPickingId();\n this._addPickingEvents();\n }\n\n // Store geometry representation as instances of THREE.BufferAttribute\n PointLayer.SetBufferAttributes(this._projectedCoordinates, this._options).then((result) => {\n this._bufferAttributes = Buffer.mergeAttributes(result.attributes);\n this._flat = result.flat;\n\n var attributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3\n };\n\n if (this._options.interactive) {\n attributeLengths.pickingIds = 1;\n }\n\n if (this.isOutput()) {\n var style = this._options.style;\n\n // Set mesh if not merging elsewhere\n // TODO: Dedupe with PolygonLayer as they are identical\n PointLayer.SetMesh(this._bufferAttributes, attributeLengths, this._flat, style, this._options, this._world._environment._skybox).then((result) => {\n // Output mesh\n this.add(result.mesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n });\n }\n\n result.attributes = null;\n result = null;\n\n resolve(this);\n }).catch(reject);\n });\n }\n\n // Return center of point as a LatLon\n //\n // This is used for things like placing popups / UI elements on the layer\n getCenter() {\n return this._center;\n }\n\n // Return point bounds in geographic coordinates\n //\n // While not useful for single points, it could be useful for MultiPoint\n //\n // TODO: Implement getBounds()\n getBounds() {}\n\n // Get unique ID for picking interaction\n _setPickingId() {\n this._pickingId = this.getPickingId();\n }\n\n // Set up and re-emit interaction events\n _addPickingEvents() {\n // TODO: Find a way to properly remove this listener on destroy\n this._world.on('pick-' + this._pickingId, (point2d, point3d, intersects) => {\n // Re-emit click event from the layer\n this.emit('click', this, point2d, point3d, intersects);\n });\n }\n\n static SetBufferAttributes(coordinates, options) {\n return new Promise((resolve) => {\n var height = 0;\n\n // Convert height into world units\n if (options.style.pointHeight) {\n height = Geo.metresToWorld(options.style.pointHeight, options.pointScale);\n }\n\n var colour = new THREE.Color();\n colour.set(options.style.pointColor);\n\n // Use default geometry if none has been provided or the provided geometry\n // isn't valid\n if (!options.pointGeometry || (!options.pointGeometry instanceof THREE.Geometry || !options.pointGeometry instanceof THREE.BufferGeometry)) {\n // Debug geometry for points is a thin bar\n //\n // TODO: Allow point geometry to be customised / overridden\n var geometryWidth = Geo.metresToWorld(25, options.pointScale);\n var geometryHeight = Geo.metresToWorld(200, options.pointScale);\n var _geometry = new THREE.BoxGeometry(geometryWidth, geometryHeight, geometryWidth);\n\n // Shift geometry up so it sits on the ground\n _geometry.translate(0, geometryHeight * 0.5, 0);\n\n // Pull attributes out of debug geometry\n geometry = new THREE.BufferGeometry().fromGeometry(_geometry);\n } else {\n if (options.geometry instanceof THREE.BufferGeometry) {\n geometry = options.pointGeometry;\n } else {\n geometry = new THREE.BufferGeometry().fromGeometry(options.pointGeometry);\n }\n }\n\n var attributes = coordinates.map((coordinate) => {\n var _vertices = [];\n var _normals = [];\n var _colours = [];\n\n var _geometry = geometry.clone();\n _geometry.translate(coordinate.x, height, coordinate.y);\n\n var _vertices = _geometry.attributes.position.clone().array;\n var _normals = _geometry.attributes.normal.clone().array;\n var _colours = _geometry.attributes.color.clone().array;\n\n for (var i = 0; i < _colours.length; i += 3) {\n _colours[i] = colour.r;\n _colours[i + 1] = colour.g;\n _colours[i + 2] = colour.b;\n }\n\n var _point = {\n positions: _vertices,\n normals: _normals,\n colors: _colours\n };\n\n if (options.interactive && options.pickingId) {\n // Inject picking ID\n _point.pickingId = options.pickingId;\n }\n\n return _point;\n });\n\n resolve({\n attributes: attributes,\n flat: false\n });\n });\n }\n\n getBufferAttributes() {\n return this._bufferAttributes;\n }\n\n // Used by external components to clear some memory when the attributes\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the attributes here after merging them\n // using something like the GeoJSONLayer\n clearBufferAttributes() {\n this._bufferAttributes = null;\n }\n\n // Used by external components to clear some memory when the coordinates\n // are no longer required to be stored in this layer\n //\n // For example, you would want to clear the coordinates here after this\n // layer is merged in something like the GeoJSONLayer\n clearCoordinates() {\n this._coordinates = null;\n this._projectedCoordinates = null;\n }\n\n static SetMesh(attributes, attributeLengths, flat, style, options, skybox) {\n var geometry = new THREE.BufferGeometry();\n\n for (var key in attributes) {\n geometry.addAttribute(key.slice(0, -1), new THREE.BufferAttribute(attributes[key], attributeLengths[key]));\n }\n\n geometry.computeBoundingBox();\n\n var material;\n if (options.pointMaterial && options.pointMaterial instanceof THREE.Material) {\n material = options.pointMaterial;\n } else if (!skybox) {\n material = new THREE.MeshPhongMaterial({\n vertexColors: THREE.VertexColors,\n // side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n } else {\n material = new THREE.MeshStandardMaterial({\n vertexColors: THREE.VertexColors,\n // side: THREE.BackSide,\n transparent: style.transparent,\n opacity: style.opacity,\n blending: style.blending\n });\n material.roughness = 1;\n material.metalness = 0.1;\n material.envMapIntensity = 3;\n material.envMap = skybox.getRenderTarget();\n }\n\n var mesh;\n\n // Pass mesh through callback, if defined\n if (typeof options.onPolygonMesh === 'function') {\n mesh = options.onPolygonMesh(geometry, material);\n } else {\n mesh = new THREE.Mesh(geometry, material);\n\n mesh.castShadow = true;\n mesh.receiveShadow = true;\n }\n\n if (flat) {\n material.depthWrite = false;\n mesh.renderOrder = 4;\n }\n\n if (options.interactive) {\n material = new PickingMaterial();\n material.side = THREE.BackSide;\n\n var pickingMesh = new THREE.Mesh(geometry, material);\n }\n\n return Promise.resolve({\n mesh: mesh,\n pickingMesh: pickingMesh\n });\n }\n\n // Convert and project coordinates\n //\n // TODO: Calculate bounds\n _setCoordinates() {\n this._bounds = [];\n this._coordinates = this._convertCoordinates(this._coordinates);\n\n this._projectedBounds = [];\n this._projectedCoordinates = this._projectCoordinates();\n\n this._center = this._coordinates;\n }\n\n // Recursively convert input coordinates into LatLon objects\n //\n // Calculate geographic bounds at the same time\n //\n // TODO: Calculate geographic bounds\n _convertCoordinates(coordinates) {\n return coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n }\n\n // Recursively project coordinates into world positions\n //\n // Calculate world bounds, offset and pointScale at the same time\n //\n // TODO: Calculate world bounds\n _projectCoordinates() {\n var _point;\n return this._coordinates.map(latlon => {\n _point = this._world.latLonToPoint(latlon);\n\n // TODO: Is offset ever being used or needed?\n if (!this._offset) {\n this._offset = Point(0, 0);\n this._offset.x = -1 * _point.x;\n this._offset.y = -1 * _point.y;\n\n this._options.pointScale = this._world.pointScale(latlon);\n }\n\n return _point;\n });\n }\n\n // Returns true if the line is flat (has no height)\n isFlat() {\n return this._flat;\n }\n\n // Returns true if coordinates refer to a single geometry\n //\n // For example, not coordinates for a MultiPoint GeoJSON feature\n static isSingle(coordinates) {\n return !Array.isArray(coordinates[0]);\n }\n\n destroy() {\n if (this._pickingMesh) {\n // TODO: Properly dispose of picking mesh\n this._pickingMesh = null;\n }\n\n this.clearCoordinates();\n this.clearBufferAttributes();\n\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default PointLayer;\n\nvar noNew = function(coordinates, options) {\n return new PointLayer(coordinates, options);\n};\n\nexport {noNew as pointLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/geometry/PointLayer.js\n **/","import Layer from './Layer';\nimport extend from 'lodash.assign';\nimport reqwest from 'reqwest';\nimport GeoJSON from '../util/GeoJSON';\nimport Worker from '../util/Worker';\nimport Buffer from '../util/Buffer';\nimport Stringify from '../util/Stringify';\nimport PolygonLayer from './geometry/PolygonLayer';\nimport PolylineLayer from './geometry/PolylineLayer';\nimport PointLayer from './geometry/PointLayer';\nimport {latLon as LatLon} from '../geo/LatLon';\nimport {point as Point} from '../geo/Point';\nimport Geo from '../geo/Geo';\nimport PickingMaterial from '../engine/PickingMaterial';\n\n// TODO: Allow filter method to be run inside a worker to improve performance\n// TODO: Allow onEachFeature method to be run inside a worker to improve performance\n\nclass GeoJSONWorkerLayer extends Layer {\n constructor(geojson, options) {\n var defaults = {\n topojson: false,\n style: GeoJSON.defaultStyle,\n onEachFeature: null,\n onEachFeatureWorker: null,\n onAddAttributes: null,\n interactive: false,\n pointGeometry: null,\n onClick: null,\n headers: {}\n };\n\n var _options = extend({}, defaults, options);\n\n if (typeof options.style === 'object') {\n _options.style = extend({}, defaults.style, options.style);\n }\n\n super(_options);\n\n this._aborted = false;\n this._geojson = geojson;\n }\n\n _onAdd(world) {\n if (this._options.interactive) {\n // Worker layer always controls output to add a picking mesh\n this._pickingMesh = new THREE.Object3D();\n }\n\n // Process GeoJSON\n return this._process(this._geojson);\n }\n\n // Use workers to request and process GeoJSON, returning data structure\n // containing geometry and any supplementary data for output\n _process(_geojson) {\n return new Promise((resolve, reject) => {\n var style = this._options.style;\n\n // TODO: Convert to buffer and use transferrable objects\n if (typeof this._options.style === 'function') {\n style = Stringify.functionToString(this._options.style);\n }\n\n var pointGeometry = this._options.pointGeometry;\n\n // TODO: Convert to buffer and use transferrable objects\n if (typeof this._options.pointGeometry === 'function') {\n pointGeometry = Stringify.functionToString(this._options.pointGeometry);\n }\n\n var geojson = _geojson;\n var transferrables = [];\n\n if (typeof geojson !== 'string') {\n this._geojson = geojson = Buffer.stringToUint8Array(JSON.stringify(geojson));\n transferrables.push(geojson.buffer);\n this._execWorker(geojson, this._options.topojson, this._world._originPoint, style, this._options.interactive, pointGeometry, transferrables).then(() => {\n resolve();\n }).catch(reject);\n } else if (typeof this._options.filter === 'function' || typeof this._options.onEachFeature === 'function') {\n GeoJSONWorkerLayer.RequestGeoJSON(geojson).then((res) => {\n // if (this._aborted) {\n // resolve();\n // return;\n // }\n\n var fc = GeoJSON.collectFeatures(res, this._options.topojson);\n var features = fc.features;\n\n // Run filter, if provided\n if (this._options.filter) {\n fc.features = features.filter(this._options.filter);\n }\n\n if (this._options.onEachFeature) {\n var feature;\n for (var i = 0; i < features.length; i++) {\n feature = features[i];\n this._options.onEachFeature(feature);\n };\n }\n\n this._geojson = geojson = Buffer.stringToUint8Array(JSON.stringify(fc));\n transferrables.push(geojson.buffer);\n\n this._execWorker(geojson, false, this._options.headers, this._world._originPoint, style, this._options.interactive, pointGeometry, transferrables).then(() => {\n resolve();\n }).catch(reject);\n });\n } else {\n this._execWorker(geojson, this._options.topojson, this._options.headers, this._world._originPoint, style, this._options.interactive, pointGeometry, transferrables).then(() => {\n resolve();\n }).catch(reject);\n }\n });\n }\n\n _execWorker(geojson, topojson, headers, originPoint, style, interactive, pointGeometry, transferrables) {\n return new Promise((resolve, reject) => {\n console.time('Worker round trip');\n\n Worker.exec('GeoJSONWorkerLayer.Process', [geojson, topojson, headers, originPoint, style, interactive, pointGeometry], transferrables).then((results) => {\n console.timeEnd('Worker round trip');\n\n // if (this._aborted) {\n // resolve();\n // return;\n // }\n\n var processPromises = [];\n\n if (results.polygons) {\n processPromises.push(this._processPolygonResults(results.polygons));\n }\n\n if (results.polylines) {\n processPromises.push(this._processPolylineResults(results.polylines));\n }\n\n if (results.points) {\n processPromises.push(this._processPointResults(results.points));\n }\n\n if (processPromises.length > 0) {\n Promise.all(processPromises).then(() => {\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n });\n });\n }\n\n // TODO: Dedupe with polyline method\n _processPolygonResults(results) {\n return new Promise((resolve, reject) => {\n var splitPositions = Buffer.splitFloat32Array(results.attributes.positions);\n var splitNormals = Buffer.splitFloat32Array(results.attributes.normals);\n var splitColors = Buffer.splitFloat32Array(results.attributes.colors);\n var splitTops = Buffer.splitFloat32Array(results.attributes.tops);\n\n var splitOutlinePositions;\n var splitOutlineColors;\n\n if (results.outlineAttributes) {\n splitOutlinePositions = Buffer.splitFloat32Array(results.outlineAttributes.positions);\n splitOutlineColors = Buffer.splitFloat32Array(results.outlineAttributes.colors);\n }\n\n var splitProperties;\n if (results.properties) {\n splitProperties = Buffer.splitUint8Array(results.properties);\n }\n\n var flats = results.flats;\n\n var objects = [];\n var outlineObjects = [];\n\n var obj;\n var pickingId;\n var pickingIds;\n var properties;\n\n var polygonAttributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3,\n tops: 1\n };\n\n var polygonOutlineAttributeLengths = {\n positions: 3,\n colors: 3\n };\n\n for (var i = 0; i < splitPositions.length; i++) {\n if (splitProperties && splitProperties[i]) {\n properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));\n } else {\n properties = {};\n }\n\n // WORKERS: obj.attributes should actually an array of polygons for\n // the feature, though the current logic isn't aware of that\n obj = {\n attributes: [{\n positions: splitPositions[i],\n normals: splitNormals[i],\n colors: splitColors[i],\n tops: splitTops[i]\n }],\n properties: properties,\n flat: flats[i]\n };\n\n // WORKERS: If interactive, generate unique ID for each feature, create\n // the buffer attributes and set up event listeners\n if (this._options.interactive) {\n pickingId = this.getPickingId();\n\n pickingIds = new Float32Array(splitPositions[i].length / 3);\n pickingIds.fill(pickingId);\n\n obj.attributes[0].pickingIds = pickingIds;\n\n polygonAttributeLengths.pickingIds = 1;\n\n this._addPicking(pickingId, properties);\n }\n\n // TODO: Make this specific to polygon attributes\n if (typeof this._options.onAddAttributes === 'function') {\n var customAttributes = this._options.onAddAttributes(obj.attributes[0], properties);\n var customAttribute;\n for (var key in customAttributes) {\n customAttribute = customAttributes[key];\n obj.attributes[0][key] = customAttribute.value;\n polygonAttributeLengths[key] = customAttribute.length;\n }\n }\n\n objects.push(obj);\n }\n\n for (var i = 0; i < splitOutlinePositions.length; i++) {\n obj = {\n attributes: [{\n positions: splitOutlinePositions[i],\n colors: splitOutlineColors[i]\n }],\n flat: true\n };\n\n outlineObjects.push(obj);\n }\n\n var polygonAttributes = [];\n var polygonOutlineAttributes = [];\n\n var polygonFlat = true;\n\n for (var i = 0; i < objects.length; i++) {\n obj = objects[i];\n\n // TODO: Work out why obj.flat is rarely set to something other than\n // true or false. Potentially undefined.\n if (polygonFlat && obj.flat === false) {\n polygonFlat = false;\n }\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n polygonAttributes.push(bufferAttributes);\n };\n\n for (var i = 0; i < outlineObjects.length; i++) {\n obj = outlineObjects[i];\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n polygonOutlineAttributes.push(bufferAttributes);\n };\n\n var outputPromises = [];\n\n var style;\n\n if (polygonAttributes.length > 0) {\n var mergedPolygonAttributes = Buffer.mergeAttributes(polygonAttributes);\n\n // TODO: Make this work when style is a function per feature\n style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n outputPromises.push(this._setPolygonMesh(mergedPolygonAttributes, polygonAttributeLengths, style, polygonFlat));\n }\n\n if (polygonOutlineAttributes.length > 0) {\n var mergedPolygonOutlineAttributes = Buffer.mergeAttributes(polygonOutlineAttributes);\n\n style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n if (style.outlineRenderOrder !== undefined) {\n style.lineRenderOrder = style.outlineRenderOrder;\n } else {\n style.lineRenderOrder = (style.renderOrder) ? style.renderOrder + 1 : 4;\n }\n\n if (style.outlineWidth) {\n style.lineWidth = style.outlineWidth;\n }\n\n outputPromises.push(this._setPolylineMesh(mergedPolygonOutlineAttributes, polygonOutlineAttributeLengths, style, true));\n }\n\n Promise.all(outputPromises).then((results) => {\n var [polygonResult, outlineResult] = results;\n\n if (polygonResult) {\n this._polygonMesh = polygonResult.mesh;\n this.add(this._polygonMesh);\n\n if (polygonResult.pickingMesh) {\n this._pickingMesh.add(polygonResult.pickingMesh);\n }\n }\n\n if (outlineResult) {\n this.add(outlineResult.mesh);\n }\n\n resolve();\n }).catch(reject);\n });\n }\n\n // TODO: Dedupe with polygon method\n _processPolylineResults(results) {\n return new Promise((resolve, reject) => {\n var splitPositions = Buffer.splitFloat32Array(results.attributes.positions);\n var splitColors = Buffer.splitFloat32Array(results.attributes.colors);\n\n var splitProperties;\n if (results.properties) {\n splitProperties = Buffer.splitUint8Array(results.properties);\n }\n\n var flats = results.flats;\n\n var objects = [];\n var obj;\n var pickingId;\n var pickingIds;\n var properties;\n\n var polylineAttributeLengths = {\n positions: 3,\n colors: 3\n };\n\n for (var i = 0; i < splitPositions.length; i++) {\n if (splitProperties && splitProperties[i]) {\n properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));\n } else {\n properties = {};\n }\n\n // WORKERS: obj.attributes should actually an array of polygons for\n // the feature, though the current logic isn't aware of that\n obj = {\n attributes: [{\n positions: splitPositions[i],\n colors: splitColors[i]\n }],\n properties: properties,\n flat: flats[i]\n };\n\n // WORKERS: If interactive, generate unique ID for each feature, create\n // the buffer attributes and set up event listeners\n if (this._options.interactive) {\n pickingId = this.getPickingId();\n\n pickingIds = new Float32Array(splitPositions[i].length / 3);\n pickingIds.fill(pickingId);\n\n obj.attributes[0].pickingIds = pickingIds;\n\n polylineAttributeLengths.pickingIds = 1;\n\n this._addPicking(pickingId, properties);\n }\n\n // TODO: Make this specific to polyline attributes\n if (typeof this._options.onAddAttributes === 'function') {\n var customAttributes = this._options.onAddAttributes(obj.attributes[0], properties);\n var customAttribute;\n for (var key in customAttributes) {\n customAttribute = customAttributes[key];\n obj.attributes[0][key] = customAttribute.value;\n polylineAttributeLengths[key] = customAttribute.length;\n }\n }\n\n objects.push(obj);\n }\n\n var polylineAttributes = [];\n\n var polylineFlat = true;\n\n for (var i = 0; i < objects.length; i++) {\n obj = objects[i];\n\n if (polylineFlat && !obj.flat) {\n polylineFlat = false;\n }\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n polylineAttributes.push(bufferAttributes);\n };\n\n if (polylineAttributes.length > 0) {\n var mergedPolylineAttributes = Buffer.mergeAttributes(polylineAttributes);\n\n // TODO: Make this work when style is a function per feature\n var style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPolylineMesh(mergedPolylineAttributes, polylineAttributeLengths, style, polylineFlat).then((result) => {\n this._polylineMesh = result.mesh;\n this.add(this._polylineMesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n });\n }\n\n _processPointResults(results) {\n return new Promise((resolve, reject) => {\n var splitPositions = Buffer.splitFloat32Array(results.attributes.positions);\n var splitNormals = Buffer.splitFloat32Array(results.attributes.normals);\n var splitColors = Buffer.splitFloat32Array(results.attributes.colors);\n\n var splitProperties;\n if (results.properties) {\n splitProperties = Buffer.splitUint8Array(results.properties);\n }\n\n var flats = results.flats;\n\n var objects = [];\n var obj;\n var pickingId;\n var pickingIds;\n var properties;\n\n var pointAttributeLengths = {\n positions: 3,\n normals: 3,\n colors: 3\n };\n\n for (var i = 0; i < splitPositions.length; i++) {\n if (splitProperties && splitProperties[i]) {\n properties = JSON.parse(Buffer.uint8ArrayToString(splitProperties[i]));\n } else {\n properties = {};\n }\n\n // WORKERS: obj.attributes should actually an array of polygons for\n // the feature, though the current logic isn't aware of that\n obj = {\n attributes: [{\n positions: splitPositions[i],\n normals: splitNormals[i],\n colors: splitColors[i]\n }],\n properties: properties,\n flat: flats[i]\n };\n\n // WORKERS: If interactive, generate unique ID for each feature, create\n // the buffer attributes and set up event listeners\n if (this._options.interactive) {\n pickingId = this.getPickingId();\n\n pickingIds = new Float32Array(splitPositions[i].length / 3);\n pickingIds.fill(pickingId);\n\n obj.attributes[0].pickingIds = pickingIds;\n\n pointAttributeLengths.pickingIds = 1;\n\n this._addPicking(pickingId, properties);\n }\n\n // TODO: Make this specific to polygon attributes\n if (typeof this._options.onAddAttributes === 'function') {\n var customAttributes = this._options.onAddAttributes(obj.attributes[0], properties);\n var customAttribute;\n for (var key in customAttributes) {\n customAttribute = customAttributes[key];\n obj.attributes[0][key] = customAttribute.value;\n pointAttributeLengths[key] = customAttribute.length;\n }\n }\n\n objects.push(obj);\n }\n\n var pointAttributes = [];\n\n var pointFlat = true;\n\n for (var i = 0; i < objects.length; i++) {\n obj = objects[i];\n\n if (pointFlat && !obj.flat) {\n pointFlat = false;\n }\n\n var bufferAttributes = Buffer.mergeAttributes(obj.attributes);\n pointAttributes.push(bufferAttributes);\n };\n\n if (pointAttributes.length > 0) {\n var mergedPointAttributes = Buffer.mergeAttributes(pointAttributes);\n\n // TODO: Make this work when style is a function per feature\n var style = (typeof this._options.style === 'function') ? this._options.style(objects[0]) : this._options.style;\n style = extend({}, GeoJSON.defaultStyle, style);\n\n this._setPointMesh(mergedPointAttributes, pointAttributeLengths, style, pointFlat).then((result) => {\n this._pointMesh = result.mesh;\n this.add(this._pointMesh);\n\n if (result.pickingMesh) {\n this._pickingMesh.add(result.pickingMesh);\n }\n\n resolve();\n }).catch(reject);\n } else {\n resolve();\n }\n });\n }\n\n // TODO: At some point this needs to return all the features to the main thread\n // so it can generate meshes and output to the scene, as well as perhaps creating\n // individual layers / components for each feature to track things like picking\n // and properties\n //\n // TODO: Find a way so the origin point isn't needed to be passed in as it\n // feels a bit messy and against the idea of a static Geo class\n //\n // TODO: Support passing custom geometry for point layers\n static Process(geojson, topojson, headers, originPoint, _style, _properties, _pointGeometry) {\n return new Promise((resolve, reject) => {\n GeoJSONWorkerLayer.ProcessGeoJSON(geojson, headers).then((res) => {\n // Collects features into a single FeatureCollection\n //\n // Also converts TopoJSON to GeoJSON if instructed\n var geojson = GeoJSON.collectFeatures(res, topojson);\n\n // TODO: Check that GeoJSON is valid / usable\n\n var features = geojson.features;\n\n // TODO: Run filter, if provided (must be static)\n\n var pointScale;\n var polygons = [];\n var polylines = [];\n var points = [];\n\n // Deserialise style function if provided\n if (typeof _style === 'string') {\n _style = Stringify.stringToFunction(_style);\n }\n\n // Assume that a style won't be set per feature\n var style = _style;\n\n var pointGeometry;\n // Deserialise pointGeometry function if provided\n if (typeof _pointGeometry === 'string') {\n pointGeometry = Stringify.stringToFunction(_pointGeometry);\n }\n\n var feature;\n for (var i = 0; i < features.length; i++) {\n feature = features[i];\n\n var geometry = feature.geometry;\n var coordinates = (geometry.coordinates) ? geometry.coordinates : null;\n\n if (!coordinates || !geometry) {\n return;\n }\n\n // Get per-feature style object, if provided\n if (typeof _style === 'function') {\n style = extend({}, GeoJSON.defaultStyle, _style(feature));\n // console.log(feature, style);\n }\n\n if (geometry.type === 'Polygon' || geometry.type === 'MultiPolygon') {\n coordinates = (PolygonLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n var converted = coordinates.map(_coordinates => {\n return _coordinates.map(ring => {\n return ring.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n });\n\n var point;\n var projected = converted.map((_coordinates) => {\n return _coordinates.map((ring) => {\n return ring.map((latlon) => {\n point = Geo.latLonToPoint(latlon)._subtract(originPoint);\n\n if (!pointScale) {\n pointScale = Geo.pointScale(latlon);\n }\n\n return point;\n });\n });\n });\n\n var polygon = {\n projected: projected,\n options: {\n pointScale: pointScale,\n style: style\n }\n };\n\n if (_properties) {\n polygon.properties = feature.properties;\n }\n\n polygons.push(polygon);\n }\n\n if (geometry.type === 'LineString' || geometry.type === 'MultiLineString') {\n coordinates = (PolylineLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n var converted = coordinates.map(_coordinates => {\n return _coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n });\n\n var point;\n var projected = converted.map((_coordinates) => {\n return _coordinates.map((latlon) => {\n point = Geo.latLonToPoint(latlon)._subtract(originPoint);\n\n if (!pointScale) {\n pointScale = Geo.pointScale(latlon);\n }\n\n return point;\n });\n });\n\n var polyline = {\n projected: projected,\n options: {\n pointScale: pointScale,\n style: style\n }\n };\n\n if (_properties) {\n polyline.properties = feature.properties;\n }\n\n polylines.push(polyline);\n }\n\n if (geometry.type === 'Point' || geometry.type === 'MultiPoint') {\n coordinates = (PointLayer.isSingle(coordinates)) ? [coordinates] : coordinates;\n\n var converted = coordinates.map(coordinate => {\n return LatLon(coordinate[1], coordinate[0]);\n });\n\n var point;\n var projected = converted.map((latlon) => {\n point = Geo.latLonToPoint(latlon)._subtract(originPoint);\n\n if (!pointScale) {\n pointScale = Geo.pointScale(latlon);\n }\n\n return point;\n });\n\n var point = {\n projected: projected,\n options: {\n pointGeometry: pointGeometry(feature),\n pointScale: pointScale,\n style: style\n }\n };\n\n if (_properties) {\n point.properties = feature.properties;\n }\n\n points.push(point);\n }\n };\n\n var polygonBufferPromises = [];\n var polylineBufferPromises = [];\n var pointBufferPromises = [];\n\n var polygon;\n for (var i = 0; i < polygons.length; i++) {\n polygon = polygons[i];\n polygonBufferPromises.push(PolygonLayer.SetBufferAttributes(polygon.projected, polygon.options));\n };\n\n var polyline;\n for (var i = 0; i < polylines.length; i++) {\n polyline = polylines[i];\n polylineBufferPromises.push(PolylineLayer.SetBufferAttributes(polyline.projected, polyline.options));\n };\n\n var point;\n for (var i = 0; i < points.length; i++) {\n point = points[i];\n pointBufferPromises.push(PointLayer.SetBufferAttributes(point.projected, point.options));\n };\n\n var data = {};\n var transferrables = [];\n\n // TODO: Make this work with polylines too\n // TODO: Make this so it's not a nest of promises\n GeoJSONWorkerLayer.ProcessPolygons(polygonBufferPromises, polygons, _properties).then((result) => {\n data.polygons = result.data;\n transferrables = transferrables.concat(result.transferrables);\n\n GeoJSONWorkerLayer.ProcessPolylines(polylineBufferPromises, polylines, _properties).then((result) => {\n data.polylines = result.data;\n transferrables = transferrables.concat(result.transferrables);\n\n GeoJSONWorkerLayer.ProcessPoints(pointBufferPromises, points, _properties).then((result) => {\n data.points = result.data;\n transferrables = transferrables.concat(result.transferrables);\n\n resolve({\n data: data,\n transferrables: transferrables\n });\n });\n });\n });\n });\n });\n }\n\n static ProcessPolygons(polygonPromises, polygons, _properties) {\n return new Promise((resolve, reject) => {\n Promise.all(polygonPromises).then((results) => {\n var transferrables = [];\n\n var positions = [];\n var normals = [];\n var colors = [];\n var tops = [];\n\n var outlinePositions = [];\n var outlineColors = [];\n\n var properties = [];\n\n var flats = [];\n var polygon;\n\n var result;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n polygon = polygons[i];\n\n // WORKERS: Making this a typed array will speed up transfer time\n // As things stand this adds on a few milliseconds\n flats.push(result.flat);\n\n // WORKERS: result.attributes is actually an array of polygons for each\n // feature, though the current logic isn't keeping these all together\n\n var attributes;\n for (var j = 0; j < result.attributes.length; j++) {\n attributes = result.attributes[j];\n\n positions.push(attributes.positions);\n normals.push(attributes.normals);\n colors.push(attributes.colors);\n tops.push(attributes.tops);\n\n if (_properties) {\n properties.push(Buffer.stringToUint8Array(JSON.stringify(polygon.properties)));\n }\n };\n\n var outlineAttributes;\n for (var j = 0; j < result.outlineAttributes.length; j++) {\n outlineAttributes = result.outlineAttributes[j];\n\n outlinePositions.push(outlineAttributes.positions);\n outlineColors.push(outlineAttributes.colors);\n };\n };\n\n var mergedAttributes = {\n positions: Buffer.mergeFloat32Arrays(positions),\n normals: Buffer.mergeFloat32Arrays(normals),\n colors: Buffer.mergeFloat32Arrays(colors),\n tops: Buffer.mergeFloat32Arrays(tops)\n };\n\n var mergedOutlineAttributes = {\n positions: Buffer.mergeFloat32Arrays(outlinePositions),\n colors: Buffer.mergeFloat32Arrays(outlineColors)\n };\n\n transferrables.push(mergedAttributes.positions[0].buffer);\n transferrables.push(mergedAttributes.positions[1].buffer);\n\n transferrables.push(mergedAttributes.normals[0].buffer);\n transferrables.push(mergedAttributes.normals[1].buffer);\n\n transferrables.push(mergedAttributes.colors[0].buffer);\n transferrables.push(mergedAttributes.colors[1].buffer);\n\n transferrables.push(mergedAttributes.tops[0].buffer);\n transferrables.push(mergedAttributes.tops[1].buffer);\n\n transferrables.push(mergedOutlineAttributes.positions[0].buffer);\n transferrables.push(mergedOutlineAttributes.positions[1].buffer);\n\n transferrables.push(mergedOutlineAttributes.colors[0].buffer);\n transferrables.push(mergedOutlineAttributes.colors[1].buffer);\n\n var mergedProperties;\n if (_properties) {\n mergedProperties = Buffer.mergeUint8Arrays(properties);\n\n transferrables.push(mergedProperties[0].buffer);\n transferrables.push(mergedProperties[1].buffer);\n }\n\n var output = {\n attributes: mergedAttributes,\n outlineAttributes: mergedOutlineAttributes,\n flats: flats\n };\n\n if (_properties) {\n output.properties = mergedProperties;\n }\n\n // TODO: Also return GeoJSON features that can be mapped to objects on\n // the main thread. Allow user to provide filter / toggles to only return\n // properties from the GeoJSON that they need (eg. don't return geometry,\n // or don't return properties.height)\n resolve({\n data: output,\n transferrables: transferrables\n });\n }).catch(reject);\n });\n }\n\n static ProcessPolylines(polylinePromises, polylines, _properties) {\n return new Promise((resolve, reject) => {\n Promise.all(polylinePromises).then((results) => {\n var transferrables = [];\n\n var positions = [];\n var colors = [];\n\n var properties = [];\n\n var flats = [];\n var polyline;\n\n var result;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n polyline = polylines[i];\n\n // WORKERS: Making this a typed array will speed up transfer time\n // As things stand this adds on a few milliseconds\n flats.push(result.flat);\n\n // WORKERS: result.attributes is actually an array of polygons for each\n // feature, though the current logic isn't keeping these all together\n\n var attributes;\n for (var j = 0; j < result.attributes.length; j++) {\n attributes = result.attributes[j];\n\n positions.push(attributes.positions);\n colors.push(attributes.colors);\n\n if (_properties) {\n properties.push(Buffer.stringToUint8Array(JSON.stringify(polyline.properties)));\n }\n };\n };\n\n var mergedAttributes = {\n positions: Buffer.mergeFloat32Arrays(positions),\n colors: Buffer.mergeFloat32Arrays(colors)\n };\n\n transferrables.push(mergedAttributes.positions[0].buffer);\n transferrables.push(mergedAttributes.positions[1].buffer);\n\n transferrables.push(mergedAttributes.colors[0].buffer);\n transferrables.push(mergedAttributes.colors[1].buffer);\n\n var mergedProperties;\n if (_properties) {\n mergedProperties = Buffer.mergeUint8Arrays(properties);\n\n transferrables.push(mergedProperties[0].buffer);\n transferrables.push(mergedProperties[1].buffer);\n }\n\n var output = {\n attributes: mergedAttributes,\n flats: flats\n };\n\n if (_properties) {\n output.properties = mergedProperties;\n }\n\n // TODO: Also return GeoJSON features that can be mapped to objects on\n // the main thread. Allow user to provide filter / toggles to only return\n // properties from the GeoJSON that they need (eg. don't return geometry,\n // or don't return properties.height)\n resolve({\n data: output,\n transferrables: transferrables\n });\n }).catch(reject);\n });\n }\n\n // TODO: Dedupe with ProcessPolygons as they are identical\n static ProcessPoints(pointPromises, points, _properties) {\n return new Promise((resolve, reject) => {\n Promise.all(pointPromises).then((results) => {\n var transferrables = [];\n\n var positions = [];\n var normals = [];\n var colors = [];\n\n var properties = [];\n\n var flats = [];\n var point;\n\n var result;\n for (var i = 0; i < results.length; i++) {\n result = results[i];\n\n point = points[i];\n\n // WORKERS: Making this a typed array will speed up transfer time\n // As things stand this adds on a few milliseconds\n flats.push(result.flat);\n\n // WORKERS: result.attributes is actually an array of polygons for each\n // feature, though the current logic isn't keeping these all together\n\n var attributes;\n for (var j = 0; j < result.attributes.length; j++) {\n attributes = result.attributes[j];\n\n positions.push(attributes.positions);\n normals.push(attributes.normals);\n colors.push(attributes.colors);\n\n if (_properties) {\n properties.push(Buffer.stringToUint8Array(JSON.stringify(polygon.properties)));\n }\n };\n };\n\n var mergedAttributes = {\n positions: Buffer.mergeFloat32Arrays(positions),\n normals: Buffer.mergeFloat32Arrays(normals),\n colors: Buffer.mergeFloat32Arrays(colors)\n };\n\n transferrables.push(mergedAttributes.positions[0].buffer);\n transferrables.push(mergedAttributes.positions[1].buffer);\n\n transferrables.push(mergedAttributes.normals[0].buffer);\n transferrables.push(mergedAttributes.normals[1].buffer);\n\n transferrables.push(mergedAttributes.colors[0].buffer);\n transferrables.push(mergedAttributes.colors[1].buffer);\n\n var mergedProperties;\n if (_properties) {\n mergedProperties = Buffer.mergeUint8Arrays(properties);\n\n transferrables.push(mergedProperties[0].buffer);\n transferrables.push(mergedProperties[1].buffer);\n }\n\n var output = {\n attributes: mergedAttributes,\n flats: flats\n };\n\n if (_properties) {\n output.properties = mergedProperties;\n }\n\n // TODO: Also return GeoJSON features that can be mapped to objects on\n // the main thread. Allow user to provide filter / toggles to only return\n // properties from the GeoJSON that they need (eg. don't return geometry,\n // or don't return properties.height)\n resolve({\n data: output,\n transferrables: transferrables\n });\n }).catch(reject);\n });\n }\n\n static ProcessGeoJSON(geojson, headers) {\n if (typeof geojson === 'string') {\n return GeoJSONWorkerLayer.RequestGeoJSON(geojson, headers);\n } else {\n return Promise.resolve(JSON.parse(Buffer.uint8ArrayToString(geojson)));\n }\n }\n\n static RequestGeoJSON(path, headers) {\n return reqwest({\n url: path,\n type: 'json',\n crossOrigin: true,\n headers: headers\n });\n }\n\n // Create and store mesh from buffer attributes\n //\n // Could make this an abstract method for each geometry layer\n _setPolygonMesh(attributes, attributeLengths, style, flat) {\n if (!this._world) {\n return Promise.reject();\n }\n\n return PolygonLayer.SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n }\n\n _setPolylineMesh(attributes, attributeLengths, style, flat) {\n if (!this._world) {\n return Promise.reject();\n }\n\n return PolylineLayer.SetMesh(attributes, attributeLengths, flat, style, this._options);\n }\n\n _setPointMesh(attributes, attributeLengths, style, flat) {\n if (!this._world) {\n return Promise.reject();\n }\n\n return PointLayer.SetMesh(attributes, attributeLengths, flat, style, this._options, this._world._environment._skybox);\n }\n\n // Set up and re-emit interaction events\n _addPicking(pickingId, properties) {\n this._world.on('pick-click-' + pickingId, (pickingId, point2d, point3d, intersects) => {\n this._world.emit('click', this, properties, point2d, point3d);\n });\n\n this._world.on('pick-hover-' + pickingId, (pickingId, point2d, point3d, intersects) => {\n this._world.emit('hover', this, properties, point2d, point3d);\n });\n }\n\n // TODO: Finish cleanup\n destroy() {\n // Run common destruction logic from parent\n super.destroy();\n }\n}\n\nexport default GeoJSONWorkerLayer;\n\nvar noNew = function(geojson, options) {\n return new GeoJSONWorkerLayer(geojson, options);\n};\n\nexport {noNew as geoJSONWorkerLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/GeoJSONWorkerLayer.js\n **/","var Stringify = (function() {\n var functionToString = function(f) {\n return f.toString();\n };\n\n // Based on https://github.com/tangrams/tangram/blob/2a31893c814cf15d5077f87ffa10af20160716b9/src/utils/utils.js#L245\n var stringToFunction = function(str) {\n if (typeof str === 'string' && str.match(/^\\s*function\\s*\\w*\\s*\\([\\s\\S]*\\)\\s*\\{[\\s\\S]*\\}/m) != null) {\n var f;\n\n try {\n eval('f = ' + str);\n return f;\n } catch (err) {\n return str;\n }\n }\n };\n\n return {\n functionToString: functionToString,\n stringToFunction: stringToFunction\n };\n})();\n\nexport default Stringify;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/Stringify.js\n **/","import GeoJSONTileLayer from './GeoJSONTileLayer';\nimport extend from 'lodash.assign';\n\nclass TopoJSONTileLayer extends GeoJSONTileLayer {\n constructor(path, options) {\n var defaults = {\n topojson: true\n };\n\n options = extend({}, defaults, options);\n\n super(path, options);\n }\n}\n\nexport default TopoJSONTileLayer;\n\nvar noNew = function(path, options) {\n return new TopoJSONTileLayer(path, options);\n};\n\nexport {noNew as topoJSONTileLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/tile/TopoJSONTileLayer.js\n **/","import GeoJSONLayer from './GeoJSONLayer';\nimport extend from 'lodash.assign';\n\nclass TopoJSONLayer extends GeoJSONLayer {\n constructor(topojson, options) {\n var defaults = {\n topojson: true\n };\n\n options = extend({}, defaults, options);\n\n super(topojson, options);\n }\n}\n\nexport default TopoJSONLayer;\n\nvar noNew = function(topojson, options) {\n return new TopoJSONLayer(topojson, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as topoJSONLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/TopoJSONLayer.js\n **/","import GeoJSONWorkerLayer from './GeoJSONWorkerLayer';\nimport extend from 'lodash.assign';\n\nclass TopoJSONWorkerLayer extends GeoJSONWorkerLayer {\n constructor(topojson, options) {\n var defaults = {\n topojson: true\n };\n\n options = extend({}, defaults, options);\n\n super(topojson, options);\n }\n}\n\nexport default TopoJSONWorkerLayer;\n\nvar noNew = function(topojson, options) {\n return new TopoJSONWorkerLayer(topojson, options);\n};\n\n// Initialise without requiring new keyword\nexport {noNew as topoJSONWorkerLayer};\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/layer/TopoJSONWorkerLayer.js\n **/","// TODO: A lot of these utils don't need to be in separate, tiny files\n\nimport wrapNum from './wrapNum';\nimport extrudePolygon from './extrudePolygon';\nimport GeoJSON from './GeoJSON';\nimport Buffer from './Buffer';\nimport Worker from './Worker';\nimport Stringify from './Stringify';\n\nconst Util = {};\n\nUtil.wrapNum = wrapNum;\nUtil.extrudePolygon = extrudePolygon;\nUtil.GeoJSON = GeoJSON;\nUtil.Buffer = Buffer;\nUtil.Worker = Worker;\nUtil.Stringify = Stringify;\n\nexport default Util;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/index.js\n **/","/*\n * Wrap the given number to lie within a certain range (eg. longitude)\n *\n * Based on:\n * https://github.com/Leaflet/Leaflet/blob/master/src/core/Util.js\n */\n\nvar wrapNum = function(x, range, includeMax) {\n var max = range[1];\n var min = range[0];\n var d = max - min;\n return x === max && includeMax ? x : ((x - min) % d + d) % d + min;\n};\n\nexport default wrapNum;\n\n\n\n/** WEBPACK FOOTER **\n ** ./src/util/wrapNum.js\n **/"],"sourceRoot":"/source/"} \ No newline at end of file