Huge News!Announcing our $40M Series B led by Abstract Ventures.Learn More
Socket
Sign inDemoInstall
Socket

three-globe

Package Overview
Dependencies
Maintainers
1
Versions
226
Alerts
File Explorer

Advanced tools

Socket logo

Install Socket

Detect and block malicious and high-risk dependencies

Install

three-globe - npm Package Compare versions

Comparing version 1.0.5 to 1.0.6

example/blue-marble.jpg

227

dist/three-globe.common.js

@@ -8,2 +8,3 @@ 'use strict';

var accessorFn = _interopDefault(require('accessor-fn'));
var d3Geo = require('d3-geo');
var tinyColor = _interopDefault(require('tinycolor2'));

@@ -19,2 +20,3 @@

BackSide: three.BackSide,
BufferGeometry: three.BufferGeometry,
Color: three.Color,

@@ -25,2 +27,3 @@ CylinderGeometry: three.CylinderGeometry,

Group: three.Group,
Line: three.Line,
Matrix4: three.Matrix4,

@@ -99,7 +102,6 @@ Mesh: three.Mesh,

globeImageUrl: {
onChange(url) {
this._loadGlobeImage(url);
},
onChange(_, state) {
state.globeNeedsUpdate = true;
}
triggerUpdate: false
},

