From 559b4950161647040c572aab0eb716fa77e80220 Mon Sep 17 00:00:00 2001 From: Xiaoji Chen Date: Thu, 23 Feb 2017 17:40:31 -0800 Subject: [PATCH] Add Wind Layer (with luma v4 api). --- examples/wind/README.md | 6 + examples/wind/package.json | 40 + examples/wind/src/app.js | 113 + examples/wind/src/control-panel.js | 56 + examples/wind/src/defaults.js | 15 + .../delaunay-cover-layer-fragment.glsl.js | 340 ++ .../delaunay-cover-layer-vertex.glsl.js | 59 + .../delaunay-cover-layer.js | 103 + .../delaunay-interpolation-fragment.glsl.js | 33 + .../delaunay-interpolation-vertex.glsl.js | 38 + .../delaunay-interpolation.js | 298 ++ .../elevation-layer-fragment.glsl.js | 19 + .../elevation-layer-vertex.glsl.js | 44 + .../layers/elevation-layer/elevation-layer.js | 139 + .../layers/elevation-layer/grid-geometry.js | 82 + .../particle-layer-fragment.glsl.js | 46 + .../particle-layer-vertex.glsl.js | 94 + .../layers/particle-layer/particle-layer.js | 416 ++ .../program-transform-feedback.js | 18 + .../transform-feedback-fragment.glsl.js | 31 + .../transform-feedback-vertex.glsl.js | 109 + .../layers/wind-layer/wind-layer-fragment.js | 347 ++ .../layers/wind-layer/wind-layer-vertex.js | 113 + .../wind/src/layers/wind-layer/wind-layer.js | 228 + examples/wind/src/utils/load-data.js | 148 + examples/wind/src/wind-demo.js | 126 + examples/wind/static/index.html | 11 + examples/wind/static/style.css | 56 + examples/wind/webpack.config.js | 40 + examples/wind/yarn.lock | 3977 +++++++++++++++++ 30 files changed, 7145 insertions(+) create mode 100644 examples/wind/README.md create mode 100644 examples/wind/package.json create mode 100644 examples/wind/src/app.js create mode 100644 examples/wind/src/control-panel.js create mode 100644 examples/wind/src/defaults.js create mode 100644 examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-fragment.glsl.js create mode 100644 examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-vertex.glsl.js create mode 100644 examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer.js create mode 100644 examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-fragment.glsl.js create mode 100644 examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-vertex.glsl.js create mode 100644 examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation.js create mode 100644 examples/wind/src/layers/elevation-layer/elevation-layer-fragment.glsl.js create mode 100644 examples/wind/src/layers/elevation-layer/elevation-layer-vertex.glsl.js create mode 100644 examples/wind/src/layers/elevation-layer/elevation-layer.js create mode 100644 examples/wind/src/layers/elevation-layer/grid-geometry.js create mode 100644 examples/wind/src/layers/particle-layer/particle-layer-fragment.glsl.js create mode 100644 examples/wind/src/layers/particle-layer/particle-layer-vertex.glsl.js create mode 100644 examples/wind/src/layers/particle-layer/particle-layer.js create mode 100644 examples/wind/src/layers/particle-layer/program-transform-feedback.js create mode 100644 examples/wind/src/layers/particle-layer/transform-feedback-fragment.glsl.js create mode 100644 examples/wind/src/layers/particle-layer/transform-feedback-vertex.glsl.js create mode 100644 examples/wind/src/layers/wind-layer/wind-layer-fragment.js create mode 100644 examples/wind/src/layers/wind-layer/wind-layer-vertex.js create mode 100644 examples/wind/src/layers/wind-layer/wind-layer.js create mode 100644 examples/wind/src/utils/load-data.js create mode 100644 examples/wind/src/wind-demo.js create mode 100644 examples/wind/static/index.html create mode 100644 examples/wind/static/style.css create mode 100644 examples/wind/webpack.config.js create mode 100644 examples/wind/yarn.lock diff --git a/examples/wind/README.md b/examples/wind/README.md new file mode 100644 index 00000000000..fd4fa19c562 --- /dev/null +++ b/examples/wind/README.md @@ -0,0 +1,6 @@ +# Wind Demo + + +Issues with luma.gl + +* Texture2D class hard to use? \ No newline at end of file diff --git a/examples/wind/package.json b/examples/wind/package.json new file mode 100644 index 00000000000..6a576356170 --- /dev/null +++ b/examples/wind/package.json @@ -0,0 +1,40 @@ +{ + "scripts": { + "start": "webpack-dev-server --progress --hot --port 3000 --open --content-base static", + "start-local": "webpack-dev-server --env.local --progress --hot --open --content-base static", + "build-clean": "rm -rf dist && mkdir dist", + "build-copy": "cp -r static/* dist", + "build-script": "NODE_ENV=production webpack --env.prod=true", + "build": "npm run build-clean && npm run build-script && npm run build-copy" + }, + "dependencies": { + "babel-polyfill": "^6.16.0", + "d3-request": "^1.0.3", + "d3-voronoi": "^1.1.1", + "deck.gl": "4.0.6", + "luma.gl": "4.0.0-beta.1", + "react": "^15.4.1", + "react-autobind": "^1.0.6", + "react-dom": "^15.4.1", + "react-map-gl": "^1.7.2", + "tween.js": "^16.6.0" + }, + "devDependencies": { + "babel-core": "^6.21.0", + "babel-loader": "^6.2.10", + "babel-preset-es2015": "^6.18.0", + "babel-preset-react": "^6.16.0", + "babel-preset-stage-2": "^6.18.0", + "brfs-babel": "^1.0.0", + "transform-loader": "^0.2.3", + "webpack": "^2.6.1", + "webpack-dev-server": "^2.4.5" + }, + "babel": { + "presets": [ + "es2015", + "stage-2", + "react" + ] + } +} diff --git a/examples/wind/src/app.js b/examples/wind/src/app.js new file mode 100644 index 00000000000..a64bd21cd43 --- /dev/null +++ b/examples/wind/src/app.js @@ -0,0 +1,113 @@ +/* global window, document */ +import React, {Component} from 'react'; +import autobind from 'react-autobind'; +import {render} from 'react-dom'; +import MapGL from 'react-map-gl'; + +import WindDemo from './wind-demo'; +import ControlPanel from './control-panel'; + +// animation +import TWEEN from 'tween.js'; +const animate = () => { + TWEEN.update(); + window.requestAnimationFrame(animate); +}; + +// Set your mapbox token here +const MAPBOX_TOKEN = process.env.MapboxAccessToken; // eslint-disable-line + +class Root extends Component { + + constructor(props) { + super(props); + this.state = { + viewport: { + bearing: 0.9642857142857792, + latitude: 37.59651729201781, + longitude: -96.86543413846587, + mapStyle: 'mapbox://styles/mapbox/dark-v9', + maxZoom: 8, + pitch: 34.095940959409596, + zoom: 4.223615382460847, + width: 500, + height: 500 + }, + settings: { + time: 0, + showParticles: false, + showWindDemo: false, + showElevation: false + } + }; + autobind(this); + } + + componentDidMount() { + window.addEventListener('resize', this._onResize); + this._onResize(); + animate(); + } + + componentWillUnmount() { + window.removeEventListener('resize', this._onResize); + } + + _onResize() { + this._updateViewport({ + width: window.innerWidth, + height: window.innerHeight + }); + } + + _updateViewport(viewport) { + this.setState({ + viewport: {...this.state.viewport, ...viewport} + }); + } + + _updateSettings(settings) { + this.setState({ + settings: {...this.state.settings, ...settings} + }); + } + + render() { + const {viewport, settings} = this.state; + + return ( +
+ + + + + + +
+

Wind

+

Visualize wind on vector fields and particles.

+
    +
  • Hold cmd + drag to tilt the map
  • +
  • Turn on/off between a particles or vector field layer
  • +
  • Slide through every hour of the day to look at wind change
  • +
+

Made with deck.gl by + @philogb +

+

Data source: NCAA