@@ -138,3 +140,3 @@ pointsData: {

},
pointHeight: {
pointAltitude: {
default: 0.1,

@@ -175,55 +177,53 @@

// boolean. Whether to merge all points into a single mesh for rendering performance
linksData: {
arcsData: {
default: [],
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkStartLat: {
arcStartLat: {
default: 'startLat',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkStartLng: {
default: 'endLng',
arcStartLng: {
default: 'startLng',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkEndLat: {
arcEndLat: {
default: 'endLat',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkEndLng: {
arcEndLng: {
default: 'endLng',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkColor: {
arcColor: {
default: () => '#ffffaa',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkHeight: {
default: 0.4,
arcAltitude: {
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}

@@ -233,16 +233,23 @@

// in units of globe radius
linkDiameter: {
default: 0.2,
arcAltitudeAutoScale: {
default: 0.5,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
// scale altitude proportional to great-arc distance between the two points
arcStroke: {
onChange(_, state) {
state.arcsNeedsRepopulating = true;
}
},
// in deg
linkCurveResolution: {
arcCurveResolution: {
default: 64,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}

@@ -252,7 +259,7 @@

// how many slice segments in the tube's circumference
linkCircularResolution: {
arcCircularResolution: {
default: 6,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}

@@ -262,11 +269,11 @@

// how many slice segments in the tube's circumference
linksMerge: {
arcsMerge: {
default: false,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
// boolean. Whether to merge all links into a single mesh for rendering performance
// boolean. Whether to merge all arcs into a single mesh for rendering performance
customLayerData: {

@@ -297,22 +304,9 @@ default: [],

};
},
}
_loadGlobeImage: function (state, imageUrl) {
if (state.globeObj && imageUrl) {
const shader = Shaders.earth;
const uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms.texture.value = new THREE.TextureLoader().load(imageUrl);
state.globeObj.material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
}
return this;
}
},
stateInit: () => ({
globeNeedsUpdate: true,
pointsNeedsRepopulating: true,
linksNeedsRepopulating: true,
arcsNeedsRepopulating: true,
customLayerNeedsRepopulating: true

@@ -335,4 +329,3 @@ }),

state.scene.add(globeObj);
state.globeImageUrl && this._loadGlobeImage(state.globeImageUrl); // add atmosphere
state.scene.add(globeObj); // add atmosphere

@@ -357,5 +350,5 @@ {

state.scene.add(state.pointsG = new THREE.Group()); // add links group
state.scene.add(state.pointsG = new THREE.Group()); // add arcs group
state.scene.add(state.linksG = new THREE.Group()); // add custom layer group
state.scene.add(state.arcsG = new THREE.Group()); // add custom layer group

@@ -368,4 +361,24 @@ state.scene.add(state.customLayerG = new THREE.Group());

if (state.globeNeedsUpdate) {
state.globeNeedsUpdate = false;
if (!state.globeImageUrl) {
// Black globe
state.globeObj.material = new THREE.MeshBasicMaterial({
color: 0x000000
});
} else {
const shader = Shaders.earth;
const uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms.texture.value = new THREE.TextureLoader().load(state.globeImageUrl);
state.globeObj.material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
}
}
if (state.pointsNeedsRepopulating) {
state.pointsNeedRepopulating = false; // Clear the existing points
state.pointsNeedsRepopulating = false; // Clear the existing points

@@ -376,3 +389,3 @@ emptyObject(state.pointsG); // Data accessors

const lngAccessor = accessorFn(state.pointLng);
const heightAccessor = accessorFn(state.pointHeight);
const altitudeAccessor = accessorFn(state.pointAltitude);
const radiusAccessor = accessorFn(state.pointRadius);

@@ -393,3 +406,3 @@ const colorAccessor = accessorFn(state.pointColor); // Add WebGL points

obj.scale.x = obj.scale.y = Math.min(30, radiusAccessor(pnt)) * pxPerDeg;
obj.scale.z = Math.max(heightAccessor(pnt) * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix
obj.scale.z = Math.max(altitudeAccessor(pnt) * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix

@@ -446,47 +459,59 @@ obj.__globeObjType = 'point'; // Add object type

if (state.linksNeedsRepopulating) {
state.linksNeedsRepopulating = false; // Clear the existing links
if (state.arcsNeedsRepopulating) {
state.arcsNeedsRepopulating = false; // Clear the existing arcs
emptyObject(state.linksG); // Data accessors
emptyObject(state.arcsG); // Data accessors
const startLatAccessor = accessorFn(state.linkStartLat);
const startLngAccessor = accessorFn(state.linkStartLng);
const endLatAccessor = accessorFn(state.linkEndLat);
const endLngAccessor = accessorFn(state.linkEndLng);
const heightAccessor = accessorFn(state.linkHeight);
const diameterAccessor = accessorFn(state.linkDiameter);
const colorAccessor = accessorFn(state.linkColor);
const linkObjs = [];
state.linksData.forEach(link => {
const startPnt = [...[startLatAccessor, startLngAccessor].map(fn => fn(link)), 0];
const endPnt = [...[endLatAccessor, endLngAccessor].map(fn => fn(link)), 0];
const startLatAccessor = accessorFn(state.arcStartLat);
const startLngAccessor = accessorFn(state.arcStartLng);
const endLatAccessor = accessorFn(state.arcEndLat);
const endLngAccessor = accessorFn(state.arcEndLng);
const altitudeAccessor = accessorFn(state.arcAltitude);
const altitudeAutoScaleAccessor = accessorFn(state.arcAltitudeAutoScale);
const strokeAccessor = accessorFn(state.arcStroke);
const colorAccessor = accessorFn(state.arcColor);
const arcObjs = [];
state.arcsData.forEach(arc => {
let curve;
{
const getVec = ([lng, lat, alt]) => {
const {
x,
y,
z
} = this.getCoords(lat, lng, alt);
return new THREE.Vector3(x, y, z);
}; //calculate curve
const getMiddle = (a, b) => a + (b - a) / 2;
const middlePoint = [getMiddle(startPnt[0], endPnt[0]), getMiddle(startPnt[1], endPnt[1]), heightAccessor(link) * 2];
const curveVecs = [startPnt, middlePoint, endPnt].map(([lat, lng, alt]) => {
const coords = this.getCoords(lat, lng, alt);
return new THREE.Vector3(coords.x, coords.y, coords.z);
});
const path = new THREE.QuadraticBezierCurve3(...curveVecs);
const linkGeometry = new THREE.TubeGeometry(path, state.linkCurveResolution, diameterAccessor(link) / 2, state.linkCircularResolution);
const obj = new THREE.Mesh(linkGeometry);
obj.__globeObjType = 'link'; // Add object type
const startPnt = [startLngAccessor, startLatAccessor].map(fn => fn(arc));
const endPnt = [endLngAccessor, endLatAccessor].map(fn => fn(arc));
let altitude = altitudeAccessor(arc);
(altitude === null || altitude === undefined) && ( // by default set altitude proportional to the great-arc distance
altitude = d3Geo.geoDistance(startPnt, endPnt) / 2 * altitudeAutoScaleAccessor(arc));
const interpolate = d3Geo.geoInterpolate(startPnt, endPnt);
const [m1Pnt, m2Pnt] = [0.25, 0.75].map(t => [...interpolate(t), altitude * 1.5]);
curve = new THREE.CubicBezierCurve3(...[startPnt, m1Pnt, m2Pnt, endPnt].map(getVec)); //const mPnt = [...interpolate(0.5), altitude * 2];
//curve = new THREE.QuadraticBezierCurve3(...[startPnt, mPnt, endPnt].map(getVec));
}
const stroke = strokeAccessor(arc);
const obj = stroke === null || stroke === undefined ? new THREE.Line(new THREE.BufferGeometry().setFromPoints(curve.getPoints(state.arcCurveResolution))) : new THREE.Mesh(new THREE.TubeGeometry(curve, state.arcCurveResolution, stroke / 2, state.arcCircularResolution));
obj.__globeObjType = 'arc'; // Add object type
obj.__data = link; // Attach point data
obj.__data = arc; // Attach point data
linkObjs.push(obj);
arcObjs.push(obj);
});
if (state.linksMerge) {
// merge links into a single mesh
const linksGeometry = new THREE.Geometry();
linkObjs.forEach(obj => {
const link = obj.__data;
const color = new THREE.Color(colorAccessor(link));
if (state.arcsMerge) {
// merge arcs into a single mesh
const arcsGeometry = new THREE.Geometry();
arcObjs.forEach(obj => {
const arc = obj.__data;
const color = new THREE.Color(colorAccessor(arc));
obj.geometry.faces.forEach(face => face.color = color);
obj.updateMatrix();
linksGeometry.merge(obj.geometry, obj.matrix);
arcsGeometry.merge(obj.geometry, obj.matrix);
});
const links = new THREE.Mesh(linksGeometry, new THREE.MeshBasicMaterial({
const arcs = new THREE.Mesh(arcsGeometry, new THREE.MeshBasicMaterial({
color: 0xffffff,

@@ -496,18 +521,18 @@ vertexColors: THREE.FaceColors,

}));
links.__globeObjType = 'links'; // Add object type
arcs.__globeObjType = 'arcs'; // Add object type
links.__data = state.linksData; // Attach obj data
arcs.__data = state.arcsData; // Attach obj data
state.linksG.add(links);
state.arcsG.add(arcs);
} else {
// Add individual meshes per link
const linkMaterials = {}; // indexed by color
// Add individual meshes per arc
const arcMaterials = {}; // indexed by color
linkObjs.forEach(obj => {
const link = obj.__data;
const color = colorAccessor(link);
arcObjs.forEach(obj => {
const arc = obj.__data;
const color = colorAccessor(arc);
const opacity = colorAlpha(color);
if (!linkMaterials.hasOwnProperty(color)) {
linkMaterials[color] = new THREE.MeshLambertMaterial({
if (!arcMaterials.hasOwnProperty(color)) {
arcMaterials[color] = new THREE.MeshLambertMaterial({
color: colorStr2Hex(color),

@@ -519,4 +544,4 @@ transparent: opacity < 1,

obj.material = linkMaterials[color];
state.linksG.add(link.__threeObj = obj);
obj.material = arcMaterials[color];
state.arcsG.add(arc.__threeObj = obj);
});

@@ -523,0 +548,0 @@ }

@@ -1,5 +0,5 @@

// Version 1.0.5 three-globe - https://github.com/vasturiano/three-globe
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("three")):"function"==typeof define&&define.amd?define(["three"],t):(e=e||self).ThreeGlobe=t(e.THREE)}(this,function(e){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}var r=n(function(e,t){"undefined"!=typeof self&&self,e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){var r,a,i,o;o=function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.stateInit,n=void 0===t?function(){return{}}:t,r=e.props,s=void 0===r?{}:r,l=e.methods,u=void 0===l?{}:l,f=e.aliases,c=void 0===f?{}:f,h=e.init,d=void 0===h?function(){}:h,g=e.update,p=void 0===g?function(){}:g,b=Object.keys(s).map(function(e){return new o(e,s[e])});return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Object.assign({},n instanceof Function?n(e):n,{initialised:!1});function r(t){return o(t,e),s(),r}var o=function(e,n){d.call(r,e,t,n),t.initialised=!0},s=(0,a.default)(function(){t.initialised&&p.call(r,t)},1);return b.forEach(function(e){r[e.name]=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e,t){};return function(i){var o=t[e];return arguments.length?(t[e]=i,a.call(r,i,t,o),n&&s(),r):o}}(e.name,e.triggerUpdate,e.onChange)}),Object.keys(u).forEach(function(e){r[e]=function(){for(var n,a=arguments.length,i=Array(a),o=0;o<a;o++)i[o]=arguments[o];return(n=u[e]).call.apply(n,[r,t].concat(i))}}),Object.entries(c).forEach(function(e){var t=i(e,2),n=t[0],a=t[1];return r[n]=r[a]}),r.resetProps=function(){return b.forEach(function(e){r[e.name](e.defaultVal)}),r},r.resetProps(),t._rerender=s,r}};var r,a=(r=n)&&r.__esModule?r:{default:r},i=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,a=!1,i=void 0;try{for(var o,s=e[Symbol.iterator]();!(r=(o=s.next()).done)&&(n.push(o.value),!t||n.length!==t);r=!0);}catch(e){a=!0,i=e}finally{try{!r&&s.return&&s.return()}finally{if(a)throw i}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},o=function e(t,n){var r=n.default,a=void 0===r?null:r,i=n.triggerUpdate,o=void 0===i||i,s=n.onChange,l=void 0===s?function(e,t){}:s;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=t,this.defaultVal=a,this.triggerUpdate=o,this.onChange=l};e.exports=t.default},a=[e,t,n(1)],void 0===(i="function"==typeof(r=o)?r.apply(t,a):r)||(e.exports=i)},function(e,t){e.exports=function(e,t,n){var r,a,i,o,s;function l(){var u=Date.now()-o;u<t&&u>=0?r=setTimeout(l,t-u):(r=null,n||(s=e.apply(i,a),i=a=null))}null==t&&(t=100);var u=function(){i=this,a=arguments,o=Date.now();var u=n&&!r;return r||(r=setTimeout(l,t)),u&&(s=e.apply(i,a),i=a=null),s};return u.clear=function(){r&&(clearTimeout(r),r=null)},u.flush=function(){r&&(s=e.apply(i,a),i=a=null,clearTimeout(r),r=null)},u}}])}),a=t(r),i=(r.Kapsule,n(function(e,t){e.exports=function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){var r,a,i;a=[e,t],void 0!==(i="function"==typeof(r=function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e instanceof Function?e:"string"==typeof e?function(t){return t[e]}:function(t){return e}},e.exports=t.default})?r.apply(t,a):r)&&(e.exports=i)}])})),o=t(i),s=(i.accessorFn,n(function(e){!function(t){var n=/^\s+/,r=/\s+$/,a=0,i=t.round,o=t.min,s=t.max,l=t.random;function u(e,l){if(l=l||{},(e=e||"")instanceof u)return e;if(!(this instanceof u))return new u(e,l);var f=function(e){var a={r:0,g:0,b:0},i=1,l=null,u=null,f=null,c=!1,h=!1;"string"==typeof e&&(e=function(e){e=e.replace(n,"").replace(r,"").toLowerCase();var t,a=!1;if(R[e])e=R[e],a=!0;else if("transparent"==e)return{r:0,g:0,b:0,a:0,format:"name"};if(t=U.rgb.exec(e))return{r:t[1],g:t[2],b:t[3]};if(t=U.rgba.exec(e))return{r:t[1],g:t[2],b:t[3],a:t[4]};if(t=U.hsl.exec(e))return{h:t[1],s:t[2],l:t[3]};if(t=U.hsla.exec(e))return{h:t[1],s:t[2],l:t[3],a:t[4]};if(t=U.hsv.exec(e))return{h:t[1],s:t[2],v:t[3]};if(t=U.hsva.exec(e))return{h:t[1],s:t[2],v:t[3],a:t[4]};if(t=U.hex8.exec(e))return{r:L(t[1]),g:L(t[2]),b:L(t[3]),a:E(t[4]),format:a?"name":"hex8"};if(t=U.hex6.exec(e))return{r:L(t[1]),g:L(t[2]),b:L(t[3]),format:a?"name":"hex"};if(t=U.hex4.exec(e))return{r:L(t[1]+""+t[1]),g:L(t[2]+""+t[2]),b:L(t[3]+""+t[3]),a:E(t[4]+""+t[4]),format:a?"name":"hex8"};if(t=U.hex3.exec(e))return{r:L(t[1]+""+t[1]),g:L(t[2]+""+t[2]),b:L(t[3]+""+t[3]),format:a?"name":"hex"};return!1}(e));"object"==typeof e&&(D(e.r)&&D(e.g)&&D(e.b)?(d=e.r,g=e.g,p=e.b,a={r:255*j(d,255),g:255*j(g,255),b:255*j(p,255)},c=!0,h="%"===String(e.r).substr(-1)?"prgb":"rgb"):D(e.h)&&D(e.s)&&D(e.v)?(l=H(e.s),u=H(e.v),a=function(e,n,r){e=6*j(e,360),n=j(n,100),r=j(r,100);var a=t.floor(e),i=e-a,o=r*(1-n),s=r*(1-i*n),l=r*(1-(1-i)*n),u=a%6;return{r:255*[r,s,o,o,l,r][u],g:255*[l,r,r,s,o,o][u],b:255*[o,o,l,r,r,s][u]}}(e.h,l,u),c=!0,h="hsv"):D(e.h)&&D(e.s)&&D(e.l)&&(l=H(e.s),f=H(e.l),a=function(e,t,n){var r,a,i;function o(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(e=j(e,360),t=j(t,100),n=j(n,100),0===t)r=a=i=n;else{var s=n<.5?n*(1+t):n+t-n*t,l=2*n-s;r=o(l,s,e+1/3),a=o(l,s,e),i=o(l,s,e-1/3)}return{r:255*r,g:255*a,b:255*i}}(e.h,l,f),c=!0,h="hsl"),e.hasOwnProperty("a")&&(i=e.a));var d,g,p;return i=N(i),{ok:c,format:e.format||h,r:o(255,s(a.r,0)),g:o(255,s(a.g,0)),b:o(255,s(a.b,0)),a:i}}(e);this._originalInput=e,this._r=f.r,this._g=f.g,this._b=f.b,this._a=f.a,this._roundA=i(100*this._a)/100,this._format=l.format||f.format,this._gradientType=l.gradientType,this._r<1&&(this._r=i(this._r)),this._g<1&&(this._g=i(this._g)),this._b<1&&(this._b=i(this._b)),this._ok=f.ok,this._tc_id=a++}function f(e,t,n){e=j(e,255),t=j(t,255),n=j(n,255);var r,a,i=s(e,t,n),l=o(e,t,n),u=(i+l)/2;if(i==l)r=a=0;else{var f=i-l;switch(a=u>.5?f/(2-i-l):f/(i+l),i){case e:r=(t-n)/f+(t<n?6:0);break;case t:r=(n-e)/f+2;break;case n:r=(e-t)/f+4}r/=6}return{h:r,s:a,l:u}}function c(e,t,n){e=j(e,255),t=j(t,255),n=j(n,255);var r,a,i=s(e,t,n),l=o(e,t,n),u=i,f=i-l;if(a=0===i?0:f/i,i==l)r=0;else{switch(i){case e:r=(t-n)/f+(t<n?6:0);break;case t:r=(n-e)/f+2;break;case n:r=(e-t)/f+4}r/=6}return{h:r,s:a,v:u}}function h(e,t,n,r){var a=[G(i(e).toString(16)),G(i(t).toString(16)),G(i(n).toString(16))];return r&&a[0].charAt(0)==a[0].charAt(1)&&a[1].charAt(0)==a[1].charAt(1)&&a[2].charAt(0)==a[2].charAt(1)?a[0].charAt(0)+a[1].charAt(0)+a[2].charAt(0):a.join("")}function d(e,t,n,r){return[G(T(r)),G(i(e).toString(16)),G(i(t).toString(16)),G(i(n).toString(16))].join("")}function g(e,t){t=0===t?0:t||10;var n=u(e).toHsl();return n.s-=t/100,n.s=O(n.s),u(n)}function p(e,t){t=0===t?0:t||10;var n=u(e).toHsl();return n.s+=t/100,n.s=O(n.s),u(n)}function b(e){return u(e).desaturate(100)}function m(e,t){t=0===t?0:t||10;var n=u(e).toHsl();return n.l+=t/100,n.l=O(n.l),u(n)}function v(e,t){t=0===t?0:t||10;var n=u(e).toRgb();return n.r=s(0,o(255,n.r-i(-t/100*255))),n.g=s(0,o(255,n.g-i(-t/100*255))),n.b=s(0,o(255,n.b-i(-t/100*255))),u(n)}function _(e,t){t=0===t?0:t||10;var n=u(e).toHsl();return n.l-=t/100,n.l=O(n.l),u(n)}function y(e,t){var n=u(e).toHsl(),r=(n.h+t)%360;return n.h=r<0?360+r:r,u(n)}function x(e){var t=u(e).toHsl();return t.h=(t.h+180)%360,u(t)}function k(e){var t=u(e).toHsl(),n=t.h;return[u(e),u({h:(n+120)%360,s:t.s,l:t.l}),u({h:(n+240)%360,s:t.s,l:t.l})]}function w(e){var t=u(e).toHsl(),n=t.h;return[u(e),u({h:(n+90)%360,s:t.s,l:t.l}),u({h:(n+180)%360,s:t.s,l:t.l}),u({h:(n+270)%360,s:t.s,l:t.l})]}function M(e){var t=u(e).toHsl(),n=t.h;return[u(e),u({h:(n+72)%360,s:t.s,l:t.l}),u({h:(n+216)%360,s:t.s,l:t.l})]}function A(e,t,n){t=t||6,n=n||30;var r=u(e).toHsl(),a=360/n,i=[u(e)];for(r.h=(r.h-(a*t>>1)+720)%360;--t;)r.h=(r.h+a)%360,i.push(u(r));return i}function C(e,t){t=t||6;for(var n=u(e).toHsv(),r=n.h,a=n.s,i=n.v,o=[],s=1/t;t--;)o.push(u({h:r,s:a,v:i})),i=(i+s)%1;return o}u.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},getLuminance:function(){var e,n,r,a=this.toRgb();return e=a.r/255,n=a.g/255,r=a.b/255,.2126*(e<=.03928?e/12.92:t.pow((e+.055)/1.055,2.4))+.7152*(n<=.03928?n/12.92:t.pow((n+.055)/1.055,2.4))+.0722*(r<=.03928?r/12.92:t.pow((r+.055)/1.055,2.4))},setAlpha:function(e){return this._a=N(e),this._roundA=i(100*this._a)/100,this},toHsv:function(){var e=c(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=c(this._r,this._g,this._b),t=i(360*e.h),n=i(100*e.s),r=i(100*e.v);return 1==this._a?"hsv("+t+", "+n+"%, "+r+"%)":"hsva("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHsl:function(){var e=f(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=f(this._r,this._g,this._b),t=i(360*e.h),n=i(100*e.s),r=i(100*e.l);return 1==this._a?"hsl("+t+", "+n+"%, "+r+"%)":"hsla("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHex:function(e){return h(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(e){return function(e,t,n,r,a){var o=[G(i(e).toString(16)),G(i(t).toString(16)),G(i(n).toString(16)),G(T(r))];if(a&&o[0].charAt(0)==o[0].charAt(1)&&o[1].charAt(0)==o[1].charAt(1)&&o[2].charAt(0)==o[2].charAt(1)&&o[3].charAt(0)==o[3].charAt(1))return o[0].charAt(0)+o[1].charAt(0)+o[2].charAt(0)+o[3].charAt(0);return o.join("")}(this._r,this._g,this._b,this._a,e)},toHex8String:function(e){return"#"+this.toHex8(e)},toRgb:function(){return{r:i(this._r),g:i(this._g),b:i(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+i(this._r)+", "+i(this._g)+", "+i(this._b)+")":"rgba("+i(this._r)+", "+i(this._g)+", "+i(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:i(100*j(this._r,255))+"%",g:i(100*j(this._g,255))+"%",b:i(100*j(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+i(100*j(this._r,255))+"%, "+i(100*j(this._g,255))+"%, "+i(100*j(this._b,255))+"%)":"rgba("+i(100*j(this._r,255))+"%, "+i(100*j(this._g,255))+"%, "+i(100*j(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(S[h(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+d(this._r,this._g,this._b,this._a),n=t,r=this._gradientType?"GradientType = 1, ":"";if(e){var a=u(e);n="#"+d(a._r,a._g,a._b,a._a)}return"progid:DXImageTransform.Microsoft.gradient("+r+"startColorstr="+t+",endColorstr="+n+")"},toString:function(e){var t=!!e;e=e||this._format;var n=!1,r=this._a<1&&this._a>=0;return t||!r||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"hex4"!==e&&"hex8"!==e&&"name"!==e?("rgb"===e&&(n=this.toRgbString()),"prgb"===e&&(n=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(n=this.toHexString()),"hex3"===e&&(n=this.toHexString(!0)),"hex4"===e&&(n=this.toHex8String(!0)),"hex8"===e&&(n=this.toHex8String()),"name"===e&&(n=this.toName()),"hsl"===e&&(n=this.toHslString()),"hsv"===e&&(n=this.toHsvString()),n||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},clone:function(){return u(this.toString())},_applyModification:function(e,t){var n=e.apply(null,[this].concat([].slice.call(t)));return this._r=n._r,this._g=n._g,this._b=n._b,this.setAlpha(n._a),this},lighten:function(){return this._applyModification(m,arguments)},brighten:function(){return this._applyModification(v,arguments)},darken:function(){return this._applyModification(_,arguments)},desaturate:function(){return this._applyModification(g,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(b,arguments)},spin:function(){return this._applyModification(y,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(A,arguments)},complement:function(){return this._applyCombination(x,arguments)},monochromatic:function(){return this._applyCombination(C,arguments)},splitcomplement:function(){return this._applyCombination(M,arguments)},triad:function(){return this._applyCombination(k,arguments)},tetrad:function(){return this._applyCombination(w,arguments)}},u.fromRatio=function(e,t){if("object"==typeof e){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]="a"===r?e[r]:H(e[r]));e=n}return u(e,t)},u.equals=function(e,t){return!(!e||!t)&&u(e).toRgbString()==u(t).toRgbString()},u.random=function(){return u.fromRatio({r:l(),g:l(),b:l()})},u.mix=function(e,t,n){n=0===n?0:n||50;var r=u(e).toRgb(),a=u(t).toRgb(),i=n/100;return u({r:(a.r-r.r)*i+r.r,g:(a.g-r.g)*i+r.g,b:(a.b-r.b)*i+r.b,a:(a.a-r.a)*i+r.a})},
// Version 1.0.6 three-globe - https://github.com/vasturiano/three-globe
!function(e,t){"object"==typeof exports&&"undefined"!=typeof module?module.exports=t(require("three")):"function"==typeof define&&define.amd?define(["three"],t):(e=e||self).ThreeGlobe=t(e.THREE)}(this,function(e){"use strict";"undefined"!=typeof window?window:"undefined"!=typeof global?global:"undefined"!=typeof self&&self;function t(e){return e&&e.__esModule&&Object.prototype.hasOwnProperty.call(e,"default")?e.default:e}function n(e,t){return e(t={exports:{}},t.exports),t.exports}var r=n(function(e,t){"undefined"!=typeof self&&self,e.exports=function(e){var t={};function n(r){if(t[r])return t[r].exports;var a=t[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,n),a.l=!0,a.exports}return n.m=e,n.c=t,n.d=function(e,t,r){n.o(e,t)||Object.defineProperty(e,t,{configurable:!1,enumerable:!0,get:r})},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=0)}([function(e,t,n){var r,a,o,i;i=function(e,t,n){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){var t=e.stateInit,n=void 0===t?function(){return{}}:t,r=e.props,s=void 0===r?{}:r,u=e.methods,l=void 0===u?{}:u,c=e.aliases,f=void 0===c?{}:c,h=e.init,d=void 0===h?function(){}:h,g=e.update,p=void 0===g?function(){}:g,b=Object.keys(s).map(function(e){return new i(e,s[e])});return function(){var e=arguments.length>0&&void 0!==arguments[0]?arguments[0]:{},t=Object.assign({},n instanceof Function?n(e):n,{initialised:!1});function r(t){return i(t,e),s(),r}var i=function(e,n){d.call(r,e,t,n),t.initialised=!0},s=(0,a.default)(function(){t.initialised&&p.call(r,t)},1);return b.forEach(function(e){r[e.name]=function(e){var n=arguments.length>1&&void 0!==arguments[1]&&arguments[1],a=arguments.length>2&&void 0!==arguments[2]?arguments[2]:function(e,t){};return function(o){var i=t[e];return arguments.length?(t[e]=o,a.call(r,o,t,i),n&&s(),r):i}}(e.name,e.triggerUpdate,e.onChange)}),Object.keys(l).forEach(function(e){r[e]=function(){for(var n,a=arguments.length,o=Array(a),i=0;i<a;i++)o[i]=arguments[i];return(n=l[e]).call.apply(n,[r,t].concat(o))}}),Object.entries(f).forEach(function(e){var t=o(e,2),n=t[0],a=t[1];return r[n]=r[a]}),r.resetProps=function(){return b.forEach(function(e){r[e.name](e.defaultVal)}),r},r.resetProps(),t._rerender=s,r}};var r,a=(r=n)&&r.__esModule?r:{default:r},o=function(e,t){if(Array.isArray(e))return e;if(Symbol.iterator in Object(e))return function(e,t){var n=[],r=!0,a=!1,o=void 0;try{for(var i,s=e[Symbol.iterator]();!(r=(i=s.next()).done)&&(n.push(i.value),!t||n.length!==t);r=!0);}catch(e){a=!0,o=e}finally{try{!r&&s.return&&s.return()}finally{if(a)throw o}}return n}(e,t);throw new TypeError("Invalid attempt to destructure non-iterable instance")},i=function e(t,n){var r=n.default,a=void 0===r?null:r,o=n.triggerUpdate,i=void 0===o||o,s=n.onChange,u=void 0===s?function(e,t){}:s;!function(e,t){if(!(e instanceof t))throw new TypeError("Cannot call a class as a function")}(this,e),this.name=t,this.defaultVal=a,this.triggerUpdate=i,this.onChange=u};e.exports=t.default},a=[e,t,n(1)],void 0===(o="function"==typeof(r=i)?r.apply(t,a):r)||(e.exports=o)},function(e,t){e.exports=function(e,t,n){var r,a,o,i,s;function u(){var l=Date.now()-i;l<t&&l>=0?r=setTimeout(u,t-l):(r=null,n||(s=e.apply(o,a),o=a=null))}null==t&&(t=100);var l=function(){o=this,a=arguments,i=Date.now();var l=n&&!r;return r||(r=setTimeout(u,t)),l&&(s=e.apply(o,a),o=a=null),s};return l.clear=function(){r&&(clearTimeout(r),r=null)},l.flush=function(){r&&(s=e.apply(o,a),o=a=null,clearTimeout(r),r=null)},l}}])}),a=t(r),o=(r.Kapsule,n(function(e,t){e.exports=function(e){function t(r){if(n[r])return n[r].exports;var a=n[r]={i:r,l:!1,exports:{}};return e[r].call(a.exports,a,a.exports,t),a.l=!0,a.exports}var n={};return t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{configurable:!1,enumerable:!0,get:r})},t.n=function(e){var n=e&&e.__esModule?function(){return e.default}:function(){return e};return t.d(n,"a",n),n},t.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},t.p="",t(t.s=0)}([function(e,t,n){var r,a,o;a=[e,t],void 0!==(o="function"==typeof(r=function(e,t){Object.defineProperty(t,"__esModule",{value:!0}),t.default=function(e){return e instanceof Function?e:"string"==typeof e?function(t){return t[e]}:function(t){return e}},e.exports=t.default})?r.apply(t,a):r)&&(e.exports=o)}])})),i=t(o);o.accessorFn;function s(){return new u}function u(){this.reset()}u.prototype={constructor:u,reset:function(){this.s=this.t=0},add:function(e){c(l,e,this.t),c(this,l.s,this.s),this.s?this.t+=l.t:this.s=l.t},valueOf:function(){return this.s}};var l=new u;function c(e,t,n){var r=e.s=t+n,a=r-t,o=r-a;e.t=t-o+(n-a)}var f=Math.PI,h=f/2,d=180/f,g=f/180,p=Math.abs,b=Math.atan2,m=Math.cos,v=Math.sin,y=Math.sqrt;function _(e){return(e=v(e/2))*e}function x(){}function w(e,t){e&&A.hasOwnProperty(e.type)&&A[e.type](e,t)}var M={Feature:function(e,t){w(e.geometry,t)},FeatureCollection:function(e,t){for(var n=e.features,r=-1,a=n.length;++r<a;)w(n[r].geometry,t)}},A={Sphere:function(e,t){t.sphere()},Point:function(e,t){e=e.coordinates,t.point(e[0],e[1],e[2])},MultiPoint:function(e,t){for(var n=e.coordinates,r=-1,a=n.length;++r<a;)e=n[r],t.point(e[0],e[1],e[2])},LineString:function(e,t){C(e.coordinates,t,0)},MultiLineString:function(e,t){for(var n=e.coordinates,r=-1,a=n.length;++r<a;)C(n[r],t,0)},Polygon:function(e,t){S(e.coordinates,t)},MultiPolygon:function(e,t){for(var n=e.coordinates,r=-1,a=n.length;++r<a;)S(n[r],t)},GeometryCollection:function(e,t){for(var n=e.geometries,r=-1,a=n.length;++r<a;)w(n[r],t)}};function C(e,t,n){var r,a=-1,o=e.length-n;for(t.lineStart();++a<o;)r=e[a],t.point(r[0],r[1],r[2]);t.lineEnd()}function S(e,t){var n=-1,r=e.length;for(t.polygonStart();++n<r;)C(e[n],t,1);t.polygonEnd()}s(),s(),s(),s();function R(e,t){return e<t?-1:e>t?1:e>=t?0:NaN}1===(k=R).length&&(N=k,k=function(e,t){return R(N(e),t)});var k,N,L,O,j,E=s(),G={sphere:x,point:x,lineStart:function(){G.point=F,G.lineEnd=T},lineEnd:x,polygonStart:x,polygonEnd:x};function T(){G.point=G.lineEnd=x}function F(e,t){L=e*=g,O=v(t*=g),j=m(t),G.point=P}function P(e,t){e*=g;var n=v(t*=g),r=m(t),a=p(e-L),o=m(a),i=r*v(a),s=j*n-O*r*o,u=O*n+j*r*o;E.add(b(y(i*i+s*s),u)),L=e,O=n,j=r}function H(e){return E.reset(),function(e,t){e&&M.hasOwnProperty(e.type)?M[e.type](e,t):w(e,t)}(e,G),+E}var U=[null,null],I={type:"LineString",coordinates:U};function B(e,t){var n,r=e[0]*g,a=e[1]*g,o=t[0]*g,i=t[1]*g,s=m(a),u=v(a),l=m(i),c=v(i),f=s*m(r),p=s*v(r),x=l*m(o),w=l*v(o),M=2*((n=y(_(i-a)+s*l*_(o-r)))>1?h:n<-1?-h:Math.asin(n)),A=v(M),C=M?function(e){var t=v(e*=M)/A,n=v(M-e)/A,r=n*f+t*x,a=n*p+t*w,o=n*u+t*c;return[b(a,r)*d,b(o,y(r*r+a*a))*d]}:function(){return[r*d,a*d]};return C.distance=M,C}s(),s(),s();var z=n(function(e){!function(t){var n=/^\s+/,r=/\s+$/,a=0,o=t.round,i=t.min,s=t.max,u=t.random;function l(e,u){if(u=u||{},(e=e||"")instanceof l)return e;if(!(this instanceof l))return new l(e,u);var c=function(e){var a={r:0,g:0,b:0},o=1,u=null,l=null,c=null,f=!1,h=!1;"string"==typeof e&&(e=function(e){e=e.replace(n,"").replace(r,"").toLowerCase();var t,a=!1;if(R[e])e=R[e],a=!0;else if("transparent"==e)return{r:0,g:0,b:0,a:0,format:"name"};if(t=I.rgb.exec(e))return{r:t[1],g:t[2],b:t[3]};if(t=I.rgba.exec(e))return{r:t[1],g:t[2],b:t[3],a:t[4]};if(t=I.hsl.exec(e))return{h:t[1],s:t[2],l:t[3]};if(t=I.hsla.exec(e))return{h:t[1],s:t[2],l:t[3],a:t[4]};if(t=I.hsv.exec(e))return{h:t[1],s:t[2],v:t[3]};if(t=I.hsva.exec(e))return{h:t[1],s:t[2],v:t[3],a:t[4]};if(t=I.hex8.exec(e))return{r:j(t[1]),g:j(t[2]),b:j(t[3]),a:F(t[4]),format:a?"name":"hex8"};if(t=I.hex6.exec(e))return{r:j(t[1]),g:j(t[2]),b:j(t[3]),format:a?"name":"hex"};if(t=I.hex4.exec(e))return{r:j(t[1]+""+t[1]),g:j(t[2]+""+t[2]),b:j(t[3]+""+t[3]),a:F(t[4]+""+t[4]),format:a?"name":"hex8"};if(t=I.hex3.exec(e))return{r:j(t[1]+""+t[1]),g:j(t[2]+""+t[2]),b:j(t[3]+""+t[3]),format:a?"name":"hex"};return!1}(e));"object"==typeof e&&(B(e.r)&&B(e.g)&&B(e.b)?(d=e.r,g=e.g,p=e.b,a={r:255*L(d,255),g:255*L(g,255),b:255*L(p,255)},f=!0,h="%"===String(e.r).substr(-1)?"prgb":"rgb"):B(e.h)&&B(e.s)&&B(e.v)?(u=G(e.s),l=G(e.v),a=function(e,n,r){e=6*L(e,360),n=L(n,100),r=L(r,100);var a=t.floor(e),o=e-a,i=r*(1-n),s=r*(1-o*n),u=r*(1-(1-o)*n),l=a%6;return{r:255*[r,s,i,i,u,r][l],g:255*[u,r,r,s,i,i][l],b:255*[i,i,u,r,r,s][l]}}(e.h,u,l),f=!0,h="hsv"):B(e.h)&&B(e.s)&&B(e.l)&&(u=G(e.s),c=G(e.l),a=function(e,t,n){var r,a,o;function i(e,t,n){return n<0&&(n+=1),n>1&&(n-=1),n<1/6?e+6*(t-e)*n:n<.5?t:n<2/3?e+(t-e)*(2/3-n)*6:e}if(e=L(e,360),t=L(t,100),n=L(n,100),0===t)r=a=o=n;else{var s=n<.5?n*(1+t):n+t-n*t,u=2*n-s;r=i(u,s,e+1/3),a=i(u,s,e),o=i(u,s,e-1/3)}return{r:255*r,g:255*a,b:255*o}}(e.h,u,c),f=!0,h="hsl"),e.hasOwnProperty("a")&&(o=e.a));var d,g,p;return o=N(o),{ok:f,format:e.format||h,r:i(255,s(a.r,0)),g:i(255,s(a.g,0)),b:i(255,s(a.b,0)),a:o}}(e);this._originalInput=e,this._r=c.r,this._g=c.g,this._b=c.b,this._a=c.a,this._roundA=o(100*this._a)/100,this._format=u.format||c.format,this._gradientType=u.gradientType,this._r<1&&(this._r=o(this._r)),this._g<1&&(this._g=o(this._g)),this._b<1&&(this._b=o(this._b)),this._ok=c.ok,this._tc_id=a++}function c(e,t,n){e=L(e,255),t=L(t,255),n=L(n,255);var r,a,o=s(e,t,n),u=i(e,t,n),l=(o+u)/2;if(o==u)r=a=0;else{var c=o-u;switch(a=l>.5?c/(2-o-u):c/(o+u),o){case e:r=(t-n)/c+(t<n?6:0);break;case t:r=(n-e)/c+2;break;case n:r=(e-t)/c+4}r/=6}return{h:r,s:a,l:l}}function f(e,t,n){e=L(e,255),t=L(t,255),n=L(n,255);var r,a,o=s(e,t,n),u=i(e,t,n),l=o,c=o-u;if(a=0===o?0:c/o,o==u)r=0;else{switch(o){case e:r=(t-n)/c+(t<n?6:0);break;case t:r=(n-e)/c+2;break;case n:r=(e-t)/c+4}r/=6}return{h:r,s:a,v:l}}function h(e,t,n,r){var a=[E(o(e).toString(16)),E(o(t).toString(16)),E(o(n).toString(16))];return r&&a[0].charAt(0)==a[0].charAt(1)&&a[1].charAt(0)==a[1].charAt(1)&&a[2].charAt(0)==a[2].charAt(1)?a[0].charAt(0)+a[1].charAt(0)+a[2].charAt(0):a.join("")}function d(e,t,n,r){return[E(T(r)),E(o(e).toString(16)),E(o(t).toString(16)),E(o(n).toString(16))].join("")}function g(e,t){t=0===t?0:t||10;var n=l(e).toHsl();return n.s-=t/100,n.s=O(n.s),l(n)}function p(e,t){t=0===t?0:t||10;var n=l(e).toHsl();return n.s+=t/100,n.s=O(n.s),l(n)}function b(e){return l(e).desaturate(100)}function m(e,t){t=0===t?0:t||10;var n=l(e).toHsl();return n.l+=t/100,n.l=O(n.l),l(n)}function v(e,t){t=0===t?0:t||10;var n=l(e).toRgb();return n.r=s(0,i(255,n.r-o(-t/100*255))),n.g=s(0,i(255,n.g-o(-t/100*255))),n.b=s(0,i(255,n.b-o(-t/100*255))),l(n)}function y(e,t){t=0===t?0:t||10;var n=l(e).toHsl();return n.l-=t/100,n.l=O(n.l),l(n)}function _(e,t){var n=l(e).toHsl(),r=(n.h+t)%360;return n.h=r<0?360+r:r,l(n)}function x(e){var t=l(e).toHsl();return t.h=(t.h+180)%360,l(t)}function w(e){var t=l(e).toHsl(),n=t.h;return[l(e),l({h:(n+120)%360,s:t.s,l:t.l}),l({h:(n+240)%360,s:t.s,l:t.l})]}function M(e){var t=l(e).toHsl(),n=t.h;return[l(e),l({h:(n+90)%360,s:t.s,l:t.l}),l({h:(n+180)%360,s:t.s,l:t.l}),l({h:(n+270)%360,s:t.s,l:t.l})]}function A(e){var t=l(e).toHsl(),n=t.h;return[l(e),l({h:(n+72)%360,s:t.s,l:t.l}),l({h:(n+216)%360,s:t.s,l:t.l})]}function C(e,t,n){t=t||6,n=n||30;var r=l(e).toHsl(),a=360/n,o=[l(e)];for(r.h=(r.h-(a*t>>1)+720)%360;--t;)r.h=(r.h+a)%360,o.push(l(r));return o}function S(e,t){t=t||6;for(var n=l(e).toHsv(),r=n.h,a=n.s,o=n.v,i=[],s=1/t;t--;)i.push(l({h:r,s:a,v:o})),o=(o+s)%1;return i}l.prototype={isDark:function(){return this.getBrightness()<128},isLight:function(){return!this.isDark()},isValid:function(){return this._ok},getOriginalInput:function(){return this._originalInput},getFormat:function(){return this._format},getAlpha:function(){return this._a},getBrightness:function(){var e=this.toRgb();return(299*e.r+587*e.g+114*e.b)/1e3},getLuminance:function(){var e,n,r,a=this.toRgb();return e=a.r/255,n=a.g/255,r=a.b/255,.2126*(e<=.03928?e/12.92:t.pow((e+.055)/1.055,2.4))+.7152*(n<=.03928?n/12.92:t.pow((n+.055)/1.055,2.4))+.0722*(r<=.03928?r/12.92:t.pow((r+.055)/1.055,2.4))},setAlpha:function(e){return this._a=N(e),this._roundA=o(100*this._a)/100,this},toHsv:function(){var e=f(this._r,this._g,this._b);return{h:360*e.h,s:e.s,v:e.v,a:this._a}},toHsvString:function(){var e=f(this._r,this._g,this._b),t=o(360*e.h),n=o(100*e.s),r=o(100*e.v);return 1==this._a?"hsv("+t+", "+n+"%, "+r+"%)":"hsva("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHsl:function(){var e=c(this._r,this._g,this._b);return{h:360*e.h,s:e.s,l:e.l,a:this._a}},toHslString:function(){var e=c(this._r,this._g,this._b),t=o(360*e.h),n=o(100*e.s),r=o(100*e.l);return 1==this._a?"hsl("+t+", "+n+"%, "+r+"%)":"hsla("+t+", "+n+"%, "+r+"%, "+this._roundA+")"},toHex:function(e){return h(this._r,this._g,this._b,e)},toHexString:function(e){return"#"+this.toHex(e)},toHex8:function(e){return function(e,t,n,r,a){var i=[E(o(e).toString(16)),E(o(t).toString(16)),E(o(n).toString(16)),E(T(r))];if(a&&i[0].charAt(0)==i[0].charAt(1)&&i[1].charAt(0)==i[1].charAt(1)&&i[2].charAt(0)==i[2].charAt(1)&&i[3].charAt(0)==i[3].charAt(1))return i[0].charAt(0)+i[1].charAt(0)+i[2].charAt(0)+i[3].charAt(0);return i.join("")}(this._r,this._g,this._b,this._a,e)},toHex8String:function(e){return"#"+this.toHex8(e)},toRgb:function(){return{r:o(this._r),g:o(this._g),b:o(this._b),a:this._a}},toRgbString:function(){return 1==this._a?"rgb("+o(this._r)+", "+o(this._g)+", "+o(this._b)+")":"rgba("+o(this._r)+", "+o(this._g)+", "+o(this._b)+", "+this._roundA+")"},toPercentageRgb:function(){return{r:o(100*L(this._r,255))+"%",g:o(100*L(this._g,255))+"%",b:o(100*L(this._b,255))+"%",a:this._a}},toPercentageRgbString:function(){return 1==this._a?"rgb("+o(100*L(this._r,255))+"%, "+o(100*L(this._g,255))+"%, "+o(100*L(this._b,255))+"%)":"rgba("+o(100*L(this._r,255))+"%, "+o(100*L(this._g,255))+"%, "+o(100*L(this._b,255))+"%, "+this._roundA+")"},toName:function(){return 0===this._a?"transparent":!(this._a<1)&&(k[h(this._r,this._g,this._b,!0)]||!1)},toFilter:function(e){var t="#"+d(this._r,this._g,this._b,this._a),n=t,r=this._gradientType?"GradientType = 1, ":"";if(e){var a=l(e);n="#"+d(a._r,a._g,a._b,a._a)}return"progid:DXImageTransform.Microsoft.gradient("+r+"startColorstr="+t+",endColorstr="+n+")"},toString:function(e){var t=!!e;e=e||this._format;var n=!1,r=this._a<1&&this._a>=0;return t||!r||"hex"!==e&&"hex6"!==e&&"hex3"!==e&&"hex4"!==e&&"hex8"!==e&&"name"!==e?("rgb"===e&&(n=this.toRgbString()),"prgb"===e&&(n=this.toPercentageRgbString()),"hex"!==e&&"hex6"!==e||(n=this.toHexString()),"hex3"===e&&(n=this.toHexString(!0)),"hex4"===e&&(n=this.toHex8String(!0)),"hex8"===e&&(n=this.toHex8String()),"name"===e&&(n=this.toName()),"hsl"===e&&(n=this.toHslString()),"hsv"===e&&(n=this.toHsvString()),n||this.toHexString()):"name"===e&&0===this._a?this.toName():this.toRgbString()},clone:function(){return l(this.toString())},_applyModification:function(e,t){var n=e.apply(null,[this].concat([].slice.call(t)));return this._r=n._r,this._g=n._g,this._b=n._b,this.setAlpha(n._a),this},lighten:function(){return this._applyModification(m,arguments)},brighten:function(){return this._applyModification(v,arguments)},darken:function(){return this._applyModification(y,arguments)},desaturate:function(){return this._applyModification(g,arguments)},saturate:function(){return this._applyModification(p,arguments)},greyscale:function(){return this._applyModification(b,arguments)},spin:function(){return this._applyModification(_,arguments)},_applyCombination:function(e,t){return e.apply(null,[this].concat([].slice.call(t)))},analogous:function(){return this._applyCombination(C,arguments)},complement:function(){return this._applyCombination(x,arguments)},monochromatic:function(){return this._applyCombination(S,arguments)},splitcomplement:function(){return this._applyCombination(A,arguments)},triad:function(){return this._applyCombination(w,arguments)},tetrad:function(){return this._applyCombination(M,arguments)}},l.fromRatio=function(e,t){if("object"==typeof e){var n={};for(var r in e)e.hasOwnProperty(r)&&(n[r]="a"===r?e[r]:G(e[r]));e=n}return l(e,t)},l.equals=function(e,t){return!(!e||!t)&&l(e).toRgbString()==l(t).toRgbString()},l.random=function(){return l.fromRatio({r:u(),g:u(),b:u()})},l.mix=function(e,t,n){n=0===n?0:n||50;var r=l(e).toRgb(),a=l(t).toRgb(),o=n/100;return l({r:(a.r-r.r)*o+r.r,g:(a.g-r.g)*o+r.g,b:(a.b-r.b)*o+r.b,a:(a.a-r.a)*o+r.a})},
// <http://www.w3.org/TR/2008/REC-WCAG20-20081211/#contrast-ratiodef (WCAG Version 2)
// Analyze the 2 colors and returns the color contrast defined by (WCAG Version 2)
u.readability=function(e,n){var r=u(e),a=u(n);return(t.max(r.getLuminance(),a.getLuminance())+.05)/(t.min(r.getLuminance(),a.getLuminance())+.05)},u.isReadable=function(e,t,n){var r,a,i=u.readability(e,t);switch(a=!1,(r=function(e){var t,n;t=((e=e||{level:"AA",size:"small"}).level||"AA").toUpperCase(),n=(e.size||"small").toLowerCase(),"AA"!==t&&"AAA"!==t&&(t="AA");"small"!==n&&"large"!==n&&(n="small");return{level:t,size:n}}(n)).level+r.size){case"AAsmall":case"AAAlarge":a=i>=4.5;break;case"AAlarge":a=i>=3;break;case"AAAsmall":a=i>=7}return a},u.mostReadable=function(e,t,n){var r,a,i,o,s=null,l=0;a=(n=n||{}).includeFallbackColors,i=n.level,o=n.size;for(var f=0;f<t.length;f++)(r=u.readability(e,t[f]))>l&&(l=r,s=u(t[f]));return u.isReadable(e,s,{level:i,size:o})||!a?s:(n.includeFallbackColors=!1,u.mostReadable(e,["#fff","#000"],n))};var R=u.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},S=u.hexNames=function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[e[n]]=n);return t}(R);function N(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}function j(e,n){(function(e){return"string"==typeof e&&-1!=e.indexOf(".")&&1===parseFloat(e)})(e)&&(e="100%");var r=function(e){return"string"==typeof e&&-1!=e.indexOf("%")}(e);return e=o(n,s(0,parseFloat(e))),r&&(e=parseInt(e*n,10)/100),t.abs(e-n)<1e-6?1:e%n/parseFloat(n)}function O(e){return o(1,s(0,e))}function L(e){return parseInt(e,16)}function G(e){return 1==e.length?"0"+e:""+e}function H(e){return e<=1&&(e=100*e+"%"),e}function T(e){return t.round(255*parseFloat(e)).toString(16)}function E(e){return L(e)/255}var F,I,P,U=(I="[\\s|\\(]+("+(F="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+F+")[,|\\s]+("+F+")\\s*\\)?",P="[\\s|\\(]+("+F+")[,|\\s]+("+F+")[,|\\s]+("+F+")[,|\\s]+("+F+")\\s*\\)?",{CSS_UNIT:new RegExp(F),rgb:new RegExp("rgb"+I),rgba:new RegExp("rgba"+P),hsl:new RegExp("hsl"+I),hsla:new RegExp("hsla"+P),hsv:new RegExp("hsv"+I),hsva:new RegExp("hsva"+P),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function D(e){return!!U.CSS_UNIT.exec(e)}e.exports?e.exports=u:window.tinycolor=u}(Math)}));const l=e=>isNaN(e)?parseInt(s(e).toHex(),16):e,u=e=>isNaN(e)?s(e).getAlpha():1,f=window.THREE?window.THREE:{AdditiveBlending:e.AdditiveBlending,BackSide:e.BackSide,Color:e.Color,CylinderGeometry:e.CylinderGeometry,FaceColors:e.FaceColors,Geometry:e.Geometry,Group:e.Group,Matrix4:e.Matrix4,Mesh:e.Mesh,MeshBasicMaterial:e.MeshBasicMaterial,MeshLambertMaterial:e.MeshLambertMaterial,QuadraticBezierCurve3:e.QuadraticBezierCurve3,ShaderMaterial:e.ShaderMaterial,SphereGeometry:e.SphereGeometry,TextureLoader:e.TextureLoader,TubeGeometry:e.TubeGeometry,UniformsUtils:e.UniformsUtils,Vector3:e.Vector3},c=e=>{const t=e=>{e instanceof Array?e.forEach(t):(e.map&&e.map.dispose(),e.dispose())},n=e=>{e.geometry&&e.geometry.dispose(),e.material&&t(e.material),e.texture&&e.texture.dispose(),e.children&&e.children.forEach(n)};for(;e.children.length;){const e=state.pointsG.children[0];state.pointsG.remove(e),n(e)}},h={earth:{uniforms:{texture:{type:"t",value:null}},vertexShader:["varying vec3 vNormal;","varying vec2 vUv;","void main() {","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","vNormal = normalize( normalMatrix * normal );","vUv = uv;","}"].join("\n"),fragmentShader:["uniform sampler2D texture;","varying vec3 vNormal;","varying vec2 vUv;","void main() {","vec3 diffuse = texture2D( texture, vUv ).xyz;","float intensity = 1.05 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) );","vec3 atmosphere = vec3( 1.0, 1.0, 1.0 ) * pow( intensity, 3.0 );","gl_FragColor = vec4( diffuse + atmosphere, 1.0 );","}"].join("\n")},atmosphere:{uniforms:{},vertexShader:["varying vec3 vNormal;","void main() {","vNormal = normalize( normalMatrix * normal );","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["varying vec3 vNormal;","void main() {","float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 12.0 );","gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;","}"].join("\n")}};return function(e,t=Object,n=!1){class r extends t{constructor(...t){super(...t),this.__kapsuleInstance=e()(...n?[this]:[],...t)}}return Object.keys(e()).forEach(e=>r.prototype[e]=function(...t){const n=this.__kapsuleInstance[e](...t);return n===this.__kapsuleInstance?this:n}),r}(a({props:{globeImageUrl:{onChange(e){this._loadGlobeImage(e)},triggerUpdate:!1},pointsData:{default:[],onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLat:{default:"lat",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLng:{default:"lng",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointColor:{default:()=>"#ffffaa",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointHeight:{default:.1,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointRadius:{default:.25,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointResolution:{default:12,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointsMerge:{default:!1,onChange(e,t){t.pointsNeedsRepopulating=!0}},linksData:{default:[],onChange(e,t){t.linksNeedsRepopulating=!0}},linkStartLat:{default:"startLat",onChange(e,t){t.linksNeedsRepopulating=!0}},linkStartLng:{default:"endLng",onChange(e,t){t.linksNeedsRepopulating=!0}},linkEndLat:{default:"endLat",onChange(e,t){t.linksNeedsRepopulating=!0}},linkEndLng:{default:"endLng",onChange(e,t){t.linksNeedsRepopulating=!0}},linkColor:{default:()=>"#ffffaa",onChange(e,t){t.linksNeedsRepopulating=!0}},linkHeight:{default:.4,onChange(e,t){t.linksNeedsRepopulating=!0}},linkDiameter:{default:.2,onChange(e,t){t.linksNeedsRepopulating=!0}},linkCurveResolution:{default:64,onChange(e,t){t.linksNeedsRepopulating=!0}},linkCircularResolution:{default:6,onChange(e,t){t.linksNeedsRepopulating=!0}},linksMerge:{default:!1,onChange(e,t){t.linksNeedsRepopulating=!0}},customLayerData:{default:[],onChange(e,t){t.customLayerNeedsRepopulating=!0}},customThreeObject:{onChange(e,t){t.customLayerNeedsRepopulating=!0}}},methods:{getCoords(e,t,n,r=0){const a=(90-t)*Math.PI/180,i=(-45-n)*Math.PI/180,o=100*(1+r);return{x:o*Math.sin(a)*Math.cos(i),y:o*Math.cos(a),z:o*Math.sin(a)*Math.sin(i)}},_loadGlobeImage:function(e,t){if(e.globeObj&&t){const n=h.earth,r=f.UniformsUtils.clone(n.uniforms);r.texture.value=(new f.TextureLoader).load(t),e.globeObj.material=new f.ShaderMaterial({uniforms:r,vertexShader:n.vertexShader,fragmentShader:n.fragmentShader})}return this}},stateInit:()=>({pointsNeedsRepopulating:!0,linksNeedsRepopulating:!0,customLayerNeedsRepopulating:!0}),init(e,t){t.scene=e,c(t.scene);const n=new f.SphereGeometry(100,40,30),r=t.globeObj=new f.Mesh(n,new f.MeshBasicMaterial({color:0}));r.rotation.y=Math.PI/4,r.__globeObjType="globe",t.scene.add(r),t.globeImageUrl&&this._loadGlobeImage(t.globeImageUrl);{const e=h.atmosphere,r=f.UniformsUtils.clone(e.uniforms),a=new f.ShaderMaterial({uniforms:r,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,side:f.BackSide,blending:f.AdditiveBlending,transparent:!0}),i=new f.Mesh(n,a);i.scale.set(1.1,1.1,1.1),i.__globeObjType="atmosphere",t.scene.add(i)}t.scene.add(t.pointsG=new f.Group),t.scene.add(t.linksG=new f.Group),t.scene.add(t.customLayerG=new f.Group)},update(e){const t=2*Math.PI*100/360;if(e.pointsNeedsRepopulating){e.pointsNeedRepopulating=!1,c(e.pointsG);const n=o(e.pointLat),r=o(e.pointLng),a=o(e.pointHeight),i=o(e.pointRadius),s=o(e.pointColor),h=new f.CylinderGeometry(1,1,1,e.pointResolution);h.applyMatrix((new f.Matrix4).makeRotationX(Math.PI/2)),h.applyMatrix((new f.Matrix4).makeTranslation(0,0,-.5));const d=[];if(e.pointsData.forEach(o=>{const s=new f.Mesh(h);Object.assign(s.position,this.getCoords(n(o),r(o))),s.lookAt(e.globeObj.position),s.scale.x=s.scale.y=Math.min(30,i(o))*t,s.scale.z=Math.max(100*a(o),.1),s.__globeObjType="point",s.__data=o,d.push(s)}),e.pointsMerge){const t=new f.Geometry;d.forEach(e=>{const n=e.__data,r=new f.Color(s(n));e.geometry.faces.forEach(e=>e.color=r),e.updateMatrix(),t.merge(e.geometry,e.matrix)});const n=new f.Mesh(t,new f.MeshBasicMaterial({color:16777215,vertexColors:f.FaceColors,morphTargets:!1}));n.__globeObjType="points",n.__data=e.pointsData,e.pointsG.add(n)}else{const t={};d.forEach(n=>{const r=n.__data,a=s(r),i=u(a);t.hasOwnProperty(a)||(t[a]=new f.MeshLambertMaterial({color:l(a),transparent:i<1,opacity:i})),n.material=t[a],e.pointsG.add(r.__threeObj=n)})}}if(e.linksNeedsRepopulating){e.linksNeedsRepopulating=!1,c(e.linksG);const t=o(e.linkStartLat),n=o(e.linkStartLng),r=o(e.linkEndLat),a=o(e.linkEndLng),i=o(e.linkHeight),s=o(e.linkDiameter),h=o(e.linkColor),d=[];if(e.linksData.forEach(o=>{const l=[...[t,n].map(e=>e(o)),0],u=[...[r,a].map(e=>e(o)),0],c=(e,t)=>e+(t-e)/2,h=[l,[c(l[0],u[0]),c(l[1],u[1]),2*i(o)],u].map(([e,t,n])=>{const r=this.getCoords(e,t,n);return new f.Vector3(r.x,r.y,r.z)}),g=new f.QuadraticBezierCurve3(...h),p=new f.TubeGeometry(g,e.linkCurveResolution,s(o)/2,e.linkCircularResolution),b=new f.Mesh(p);b.__globeObjType="link",b.__data=o,d.push(b)}),e.linksMerge){const t=new f.Geometry;d.forEach(e=>{const n=e.__data,r=new f.Color(h(n));e.geometry.faces.forEach(e=>e.color=r),e.updateMatrix(),t.merge(e.geometry,e.matrix)});const n=new f.Mesh(t,new f.MeshBasicMaterial({color:16777215,vertexColors:f.FaceColors,morphTargets:!1}));n.__globeObjType="links",n.__data=e.linksData,e.linksG.add(n)}else{const t={};d.forEach(n=>{const r=n.__data,a=h(r),i=u(a);t.hasOwnProperty(a)||(t[a]=new f.MeshLambertMaterial({color:l(a),transparent:i<1,opacity:i})),n.material=t[a],e.linksG.add(r.__threeObj=n)})}}if(e.customLayerNeedsRepopulating){e.customLayerNeedsRepopulating=!1,c(e.customLayerG);const t=o(e.customThreeObject);e.customLayerData.forEach(n=>{let r=t(n,100);r&&(e.customThreeObject===r&&(r=r.clone()),r.__globeObjType="custom",r.__data=n,e.customLayerG.add(n.__threeObj=r))})}}}),e.Group,!0)});
l.readability=function(e,n){var r=l(e),a=l(n);return(t.max(r.getLuminance(),a.getLuminance())+.05)/(t.min(r.getLuminance(),a.getLuminance())+.05)},l.isReadable=function(e,t,n){var r,a,o=l.readability(e,t);switch(a=!1,(r=function(e){var t,n;t=((e=e||{level:"AA",size:"small"}).level||"AA").toUpperCase(),n=(e.size||"small").toLowerCase(),"AA"!==t&&"AAA"!==t&&(t="AA");"small"!==n&&"large"!==n&&(n="small");return{level:t,size:n}}(n)).level+r.size){case"AAsmall":case"AAAlarge":a=o>=4.5;break;case"AAlarge":a=o>=3;break;case"AAAsmall":a=o>=7}return a},l.mostReadable=function(e,t,n){var r,a,o,i,s=null,u=0;a=(n=n||{}).includeFallbackColors,o=n.level,i=n.size;for(var c=0;c<t.length;c++)(r=l.readability(e,t[c]))>u&&(u=r,s=l(t[c]));return l.isReadable(e,s,{level:o,size:i})||!a?s:(n.includeFallbackColors=!1,l.mostReadable(e,["#fff","#000"],n))};var R=l.names={aliceblue:"f0f8ff",antiquewhite:"faebd7",aqua:"0ff",aquamarine:"7fffd4",azure:"f0ffff",beige:"f5f5dc",bisque:"ffe4c4",black:"000",blanchedalmond:"ffebcd",blue:"00f",blueviolet:"8a2be2",brown:"a52a2a",burlywood:"deb887",burntsienna:"ea7e5d",cadetblue:"5f9ea0",chartreuse:"7fff00",chocolate:"d2691e",coral:"ff7f50",cornflowerblue:"6495ed",cornsilk:"fff8dc",crimson:"dc143c",cyan:"0ff",darkblue:"00008b",darkcyan:"008b8b",darkgoldenrod:"b8860b",darkgray:"a9a9a9",darkgreen:"006400",darkgrey:"a9a9a9",darkkhaki:"bdb76b",darkmagenta:"8b008b",darkolivegreen:"556b2f",darkorange:"ff8c00",darkorchid:"9932cc",darkred:"8b0000",darksalmon:"e9967a",darkseagreen:"8fbc8f",darkslateblue:"483d8b",darkslategray:"2f4f4f",darkslategrey:"2f4f4f",darkturquoise:"00ced1",darkviolet:"9400d3",deeppink:"ff1493",deepskyblue:"00bfff",dimgray:"696969",dimgrey:"696969",dodgerblue:"1e90ff",firebrick:"b22222",floralwhite:"fffaf0",forestgreen:"228b22",fuchsia:"f0f",gainsboro:"dcdcdc",ghostwhite:"f8f8ff",gold:"ffd700",goldenrod:"daa520",gray:"808080",green:"008000",greenyellow:"adff2f",grey:"808080",honeydew:"f0fff0",hotpink:"ff69b4",indianred:"cd5c5c",indigo:"4b0082",ivory:"fffff0",khaki:"f0e68c",lavender:"e6e6fa",lavenderblush:"fff0f5",lawngreen:"7cfc00",lemonchiffon:"fffacd",lightblue:"add8e6",lightcoral:"f08080",lightcyan:"e0ffff",lightgoldenrodyellow:"fafad2",lightgray:"d3d3d3",lightgreen:"90ee90",lightgrey:"d3d3d3",lightpink:"ffb6c1",lightsalmon:"ffa07a",lightseagreen:"20b2aa",lightskyblue:"87cefa",lightslategray:"789",lightslategrey:"789",lightsteelblue:"b0c4de",lightyellow:"ffffe0",lime:"0f0",limegreen:"32cd32",linen:"faf0e6",magenta:"f0f",maroon:"800000",mediumaquamarine:"66cdaa",mediumblue:"0000cd",mediumorchid:"ba55d3",mediumpurple:"9370db",mediumseagreen:"3cb371",mediumslateblue:"7b68ee",mediumspringgreen:"00fa9a",mediumturquoise:"48d1cc",mediumvioletred:"c71585",midnightblue:"191970",mintcream:"f5fffa",mistyrose:"ffe4e1",moccasin:"ffe4b5",navajowhite:"ffdead",navy:"000080",oldlace:"fdf5e6",olive:"808000",olivedrab:"6b8e23",orange:"ffa500",orangered:"ff4500",orchid:"da70d6",palegoldenrod:"eee8aa",palegreen:"98fb98",paleturquoise:"afeeee",palevioletred:"db7093",papayawhip:"ffefd5",peachpuff:"ffdab9",peru:"cd853f",pink:"ffc0cb",plum:"dda0dd",powderblue:"b0e0e6",purple:"800080",rebeccapurple:"663399",red:"f00",rosybrown:"bc8f8f",royalblue:"4169e1",saddlebrown:"8b4513",salmon:"fa8072",sandybrown:"f4a460",seagreen:"2e8b57",seashell:"fff5ee",sienna:"a0522d",silver:"c0c0c0",skyblue:"87ceeb",slateblue:"6a5acd",slategray:"708090",slategrey:"708090",snow:"fffafa",springgreen:"00ff7f",steelblue:"4682b4",tan:"d2b48c",teal:"008080",thistle:"d8bfd8",tomato:"ff6347",turquoise:"40e0d0",violet:"ee82ee",wheat:"f5deb3",white:"fff",whitesmoke:"f5f5f5",yellow:"ff0",yellowgreen:"9acd32"},k=l.hexNames=function(e){var t={};for(var n in e)e.hasOwnProperty(n)&&(t[e[n]]=n);return t}(R);function N(e){return e=parseFloat(e),(isNaN(e)||e<0||e>1)&&(e=1),e}function L(e,n){(function(e){return"string"==typeof e&&-1!=e.indexOf(".")&&1===parseFloat(e)})(e)&&(e="100%");var r=function(e){return"string"==typeof e&&-1!=e.indexOf("%")}(e);return e=i(n,s(0,parseFloat(e))),r&&(e=parseInt(e*n,10)/100),t.abs(e-n)<1e-6?1:e%n/parseFloat(n)}function O(e){return i(1,s(0,e))}function j(e){return parseInt(e,16)}function E(e){return 1==e.length?"0"+e:""+e}function G(e){return e<=1&&(e=100*e+"%"),e}function T(e){return t.round(255*parseFloat(e)).toString(16)}function F(e){return j(e)/255}var P,H,U,I=(H="[\\s|\\(]+("+(P="(?:[-\\+]?\\d*\\.\\d+%?)|(?:[-\\+]?\\d+%?)")+")[,|\\s]+("+P+")[,|\\s]+("+P+")\\s*\\)?",U="[\\s|\\(]+("+P+")[,|\\s]+("+P+")[,|\\s]+("+P+")[,|\\s]+("+P+")\\s*\\)?",{CSS_UNIT:new RegExp(P),rgb:new RegExp("rgb"+H),rgba:new RegExp("rgba"+U),hsl:new RegExp("hsl"+H),hsla:new RegExp("hsla"+U),hsv:new RegExp("hsv"+H),hsva:new RegExp("hsva"+U),hex3:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex6:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/,hex4:/^#?([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})([0-9a-fA-F]{1})$/,hex8:/^#?([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})([0-9a-fA-F]{2})$/});function B(e){return!!I.CSS_UNIT.exec(e)}e.exports?e.exports=l:window.tinycolor=l}(Math)});const D=e=>isNaN(e)?parseInt(z(e).toHex(),16):e,q=e=>isNaN(e)?z(e).getAlpha():1,V=window.THREE?window.THREE:{AdditiveBlending:e.AdditiveBlending,BackSide:e.BackSide,BufferGeometry:e.BufferGeometry,Color:e.Color,CylinderGeometry:e.CylinderGeometry,FaceColors:e.FaceColors,Geometry:e.Geometry,Group:e.Group,Line:e.Line,Matrix4:e.Matrix4,Mesh:e.Mesh,MeshBasicMaterial:e.MeshBasicMaterial,MeshLambertMaterial:e.MeshLambertMaterial,QuadraticBezierCurve3:e.QuadraticBezierCurve3,ShaderMaterial:e.ShaderMaterial,SphereGeometry:e.SphereGeometry,TextureLoader:e.TextureLoader,TubeGeometry:e.TubeGeometry,UniformsUtils:e.UniformsUtils,Vector3:e.Vector3},$=e=>{const t=e=>{e instanceof Array?e.forEach(t):(e.map&&e.map.dispose(),e.dispose())},n=e=>{e.geometry&&e.geometry.dispose(),e.material&&t(e.material),e.texture&&e.texture.dispose(),e.children&&e.children.forEach(n)};for(;e.children.length;){const e=state.pointsG.children[0];state.pointsG.remove(e),n(e)}},Q={earth:{uniforms:{texture:{type:"t",value:null}},vertexShader:["varying vec3 vNormal;","varying vec2 vUv;","void main() {","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","vNormal = normalize( normalMatrix * normal );","vUv = uv;","}"].join("\n"),fragmentShader:["uniform sampler2D texture;","varying vec3 vNormal;","varying vec2 vUv;","void main() {","vec3 diffuse = texture2D( texture, vUv ).xyz;","float intensity = 1.05 - dot( vNormal, vec3( 0.0, 0.0, 1.0 ) );","vec3 atmosphere = vec3( 1.0, 1.0, 1.0 ) * pow( intensity, 3.0 );","gl_FragColor = vec4( diffuse + atmosphere, 1.0 );","}"].join("\n")},atmosphere:{uniforms:{},vertexShader:["varying vec3 vNormal;","void main() {","vNormal = normalize( normalMatrix * normal );","gl_Position = projectionMatrix * modelViewMatrix * vec4( position, 1.0 );","}"].join("\n"),fragmentShader:["varying vec3 vNormal;","void main() {","float intensity = pow( 0.8 - dot( vNormal, vec3( 0, 0, 1.0 ) ), 12.0 );","gl_FragColor = vec4( 1.0, 1.0, 1.0, 1.0 ) * intensity;","}"].join("\n")}};return function(e,t=Object,n=!1){class r extends t{constructor(...t){super(...t),this.__kapsuleInstance=e()(...n?[this]:[],...t)}}return Object.keys(e()).forEach(e=>r.prototype[e]=function(...t){const n=this.__kapsuleInstance[e](...t);return n===this.__kapsuleInstance?this:n}),r}(a({props:{globeImageUrl:{onChange(e,t){t.globeNeedsUpdate=!0}},pointsData:{default:[],onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLat:{default:"lat",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointLng:{default:"lng",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointColor:{default:()=>"#ffffaa",onChange(e,t){t.pointsNeedsRepopulating=!0}},pointAltitude:{default:.1,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointRadius:{default:.25,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointResolution:{default:12,onChange(e,t){t.pointsNeedsRepopulating=!0}},pointsMerge:{default:!1,onChange(e,t){t.pointsNeedsRepopulating=!0}},arcsData:{default:[],onChange(e,t){t.arcsNeedsRepopulating=!0}},arcStartLat:{default:"startLat",onChange(e,t){t.arcsNeedsRepopulating=!0}},arcStartLng:{default:"startLng",onChange(e,t){t.arcsNeedsRepopulating=!0}},arcEndLat:{default:"endLat",onChange(e,t){t.arcsNeedsRepopulating=!0}},arcEndLng:{default:"endLng",onChange(e,t){t.arcsNeedsRepopulating=!0}},arcColor:{default:()=>"#ffffaa",onChange(e,t){t.arcsNeedsRepopulating=!0}},arcAltitude:{onChange(e,t){t.arcsNeedsRepopulating=!0}},arcAltitudeAutoScale:{default:.5,onChange(e,t){t.arcsNeedsRepopulating=!0}},arcStroke:{onChange(e,t){t.arcsNeedsRepopulating=!0}},arcCurveResolution:{default:64,onChange(e,t){t.arcsNeedsRepopulating=!0}},arcCircularResolution:{default:6,onChange(e,t){t.arcsNeedsRepopulating=!0}},arcsMerge:{default:!1,onChange(e,t){t.arcsNeedsRepopulating=!0}},customLayerData:{default:[],onChange(e,t){t.customLayerNeedsRepopulating=!0}},customThreeObject:{onChange(e,t){t.customLayerNeedsRepopulating=!0}}},methods:{getCoords(e,t,n,r=0){const a=(90-t)*Math.PI/180,o=(-45-n)*Math.PI/180,i=100*(1+r);return{x:i*Math.sin(a)*Math.cos(o),y:i*Math.cos(a),z:i*Math.sin(a)*Math.sin(o)}}},stateInit:()=>({globeNeedsUpdate:!0,pointsNeedsRepopulating:!0,arcsNeedsRepopulating:!0,customLayerNeedsRepopulating:!0}),init(e,t){t.scene=e,$(t.scene);const n=new V.SphereGeometry(100,40,30),r=t.globeObj=new V.Mesh(n,new V.MeshBasicMaterial({color:0}));r.rotation.y=Math.PI/4,r.__globeObjType="globe",t.scene.add(r);{const e=Q.atmosphere,r=V.UniformsUtils.clone(e.uniforms),a=new V.ShaderMaterial({uniforms:r,vertexShader:e.vertexShader,fragmentShader:e.fragmentShader,side:V.BackSide,blending:V.AdditiveBlending,transparent:!0}),o=new V.Mesh(n,a);o.scale.set(1.1,1.1,1.1),o.__globeObjType="atmosphere",t.scene.add(o)}t.scene.add(t.pointsG=new V.Group),t.scene.add(t.arcsG=new V.Group),t.scene.add(t.customLayerG=new V.Group)},update(e){const t=2*Math.PI*100/360;if(e.globeNeedsUpdate)if(e.globeNeedsUpdate=!1,e.globeImageUrl){const t=Q.earth,n=V.UniformsUtils.clone(t.uniforms);n.texture.value=(new V.TextureLoader).load(e.globeImageUrl),e.globeObj.material=new V.ShaderMaterial({uniforms:n,vertexShader:t.vertexShader,fragmentShader:t.fragmentShader})}else e.globeObj.material=new V.MeshBasicMaterial({color:0});if(e.pointsNeedsRepopulating){e.pointsNeedsRepopulating=!1,$(e.pointsG);const n=i(e.pointLat),r=i(e.pointLng),a=i(e.pointAltitude),o=i(e.pointRadius),s=i(e.pointColor),u=new V.CylinderGeometry(1,1,1,e.pointResolution);u.applyMatrix((new V.Matrix4).makeRotationX(Math.PI/2)),u.applyMatrix((new V.Matrix4).makeTranslation(0,0,-.5));const l=[];if(e.pointsData.forEach(i=>{const s=new V.Mesh(u);Object.assign(s.position,this.getCoords(n(i),r(i))),s.lookAt(e.globeObj.position),s.scale.x=s.scale.y=Math.min(30,o(i))*t,s.scale.z=Math.max(100*a(i),.1),s.__globeObjType="point",s.__data=i,l.push(s)}),e.pointsMerge){const t=new V.Geometry;l.forEach(e=>{const n=e.__data,r=new V.Color(s(n));e.geometry.faces.forEach(e=>e.color=r),e.updateMatrix(),t.merge(e.geometry,e.matrix)});const n=new V.Mesh(t,new V.MeshBasicMaterial({color:16777215,vertexColors:V.FaceColors,morphTargets:!1}));n.__globeObjType="points",n.__data=e.pointsData,e.pointsG.add(n)}else{const t={};l.forEach(n=>{const r=n.__data,a=s(r),o=q(a);t.hasOwnProperty(a)||(t[a]=new V.MeshLambertMaterial({color:D(a),transparent:o<1,opacity:o})),n.material=t[a],e.pointsG.add(r.__threeObj=n)})}}if(e.arcsNeedsRepopulating){e.arcsNeedsRepopulating=!1,$(e.arcsG);const t=i(e.arcStartLat),n=i(e.arcStartLng),r=i(e.arcEndLat),a=i(e.arcEndLng),o=i(e.arcAltitude),s=i(e.arcAltitudeAutoScale),u=i(e.arcStroke),l=i(e.arcColor),c=[];if(e.arcsData.forEach(i=>{let l;{const e=([e,t,n])=>{const{x:r,y:a,z:o}=this.getCoords(t,e,n);return new V.Vector3(r,a,o)},u=[n,t].map(e=>e(i)),c=[a,r].map(e=>e(i));let f=o(i);null==f&&(f=function(e,t){return U[0]=e,U[1]=t,H(I)}(u,c)/2*s(i));const h=B(u,c),[d,g]=[.25,.75].map(e=>[...h(e),1.5*f]);l=new V.CubicBezierCurve3(...[u,d,g,c].map(e))}const f=u(i),h=null==f?new V.Line((new V.BufferGeometry).setFromPoints(l.getPoints(e.arcCurveResolution))):new V.Mesh(new V.TubeGeometry(l,e.arcCurveResolution,f/2,e.arcCircularResolution));h.__globeObjType="arc",h.__data=i,c.push(h)}),e.arcsMerge){const t=new V.Geometry;c.forEach(e=>{const n=e.__data,r=new V.Color(l(n));e.geometry.faces.forEach(e=>e.color=r),e.updateMatrix(),t.merge(e.geometry,e.matrix)});const n=new V.Mesh(t,new V.MeshBasicMaterial({color:16777215,vertexColors:V.FaceColors,morphTargets:!1}));n.__globeObjType="arcs",n.__data=e.arcsData,e.arcsG.add(n)}else{const t={};c.forEach(n=>{const r=n.__data,a=l(r),o=q(a);t.hasOwnProperty(a)||(t[a]=new V.MeshLambertMaterial({color:D(a),transparent:o<1,opacity:o})),n.material=t[a],e.arcsG.add(r.__threeObj=n)})}}if(e.customLayerNeedsRepopulating){e.customLayerNeedsRepopulating=!1,$(e.customLayerG);const t=i(e.customThreeObject);e.customLayerData.forEach(n=>{let r=t(n,100);r&&(e.customThreeObject===r&&(r=r.clone()),r.__globeObjType="custom",r.__data=n,e.customLayerG.add(n.__threeObj=r))})}}}),e.Group,!0)});

@@ -1,4 +0,5 @@

import { AdditiveBlending, BackSide, Color, CylinderGeometry, FaceColors, Geometry, Group, Matrix4, Mesh, MeshBasicMaterial, MeshLambertMaterial, QuadraticBezierCurve3, ShaderMaterial, SphereGeometry, TextureLoader, TubeGeometry, UniformsUtils, Vector3 } from 'three';
import { AdditiveBlending, BackSide, BufferGeometry, Color, CylinderGeometry, FaceColors, Geometry, Group, Line, Matrix4, Mesh, MeshBasicMaterial, MeshLambertMaterial, QuadraticBezierCurve3, ShaderMaterial, SphereGeometry, TextureLoader, TubeGeometry, UniformsUtils, Vector3 } from 'three';
import Kapsule from 'kapsule';
import accessorFn from 'accessor-fn';
import { geoDistance, geoInterpolate } from 'd3-geo';
import tinyColor from 'tinycolor2';

@@ -14,2 +15,3 @@

BackSide,
BufferGeometry,
Color,

@@ -20,2 +22,3 @@ CylinderGeometry,

Group,
Line,
Matrix4,

@@ -94,7 +97,6 @@ Mesh,

globeImageUrl: {
onChange(url) {
this._loadGlobeImage(url);
},
onChange(_, state) {
state.globeNeedsUpdate = true;
}
triggerUpdate: false
},

@@ -133,3 +135,3 @@ pointsData: {

},
pointHeight: {
pointAltitude: {
default: 0.1,

@@ -170,55 +172,53 @@

// boolean. Whether to merge all points into a single mesh for rendering performance
linksData: {
arcsData: {
default: [],
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkStartLat: {
arcStartLat: {
default: 'startLat',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkStartLng: {
default: 'endLng',
arcStartLng: {
default: 'startLng',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkEndLat: {
arcEndLat: {
default: 'endLat',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkEndLng: {
arcEndLng: {
default: 'endLng',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkColor: {
arcColor: {
default: () => '#ffffaa',
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
linkHeight: {
default: 0.4,
arcAltitude: {
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}

@@ -228,16 +228,23 @@

// in units of globe radius
linkDiameter: {
default: 0.2,
arcAltitudeAutoScale: {
default: 0.5,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
// scale altitude proportional to great-arc distance between the two points
arcStroke: {
onChange(_, state) {
state.arcsNeedsRepopulating = true;
}
},
// in deg
linkCurveResolution: {
arcCurveResolution: {
default: 64,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}

@@ -247,7 +254,7 @@

// how many slice segments in the tube's circumference
linkCircularResolution: {
arcCircularResolution: {
default: 6,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}

@@ -257,11 +264,11 @@

// how many slice segments in the tube's circumference
linksMerge: {
arcsMerge: {
default: false,
onChange(_, state) {
state.linksNeedsRepopulating = true;
state.arcsNeedsRepopulating = true;
}
},
// boolean. Whether to merge all links into a single mesh for rendering performance
// boolean. Whether to merge all arcs into a single mesh for rendering performance
customLayerData: {

@@ -292,22 +299,9 @@ default: [],

};
},
}
_loadGlobeImage: function (state, imageUrl) {
if (state.globeObj && imageUrl) {
const shader = Shaders.earth;
const uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms.texture.value = new THREE.TextureLoader().load(imageUrl);
state.globeObj.material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
}
return this;
}
},
stateInit: () => ({
globeNeedsUpdate: true,
pointsNeedsRepopulating: true,
linksNeedsRepopulating: true,
arcsNeedsRepopulating: true,
customLayerNeedsRepopulating: true

@@ -330,4 +324,3 @@ }),

state.scene.add(globeObj);
state.globeImageUrl && this._loadGlobeImage(state.globeImageUrl); // add atmosphere
state.scene.add(globeObj); // add atmosphere

@@ -352,5 +345,5 @@ {

state.scene.add(state.pointsG = new THREE.Group()); // add links group
state.scene.add(state.pointsG = new THREE.Group()); // add arcs group
state.scene.add(state.linksG = new THREE.Group()); // add custom layer group
state.scene.add(state.arcsG = new THREE.Group()); // add custom layer group

@@ -363,4 +356,24 @@ state.scene.add(state.customLayerG = new THREE.Group());

if (state.globeNeedsUpdate) {
state.globeNeedsUpdate = false;
if (!state.globeImageUrl) {
// Black globe
state.globeObj.material = new THREE.MeshBasicMaterial({
color: 0x000000
});
} else {
const shader = Shaders.earth;
const uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms.texture.value = new THREE.TextureLoader().load(state.globeImageUrl);
state.globeObj.material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
}
}
if (state.pointsNeedsRepopulating) {
state.pointsNeedRepopulating = false; // Clear the existing points
state.pointsNeedsRepopulating = false; // Clear the existing points

@@ -371,3 +384,3 @@ emptyObject(state.pointsG); // Data accessors

const lngAccessor = accessorFn(state.pointLng);
const heightAccessor = accessorFn(state.pointHeight);
const altitudeAccessor = accessorFn(state.pointAltitude);
const radiusAccessor = accessorFn(state.pointRadius);

@@ -388,3 +401,3 @@ const colorAccessor = accessorFn(state.pointColor); // Add WebGL points

obj.scale.x = obj.scale.y = Math.min(30, radiusAccessor(pnt)) * pxPerDeg;
obj.scale.z = Math.max(heightAccessor(pnt) * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix
obj.scale.z = Math.max(altitudeAccessor(pnt) * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix

@@ -441,47 +454,59 @@ obj.__globeObjType = 'point'; // Add object type

if (state.linksNeedsRepopulating) {
state.linksNeedsRepopulating = false; // Clear the existing links
if (state.arcsNeedsRepopulating) {
state.arcsNeedsRepopulating = false; // Clear the existing arcs
emptyObject(state.linksG); // Data accessors
emptyObject(state.arcsG); // Data accessors
const startLatAccessor = accessorFn(state.linkStartLat);
const startLngAccessor = accessorFn(state.linkStartLng);
const endLatAccessor = accessorFn(state.linkEndLat);
const endLngAccessor = accessorFn(state.linkEndLng);
const heightAccessor = accessorFn(state.linkHeight);
const diameterAccessor = accessorFn(state.linkDiameter);
const colorAccessor = accessorFn(state.linkColor);
const linkObjs = [];
state.linksData.forEach(link => {
const startPnt = [...[startLatAccessor, startLngAccessor].map(fn => fn(link)), 0];
const endPnt = [...[endLatAccessor, endLngAccessor].map(fn => fn(link)), 0];
const startLatAccessor = accessorFn(state.arcStartLat);
const startLngAccessor = accessorFn(state.arcStartLng);
const endLatAccessor = accessorFn(state.arcEndLat);
const endLngAccessor = accessorFn(state.arcEndLng);
const altitudeAccessor = accessorFn(state.arcAltitude);
const altitudeAutoScaleAccessor = accessorFn(state.arcAltitudeAutoScale);
const strokeAccessor = accessorFn(state.arcStroke);
const colorAccessor = accessorFn(state.arcColor);
const arcObjs = [];
state.arcsData.forEach(arc => {
let curve;
{
const getVec = ([lng, lat, alt]) => {
const {
x,
y,
z
} = this.getCoords(lat, lng, alt);
return new THREE.Vector3(x, y, z);
}; //calculate curve
const getMiddle = (a, b) => a + (b - a) / 2;
const middlePoint = [getMiddle(startPnt[0], endPnt[0]), getMiddle(startPnt[1], endPnt[1]), heightAccessor(link) * 2];
const curveVecs = [startPnt, middlePoint, endPnt].map(([lat, lng, alt]) => {
const coords = this.getCoords(lat, lng, alt);
return new THREE.Vector3(coords.x, coords.y, coords.z);
});
const path = new THREE.QuadraticBezierCurve3(...curveVecs);
const linkGeometry = new THREE.TubeGeometry(path, state.linkCurveResolution, diameterAccessor(link) / 2, state.linkCircularResolution);
const obj = new THREE.Mesh(linkGeometry);
obj.__globeObjType = 'link'; // Add object type
const startPnt = [startLngAccessor, startLatAccessor].map(fn => fn(arc));
const endPnt = [endLngAccessor, endLatAccessor].map(fn => fn(arc));
let altitude = altitudeAccessor(arc);
(altitude === null || altitude === undefined) && ( // by default set altitude proportional to the great-arc distance
altitude = geoDistance(startPnt, endPnt) / 2 * altitudeAutoScaleAccessor(arc));
const interpolate = geoInterpolate(startPnt, endPnt);
const [m1Pnt, m2Pnt] = [0.25, 0.75].map(t => [...interpolate(t), altitude * 1.5]);
curve = new THREE.CubicBezierCurve3(...[startPnt, m1Pnt, m2Pnt, endPnt].map(getVec)); //const mPnt = [...interpolate(0.5), altitude * 2];
//curve = new THREE.QuadraticBezierCurve3(...[startPnt, mPnt, endPnt].map(getVec));
}
const stroke = strokeAccessor(arc);
const obj = stroke === null || stroke === undefined ? new THREE.Line(new THREE.BufferGeometry().setFromPoints(curve.getPoints(state.arcCurveResolution))) : new THREE.Mesh(new THREE.TubeGeometry(curve, state.arcCurveResolution, stroke / 2, state.arcCircularResolution));
obj.__globeObjType = 'arc'; // Add object type
obj.__data = link; // Attach point data
obj.__data = arc; // Attach point data
linkObjs.push(obj);
arcObjs.push(obj);
});
if (state.linksMerge) {
// merge links into a single mesh
const linksGeometry = new THREE.Geometry();
linkObjs.forEach(obj => {
const link = obj.__data;
const color = new THREE.Color(colorAccessor(link));
if (state.arcsMerge) {
// merge arcs into a single mesh
const arcsGeometry = new THREE.Geometry();
arcObjs.forEach(obj => {
const arc = obj.__data;
const color = new THREE.Color(colorAccessor(arc));
obj.geometry.faces.forEach(face => face.color = color);
obj.updateMatrix();
linksGeometry.merge(obj.geometry, obj.matrix);
arcsGeometry.merge(obj.geometry, obj.matrix);
});
const links = new THREE.Mesh(linksGeometry, new THREE.MeshBasicMaterial({
const arcs = new THREE.Mesh(arcsGeometry, new THREE.MeshBasicMaterial({
color: 0xffffff,

@@ -491,18 +516,18 @@ vertexColors: THREE.FaceColors,

}));
links.__globeObjType = 'links'; // Add object type
arcs.__globeObjType = 'arcs'; // Add object type
links.__data = state.linksData; // Attach obj data
arcs.__data = state.arcsData; // Attach obj data
state.linksG.add(links);
state.arcsG.add(arcs);
} else {
// Add individual meshes per link
const linkMaterials = {}; // indexed by color
// Add individual meshes per arc
const arcMaterials = {}; // indexed by color
linkObjs.forEach(obj => {
const link = obj.__data;
const color = colorAccessor(link);
arcObjs.forEach(obj => {
const arc = obj.__data;
const color = colorAccessor(arc);
const opacity = colorAlpha(color);
if (!linkMaterials.hasOwnProperty(color)) {
linkMaterials[color] = new THREE.MeshLambertMaterial({
if (!arcMaterials.hasOwnProperty(color)) {
arcMaterials[color] = new THREE.MeshLambertMaterial({
color: colorStr2Hex(color),

@@ -514,4 +539,4 @@ transparent: opacity < 1,

obj.material = linkMaterials[color];
state.linksG.add(link.__threeObj = obj);
obj.material = arcMaterials[color];
state.arcsG.add(arc.__threeObj = obj);
});

@@ -518,0 +543,0 @@ }

{
"name": "three-globe",
"version": "1.0.5",
"version": "1.0.6",
"description": "Globe data visualization as a ThreeJS reusable 3D object",

@@ -41,2 +41,3 @@ "unpkg": "dist/three-globe.min.js",

"accessor-fn": "^1.2.2",
"d3-geo": "^1.11.3",
"kapsule": "^1.10.0",

@@ -43,0 +44,0 @@ "tinycolor2": "^1.4.1"

@@ -9,3 +9,3 @@ # ThreeJS Globe Visualization

Largely inspired by the [WebGL Globe](https://experiments.withgoogle.com/chrome/globe), this is a [ThreeJS](https://threejs.org/) WebGL class to represent data visualization layers on a globe, using spherical projection.
Largely inspired by [WebGL Globe](https://experiments.withgoogle.com/chrome/globe), this is a [ThreeJS](https://threejs.org/) WebGL class to represent data visualization layers on a globe, using spherical projection.

@@ -12,0 +12,0 @@ ## Quick start

import {
AdditiveBlending,
BackSide,
BufferGeometry,
Color,

@@ -9,2 +10,3 @@ CylinderGeometry,

Group,
Line,
Matrix4,

@@ -28,2 +30,3 @@ Mesh,

BackSide,
BufferGeometry,
Color,

@@ -34,2 +37,3 @@ CylinderGeometry,

Group,
Line,
Matrix4,

@@ -50,2 +54,3 @@ Mesh,

import accessorFn from 'accessor-fn';
import { geoDistance, geoInterpolate } from 'd3-geo';

@@ -129,3 +134,3 @@ import { colorStr2Hex, colorAlpha } from './color-utils';

props: {
globeImageUrl: { onChange(url) { this._loadGlobeImage(url)}, triggerUpdate: false},
globeImageUrl: { onChange(_, state) { state.globeNeedsUpdate = true }},
pointsData: { default: [], onChange(_, state) { state.pointsNeedsRepopulating = true }},

@@ -135,17 +140,18 @@ pointLat: { default: 'lat', onChange(_, state) { state.pointsNeedsRepopulating = true }},

pointColor: { default: () => '#ffffaa', onChange(_, state) { state.pointsNeedsRepopulating = true }},
pointHeight: { default: 0.1, onChange(_, state) { state.pointsNeedsRepopulating = true }}, // in units of globe radius
pointAltitude: { default: 0.1, onChange(_, state) { state.pointsNeedsRepopulating = true }}, // in units of globe radius
pointRadius: { default: 0.25, onChange(_, state) { state.pointsNeedsRepopulating = true }}, // in deg
pointResolution: { default: 12, onChange(_, state) { state.pointsNeedsRepopulating = true }}, // how many slice segments in the cylinder's circumference
pointsMerge: { default: false, onChange(_, state) { state.pointsNeedsRepopulating = true }}, // boolean. Whether to merge all points into a single mesh for rendering performance
linksData: { default: [], onChange(_, state) { state.linksNeedsRepopulating = true }},
linkStartLat: { default: 'startLat', onChange(_, state) { state.linksNeedsRepopulating = true }},
linkStartLng: { default: 'endLng', onChange(_, state) { state.linksNeedsRepopulating = true }},
linkEndLat: { default: 'endLat', onChange(_, state) { state.linksNeedsRepopulating = true }},
linkEndLng: { default: 'endLng', onChange(_, state) { state.linksNeedsRepopulating = true }},
linkColor: { default: () => '#ffffaa', onChange(_, state) { state.linksNeedsRepopulating = true }},
linkHeight: { default: 0.4, onChange(_, state) { state.linksNeedsRepopulating = true }}, // in units of globe radius
linkDiameter: { default: 0.2, onChange(_, state) { state.linksNeedsRepopulating = true }}, // in deg
linkCurveResolution: { default: 64, onChange(_, state) { state.linksNeedsRepopulating = true }}, // how many slice segments in the tube's circumference
linkCircularResolution: { default: 6, onChange(_, state) { state.linksNeedsRepopulating = true }}, // how many slice segments in the tube's circumference
linksMerge: { default: false, onChange(_, state) { state.linksNeedsRepopulating = true }}, // boolean. Whether to merge all links into a single mesh for rendering performance
arcsData: { default: [], onChange(_, state) { state.arcsNeedsRepopulating = true }},
arcStartLat: { default: 'startLat', onChange(_, state) { state.arcsNeedsRepopulating = true }},
arcStartLng: { default: 'startLng', onChange(_, state) { state.arcsNeedsRepopulating = true }},
arcEndLat: { default: 'endLat', onChange(_, state) { state.arcsNeedsRepopulating = true }},
arcEndLng: { default: 'endLng', onChange(_, state) { state.arcsNeedsRepopulating = true }},
arcColor: { default: () => '#ffffaa', onChange(_, state) { state.arcsNeedsRepopulating = true }},
arcAltitude: { onChange(_, state) { state.arcsNeedsRepopulating = true }}, // in units of globe radius
arcAltitudeAutoScale: { default: 0.5, onChange(_, state) { state.arcsNeedsRepopulating = true }}, // scale altitude proportional to great-arc distance between the two points
arcStroke: { onChange(_, state) { state.arcsNeedsRepopulating = true }}, // in deg
arcCurveResolution: { default: 64, onChange(_, state) { state.arcsNeedsRepopulating = true }}, // how many slice segments in the tube's circumference
arcCircularResolution: { default: 6, onChange(_, state) { state.arcsNeedsRepopulating = true }}, // how many slice segments in the tube's circumference
arcsMerge: { default: false, onChange(_, state) { state.arcsNeedsRepopulating = true }}, // boolean. Whether to merge all arcs into a single mesh for rendering performance
customLayerData: { default: [], onChange(_, state) { state.customLayerNeedsRepopulating = true }},

@@ -165,16 +171,2 @@ customThreeObject: { onChange(_, state) { state.customLayerNeedsRepopulating = true }}

};
},
_loadGlobeImage: function(state, imageUrl) {
if (state.globeObj && imageUrl) {
const shader = Shaders.earth;
const uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms.texture.value = new THREE.TextureLoader().load(imageUrl);
state.globeObj.material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
}
return this;
}

@@ -184,4 +176,5 @@ },

stateInit: () => ({
globeNeedsUpdate: true,
pointsNeedsRepopulating: true,
linksNeedsRepopulating: true,
arcsNeedsRepopulating: true,
customLayerNeedsRepopulating: true

@@ -203,3 +196,2 @@ }),

state.scene.add(globeObj);
state.globeImageUrl && this._loadGlobeImage(state.globeImageUrl);

@@ -228,4 +220,4 @@ // add atmosphere

// add links group
state.scene.add(state.linksG = new THREE.Group());
// add arcs group
state.scene.add(state.arcsG = new THREE.Group());

@@ -239,4 +231,23 @@ // add custom layer group

if (state.globeNeedsUpdate) {
state.globeNeedsUpdate = false;
if (!state.globeImageUrl) {
// Black globe
state.globeObj.material = new THREE.MeshBasicMaterial({ color: 0x000000 });
} else {
const shader = Shaders.earth;
const uniforms = THREE.UniformsUtils.clone(shader.uniforms);
uniforms.texture.value = new THREE.TextureLoader().load(state.globeImageUrl);
state.globeObj.material = new THREE.ShaderMaterial({
uniforms: uniforms,
vertexShader: shader.vertexShader,
fragmentShader: shader.fragmentShader
});
}
}
if (state.pointsNeedsRepopulating) {
state.pointsNeedRepopulating = false;
state.pointsNeedsRepopulating = false;

@@ -249,3 +260,3 @@ // Clear the existing points

const lngAccessor = accessorFn(state.pointLng);
const heightAccessor = accessorFn(state.pointHeight);
const altitudeAccessor = accessorFn(state.pointAltitude);
const radiusAccessor = accessorFn(state.pointRadius);

@@ -272,3 +283,3 @@ const colorAccessor = accessorFn(state.pointColor);

obj.scale.x = obj.scale.y = Math.min(30, radiusAccessor(pnt)) * pxPerDeg;
obj.scale.z = Math.max(heightAccessor(pnt) * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix
obj.scale.z = Math.max(altitudeAccessor(pnt) * GLOBE_RADIUS, 0.1); // avoid non-invertible matrix

@@ -329,50 +340,68 @@ obj.__globeObjType = 'point'; // Add object type

if (state.linksNeedsRepopulating) {
state.linksNeedsRepopulating = false;
if (state.arcsNeedsRepopulating) {
state.arcsNeedsRepopulating = false;
// Clear the existing links
emptyObject(state.linksG);
// Clear the existing arcs
emptyObject(state.arcsG);
// Data accessors
const startLatAccessor = accessorFn(state.linkStartLat);
const startLngAccessor = accessorFn(state.linkStartLng);
const endLatAccessor = accessorFn(state.linkEndLat);
const endLngAccessor = accessorFn(state.linkEndLng);
const heightAccessor = accessorFn(state.linkHeight);
const diameterAccessor = accessorFn(state.linkDiameter);
const colorAccessor = accessorFn(state.linkColor);
const startLatAccessor = accessorFn(state.arcStartLat);
const startLngAccessor = accessorFn(state.arcStartLng);
const endLatAccessor = accessorFn(state.arcEndLat);
const endLngAccessor = accessorFn(state.arcEndLng);
const altitudeAccessor = accessorFn(state.arcAltitude);
const altitudeAutoScaleAccessor = accessorFn(state.arcAltitudeAutoScale);
const strokeAccessor = accessorFn(state.arcStroke);
const colorAccessor = accessorFn(state.arcColor);
const linkObjs = [];
const arcObjs = [];
state.linksData.forEach(link => {
const startPnt = [...[startLatAccessor, startLngAccessor].map(fn => fn(link)), 0];
const endPnt = [...[endLatAccessor, endLngAccessor].map(fn => fn(link)), 0];
state.arcsData.forEach(arc => {
let curve;
{
const getVec = ([lng, lat, alt]) => {
const { x, y, z } = this.getCoords(lat, lng, alt);
return new THREE.Vector3(x, y, z);
};
const getMiddle = (a, b) => a + (b-a) / 2;
const middlePoint = [getMiddle(startPnt[0], endPnt[0]), getMiddle(startPnt[1], endPnt[1]), heightAccessor(link) * 2];
//calculate curve
const startPnt = [startLngAccessor, startLatAccessor].map(fn => fn(arc));
const endPnt = [endLngAccessor, endLatAccessor].map(fn => fn(arc));
const curveVecs = [startPnt, middlePoint, endPnt].map(([lat, lng, alt]) => {
const coords = this.getCoords(lat, lng, alt);
return new THREE.Vector3(coords.x, coords.y, coords.z);
});
let altitude = altitudeAccessor(arc);
(altitude === null || altitude === undefined) &&
// by default set altitude proportional to the great-arc distance
(altitude = geoDistance(startPnt, endPnt) / 2 * altitudeAutoScaleAccessor(arc));
const path = new THREE.QuadraticBezierCurve3(...curveVecs);
const interpolate = geoInterpolate(startPnt, endPnt);
const [m1Pnt, m2Pnt] = [0.25, 0.75].map(t => [...interpolate(t), altitude * 1.5]);
curve = new THREE.CubicBezierCurve3(...[startPnt, m1Pnt, m2Pnt, endPnt].map(getVec));
const linkGeometry = new THREE.TubeGeometry(path, state.linkCurveResolution, diameterAccessor(link) / 2, state.linkCircularResolution);
//const mPnt = [...interpolate(0.5), altitude * 2];
//curve = new THREE.QuadraticBezierCurve3(...[startPnt, mPnt, endPnt].map(getVec));
}
const obj = new THREE.Mesh(linkGeometry);
const stroke = strokeAccessor(arc);
obj.__globeObjType = 'link'; // Add object type
obj.__data = link; // Attach point data
const obj = (stroke === null || stroke === undefined)
? new THREE.Line(
new THREE.BufferGeometry().setFromPoints(curve.getPoints(state.arcCurveResolution))
)
: new THREE.Mesh(
new THREE.TubeGeometry(curve, state.arcCurveResolution, stroke / 2, state.arcCircularResolution)
);
linkObjs.push(obj);
obj.__globeObjType = 'arc'; // Add object type
obj.__data = arc; // Attach point data
arcObjs.push(obj);
});
if (state.linksMerge) { // merge links into a single mesh
const linksGeometry = new THREE.Geometry();
if (state.arcsMerge) { // merge arcs into a single mesh
const arcsGeometry = new THREE.Geometry();
linkObjs.forEach(obj => {
const link = obj.__data;
arcObjs.forEach(obj => {
const arc = obj.__data;
const color = new THREE.Color(colorAccessor(link));
const color = new THREE.Color(colorAccessor(arc));
obj.geometry.faces.forEach(face => face.color = color);

@@ -382,6 +411,6 @@

linksGeometry.merge(obj.geometry, obj.matrix);
arcsGeometry.merge(obj.geometry, obj.matrix);
});
const links = new THREE.Mesh(linksGeometry, new THREE.MeshBasicMaterial({
const arcs = new THREE.Mesh(arcsGeometry, new THREE.MeshBasicMaterial({
color: 0xffffff,

@@ -392,17 +421,17 @@ vertexColors: THREE.FaceColors,

links.__globeObjType = 'links'; // Add object type
links.__data = state.linksData; // Attach obj data
arcs.__globeObjType = 'arcs'; // Add object type
arcs.__data = state.arcsData; // Attach obj data
state.linksG.add(links);
state.arcsG.add(arcs);
} else { // Add individual meshes per link
} else { // Add individual meshes per arc
const linkMaterials = {}; // indexed by color
const arcMaterials = {}; // indexed by color
linkObjs.forEach(obj => {
const link = obj.__data;
const color = colorAccessor(link);
arcObjs.forEach(obj => {
const arc = obj.__data;
const color = colorAccessor(arc);
const opacity = colorAlpha(color);
if (!linkMaterials.hasOwnProperty(color)) {
linkMaterials[color] = new THREE.MeshLambertMaterial({
if (!arcMaterials.hasOwnProperty(color)) {
arcMaterials[color] = new THREE.MeshLambertMaterial({
color: colorStr2Hex(color),

@@ -414,5 +443,5 @@ transparent: opacity < 1,

obj.material = linkMaterials[color];
obj.material = arcMaterials[color];
state.linksG.add(link.__threeObj = obj);
state.arcsG.add(arc.__threeObj = obj);
});

@@ -419,0 +448,0 @@ }

Sorry, the diff of this file is too big to display

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

Sorry, the diff of this file is not supported yet

SocketSocket SOC 2 Logo

Product

  • Package Alerts
  • Integrations
  • Docs
  • Pricing
  • FAQ
  • Roadmap
  • Changelog

Packages

npm

Stay in touch

Get open source security insights delivered straight into your inbox.


  • Terms
  • Privacy
  • Security

Made with ⚡️ by Socket Inc