+
+ + + +
+ +
+ ); + } +} + +render(, document.body.appendChild(document.createElement('div'))); diff --git a/examples/wind/src/control-panel.js b/examples/wind/src/control-panel.js new file mode 100644 index 00000000000..5a07d0ffa5a --- /dev/null +++ b/examples/wind/src/control-panel.js @@ -0,0 +1,56 @@ +import React, {Component, PropTypes} from 'react'; +import TWEEN from 'tween.js'; + +const propTypes = { + settings: PropTypes.object.isRequired, + onChange: PropTypes.func.isRequired +}; + +export default class ControlPanel extends Component { + + constructor(props) { + super(props); + + const timeState = {time: 0}; + + this.timeTween = new TWEEN.Tween(timeState) + .to({time: 1800}, 60000) + .onUpdate(() => this.props.onChange(timeState)) + .repeat(Infinity); + } + + _renderToggle(key, displayName) { + return ( +
+ + this.props.onChange({[key]: e.target.checked}) } /> +
+ ); + } + + _renderSlider(key, displayName, props) { + return ( +
+ + this.props.onChange({[key]: e.target.value}) } /> +
+ ); + } + + render() { + return ( +
+ { this._renderToggle('showParticles', 'particles') } + { this._renderToggle('showWind', 'field') } + { this._renderToggle('showElevation', 'elevation') } + { this._renderSlider('time', 'time', {min: 0, max: 70, step: 0.1}) } +
+ ); + } +} + +ControlPanel.propTypes = propTypes; diff --git a/examples/wind/src/defaults.js b/examples/wind/src/defaults.js new file mode 100644 index 00000000000..6fdcdd59649 --- /dev/null +++ b/examples/wind/src/defaults.js @@ -0,0 +1,15 @@ +export const SAMPLE = 140; +export const MARGIN = 10; + +export const ELEVATION_DATA_IMAGE = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/wind/elevation.png'; // eslint-disable-line +export const ELEVATION_DATA_BOUNDS = [-125, 24.4, -66.7, 49.6]; +export const ELEVATION_RANGE = [-100, 4126]; + +export const LIGHT_UNIFORMS = { + lightsPosition: [-70.585, 38.00, 15000], + lightsStrength: [1.0, 0.0], + ambientRatio: 0.9, + diffuseRatio: 0.8, + specularRatio: 0.9, + numberOfLights: 2 +}; diff --git a/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-fragment.glsl.js b/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-fragment.glsl.js new file mode 100644 index 00000000000..abe63b2f799 --- /dev/null +++ b/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-fragment.glsl.js @@ -0,0 +1,340 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME delaunay-cover-fragment-shader + +#ifdef GL_ES +precision highp float; +#endif + +#define NUM_OF_LIGHTS 2 + +varying vec4 vPosition; +varying vec4 vNormal; +varying vec4 vColor; + +uniform vec3 cameraPos; +uniform vec3 lightsPosition; +uniform vec2 lightsStrength; +uniform float ambientRatio; +uniform float diffuseRatio; +uniform float specularRatio; + +const float TILE_SIZE = 512.0; +const float PI = 3.1415926536; +const float WORLD_SCALE = TILE_SIZE / (PI * 2.0); + +const float PROJECT_LINEAR = 0.; +const float PROJECT_MERCATOR = 1.; +const float PROJECT_MERCATOR_OFFSETS = 2.; + +uniform float projectionMode; +uniform float projectionScale; +uniform vec4 projectionCenter; +uniform vec3 projectionPixelsPerUnit; +uniform mat4 projectionMatrix; +uniform mat4 projectionMatrixUncentered; + +#ifdef INTEL_TAN_WORKAROUND + +// All these functions are for substituting tan() function from Intel GPU only +const float TWO_PI = 6.2831854820251465; +const float PI_2 = 1.5707963705062866; +const float PI_16 = 0.1963495463132858; + +const float SIN_TABLE_0 = 0.19509032368659973; +const float SIN_TABLE_1 = 0.3826834261417389; +const float SIN_TABLE_2 = 0.5555702447891235; +const float SIN_TABLE_3 = 0.7071067690849304; + +const float COS_TABLE_0 = 0.9807852506637573; +const float COS_TABLE_1 = 0.9238795042037964; +const float COS_TABLE_2 = 0.8314695954322815; +const float COS_TABLE_3 = 0.7071067690849304; + +const float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; // 1/3! +const float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; // 1/5! +const float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; // 1/7! +const float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; // 1/9! + +float sin_taylor_fp32(float a) { + float r, s, t, x; + + if (a == 0.0) { + return 0.0; + } + + x = -a * a; + s = a; + r = a; + + r = r * x; + t = r * INVERSE_FACTORIAL_3; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_5; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_7; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_9; + s = s + t; + + return s; +} + +void sincos_taylor_fp32(float a, out float sin_t, out float cos_t) { + if (a == 0.0) { + sin_t = 0.0; + cos_t = 1.0; + } + sin_t = sin_taylor_fp32(a); + cos_t = sqrt(1.0 - sin_t * sin_t); +} + +float tan_fp32(float a) { + float sin_a; + float cos_a; + + if (a == 0.0) { + return 0.0; + } + + // 2pi range reduction + float z = floor(a / TWO_PI); + float r = a - TWO_PI * z; + + float t; + float q = floor(r / PI_2 + 0.5); + int j = int(q); + + if (j < -2 || j > 2) { + return 0.0 / 0.0; + } + + t = r - PI_2 * q; + + q = floor(t / PI_16 + 0.5); + int k = int(q); + int abs_k = int(abs(float(k))); + + if (abs_k > 4) { + return 0.0 / 0.0; + } else { + t = t - PI_16 * q; + } + + float u = 0.0; + float v = 0.0; + + float sin_t, cos_t; + float s, c; + sincos_taylor_fp32(t, sin_t, cos_t); + + if (k == 0) { + s = sin_t; + c = cos_t; + } else { + if (abs(float(abs_k) - 1.0) < 0.5) { + u = COS_TABLE_0; + v = SIN_TABLE_0; + } else if (abs(float(abs_k) - 2.0) < 0.5) { + u = COS_TABLE_1; + v = SIN_TABLE_1; + } else if (abs(float(abs_k) - 3.0) < 0.5) { + u = COS_TABLE_2; + v = SIN_TABLE_2; + } else if (abs(float(abs_k) - 4.0) < 0.5) { + u = COS_TABLE_3; + v = SIN_TABLE_3; + } + if (k > 0) { + s = u * sin_t + v * cos_t; + c = u * cos_t - v * sin_t; + } else { + s = u * sin_t - v * cos_t; + c = u * cos_t + v * sin_t; + } + } + + if (j == 0) { + sin_a = s; + cos_a = c; + } else if (j == 1) { + sin_a = c; + cos_a = -s; + } else if (j == -1) { + sin_a = -c; + cos_a = s; + } else { + sin_a = -s; + cos_a = -c; + } + return sin_a / cos_a; +} +#endif + +// +// Scaling offsets +// + +float project_scale(float meters) { + return meters * projectionPixelsPerUnit.x; +} + +vec2 project_scale(vec2 meters) { + return vec2( + meters.x * projectionPixelsPerUnit.x, + meters.y * projectionPixelsPerUnit.x + ); +} + +vec3 project_scale(vec3 meters) { + return vec3( + meters.x * projectionPixelsPerUnit.x, + meters.y * projectionPixelsPerUnit.x, + meters.z * projectionPixelsPerUnit.x + ); +} + +vec4 project_scale(vec4 meters) { + return vec4( + meters.x * projectionPixelsPerUnit.x, + meters.y * projectionPixelsPerUnit.x, + meters.z * projectionPixelsPerUnit.x, + meters.w + ); +} + +// +// Projecting positions +// + +// non-linear projection: lnglats => unit tile [0-1, 0-1] +vec2 project_mercator_(vec2 lnglat) { + return vec2( + radians(lnglat.x) + PI, +#ifdef INTEL_TAN_WORKAROUND + PI - log(tan_fp32(PI * 0.25 + radians(lnglat.y) * 0.5)) +#else + PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5)) +#endif + ); +} + +vec2 project_position(vec2 position) { + if (projectionMode == PROJECT_LINEAR) { + return (position + vec2(TILE_SIZE / 2.0)) * projectionScale; + } + if (projectionMode == PROJECT_MERCATOR_OFFSETS) { + return project_scale(position); + } + // Covers projectionMode == PROJECT_MERCATOR + return project_mercator_(position) * WORLD_SCALE * projectionScale; +} + +vec3 project_position(vec3 position) { + return vec3(project_position(position.xy), project_scale(position.z) + .1); +} + +vec4 project_position(vec4 position) { + return vec4(project_position(position.xyz), position.w); +} + +// + +vec4 project_to_clipspace(vec4 position) { + if (projectionMode == PROJECT_MERCATOR_OFFSETS) { + return projectionMatrix * vec4(position.xyz, 0.0) + projectionCenter; + } + return projectionMatrix * position; +} + +// Backwards compatibility + +float scale(float position) { + return project_scale(position); +} + +vec2 scale(vec2 position) { + return project_scale(position); +} + +vec3 scale(vec3 position) { + return project_scale(position); +} + +vec4 scale(vec4 position) { + return project_scale(position); +} + +vec2 preproject(vec2 position) { + return project_position(position); +} + +vec3 preproject(vec3 position) { + return project_position(position); +} + +vec4 preproject(vec4 position) { + return project_position(position); +} + +vec4 project(vec4 position) { + return project_to_clipspace(position); +} + +float getLightWeight(vec4 position_worldspace, vec3 normals_worldspace) { + float lightWeight = 0.0; + + vec3 position_worldspace_vec3 = position_worldspace.xyz / position_worldspace.w; + vec3 normals_worldspace_vec3 = normals_worldspace.xzy; + + vec3 camera_pos_worldspace = cameraPos; + vec3 view_direction = normalize(camera_pos_worldspace - position_worldspace_vec3); + + vec3 light_position_worldspace = project_position(lightsPosition); + vec3 light_direction = normalize(light_position_worldspace - position_worldspace_vec3); + + vec3 halfway_direction = normalize(light_direction + view_direction); + float lambertian = dot(light_direction, normals_worldspace_vec3); + float specular = 0.0; + if (lambertian > 0.0) { + float specular_angle = max(dot(normals_worldspace_vec3, halfway_direction), 0.0); + specular = pow(specular_angle, 32.0); + } + lambertian = max(lambertian, 0.0); + lightWeight += + (ambientRatio + lambertian * diffuseRatio + specular * specularRatio) * + lightsStrength.x; + + return lightWeight; +} + +void main(void) { + float lightWeight = getLightWeight(vPosition, vNormal.xyz); + gl_FragColor = vec4(vColor.xyz * lightWeight, vColor.a); +} +`; diff --git a/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-vertex.glsl.js b/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-vertex.glsl.js new file mode 100644 index 00000000000..169b0a1334d --- /dev/null +++ b/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer-vertex.glsl.js @@ -0,0 +1,59 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME delaunay-cover-vertex-shader +#define HEIGHT_FACTOR 25. + +uniform vec2 bounds; + +attribute vec3 positions; +attribute vec3 next; +attribute vec3 next2; + +varying vec4 vPosition; +varying vec4 vNormal; +varying vec4 vColor; + +vec4 getWorldSpacePos(vec3 positions) { + vec2 pos = project_position(positions.xy); + float elevation = project_scale(positions.z * 100.); + vec3 extrudedPosition = vec3(pos.xy, elevation + 1.0); + vec4 position_worldspace = vec4(extrudedPosition, 1.0); + return position_worldspace; +} + +void main(void) { + vec4 position_worldspace = getWorldSpacePos(positions); + gl_Position = project_to_clipspace(position_worldspace); + + vec4 pos2 = getWorldSpacePos(next); + vec4 pos3 = getWorldSpacePos(next2); + + vec4 a = pos2 - position_worldspace; + vec4 b = pos3 - position_worldspace; + vec3 normal = normalize(cross(a.xyz, b.xyz)); + + vPosition = position_worldspace; + vNormal = vec4(normal, 1); + // vColor = vec4(1, 0.25, 0.4, (positions.z - bounds.x) / (bounds.y - bounds.x)); + vColor = vec4(15./70., 26./70., 36./70., (positions.z - bounds.x) / (bounds.y - bounds.x)); +} +`; diff --git a/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer.js b/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer.js new file mode 100644 index 00000000000..44e1426e1c5 --- /dev/null +++ b/examples/wind/src/layers/delaunay-cover-layer/delaunay-cover-layer.js @@ -0,0 +1,103 @@ +import {Layer} from 'deck.gl'; +// import {Model, Geometry, Program} from 'luma.gl'; +// +// import vertex from './delaunay-cover-layer-vertex.glsl'; +// import fragment from './delaunay-cover-layer-fragment.glsl'; + +export default class DelaunayCoverLayer extends Layer { +// NOTE: commenting out, it is not used anywhere. +/* + getShaders() { + return { + vs: vertex, + fs: fragment + }; + } + + initializeState() { + const {gl} = this.context; + const {triangulation} = this.props; + const model = this.getModel(gl, triangulation); + this.setState({model}); + } + + updateState({props, oldProps, changeFlags: {dataChanged, somethingChanged}}) { + } + + getModel(gl, triangulation) { + const bounds = [Infinity, -Infinity]; + triangulation.forEach(triangle => { + const minT = Math.min(...triangle.map(d => d.elv)); + const maxT = Math.max(...triangle.map(d => d.elv)); + bounds[0] = bounds[0] > minT ? minT : bounds[0]; + bounds[1] = bounds[1] < maxT ? maxT : bounds[1]; + }); + + const positions = []; + triangulation.forEach(t => positions.push( + -t[0].long, t[0].lat, t[0].elv, + -t[1].long, t[1].lat, t[1].elv, + -t[2].long, t[2].lat, t[2].elv) + ); + + const next = []; + triangulation.forEach(t => next.push( + -t[1].long, t[1].lat, t[1].elv, + -t[2].long, t[2].lat, t[2].elv, + -t[0].long, t[0].lat, t[0].elv) + ); + + const next2 = []; + triangulation.forEach(t => next2.push( + -t[2].long, t[2].lat, t[2].elv, + -t[0].long, t[0].lat, t[0].elv, + -t[1].long, t[1].lat, t[1].elv) + ); + + const shaders = this.getShaders(); + + const model = new Model(gl, { + id: 'delaunay', + program: new Program(gl, shaders), + geometry: new Geometry({ + drawMode: 'TRIANGLES', + attributes: { + positions: new Float32Array(positions), + next: { + value: new Float32Array(next), + type: gl.FLOAT, + size: 3 + }, + next2: { + value: new Float32Array(next2), + type: gl.FLOAT, + size: 3 + } + } + }), + isIndexed: false, + onBeforeRender: () => { + model.program.setUniforms({ + lightsPosition: [-100, 25, 15000], + ambientRatio: 0.2, + diffuseRatio: 0.9, + specularRatio: 0.2, + lightsStrength: [1.0, 0.0], + numberOfLights: 2, + bounds + }); + // gl.disable(gl.BLEND); + gl.enable(gl.BLEND); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE); + gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + gl.blendEquation(gl.FUNC_ADD); + }, + onAfterRender: () => { + // gl.blendFunc(gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA); + } + }); + + return model; + } +*/ +} diff --git a/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-fragment.glsl.js b/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-fragment.glsl.js new file mode 100644 index 00000000000..6c67e4a84b9 --- /dev/null +++ b/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-fragment.glsl.js @@ -0,0 +1,33 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME delaunay-fragment-shader + +#ifdef GL_ES +precision highp float; +#endif + +varying vec4 vColor; + +void main(void) { + gl_FragColor = vColor; +} +`; diff --git a/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-vertex.glsl.js b/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-vertex.glsl.js new file mode 100644 index 00000000000..0d148fd9e3c --- /dev/null +++ b/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation-vertex.glsl.js @@ -0,0 +1,38 @@ +// Copyright (c) 2017 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME delaunay-vertex-shader + +uniform vec4 boundingBox; +uniform vec2 size; + +attribute vec3 positions; +attribute vec3 data; + +varying vec4 vColor; + +void main(void) { + float posX = mix(-1., 1., (positions.x - boundingBox.x) / (boundingBox.y - boundingBox.x)); + float posY = mix(-1., 1., (positions.y - boundingBox.z) / (boundingBox.w - boundingBox.z)); + vColor = vec4(data.xyz, positions.z); + gl_Position = vec4(posX, posY, 0, 1); +} +`; diff --git a/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation.js b/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation.js new file mode 100644 index 00000000000..2ac2d43a919 --- /dev/null +++ b/examples/wind/src/layers/delaunay-interpolation/delaunay-interpolation.js @@ -0,0 +1,298 @@ +/* global document */ +import { + Model, Geometry, createGLContext, + Texture2D, Renderbuffer, Framebuffer, + withParameters} from 'luma.gl'; + +import vertex from './delaunay-interpolation-vertex.glsl'; +import fragment from './delaunay-interpolation-fragment.glsl'; +import assert from 'assert'; + +export default class DelaunayInterpolation { + constructor(opts) { + this.props = opts; + this.context = opts.gl; + if (!opts.gl) { + const canvas = document.getElementById('texture-canvas') || document.createElement('canvas'); + canvas.id = 'texture-canvas'; + canvas.style.display = 'none'; + document.body.appendChild(canvas); + this.context = createGLContext({canvas: 'texture-canvas', debug: false, webgl2: true}); + } + } + + getTextureWidth() { + return this.props.textureWidth || 256; + } + + generateTextures() { + const gl = this.context; + const {boundingBox, measures, triangulation} = this.props; + const {txt, bounds, textures, width, height} = + this._generateTextures(gl, boundingBox, triangulation, measures); + + return { + textureObject: txt, + dataBounds: bounds, + textureArray: textures, + textureSize: {width, height} + }; + } + + getDelaunayShaders() { + return { + vs: vertex, + fs: fragment + }; + } + + getDelaunayModel(gl, triangulation) { + const positions = []; + triangulation.forEach(triangle => positions.push( + -triangle[0].long, triangle[0].lat, triangle[0].elv, + -triangle[1].long, triangle[1].lat, triangle[1].elv, + -triangle[2].long, triangle[2].lat, triangle[2].elv + )); + + const shaders = this.getDelaunayShaders(); + + return new Model(gl, { + id: 'delaunay', + vs: shaders.vs, + fs: shaders.fs, + geometry: new Geometry({ + drawMode: gl.TRIANGLES, + positions: new Float32Array(positions) + }), + isInstanced: false + }); + } + + createTextureNew(gl, options) { + + const opt = Object.assign({ + textureType: gl.TEXTURE_2D, + pixelStore: [ + {name: gl.UNPACK_FLIP_Y_WEBGL, value: true} + ], + parameters: [ + {name: gl.TEXTURE_MAG_FILTER, value: gl.NEAREST}, + {name: gl.TEXTURE_MIN_FILTER, value: gl.NEAREST}, + {name: gl.TEXTURE_WRAP_S, value: gl.CLAMP_TO_EDGE}, + {name: gl.TEXTURE_WRAP_T, value: gl.CLAMP_TO_EDGE} + ], + data: { + internalFormat: gl.RGBA32F, + format: gl.RGBA, + value: false, + type: gl.FLOAT, + + width: 0, + height: 0, + border: 0 + } + }, options); + + const data = opt.data; + const type = data.type; + const format = data.format; + const internalFormat = data.internalFormat; + const hasValue = Boolean(data.value); + + // TODO: remove this assert after cleanup. + assert(hasValue !== true, 'Handling only hasValue = true cases'); + + const texture = new Texture2D(gl, { + format: internalFormat, + dataFormat: format, + type, // TODO: type should be Float, for now defaulting to bye type + border: data.border, + parameters: { + [gl.TEXTURE_MAG_FILTER]: gl.NEAREST, + [gl.TEXTURE_MIN_FILTER]: gl.NEAREST, + [gl.TEXTURE_WRAP_S]: gl.CLAMP_TO_EDGE, + [gl.TEXTURE_WRAP_T]: gl.CLAMP_TO_EDGE + }, + pixelStore: {[gl.UNPACK_FLIP_Y_WEBGL]: true} + }); + + return texture; + } + + createRenderbuffer(gl, options) { + const opt = Object.assign({ + storageType: gl.DEPTH_COMPONENT16, + width: 0, + height: 0 + }, options); + + return new Renderbuffer(gl, { + format: opt.storageType, + width: opt.width, + height: opt.height + }); + } + + createFramebufferWithTexture(gl, options) { + const opt = Object.assign({ + width: 0, + height: 0, + // All texture params + bindToTexture: false, + textureOptions: { + attachment: gl.COLOR_ATTACHMENT0 + }, + // All render buffer params + bindToRenderBuffer: false, + renderBufferOptions: { + attachment: gl.DEPTH_ATTACHMENT + } + }, options.fb); + + const texture = this.createTextureNew(gl, options.txt); + const rb = this.createRenderbuffer(gl, options.rb); + const fb = new Framebuffer(gl, { + width: opt.width, + height: opt.height, + attachments: { + [gl.COLOR_ATTACHMENT0]: texture, + [gl.DEPTH_ATTACHMENT]: rb + } + }); + return {fb, rb, texture}; + } + + _generateTextures(gl, boundingBox, triangulation, measures) { + const delaunayModel = this.getDelaunayModel(gl, triangulation); + const lngDiff = Math.abs(boundingBox.maxLng - boundingBox.minLng); + const latDiff = Math.abs(boundingBox.maxLat - boundingBox.minLat); + const width = this.getTextureWidth(); + const height = Math.ceil(latDiff * width / lngDiff); + const bounds = []; + const correctAngles = (angle1, angle2, angle3) => { + // return [angle1, angle2, angle3]; + const abs = Math.abs.bind(Math); + const modulo = 8; + let flip = false; + if (abs(angle1 - angle2) > abs(angle1 - (angle2 + modulo))) { + flip = true; + } + if (abs(angle1 - angle3) > abs(angle1 - (angle3 + modulo))) { + if (flip) { + // need to flip angle1 + angle1 -= modulo; + } else { + // need to flip angle3 + angle3 += modulo; + } + } else if (flip) { + // need to flip angle2 + angle2 += modulo; + } + return [angle1, angle2, angle3]; + }; + const {fb, rb, texture} = this.createFramebufferWithTexture(gl, { + fb: {width, height}, + rb: {width, height}, + txt: { + data: { + internalFormat: gl.RGBA32F, + format: gl.RGBA, + value: false, + type: gl.FLOAT, + width, + height, + border: 0 + } + } + }); + + let textures; + + withParameters(gl, { + clearColor: [0.0, 0.0, 0.0, 0.0], + clearDepth: 1.0, + blend: false, + depthTest: false, + depthFunc: gl.LEQUAL, + viewport: [0, 0, width, height], + framebuffer: fb + }, () => { + textures = measures.map((measure, hour) => { + const sample = []; + gl.clear(gl.COLOR_BUFFER_BIT | gl.DEPTH_BUFFER_BIT); + function processTriplet(triplet) { + if (!bounds[0]) { + bounds[0] = {min: measure[triplet[0].index][0], max: measure[triplet[0].index][0]}; + bounds[1] = {min: measure[triplet[0].index][1], max: measure[triplet[0].index][1]}; + bounds[2] = {min: measure[triplet[0].index][2], max: measure[triplet[0].index][2]}; + } else { + [0, 1, 2].forEach(index => { + triplet.forEach(t => { // eslint-disable-line + if (measure[t.index][index] !== 0) { + bounds[index].min = bounds[index].min > measure[t.index][index] ? + measure[t.index][index] : bounds[index].min; + bounds[index].max = bounds[index].max < measure[t.index][index] ? + measure[t.index][index] : bounds[index].max; + } + }); + }); + } + + const [angle1, angle2, angle3] = correctAngles( + measure[triplet[0].index][0], + measure[triplet[1].index][0], + measure[triplet[2].index][0] + ); + + sample.push( + angle1, + measure[triplet[0].index][1], + measure[triplet[0].index][2], + + angle2, + measure[triplet[1].index][1], + measure[triplet[1].index][2], + + angle3, + measure[triplet[2].index][1], + measure[triplet[2].index][2] + ); + } + + triangulation.forEach(processTriplet); + + delaunayModel.setAttributes({ + data: { + id: 'data', + value: new Float32Array(sample), + bytes: Float32Array.BYTES_PER_ELEMENT * sample.length, + size: 3, + type: gl.FLOAT, + isIndexed: false + } + }); + + delaunayModel.render({ + boundingBox: [ + boundingBox.minLng, boundingBox.maxLng, boundingBox.minLat, boundingBox.maxLat + ], + size: [width, height] + }); + + // read texture back + const pixels = new Float32Array(width * height * 4); + const pixelStoreParameters = { + [gl.UNPACK_FLIP_Y_WEBGL]: true + }; + withParameters(gl, pixelStoreParameters, () => { + gl.readPixels(0, 0, width, height, gl.RGBA, gl.FLOAT, pixels, 0); + }); + + return pixels; + }); + }); + + return {fb, rb, texture, bounds, textures, width, height}; + } +} diff --git a/examples/wind/src/layers/elevation-layer/elevation-layer-fragment.glsl.js b/examples/wind/src/layers/elevation-layer/elevation-layer-fragment.glsl.js new file mode 100644 index 00000000000..dc860f6a96c --- /dev/null +++ b/examples/wind/src/layers/elevation-layer/elevation-layer-fragment.glsl.js @@ -0,0 +1,19 @@ +export default `\ +#define SHADER_NAME elevation-layer-fragment-shader + +uniform vec2 elevationRange; + +varying float lightWeight; +varying vec3 vNormal; +varying float vAltitude; + +void main() { + if (vAltitude < -90.0) { + discard; + } + + float opacity = smoothstep(elevationRange.x, elevationRange.y / 2.0, vAltitude) * 1.; + + gl_FragColor = vec4(vec3(15./70., 26./70., 36./70.) * lightWeight, opacity); +} +`; diff --git a/examples/wind/src/layers/elevation-layer/elevation-layer-vertex.glsl.js b/examples/wind/src/layers/elevation-layer/elevation-layer-vertex.glsl.js new file mode 100644 index 00000000000..3860c4b8854 --- /dev/null +++ b/examples/wind/src/layers/elevation-layer/elevation-layer-vertex.glsl.js @@ -0,0 +1,44 @@ +export default `\ +#define SHADER_NAME elevation-layer-vertex-shader + +uniform sampler2D elevationTexture; +uniform vec4 elevationBounds; +uniform vec2 elevationRange; +uniform float zScale; + +attribute vec3 positions; + +varying float lightWeight; +varying vec3 vNormal; +varying float vAltitude; + +vec3 getWorldPosition(vec2 lngLat) { + vec2 texCoords = (lngLat - elevationBounds.xy) / (elevationBounds.zw - elevationBounds.xy); + vec4 elevation = texture2D(elevationTexture, texCoords); + + float altitude = mix(elevationRange.x, elevationRange.y, elevation.r); + + return vec3(lngLat, altitude * zScale); +} + +void main() { + + vec3 curr = getWorldPosition(positions.xy); + vAltitude = curr.z / zScale; + curr = project_position(curr); + + vec3 prev = getWorldPosition(positions.xy + vec2(1., 0.0)); + prev = project_position(prev); + vec3 next = getWorldPosition(positions.xy - vec2(0.0, 1.)); + next = project_position(next); + + curr.z = (curr.z + prev.z + next.z) / 3.; + + vec4 position_worldspace = vec4(curr, 1.0); + gl_Position = project_to_clipspace(position_worldspace); + + vNormal = cross(prev - curr, next - curr); + + lightWeight = getLightWeight(curr, normalize(vNormal)); +} +`; diff --git a/examples/wind/src/layers/elevation-layer/elevation-layer.js b/examples/wind/src/layers/elevation-layer/elevation-layer.js new file mode 100644 index 00000000000..d6685fdf9df --- /dev/null +++ b/examples/wind/src/layers/elevation-layer/elevation-layer.js @@ -0,0 +1,139 @@ +import {Layer} from 'deck.gl'; +import {GL, Model, loadTextures} from 'luma.gl'; + +import {ELEVATION_DATA_IMAGE, ELEVATION_DATA_BOUNDS, ELEVATION_RANGE} from '../../defaults'; +import GridGeometry from './grid-geometry'; + +import vertex from './elevation-layer-vertex.glsl'; +import fragment from './elevation-layer-fragment.glsl'; + +const LIGHT_UNIFORMS = { + lightsPosition: [-60, 25, 15000, -140, 0, 400000], + ambientRatio: 0.4, + diffuseRatio: 0.6, + specularRatio: 0.2, + lightsStrength: [1.0, 2.0], + numberOfLights: 2 +}; + +const defaultProps = { + boundingBox: null, // : {minLng, minLat, maxLng, maxLat}, lngResolution, latResolution} + lngResolution: 100, + latResolution: 100, + zScale: 1 +}; + +export default class ElevationLayer extends Layer { + getShaders() { + return { + vs: vertex, + fs: fragment, + modules: ['lighting'], + shaderCache: this.context.shaderCache + }; + } + + initializeState() { + const {gl} = this.context; + + loadTextures(gl, { + urls: [ELEVATION_DATA_IMAGE], + // TODO open bug for this, refine the loadTextures interface + parameters: { + parameters: { + [GL.TEXTURE_MAG_FILTER]: GL.LINEAR, + [GL.TEXTURE_MIN_FILTER]: GL.LINEAR, + [GL.TEXTURE_WRAP_S]: GL.CLAMP_TO_EDGE, + [GL.TEXTURE_WRAP_T]: GL.CLAMP_TO_EDGE + } + } + }).then(textures => { + this.setState({data: textures[0]}); + }); + + this.setState({model: this.getModel(gl)}); + + this.setUniforms({ + ...LIGHT_UNIFORMS, + elevationBounds: ELEVATION_DATA_BOUNDS, + elevationRange: ELEVATION_RANGE + }); + } + + updateState({oldProps, props, changeFlags}) { + if (changeFlags.propsChanged) { + const {boundingBox, lngResolution, latResolution} = props; + + const propsChanged = + boundingBox !== oldProps.boundingBox || + lngResolution !== oldProps.lngResolution || + latResolution !== oldProps.latResolution; + + if (propsChanged) { + this.setState({ + vertexCount: lngResolution * latResolution + }); + this.state.attributeManager.invalidateAll(); + } + } + } + + draw({uniforms}) { + const {gl} = this.context; + const {zScale} = this.props; + const {data, model} = this.state; + + if (!data || !model) { + return; + } + + const parameters = { + depthTest: true, + depthFunc: gl.LEQUAL, + blend: true, + blendFunc: [gl.SRC_ALPHA, gl.ONE_MINUS_SRC_ALPHA], + blendEquation: gl.FUNC_ADD + }; + + uniforms = Object.assign({}, uniforms, { + elevationTexture: data, + zScale + }); + + model.draw({uniforms, parameters}); + } + + getModel(gl) { + const shaders = this.getShaders(); + // 3d surface + const vsShader = shaders.vs; + const fsSource = shaders.fs; + + const fsShader = `\ +#ifdef GL_ES +precision highp float; +#endif +${fsSource}`; + + const {lngResolution, latResolution, boundingBox} = this.props; + + const geometry = new GridGeometry({ + xResolution: lngResolution, + yResolution: latResolution, + boundingBox + }); + + return new Model(gl, { + id: this.props.id, + vs: vsShader, + fs: fsShader, + geometry, + // FIXME - isIndexed should be set in "GridGeometry" + isIndexed: true, + modules: ['lighting'] + }); + } +} + +ElevationLayer.layerName = 'ElevationLayer'; +ElevationLayer.defaultProps = defaultProps; diff --git a/examples/wind/src/layers/elevation-layer/grid-geometry.js b/examples/wind/src/layers/elevation-layer/grid-geometry.js new file mode 100644 index 00000000000..55086e433c4 --- /dev/null +++ b/examples/wind/src/layers/elevation-layer/grid-geometry.js @@ -0,0 +1,82 @@ +import {GL, Geometry} from 'luma.gl'; + +export default class GridGeometry extends Geometry { + constructor(opts = {}) { + const {id = 'grid-geometry'} = opts; + + const indices = calculateIndices(opts); + const positions = calculatePositions(opts); + + super(Object.assign({}, opts, { + id, + drawMode: GL.TRIANGLES, + attributes: { + // No size/type information is needed for known vertex names + indices, + positions + }, + vertexCount: indices.length + })); + } +} + +function calculateIndices({xResolution, yResolution}) { + // # of squares = (nx - 1) * (ny - 1) + // # of triangles = squares * 2 + // # of indices = triangles * 3 + const indicesCount = (xResolution - 1) * (yResolution - 1) * 2 * 3; + + const indices = new Uint32Array(indicesCount); + + let i = 0; + for (let lngIndex = 0; lngIndex < xResolution - 1; lngIndex++) { + for (let latIndex = 0; latIndex < yResolution - 1; latIndex++) { + /* + * i0 i1 + * +--.+--- + * | / | + * +'--+--- + * | | + * i2 i3 + */ + const i0 = latIndex * xResolution + lngIndex; + const i1 = i0 + 1; + const i2 = i0 + xResolution; + const i3 = i2 + 1; + + indices[i++] = i0; + indices[i++] = i2; + indices[i++] = i1; + indices[i++] = i1; + indices[i++] = i2; + indices[i++] = i3; + } + } + + return indices; +} + +function calculatePositions({ + boundingBox, + xResolution, + yResolution +}) { + const {minLng, minLat, maxLng, maxLat} = boundingBox; + + // step between samples + const deltaLng = (maxLng - minLng) / (xResolution - 1); + const deltaLat = (maxLat - minLat) / (yResolution - 1); + + const positions = new Float32Array(xResolution * yResolution * 3); + + let i = 0; + for (let latIndex = 0; latIndex < yResolution; latIndex++) { + for (let lngIndex = 0; lngIndex < xResolution; lngIndex++) { + positions[i++] = lngIndex * deltaLng + minLng; + positions[i++] = latIndex * deltaLat + minLat; + positions[i++] = 0; + } + } + + return positions; +} diff --git a/examples/wind/src/layers/particle-layer/particle-layer-fragment.glsl.js b/examples/wind/src/layers/particle-layer/particle-layer-fragment.glsl.js new file mode 100644 index 00000000000..57c03870d98 --- /dev/null +++ b/examples/wind/src/layers/particle-layer/particle-layer-fragment.glsl.js @@ -0,0 +1,46 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME particle-layer-fragment-shader + +#ifdef GL_ES +precision highp float; +#endif + +varying vec4 vColor; +varying float vAltitude; + +void main(void) { + // if (vColor.a < 0.07) { + // discard; + // } + + if (vAltitude < -90.0) { + discard; + } + + vec2 diff = gl_PointCoord - vec2(.5); + if (length(diff) > 0.5) { + discard; + } + gl_FragColor = vColor; +} +`; diff --git a/examples/wind/src/layers/particle-layer/particle-layer-vertex.glsl.js b/examples/wind/src/layers/particle-layer/particle-layer-vertex.glsl.js new file mode 100644 index 00000000000..b9b302f1882 --- /dev/null +++ b/examples/wind/src/layers/particle-layer/particle-layer-vertex.glsl.js @@ -0,0 +1,94 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME particle-layer-vertex-shader + +#define HEIGHT_FACTOR 25. +#define ELEVATION_SCALE 80. + +uniform sampler2D dataFrom; +uniform sampler2D dataTo; +uniform sampler2D elevationTexture; +uniform float delta; + +uniform vec4 boundingBox; +uniform vec2 size; +uniform vec2 bounds0; +uniform vec2 bounds1; +uniform vec2 bounds2; +uniform vec4 elevationBounds; +uniform vec2 elevationRange; +uniform float zScale; + +// attribute vec3 positions; +attribute vec4 posFrom; +// attribute vec3 vertices; + +varying vec4 vColor; +varying float vAltitude; + +vec3 getWorldPosition(vec2 lngLat) { + vec2 texCoords = (lngLat - elevationBounds.xy) / (elevationBounds.zw - elevationBounds.xy); + vec4 elevation = texture2D(elevationTexture, texCoords); + + float altitude = mix(elevationRange.x, elevationRange.y, elevation.r); + + return vec3(lngLat, altitude * zScale); +} + +float getAltitude(vec2 lngLat) { + vec2 texCoords = (lngLat - elevationBounds.xy) / (elevationBounds.zw - elevationBounds.xy); + vec4 elevation = texture2D(elevationTexture, texCoords); + + return mix(elevationRange.x, elevationRange.y, elevation.r); +} + +void main(void) { + // position in texture coords + float x = (posFrom.x - boundingBox.x) / (boundingBox.y - boundingBox.x); + float y = (posFrom.y - boundingBox.z) / (boundingBox.w - boundingBox.z); + vec2 coord = vec2(x, 1. - y); + vec4 texel = mix(texture2D(dataFrom, coord), texture2D(dataTo, coord), delta); + + vAltitude = getAltitude(posFrom.xy); + //float wind = (texel.y - bounds1.x) / (bounds1.y - bounds1.x); + float wind = 0.05 + (texel.y - bounds1.x) / (bounds1.y - bounds1.x) * 0.9; + + vec3 prev = getWorldPosition(posFrom.xy + vec2(1., 0.0)); + prev = project_position(prev); + vec3 next = getWorldPosition(posFrom.xy - vec2(0.0, 1.)); + next = project_position(next); + vec2 pos = project_position(posFrom.xy); + float elevation = (project_scale(vAltitude * zScale) + prev.z + next.z) / 3.; + vec3 extrudedPosition = vec3(pos.xy, elevation + 1.0); + vec4 position_worldspace = vec4(extrudedPosition, 1.0); + gl_Position = project_to_clipspace(position_worldspace); + gl_PointSize = pow(3.5 / (gl_Position.z + 0.7), 2.); + + float alpha = mix(0., 0.8, pow(wind, .5)); + if (texel.x == 0. && texel.y == 0. && texel.z == 0.) { + alpha = 0.; + } + // temperature in 0-1 + float temp = (texel.z - bounds2.x) / (bounds2.y - bounds2.x); + vColor = vec4(vec3(0.5), alpha); +} +`; diff --git a/examples/wind/src/layers/particle-layer/particle-layer.js b/examples/wind/src/layers/particle-layer/particle-layer.js new file mode 100644 index 00000000000..274a503164b --- /dev/null +++ b/examples/wind/src/layers/particle-layer/particle-layer.js @@ -0,0 +1,416 @@ +/* global Image */ +import {Layer} from 'deck.gl'; +import {GL, Model, Geometry, Buffer, TransformFeedback, setParameters} from 'luma.gl'; +import ProgramTransformFeedback from './program-transform-feedback'; + +import DelaunayInterpolation from '../delaunay-interpolation/delaunay-interpolation'; +import {ELEVATION_DATA_IMAGE, ELEVATION_DATA_BOUNDS, ELEVATION_RANGE} from '../../defaults'; + +import vertex from './particle-layer-vertex.glsl'; +import fragment from './particle-layer-fragment.glsl'; +import vertexTF from './transform-feedback-vertex.glsl'; +import fragmentTF from './transform-feedback-fragment.glsl'; + +const defaultProps = { + boundingBox: null, + originalBoundingBox: null, + texData: null, + zScale: 1, + time: 0 +}; + +export default class ParticleLayer extends Layer { + getShaders() { + return { + vs: vertex, + fs: fragment + }; + } + + initializeState() { + const {gl} = this.context; + const {boundingBox, texData, originalBoundingBox} = this.props; + + const data = {}; + const image = new Image(584, 253); + image.onload = () => { + data.img = image; + }; + image.src = ELEVATION_DATA_IMAGE; + + const elevationWidth = 584; + const elevationHeight = 253; + + const elevationTexture = this.createTexture(gl, { + width: elevationWidth, + height: elevationHeight, + type: gl.UNSIGNED_BYTE, + internalFormat: gl.RGBA, + parameters: [ + {name: gl.TEXTURE_MAG_FILTER, value: gl.LINEAR}, + {name: gl.TEXTURE_MIN_FILTER, value: gl.LINEAR}, + {name: gl.TEXTURE_WRAP_S, value: gl.CLAMP_TO_EDGE}, + {name: gl.TEXTURE_WRAP_T, value: gl.CLAMP_TO_EDGE} + ] + }); + + const {textureSize} = this.props.texData; + const {width, height} = textureSize; + const textureFrom = this.createTexture(gl, {width, height}); + const textureTo = this.createTexture(gl, {width, height}); + + const model = this.getModel({ + gl, boundingBox, originalBoundingBox, nx: 1200, ny: 600, texData + }); + + this.setupTransformFeedback({gl, boundingBox, nx: 1200, ny: 600}); + + const modelTF = this.getModelTF({ + gl, boundingBox, originalBoundingBox, nx: 1200, ny: 600, texData + }); + + this.setState({ + model, + modelTF, + texData, + data, + elevationWidth, + elevationHeight, + elevationTexture, + textureFrom, + textureTo, + width, + height + }); + } + + updateState({props, oldProps, changeFlags: {dataChanged, somethingChanged}}) { + const {time} = this.props; + const timeInterval = Math.floor(time); + const delta = time - timeInterval; + this.setState({ + timeInterval, + delta + }); + } + + /* eslint-disable max-statements */ + draw({uniforms}) { + const {gl} = this.context; + + const state = this.state; + const props = this.props; + const {boundingBox, texData} = this.props; + const {dataBounds} = texData; + + this.runTransformFeedback({gl}); + + const {model, textureFrom, textureTo, delta} = this.state; + const {textureArray} = texData; + const { + width, height, + elevationTexture, elevationWidth, elevationHeight, + bufferTo, bufferFrom, + timeInterval + } = this.state; + + const currentUniforms = { + boundingBox: [boundingBox.minLng, boundingBox.maxLng, boundingBox.minLat, boundingBox.maxLat], + bounds0: [dataBounds[0].min, dataBounds[0].max], + bounds1: [dataBounds[1].min, dataBounds[1].max], + bounds2: [dataBounds[2].min, dataBounds[2].max], + color0: [83, 185, 148].map(d => d / 255), + color1: [255, 255, 174].map(d => d / 255), + color2: [241, 85, 46].map(d => d / 255), + dataFrom: textureFrom, + dataTo: textureTo, + elevationTexture, + elevationBounds: ELEVATION_DATA_BOUNDS, + elevationRange: ELEVATION_RANGE, + zScale: props.zScale, + delta // TODO: looks to be 0 always , verify. + }; + + setParameters(gl, { + blend: true, + blendFunc: [gl.SRC_ALPHA, gl.ONE] + }); + const pixelStoreParameters = { + [GL.UNPACK_FLIP_Y_WEBGL]: true + }; + + textureFrom.setImageData({ + pixels: textureArray[timeInterval], + width, + height, + format: gl.RGBA32F, + type: gl.FLOAT, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + + textureTo.setImageData({ + pixels: textureArray[timeInterval + 1], + width, + height, + format: gl.RGBA32F, + type: gl.FLOAT, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + + if (state.data && state.data.img) { + elevationTexture.setImageData({ + pixels: state.data.img, + width: elevationWidth, + height: elevationHeight, + format: gl.RGBA, + type: gl.UNSIGNED_BYTE, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + } + + model.setAttributes({ + posFrom: bufferFrom + }); + + model.render(Object.assign({}, currentUniforms, uniforms)); + + // Swap the buffers + this.setState({ + bufferFrom: bufferTo, + bufferTo: bufferFrom + }); + } + + setupTransformFeedback({gl, boundingBox, nx, ny}) { + const positions4 = this.calculatePositions4({boundingBox, nx, ny}); + + const bufferFrom = new Buffer(gl, { + size: 4, data: positions4, usage: gl.DYNAMIC_COPY}); + + const bufferTo = new Buffer(gl, { + size: 4, bytes: 4 * positions4.length, usage: gl.DYNAMIC_COPY}); + + const transformFeedback = new TransformFeedback(gl, {}); + + this.setState({ + counter: 0, + bufferFrom, + bufferTo, + transformFeedback + }); + } + + runTransformFeedback({gl}) { + // Run transform feedback + const {modelTF, textureFrom, textureTo, delta} = this.state; + + const {boundingBox, originalBoundingBox} = this.props; + const {dataBounds, textureArray, textureSize} = this.props.texData; + const {width, height} = textureSize; + const timeInterval = 0; + + let now = Date.now(); + + const {bufferFrom, bufferTo} = this.state; + let {counter} = this.state; + + // onBeforeRender + const time = Date.now() - now; + let flip = time > 500 ? 1 : -1; + if (flip > 0) { + counter = (counter + 1) % 10; + flip = counter; + } + + if (flip > 0) { + flip = -1; + now = Date.now(); + } + + const pixelStoreParameters = { + [GL.UNPACK_FLIP_Y_WEBGL]: true + }; + + textureFrom.setImageData({ + pixels: textureArray[timeInterval], + width, + height, + format: gl.RGBA32F, + type: gl.FLOAT, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + + textureTo.setImageData({ + pixels: textureArray[timeInterval + 1], + width, + height, + format: gl.RGBA32F, + type: gl.FLOAT, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + + modelTF.program.use(); + const {transformFeedback} = this.state; + + modelTF.setAttributes({ + posFrom: bufferFrom + }); + + transformFeedback.bindBuffers( + { + 0: bufferTo + }, + { + clear: true + }); + + transformFeedback.begin(gl.POINTS); + + const uniforms = { + boundingBox: [ + boundingBox.minLng, boundingBox.maxLng, + boundingBox.minLat, boundingBox.maxLat + ], + originalBoundingBox: [ + originalBoundingBox.minLng, originalBoundingBox.maxLng, + originalBoundingBox.minLat, originalBoundingBox.maxLat + ], + bounds0: [dataBounds[0].min, dataBounds[0].max], + bounds1: [dataBounds[1].min, dataBounds[1].max], + bounds2: [dataBounds[2].min, dataBounds[2].max], + dataFrom: textureFrom, + dataTo: textureTo, + time, + flip, + delta // TODO: looks to be 0 always , verify. + }; + + const parameters = { + [GL.RASTERIZER_DISCARD]: true + }; + + modelTF.draw({uniforms, parameters}); + + transformFeedback.end(); + + this.setState({ + counter + }); + } + /* eslint-enable max-statements */ + + getModelTF({gl, boundingBox, originalBoundingBox, nx, ny, texData}) { + const positions3 = this.calculatePositions3({nx, ny}); + + const modelTF = new Model(gl, { + id: 'ParticleLayer-modelTF', + program: new ProgramTransformFeedback(gl, { + vs: vertexTF, + fs: fragmentTF + }), + geometry: new Geometry({ + id: this.props.id, + drawMode: GL.POINTS, + isInstanced: false, + attributes: { + positions: {size: 3, type: gl.FLOAT, value: positions3} + } + }), + isIndexed: false, + isInstanced: false + }); + + return modelTF; + } + + getModel({gl, nx, ny, texData}) { + // This will be a grid of elements + this.state.numInstances = nx * ny; + + const positions3 = this.calculatePositions3({nx, ny}); + + return new Model(gl, { + id: 'ParticleLayer-model', + vs: vertex, + fs: fragment, + geometry: new Geometry({ + id: this.props.id, + drawMode: GL.POINTS, + attributes: { + positions: {size: 3, type: GL.FLOAT, value: positions3}, + vertices: {size: 3, type: GL.FLOAT, value: positions3} + } + }), + isIndexed: false + }); + } + + getNumInstances() { + return this.state.numInstances; + } + + createTexture(gl, opt) { + const options = { + data: { + format: gl.RGBA, + value: false, + type: opt.type || gl.FLOAT, + internalFormat: opt.internalFormat || gl.RGBA32F, + width: opt.width, + height: opt.height, + border: 0 + } + }; + + if (opt.parameters) { + options.parameters = opt.parameters; + } + + return new DelaunayInterpolation({gl}) + .createTextureNew(gl, options); + } + + calculatePositions3({nx, ny}) { + const positions3 = new Float32Array(nx * ny * 3); + + for (let i = 0; i < nx; ++i) { + for (let j = 0; j < ny; ++j) { + const index3 = (i + j * nx) * 3; + positions3[index3 + 0] = 0; + positions3[index3 + 1] = 0; + positions3[index3 + 2] = Math.random() * nx; + } + } + + return positions3; + } + + calculatePositions4({boundingBox, nx, ny}) { + const diffX = boundingBox.maxLng - boundingBox.minLng; + const diffY = boundingBox.maxLat - boundingBox.minLat; + const spanX = diffX / (nx - 1); + const spanY = diffY / (ny - 1); + + const positions4 = new Float32Array(nx * ny * 4); + + for (let i = 0; i < nx; ++i) { + for (let j = 0; j < ny; ++j) { + const index4 = (i + j * nx) * 4; + positions4[index4 + 0] = i * spanX + boundingBox.minLng; + positions4[index4 + 1] = j * spanY + boundingBox.minLat; + positions4[index4 + 2] = -1; + positions4[index4 + 3] = -1; + } + } + + return positions4; + } +} + +ParticleLayer.layerName = 'ParticleLayer'; +ParticleLayer.defaultProps = defaultProps; diff --git a/examples/wind/src/layers/particle-layer/program-transform-feedback.js b/examples/wind/src/layers/particle-layer/program-transform-feedback.js new file mode 100644 index 00000000000..fb2a2a7acc4 --- /dev/null +++ b/examples/wind/src/layers/particle-layer/program-transform-feedback.js @@ -0,0 +1,18 @@ +import {Program} from 'luma.gl'; + +export default class ProgramTransformFeedback extends Program { + + _compileAndLink() { + const {gl} = this; + gl.attachShader(this.handle, this.vs.handle); + gl.attachShader(this.handle, this.fs.handle); + // enable transform feedback for this program + gl.transformFeedbackVaryings(this.handle, ['gl_Position'], gl.SEPARATE_ATTRIBS); + gl.linkProgram(this.handle); + gl.validateProgram(this.handle); + const linked = gl.getProgramParameter(this.handle, gl.LINK_STATUS); + if (!linked) { + throw new Error(`Error linking ${gl.getProgramInfoLog(this.handle)}`); + } + } +} diff --git a/examples/wind/src/layers/particle-layer/transform-feedback-fragment.glsl.js b/examples/wind/src/layers/particle-layer/transform-feedback-fragment.glsl.js new file mode 100644 index 00000000000..330eac29555 --- /dev/null +++ b/examples/wind/src/layers/particle-layer/transform-feedback-fragment.glsl.js @@ -0,0 +1,31 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME particle-feedback-fragment-shader + +#ifdef GL_ES +precision highp float; +#endif + +void main(void) { + gl_FragColor = vec4(0); +} +`; diff --git a/examples/wind/src/layers/particle-layer/transform-feedback-vertex.glsl.js b/examples/wind/src/layers/particle-layer/transform-feedback-vertex.glsl.js new file mode 100644 index 00000000000..22403fb9c67 --- /dev/null +++ b/examples/wind/src/layers/particle-layer/transform-feedback-vertex.glsl.js @@ -0,0 +1,109 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME particle-feedback-vertex-shader + +#define PI 3.1415926535 +#define PI2 1.5707963267949 +#define PI4 0.78539816339745 +#define HEIGHT_FACTOR 25. +#define EPSILON 0.013 +#define DELTA 5. +#define FACTOR .015 + +uniform sampler2D dataFrom; +uniform sampler2D dataTo; +uniform float delta; +uniform float time; + +uniform float flip; +uniform vec4 boundingBox; +uniform vec4 originalBoundingBox; +uniform vec2 bounds0; +uniform vec2 bounds1; +uniform vec2 bounds2; + +//attribute vec3 positions; +attribute vec4 posFrom; + +float rand(vec2 co){ + return fract(sin(dot(co.xy ,vec2(12.9898,78.233))) * 43758.5453); +} + +void main(void) { + // position in texture coords + float x = (posFrom.x - boundingBox.x) / (boundingBox.y - boundingBox.x); + float y = (posFrom.y - boundingBox.z) / (boundingBox.w - boundingBox.z); + vec2 coord = vec2(x, 1. - y); + vec4 texel1 = texture2D(dataFrom, coord); + vec4 texel2 = texture2D(dataTo, coord); + vec4 texel = mix(texel1, texel2, delta); + + // angle + float angle = texel.x * PI4; + float anglePast = posFrom.z; + if (angle < 0.) { + angle += PI * 2.; + } + if (anglePast > -1.) { + if (angle > anglePast && abs(angle - anglePast) > abs(angle - (anglePast + PI * 2.))) { + anglePast += PI * 2.; + } else if (angle < anglePast && abs(anglePast - angle) > abs(anglePast - (angle + PI * 2.))) { + angle += PI * 2.; + } + angle = angle * FACTOR + anglePast * (1. - FACTOR); + } + + // wind speed + float wind = 0.05 + 0.95 * (texel.y - bounds1.x) / (bounds1.y - bounds1.x); + float windPast = posFrom.w; + if (windPast > -1.) { + wind = wind * FACTOR + windPast * (1. - FACTOR); + } + + vec2 offset = vec2(cos(angle), sin(angle)) * (wind * 0.2 + 0.002); + vec2 offsetPos = posFrom.xy + offset; + + vec4 endPos = vec4(offsetPos, mod(angle, PI * 2.), wind); + + // if out of bounds then map to random position + float r1 = rand(vec2(posFrom.x, offset.x + time)); + float r2 = rand(vec2(posFrom.y, offset.y + time)); + r1 = r1 * (originalBoundingBox.y - originalBoundingBox.x) + originalBoundingBox.x; + r2 = r2 * (originalBoundingBox.w - originalBoundingBox.z) + originalBoundingBox.z; + vec2 randValues = vec2(r1, r2); + + // endPos = vec4(offsetPos, randValues); + endPos.xy = mix(offsetPos, randValues, + float(offsetPos.x < boundingBox.x || offsetPos.x > boundingBox.y || + offsetPos.y < boundingBox.z || offsetPos.y > boundingBox.w)); + endPos.xy = mix(endPos.xy, randValues, float(length(offset) < EPSILON)); + endPos.xy = mix(endPos.xy, randValues, float(texel.x == 0. && texel.y == 0. && texel.z == 0.)); + if (flip > 0.) { + if (abs(abs(fract(endPos.x)) - flip / 10.) < EPSILON) { + endPos.xy = randValues; + } + } + // endPos.xy = mix(endPos.xy, randValues, abs(flip - positions.z) <= DELTA ? 1. : 0.); + + gl_Position = endPos; +} +`; diff --git a/examples/wind/src/layers/wind-layer/wind-layer-fragment.js b/examples/wind/src/layers/wind-layer/wind-layer-fragment.js new file mode 100644 index 00000000000..39c4b79edbb --- /dev/null +++ b/examples/wind/src/layers/wind-layer/wind-layer-fragment.js @@ -0,0 +1,347 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME wind-layer-fragment-shader + +#ifdef GL_ES +precision highp float; +#endif + +#define NUM_OF_LIGHTS 2 + +varying vec4 vPosition; +varying vec4 vNormal; +varying vec4 vColor; +varying float vAltitude; + +uniform vec3 cameraPos; +uniform vec3 lightsPosition; +uniform vec2 lightsStrength; +uniform float ambientRatio; +uniform float diffuseRatio; +uniform float specularRatio; + +const float TILE_SIZE = 512.0; +const float PI = 3.1415926536; +const float WORLD_SCALE = TILE_SIZE / (PI * 2.0); + +const float PROJECT_LINEAR = 0.; +const float PROJECT_MERCATOR = 1.; +const float PROJECT_MERCATOR_OFFSETS = 2.; + +uniform float projectionMode; +uniform float projectionScale; +uniform vec4 projectionCenter; +uniform vec3 projectionPixelsPerUnit; +uniform mat4 projectionMatrix; +uniform mat4 projectionMatrixUncentered; + +#ifdef INTEL_TAN_WORKAROUND + +// All these functions are for substituting tan() function from Intel GPU only +const float TWO_PI = 6.2831854820251465; +const float PI_2 = 1.5707963705062866; +const float PI_16 = 0.1963495463132858; + +const float SIN_TABLE_0 = 0.19509032368659973; +const float SIN_TABLE_1 = 0.3826834261417389; +const float SIN_TABLE_2 = 0.5555702447891235; +const float SIN_TABLE_3 = 0.7071067690849304; + +const float COS_TABLE_0 = 0.9807852506637573; +const float COS_TABLE_1 = 0.9238795042037964; +const float COS_TABLE_2 = 0.8314695954322815; +const float COS_TABLE_3 = 0.7071067690849304; + +const float INVERSE_FACTORIAL_3 = 1.666666716337204e-01; // 1/3! +const float INVERSE_FACTORIAL_5 = 8.333333767950535e-03; // 1/5! +const float INVERSE_FACTORIAL_7 = 1.9841270113829523e-04; // 1/7! +const float INVERSE_FACTORIAL_9 = 2.75573188446287533e-06; // 1/9! + +float sin_taylor_fp32(float a) { + float r, s, t, x; + + if (a == 0.0) { + return 0.0; + } + + x = -a * a; + s = a; + r = a; + + r = r * x; + t = r * INVERSE_FACTORIAL_3; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_5; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_7; + s = s + t; + + r = r * x; + t = r * INVERSE_FACTORIAL_9; + s = s + t; + + return s; +} + +void sincos_taylor_fp32(float a, out float sin_t, out float cos_t) { + if (a == 0.0) { + sin_t = 0.0; + cos_t = 1.0; + } + sin_t = sin_taylor_fp32(a); + cos_t = sqrt(1.0 - sin_t * sin_t); +} + +float tan_fp32(float a) { + float sin_a; + float cos_a; + + if (a == 0.0) { + return 0.0; + } + + // 2pi range reduction + float z = floor(a / TWO_PI); + float r = a - TWO_PI * z; + + float t; + float q = floor(r / PI_2 + 0.5); + int j = int(q); + + if (j < -2 || j > 2) { + return 0.0 / 0.0; + } + + t = r - PI_2 * q; + + q = floor(t / PI_16 + 0.5); + int k = int(q); + int abs_k = int(abs(float(k))); + + if (abs_k > 4) { + return 0.0 / 0.0; + } else { + t = t - PI_16 * q; + } + + float u = 0.0; + float v = 0.0; + + float sin_t, cos_t; + float s, c; + sincos_taylor_fp32(t, sin_t, cos_t); + + if (k == 0) { + s = sin_t; + c = cos_t; + } else { + if (abs(float(abs_k) - 1.0) < 0.5) { + u = COS_TABLE_0; + v = SIN_TABLE_0; + } else if (abs(float(abs_k) - 2.0) < 0.5) { + u = COS_TABLE_1; + v = SIN_TABLE_1; + } else if (abs(float(abs_k) - 3.0) < 0.5) { + u = COS_TABLE_2; + v = SIN_TABLE_2; + } else if (abs(float(abs_k) - 4.0) < 0.5) { + u = COS_TABLE_3; + v = SIN_TABLE_3; + } + if (k > 0) { + s = u * sin_t + v * cos_t; + c = u * cos_t - v * sin_t; + } else { + s = u * sin_t - v * cos_t; + c = u * cos_t + v * sin_t; + } + } + + if (j == 0) { + sin_a = s; + cos_a = c; + } else if (j == 1) { + sin_a = c; + cos_a = -s; + } else if (j == -1) { + sin_a = -c; + cos_a = s; + } else { + sin_a = -s; + cos_a = -c; + } + return sin_a / cos_a; +} +#endif + +// +// Scaling offsets +// + +float project_scale(float meters) { + return meters * projectionPixelsPerUnit.x; +} + +vec2 project_scale(vec2 meters) { + return vec2( + meters.x * projectionPixelsPerUnit.x, + meters.y * projectionPixelsPerUnit.x + ); +} + +vec3 project_scale(vec3 meters) { + return vec3( + meters.x * projectionPixelsPerUnit.x, + meters.y * projectionPixelsPerUnit.x, + meters.z * projectionPixelsPerUnit.x + ); +} + +vec4 project_scale(vec4 meters) { + return vec4( + meters.x * projectionPixelsPerUnit.x, + meters.y * projectionPixelsPerUnit.x, + meters.z * projectionPixelsPerUnit.x, + meters.w + ); +} + +// +// Projecting positions +// + +// non-linear projection: lnglats => unit tile [0-1, 0-1] +vec2 project_mercator_(vec2 lnglat) { + return vec2( + radians(lnglat.x) + PI, +#ifdef INTEL_TAN_WORKAROUND + PI - log(tan_fp32(PI * 0.25 + radians(lnglat.y) * 0.5)) +#else + PI - log(tan(PI * 0.25 + radians(lnglat.y) * 0.5)) +#endif + ); +} + +vec2 project_position(vec2 position) { + if (projectionMode == PROJECT_LINEAR) { + return (position + vec2(TILE_SIZE / 2.0)) * projectionScale; + } + if (projectionMode == PROJECT_MERCATOR_OFFSETS) { + return project_scale(position); + } + // Covers projectionMode == PROJECT_MERCATOR + return project_mercator_(position) * WORLD_SCALE * projectionScale; +} + +vec3 project_position(vec3 position) { + return vec3(project_position(position.xy), project_scale(position.z) + .1); +} + +vec4 project_position(vec4 position) { + return vec4(project_position(position.xyz), position.w); +} + +// + +vec4 project_to_clipspace(vec4 position) { + if (projectionMode == PROJECT_MERCATOR_OFFSETS) { + return projectionMatrix * vec4(position.xyz, 0.0) + projectionCenter; + } + return projectionMatrix * position; +} + +// Backwards compatibility + +float scale(float position) { + return project_scale(position); +} + +vec2 scale(vec2 position) { + return project_scale(position); +} + +vec3 scale(vec3 position) { + return project_scale(position); +} + +vec4 scale(vec4 position) { + return project_scale(position); +} + +vec2 preproject(vec2 position) { + return project_position(position); +} + +vec3 preproject(vec3 position) { + return project_position(position); +} + +vec4 preproject(vec4 position) { + return project_position(position); +} + +vec4 project(vec4 position) { + return project_to_clipspace(position); +} + +float getLightWeight(vec4 position_worldspace, vec3 normals_worldspace) { + float lightWeight = 0.0; + + vec3 position_worldspace_vec3 = position_worldspace.xyz / position_worldspace.w; + vec3 normals_worldspace_vec3 = normals_worldspace.xzy; + + vec3 camera_pos_worldspace = cameraPos; + vec3 view_direction = normalize(camera_pos_worldspace - position_worldspace_vec3); + + vec3 light_position_worldspace = project_position(lightsPosition); + vec3 light_direction = normalize(light_position_worldspace - position_worldspace_vec3); + + vec3 halfway_direction = normalize(light_direction + view_direction); + float lambertian = dot(light_direction, normals_worldspace_vec3); + float specular = 0.0; + if (lambertian > 0.0) { + float specular_angle = max(dot(normals_worldspace_vec3, halfway_direction), 0.0); + specular = pow(specular_angle, 32.0); + } + lambertian = max(lambertian, 0.0); + lightWeight += + (ambientRatio + lambertian * diffuseRatio + specular * specularRatio) * + lightsStrength.x; + + return lightWeight; +} + +void main(void) { + if (vColor.a == 0.) { + discard; + } + if (vAltitude < -90.) { + discard; + } + float lightWeight = getLightWeight(vPosition, vNormal.xyz); + gl_FragColor = vec4(vColor.xyz * lightWeight, 1); +} +`; diff --git a/examples/wind/src/layers/wind-layer/wind-layer-vertex.js b/examples/wind/src/layers/wind-layer/wind-layer-vertex.js new file mode 100644 index 00000000000..392dd219fa3 --- /dev/null +++ b/examples/wind/src/layers/wind-layer/wind-layer-vertex.js @@ -0,0 +1,113 @@ +// Copyright (c) 2015 Uber Technologies, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +export default `\ +#define SHADER_NAME wind-layer-vertex-shader + +#define PI 3.1415926535 +#define PI2 1.5707963267949 +#define PI4 0.78539816339745 +#define HEIGHT_FACTOR 25. +#define ELEVATION_SCALE 80. + +uniform sampler2D dataFrom; +uniform sampler2D dataTo; +uniform sampler2D elevationTexture; +uniform float delta; + +uniform vec4 boundingBox; +uniform vec2 size; +uniform vec2 bounds0; +uniform vec2 bounds1; +uniform vec2 bounds2; +uniform vec4 elevationBounds; +uniform vec2 elevationRange; + +attribute vec3 positions; +attribute vec3 vertices; +attribute vec3 normals; + +varying vec4 vPosition; +varying vec4 vNormal; +varying vec4 vColor; +varying float vAltitude; + +float getAltitude(vec2 lngLat) { + vec2 texCoords = (lngLat - elevationBounds.xy) / (elevationBounds.zw - elevationBounds.xy); + vec4 elevation = texture2D(elevationTexture, texCoords); + + return mix(elevationRange.x, elevationRange.y, elevation.r); +} + +void main(void) { + // position in texture coords + float x = (positions.x - boundingBox.x) / (boundingBox.y - boundingBox.x); + float y = (positions.y - boundingBox.z) / (boundingBox.w - boundingBox.z); + vec2 coord = vec2(x, 1. - y); + vec4 texel1 = texture2D(dataFrom, coord); + vec4 texel2 = texture2D(dataTo, coord); + vec4 texel = mix(texel1, texel2, delta); + + // angle + float angleFrom = texel1.x * PI4; + float angleTo = texel2.x * PI4; + if (angleFrom < 0.) { + angleFrom += PI * 2.; + } + if (angleTo < 0.) { + angleTo += PI * 2.; + } + if (angleFrom < angleTo) { + if (abs(angleTo - angleFrom) > abs(angleTo - (angleFrom + PI * 2.))) { + angleFrom += PI * 2.; + } + } else { + if (abs(angleFrom - angleTo) > abs(angleFrom - (angleTo + PI * 2.))) { + angleTo += PI * 2.; + } + } + float angle = mix(angleFrom, angleTo, delta); + mat2 rotation = mat2(cos(angle), sin(angle), -sin(angle), cos(angle)); + + // wind speed in 0-1 + float wind = 0.05 + (texel.y - bounds1.x) / (bounds1.y - bounds1.x) * 0.95; + // float wind = (texel.y - bounds1.x) / (bounds1.y - bounds1.x); + float factor = wind * 4.; + vec2 vertex = rotation * vertices.xy; + vec2 normal = rotation * normals.xy; + vec2 pos = project_position(positions.xy + vertex.xy * factor); + vec3 extrudedPosition = vec3(pos.xy, 1.0); + vec4 position_worldspace = vec4(extrudedPosition, 1.0); + gl_Position = project_to_clipspace(position_worldspace); + + // temperature in 0-1 + float temp = (texel.z - bounds2.x) / (bounds2.y - bounds2.x); + temp = floor((log(temp + 1.) * 3.) * 3.) / 3.; + + vPosition = position_worldspace; + vNormal = vec4(normal, normals.z, 1); + vColor = vec4(vec3(temp, temp, 0.8), 1); + vAltitude = getAltitude(positions.xy); + // out of bounds + if (texel.x == 0. && texel.y == 0. && texel.z == 0.) { + vColor.a = 0.; + } +} +`; diff --git a/examples/wind/src/layers/wind-layer/wind-layer.js b/examples/wind/src/layers/wind-layer/wind-layer.js new file mode 100644 index 00000000000..8741c6e4b70 --- /dev/null +++ b/examples/wind/src/layers/wind-layer/wind-layer.js @@ -0,0 +1,228 @@ +/* global Image */ +import {Layer} from 'deck.gl'; +import {GL, Model, Geometry} from 'luma.gl'; + +import DelaunayInterpolation from '../delaunay-interpolation/delaunay-interpolation'; +import { + ELEVATION_DATA_IMAGE, ELEVATION_DATA_BOUNDS, ELEVATION_RANGE, LIGHT_UNIFORMS +} from '../../defaults'; + +import vertex from './wind-layer-vertex'; +import fragment from './wind-layer-fragment'; + +const defaultProps = { + boundingBox: null, + originalBoundingBox: null, + dataBounds: null, + dataTextureArray: null, + dataTextureSize: null, + time: 0 +}; + +export default class WindLayer extends Layer { + + initializeState() { + const {gl} = this.context; + const {dataTextureSize, originalBoundingBox} = this.props; + + // FIXME - Layer API for async loading + const data = {}; + const image = new Image(584, 253); + image.onload = () => { + data.img = image; + }; + image.src = ELEVATION_DATA_IMAGE; + + const model = this.getModel({gl, originalBoundingBox, nx: 80, ny: 30}); + + const elevationWidth = 584; + const elevationHeight = 253; + const elevationTexture = this.createTexture(gl, { + width: elevationWidth, + height: elevationHeight, + parameters: [ + {name: gl.TEXTURE_MAG_FILTER, value: gl.LINEAR}, + {name: gl.TEXTURE_MIN_FILTER, value: gl.LINEAR}, + {name: gl.TEXTURE_WRAP_S, value: gl.CLAMP_TO_EDGE}, + {name: gl.TEXTURE_WRAP_T, value: gl.CLAMP_TO_EDGE} + ] + }); + + const {width, height} = dataTextureSize; + const textureFrom = this.createTexture(gl, {width, height}); + const textureTo = this.createTexture(gl, {width, height}); + + this.setState({ + model, data, + elevationTexture, elevationWidth, elevationHeight, + textureFrom, textureTo, width, height + }); + } + + updateState({props, oldProps, changeFlags: {dataChanged, somethingChanged}}) { + this.updateTime(); + } + + updateTime() { + const {time} = this.props; + const timeInterval = Math.floor(time); + this.setState({ + timeInterval, + delta: time - timeInterval + }); + } + + getNumInstances() { + return this.state.numInstances; + } + + /* eslint-disable max-statements */ + draw({uniforms}) { + const {gl} = this.context; + + const { + model, data, + elevationTexture, elevationWidth, elevationHeight, + textureFrom, textureTo, width, height, + delta, timeInterval + } = this.state; + + const {boundingBox, dataBounds, dataTextureArray} = this.props; + const pixelStoreParameters = { + [GL.UNPACK_FLIP_Y_WEBGL]: true + }; + + textureFrom.setImageData({ + pixels: dataTextureArray[timeInterval | 0], + width, + height, + format: gl.RGBA32F, + type: gl.FLOAT, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + + textureTo.setImageData({ + pixels: dataTextureArray[timeInterval | 0 + 1], + width, + height, + format: gl.RGBA32F, + type: gl.FLOAT, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + + if (data && data.img) { + elevationTexture.setImageData({ + pixels: data.img, + width: elevationWidth, + height: elevationHeight, + format: gl.RGBA, + type: gl.UNSIGNED_BYTE, + dataFormat: gl.RGBA, + parameters: pixelStoreParameters + }); + } + + const parameters = { + clearDepth: 1.0, + depth: true, + depthFunc: gl.LEQUAL + }; + + uniforms = Object.assign({}, uniforms, LIGHT_UNIFORMS, { + boundingBox: [boundingBox.minLng, boundingBox.maxLng, boundingBox.minLat, boundingBox.maxLat], + size: [width, height], + delta, + bounds0: [dataBounds[0].min, dataBounds[0].max], + bounds1: [dataBounds[1].min, dataBounds[1].max], + bounds2: [dataBounds[2].min, dataBounds[2].max], + dataFrom: textureFrom, + dataTo: textureTo, + elevationTexture, + elevationBounds: ELEVATION_DATA_BOUNDS, + elevationRange: ELEVATION_RANGE + }); + + model.draw({uniforms, parameters}); + + // onAfterRender + gl.bindTexture(gl.TEXTURE_2D, null); + } + /* eslint-enable max-statements */ + + getModel({gl, originalBoundingBox, nx, ny}) { + // This will be a grid of elements + this.state.numInstances = nx * ny; + + const positions = this.calculatePositions({nx, ny, originalBoundingBox}); + const vertices = new Float32Array([0.3, 0, 250, 0, 0.10, 0, 1, 0, 0, 0, -0.10, 0, 0, 0.10, 0]); + const normals = new Float32Array([0, 0, 1, 0, 0.10, 0, 1, 0, 0, 0, -0.10, 0, 0, 0.10, 0]); + + const geometry = new Geometry({ + id: this.props.id, + drawMode: GL.TRIANGLE_FAN, + isInstanced: true, + instanceCount: 1, + attributes: { + positions: {size: 3, type: gl.FLOAT, value: positions, instanced: 1}, + vertices: {size: 3, type: gl.FLOAT, value: vertices}, + normals: {size: 3, type: gl.FLOAT, value: normals} + } + }); + + return new Model(gl, { + vs: vertex, + fs: fragment, + modules: ['project'], + isIndexed: false, + isInstanced: true, + geometry + }); + } + + createTexture(gl, opt) { + const options = { + data: { + format: gl.RGBA, + value: false, + type: opt.type || gl.FLOAT, + internalFormat: opt.internalFormat || gl.RGBA32F, + width: opt.width, + height: opt.height, + border: 0 + } + }; + + if (opt.parameters) { + options.parameters = opt.parameters; + } + + return new DelaunayInterpolation({gl}) + .createTextureNew(gl, options); + } + + calculatePositions({nx, ny, originalBoundingBox}) { + const diffX = originalBoundingBox.maxLng - originalBoundingBox.minLng; + const diffY = originalBoundingBox.maxLat - originalBoundingBox.minLat; + const spanX = diffX / (nx - 1); + const spanY = diffY / (ny - 1); + + const positions = new Float32Array(nx * ny * 3); + + // build lines for the vector field + for (let i = 0; i < nx; ++i) { + for (let j = 0; j < ny; ++j) { + const index = (i + j * nx) * 3; + positions[index + 0] = i * spanX + originalBoundingBox.minLng + ((j % 2) ? spanX / 2 : 0); + positions[index + 1] = j * spanY + originalBoundingBox.minLat; + positions[index + 2] = 0; + } + } + + return positions; + } +} + +WindLayer.layerName = 'WindLayer'; +WindLayer.defaultProps = defaultProps; diff --git a/examples/wind/src/utils/load-data.js b/examples/wind/src/utils/load-data.js new file mode 100644 index 00000000000..9f1e0230338 --- /dev/null +++ b/examples/wind/src/utils/load-data.js @@ -0,0 +1,148 @@ +import {request, json} from 'd3-request'; +import {voronoi} from 'd3-voronoi'; +import DelaunayInterpolation from '../layers/delaunay-interpolation/delaunay-interpolation'; +import {MARGIN, SAMPLE} from '../defaults'; + +const STATIONS_DATA_URL = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/wind/stations.json'; // eslint-disable-line +const WEATHER_DATA_URL = 'https://raw.githubusercontent.com/uber-common/deck.gl-data/master/examples/wind/weather.bin'; // eslint-disable-line + +export function loadData() { + return Promise.all([ + loadStations(), + loadWeatherData() + ]) + .then(([stations, weather]) => { + const boundingBox = getBBox(stations); + const triangulation = triangulate(stations); + const delaunayInterpolation = new DelaunayInterpolation({ + boundingBox, + triangulation, + measures: weather, + textureWidth: 1024 + }); + const texData = delaunayInterpolation.generateTextures(); + + return { + stations, + weather, + boundingBox, + triangulation, + texData + }; + }); +} + +function loadStations() { + return new Promise((resolve, reject) => { + json(STATIONS_DATA_URL) + .on('load', (stations) => { + // add four dummy stations at the end + const boundingBox = getBBox(stations); + const boundingBoxMargin = { + minLat: boundingBox.minLat - MARGIN, + maxLat: boundingBox.maxLat + MARGIN, + minLng: boundingBox.minLng - MARGIN, + maxLng: boundingBox.maxLng + MARGIN + }; + const centroid = { + long: (boundingBoxMargin.maxLng + boundingBoxMargin.minLng) / 2, + lat: (boundingBoxMargin.maxLat + boundingBoxMargin.minLat) / 2 + }; + const a = (boundingBoxMargin.maxLng - boundingBoxMargin.minLng) / 2; + const b = (boundingBoxMargin.maxLat - boundingBoxMargin.minLat) / 2; + const dummy = Array.from(Array(SAMPLE)).map((_, i) => { + const angle = Math.PI * 2 / SAMPLE * i; + const long = -(Math.cos(angle) * a + centroid.long); + const lat = Math.sin(angle) * b + centroid.lat; + return {long, lat, elv: 10}; + }); + resolve(stations.concat(dummy)); + }) + .on('error', reject) + .get(); + }); +} + +function loadWeatherData() { + return new Promise((resolve, reject) => { + request(WEATHER_DATA_URL) + .responseType('arraybuffer') + .on('load', req => { + resolve(parseData(req.response)); + }) + .on('error', reject) + .get(); + }); +} + +function getBBox(data) { + let minLat = Infinity; + let maxLat = -Infinity; + let minLng = Infinity; + let maxLng = -Infinity; + + data.forEach(d => { + minLat = d.lat < minLat ? d.lat : minLat; + minLng = -d.long < minLng ? -d.long : minLng; + maxLat = d.lat > maxLat ? d.lat : maxLat; + maxLng = -d.long > maxLng ? -d.long : maxLng; + }); + + return {minLat, minLng, maxLat, maxLng}; +} + +function triangulate(data) { + data.forEach((d, i) => { + d.index = i; + }); + return voronoi(data) + .x(d => -d.long) + .y(d => d.lat) + .triangles(data); +} + +function parseData(buffer) { + const bufferData = new Uint16Array(buffer); + const hours = 72; + const components = 3; + const l = bufferData.length / (hours * components); + const hourlyData = Array(hours); + + for (let i = 0; i < hours; ++i) { + hourlyData[i] = createHourlyData(bufferData, i, l, hours, components); + } + + return hourlyData; +} + +function createHourlyData(bufferData, i, l, hours, components) { + const array = []; // add four dummy stations + + let count = 0; + for (let j = i * components; count < l; j += (hours * components)) { + count++; + array.push(new Float32Array([ + bufferData[j + 0], + bufferData[j + 1], + bufferData[j + 2] + ])); + } + // four dummy stations all point towards the centroid of the states + // array.push(new Float32Array([ 1,0,0]), + // new Float32Array([ 7,0,0]), + // new Float32Array([ 3,0,0]), + // new Float32Array([ 5,0,0])); + + // four dummy stations all point against the centroid of the states + // array.push(new Float32Array([ 5,10,10]), + // new Float32Array([ 3,10,10]), + // new Float32Array([ 7,10,10]), + // new Float32Array([ 1,10,10])); + + Array.from(Array(SAMPLE)).forEach((_, i) => { // eslint-disable-line + const angle = Math.round(((Math.PI * 2 / SAMPLE * i) % (Math.PI * 2)) / (Math.PI / 4)); + array.push(new Float32Array([angle, 0, 0])); + }); + + return array; +} diff --git a/examples/wind/src/wind-demo.js b/examples/wind/src/wind-demo.js new file mode 100644 index 00000000000..e101c745534 --- /dev/null +++ b/examples/wind/src/wind-demo.js @@ -0,0 +1,126 @@ +/* global, window */ +import React, {Component, PropTypes} from 'react'; +import DeckGL, {ScatterplotLayer} from 'deck.gl'; + +import WindLayer from './layers/wind-layer/wind-layer'; +import ElevationLayer from './layers/elevation-layer/elevation-layer'; +import ParticleLayer from './layers/particle-layer/particle-layer'; + +import {loadData} from './utils/load-data'; +import {MARGIN, SAMPLE} from './defaults'; + +import TWEEN from 'tween.js'; + +const propTypes = { + viewport: PropTypes.object.isRequired, + settings: PropTypes.object.isRequired +}; + +export default class WindDemo extends Component { + + constructor(props) { + super(props); + + this.state = { + data: null + }; + + const particleState = {particleTime: 0}; + this._particleAnimation = new TWEEN.Tween(particleState) + .to({particleTime: 60}, 1000) + .onUpdate(() => this.setState(particleState)) + .repeat(Infinity); + } + + componentDidMount() { + loadData().then(data => { + this.setState({data}); + }); + + if (this.props.settings.showParticles) { + this._particleAnimation.start(); + } + } + + componentWillReceiveProps(nextProps) { + const {settings: {showParticles}} = nextProps; + if (this.props.settings.showParticles !== showParticles) { + if (showParticles) { + this._particleAnimation.start(); + } else { + this._particleAnimation.stop(); + } + } + } + + componentWillUnmount() { + this._particleAnimation.stop(); + } + + render() { + const {viewport, settings} = this.props; + const {data} = this.state; + + if (!data) { + return null; + } + + const {stations, triangulation, texData, boundingBox} = data; + + // FIXME - calculate slice and bounding box when loaded, not in render + const newStations = stations.slice(0, -SAMPLE); + const originalBoundingBox = { + minLng: boundingBox.minLng + MARGIN, + maxLng: boundingBox.maxLng - MARGIN, + minLat: boundingBox.minLat + MARGIN, + maxLat: boundingBox.maxLat - MARGIN + }; + + const layers = [ + new ScatterplotLayer({ + id: 'stations', + data: newStations, + getPosition: d => [-d.long, d.lat, d.elv], + getColor: d => [200, 200, 100], + getRadius: d => 150, + opacity: 0.2 + }), + settings.showParticles && new ParticleLayer({ + id: 'particles', + boundingBox, + originalBoundingBox, + texData, + time: settings.time, + zScale: 100 + }), + settings.showWind && new WindLayer({ + id: 'wind', + boundingBox, + originalBoundingBox, + dataBounds: texData.dataBounds, + dataTextureArray: texData.textureArray, + dataTextureSize: texData.textureSize, + time: settings.time + }), + settings.showElevation && new ElevationLayer({ + id: 'elevation', + boundingBox, + triangulation, + lngResolution: 200, + latResolution: 100, + zScale: 100 + }) + // FIXME - deck.gl should automatically cull null/false layers + ].filter(Boolean); + + return ( + + ); + } +} + +WindDemo.propTypes = propTypes; diff --git a/examples/wind/static/index.html b/examples/wind/static/index.html new file mode 100644 index 00000000000..51d237b99cd --- /dev/null +++ b/examples/wind/static/index.html @@ -0,0 +1,11 @@ + + + + + Wind / deck.gl + + + + + + diff --git a/examples/wind/static/style.css b/examples/wind/static/style.css new file mode 100644 index 00000000000..f9c33d81c40 --- /dev/null +++ b/examples/wind/static/style.css @@ -0,0 +1,56 @@ +* { + box-sizing: border-box; +} + +body { + font-family: "Helvetica Neue", Helvetica, sans-serif !important; + font-size: 11px; + padding: 0; + margin: 0; + color: #fff; + background: #111; + overflow: hidden; +} + +a, a:visited { + color: #08f; + text-decoration: none; + font-style: italic; +} +a:hover { + text-decoration: underline; +} + +.control-panel { + position: fixed; + top: 20px; + left: 20px; + padding: 12px; + width: 320px; + background: rgba(40,40,40,0.8); + box-shadow: 0 0 4px rgba(0, 0, 0, 0.5); +} + +hr { + margin: 24px 0; + border-color: #888; + opacity: 0.3; +} + +.input label { + min-width: 60px; + margin-right: 8px; + display: inline-block; + line-height: 24px; + text-transform: uppercase; +} + +ul { + margin: 0; + padding: 0 0 0 12px; +} + +li { + margin: 9px; + list-style-type: square; +} diff --git a/examples/wind/webpack.config.js b/examples/wind/webpack.config.js new file mode 100644 index 00000000000..46282e6e48b --- /dev/null +++ b/examples/wind/webpack.config.js @@ -0,0 +1,40 @@ +const {resolve} = require('path'); +const webpack = require('webpack'); + +const CONFIG = { + entry: { + app: resolve('./src/app.js') + }, + + devtool: 'source-maps', + + output: { + path: resolve('./dist'), + filename: 'bundle.js' + }, + module: { + rules: [{ + test: /\.js$/, + loader: 'babel-loader', + include: resolve('./src') + }, { + include: [resolve('./src')], + loader: 'transform-loader', + query: 'brfs-babel' + }] + }, + + resolve: { + alias: { + 'mapbox-gl$': resolve('./node_modules/mapbox-gl/dist/mapbox-gl.js') + } + }, + + // Optional: Enables reading mapbox token from environment variable + plugins: [ + new webpack.EnvironmentPlugin(['MapboxAccessToken']) + ] +}; + +// This line enables bundling against src in this repo rather than installed deck.gl module +module.exports = env => env ? require('../webpack.config.local')(CONFIG)(env) : CONFIG; diff --git a/examples/wind/yarn.lock b/examples/wind/yarn.lock new file mode 100644 index 00000000000..dd1ae5c62d1 --- /dev/null +++ b/examples/wind/yarn.lock @@ -0,0 +1,3977 @@ +# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY. +# yarn lockfile v1 + + +"JSV@>= 4.0.x": + version "4.0.2" + resolved "https://registry.yarnpkg.com/JSV/-/JSV-4.0.2.tgz#d077f6825571f82132f9dffaed587b4029feff57" + +abbrev@1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/abbrev/-/abbrev-1.1.0.tgz#d0554c2256636e2f56e7c2e5ad183f859428d81f" + +accepts@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/accepts/-/accepts-1.3.3.tgz#c3ca7434938648c3e0d9c1e328dd68b622c284ca" + dependencies: + mime-types "~2.1.11" + negotiator "0.6.1" + +acorn-dynamic-import@^2.0.0: + version "2.0.2" + resolved "https://registry.yarnpkg.com/acorn-dynamic-import/-/acorn-dynamic-import-2.0.2.tgz#c752bd210bef679501b6c6cb7fc84f8f47158cc4" + dependencies: + acorn "^4.0.3" + +acorn@^1.0.3: + version "1.2.2" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-1.2.2.tgz#c8ce27de0acc76d896d2b1fad3df588d9e82f014" + +acorn@^4.0.0, acorn@^4.0.3, acorn@^4.0.4: + version "4.0.11" + resolved "https://registry.yarnpkg.com/acorn/-/acorn-4.0.11.tgz#edcda3bd937e7556410d42ed5860f67399c794c0" + +ajv-keywords@^1.1.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/ajv-keywords/-/ajv-keywords-1.5.1.tgz#314dd0a4b3368fad3dfcdc54ede6171b886daf3c" + +ajv@^4.7.0, ajv@^4.9.1: + version "4.11.4" + resolved "https://registry.yarnpkg.com/ajv/-/ajv-4.11.4.tgz#ebf3a55d4b132ea60ff5847ae85d2ef069960b45" + dependencies: + co "^4.6.0" + json-stable-stringify "^1.0.1" + +align-text@^0.1.1, align-text@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/align-text/-/align-text-0.1.4.tgz#0cd90a561093f35d0a99256c22b7069433fad117" + dependencies: + kind-of "^3.0.2" + longest "^1.0.1" + repeat-string "^1.5.2" + +amdefine@>=0.0.4: + version "1.0.1" + resolved "https://registry.yarnpkg.com/amdefine/-/amdefine-1.0.1.tgz#4a5282ac164729e93619bcfd3ad151f817ce91f5" + +ansi-html@0.0.7: + version "0.0.7" + resolved "https://registry.yarnpkg.com/ansi-html/-/ansi-html-0.0.7.tgz#813584021962a9e9e6fd039f940d12f56ca7859e" + +ansi-regex@^2.0.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df" + +ansi-styles@^2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe" + +ansi-styles@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-1.0.0.tgz#cb102df1c56f5123eab8b67cd7b98027a0279178" + +anymatch@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/anymatch/-/anymatch-1.3.0.tgz#a3e52fa39168c825ff57b0248126ce5a8ff95507" + dependencies: + arrify "^1.0.0" + micromatch "^2.1.5" + +aproba@^1.0.3: + version "1.1.1" + resolved "https://registry.yarnpkg.com/aproba/-/aproba-1.1.1.tgz#95d3600f07710aa0e9298c726ad5ecf2eacbabab" + +are-we-there-yet@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/are-we-there-yet/-/are-we-there-yet-1.1.2.tgz#80e470e95a084794fe1899262c5667c6e88de1b3" + dependencies: + delegates "^1.0.0" + readable-stream "^2.0.0 || ^1.1.13" + +arr-diff@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/arr-diff/-/arr-diff-2.0.0.tgz#8f3b827f955a8bd669697e4a4256ac3ceae356cf" + dependencies: + arr-flatten "^1.0.1" + +arr-flatten@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arr-flatten/-/arr-flatten-1.0.1.tgz#e5ffe54d45e19f32f216e91eb99c8ce892bb604b" + +array-flatten@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/array-flatten/-/array-flatten-1.1.1.tgz#9a5f699051b1e7073328f2a008968b64ea2955d2" + +array-unique@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/array-unique/-/array-unique-0.2.1.tgz#a1d97ccafcbc2625cc70fadceb36a50c58b01a53" + +arrify@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/arrify/-/arrify-1.0.1.tgz#898508da2226f380df904728456849c1501a4b0d" + +asap@~2.0.3: + version "2.0.5" + resolved "https://registry.yarnpkg.com/asap/-/asap-2.0.5.tgz#522765b50c3510490e52d7dcfe085ef9ba96958f" + +asn1.js@^4.0.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/asn1.js/-/asn1.js-4.9.1.tgz#48ba240b45a9280e94748990ba597d216617fd40" + dependencies: + bn.js "^4.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +asn1@~0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86" + +assert-plus@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.2.0.tgz#d74e1b87e7affc0db8aadb7021f3fe48101ab234" + +assert-plus@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525" + +assert@^1.1.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/assert/-/assert-1.4.1.tgz#99912d591836b5a6f5b345c0f07eefc08fc65d91" + dependencies: + util "0.10.3" + +async-each@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/async-each/-/async-each-1.0.1.tgz#19d386a1d9edc6e7c1c85d388aedbcc56d33602d" + +async@^1.5.2: + version "1.5.2" + resolved "https://registry.yarnpkg.com/async/-/async-1.5.2.tgz#ec6a61ae56480c0c3cb241c95618e20892f9672a" + +async@^2.1.2: + version "2.1.5" + resolved "https://registry.yarnpkg.com/async/-/async-2.1.5.tgz#e587c68580994ac67fc56ff86d3ac56bdbe810bc" + dependencies: + lodash "^4.14.0" + +asynckit@^0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79" + +autobind-decorator@^1.3.3: + version "1.3.4" + resolved "https://registry.yarnpkg.com/autobind-decorator/-/autobind-decorator-1.3.4.tgz#b67560e6bbbb68a35c049c82d6351ea0e82d820d" + +aws-sign2@~0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.6.0.tgz#14342dd38dbcc94d0e5b87d763cd63612c0e794f" + +aws4@^1.2.1: + version "1.6.0" + resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e" + +babel-code-frame@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-code-frame/-/babel-code-frame-6.22.0.tgz#027620bee567a88c32561574e7fd0801d33118e4" + dependencies: + chalk "^1.1.0" + esutils "^2.0.2" + js-tokens "^3.0.0" + +babel-core@^6.21.0, babel-core@^6.23.0, babel-core@^6.4.0: + version "6.23.1" + resolved "https://registry.yarnpkg.com/babel-core/-/babel-core-6.23.1.tgz#c143cb621bb2f621710c220c5d579d15b8a442df" + dependencies: + babel-code-frame "^6.22.0" + babel-generator "^6.23.0" + babel-helpers "^6.23.0" + babel-messages "^6.23.0" + babel-register "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.1" + babel-types "^6.23.0" + babylon "^6.11.0" + convert-source-map "^1.1.0" + debug "^2.1.1" + json5 "^0.5.0" + lodash "^4.2.0" + minimatch "^3.0.2" + path-is-absolute "^1.0.0" + private "^0.1.6" + slash "^1.0.0" + source-map "^0.5.0" + +babel-generator@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-generator/-/babel-generator-6.23.0.tgz#6b8edab956ef3116f79d8c84c5a3c05f32a74bc5" + dependencies: + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.23.0" + detect-indent "^4.0.0" + jsesc "^1.3.0" + lodash "^4.2.0" + source-map "^0.5.0" + trim-right "^1.0.1" + +babel-helper-bindify-decorators@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-bindify-decorators/-/babel-helper-bindify-decorators-6.22.0.tgz#d7f5bc261275941ac62acfc4e20dacfb8a3fe952" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-builder-binary-assignment-operator-visitor@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-binary-assignment-operator-visitor/-/babel-helper-builder-binary-assignment-operator-visitor-6.22.0.tgz#29df56be144d81bdeac08262bfa41d2c5e91cdcd" + dependencies: + babel-helper-explode-assignable-expression "^6.22.0" + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-helper-builder-react-jsx@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helper-builder-react-jsx/-/babel-helper-builder-react-jsx-6.23.0.tgz#d53fc8c996e0bc56d0de0fc4cc55a7138395ea4b" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.23.0" + esutils "^2.0.0" + lodash "^4.2.0" + +babel-helper-call-delegate@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-call-delegate/-/babel-helper-call-delegate-6.22.0.tgz#119921b56120f17e9dae3f74b4f5cc7bcc1b37ef" + dependencies: + babel-helper-hoist-variables "^6.22.0" + babel-runtime "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-define-map@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helper-define-map/-/babel-helper-define-map-6.23.0.tgz#1444f960c9691d69a2ced6a205315f8fd00804e7" + dependencies: + babel-helper-function-name "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.23.0" + lodash "^4.2.0" + +babel-helper-explode-assignable-expression@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-assignable-expression/-/babel-helper-explode-assignable-expression-6.22.0.tgz#c97bf76eed3e0bae4048121f2b9dae1a4e7d0478" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-explode-class@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-explode-class/-/babel-helper-explode-class-6.22.0.tgz#646304924aa6388a516843ba7f1855ef8dfeb69b" + dependencies: + babel-helper-bindify-decorators "^6.22.0" + babel-runtime "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-function-name@^6.22.0, babel-helper-function-name@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helper-function-name/-/babel-helper-function-name-6.23.0.tgz#25742d67175c8903dbe4b6cb9d9e1fcb8dcf23a6" + dependencies: + babel-helper-get-function-arity "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + +babel-helper-get-function-arity@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-get-function-arity/-/babel-helper-get-function-arity-6.22.0.tgz#0beb464ad69dc7347410ac6ade9f03a50634f5ce" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-helper-hoist-variables@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-hoist-variables/-/babel-helper-hoist-variables-6.22.0.tgz#3eacbf731d80705845dd2e9718f600cfb9b4ba72" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-helper-optimise-call-expression@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helper-optimise-call-expression/-/babel-helper-optimise-call-expression-6.23.0.tgz#f3ee7eed355b4282138b33d02b78369e470622f5" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.23.0" + +babel-helper-regex@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-regex/-/babel-helper-regex-6.22.0.tgz#79f532be1647b1f0ee3474b5f5c3da58001d247d" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + lodash "^4.2.0" + +babel-helper-remap-async-to-generator@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-helper-remap-async-to-generator/-/babel-helper-remap-async-to-generator-6.22.0.tgz#2186ae73278ed03b8b15ced089609da981053383" + dependencies: + babel-helper-function-name "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.22.0" + babel-traverse "^6.22.0" + babel-types "^6.22.0" + +babel-helper-replace-supers@^6.22.0, babel-helper-replace-supers@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helper-replace-supers/-/babel-helper-replace-supers-6.23.0.tgz#eeaf8ad9b58ec4337ca94223bacdca1f8d9b4bfd" + dependencies: + babel-helper-optimise-call-expression "^6.23.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + +babel-helpers@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-helpers/-/babel-helpers-6.23.0.tgz#4f8f2e092d0b6a8808a4bde79c27f1e2ecf0d992" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.23.0" + +babel-loader@^6.2.10: + version "6.4.0" + resolved "https://registry.yarnpkg.com/babel-loader/-/babel-loader-6.4.0.tgz#e98c239662a22533b9e7a49594ef216d7635ea28" + dependencies: + find-cache-dir "^0.1.1" + loader-utils "^0.2.16" + mkdirp "^0.5.1" + object-assign "^4.0.1" + +babel-messages@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-messages/-/babel-messages-6.23.0.tgz#f3cdf4703858035b2a2951c6ec5edf6c62f2630e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-check-es2015-constants@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-check-es2015-constants/-/babel-plugin-check-es2015-constants-6.22.0.tgz#35157b101426fd2ffd3da3f75c7d1e91835bbf8a" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-static-fs@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/babel-plugin-static-fs/-/babel-plugin-static-fs-1.1.0.tgz#812aedc06297e90beab8ed02f2a69acdcca23c05" + dependencies: + babel-template "^6.3.13" + babel-types "^6.4.1" + events "^1.1.0" + +babel-plugin-syntax-async-functions@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-functions/-/babel-plugin-syntax-async-functions-6.13.0.tgz#cad9cad1191b5ad634bf30ae0872391e0647be95" + +babel-plugin-syntax-async-generators@^6.5.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-async-generators/-/babel-plugin-syntax-async-generators-6.13.0.tgz#6bc963ebb16eccbae6b92b596eb7f35c342a8b9a" + +babel-plugin-syntax-class-properties@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-class-properties/-/babel-plugin-syntax-class-properties-6.13.0.tgz#d7eb23b79a317f8543962c505b827c7d6cac27de" + +babel-plugin-syntax-decorators@^6.13.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-decorators/-/babel-plugin-syntax-decorators-6.13.0.tgz#312563b4dbde3cc806cee3e416cceeaddd11ac0b" + +babel-plugin-syntax-dynamic-import@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-dynamic-import/-/babel-plugin-syntax-dynamic-import-6.18.0.tgz#8d6a26229c83745a9982a441051572caa179b1da" + +babel-plugin-syntax-exponentiation-operator@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-exponentiation-operator/-/babel-plugin-syntax-exponentiation-operator-6.13.0.tgz#9ee7e8337290da95288201a6a57f4170317830de" + +babel-plugin-syntax-flow@^6.18.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-flow/-/babel-plugin-syntax-flow-6.18.0.tgz#4c3ab20a2af26aa20cd25995c398c4eb70310c8d" + +babel-plugin-syntax-jsx@^6.3.13, babel-plugin-syntax-jsx@^6.8.0: + version "6.18.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-jsx/-/babel-plugin-syntax-jsx-6.18.0.tgz#0af32a9a6e13ca7a3fd5069e62d7b0f58d0d8946" + +babel-plugin-syntax-object-rest-spread@^6.8.0: + version "6.13.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-object-rest-spread/-/babel-plugin-syntax-object-rest-spread-6.13.0.tgz#fd6536f2bce13836ffa3a5458c4903a597bb3bf5" + +babel-plugin-syntax-trailing-function-commas@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-syntax-trailing-function-commas/-/babel-plugin-syntax-trailing-function-commas-6.22.0.tgz#ba0360937f8d06e40180a43fe0d5616fff532cf3" + +babel-plugin-transform-async-generator-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-generator-functions/-/babel-plugin-transform-async-generator-functions-6.22.0.tgz#a720a98153a7596f204099cd5409f4b3c05bab46" + dependencies: + babel-helper-remap-async-to-generator "^6.22.0" + babel-plugin-syntax-async-generators "^6.5.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-async-to-generator@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-async-to-generator/-/babel-plugin-transform-async-to-generator-6.22.0.tgz#194b6938ec195ad36efc4c33a971acf00d8cd35e" + dependencies: + babel-helper-remap-async-to-generator "^6.22.0" + babel-plugin-syntax-async-functions "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-class-properties@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-class-properties/-/babel-plugin-transform-class-properties-6.23.0.tgz#187b747ee404399013563c993db038f34754ac3b" + dependencies: + babel-helper-function-name "^6.23.0" + babel-plugin-syntax-class-properties "^6.8.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + +babel-plugin-transform-decorators@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-decorators/-/babel-plugin-transform-decorators-6.22.0.tgz#c03635b27a23b23b7224f49232c237a73988d27c" + dependencies: + babel-helper-explode-class "^6.22.0" + babel-plugin-syntax-decorators "^6.13.0" + babel-runtime "^6.22.0" + babel-template "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-arrow-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-arrow-functions/-/babel-plugin-transform-es2015-arrow-functions-6.22.0.tgz#452692cb711d5f79dc7f85e440ce41b9f244d221" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoped-functions@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoped-functions/-/babel-plugin-transform-es2015-block-scoped-functions-6.22.0.tgz#bbc51b49f964d70cb8d8e0b94e820246ce3a6141" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-block-scoping@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-block-scoping/-/babel-plugin-transform-es2015-block-scoping-6.23.0.tgz#e48895cf0b375be148cd7c8879b422707a053b51" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + lodash "^4.2.0" + +babel-plugin-transform-es2015-classes@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-classes/-/babel-plugin-transform-es2015-classes-6.23.0.tgz#49b53f326202a2fd1b3bbaa5e2edd8a4f78643c1" + dependencies: + babel-helper-define-map "^6.23.0" + babel-helper-function-name "^6.23.0" + babel-helper-optimise-call-expression "^6.23.0" + babel-helper-replace-supers "^6.23.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + +babel-plugin-transform-es2015-computed-properties@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-computed-properties/-/babel-plugin-transform-es2015-computed-properties-6.22.0.tgz#7c383e9629bba4820c11b0425bdd6290f7f057e7" + dependencies: + babel-runtime "^6.22.0" + babel-template "^6.22.0" + +babel-plugin-transform-es2015-destructuring@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-destructuring/-/babel-plugin-transform-es2015-destructuring-6.23.0.tgz#997bb1f1ab967f682d2b0876fe358d60e765c56d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-duplicate-keys@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-duplicate-keys/-/babel-plugin-transform-es2015-duplicate-keys-6.22.0.tgz#672397031c21610d72dd2bbb0ba9fb6277e1c36b" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-for-of@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-for-of/-/babel-plugin-transform-es2015-for-of-6.23.0.tgz#f47c95b2b613df1d3ecc2fdb7573623c75248691" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-function-name@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-function-name/-/babel-plugin-transform-es2015-function-name-6.22.0.tgz#f5fcc8b09093f9a23c76ac3d9e392c3ec4b77104" + dependencies: + babel-helper-function-name "^6.22.0" + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-literals/-/babel-plugin-transform-es2015-literals-6.22.0.tgz#4f54a02d6cd66cf915280019a31d31925377ca2e" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-modules-amd@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-amd/-/babel-plugin-transform-es2015-modules-amd-6.22.0.tgz#bf69cd34889a41c33d90dfb740e0091ccff52f21" + dependencies: + babel-plugin-transform-es2015-modules-commonjs "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.22.0" + +babel-plugin-transform-es2015-modules-commonjs@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-commonjs/-/babel-plugin-transform-es2015-modules-commonjs-6.23.0.tgz#cba7aa6379fb7ec99250e6d46de2973aaffa7b92" + dependencies: + babel-plugin-transform-strict-mode "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-types "^6.23.0" + +babel-plugin-transform-es2015-modules-systemjs@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-systemjs/-/babel-plugin-transform-es2015-modules-systemjs-6.23.0.tgz#ae3469227ffac39b0310d90fec73bfdc4f6317b0" + dependencies: + babel-helper-hoist-variables "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + +babel-plugin-transform-es2015-modules-umd@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-modules-umd/-/babel-plugin-transform-es2015-modules-umd-6.23.0.tgz#8d284ae2e19ed8fe21d2b1b26d6e7e0fcd94f0f1" + dependencies: + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + +babel-plugin-transform-es2015-object-super@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-object-super/-/babel-plugin-transform-es2015-object-super-6.22.0.tgz#daa60e114a042ea769dd53fe528fc82311eb98fc" + dependencies: + babel-helper-replace-supers "^6.22.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-parameters@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-parameters/-/babel-plugin-transform-es2015-parameters-6.23.0.tgz#3a2aabb70c8af945d5ce386f1a4250625a83ae3b" + dependencies: + babel-helper-call-delegate "^6.22.0" + babel-helper-get-function-arity "^6.22.0" + babel-runtime "^6.22.0" + babel-template "^6.23.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + +babel-plugin-transform-es2015-shorthand-properties@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-shorthand-properties/-/babel-plugin-transform-es2015-shorthand-properties-6.22.0.tgz#8ba776e0affaa60bff21e921403b8a652a2ff723" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-spread@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-spread/-/babel-plugin-transform-es2015-spread-6.22.0.tgz#d6d68a99f89aedc4536c81a542e8dd9f1746f8d1" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-sticky-regex@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-sticky-regex/-/babel-plugin-transform-es2015-sticky-regex-6.22.0.tgz#ab316829e866ee3f4b9eb96939757d19a5bc4593" + dependencies: + babel-helper-regex "^6.22.0" + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-plugin-transform-es2015-template-literals@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-template-literals/-/babel-plugin-transform-es2015-template-literals-6.22.0.tgz#a84b3450f7e9f8f1f6839d6d687da84bb1236d8d" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-typeof-symbol@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-typeof-symbol/-/babel-plugin-transform-es2015-typeof-symbol-6.23.0.tgz#dec09f1cddff94b52ac73d505c84df59dcceb372" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-es2015-unicode-regex@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-es2015-unicode-regex/-/babel-plugin-transform-es2015-unicode-regex-6.22.0.tgz#8d9cc27e7ee1decfe65454fb986452a04a613d20" + dependencies: + babel-helper-regex "^6.22.0" + babel-runtime "^6.22.0" + regexpu-core "^2.0.0" + +babel-plugin-transform-exponentiation-operator@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-exponentiation-operator/-/babel-plugin-transform-exponentiation-operator-6.22.0.tgz#d57c8335281918e54ef053118ce6eb108468084d" + dependencies: + babel-helper-builder-binary-assignment-operator-visitor "^6.22.0" + babel-plugin-syntax-exponentiation-operator "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-flow-strip-types@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-flow-strip-types/-/babel-plugin-transform-flow-strip-types-6.22.0.tgz#84cb672935d43714fdc32bce84568d87441cf7cf" + dependencies: + babel-plugin-syntax-flow "^6.18.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-object-rest-spread@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-object-rest-spread/-/babel-plugin-transform-object-rest-spread-6.23.0.tgz#875d6bc9be761c58a2ae3feee5dc4895d8c7f921" + dependencies: + babel-plugin-syntax-object-rest-spread "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-display-name@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-display-name/-/babel-plugin-transform-react-display-name-6.23.0.tgz#4398910c358441dc4cef18787264d0412ed36b37" + dependencies: + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-self@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-self/-/babel-plugin-transform-react-jsx-self-6.22.0.tgz#df6d80a9da2612a121e6ddd7558bcbecf06e636e" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx-source@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx-source/-/babel-plugin-transform-react-jsx-source-6.22.0.tgz#66ac12153f5cd2d17b3c19268f4bf0197f44ecd6" + dependencies: + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-react-jsx@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-react-jsx/-/babel-plugin-transform-react-jsx-6.23.0.tgz#23e892f7f2e759678eb5e4446a8f8e94e81b3470" + dependencies: + babel-helper-builder-react-jsx "^6.23.0" + babel-plugin-syntax-jsx "^6.8.0" + babel-runtime "^6.22.0" + +babel-plugin-transform-regenerator@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-regenerator/-/babel-plugin-transform-regenerator-6.22.0.tgz#65740593a319c44522157538d690b84094617ea6" + dependencies: + regenerator-transform "0.9.8" + +babel-plugin-transform-strict-mode@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-plugin-transform-strict-mode/-/babel-plugin-transform-strict-mode-6.22.0.tgz#e008df01340fdc87e959da65991b7e05970c8c7c" + dependencies: + babel-runtime "^6.22.0" + babel-types "^6.22.0" + +babel-polyfill@^6.16.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-polyfill/-/babel-polyfill-6.23.0.tgz#8364ca62df8eafb830499f699177466c3b03499d" + dependencies: + babel-runtime "^6.22.0" + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-preset-es2015@^6.18.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-preset-es2015/-/babel-preset-es2015-6.22.0.tgz#af5a98ecb35eb8af764ad8a5a05eb36dc4386835" + dependencies: + babel-plugin-check-es2015-constants "^6.22.0" + babel-plugin-transform-es2015-arrow-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoped-functions "^6.22.0" + babel-plugin-transform-es2015-block-scoping "^6.22.0" + babel-plugin-transform-es2015-classes "^6.22.0" + babel-plugin-transform-es2015-computed-properties "^6.22.0" + babel-plugin-transform-es2015-destructuring "^6.22.0" + babel-plugin-transform-es2015-duplicate-keys "^6.22.0" + babel-plugin-transform-es2015-for-of "^6.22.0" + babel-plugin-transform-es2015-function-name "^6.22.0" + babel-plugin-transform-es2015-literals "^6.22.0" + babel-plugin-transform-es2015-modules-amd "^6.22.0" + babel-plugin-transform-es2015-modules-commonjs "^6.22.0" + babel-plugin-transform-es2015-modules-systemjs "^6.22.0" + babel-plugin-transform-es2015-modules-umd "^6.22.0" + babel-plugin-transform-es2015-object-super "^6.22.0" + babel-plugin-transform-es2015-parameters "^6.22.0" + babel-plugin-transform-es2015-shorthand-properties "^6.22.0" + babel-plugin-transform-es2015-spread "^6.22.0" + babel-plugin-transform-es2015-sticky-regex "^6.22.0" + babel-plugin-transform-es2015-template-literals "^6.22.0" + babel-plugin-transform-es2015-typeof-symbol "^6.22.0" + babel-plugin-transform-es2015-unicode-regex "^6.22.0" + babel-plugin-transform-regenerator "^6.22.0" + +babel-preset-flow@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-flow/-/babel-preset-flow-6.23.0.tgz#e71218887085ae9a24b5be4169affb599816c49d" + dependencies: + babel-plugin-transform-flow-strip-types "^6.22.0" + +babel-preset-react@^6.16.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-preset-react/-/babel-preset-react-6.23.0.tgz#eb7cee4de98a3f94502c28565332da9819455195" + dependencies: + babel-plugin-syntax-jsx "^6.3.13" + babel-plugin-transform-react-display-name "^6.23.0" + babel-plugin-transform-react-jsx "^6.23.0" + babel-plugin-transform-react-jsx-self "^6.22.0" + babel-plugin-transform-react-jsx-source "^6.22.0" + babel-preset-flow "^6.23.0" + +babel-preset-stage-2@^6.18.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-2/-/babel-preset-stage-2-6.22.0.tgz#ccd565f19c245cade394b21216df704a73b27c07" + dependencies: + babel-plugin-syntax-dynamic-import "^6.18.0" + babel-plugin-transform-class-properties "^6.22.0" + babel-plugin-transform-decorators "^6.22.0" + babel-preset-stage-3 "^6.22.0" + +babel-preset-stage-3@^6.22.0: + version "6.22.0" + resolved "https://registry.yarnpkg.com/babel-preset-stage-3/-/babel-preset-stage-3-6.22.0.tgz#a4e92bbace7456fafdf651d7a7657ee0bbca9c2e" + dependencies: + babel-plugin-syntax-trailing-function-commas "^6.22.0" + babel-plugin-transform-async-generator-functions "^6.22.0" + babel-plugin-transform-async-to-generator "^6.22.0" + babel-plugin-transform-exponentiation-operator "^6.22.0" + babel-plugin-transform-object-rest-spread "^6.22.0" + +babel-register@^6.23.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-register/-/babel-register-6.23.0.tgz#c9aa3d4cca94b51da34826c4a0f9e08145d74ff3" + dependencies: + babel-core "^6.23.0" + babel-runtime "^6.22.0" + core-js "^2.4.0" + home-or-tmp "^2.0.0" + lodash "^4.2.0" + mkdirp "^0.5.1" + source-map-support "^0.4.2" + +babel-runtime@^6.18.0, babel-runtime@^6.22.0: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-runtime/-/babel-runtime-6.23.0.tgz#0a9489f144de70efb3ce4300accdb329e2fc543b" + dependencies: + core-js "^2.4.0" + regenerator-runtime "^0.10.0" + +babel-template@^6.22.0, babel-template@^6.23.0, babel-template@^6.3.13: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-template/-/babel-template-6.23.0.tgz#04d4f270adbb3aa704a8143ae26faa529238e638" + dependencies: + babel-runtime "^6.22.0" + babel-traverse "^6.23.0" + babel-types "^6.23.0" + babylon "^6.11.0" + lodash "^4.2.0" + +babel-traverse@^6.22.0, babel-traverse@^6.23.0, babel-traverse@^6.23.1: + version "6.23.1" + resolved "https://registry.yarnpkg.com/babel-traverse/-/babel-traverse-6.23.1.tgz#d3cb59010ecd06a97d81310065f966b699e14f48" + dependencies: + babel-code-frame "^6.22.0" + babel-messages "^6.23.0" + babel-runtime "^6.22.0" + babel-types "^6.23.0" + babylon "^6.15.0" + debug "^2.2.0" + globals "^9.0.0" + invariant "^2.2.0" + lodash "^4.2.0" + +babel-types@^6.19.0, babel-types@^6.22.0, babel-types@^6.23.0, babel-types@^6.4.1: + version "6.23.0" + resolved "https://registry.yarnpkg.com/babel-types/-/babel-types-6.23.0.tgz#bb17179d7538bad38cd0c9e115d340f77e7e9acf" + dependencies: + babel-runtime "^6.22.0" + esutils "^2.0.2" + lodash "^4.2.0" + to-fast-properties "^1.0.1" + +babylon@^6.11.0, babylon@^6.15.0: + version "6.16.1" + resolved "https://registry.yarnpkg.com/babylon/-/babylon-6.16.1.tgz#30c5a22f481978a9e7f8cdfdf496b11d94b404d3" + +balanced-match@^0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-0.4.2.tgz#cb3f3e3c732dc0f01ee70b403f302e61d7709838" + +base64-js@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-0.0.2.tgz#024f0f72afa25b75f9c0ee73cd4f55ec1bed9784" + +base64-js@^1.0.2: + version "1.2.0" + resolved "https://registry.yarnpkg.com/base64-js/-/base64-js-1.2.0.tgz#a39992d723584811982be5e290bb6a53d86700f1" + +batch@0.5.3: + version "0.5.3" + resolved "https://registry.yarnpkg.com/batch/-/batch-0.5.3.tgz#3f3414f380321743bfc1042f9a83ff1d5824d464" + +bcrypt-pbkdf@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d" + dependencies: + tweetnacl "^0.14.3" + +big.js@^3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/big.js/-/big.js-3.1.3.tgz#4cada2193652eb3ca9ec8e55c9015669c9806978" + +binary-extensions@^1.0.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/binary-extensions/-/binary-extensions-1.8.0.tgz#48ec8d16df4377eae5fa5884682480af4d95c774" + +block-stream@*: + version "0.0.9" + resolved "https://registry.yarnpkg.com/block-stream/-/block-stream-0.0.9.tgz#13ebfe778a03205cfe03751481ebb4b3300c126a" + dependencies: + inherits "~2.0.0" + +bn.js@^4.0.0, bn.js@^4.1.0, bn.js@^4.1.1, bn.js@^4.4.0: + version "4.11.6" + resolved "https://registry.yarnpkg.com/bn.js/-/bn.js-4.11.6.tgz#53344adb14617a13f6e8dd2ce28905d1c0ba3215" + +boom@2.x.x: + version "2.10.1" + resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f" + dependencies: + hoek "2.x.x" + +bops@0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/bops/-/bops-0.0.6.tgz#082d1d55fa01e60dbdc2ebc2dba37f659554cf3a" + dependencies: + base64-js "0.0.2" + to-utf8 "0.0.1" + +bowser@^1.2.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/bowser/-/bowser-1.6.0.tgz#37fc387b616cb6aef370dab4d6bd402b74c5c54d" + +brace-expansion@^1.0.0: + version "1.1.6" + resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.6.tgz#7197d7eaa9b87e648390ea61fc66c84427420df9" + dependencies: + balanced-match "^0.4.1" + concat-map "0.0.1" + +braces@^1.8.2: + version "1.8.5" + resolved "https://registry.yarnpkg.com/braces/-/braces-1.8.5.tgz#ba77962e12dff969d6b76711e914b737857bf6a7" + dependencies: + expand-range "^1.8.1" + preserve "^0.2.0" + repeat-element "^1.1.2" + +brfs-babel@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/brfs-babel/-/brfs-babel-1.0.0.tgz#672df60067d029210c49328d78b3979d57b50b18" + dependencies: + babel-core "^6.4.0" + babel-plugin-static-fs "^1.1.0" + through2 "^2.0.0" + +brfs@^1.4.0: + version "1.4.3" + resolved "https://registry.yarnpkg.com/brfs/-/brfs-1.4.3.tgz#db675d6f5e923e6df087fca5859c9090aaed3216" + dependencies: + quote-stream "^1.0.1" + resolve "^1.1.5" + static-module "^1.1.0" + through2 "^2.0.0" + +brorand@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/brorand/-/brorand-1.1.0.tgz#12c25efe40a45e3c323eb8675a0a0ce57b22371f" + +browserify-aes@^1.0.0, browserify-aes@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/browserify-aes/-/browserify-aes-1.0.6.tgz#5e7725dbdef1fd5930d4ebab48567ce451c48a0a" + dependencies: + buffer-xor "^1.0.2" + cipher-base "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + inherits "^2.0.1" + +browserify-cipher@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-cipher/-/browserify-cipher-1.0.0.tgz#9988244874bf5ed4e28da95666dcd66ac8fc363a" + dependencies: + browserify-aes "^1.0.4" + browserify-des "^1.0.0" + evp_bytestokey "^1.0.0" + +browserify-des@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/browserify-des/-/browserify-des-1.0.0.tgz#daa277717470922ed2fe18594118a175439721dd" + dependencies: + cipher-base "^1.0.1" + des.js "^1.0.0" + inherits "^2.0.1" + +browserify-package-json@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/browserify-package-json/-/browserify-package-json-1.0.1.tgz#98dde8aa5c561fd6d3fe49bbaa102b74b396fdea" + +browserify-rsa@^4.0.0: + version "4.0.1" + resolved "https://registry.yarnpkg.com/browserify-rsa/-/browserify-rsa-4.0.1.tgz#21e0abfaf6f2029cf2fafb133567a701d4135524" + dependencies: + bn.js "^4.1.0" + randombytes "^2.0.1" + +browserify-sign@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/browserify-sign/-/browserify-sign-4.0.0.tgz#10773910c3c206d5420a46aad8694f820b85968f" + dependencies: + bn.js "^4.1.1" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.2" + elliptic "^6.0.0" + inherits "^2.0.1" + parse-asn1 "^5.0.0" + +browserify-zlib@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/browserify-zlib/-/browserify-zlib-0.1.4.tgz#bb35f8a519f600e0fa6b8485241c979d0141fb2d" + dependencies: + pako "~0.2.0" + +buffer-equal@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/buffer-equal/-/buffer-equal-0.0.1.tgz#91bc74b11ea405bc916bc6aa908faafa5b4aac4b" + +buffer-shims@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/buffer-shims/-/buffer-shims-1.0.0.tgz#9978ce317388c649ad8793028c3477ef044a8b51" + +buffer-xor@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/buffer-xor/-/buffer-xor-1.0.3.tgz#26e61ed1422fb70dd42e6e36729ed51d855fe8d9" + +buffer@^4.3.0: + version "4.9.1" + resolved "https://registry.yarnpkg.com/buffer/-/buffer-4.9.1.tgz#6d1bb601b07a4efced97094132093027c95bc298" + dependencies: + base64-js "^1.0.2" + ieee754 "^1.1.4" + isarray "^1.0.0" + +builtin-modules@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/builtin-modules/-/builtin-modules-1.1.1.tgz#270f076c5a72c02f5b65a47df94c5fe3a278892f" + +builtin-status-codes@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/builtin-status-codes/-/builtin-status-codes-3.0.0.tgz#85982878e21b98e1c66425e03d0174788f569ee8" + +bytes@2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/bytes/-/bytes-2.3.0.tgz#d5b680a165b6201739acb611542aabc2d8ceb070" + +call-matcher@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/call-matcher/-/call-matcher-1.0.1.tgz#5134d077984f712a54dad3cbf62de28dce416ca8" + dependencies: + core-js "^2.0.0" + deep-equal "^1.0.0" + espurify "^1.6.0" + estraverse "^4.0.0" + +camelcase@^1.0.2: + version "1.2.1" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-1.2.1.tgz#9bb5304d2e0b56698b2c758b08a3eaa9daa58a39" + +camelcase@^3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/camelcase/-/camelcase-3.0.0.tgz#32fc4b9fcdaf845fcdf7e73bb97cac2261f0ab0a" + +canvas-composite-types@^1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/canvas-composite-types/-/canvas-composite-types-1.0.4.tgz#7b44e7b179f06d84acbf1570480e70bef2a6a922" + +caseless@~0.12.0: + version "0.12.0" + resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc" + +center-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/center-align/-/center-align-0.1.3.tgz#aa0d32629b6ee972200411cbd4461c907bc2b7ad" + dependencies: + align-text "^0.1.3" + lazy-cache "^1.0.3" + +chalk@^1.1.0: + version "1.1.3" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98" + dependencies: + ansi-styles "^2.2.1" + escape-string-regexp "^1.0.2" + has-ansi "^2.0.0" + strip-ansi "^3.0.0" + supports-color "^2.0.0" + +chalk@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/chalk/-/chalk-0.4.0.tgz#5199a3ddcd0c1efe23bc08c1b027b06176e0c64f" + dependencies: + ansi-styles "~1.0.0" + has-color "~0.1.0" + strip-ansi "~0.1.0" + +chokidar@^1.4.3, chokidar@^1.6.0: + version "1.6.1" + resolved "https://registry.yarnpkg.com/chokidar/-/chokidar-1.6.1.tgz#2f4447ab5e96e50fb3d789fd90d4c72e0e4c70c2" + dependencies: + anymatch "^1.3.0" + async-each "^1.0.0" + glob-parent "^2.0.0" + inherits "^2.0.1" + is-binary-path "^1.0.0" + is-glob "^2.0.0" + path-is-absolute "^1.0.0" + readdirp "^2.0.0" + optionalDependencies: + fsevents "^1.0.0" + +cipher-base@^1.0.0, cipher-base@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/cipher-base/-/cipher-base-1.0.3.tgz#eeabf194419ce900da3018c207d212f2a6df0a07" + dependencies: + inherits "^2.0.1" + +cliui@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-2.1.0.tgz#4b475760ff80264c762c3a1719032e91c7fea0d1" + dependencies: + center-align "^0.1.1" + right-align "^0.1.1" + wordwrap "0.0.2" + +cliui@^3.2.0: + version "3.2.0" + resolved "https://registry.yarnpkg.com/cliui/-/cliui-3.2.0.tgz#120601537a916d29940f934da3b48d585a39213d" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + wrap-ansi "^2.0.0" + +co@^4.6.0: + version "4.6.0" + resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184" + +code-point-at@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/code-point-at/-/code-point-at-1.1.0.tgz#0d070b4d043a5bea33a2f1a40e2edb3d9a4ccf77" + +combined-stream@^1.0.5, combined-stream@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009" + dependencies: + delayed-stream "~1.0.0" + +commander@2: + version "2.9.0" + resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4" + dependencies: + graceful-readlink ">= 1.0.0" + +commondir@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/commondir/-/commondir-1.0.1.tgz#ddd800da0c66127393cca5950ea968a3aaf1253b" + +compressible@~2.0.8: + version "2.0.9" + resolved "https://registry.yarnpkg.com/compressible/-/compressible-2.0.9.tgz#6daab4e2b599c2770dd9e21e7a891b1c5a755425" + dependencies: + mime-db ">= 1.24.0 < 2" + +compression@^1.5.2: + version "1.6.2" + resolved "https://registry.yarnpkg.com/compression/-/compression-1.6.2.tgz#cceb121ecc9d09c52d7ad0c3350ea93ddd402bc3" + dependencies: + accepts "~1.3.3" + bytes "2.3.0" + compressible "~2.0.8" + debug "~2.2.0" + on-headers "~1.0.1" + vary "~1.1.0" + +concat-map@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b" + +concat-stream@~1.2.1: + version "1.2.1" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.2.1.tgz#f35100b6c46378bfba8b6b80f9f0d0ccdf13dc60" + dependencies: + bops "0.0.6" + +concat-stream@~1.4.5: + version "1.4.10" + resolved "https://registry.yarnpkg.com/concat-stream/-/concat-stream-1.4.10.tgz#acc3bbf5602cb8cc980c6ac840fa7d8603e3ef36" + dependencies: + inherits "~2.0.1" + readable-stream "~1.1.9" + typedarray "~0.0.5" + +connect-history-api-fallback@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/connect-history-api-fallback/-/connect-history-api-fallback-1.3.0.tgz#e51d17f8f0ef0db90a64fdb47de3051556e9f169" + +console-browserify@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-browserify/-/console-browserify-1.1.0.tgz#f0241c45730a9fc6323b206dbf38edc741d0bb10" + dependencies: + date-now "^0.1.4" + +console-control-strings@^1.0.0, console-control-strings@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/console-control-strings/-/console-control-strings-1.1.0.tgz#3d7cf4464db6446ea644bf4b39507f9851008e8e" + +constants-browserify@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/constants-browserify/-/constants-browserify-1.0.0.tgz#c20b96d8c617748aaf1c16021760cd27fcb8cb75" + +content-disposition@0.5.2: + version "0.5.2" + resolved "https://registry.yarnpkg.com/content-disposition/-/content-disposition-0.5.2.tgz#0cf68bb9ddf5f2be7961c3a85178cb85dba78cb4" + +content-type@~1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/content-type/-/content-type-1.0.2.tgz#b7d113aee7a8dd27bd21133c4dc2529df1721eed" + +convert-source-map@^1.1.0, convert-source-map@^1.1.1: + version "1.4.0" + resolved "https://registry.yarnpkg.com/convert-source-map/-/convert-source-map-1.4.0.tgz#e3dad195bf61bfe13a7a3c73e9876ec14a0268f3" + +cookie-signature@1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/cookie-signature/-/cookie-signature-1.0.6.tgz#e303a882b342cc3ee8ca513a79999734dab3ae2c" + +cookie@0.3.1: + version "0.3.1" + resolved "https://registry.yarnpkg.com/cookie/-/cookie-0.3.1.tgz#e7e0a1f9ef43b4c8ba925c5c5a96e806d16873bb" + +core-js@^1.0.0: + version "1.2.7" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-1.2.7.tgz#652294c14651db28fa93bd2d5ff2983a4f08c636" + +core-js@^2.0.0, core-js@^2.4.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/core-js/-/core-js-2.4.1.tgz#4de911e667b0eae9124e34254b53aea6fc618d3e" + +core-util-is@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7" + +create-ecdh@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/create-ecdh/-/create-ecdh-4.0.0.tgz#888c723596cdf7612f6498233eebd7a35301737d" + dependencies: + bn.js "^4.1.0" + elliptic "^6.0.0" + +create-hash@^1.1.0, create-hash@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/create-hash/-/create-hash-1.1.2.tgz#51210062d7bb7479f6c65bb41a92208b1d61abad" + dependencies: + cipher-base "^1.0.1" + inherits "^2.0.1" + ripemd160 "^1.0.0" + sha.js "^2.3.6" + +create-hmac@^1.1.0, create-hmac@^1.1.2: + version "1.1.4" + resolved "https://registry.yarnpkg.com/create-hmac/-/create-hmac-1.1.4.tgz#d3fb4ba253eb8b3f56e39ea2fbcb8af747bd3170" + dependencies: + create-hash "^1.1.0" + inherits "^2.0.1" + +cryptiles@2.x.x: + version "2.0.5" + resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8" + dependencies: + boom "2.x.x" + +crypto-browserify@^3.11.0: + version "3.11.0" + resolved "https://registry.yarnpkg.com/crypto-browserify/-/crypto-browserify-3.11.0.tgz#3652a0906ab9b2a7e0c3ce66a408e957a2485522" + dependencies: + browserify-cipher "^1.0.0" + browserify-sign "^4.0.0" + create-ecdh "^4.0.0" + create-hash "^1.1.0" + create-hmac "^1.1.0" + diffie-hellman "^5.0.0" + inherits "^2.0.1" + pbkdf2 "^3.0.3" + public-encrypt "^4.0.0" + randombytes "^2.0.0" + +csscolorparser@^1.0.2, csscolorparser@~1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/csscolorparser/-/csscolorparser-1.0.3.tgz#b34f391eea4da8f3e98231e2ccd8df9c041f171b" + +d3-array@1, d3-array@^1.0.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-array/-/d3-array-1.1.1.tgz#a01abe63a25ffb91d3423c3c6d051b4d36bc8a09" + +d3-collection@1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-collection/-/d3-collection-1.0.3.tgz#00bdea94fbc1628d435abbae2f4dc2164e37dd34" + +d3-color@1, d3-color@^1.0.1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-color/-/d3-color-1.0.3.tgz#bc7643fca8e53a8347e2fbdaffa236796b58509b" + +d3-dispatch@1: + version "1.0.3" + resolved "https://registry.yarnpkg.com/d3-dispatch/-/d3-dispatch-1.0.3.tgz#46e1491eaa9b58c358fce5be4e8bed626e7871f8" + +d3-dsv@1: + version "1.0.5" + resolved "https://registry.yarnpkg.com/d3-dsv/-/d3-dsv-1.0.5.tgz#419f7db47f628789fc3fdb636e678449d0821136" + dependencies: + commander "2" + iconv-lite "0.4" + rw "1" + +d3-format@1, d3-format@^1.0.2: + version "1.1.1" + resolved "https://registry.yarnpkg.com/d3-format/-/d3-format-1.1.1.tgz#26e094e7b0fa925d3615aa6f43b265c5ca82b46e" + +d3-geo@^1.2.4: + version "1.6.2" + resolved "https://registry.yarnpkg.com/d3-geo/-/d3-geo-1.6.2.tgz#efce6f034b343f13c94a4e680dee353b476c7bca" + dependencies: + d3-array "1" + +d3-hexbin@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/d3-hexbin/-/d3-hexbin-0.2.1.tgz#24459c47c933b67ed38aecde43d9248f6e3e2001" + +d3-interpolate@1: + version "1.1.4" + resolved "https://registry.yarnpkg.com/d3-interpolate/-/d3-interpolate-1.1.4.tgz#a43ec5b3bee350d8516efdf819a4c08c053db302" + dependencies: + d3-color "1" + +d3-request@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/d3-request/-/d3-request-1.0.5.tgz#4daae946d1dd0d57dfe01f022956354958d51f23" + dependencies: + d3-collection "1" + d3-dispatch "1" + d3-dsv "1" + xmlhttprequest "1" + +d3-scale@^1.0.3: + version "1.0.5" + resolved "https://registry.yarnpkg.com/d3-scale/-/d3-scale-1.0.5.tgz#418506f0fb18eb052b385e196398acc2a4134858" + dependencies: + d3-array "1" + d3-collection "1" + d3-color "1" + d3-format "1" + d3-interpolate "1" + d3-time "1" + d3-time-format "2" + +d3-selection@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/d3-selection/-/d3-selection-1.0.5.tgz#948c73b41a44e28d1742ae2ff207c2aebca2734b" + +d3-time-format@2: + version "2.0.5" + resolved "https://registry.yarnpkg.com/d3-time-format/-/d3-time-format-2.0.5.tgz#9d7780204f7c9119c9170b1a56db4de9a8af972e" + dependencies: + d3-time "1" + +d3-time@1: + version "1.0.6" + resolved "https://registry.yarnpkg.com/d3-time/-/d3-time-1.0.6.tgz#a55b13d7d15d3a160ae91708232e0835f1d5e945" + +d3-voronoi@^1.1.1: + version "1.1.2" + resolved "https://registry.yarnpkg.com/d3-voronoi/-/d3-voronoi-1.1.2.tgz#1687667e8f13a2d158c80c1480c5a29cb0d8973c" + +dashdash@^1.12.0: + version "1.14.1" + resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0" + dependencies: + assert-plus "^1.0.0" + +date-now@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/date-now/-/date-now-0.1.4.tgz#eaf439fd4d4848ad74e5cc7dbef200672b9e345b" + +debug@2.6.1: + version "2.6.1" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.1.tgz#79855090ba2c4e3115cc7d8769491d58f0491351" + dependencies: + ms "0.7.2" + +debug@^2.1.1, debug@^2.2.0: + version "2.6.2" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.2.tgz#dfa96a861ee9b8c2f29349b3bcc41aa599a71e0f" + dependencies: + ms "0.7.2" + +debug@~2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/debug/-/debug-2.2.0.tgz#f87057e995b1a1f6ae6a4960664137bc56f039da" + dependencies: + ms "0.7.1" + +decamelize@^1.0.0, decamelize@^1.1.1: + version "1.2.0" + resolved "https://registry.yarnpkg.com/decamelize/-/decamelize-1.2.0.tgz#f6534d15148269b20352e7bee26f501f9a191290" + +deck.gl@4.0.0-beta.5: + version "4.0.0-beta.5" + resolved "https://registry.yarnpkg.com/deck.gl/-/deck.gl-4.0.0-beta.5.tgz#0189b07429487c8802f9cf94965c76e23c0f2661" + dependencies: + d3-hexbin "^0.2.1" + earcut "^2.0.6" + gl-matrix "^2.3.2" + lodash.flattendeep "^4.4.0" + +deep-equal@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/deep-equal/-/deep-equal-1.0.1.tgz#f5d260292b660e084eff4cdbc9f08ad3247448b5" + +deep-extend@~0.4.0: + version "0.4.1" + resolved "https://registry.yarnpkg.com/deep-extend/-/deep-extend-0.4.1.tgz#efe4113d08085f4e6f9687759810f807469e2253" + +deep-is@~0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/deep-is/-/deep-is-0.1.3.tgz#b369d6fb5dbc13eecf524f91b070feedc357cf34" + +delayed-stream@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619" + +delegates@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/delegates/-/delegates-1.0.0.tgz#84c6e159b81904fdca59a0ef44cd870d31250f9a" + +depd@1.1.0, depd@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/depd/-/depd-1.1.0.tgz#e1bd82c6aab6ced965b97b88b17ed3e528ca18c3" + +des.js@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/des.js/-/des.js-1.0.0.tgz#c074d2e2aa6a8a9a07dbd61f9a15c2cd83ec8ecc" + dependencies: + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + +destroy@~1.0.4: + version "1.0.4" + resolved "https://registry.yarnpkg.com/destroy/-/destroy-1.0.4.tgz#978857442c44749e4206613e37946205826abd80" + +detect-indent@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/detect-indent/-/detect-indent-4.0.0.tgz#f76d064352cdf43a1cb6ce619c4ee3a9475de208" + dependencies: + repeating "^2.0.0" + +diffie-hellman@^5.0.0: + version "5.0.2" + resolved "https://registry.yarnpkg.com/diffie-hellman/-/diffie-hellman-5.0.2.tgz#b5835739270cfe26acf632099fded2a07f209e5e" + dependencies: + bn.js "^4.1.0" + miller-rabin "^4.0.0" + randombytes "^2.0.0" + +dom-walk@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/dom-walk/-/dom-walk-0.1.1.tgz#672226dc74c8f799ad35307df936aba11acd6018" + +domain-browser@^1.1.1: + version "1.1.7" + resolved "https://registry.yarnpkg.com/domain-browser/-/domain-browser-1.1.7.tgz#867aa4b093faa05f1de08c06f4d7b21fdf8698bc" + +duplexer2@~0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/duplexer2/-/duplexer2-0.0.2.tgz#c614dcf67e2fb14995a91711e5a617e8a60a31db" + dependencies: + readable-stream "~1.1.9" + +earcut@^2.0.3, earcut@^2.0.6: + version "2.1.1" + resolved "https://registry.yarnpkg.com/earcut/-/earcut-2.1.1.tgz#157634e5f3ebb42224e475016e86a5b6ce556b45" + +ecc-jsbn@~0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505" + dependencies: + jsbn "~0.1.0" + +ee-first@1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/ee-first/-/ee-first-1.1.1.tgz#590c61156b0ae2f4f0255732a158b266bc56b21d" + +elliptic@^6.0.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/elliptic/-/elliptic-6.4.0.tgz#cac9af8762c85836187003c8dfe193e5e2eae5df" + dependencies: + bn.js "^4.4.0" + brorand "^1.0.1" + hash.js "^1.0.0" + hmac-drbg "^1.0.0" + inherits "^2.0.1" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.0" + +emojis-list@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/emojis-list/-/emojis-list-2.1.0.tgz#4daa4d9db00f9819880c79fa457ae5b09a1fd389" + +encodeurl@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/encodeurl/-/encodeurl-1.0.1.tgz#79e3d58655346909fe6f0f45a5de68103b294d20" + +encoding@^0.1.11: + version "0.1.12" + resolved "https://registry.yarnpkg.com/encoding/-/encoding-0.1.12.tgz#538b66f3ee62cd1ab51ec323829d1f9480c74beb" + dependencies: + iconv-lite "~0.4.13" + +enhanced-resolve@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/enhanced-resolve/-/enhanced-resolve-3.1.0.tgz#9f4b626f577245edcf4b2ad83d86e17f4f421dec" + dependencies: + graceful-fs "^4.1.2" + memory-fs "^0.4.0" + object-assign "^4.0.1" + tapable "^0.2.5" + +errno@^0.1.3: + version "0.1.4" + resolved "https://registry.yarnpkg.com/errno/-/errno-0.1.4.tgz#b896e23a9e5e8ba33871fc996abd3635fc9a1c7d" + dependencies: + prr "~0.0.0" + +error-ex@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/error-ex/-/error-ex-1.3.1.tgz#f855a86ce61adc4e8621c3cda21e7a7612c3a8dc" + dependencies: + is-arrayish "^0.2.1" + +escape-html@~1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/escape-html/-/escape-html-1.0.3.tgz#0258eae4d3d0c0974de1c169188ef0051d1d1988" + +escape-string-regexp@^1.0.2: + version "1.0.5" + resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4" + +escodegen@^1.6.1: + version "1.8.1" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.8.1.tgz#5a5b53af4693110bebb0867aa3430dd3b70a1018" + dependencies: + esprima "^2.7.1" + estraverse "^1.9.1" + esutils "^2.0.2" + optionator "^0.8.1" + optionalDependencies: + source-map "~0.2.0" + +escodegen@~0.0.24: + version "0.0.28" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-0.0.28.tgz#0e4ff1715f328775d6cab51ac44a406cd7abffd3" + dependencies: + esprima "~1.0.2" + estraverse "~1.3.0" + optionalDependencies: + source-map ">= 0.1.2" + +escodegen@~1.3.2: + version "1.3.3" + resolved "https://registry.yarnpkg.com/escodegen/-/escodegen-1.3.3.tgz#f024016f5a88e046fd12005055e939802e6c5f23" + dependencies: + esprima "~1.1.1" + estraverse "~1.5.0" + esutils "~1.0.0" + optionalDependencies: + source-map "~0.1.33" + +esprima@^2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-2.7.3.tgz#96e3b70d5779f6ad49cd032673d1c312767ba581" + +esprima@~1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.0.4.tgz#9f557e08fc3b4d26ece9dd34f8fbf476b62585ad" + +esprima@~1.1.1: + version "1.1.1" + resolved "https://registry.yarnpkg.com/esprima/-/esprima-1.1.1.tgz#5b6f1547f4d102e670e140c509be6771d6aeb549" + +espurify@^1.3.0, espurify@^1.6.0: + version "1.7.0" + resolved "https://registry.yarnpkg.com/espurify/-/espurify-1.7.0.tgz#1c5cf6cbccc32e6f639380bd4f991fab9ba9d226" + dependencies: + core-js "^2.0.0" + +estraverse@^1.9.1: + version "1.9.3" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.9.3.tgz#af67f2dc922582415950926091a4005d29c9bb44" + +estraverse@^4.0.0, estraverse@^4.1.0: + version "4.2.0" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-4.2.0.tgz#0dee3fed31fcd469618ce7342099fc1afa0bdb13" + +estraverse@~1.3.0: + version "1.3.2" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.3.2.tgz#37c2b893ef13d723f276d878d60d8535152a6c42" + +estraverse@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/estraverse/-/estraverse-1.5.1.tgz#867a3e8e58a9f84618afb6c2ddbcd916b7cbaf71" + +esutils@^2.0.0, esutils@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-2.0.2.tgz#0abf4f1caa5bcb1f7a9d8acc6dea4faaa04bac9b" + +esutils@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/esutils/-/esutils-1.0.0.tgz#8151d358e20c8acc7fb745e7472c0025fe496570" + +etag@~1.8.0: + version "1.8.0" + resolved "https://registry.yarnpkg.com/etag/-/etag-1.8.0.tgz#6f631aef336d6c46362b51764044ce216be3c051" + +eventemitter3@1.x.x: + version "1.2.0" + resolved "https://registry.yarnpkg.com/eventemitter3/-/eventemitter3-1.2.0.tgz#1c86991d816ad1e504750e73874224ecf3bec508" + +events@^1.0.0, events@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/events/-/events-1.1.1.tgz#9ebdb7635ad099c70dcc4c2a1f5004288e8bd924" + +eventsource@0.1.6: + version "0.1.6" + resolved "https://registry.yarnpkg.com/eventsource/-/eventsource-0.1.6.tgz#0acede849ed7dd1ccc32c811bb11b944d4f29232" + dependencies: + original ">=0.0.5" + +evp_bytestokey@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/evp_bytestokey/-/evp_bytestokey-1.0.0.tgz#497b66ad9fef65cd7c08a6180824ba1476b66e53" + dependencies: + create-hash "^1.1.1" + +expand-brackets@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/expand-brackets/-/expand-brackets-0.1.5.tgz#df07284e342a807cd733ac5af72411e581d1177b" + dependencies: + is-posix-bracket "^0.1.0" + +expand-range@^1.8.1: + version "1.8.2" + resolved "https://registry.yarnpkg.com/expand-range/-/expand-range-1.8.2.tgz#a299effd335fe2721ebae8e257ec79644fc85337" + dependencies: + fill-range "^2.1.0" + +express@^4.13.3: + version "4.15.2" + resolved "https://registry.yarnpkg.com/express/-/express-4.15.2.tgz#af107fc148504457f2dca9a6f2571d7129b97b35" + dependencies: + accepts "~1.3.3" + array-flatten "1.1.1" + content-disposition "0.5.2" + content-type "~1.0.2" + cookie "0.3.1" + cookie-signature "1.0.6" + debug "2.6.1" + depd "~1.1.0" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.0" + finalhandler "~1.0.0" + fresh "0.5.0" + merge-descriptors "1.0.1" + methods "~1.1.2" + on-finished "~2.3.0" + parseurl "~1.3.1" + path-to-regexp "0.1.7" + proxy-addr "~1.1.3" + qs "6.4.0" + range-parser "~1.2.0" + send "0.15.1" + serve-static "1.12.1" + setprototypeof "1.0.3" + statuses "~1.3.1" + type-is "~1.6.14" + utils-merge "1.0.0" + vary "~1.1.0" + +extend@~3.0.0: + version "3.0.0" + resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4" + +extglob@^0.3.1: + version "0.3.2" + resolved "https://registry.yarnpkg.com/extglob/-/extglob-0.3.2.tgz#2e18ff3d2f49ab2765cec9023f011daa8d8349a1" + dependencies: + is-extglob "^1.0.0" + +extsprintf@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.0.2.tgz#e1080e0658e300b06294990cc70e1502235fd550" + +falafel@^1.0.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/falafel/-/falafel-1.2.0.tgz#c18d24ef5091174a497f318cd24b026a25cddab4" + dependencies: + acorn "^1.0.3" + foreach "^2.0.5" + isarray "0.0.1" + object-keys "^1.0.6" + +fast-levenshtein@~2.0.4: + version "2.0.6" + resolved "https://registry.yarnpkg.com/fast-levenshtein/-/fast-levenshtein-2.0.6.tgz#3d8a5c66883a16a30ca8643e851f19baa7797917" + +faye-websocket@^0.10.0: + version "0.10.0" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.10.0.tgz#4e492f8d04dfb6f89003507f6edbf2d501e7c6f4" + dependencies: + websocket-driver ">=0.5.1" + +faye-websocket@~0.11.0: + version "0.11.1" + resolved "https://registry.yarnpkg.com/faye-websocket/-/faye-websocket-0.11.1.tgz#f0efe18c4f56e4f40afc7e06c719fd5ee6188f38" + dependencies: + websocket-driver ">=0.5.1" + +fbjs@^0.8.0, fbjs@^0.8.1, fbjs@^0.8.4: + version "0.8.9" + resolved "https://registry.yarnpkg.com/fbjs/-/fbjs-0.8.9.tgz#180247fbd347dcc9004517b904f865400a0c8f14" + dependencies: + core-js "^1.0.0" + isomorphic-fetch "^2.1.1" + loose-envify "^1.0.0" + object-assign "^4.1.0" + promise "^7.1.1" + setimmediate "^1.0.5" + ua-parser-js "^0.7.9" + +feature-filter@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/feature-filter/-/feature-filter-2.2.0.tgz#3cc356015e968c362afbdf7ff1bb744ddf7fc2e0" + +filename-regex@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/filename-regex/-/filename-regex-2.0.0.tgz#996e3e80479b98b9897f15a8a58b3d084e926775" + +fill-range@^2.1.0: + version "2.2.3" + resolved "https://registry.yarnpkg.com/fill-range/-/fill-range-2.2.3.tgz#50b77dfd7e469bc7492470963699fe7a8485a723" + dependencies: + is-number "^2.1.0" + isobject "^2.0.0" + randomatic "^1.1.3" + repeat-element "^1.1.2" + repeat-string "^1.5.2" + +finalhandler@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/finalhandler/-/finalhandler-1.0.0.tgz#b5691c2c0912092f18ac23e9416bde5cd7dc6755" + dependencies: + debug "2.6.1" + encodeurl "~1.0.1" + escape-html "~1.0.3" + on-finished "~2.3.0" + parseurl "~1.3.1" + statuses "~1.3.1" + unpipe "~1.0.0" + +find-cache-dir@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/find-cache-dir/-/find-cache-dir-0.1.1.tgz#c8defae57c8a52a8a784f9e31c57c742e993a0b9" + dependencies: + commondir "^1.0.1" + mkdirp "^0.5.1" + pkg-dir "^1.0.0" + +find-up@^1.0.0: + version "1.1.2" + resolved "https://registry.yarnpkg.com/find-up/-/find-up-1.1.2.tgz#6b2e9822b1a2ce0a60ab64d610eccad53cb24d0f" + dependencies: + path-exists "^2.0.0" + pinkie-promise "^2.0.0" + +for-in@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/for-in/-/for-in-1.0.2.tgz#81068d295a8142ec0ac726c6e2200c30fb6d5e80" + +for-own@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/for-own/-/for-own-0.1.5.tgz#5265c681a4f294dabbf17c9509b6763aa84510ce" + dependencies: + for-in "^1.0.1" + +foreach@^2.0.5: + version "2.0.5" + resolved "https://registry.yarnpkg.com/foreach/-/foreach-2.0.5.tgz#0bee005018aeb260d0a3af3ae658dd0136ec1b99" + +forever-agent@~0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91" + +form-data@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.1.2.tgz#89c3534008b97eada4cbb157d58f6f5df025eae4" + dependencies: + asynckit "^0.4.0" + combined-stream "^1.0.5" + mime-types "^2.1.12" + +forwarded@~0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/forwarded/-/forwarded-0.1.0.tgz#19ef9874c4ae1c297bcf078fde63a09b66a84363" + +fresh@0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/fresh/-/fresh-0.5.0.tgz#f474ca5e6a9246d6fd8e0953cfa9b9c805afa78e" + +fs.realpath@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f" + +fsevents@^1.0.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/fsevents/-/fsevents-1.1.1.tgz#f19fd28f43eeaf761680e519a203c4d0b3d31aff" + dependencies: + nan "^2.3.0" + node-pre-gyp "^0.6.29" + +fstream-ignore@~1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/fstream-ignore/-/fstream-ignore-1.0.5.tgz#9c31dae34767018fe1d249b24dada67d092da105" + dependencies: + fstream "^1.0.0" + inherits "2" + minimatch "^3.0.0" + +fstream@^1.0.0, fstream@^1.0.2, fstream@~1.0.10: + version "1.0.11" + resolved "https://registry.yarnpkg.com/fstream/-/fstream-1.0.11.tgz#5c1fb1f117477114f0632a0eb4b71b3cb0fd3171" + dependencies: + graceful-fs "^4.1.2" + inherits "~2.0.0" + mkdirp ">=0.5 0" + rimraf "2" + +function-bind@^1.0.2: + version "1.1.0" + resolved "https://registry.yarnpkg.com/function-bind/-/function-bind-1.1.0.tgz#16176714c801798e4e8f2cf7f7529467bb4a5771" + +gauge@~2.7.1: + version "2.7.3" + resolved "https://registry.yarnpkg.com/gauge/-/gauge-2.7.3.tgz#1c23855f962f17b3ad3d0dc7443f304542edfe09" + dependencies: + aproba "^1.0.3" + console-control-strings "^1.0.0" + has-unicode "^2.0.0" + object-assign "^4.1.0" + signal-exit "^3.0.0" + string-width "^1.0.1" + strip-ansi "^3.0.1" + wide-align "^1.1.0" + +geojson-area@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/geojson-area/-/geojson-area-0.1.0.tgz#d48d807082cfadf4a78df1349be50f38bf1894ae" + dependencies: + wgs84 "0.0.0" + +geojson-rewind@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/geojson-rewind/-/geojson-rewind-0.1.0.tgz#57022a054b196660d755354fe5d26684d90cd019" + dependencies: + concat-stream "~1.2.1" + geojson-area "0.1.0" + minimist "0.0.5" + +geojson-vt@^2.4.0: + version "2.4.0" + resolved "https://registry.yarnpkg.com/geojson-vt/-/geojson-vt-2.4.0.tgz#3c1cf44493f35eb4d2c70c95da6550de66072c05" + +get-caller-file@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/get-caller-file/-/get-caller-file-1.0.2.tgz#f702e63127e7e231c160a80c1554acb70d5047e5" + +getpass@^0.1.1: + version "0.1.6" + resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.6.tgz#283ffd9fc1256840875311c1b60e8c40187110e6" + dependencies: + assert-plus "^1.0.0" + +gl-constants@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/gl-constants/-/gl-constants-1.0.0.tgz#597a504e364750ff50253aa35f8dea7af4a5d233" + +gl-matrix@^2.3.1, gl-matrix@^2.3.2: + version "2.3.2" + resolved "https://registry.yarnpkg.com/gl-matrix/-/gl-matrix-2.3.2.tgz#aac808c74af7d5db05fe04cb60ca1a0fcb174d74" + +glob-base@^0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/glob-base/-/glob-base-0.3.0.tgz#dbb164f6221b1c0b1ccf82aea328b497df0ea3c4" + dependencies: + glob-parent "^2.0.0" + is-glob "^2.0.0" + +glob-parent@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/glob-parent/-/glob-parent-2.0.0.tgz#81383d72db054fcccf5336daa902f182f6edbb28" + dependencies: + is-glob "^2.0.0" + +glob@^7.0.5: + version "7.1.1" + resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8" + dependencies: + fs.realpath "^1.0.0" + inflight "^1.0.4" + inherits "2" + minimatch "^3.0.2" + once "^1.3.0" + path-is-absolute "^1.0.0" + +global@^4.3.0: + version "4.3.1" + resolved "https://registry.yarnpkg.com/global/-/global-4.3.1.tgz#5f757908c7cbabce54f386ae440e11e26b7916df" + dependencies: + min-document "^2.19.0" + process "~0.5.1" + +globals@^9.0.0: + version "9.16.0" + resolved "https://registry.yarnpkg.com/globals/-/globals-9.16.0.tgz#63e903658171ec2d9f51b1d31de5e2b8dc01fb80" + +graceful-fs@^4.1.2: + version "4.1.11" + resolved "https://registry.yarnpkg.com/graceful-fs/-/graceful-fs-4.1.11.tgz#0e8bdfe4d1ddb8854d64e04ea7c00e2a026e5658" + +"graceful-readlink@>= 1.0.0": + version "1.0.1" + resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725" + +grid-index@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/grid-index/-/grid-index-1.0.0.tgz#ad2c5d54ce5b35437faff1d70a9aeb3d1d261110" + +handle-thing@^1.2.4: + version "1.2.5" + resolved "https://registry.yarnpkg.com/handle-thing/-/handle-thing-1.2.5.tgz#fd7aad726bf1a5fd16dfc29b2f7a6601d27139c4" + +har-schema@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-1.0.5.tgz#d263135f43307c02c602afc8fe95970c0151369e" + +har-validator@~4.2.1: + version "4.2.1" + resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-4.2.1.tgz#33481d0f1bbff600dd203d75812a6a5fba002e2a" + dependencies: + ajv "^4.9.1" + har-schema "^1.0.5" + +has-ansi@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91" + dependencies: + ansi-regex "^2.0.0" + +has-color@~0.1.0: + version "0.1.7" + resolved "https://registry.yarnpkg.com/has-color/-/has-color-0.1.7.tgz#67144a5260c34fc3cca677d041daf52fe7b78b2f" + +has-flag@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa" + +has-unicode@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/has-unicode/-/has-unicode-2.0.1.tgz#e0e6fe6a28cf51138855e086d1691e771de2a8b9" + +has@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/has/-/has-1.0.1.tgz#8461733f538b0837c9361e39a9ab9e9704dc2f28" + dependencies: + function-bind "^1.0.2" + +hash.js@^1.0.0, hash.js@^1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/hash.js/-/hash.js-1.0.3.tgz#1332ff00156c0a0ffdd8236013d07b77a0451573" + dependencies: + inherits "^2.0.1" + +hawk@~3.1.3: + version "3.1.3" + resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4" + dependencies: + boom "2.x.x" + cryptiles "2.x.x" + hoek "2.x.x" + sntp "1.x.x" + +hmac-drbg@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/hmac-drbg/-/hmac-drbg-1.0.0.tgz#3db471f45aae4a994a0688322171f51b8b91bee5" + dependencies: + hash.js "^1.0.3" + minimalistic-assert "^1.0.0" + minimalistic-crypto-utils "^1.0.1" + +hoek@2.x.x: + version "2.16.3" + resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed" + +home-or-tmp@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/home-or-tmp/-/home-or-tmp-2.0.0.tgz#e36c3f2d2cae7d746a857e38d18d5f32a7882db8" + dependencies: + os-homedir "^1.0.0" + os-tmpdir "^1.0.1" + +hosted-git-info@^2.1.4: + version "2.2.0" + resolved "https://registry.yarnpkg.com/hosted-git-info/-/hosted-git-info-2.2.0.tgz#7a0d097863d886c0fabbdcd37bf1758d8becf8a5" + +hpack.js@^2.1.6: + version "2.1.6" + resolved "https://registry.yarnpkg.com/hpack.js/-/hpack.js-2.1.6.tgz#87774c0949e513f42e84575b3c45681fade2a0b2" + dependencies: + inherits "^2.0.1" + obuf "^1.0.0" + readable-stream "^2.0.1" + wbuf "^1.1.0" + +html-entities@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/html-entities/-/html-entities-1.2.0.tgz#41948caf85ce82fed36e4e6a0ed371a6664379e2" + +http-deceiver@^1.2.4: + version "1.2.7" + resolved "https://registry.yarnpkg.com/http-deceiver/-/http-deceiver-1.2.7.tgz#fa7168944ab9a519d337cb0bec7284dc3e723d87" + +http-errors@~1.5.0: + version "1.5.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.5.1.tgz#788c0d2c1de2c81b9e6e8c01843b6b97eb920750" + dependencies: + inherits "2.0.3" + setprototypeof "1.0.2" + statuses ">= 1.3.1 < 2" + +http-errors@~1.6.1: + version "1.6.1" + resolved "https://registry.yarnpkg.com/http-errors/-/http-errors-1.6.1.tgz#5f8b8ed98aca545656bf572997387f904a722257" + dependencies: + depd "1.1.0" + inherits "2.0.3" + setprototypeof "1.0.3" + statuses ">= 1.3.1 < 2" + +http-proxy-middleware@~0.17.1: + version "0.17.4" + resolved "https://registry.yarnpkg.com/http-proxy-middleware/-/http-proxy-middleware-0.17.4.tgz#642e8848851d66f09d4f124912846dbaeb41b833" + dependencies: + http-proxy "^1.16.2" + is-glob "^3.1.0" + lodash "^4.17.2" + micromatch "^2.3.11" + +http-proxy@^1.16.2: + version "1.16.2" + resolved "https://registry.yarnpkg.com/http-proxy/-/http-proxy-1.16.2.tgz#06dff292952bf64dbe8471fa9df73066d4f37742" + dependencies: + eventemitter3 "1.x.x" + requires-port "1.x.x" + +http-signature@~1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.1.1.tgz#df72e267066cd0ac67fb76adf8e134a8fbcf91bf" + dependencies: + assert-plus "^0.2.0" + jsprim "^1.2.2" + sshpk "^1.7.0" + +https-browserify@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/https-browserify/-/https-browserify-0.0.1.tgz#3f91365cabe60b77ed0ebba24b454e3e09d95a82" + +iconv-lite@0.4, iconv-lite@~0.4.13: + version "0.4.15" + resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.15.tgz#fe265a218ac6a57cfe854927e9d04c19825eddeb" + +ieee754@^1.1.4, ieee754@^1.1.6: + version "1.1.8" + resolved "https://registry.yarnpkg.com/ieee754/-/ieee754-1.1.8.tgz#be33d40ac10ef1926701f6f08a2d86fbfd1ad3e4" + +immutable@^3.8.1: + version "3.8.1" + resolved "https://registry.yarnpkg.com/immutable/-/immutable-3.8.1.tgz#200807f11ab0f72710ea485542de088075f68cd2" + +indexof@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/indexof/-/indexof-0.0.1.tgz#82dc336d232b9062179d05ab3293a66059fd435d" + +inflight@^1.0.4: + version "1.0.6" + resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9" + dependencies: + once "^1.3.0" + wrappy "1" + +inherits@2, inherits@2.0.3, inherits@^2.0.1, inherits@~2.0.0, inherits@~2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de" + +inherits@2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.1.tgz#b17d08d326b4423e568eff719f91b0b1cbdf69f1" + +ini@~1.3.0: + version "1.3.4" + resolved "https://registry.yarnpkg.com/ini/-/ini-1.3.4.tgz#0537cb79daf59b59a1a517dff706c86ec039162e" + +interpret@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/interpret/-/interpret-1.0.1.tgz#d579fb7f693b858004947af39fa0db49f795602c" + +invariant@^2.2.0: + version "2.2.2" + resolved "https://registry.yarnpkg.com/invariant/-/invariant-2.2.2.tgz#9e1f56ac0acdb6bf303306f338be3b204ae60360" + dependencies: + loose-envify "^1.0.0" + +invert-kv@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/invert-kv/-/invert-kv-1.0.0.tgz#104a8e4aaca6d3d8cd157a8ef8bfab2d7a3ffdb6" + +ipaddr.js@1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/ipaddr.js/-/ipaddr.js-1.2.0.tgz#8aba49c9192799585bdd643e0ccb50e8ae777ba4" + +is-arrayish@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-arrayish/-/is-arrayish-0.2.1.tgz#77c99840527aa8ecb1a8ba697b80645a7a926a9d" + +is-binary-path@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/is-binary-path/-/is-binary-path-1.0.1.tgz#75f16642b480f187a711c814161fd3a4a7655898" + dependencies: + binary-extensions "^1.0.0" + +is-buffer@^1.0.2: + version "1.1.5" + resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.5.tgz#1f3b26ef613b214b88cbca23cc6c01d87961eecc" + +is-builtin-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-builtin-module/-/is-builtin-module-1.0.0.tgz#540572d34f7ac3119f8f76c30cbc1b1e037affbe" + dependencies: + builtin-modules "^1.0.0" + +is-dotfile@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-dotfile/-/is-dotfile-1.0.2.tgz#2c132383f39199f8edc268ca01b9b007d205cc4d" + +is-equal-shallow@^0.1.3: + version "0.1.3" + resolved "https://registry.yarnpkg.com/is-equal-shallow/-/is-equal-shallow-0.1.3.tgz#2238098fc221de0bcfa5d9eac4c45d638aa1c534" + dependencies: + is-primitive "^2.0.0" + +is-extendable@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-extendable/-/is-extendable-0.1.1.tgz#62b110e289a471418e3ec36a617d472e301dfc89" + +is-extglob@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-1.0.0.tgz#ac468177c4943405a092fc8f29760c6ffc6206c0" + +is-extglob@^2.1.0: + version "2.1.1" + resolved "https://registry.yarnpkg.com/is-extglob/-/is-extglob-2.1.1.tgz#a88c02535791f02ed37c76a1b9ea9773c833f8c2" + +is-finite@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/is-finite/-/is-finite-1.0.2.tgz#cc6677695602be550ef11e8b4aa6305342b6d0aa" + dependencies: + number-is-nan "^1.0.0" + +is-fullwidth-code-point@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-fullwidth-code-point/-/is-fullwidth-code-point-1.0.0.tgz#ef9e31386f031a7f0d643af82fde50c457ef00cb" + dependencies: + number-is-nan "^1.0.0" + +is-glob@^2.0.0, is-glob@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-2.0.1.tgz#d096f926a3ded5600f3fdfd91198cb0888c2d863" + dependencies: + is-extglob "^1.0.0" + +is-glob@^3.1.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/is-glob/-/is-glob-3.1.0.tgz#7ba5ae24217804ac70707b96922567486cc3e84a" + dependencies: + is-extglob "^2.1.0" + +is-number@^2.0.2, is-number@^2.1.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/is-number/-/is-number-2.1.0.tgz#01fcbbb393463a548f2f466cce16dece49db908f" + dependencies: + kind-of "^3.0.2" + +is-posix-bracket@^0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/is-posix-bracket/-/is-posix-bracket-0.1.1.tgz#3334dc79774368e92f016e6fbc0a88f5cd6e6bc4" + +is-primitive@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/is-primitive/-/is-primitive-2.0.0.tgz#207bab91638499c07b2adf240a41a87210034575" + +is-stream@^1.0.1: + version "1.1.0" + resolved "https://registry.yarnpkg.com/is-stream/-/is-stream-1.1.0.tgz#12d4a3dd4e68e0b79ceb8dbc84173ae80d91ca44" + +is-typedarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a" + +is-utf8@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/is-utf8/-/is-utf8-0.2.1.tgz#4b0da1442104d1b336340e80797e865cf39f7d72" + +isarray@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-0.0.1.tgz#8a18acfca9a8f4177e09abfc6038939b05d1eedf" + +isarray@1.0.0, isarray@^1.0.0, isarray@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11" + +isobject@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/isobject/-/isobject-2.1.0.tgz#f065561096a3f1da2ef46272f815c840d87e0c89" + dependencies: + isarray "1.0.0" + +isomorphic-fetch@^2.1.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/isomorphic-fetch/-/isomorphic-fetch-2.2.1.tgz#611ae1acf14f5e81f729507472819fe9733558a9" + dependencies: + node-fetch "^1.0.1" + whatwg-fetch ">=0.10.0" + +isstream@~0.1.2: + version "0.1.2" + resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a" + +jodid25519@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/jodid25519/-/jodid25519-1.0.2.tgz#06d4912255093419477d425633606e0e90782967" + dependencies: + jsbn "~0.1.0" + +js-tokens@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/js-tokens/-/js-tokens-3.0.1.tgz#08e9f132484a2c45a30907e9dc4d5567b7f114d7" + +jsbn@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513" + +jsesc@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-1.3.0.tgz#46c3fec8c1892b12b0833db9bc7622176dbab34b" + +jsesc@~0.5.0: + version "0.5.0" + resolved "https://registry.yarnpkg.com/jsesc/-/jsesc-0.5.0.tgz#e7dee66e35d6fc16f710fe91d5cf69f70f08911d" + +json-loader@^0.5.4: + version "0.5.4" + resolved "https://registry.yarnpkg.com/json-loader/-/json-loader-0.5.4.tgz#8baa1365a632f58a3c46d20175fc6002c96e37de" + +json-schema@0.2.3: + version "0.2.3" + resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13" + +json-stable-stringify@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/json-stable-stringify/-/json-stable-stringify-1.0.1.tgz#9a759d39c5f2ff503fd5300646ed445f88c4f9af" + dependencies: + jsonify "~0.0.0" + +json-stringify-safe@~5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb" + +json3@^3.3.2: + version "3.3.2" + resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1" + +json5@^0.5.0: + version "0.5.1" + resolved "https://registry.yarnpkg.com/json5/-/json5-0.5.1.tgz#1eade7acc012034ad84e2396767ead9fa5495821" + +jsonify@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/jsonify/-/jsonify-0.0.0.tgz#2c74b6ee41d93ca51b7b5aaee8f503631d252a73" + +jsonlint-lines-primitives@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/jsonlint-lines-primitives/-/jsonlint-lines-primitives-1.6.0.tgz#bb89f60c8b9b612fd913ddaa236649b840d86611" + dependencies: + JSV ">= 4.0.x" + nomnom ">= 1.5.x" + +jsprim@^1.2.2: + version "1.3.1" + resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.3.1.tgz#2a7256f70412a29ee3670aaca625994c4dcff252" + dependencies: + extsprintf "1.0.2" + json-schema "0.2.3" + verror "1.3.6" + +kdbush@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/kdbush/-/kdbush-1.0.1.tgz#3cbd03e9dead9c0f6f66ccdb96450e5cecc640e0" + +kind-of@^3.0.2: + version "3.1.0" + resolved "https://registry.yarnpkg.com/kind-of/-/kind-of-3.1.0.tgz#475d698a5e49ff5e53d14e3e732429dc8bf4cf47" + dependencies: + is-buffer "^1.0.2" + +lazy-cache@^1.0.3: + version "1.0.4" + resolved "https://registry.yarnpkg.com/lazy-cache/-/lazy-cache-1.0.4.tgz#a1d78fc3a50474cb80845d3b3b6e1da49a446e8e" + +lcid@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/lcid/-/lcid-1.0.0.tgz#308accafa0bc483a3867b4b6f2b9506251d1b835" + dependencies: + invert-kv "^1.0.0" + +levn@~0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/levn/-/levn-0.3.0.tgz#3b09924edf9f083c0490fdd4c0bc4421e04764ee" + dependencies: + prelude-ls "~1.1.2" + type-check "~0.3.2" + +load-json-file@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/load-json-file/-/load-json-file-1.1.0.tgz#956905708d58b4bab4c2261b04f59f31c99374c0" + dependencies: + graceful-fs "^4.1.2" + parse-json "^2.2.0" + pify "^2.0.0" + pinkie-promise "^2.0.0" + strip-bom "^2.0.0" + +loader-runner@^2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/loader-runner/-/loader-runner-2.3.0.tgz#f482aea82d543e07921700d5a46ef26fdac6b8a2" + +loader-utils@^0.2.16: + version "0.2.17" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-0.2.17.tgz#f86e6374d43205a6e6c60e9196f17c0299bfb348" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + object-assign "^4.0.1" + +loader-utils@^1.0.2: + version "1.0.3" + resolved "https://registry.yarnpkg.com/loader-utils/-/loader-utils-1.0.3.tgz#566c320c24c33cb3f02db4df83f3dbf60b253de3" + dependencies: + big.js "^3.1.3" + emojis-list "^2.0.0" + json5 "^0.5.0" + +lodash._baseisequal@^3.0.0: + version "3.0.7" + resolved "https://registry.yarnpkg.com/lodash._baseisequal/-/lodash._baseisequal-3.0.7.tgz#d8025f76339d29342767dcc887ce5cb95a5b51f1" + dependencies: + lodash.isarray "^3.0.0" + lodash.istypedarray "^3.0.0" + lodash.keys "^3.0.0" + +lodash._bindcallback@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/lodash._bindcallback/-/lodash._bindcallback-3.0.1.tgz#e531c27644cf8b57a99e17ed95b35c748789392e" + +lodash._getnative@^3.0.0: + version "3.9.1" + resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5" + +lodash.flattendeep@^4.4.0: + version "4.4.0" + resolved "https://registry.yarnpkg.com/lodash.flattendeep/-/lodash.flattendeep-4.4.0.tgz#fb030917f86a3134e5bc9bec0d69e0013ddfedb2" + +lodash.isarguments@^3.0.0: + version "3.1.0" + resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a" + +lodash.isarray@^3.0.0: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55" + +lodash.isequal@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/lodash.isequal/-/lodash.isequal-3.0.4.tgz#1c35eb3b6ef0cd1ff51743e3ea3cf7fdffdacb64" + dependencies: + lodash._baseisequal "^3.0.0" + lodash._bindcallback "^3.0.0" + +lodash.istypedarray@^3.0.0: + version "3.0.6" + resolved "https://registry.yarnpkg.com/lodash.istypedarray/-/lodash.istypedarray-3.0.6.tgz#c9a477498607501d8e8494d283b87c39281cef62" + +lodash.keys@^3.0.0: + version "3.1.2" + resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a" + dependencies: + lodash._getnative "^3.0.0" + lodash.isarguments "^3.0.0" + lodash.isarray "^3.0.0" + +lodash@^4.14.0, lodash@^4.17.2, lodash@^4.2.0: + version "4.17.4" + resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae" + +longest@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/longest/-/longest-1.0.1.tgz#30a0b2da38f73770e8294a0d22e6625ed77d0097" + +loose-envify@^1.0.0, loose-envify@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/loose-envify/-/loose-envify-1.3.1.tgz#d1a8ad33fa9ce0e713d65fdd0ac8b748d478c848" + dependencies: + js-tokens "^3.0.0" + +luma.gl@3.0.0-beta.11: + version "3.0.0-beta.11" + resolved "https://registry.yarnpkg.com/luma.gl/-/luma.gl-3.0.0-beta.11.tgz#e4f015c8972df8cdbc060aa114c7e7104908f54f" + dependencies: + gl-constants "^1.0.0" + gl-matrix "^2.3.2" + webgl-debug "^1.0.2" + +mapbox-gl-function@mapbox/mapbox-gl-function#111a2b442be0689a65f5818dd2603c9b06962be0: + version "1.3.0" + resolved "https://codeload.github.com/mapbox/mapbox-gl-function/tar.gz/111a2b442be0689a65f5818dd2603c9b06962be0" + +mapbox-gl-shaders@mapbox/mapbox-gl-shaders#44b65f8090a74cbb0319664d010b8d8a8a1512b0: + version "1.0.0" + resolved "https://codeload.github.com/mapbox/mapbox-gl-shaders/tar.gz/44b65f8090a74cbb0319664d010b8d8a8a1512b0" + dependencies: + brfs "^1.4.0" + +mapbox-gl-style-spec@mapbox/mapbox-gl-style-spec#7d330d2abf1775abc95ab8b889089cf5ff579357: + version "8.9.0" + resolved "https://codeload.github.com/mapbox/mapbox-gl-style-spec/tar.gz/7d330d2abf1775abc95ab8b889089cf5ff579357" + dependencies: + csscolorparser "~1.0.2" + jsonlint-lines-primitives "~1.6.0" + lodash.isequal "^3.0.4" + minimist "0.0.8" + rw "^0.1.4" + sort-object "^0.3.2" + +mapbox-gl-supported@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/mapbox-gl-supported/-/mapbox-gl-supported-1.2.0.tgz#cbd34df894206cadda9a33c8d9a4609f26bb1989" + +mapbox-gl@0.26.0: + version "0.26.0" + resolved "https://registry.yarnpkg.com/mapbox-gl/-/mapbox-gl-0.26.0.tgz#c667e8870ade4fb46f196fb4f9a675d2f3d70c3b" + dependencies: + csscolorparser "^1.0.2" + earcut "^2.0.3" + feature-filter "^2.2.0" + geojson-rewind "^0.1.0" + geojson-vt "^2.4.0" + gl-matrix "^2.3.1" + grid-index "^1.0.0" + mapbox-gl-function mapbox/mapbox-gl-function#111a2b442be0689a65f5818dd2603c9b06962be0 + mapbox-gl-shaders mapbox/mapbox-gl-shaders#44b65f8090a74cbb0319664d010b8d8a8a1512b0 + mapbox-gl-style-spec mapbox/mapbox-gl-style-spec#7d330d2abf1775abc95ab8b889089cf5ff579357 + mapbox-gl-supported "^1.2.0" + package-json-versionify "^1.0.2" + pbf "^1.3.2" + pngjs "^2.2.0" + point-geometry "^0.0.0" + quickselect "^1.0.0" + request "^2.39.0" + shelf-pack "^1.0.0" + supercluster "^2.0.1" + tinyqueue "^1.1.0" + unassertify "^2.0.0" + unitbezier "^0.0.0" + vector-tile "^1.3.0" + vt-pbf "^2.0.2" + webworkify "^1.4.0" + whoots-js "^2.0.0" + +media-typer@0.3.0: + version "0.3.0" + resolved "https://registry.yarnpkg.com/media-typer/-/media-typer-0.3.0.tgz#8710d7af0aa626f8fffa1ce00168545263255748" + +memory-fs@^0.4.0, memory-fs@~0.4.1: + version "0.4.1" + resolved "https://registry.yarnpkg.com/memory-fs/-/memory-fs-0.4.1.tgz#3a9a20b8462523e447cfbc7e8bb80ed667bfc552" + dependencies: + errno "^0.1.3" + readable-stream "^2.0.1" + +merge-descriptors@1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/merge-descriptors/-/merge-descriptors-1.0.1.tgz#b00aaa556dd8b44568150ec9d1b953f3f90cbb61" + +methods@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/methods/-/methods-1.1.2.tgz#5529a4d67654134edcc5266656835b0f851afcee" + +micromatch@^2.1.5, micromatch@^2.3.11: + version "2.3.11" + resolved "https://registry.yarnpkg.com/micromatch/-/micromatch-2.3.11.tgz#86677c97d1720b363431d04d0d15293bd38c1565" + dependencies: + arr-diff "^2.0.0" + array-unique "^0.2.1" + braces "^1.8.2" + expand-brackets "^0.1.4" + extglob "^0.3.1" + filename-regex "^2.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.1" + kind-of "^3.0.2" + normalize-path "^2.0.1" + object.omit "^2.0.0" + parse-glob "^3.0.4" + regex-cache "^0.4.2" + +miller-rabin@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/miller-rabin/-/miller-rabin-4.0.0.tgz#4a62fb1d42933c05583982f4c716f6fb9e6c6d3d" + dependencies: + bn.js "^4.0.0" + brorand "^1.0.1" + +"mime-db@>= 1.24.0 < 2", mime-db@~1.26.0: + version "1.26.0" + resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.26.0.tgz#eaffcd0e4fc6935cf8134da246e2e6c35305adff" + +mime-types@^2.1.12, mime-types@~2.1.11, mime-types@~2.1.13, mime-types@~2.1.7: + version "2.1.14" + resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.14.tgz#f7ef7d97583fcaf3b7d282b6f8b5679dab1e94ee" + dependencies: + mime-db "~1.26.0" + +mime@1.3.4, mime@^1.3.4: + version "1.3.4" + resolved "https://registry.yarnpkg.com/mime/-/mime-1.3.4.tgz#115f9e3b6b3daf2959983cb38f149a2d40eb5d53" + +min-document@^2.19.0: + version "2.19.0" + resolved "https://registry.yarnpkg.com/min-document/-/min-document-2.19.0.tgz#7bd282e3f5842ed295bb748cdd9f1ffa2c824685" + dependencies: + dom-walk "^0.1.0" + +minimalistic-assert@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/minimalistic-assert/-/minimalistic-assert-1.0.0.tgz#702be2dda6b37f4836bcb3f5db56641b64a1d3d3" + +minimalistic-crypto-utils@^1.0.0, minimalistic-crypto-utils@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/minimalistic-crypto-utils/-/minimalistic-crypto-utils-1.0.1.tgz#f6c00c1c0b082246e5c4d99dfb8c7c083b2b582a" + +minimatch@^3.0.0, minimatch@^3.0.2: + version "3.0.3" + resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.3.tgz#2a4e4090b96b2db06a9d7df01055a62a77c9b774" + dependencies: + brace-expansion "^1.0.0" + +minimist@0.0.5: + version "0.0.5" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.5.tgz#d7aa327bcecf518f9106ac6b8f003fa3bcea8566" + +minimist@0.0.8: + version "0.0.8" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d" + +minimist@^1.1.3, minimist@^1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/minimist/-/minimist-1.2.0.tgz#a35008b20f41383eec1fb914f4cd5df79a264284" + +mkdirp@0.5.x, "mkdirp@>=0.5 0", mkdirp@^0.5.1, mkdirp@~0.5.0, mkdirp@~0.5.1: + version "0.5.1" + resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903" + dependencies: + minimist "0.0.8" + +ms@0.7.1: + version "0.7.1" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098" + +ms@0.7.2: + version "0.7.2" + resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.2.tgz#ae25cf2512b3885a1d95d7f037868d8431124765" + +multi-stage-sourcemap@^0.2.1: + version "0.2.1" + resolved "https://registry.yarnpkg.com/multi-stage-sourcemap/-/multi-stage-sourcemap-0.2.1.tgz#b09fc8586eaa17f81d575c4ad02e0f7a3f6b1105" + dependencies: + source-map "^0.1.34" + +nan@^2.3.0: + version "2.5.1" + resolved "https://registry.yarnpkg.com/nan/-/nan-2.5.1.tgz#d5b01691253326a97a2bbee9e61c55d8d60351e2" + +negotiator@0.6.1: + version "0.6.1" + resolved "https://registry.yarnpkg.com/negotiator/-/negotiator-0.6.1.tgz#2b327184e8992101177b28563fb5e7102acd0ca9" + +node-fetch@^1.0.1: + version "1.6.3" + resolved "https://registry.yarnpkg.com/node-fetch/-/node-fetch-1.6.3.tgz#dc234edd6489982d58e8f0db4f695029abcd8c04" + dependencies: + encoding "^0.1.11" + is-stream "^1.0.1" + +node-libs-browser@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/node-libs-browser/-/node-libs-browser-2.0.0.tgz#a3a59ec97024985b46e958379646f96c4b616646" + dependencies: + assert "^1.1.1" + browserify-zlib "^0.1.4" + buffer "^4.3.0" + console-browserify "^1.1.0" + constants-browserify "^1.0.0" + crypto-browserify "^3.11.0" + domain-browser "^1.1.1" + events "^1.0.0" + https-browserify "0.0.1" + os-browserify "^0.2.0" + path-browserify "0.0.0" + process "^0.11.0" + punycode "^1.2.4" + querystring-es3 "^0.2.0" + readable-stream "^2.0.5" + stream-browserify "^2.0.1" + stream-http "^2.3.1" + string_decoder "^0.10.25" + timers-browserify "^2.0.2" + tty-browserify "0.0.0" + url "^0.11.0" + util "^0.10.3" + vm-browserify "0.0.4" + +node-pre-gyp@^0.6.29: + version "0.6.33" + resolved "https://registry.yarnpkg.com/node-pre-gyp/-/node-pre-gyp-0.6.33.tgz#640ac55198f6a925972e0c16c4ac26a034d5ecc9" + dependencies: + mkdirp "~0.5.1" + nopt "~3.0.6" + npmlog "^4.0.1" + rc "~1.1.6" + request "^2.79.0" + rimraf "~2.5.4" + semver "~5.3.0" + tar "~2.2.1" + tar-pack "~3.3.0" + +"nomnom@>= 1.5.x": + version "1.8.1" + resolved "https://registry.yarnpkg.com/nomnom/-/nomnom-1.8.1.tgz#2151f722472ba79e50a76fc125bb8c8f2e4dc2a7" + dependencies: + chalk "~0.4.0" + underscore "~1.6.0" + +nopt@~3.0.6: + version "3.0.6" + resolved "https://registry.yarnpkg.com/nopt/-/nopt-3.0.6.tgz#c6465dbf08abcd4db359317f79ac68a646b28ff9" + dependencies: + abbrev "1" + +normalize-package-data@^2.3.2: + version "2.3.6" + resolved "https://registry.yarnpkg.com/normalize-package-data/-/normalize-package-data-2.3.6.tgz#498fa420c96401f787402ba21e600def9f981fff" + dependencies: + hosted-git-info "^2.1.4" + is-builtin-module "^1.0.0" + semver "2 || 3 || 4 || 5" + validate-npm-package-license "^3.0.1" + +normalize-path@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/normalize-path/-/normalize-path-2.0.1.tgz#47886ac1662760d4261b7d979d241709d3ce3f7a" + +npmlog@^4.0.1: + version "4.0.2" + resolved "https://registry.yarnpkg.com/npmlog/-/npmlog-4.0.2.tgz#d03950e0e78ce1527ba26d2a7592e9348ac3e75f" + dependencies: + are-we-there-yet "~1.1.2" + console-control-strings "~1.1.0" + gauge "~2.7.1" + set-blocking "~2.0.0" + +number-is-nan@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/number-is-nan/-/number-is-nan-1.0.1.tgz#097b602b53422a522c1afb8790318336941a011d" + +oauth-sign@~0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43" + +object-assign@^4.0.1, object-assign@^4.1.0: + version "4.1.1" + resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863" + +object-inspect@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-inspect/-/object-inspect-0.4.0.tgz#f5157c116c1455b243b06ee97703392c5ad89fec" + +object-keys@^1.0.6: + version "1.0.11" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-1.0.11.tgz#c54601778ad560f1142ce0e01bcca8b56d13426d" + +object-keys@~0.4.0: + version "0.4.0" + resolved "https://registry.yarnpkg.com/object-keys/-/object-keys-0.4.0.tgz#28a6aae7428dd2c3a92f3d95f21335dd204e0336" + +object.omit@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/object.omit/-/object.omit-2.0.1.tgz#1a9c744829f39dbb858c76ca3579ae2a54ebd1fa" + dependencies: + for-own "^0.1.4" + is-extendable "^0.1.1" + +obuf@^1.0.0, obuf@^1.1.0: + version "1.1.1" + resolved "https://registry.yarnpkg.com/obuf/-/obuf-1.1.1.tgz#104124b6c602c6796881a042541d36db43a5264e" + +on-finished@~2.3.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/on-finished/-/on-finished-2.3.0.tgz#20f1336481b083cd75337992a16971aa2d906947" + dependencies: + ee-first "1.1.1" + +on-headers@~1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/on-headers/-/on-headers-1.0.1.tgz#928f5d0f470d49342651ea6794b0857c100693f7" + +once@^1.3.0, once@~1.3.3: + version "1.3.3" + resolved "https://registry.yarnpkg.com/once/-/once-1.3.3.tgz#b2e261557ce4c314ec8304f3fa82663e4297ca20" + dependencies: + wrappy "1" + +opn@4.0.2: + version "4.0.2" + resolved "https://registry.yarnpkg.com/opn/-/opn-4.0.2.tgz#7abc22e644dff63b0a96d5ab7f2790c0f01abc95" + dependencies: + object-assign "^4.0.1" + pinkie-promise "^2.0.0" + +optionator@^0.8.1: + version "0.8.2" + resolved "https://registry.yarnpkg.com/optionator/-/optionator-0.8.2.tgz#364c5e409d3f4d6301d6c0b4c05bba50180aeb64" + dependencies: + deep-is "~0.1.3" + fast-levenshtein "~2.0.4" + levn "~0.3.0" + prelude-ls "~1.1.2" + type-check "~0.3.2" + wordwrap "~1.0.0" + +original@>=0.0.5: + version "1.0.0" + resolved "https://registry.yarnpkg.com/original/-/original-1.0.0.tgz#9147f93fa1696d04be61e01bd50baeaca656bd3b" + dependencies: + url-parse "1.0.x" + +os-browserify@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/os-browserify/-/os-browserify-0.2.1.tgz#63fc4ccee5d2d7763d26bbf8601078e6c2e0044f" + +os-homedir@^1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-homedir/-/os-homedir-1.0.2.tgz#ffbc4988336e0e833de0c168c7ef152121aa7fb3" + +os-locale@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/os-locale/-/os-locale-1.4.0.tgz#20f9f17ae29ed345e8bde583b13d2009803c14d9" + dependencies: + lcid "^1.0.0" + +os-tmpdir@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/os-tmpdir/-/os-tmpdir-1.0.2.tgz#bbe67406c79aa85c5cfec766fe5734555dfa1274" + +package-json-versionify@^1.0.2: + version "1.0.4" + resolved "https://registry.yarnpkg.com/package-json-versionify/-/package-json-versionify-1.0.4.tgz#5860587a944873a6b7e6d26e8e51ffb22315bf17" + dependencies: + browserify-package-json "^1.0.0" + +pako@~0.2.0: + version "0.2.9" + resolved "https://registry.yarnpkg.com/pako/-/pako-0.2.9.tgz#f3f7522f4ef782348da8161bad9ecfd51bf83a75" + +parse-asn1@^5.0.0: + version "5.0.0" + resolved "https://registry.yarnpkg.com/parse-asn1/-/parse-asn1-5.0.0.tgz#35060f6d5015d37628c770f4e091a0b5a278bc23" + dependencies: + asn1.js "^4.0.0" + browserify-aes "^1.0.0" + create-hash "^1.1.0" + evp_bytestokey "^1.0.0" + pbkdf2 "^3.0.3" + +parse-glob@^3.0.4: + version "3.0.4" + resolved "https://registry.yarnpkg.com/parse-glob/-/parse-glob-3.0.4.tgz#b2c376cfb11f35513badd173ef0bb6e3a388391c" + dependencies: + glob-base "^0.3.0" + is-dotfile "^1.0.0" + is-extglob "^1.0.0" + is-glob "^2.0.0" + +parse-json@^2.2.0: + version "2.2.0" + resolved "https://registry.yarnpkg.com/parse-json/-/parse-json-2.2.0.tgz#f480f40434ef80741f8469099f8dea18f55a4dc9" + dependencies: + error-ex "^1.2.0" + +parseurl@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/parseurl/-/parseurl-1.3.1.tgz#c8ab8c9223ba34888aa64a297b28853bec18da56" + +path-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/path-browserify/-/path-browserify-0.0.0.tgz#a0b870729aae214005b7d5032ec2cbbb0fb4451a" + +path-exists@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/path-exists/-/path-exists-2.1.0.tgz#0feb6c64f0fc518d9a754dd5efb62c7022761f4b" + dependencies: + pinkie-promise "^2.0.0" + +path-is-absolute@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f" + +path-parse@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/path-parse/-/path-parse-1.0.5.tgz#3c1adf871ea9cd6c9431b6ea2bd74a0ff055c4c1" + +path-to-regexp@0.1.7: + version "0.1.7" + resolved "https://registry.yarnpkg.com/path-to-regexp/-/path-to-regexp-0.1.7.tgz#df604178005f522f15eb4490e7247a1bfaa67f8c" + +path-type@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/path-type/-/path-type-1.1.0.tgz#59c44f7ee491da704da415da5a4070ba4f8fe441" + dependencies: + graceful-fs "^4.1.2" + pify "^2.0.0" + pinkie-promise "^2.0.0" + +pbf@^1.3.2: + version "1.3.7" + resolved "https://registry.yarnpkg.com/pbf/-/pbf-1.3.7.tgz#1e3d047ba3cbe8086ae854a25503ab4537d4335d" + dependencies: + ieee754 "^1.1.6" + resolve-protobuf-schema "^2.0.0" + +pbkdf2@^3.0.3: + version "3.0.9" + resolved "https://registry.yarnpkg.com/pbkdf2/-/pbkdf2-3.0.9.tgz#f2c4b25a600058b3c3773c086c37dbbee1ffe693" + dependencies: + create-hmac "^1.1.2" + +performance-now@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-0.2.0.tgz#33ef30c5c77d4ea21c5a53869d91b56d8f2555e5" + +pify@^2.0.0: + version "2.3.0" + resolved "https://registry.yarnpkg.com/pify/-/pify-2.3.0.tgz#ed141a6ac043a849ea588498e7dca8b15330e90c" + +pinkie-promise@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/pinkie-promise/-/pinkie-promise-2.0.1.tgz#2135d6dfa7a358c069ac9b178776288228450ffa" + dependencies: + pinkie "^2.0.0" + +pinkie@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/pinkie/-/pinkie-2.0.4.tgz#72556b80cfa0d48a974e80e77248e80ed4f7f870" + +pkg-dir@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/pkg-dir/-/pkg-dir-1.0.0.tgz#7a4b508a8d5bb2d629d447056ff4e9c9314cf3d4" + dependencies: + find-up "^1.0.0" + +pngjs@^2.2.0: + version "2.3.1" + resolved "https://registry.yarnpkg.com/pngjs/-/pngjs-2.3.1.tgz#11d1e12b9cb64d63e30c143a330f4c1f567da85f" + +point-geometry@0.0.0, point-geometry@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/point-geometry/-/point-geometry-0.0.0.tgz#6fcbcad7a803b6418247dd6e49c2853c584daff7" + +portfinder@^1.0.9: + version "1.0.13" + resolved "https://registry.yarnpkg.com/portfinder/-/portfinder-1.0.13.tgz#bb32ecd87c27104ae6ee44b5a3ccbf0ebb1aede9" + dependencies: + async "^1.5.2" + debug "^2.2.0" + mkdirp "0.5.x" + +prelude-ls@~1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/prelude-ls/-/prelude-ls-1.1.2.tgz#21932a549f5e52ffd9a827f570e04be62a97da54" + +preserve@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/preserve/-/preserve-0.2.0.tgz#815ed1f6ebc65926f865b310c0713bcb3315ce4b" + +private@^0.1.6: + version "0.1.7" + resolved "https://registry.yarnpkg.com/private/-/private-0.1.7.tgz#68ce5e8a1ef0a23bb570cc28537b5332aba63ef1" + +process-nextick-args@~1.0.6: + version "1.0.7" + resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3" + +process@^0.11.0: + version "0.11.9" + resolved "https://registry.yarnpkg.com/process/-/process-0.11.9.tgz#7bd5ad21aa6253e7da8682264f1e11d11c0318c1" + +process@~0.5.1: + version "0.5.2" + resolved "https://registry.yarnpkg.com/process/-/process-0.5.2.tgz#1638d8a8e34c2f440a91db95ab9aeb677fc185cf" + +promise@^7.1.1: + version "7.1.1" + resolved "https://registry.yarnpkg.com/promise/-/promise-7.1.1.tgz#489654c692616b8aa55b0724fa809bb7db49c5bf" + dependencies: + asap "~2.0.3" + +protocol-buffers-schema@^2.0.2: + version "2.2.0" + resolved "https://registry.yarnpkg.com/protocol-buffers-schema/-/protocol-buffers-schema-2.2.0.tgz#d29c6cd73fb655978fb6989691180db844119f61" + +proxy-addr@~1.1.3: + version "1.1.3" + resolved "https://registry.yarnpkg.com/proxy-addr/-/proxy-addr-1.1.3.tgz#dc97502f5722e888467b3fa2297a7b1ff47df074" + dependencies: + forwarded "~0.1.0" + ipaddr.js "1.2.0" + +prr@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/prr/-/prr-0.0.0.tgz#1a84b85908325501411853d0081ee3fa86e2926a" + +public-encrypt@^4.0.0: + version "4.0.0" + resolved "https://registry.yarnpkg.com/public-encrypt/-/public-encrypt-4.0.0.tgz#39f699f3a46560dd5ebacbca693caf7c65c18cc6" + dependencies: + bn.js "^4.1.0" + browserify-rsa "^4.0.0" + create-hash "^1.1.0" + parse-asn1 "^5.0.0" + randombytes "^2.0.1" + +punycode@1.3.2: + version "1.3.2" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.3.2.tgz#9653a036fb7c1ee42342f2325cceefea3926c48d" + +punycode@^1.2.4, punycode@^1.4.1: + version "1.4.1" + resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e" + +pure-render-decorator@^1.1.0: + version "1.2.1" + resolved "https://registry.yarnpkg.com/pure-render-decorator/-/pure-render-decorator-1.2.1.tgz#568870eeca17a1cee536b4fe94a3477fcd31eeb9" + dependencies: + fbjs "^0.8.0" + +qs@6.4.0, qs@~6.4.0: + version "6.4.0" + resolved "https://registry.yarnpkg.com/qs/-/qs-6.4.0.tgz#13e26d28ad6b0ffaa91312cd3bf708ed351e7233" + +querystring-es3@^0.2.0: + version "0.2.1" + resolved "https://registry.yarnpkg.com/querystring-es3/-/querystring-es3-0.2.1.tgz#9ec61f79049875707d69414596fd907a4d711e73" + +querystring@0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/querystring/-/querystring-0.2.0.tgz#b209849203bb25df820da756e747005878521620" + +querystringify@0.0.x: + version "0.0.4" + resolved "https://registry.yarnpkg.com/querystringify/-/querystringify-0.0.4.tgz#0cf7f84f9463ff0ae51c4c4b142d95be37724d9c" + +quickselect@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/quickselect/-/quickselect-1.0.0.tgz#02630818f9aae4ecab26f0103f98d061c17c58f3" + +quote-stream@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-1.0.2.tgz#84963f8c9c26b942e153feeb53aae74652b7e0b2" + dependencies: + buffer-equal "0.0.1" + minimist "^1.1.3" + through2 "^2.0.0" + +quote-stream@~0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/quote-stream/-/quote-stream-0.0.0.tgz#cde29e94c409b16e19dc7098b89b6658f9721d3b" + dependencies: + minimist "0.0.8" + through2 "~0.4.1" + +randomatic@^1.1.3: + version "1.1.6" + resolved "https://registry.yarnpkg.com/randomatic/-/randomatic-1.1.6.tgz#110dcabff397e9dcff7c0789ccc0a49adf1ec5bb" + dependencies: + is-number "^2.0.2" + kind-of "^3.0.2" + +randombytes@^2.0.0, randombytes@^2.0.1: + version "2.0.3" + resolved "https://registry.yarnpkg.com/randombytes/-/randombytes-2.0.3.tgz#674c99760901c3c4112771a31e521dc349cc09ec" + +range-parser@^1.0.3, range-parser@~1.2.0: + version "1.2.0" + resolved "https://registry.yarnpkg.com/range-parser/-/range-parser-1.2.0.tgz#f49be6b487894ddc40dcc94a322f611092e00d5e" + +rc@~1.1.6: + version "1.1.7" + resolved "https://registry.yarnpkg.com/rc/-/rc-1.1.7.tgz#c5ea564bb07aff9fd3a5b32e906c1d3a65940fea" + dependencies: + deep-extend "~0.4.0" + ini "~1.3.0" + minimist "^1.2.0" + strip-json-comments "~2.0.1" + +react-autobind@^1.0.6: + version "1.0.6" + resolved "https://registry.yarnpkg.com/react-autobind/-/react-autobind-1.0.6.tgz#936bb58edf6b89b619c50f82f0e617159fdfd4f1" + +react-dom@^15.4.1: + version "15.4.2" + resolved "https://registry.yarnpkg.com/react-dom/-/react-dom-15.4.2.tgz#015363f05b0a1fd52ae9efdd3a0060d90695208f" + dependencies: + fbjs "^0.8.1" + loose-envify "^1.1.0" + object-assign "^4.1.0" + +react-map-gl@^1.7.2: + version "1.8.1" + resolved "https://registry.yarnpkg.com/react-map-gl/-/react-map-gl-1.8.1.tgz#0480d1c4aa162103f52e9cc518ab40af242665fc" + dependencies: + autobind-decorator "^1.3.3" + bowser "^1.2.0" + canvas-composite-types "^1.0.4" + d3-array "^1.0.1" + d3-color "^1.0.1" + d3-format "^1.0.2" + d3-geo "^1.2.4" + d3-scale "^1.0.3" + d3-selection "^1.0.2" + global "^4.3.0" + mapbox-gl "0.26.0" + pure-render-decorator "^1.1.0" + svg-transform "0.0.3" + viewport-mercator-project "^2.0.1" + +react@^15.4.1: + version "15.4.2" + resolved "https://registry.yarnpkg.com/react/-/react-15.4.2.tgz#41f7991b26185392ba9bae96c8889e7e018397ef" + dependencies: + fbjs "^0.8.4" + loose-envify "^1.1.0" + object-assign "^4.1.0" + +read-pkg-up@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/read-pkg-up/-/read-pkg-up-1.0.1.tgz#9d63c13276c065918d57f002a57f40a1b643fb02" + dependencies: + find-up "^1.0.0" + read-pkg "^1.0.0" + +read-pkg@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/read-pkg/-/read-pkg-1.1.0.tgz#f5ffaa5ecd29cb31c0474bca7d756b6bb29e3f28" + dependencies: + load-json-file "^1.0.0" + normalize-package-data "^2.3.2" + path-type "^1.0.0" + +"readable-stream@^2.0.0 || ^1.1.13", readable-stream@^2.0.1, readable-stream@^2.0.2, readable-stream@^2.0.5, readable-stream@^2.1.0, readable-stream@^2.1.5: + version "2.2.3" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.2.3.tgz#9cf49463985df016c8ae8813097a9293a9b33729" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readable-stream@~1.0.17, readable-stream@~1.0.27-1: + version "1.0.34" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.0.34.tgz#125820e34bc842d2f2aaafafe4c2916ee32c157c" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~1.1.9: + version "1.1.14" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-1.1.14.tgz#7cf4c54ef648e3813084c636dd2079e166c081d9" + dependencies: + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "0.0.1" + string_decoder "~0.10.x" + +readable-stream@~2.1.4: + version "2.1.5" + resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.1.5.tgz#66fa8b720e1438b364681f2ad1a63c618448c9d0" + dependencies: + buffer-shims "^1.0.0" + core-util-is "~1.0.0" + inherits "~2.0.1" + isarray "~1.0.0" + process-nextick-args "~1.0.6" + string_decoder "~0.10.x" + util-deprecate "~1.0.1" + +readdirp@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/readdirp/-/readdirp-2.1.0.tgz#4ed0ad060df3073300c48440373f72d1cc642d78" + dependencies: + graceful-fs "^4.1.2" + minimatch "^3.0.2" + readable-stream "^2.0.2" + set-immediate-shim "^1.0.1" + +regenerate@^1.2.1: + version "1.3.2" + resolved "https://registry.yarnpkg.com/regenerate/-/regenerate-1.3.2.tgz#d1941c67bad437e1be76433add5b385f95b19260" + +regenerator-runtime@^0.10.0: + version "0.10.3" + resolved "https://registry.yarnpkg.com/regenerator-runtime/-/regenerator-runtime-0.10.3.tgz#8c4367a904b51ea62a908ac310bf99ff90a82a3e" + +regenerator-transform@0.9.8: + version "0.9.8" + resolved "https://registry.yarnpkg.com/regenerator-transform/-/regenerator-transform-0.9.8.tgz#0f88bb2bc03932ddb7b6b7312e68078f01026d6c" + dependencies: + babel-runtime "^6.18.0" + babel-types "^6.19.0" + private "^0.1.6" + +regex-cache@^0.4.2: + version "0.4.3" + resolved "https://registry.yarnpkg.com/regex-cache/-/regex-cache-0.4.3.tgz#9b1a6c35d4d0dfcef5711ae651e8e9d3d7114145" + dependencies: + is-equal-shallow "^0.1.3" + is-primitive "^2.0.0" + +regexpu-core@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/regexpu-core/-/regexpu-core-2.0.0.tgz#49d038837b8dcf8bfa5b9a42139938e6ea2ae240" + dependencies: + regenerate "^1.2.1" + regjsgen "^0.2.0" + regjsparser "^0.1.4" + +regjsgen@^0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/regjsgen/-/regjsgen-0.2.0.tgz#6c016adeac554f75823fe37ac05b92d5a4edb1f7" + +regjsparser@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/regjsparser/-/regjsparser-0.1.5.tgz#7ee8f84dc6fa792d3fd0ae228d24bd949ead205c" + dependencies: + jsesc "~0.5.0" + +repeat-element@^1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/repeat-element/-/repeat-element-1.1.2.tgz#ef089a178d1483baae4d93eb98b4f9e4e11d990a" + +repeat-string@^1.5.2: + version "1.6.1" + resolved "https://registry.yarnpkg.com/repeat-string/-/repeat-string-1.6.1.tgz#8dcae470e1c88abc2d600fff4a776286da75e637" + +repeating@^2.0.0: + version "2.0.1" + resolved "https://registry.yarnpkg.com/repeating/-/repeating-2.0.1.tgz#5214c53a926d3552707527fbab415dbc08d06dda" + dependencies: + is-finite "^1.0.0" + +request@^2.39.0, request@^2.79.0: + version "2.81.0" + resolved "https://registry.yarnpkg.com/request/-/request-2.81.0.tgz#c6928946a0e06c5f8d6f8a9333469ffda46298a0" + dependencies: + aws-sign2 "~0.6.0" + aws4 "^1.2.1" + caseless "~0.12.0" + combined-stream "~1.0.5" + extend "~3.0.0" + forever-agent "~0.6.1" + form-data "~2.1.1" + har-validator "~4.2.1" + hawk "~3.1.3" + http-signature "~1.1.0" + is-typedarray "~1.0.0" + isstream "~0.1.2" + json-stringify-safe "~5.0.1" + mime-types "~2.1.7" + oauth-sign "~0.8.1" + performance-now "^0.2.0" + qs "~6.4.0" + safe-buffer "^5.0.1" + stringstream "~0.0.4" + tough-cookie "~2.3.0" + tunnel-agent "^0.6.0" + uuid "^3.0.0" + +require-directory@^2.1.1: + version "2.1.1" + resolved "https://registry.yarnpkg.com/require-directory/-/require-directory-2.1.1.tgz#8c64ad5fd30dab1c976e2344ffe7f792a6a6df42" + +require-main-filename@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/require-main-filename/-/require-main-filename-1.0.1.tgz#97f717b69d48784f5f526a6c5aa8ffdda055a4d1" + +requires-port@1.0.x, requires-port@1.x.x: + version "1.0.0" + resolved "https://registry.yarnpkg.com/requires-port/-/requires-port-1.0.0.tgz#925d2601d39ac485e091cf0da5c6e694dc3dcaff" + +resolve-protobuf-schema@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/resolve-protobuf-schema/-/resolve-protobuf-schema-2.0.0.tgz#e67b062a67f02d11bd6886e70efda788407e0fb4" + dependencies: + protocol-buffers-schema "^2.0.2" + +resolve@^1.1.5: + version "1.3.2" + resolved "https://registry.yarnpkg.com/resolve/-/resolve-1.3.2.tgz#1f0442c9e0cbb8136e87b9305f932f46c7f28235" + dependencies: + path-parse "^1.0.5" + +right-align@^0.1.1: + version "0.1.3" + resolved "https://registry.yarnpkg.com/right-align/-/right-align-0.1.3.tgz#61339b722fe6a3515689210d24e14c96148613ef" + dependencies: + align-text "^0.1.1" + +rimraf@2, rimraf@~2.5.1, rimraf@~2.5.4: + version "2.5.4" + resolved "https://registry.yarnpkg.com/rimraf/-/rimraf-2.5.4.tgz#96800093cbf1a0c86bd95b4625467535c29dfa04" + dependencies: + glob "^7.0.5" + +ripemd160@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/ripemd160/-/ripemd160-1.0.1.tgz#93a4bbd4942bc574b69a8fa57c71de10ecca7d6e" + +rw@1: + version "1.3.3" + resolved "https://registry.yarnpkg.com/rw/-/rw-1.3.3.tgz#3f862dfa91ab766b14885ef4d01124bfda074fb4" + +rw@^0.1.4: + version "0.1.4" + resolved "https://registry.yarnpkg.com/rw/-/rw-0.1.4.tgz#4903cbd80248ae0ede685bf58fd236a7a9b29a3e" + +safe-buffer@^5.0.1: + version "5.0.1" + resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.0.1.tgz#d263ca54696cd8a306b5ca6551e92de57918fbe7" + +select-hose@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/select-hose/-/select-hose-2.0.0.tgz#625d8658f865af43ec962bfc376a37359a4994ca" + +"semver@2 || 3 || 4 || 5", semver@~5.3.0: + version "5.3.0" + resolved "https://registry.yarnpkg.com/semver/-/semver-5.3.0.tgz#9b2ce5d3de02d17c6012ad326aa6b4d0cf54f94f" + +send@0.15.1: + version "0.15.1" + resolved "https://registry.yarnpkg.com/send/-/send-0.15.1.tgz#8a02354c26e6f5cca700065f5f0cdeba90ec7b5f" + dependencies: + debug "2.6.1" + depd "~1.1.0" + destroy "~1.0.4" + encodeurl "~1.0.1" + escape-html "~1.0.3" + etag "~1.8.0" + fresh "0.5.0" + http-errors "~1.6.1" + mime "1.3.4" + ms "0.7.2" + on-finished "~2.3.0" + range-parser "~1.2.0" + statuses "~1.3.1" + +serve-index@^1.7.2: + version "1.8.0" + resolved "https://registry.yarnpkg.com/serve-index/-/serve-index-1.8.0.tgz#7c5d96c13fb131101f93c1c5774f8516a1e78d3b" + dependencies: + accepts "~1.3.3" + batch "0.5.3" + debug "~2.2.0" + escape-html "~1.0.3" + http-errors "~1.5.0" + mime-types "~2.1.11" + parseurl "~1.3.1" + +serve-static@1.12.1: + version "1.12.1" + resolved "https://registry.yarnpkg.com/serve-static/-/serve-static-1.12.1.tgz#7443a965e3ced647aceb5639fa06bf4d1bbe0039" + dependencies: + encodeurl "~1.0.1" + escape-html "~1.0.3" + parseurl "~1.3.1" + send "0.15.1" + +set-blocking@^2.0.0, set-blocking@~2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/set-blocking/-/set-blocking-2.0.0.tgz#045f9782d011ae9a6803ddd382b24392b3d890f7" + +set-immediate-shim@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/set-immediate-shim/-/set-immediate-shim-1.0.1.tgz#4b2b1b27eb808a9f8dcc481a58e5e56f599f3f61" + +setimmediate@^1.0.4, setimmediate@^1.0.5: + version "1.0.5" + resolved "https://registry.yarnpkg.com/setimmediate/-/setimmediate-1.0.5.tgz#290cbb232e306942d7d7ea9b83732ab7856f8285" + +setprototypeof@1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.2.tgz#81a552141ec104b88e89ce383103ad5c66564d08" + +setprototypeof@1.0.3: + version "1.0.3" + resolved "https://registry.yarnpkg.com/setprototypeof/-/setprototypeof-1.0.3.tgz#66567e37043eeb4f04d91bd658c0cbefb55b8e04" + +sha.js@^2.3.6: + version "2.4.8" + resolved "https://registry.yarnpkg.com/sha.js/-/sha.js-2.4.8.tgz#37068c2c476b6baf402d14a49c67f597921f634f" + dependencies: + inherits "^2.0.1" + +shallow-copy@~0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/shallow-copy/-/shallow-copy-0.0.1.tgz#415f42702d73d810330292cc5ee86eae1a11a170" + +shelf-pack@^1.0.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/shelf-pack/-/shelf-pack-1.1.0.tgz#b4679afdd00ad68dfd9bbd2b5a3e819293a74d82" + +signal-exit@^3.0.0: + version "3.0.2" + resolved "https://registry.yarnpkg.com/signal-exit/-/signal-exit-3.0.2.tgz#b5fdc08f1287ea1178628e415e25132b73646c6d" + +slash@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/slash/-/slash-1.0.0.tgz#c41f2f6c39fc16d1cd17ad4b5d896114ae470d55" + +sntp@1.x.x: + version "1.0.9" + resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198" + dependencies: + hoek "2.x.x" + +sockjs-client@1.1.2: + version "1.1.2" + resolved "https://registry.yarnpkg.com/sockjs-client/-/sockjs-client-1.1.2.tgz#f0212a8550e4c9468c8cceaeefd2e3493c033ad5" + dependencies: + debug "^2.2.0" + eventsource "0.1.6" + faye-websocket "~0.11.0" + inherits "^2.0.1" + json3 "^3.3.2" + url-parse "^1.1.1" + +sockjs@0.3.18: + version "0.3.18" + resolved "https://registry.yarnpkg.com/sockjs/-/sockjs-0.3.18.tgz#d9b289316ca7df77595ef299e075f0f937eb4207" + dependencies: + faye-websocket "^0.10.0" + uuid "^2.0.2" + +sort-asc@^0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/sort-asc/-/sort-asc-0.1.0.tgz#ab799df61fc73ea0956c79c4b531ed1e9e7727e9" + +sort-desc@^0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/sort-desc/-/sort-desc-0.1.1.tgz#198b8c0cdeb095c463341861e3925d4ee359a9ee" + +sort-object@^0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/sort-object/-/sort-object-0.3.2.tgz#98e0d199ede40e07c61a84403c61d6c3b290f9e2" + dependencies: + sort-asc "^0.1.0" + sort-desc "^0.1.1" + +source-list-map@~0.1.7: + version "0.1.8" + resolved "https://registry.yarnpkg.com/source-list-map/-/source-list-map-0.1.8.tgz#c550b2ab5427f6b3f21f5afead88c4f5587b2106" + +source-map-support@^0.4.2: + version "0.4.11" + resolved "https://registry.yarnpkg.com/source-map-support/-/source-map-support-0.4.11.tgz#647f939978b38535909530885303daf23279f322" + dependencies: + source-map "^0.5.3" + +"source-map@>= 0.1.2", source-map@^0.5.0, source-map@^0.5.3, source-map@~0.5.1, source-map@~0.5.3: + version "0.5.6" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.5.6.tgz#75ce38f52bf0733c5a7f0c118d81334a2bb5f412" + +source-map@^0.1.34, source-map@~0.1.33: + version "0.1.43" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.1.43.tgz#c24bc146ca517c1471f5dacbe2571b2b7f9e3346" + dependencies: + amdefine ">=0.0.4" + +source-map@~0.2.0: + version "0.2.0" + resolved "https://registry.yarnpkg.com/source-map/-/source-map-0.2.0.tgz#dab73fbcfc2ba819b4de03bd6f6eaa48164b3f9d" + dependencies: + amdefine ">=0.0.4" + +spdx-correct@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/spdx-correct/-/spdx-correct-1.0.2.tgz#4b3073d933ff51f3912f03ac5519498a4150db40" + dependencies: + spdx-license-ids "^1.0.2" + +spdx-expression-parse@~1.0.0: + version "1.0.4" + resolved "https://registry.yarnpkg.com/spdx-expression-parse/-/spdx-expression-parse-1.0.4.tgz#9bdf2f20e1f40ed447fbe273266191fced51626c" + +spdx-license-ids@^1.0.2: + version "1.2.2" + resolved "https://registry.yarnpkg.com/spdx-license-ids/-/spdx-license-ids-1.2.2.tgz#c9df7a3424594ade6bd11900d596696dc06bac57" + +spdy-transport@^2.0.15: + version "2.0.18" + resolved "https://registry.yarnpkg.com/spdy-transport/-/spdy-transport-2.0.18.tgz#43fc9c56be2cccc12bb3e2754aa971154e836ea6" + dependencies: + debug "^2.2.0" + hpack.js "^2.1.6" + obuf "^1.1.0" + readable-stream "^2.0.1" + wbuf "^1.4.0" + +spdy@^3.4.1: + version "3.4.4" + resolved "https://registry.yarnpkg.com/spdy/-/spdy-3.4.4.tgz#e0406407ca90ff01b553eb013505442649f5a819" + dependencies: + debug "^2.2.0" + handle-thing "^1.2.4" + http-deceiver "^1.2.4" + select-hose "^2.0.0" + spdy-transport "^2.0.15" + +sshpk@^1.7.0: + version "1.11.0" + resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.11.0.tgz#2d8d5ebb4a6fab28ffba37fa62a90f4a3ea59d77" + dependencies: + asn1 "~0.2.3" + assert-plus "^1.0.0" + dashdash "^1.12.0" + getpass "^0.1.1" + optionalDependencies: + bcrypt-pbkdf "^1.0.0" + ecc-jsbn "~0.1.1" + jodid25519 "^1.0.0" + jsbn "~0.1.0" + tweetnacl "~0.14.0" + +static-eval@~0.2.0: + version "0.2.4" + resolved "https://registry.yarnpkg.com/static-eval/-/static-eval-0.2.4.tgz#b7d34d838937b969f9641ca07d48f8ede263ea7b" + dependencies: + escodegen "~0.0.24" + +static-module@^1.1.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/static-module/-/static-module-1.3.1.tgz#79071d340e4419e4ab5ce87976a9eb67250c8493" + dependencies: + concat-stream "~1.4.5" + duplexer2 "~0.0.2" + escodegen "~1.3.2" + falafel "^1.0.0" + has "^1.0.0" + object-inspect "~0.4.0" + quote-stream "~0.0.0" + readable-stream "~1.0.27-1" + shallow-copy "~0.0.1" + static-eval "~0.2.0" + through2 "~0.4.1" + +"statuses@>= 1.3.1 < 2", statuses@~1.3.1: + version "1.3.1" + resolved "https://registry.yarnpkg.com/statuses/-/statuses-1.3.1.tgz#faf51b9eb74aaef3b3acf4ad5f61abf24cb7b93e" + +stream-browserify@^2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/stream-browserify/-/stream-browserify-2.0.1.tgz#66266ee5f9bdb9940a4e4514cafb43bb71e5c9db" + dependencies: + inherits "~2.0.1" + readable-stream "^2.0.2" + +stream-http@^2.3.1: + version "2.6.3" + resolved "https://registry.yarnpkg.com/stream-http/-/stream-http-2.6.3.tgz#4c3ddbf9635968ea2cfd4e48d43de5def2625ac3" + dependencies: + builtin-status-codes "^3.0.0" + inherits "^2.0.1" + readable-stream "^2.1.0" + to-arraybuffer "^1.0.0" + xtend "^4.0.0" + +string-width@^1.0.1, string-width@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/string-width/-/string-width-1.0.2.tgz#118bdf5b8cdc51a2a7e70d211e07e2b0b9b107d3" + dependencies: + code-point-at "^1.0.0" + is-fullwidth-code-point "^1.0.0" + strip-ansi "^3.0.0" + +string_decoder@^0.10.25, string_decoder@~0.10.x: + version "0.10.31" + resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94" + +stringstream@~0.0.4: + version "0.0.5" + resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878" + +strip-ansi@^3.0.0, strip-ansi@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf" + dependencies: + ansi-regex "^2.0.0" + +strip-ansi@~0.1.0: + version "0.1.1" + resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-0.1.1.tgz#39e8a98d044d150660abe4a6808acf70bb7bc991" + +strip-bom@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/strip-bom/-/strip-bom-2.0.0.tgz#6219a85616520491f35788bdbf1447a99c7e6b0e" + dependencies: + is-utf8 "^0.2.0" + +strip-json-comments@~2.0.1: + version "2.0.1" + resolved "https://registry.yarnpkg.com/strip-json-comments/-/strip-json-comments-2.0.1.tgz#3c531942e908c2697c0ec344858c286c7ca0a60a" + +supercluster@^2.0.1: + version "2.3.0" + resolved "https://registry.yarnpkg.com/supercluster/-/supercluster-2.3.0.tgz#87ab56081bbea9a1d724df5351ee9e8c3af2f48b" + dependencies: + kdbush "^1.0.1" + +supports-color@^2.0.0: + version "2.0.0" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7" + +supports-color@^3.1.0, supports-color@^3.1.1: + version "3.2.3" + resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.2.3.tgz#65ac0504b3954171d8a64946b2ae3cbb8a5f54f6" + dependencies: + has-flag "^1.0.0" + +svg-transform@0.0.3: + version "0.0.3" + resolved "https://registry.yarnpkg.com/svg-transform/-/svg-transform-0.0.3.tgz#dbe5756748483a8ba0d262674357aeb29a64b081" + +tapable@^0.2.5, tapable@~0.2.5: + version "0.2.6" + resolved "https://registry.yarnpkg.com/tapable/-/tapable-0.2.6.tgz#206be8e188860b514425375e6f1ae89bfb01fd8d" + +tar-pack@~3.3.0: + version "3.3.0" + resolved "https://registry.yarnpkg.com/tar-pack/-/tar-pack-3.3.0.tgz#30931816418f55afc4d21775afdd6720cee45dae" + dependencies: + debug "~2.2.0" + fstream "~1.0.10" + fstream-ignore "~1.0.5" + once "~1.3.3" + readable-stream "~2.1.4" + rimraf "~2.5.1" + tar "~2.2.1" + uid-number "~0.0.6" + +tar@~2.2.1: + version "2.2.1" + resolved "https://registry.yarnpkg.com/tar/-/tar-2.2.1.tgz#8e4d2a256c0e2185c6b18ad694aec968b83cb1d1" + dependencies: + block-stream "*" + fstream "^1.0.2" + inherits "2" + +through2@^2.0.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/through2/-/through2-2.0.3.tgz#0004569b37c7c74ba39c43f3ced78d1ad94140be" + dependencies: + readable-stream "^2.1.5" + xtend "~4.0.1" + +through2@~0.4.1: + version "0.4.2" + resolved "https://registry.yarnpkg.com/through2/-/through2-0.4.2.tgz#dbf5866031151ec8352bb6c4db64a2292a840b9b" + dependencies: + readable-stream "~1.0.17" + xtend "~2.1.1" + +through@^2.3.7: + version "2.3.8" + resolved "https://registry.yarnpkg.com/through/-/through-2.3.8.tgz#0dd4c9ffaabc357960b1b724115d7e0e86a2e1f5" + +timers-browserify@^2.0.2: + version "2.0.2" + resolved "https://registry.yarnpkg.com/timers-browserify/-/timers-browserify-2.0.2.tgz#ab4883cf597dcd50af211349a00fbca56ac86b86" + dependencies: + setimmediate "^1.0.4" + +tinyqueue@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/tinyqueue/-/tinyqueue-1.1.0.tgz#9c5f76f54a845f4914e754f5aa8d73ef6c011f7b" + +to-arraybuffer@^1.0.0: + version "1.0.1" + resolved "https://registry.yarnpkg.com/to-arraybuffer/-/to-arraybuffer-1.0.1.tgz#7d229b1fcc637e466ca081180836a7aabff83f43" + +to-fast-properties@^1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/to-fast-properties/-/to-fast-properties-1.0.2.tgz#f3f5c0c3ba7299a7ef99427e44633257ade43320" + +to-utf8@0.0.1: + version "0.0.1" + resolved "https://registry.yarnpkg.com/to-utf8/-/to-utf8-0.0.1.tgz#d17aea72ff2fba39b9e43601be7b3ff72e089852" + +tough-cookie@~2.3.0: + version "2.3.2" + resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.2.tgz#f081f76e4c85720e6c37a5faced737150d84072a" + dependencies: + punycode "^1.4.1" + +transform-loader@^0.2.3: + version "0.2.4" + resolved "https://registry.yarnpkg.com/transform-loader/-/transform-loader-0.2.4.tgz#e5c87877ba96d51d3f225368587b46e226d1cec9" + dependencies: + loader-utils "^1.0.2" + +trim-right@^1.0.1: + version "1.0.1" + resolved "https://registry.yarnpkg.com/trim-right/-/trim-right-1.0.1.tgz#cb2e1203067e0c8de1f614094b9fe45704ea6003" + +tty-browserify@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/tty-browserify/-/tty-browserify-0.0.0.tgz#a157ba402da24e9bf957f9aa69d524eed42901a6" + +tunnel-agent@^0.6.0: + version "0.6.0" + resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd" + dependencies: + safe-buffer "^5.0.1" + +tween.js@^16.6.0: + version "16.6.0" + resolved "https://registry.yarnpkg.com/tween.js/-/tween.js-16.6.0.tgz#739104c9336cc4f11ee53f9ce7cede51e6723624" + +tweetnacl@^0.14.3, tweetnacl@~0.14.0: + version "0.14.5" + resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64" + +type-check@~0.3.2: + version "0.3.2" + resolved "https://registry.yarnpkg.com/type-check/-/type-check-0.3.2.tgz#5884cab512cf1d355e3fb784f30804b2b520db72" + dependencies: + prelude-ls "~1.1.2" + +type-is@~1.6.14: + version "1.6.14" + resolved "https://registry.yarnpkg.com/type-is/-/type-is-1.6.14.tgz#e219639c17ded1ca0789092dd54a03826b817cb2" + dependencies: + media-typer "0.3.0" + mime-types "~2.1.13" + +typedarray@~0.0.5: + version "0.0.6" + resolved "https://registry.yarnpkg.com/typedarray/-/typedarray-0.0.6.tgz#867ac74e3864187b1d3d47d996a78ec5c8830777" + +ua-parser-js@^0.7.9: + version "0.7.12" + resolved "https://registry.yarnpkg.com/ua-parser-js/-/ua-parser-js-0.7.12.tgz#04c81a99bdd5dc52263ea29d24c6bf8d4818a4bb" + +uglify-js@^2.7.5: + version "2.8.12" + resolved "https://registry.yarnpkg.com/uglify-js/-/uglify-js-2.8.12.tgz#8a50f5d482243650b7108f6080aa3a6afe2a6c55" + dependencies: + source-map "~0.5.1" + uglify-to-browserify "~1.0.0" + yargs "~3.10.0" + +uglify-to-browserify@~1.0.0: + version "1.0.2" + resolved "https://registry.yarnpkg.com/uglify-to-browserify/-/uglify-to-browserify-1.0.2.tgz#6e0924d6bda6b5afe349e39a6d632850a0f882b7" + +uid-number@~0.0.6: + version "0.0.6" + resolved "https://registry.yarnpkg.com/uid-number/-/uid-number-0.0.6.tgz#0ea10e8035e8eb5b8e4449f06da1c730663baa81" + +unassert@^1.3.1: + version "1.5.1" + resolved "https://registry.yarnpkg.com/unassert/-/unassert-1.5.1.tgz#cbc88ec387417c5a5e4c02d3cd07be98bd75ff76" + dependencies: + acorn "^4.0.0" + call-matcher "^1.0.1" + deep-equal "^1.0.0" + espurify "^1.3.0" + estraverse "^4.1.0" + esutils "^2.0.2" + object-assign "^4.1.0" + +unassertify@^2.0.0: + version "2.0.4" + resolved "https://registry.yarnpkg.com/unassertify/-/unassertify-2.0.4.tgz#b3ca2ba5f29b4836e35a6dd77e5b20f6dbbf8e52" + dependencies: + acorn "^4.0.0" + convert-source-map "^1.1.1" + escodegen "^1.6.1" + multi-stage-sourcemap "^0.2.1" + through "^2.3.7" + unassert "^1.3.1" + +underscore@~1.6.0: + version "1.6.0" + resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.6.0.tgz#8b38b10cacdef63337b8b24e4ff86d45aea529a8" + +unitbezier@^0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/unitbezier/-/unitbezier-0.0.0.tgz#33bf7f5d7284c5350bfc5c7f770fba7549c54a5e" + +unpipe@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/unpipe/-/unpipe-1.0.0.tgz#b2bf4ee8514aae6165b4817829d21b2ef49904ec" + +url-parse@1.0.x: + version "1.0.5" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.0.5.tgz#0854860422afdcfefeb6c965c662d4800169927b" + dependencies: + querystringify "0.0.x" + requires-port "1.0.x" + +url-parse@^1.1.1: + version "1.1.8" + resolved "https://registry.yarnpkg.com/url-parse/-/url-parse-1.1.8.tgz#7a65b3a8d57a1e86af6b4e2276e34774167c0156" + dependencies: + querystringify "0.0.x" + requires-port "1.0.x" + +url@^0.11.0: + version "0.11.0" + resolved "https://registry.yarnpkg.com/url/-/url-0.11.0.tgz#3838e97cfc60521eb73c525a8e55bfdd9e2e28f1" + dependencies: + punycode "1.3.2" + querystring "0.2.0" + +util-deprecate@~1.0.1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf" + +util@0.10.3, util@^0.10.3: + version "0.10.3" + resolved "https://registry.yarnpkg.com/util/-/util-0.10.3.tgz#7afb1afe50805246489e3db7fe0ed379336ac0f9" + dependencies: + inherits "2.0.1" + +utils-merge@1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/utils-merge/-/utils-merge-1.0.0.tgz#0294fb922bb9375153541c4f7096231f287c8af8" + +uuid@^2.0.2: + version "2.0.3" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-2.0.3.tgz#67e2e863797215530dff318e5bf9dcebfd47b21a" + +uuid@^3.0.0: + version "3.0.1" + resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.0.1.tgz#6544bba2dfda8c1cf17e629a3a305e2bb1fee6c1" + +validate-npm-package-license@^3.0.1: + version "3.0.1" + resolved "https://registry.yarnpkg.com/validate-npm-package-license/-/validate-npm-package-license-3.0.1.tgz#2804babe712ad3379459acfbe24746ab2c303fbc" + dependencies: + spdx-correct "~1.0.0" + spdx-expression-parse "~1.0.0" + +vary@~1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/vary/-/vary-1.1.0.tgz#e1e5affbbd16ae768dd2674394b9ad3022653140" + +vector-tile@^1.1.3, vector-tile@^1.3.0: + version "1.3.0" + resolved "https://registry.yarnpkg.com/vector-tile/-/vector-tile-1.3.0.tgz#06d516a83b063f04c82ef539cf1bb1aebeb696b4" + dependencies: + point-geometry "0.0.0" + +verror@1.3.6: + version "1.3.6" + resolved "https://registry.yarnpkg.com/verror/-/verror-1.3.6.tgz#cff5df12946d297d2baaefaa2689e25be01c005c" + dependencies: + extsprintf "1.0.2" + +viewport-mercator-project@^2.0.1: + version "2.1.0" + resolved "https://registry.yarnpkg.com/viewport-mercator-project/-/viewport-mercator-project-2.1.0.tgz#6ae6249d199a80ca01319cdd821d7c6b7feae792" + +vm-browserify@0.0.4: + version "0.0.4" + resolved "https://registry.yarnpkg.com/vm-browserify/-/vm-browserify-0.0.4.tgz#5d7ea45bbef9e4a6ff65f95438e0a87c357d5a73" + dependencies: + indexof "0.0.1" + +vt-pbf@^2.0.2: + version "2.1.2" + resolved "https://registry.yarnpkg.com/vt-pbf/-/vt-pbf-2.1.2.tgz#75409fded5f6c3910073a64c3e575cdeba387f01" + dependencies: + pbf "^1.3.2" + point-geometry "0.0.0" + vector-tile "^1.1.3" + +watchpack@^1.2.0: + version "1.3.1" + resolved "https://registry.yarnpkg.com/watchpack/-/watchpack-1.3.1.tgz#7d8693907b28ce6013e7f3610aa2a1acf07dad87" + dependencies: + async "^2.1.2" + chokidar "^1.4.3" + graceful-fs "^4.1.2" + +wbuf@^1.1.0, wbuf@^1.4.0: + version "1.7.2" + resolved "https://registry.yarnpkg.com/wbuf/-/wbuf-1.7.2.tgz#d697b99f1f59512df2751be42769c1580b5801fe" + dependencies: + minimalistic-assert "^1.0.0" + +webgl-debug@^1.0.2: + version "1.0.2" + resolved "https://registry.yarnpkg.com/webgl-debug/-/webgl-debug-1.0.2.tgz#93bac5aed181343a136ad34f249920d3b9ccc69a" + +webpack-dev-middleware@^1.9.0: + version "1.10.1" + resolved "https://registry.yarnpkg.com/webpack-dev-middleware/-/webpack-dev-middleware-1.10.1.tgz#c6b4cf428139cf1aefbe06a0c00fdb4f8da2f893" + dependencies: + memory-fs "~0.4.1" + mime "^1.3.4" + path-is-absolute "^1.0.0" + range-parser "^1.0.3" + +webpack-dev-server@^2.2.0: + version "2.4.1" + resolved "https://registry.yarnpkg.com/webpack-dev-server/-/webpack-dev-server-2.4.1.tgz#48556f793186eac0758df94730c034ed9a4d0f12" + dependencies: + ansi-html "0.0.7" + chokidar "^1.6.0" + compression "^1.5.2" + connect-history-api-fallback "^1.3.0" + express "^4.13.3" + html-entities "^1.2.0" + http-proxy-middleware "~0.17.1" + opn "4.0.2" + portfinder "^1.0.9" + serve-index "^1.7.2" + sockjs "0.3.18" + sockjs-client "1.1.2" + spdy "^3.4.1" + strip-ansi "^3.0.0" + supports-color "^3.1.1" + webpack-dev-middleware "^1.9.0" + yargs "^6.0.0" + +webpack-sources@^0.1.4: + version "0.1.5" + resolved "https://registry.yarnpkg.com/webpack-sources/-/webpack-sources-0.1.5.tgz#aa1f3abf0f0d74db7111c40e500b84f966640750" + dependencies: + source-list-map "~0.1.7" + source-map "~0.5.3" + +webpack@^2.2.0: + version "2.2.1" + resolved "https://registry.yarnpkg.com/webpack/-/webpack-2.2.1.tgz#7bb1d72ae2087dd1a4af526afec15eed17dda475" + dependencies: + acorn "^4.0.4" + acorn-dynamic-import "^2.0.0" + ajv "^4.7.0" + ajv-keywords "^1.1.1" + async "^2.1.2" + enhanced-resolve "^3.0.0" + interpret "^1.0.0" + json-loader "^0.5.4" + loader-runner "^2.3.0" + loader-utils "^0.2.16" + memory-fs "~0.4.1" + mkdirp "~0.5.0" + node-libs-browser "^2.0.0" + source-map "^0.5.3" + supports-color "^3.1.0" + tapable "~0.2.5" + uglify-js "^2.7.5" + watchpack "^1.2.0" + webpack-sources "^0.1.4" + yargs "^6.0.0" + +websocket-driver@>=0.5.1: + version "0.6.5" + resolved "https://registry.yarnpkg.com/websocket-driver/-/websocket-driver-0.6.5.tgz#5cb2556ceb85f4373c6d8238aa691c8454e13a36" + dependencies: + websocket-extensions ">=0.1.1" + +websocket-extensions@>=0.1.1: + version "0.1.1" + resolved "https://registry.yarnpkg.com/websocket-extensions/-/websocket-extensions-0.1.1.tgz#76899499c184b6ef754377c2dbb0cd6cb55d29e7" + +webworkify@^1.4.0: + version "1.4.0" + resolved "https://registry.yarnpkg.com/webworkify/-/webworkify-1.4.0.tgz#71245d1e34cacf54e426bd955f8cc6ee12d024c2" + +wgs84@0.0.0: + version "0.0.0" + resolved "https://registry.yarnpkg.com/wgs84/-/wgs84-0.0.0.tgz#34fdc555917b6e57cf2a282ed043710c049cdc76" + +whatwg-fetch@>=0.10.0: + version "2.0.3" + resolved "https://registry.yarnpkg.com/whatwg-fetch/-/whatwg-fetch-2.0.3.tgz#9c84ec2dcf68187ff00bc64e1274b442176e1c84" + +which-module@^1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/which-module/-/which-module-1.0.0.tgz#bba63ca861948994ff307736089e3b96026c2a4f" + +whoots-js@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/whoots-js/-/whoots-js-2.1.0.tgz#bcb201c34e0eaf335fcce5ae2cf874579a99c487" + +wide-align@^1.1.0: + version "1.1.0" + resolved "https://registry.yarnpkg.com/wide-align/-/wide-align-1.1.0.tgz#40edde802a71fea1f070da3e62dcda2e7add96ad" + dependencies: + string-width "^1.0.1" + +window-size@0.1.0: + version "0.1.0" + resolved "https://registry.yarnpkg.com/window-size/-/window-size-0.1.0.tgz#5438cd2ea93b202efa3a19fe8887aee7c94f9c9d" + +wordwrap@0.0.2: + version "0.0.2" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-0.0.2.tgz#b79669bb42ecb409f83d583cad52ca17eaa1643f" + +wordwrap@~1.0.0: + version "1.0.0" + resolved "https://registry.yarnpkg.com/wordwrap/-/wordwrap-1.0.0.tgz#27584810891456a4171c8d0226441ade90cbcaeb" + +wrap-ansi@^2.0.0: + version "2.1.0" + resolved "https://registry.yarnpkg.com/wrap-ansi/-/wrap-ansi-2.1.0.tgz#d8fc3d284dd05794fe84973caecdd1cf824fdd85" + dependencies: + string-width "^1.0.1" + strip-ansi "^3.0.1" + +wrappy@1: + version "1.0.2" + resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f" + +xmlhttprequest@1: + version "1.8.0" + resolved "https://registry.yarnpkg.com/xmlhttprequest/-/xmlhttprequest-1.8.0.tgz#67fe075c5c24fef39f9d65f5f7b7fe75171968fc" + +xtend@^4.0.0, xtend@~4.0.1: + version "4.0.1" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af" + +xtend@~2.1.1: + version "2.1.2" + resolved "https://registry.yarnpkg.com/xtend/-/xtend-2.1.2.tgz#6efecc2a4dad8e6962c4901b337ce7ba87b5d28b" + dependencies: + object-keys "~0.4.0" + +y18n@^3.2.1: + version "3.2.1" + resolved "https://registry.yarnpkg.com/y18n/-/y18n-3.2.1.tgz#6d15fba884c08679c0d77e88e7759e811e07fa41" + +yargs-parser@^4.2.0: + version "4.2.1" + resolved "https://registry.yarnpkg.com/yargs-parser/-/yargs-parser-4.2.1.tgz#29cceac0dc4f03c6c87b4a9f217dd18c9f74871c" + dependencies: + camelcase "^3.0.0" + +yargs@^6.0.0: + version "6.6.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-6.6.0.tgz#782ec21ef403345f830a808ca3d513af56065208" + dependencies: + camelcase "^3.0.0" + cliui "^3.2.0" + decamelize "^1.1.1" + get-caller-file "^1.0.1" + os-locale "^1.4.0" + read-pkg-up "^1.0.1" + require-directory "^2.1.1" + require-main-filename "^1.0.1" + set-blocking "^2.0.0" + string-width "^1.0.2" + which-module "^1.0.0" + y18n "^3.2.1" + yargs-parser "^4.2.0" + +yargs@~3.10.0: + version "3.10.0" + resolved "https://registry.yarnpkg.com/yargs/-/yargs-3.10.0.tgz#f7ee7bd857dd7c1d2d38c0e74efbd681d1431fd1" + dependencies: + camelcase "^1.0.2" + cliui "^2.1.0" + decamelize "^1.0.0" + window-size "0.1.0"