diff --git a/demos/epidemic/epidemic.html b/demos/epidemic/epidemic.html index 1a5f9ee..3f9e321 100644 --- a/demos/epidemic/epidemic.html +++ b/demos/epidemic/epidemic.html @@ -36,7 +36,8 @@ - + + diff --git a/devdocs/Agentmap.html b/devdocs/Agentmap.html index 71cca0c..d3659c2 100644 --- a/devdocs/Agentmap.html +++ b/devdocs/Agentmap.html @@ -927,7 +927,7 @@ -

buildingify(bounding_box, streets_data, street_optionsopt, unit_optionsopt, units_dataopt)

+

buildingify(bounding_box, OSM_data, street_optionsopt, unit_optionsopt, unit_layersopt, street_layersopt)

@@ -1004,7 +1004,7 @@ - streets_data + OSM_data @@ -1287,7 +1287,7 @@ - units_data + unit_layers @@ -1313,7 +1313,40 @@ - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + + + + + + + street_layers + + + + + +object + + + + + + + + + <optional>
+ + + + + + + + + + + If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. @@ -1354,7 +1387,7 @@
Source:
@@ -3063,13 +3096,13 @@
diff --git a/devdocs/DEVDOCS.md b/devdocs/DEVDOCS.md index 0c25373..dd79f81 100644 --- a/devdocs/DEVDOCS.md +++ b/devdocs/DEVDOCS.md @@ -89,10 +89,18 @@ agentmap.buildingify(my_data, [[43.3071, -88.0158], [43.2884, -87.9759]]); `Agentmap.buildingify` accepts more arguments specifying the dimension and appearance of the units and streets it will build. For more on that, see the section on [Feature Styling](#feature-styling). `Agentmap.buildingify` does a lot of work checking for and removing overlapping units, and so the bigger your neighborhood, the noticeably longer it will take. -To compensate for this and help make your simulation more responsive, `Agentmap.buildingify`'s last parameter, after the styling options, accepts a `units_data` object: a GeoJSON FeatureGroup of units. -If one is passed as an argument, instead of generating the units from scratch, `Agentmap.buildingify` will more quickly just use the blueprints in `units_data`. +To compensate for this and help make your simulation more responsive, `Agentmap.buildingify`'s last two parameters, after the styling options, accept a `unit_layers` object and `street_layers` object respectively: a GeoJSON FeatureGroup of units or streets exported from a previous AgentMaps simulation. +If either of these is passed as an argument, instead of generating the unit or street layers from scratch, `Agentmap.buildingify` will more quickly just use the blueprints in `unit_layers` and `street_layers`. -How do you get a `units_data` object? Agentmaps have an [Agentmap.downloadUnits](./Agentmap.html#downloadUnits) method which, when called, will generate a *js* file containing a single variable named `units_data` defined as the vale of `Agentmap.units.toGeoJSON()`. +How do you get a `unit_layers` or `street_layers` object? Agentmaps have an +[Agentmap.downloadUnits](./Agentmap.html#downloadUnits) method and a [Agentmap.downloadStreets](./Agentmap.html#downloadStreets) +method which, when called, will generate a *js* file containing a single variable named `unit_data` or `street_data` defined as the vale of `Agentmap.units.toGeoJSON(20)` or `Agentmap.streets.toGeoJSON(20)` respectively. + +What if your OSM street data is too big for a browser to feasibly generate all the appropriate building layers? +The npm package comes with a command line tool named "featuretool" which, given the bounding coordinates and path to a file containing OSM-style GeoJSON, generates all the appropriate layers and exports them to files similar to those that `Agentmap.downloadUnits` and `Agentmap.downloadStreets` generate. +To use it, you need to have installed AgentMaps globally with `npm install -g AgentMaps`. + +To use featuretool, you'd do something like this: `featuretool --bbox [[39.9058,-86.0910],[39.8992,-86.1017]] --streets data/townmap.js`. ## Navigating Streets diff --git a/devdocs/agentmap.js.html b/devdocs/agentmap.js.html index 05a6809..3b718da 100644 --- a/devdocs/agentmap.js.html +++ b/devdocs/agentmap.js.html @@ -337,13 +337,13 @@ exports.agentmap = agentmapFactory;
diff --git a/devdocs/agents.js.html b/devdocs/agents.js.html index 03b559e..d2d4317 100644 --- a/devdocs/agents.js.html +++ b/devdocs/agents.js.html @@ -816,13 +816,13 @@ exports.agent = agent;
diff --git a/devdocs/buildings.js.html b/devdocs/buildings.js.html index 963c93d..fa600e3 100644 --- a/devdocs/buildings.js.html +++ b/devdocs/buildings.js.html @@ -43,30 +43,30 @@ getPathFinder = require('./routing').getPathFinder; * @instance * * @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates. - * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} [street_options] - An object containing the Leaflet styling options for streets. See available options here: {@link https://leafletjs.com/reference-1.3.2.html#polyline-l-polyline}. * @param {object} [unit_options] - An object containing the Leaflet & AgentMaps styling options for units.<br/>See available Leaflet options here: {@link https://leafletjs.com/reference-1.3.2.html#polygon-l-polygon}<br/>Additional AgentMaps-specific options are described below. * @param {number} [unit_options.front_buffer = 6] - The number of meters beetween the front of unit and its street. * @param {number} [unit_options.side_buffer = 3] - The number of meters between two units on the same street. * @param {number} [unit_options.length = 14] - The length of the unit in meters along the street. * @param {number} [unit_options.depth = 18] - The depth of the unit in meters out from its front. - * @param {object} [units_data]- If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + * @param {object} [unit_layers]- If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + * @param {object} [street_layers]- If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. */ -function buildingify(bounding_box, streets_data, street_options, unit_options, units_data) { - setupStreetFeatures.call(this, streets_data, street_options); - setupUnitFeatures.call(this, bounding_box, streets_data, unit_options, units_data); +function buildingify(bounding_box, OSM_data, street_options, unit_options, unit_layers, street_layers) { + setupStreetFeatures.call(this, OSM_data, street_options); + setupUnitFeatures.call(this, bounding_box, OSM_data, unit_options, unit_layers); } /** * Generate and setup streets based on the provided GeoJSON data. * - * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} street_options - An object containing the Leaflet styling options for streets. + * @param {object} [street_layers] - If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. */ -function setupStreetFeatures(streets_data, street_options) { - let street_features = getStreetFeatures(streets_data); - - default_options = { +function setupStreetFeatures(OSM_data, street_options, street_layers) { + let default_options = { "color": "yellow", "weight": 4, "opacity": .5 @@ -74,10 +74,19 @@ function setupStreetFeatures(streets_data, street_options) { street_options = Object.assign(default_options, street_options); - let street_feature_collection = { - type: "FeatureCollection", - features: street_features - }; + let street_feature_collection; + + if (typeof(street_layers) === "undefined") { + let street_features = getStreetFeatures(OSM_data); + + street_feature_collection = { + type: "FeatureCollection", + features: street_features + }; + } + else { + street_feature_collection = street_layers; + } this.streets = L.geoJSON( street_feature_collection, @@ -86,18 +95,18 @@ function setupStreetFeatures(streets_data, street_options) { //Map streets' OSM IDs to their Leaflet IDs. this.streets.id_map = {}; - + //Having added the streets as layers to the map, do any processing that requires access to those layers. this.streets.eachLayer(function(street) { this.streets.id_map[street.feature.id] = street._leaflet_id; - + addStreetLayerIntersections.call(this, street); }, this); //Add general graph-making and path-finder-making methods to Agentmap, in case streets are added, removed, or modified mid-simulation. this.streetsToGraph = streetsToGraph, - this.getPathFinder = getPathFinder; - + this.getPathFinder = getPathFinder; + this.streets.graph = streetsToGraph(this.streets), this.pathfinder = getPathFinder(this.streets.graph); } @@ -106,15 +115,15 @@ function setupStreetFeatures(streets_data, street_options) { * Get all streets from the GeoJSON data. * @private * - * @param {Object} streets_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box. + * @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box. * @returns {Array<Feature>} - array of street features. */ -function getStreetFeatures(streets_data) { +function getStreetFeatures(OSM_data) { let street_features = []; - for (let i = 0; i < streets_data.features.length; ++i) { - let feature = streets_data.features[i]; - + for (let i = 0; i < OSM_data.features.length; ++i) { + let feature = OSM_data.features[i]; + if (feature.geometry.type === "LineString" && feature.properties.highway) { let street_feature = feature; @@ -161,11 +170,11 @@ function addStreetLayerIntersections(street) { * Generate and setup building units based on the provided GeoJSON data. * * @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates. - * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} unit_options - An object containing the Leaflet & AgentMaps styling options for units. - * @param {object} [units_data] - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + * @param {object} [unit_layers] - If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. */ -function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_data) { +function setupUnitFeatures(bounding_box, OSM_data, unit_options = {}, unit_layers) { let default_options = { "color": "green", "weight": 1, @@ -180,10 +189,10 @@ function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_ let unit_feature_collection; - //If no units_data is supplied, generate the units from scratch. - if (typeof(units_data) === "undefined") { + //If no unit_layers is supplied, generate the units from scratch. + if (typeof(unit_layers) === "undefined") { //Bind getUnitFeatures to "this" so it can access the agentmap as "this.agentmap". - let unit_features = getUnitFeatures.bind(this)(bounding_box, streets_data, unit_options); + let unit_features = getUnitFeatures.bind(this)(bounding_box, OSM_data, unit_options); unit_feature_collection = { type: "FeatureCollection", @@ -191,7 +200,7 @@ function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_ }; } else { - unit_feature_collection = units_data; + unit_feature_collection = unit_layers; } this.units = L.geoJSON( @@ -201,7 +210,7 @@ function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_ //Having added the units as layers to the map, do any processing that requires access to those layers. this.units.eachLayer(function(unit) { - if (typeof(units_data) === "undefined") { + if (typeof(unit_layers) === "undefined") { unit.street_id = unit.feature.properties.street_id; } else { @@ -248,11 +257,11 @@ function getUnitNeighborLayerIDs(neighbors) { * @private * * @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates. - * @param {Object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} unit_options - An object containing the AgentMaps styling options for units. - * @returns {Array<Feature>} - array of features representing real estate units. + * @returns {Array<Feature>} - Array of features representing real estate units. */ -function getUnitFeatures(bounding_box, streets_data, unit_options) { +function getUnitFeatures(bounding_box, OSM_data, unit_options) { let proposed_unit_features = []; this.streets.eachLayer(function(layer) { @@ -438,7 +447,6 @@ function unitsOutOfStreets(unit_features, street_layers) { * @returns {boolean} - Whether the polygon_feature overlaps with any one in the array. */ function noOverlaps(reference_polygon_feature, polygon_feature_array) { - //return true; for (feature_array_element of polygon_feature_array) { let overlap_exists = intersect(reference_polygon_feature, feature_array_element); if (overlap_exists) { @@ -450,6 +458,7 @@ function noOverlaps(reference_polygon_feature, polygon_feature_array) { } Agentmap.prototype.buildingify = buildingify; +exports.buildingify = buildingify; @@ -460,13 +469,13 @@ Agentmap.prototype.buildingify = buildingify;
diff --git a/devdocs/global.html b/devdocs/global.html index c0bf04a..ecca53e 100644 --- a/devdocs/global.html +++ b/devdocs/global.html @@ -271,7 +271,7 @@
Source:
@@ -1286,7 +1286,7 @@
Source:
@@ -1702,7 +1702,7 @@ -

(private) getStreetFeatures(streets_data) → {Array.<Feature>}

+

(private) getStreetFeatures(OSM_data) → {Array.<Feature>}

@@ -1746,7 +1746,7 @@ - streets_data + OSM_data @@ -1803,7 +1803,7 @@
Source:
@@ -1983,7 +1983,7 @@
Source:
@@ -2039,7 +2039,7 @@ -

(private) getUnitFeatures(bounding_box, streets_data, unit_options) → {Array.<Feature>}

+

(private) getUnitFeatures(bounding_box, OSM_data, unit_options) → {Array.<Feature>}

@@ -2106,7 +2106,7 @@ - streets_data + OSM_data @@ -2186,7 +2186,7 @@
Source:
@@ -2213,7 +2213,7 @@
- - array of features representing real estate units. + - Array of features representing real estate units.
@@ -2343,7 +2343,7 @@
Source:
@@ -2680,7 +2680,7 @@
Source:
@@ -3056,7 +3056,7 @@ -

setupStreetFeatures(streets_data, street_options)

+

setupStreetFeatures(OSM_data, street_options, street_layersopt)

@@ -3088,6 +3088,8 @@ Type + Attributes + @@ -3100,7 +3102,7 @@ - streets_data + OSM_data @@ -3113,6 +3115,14 @@ + + + + + + + + @@ -3136,6 +3146,14 @@ + + + + + + + + @@ -3143,6 +3161,39 @@ + + + + street_layers + + + + + +object + + + + + + + + + <optional>
+ + + + + + + + + + + If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. + + + @@ -3180,7 +3231,7 @@
Source:
@@ -3214,7 +3265,7 @@ -

setupUnitFeatures(bounding_box, streets_data, unit_options, units_dataopt)

+

setupUnitFeatures(bounding_box, OSM_data, unit_options, unit_layersopt)

@@ -3291,7 +3342,7 @@ - streets_data + OSM_data @@ -3353,7 +3404,7 @@ - units_data + unit_layers @@ -3379,7 +3430,7 @@ - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. @@ -3420,7 +3471,7 @@
Source:
@@ -3893,7 +3944,7 @@
Source:
@@ -4836,13 +4887,13 @@
diff --git a/devdocs/index.html b/devdocs/index.html index 2cdc04d..8657835 100644 --- a/devdocs/index.html +++ b/devdocs/index.html @@ -96,9 +96,15 @@ These FeatureGroups can be looped through like any other Leaflet FeatureGroup (u stored in a variable my_data and the coordinates of the top left and bottom right corners of the bounding rectangle are [43.3071, -88.0158] and [43.2884, -87.9759] respectively, the corresponding call to Agentmap.buildingify would look something like:

agentmap.buildingify(my_data, [[43.3071, -88.0158], [43.2884, -87.9759]]);

Agentmap.buildingify accepts more arguments specifying the dimension and appearance of the units and streets it will build. For more on that, see the section on Feature Styling.

Agentmap.buildingify does a lot of work checking for and removing overlapping units, and so the bigger your neighborhood, the noticeably longer it will take. -To compensate for this and help make your simulation more responsive, Agentmap.buildingify's last parameter, after the styling options, accepts a units_data object: a GeoJSON FeatureGroup of units. -If one is passed as an argument, instead of generating the units from scratch, Agentmap.buildingify will more quickly just use the blueprints in units_data.

-

How do you get a units_data object? Agentmaps have an Agentmap.downloadUnits method which, when called, will generate a js file containing a single variable named units_data defined as the vale of Agentmap.units.toGeoJSON().

+To compensate for this and help make your simulation more responsive, Agentmap.buildingify's last two parameters, after the styling options, accept a unit_layers object and street_layers object respectively: a GeoJSON FeatureGroup of units or streets exported from a previous AgentMaps simulation. +If either of these is passed as an argument, instead of generating the unit or street layers from scratch, Agentmap.buildingify will more quickly just use the blueprints in unit_layers and street_layers.

+

How do you get a unit_layers or street_layers object? Agentmaps have an +Agentmap.downloadUnits method and a Agentmap.downloadStreets +method which, when called, will generate a js file containing a single variable named unit_data or street_data defined as the vale of Agentmap.units.toGeoJSON(20) or Agentmap.streets.toGeoJSON(20) respectively.

+

What if your OSM street data is too big for a browser to feasibly generate all the appropriate building layers? +The npm package comes with a command line tool named "featuretool" which, given the bounding coordinates and path to a file containing OSM-style GeoJSON, generates all the appropriate layers and exports them to files similar to those that Agentmap.downloadUnits and Agentmap.downloadStreets generate. +To use it, you need to have installed AgentMaps globally with npm install -g AgentMaps.

+

To use featuretool, you'd do something like this: featuretool --bbox [[39.9058,-86.0910],[39.8992,-86.1017]] --streets data/townmap.js.

Navigating Streets

Given a neighborhood's streets in GeoJSON, AgentMaps extracts a street network and converts it to a graph with the help of the ngraph.graph library. Then, it uses ngraph.path to find an (approximately) shortest path. The graph itself is made out of the start point, end point, and intersections of each street.

The graph is stored in the Agentmap.streets.graph property. It is a symmetric graph; for each edge between two points, an inversely directed edge between them also exists. That is, by default, there are no one-way streets. However, if you'd like to remove some of the directed edges of certain streets from the graph (i.e. for making one-way streets), a very accessible guide to manipulating the graphs is available in the ngraph.graph README.

Navigating Within Units

Every Agentmap has an Agentmap.getUnitPoint method which makes it easy to specify a position inside of a unit, relative to one of its corners, and get back the global coordinates of that spot.

@@ -235,13 +241,13 @@ and a new animation frame will be requested to do the same thing over again.


diff --git a/devdocs/jsdocs.js.html b/devdocs/jsdocs.js.html index dc72c3c..74e3f8d 100644 --- a/devdocs/jsdocs.js.html +++ b/devdocs/jsdocs.js.html @@ -74,13 +74,13 @@
diff --git a/devdocs/routing.js.html b/devdocs/routing.js.html index c9e6e99..29f05fb 100644 --- a/devdocs/routing.js.html +++ b/devdocs/routing.js.html @@ -314,13 +314,13 @@ exports.encodeLatLng = encodeLatLng;
diff --git a/devdocs/tutorial-extra.html b/devdocs/tutorial-extra.html index 8f24e15..b64c9d2 100644 --- a/devdocs/tutorial-extra.html +++ b/devdocs/tutorial-extra.html @@ -48,7 +48,7 @@
diff --git a/devdocs/tutorial-quickstart.html b/devdocs/tutorial-quickstart.html index e712970..5650cd9 100644 --- a/devdocs/tutorial-quickstart.html +++ b/devdocs/tutorial-quickstart.html @@ -123,13 +123,13 @@ controller function, outside of the 300 tick condition:


diff --git a/devdocs/utils.js.html b/devdocs/utils.js.html index 345bc86..1ca08e4 100644 --- a/devdocs/utils.js.html +++ b/devdocs/utils.js.html @@ -158,13 +158,13 @@ exports.pointToCoordinateArray = pointToCoordinateArray;
diff --git a/dist/agentmaps.js b/dist/agentmaps.js index 3334349..115be19 100644 --- a/dist/agentmaps.js +++ b/dist/agentmaps.js @@ -1 +1 @@ -!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return 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,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=18)}([function(module,__webpack_exports__,__webpack_require__){"use strict";eval("\n// CONCATENATED MODULE: ./node_modules/@turf/meta/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar factors = {\n meters: earthRadius,\n metres: earthRadius,\n millimeters: earthRadius * 1000,\n millimetres: earthRadius * 1000,\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n kilometers: earthRadius / 1000,\n kilometres: earthRadius / 1000,\n miles: earthRadius / 1609.344,\n nauticalmiles: earthRadius / 1852,\n inches: earthRadius * 39.370,\n yards: earthRadius / 1.0936,\n feet: earthRadius * 3.28084,\n radians: 1,\n degrees: earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = point(coordinates).geometry; break;\n case 'LineString': geom = lineString(coordinates).geometry; break;\n case 'Polygon': geom = polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/meta/main.es.js\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return coordEach; });\n/* unused harmony export coordReduce */\n/* unused harmony export propEach */\n/* unused harmony export propReduce */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return featureEach; });\n/* unused harmony export featureReduce */\n/* unused harmony export coordAll */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return geomEach; });\n/* unused harmony export geomReduce */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return flattenEach; });\n/* unused harmony export flattenReduce */\n/* unused harmony export segmentEach */\n/* unused harmony export segmentReduce */\n/* unused harmony export lineEach */\n/* unused harmony export lineReduce */\n/* unused harmony export findSegment */\n/* unused harmony export findPoint */\n\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n if (geomType === 'MultiPolygon') geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature$$1, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature$$1.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature$$1.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n if (coordEach(feature$$1, function (currentCoord, coordIndex, featureIndexCoord, mutliPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined) {\n previousCoords = currentCoord;\n return;\n }\n var currentSegment = lineString([previousCoords, currentCoord], feature$$1.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature$$1, featureIndex, multiFeatureIndex) {\n if (feature$$1.geometry === null) return;\n var type = feature$$1.geometry.type;\n var coords = feature$$1.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature$$1, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(lineString(coords[geometryIndex], feature$$1.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n\n\n\n//# sourceURL=webpack:///./node_modules/@turf/meta/main.es.js_+_1_modules?")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\n/**\n * @module helpers\n */\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n *\n * @memberof helpers\n * @type {number}\n */\nexports.earthRadius = 6371008.8;\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n *\n * @memberof helpers\n * @type {Object}\n */\nexports.factors = {\n centimeters: exports.earthRadius * 100,\n centimetres: exports.earthRadius * 100,\n degrees: exports.earthRadius / 111325,\n feet: exports.earthRadius * 3.28084,\n inches: exports.earthRadius * 39.370,\n kilometers: exports.earthRadius / 1000,\n kilometres: exports.earthRadius / 1000,\n meters: exports.earthRadius,\n metres: exports.earthRadius,\n miles: exports.earthRadius / 1609.344,\n millimeters: exports.earthRadius * 1000,\n millimetres: exports.earthRadius * 1000,\n nauticalmiles: exports.earthRadius / 1852,\n radians: 1,\n yards: exports.earthRadius / 1.0936,\n};\n/**\n * Units of measurement factors based on 1 meter.\n *\n * @memberof helpers\n * @type {Object}\n */\nexports.unitsFactors = {\n centimeters: 100,\n centimetres: 100,\n degrees: 1 / 111325,\n feet: 3.28084,\n inches: 39.370,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n meters: 1,\n metres: 1,\n miles: 1 / 1609.344,\n millimeters: 1000,\n millimetres: 1000,\n nauticalmiles: 1 / 1852,\n radians: 1 / exports.earthRadius,\n yards: 1 / 1.0936,\n};\n/**\n * Area of measurement factors based on 1 square meter.\n *\n * @memberof helpers\n * @type {Object}\n */\nexports.areaFactors = {\n acres: 0.000247105,\n centimeters: 10000,\n centimetres: 10000,\n feet: 10.763910417,\n inches: 1550.003100006,\n kilometers: 0.000001,\n kilometres: 0.000001,\n meters: 1,\n metres: 1,\n miles: 3.86e-7,\n millimeters: 1000000,\n millimetres: 1000000,\n yards: 1.195990046,\n};\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * "type": "Point",\n * "coordinates": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction feature(geom, properties, options) {\n if (options === void 0) { options = {}; }\n var feat = { type: "Feature" };\n if (options.id === 0 || options.id) {\n feat.id = options.id;\n }\n if (options.bbox) {\n feat.bbox = options.bbox;\n }\n feat.properties = properties || {};\n feat.geometry = geom;\n return feat;\n}\nexports.feature = feature;\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = "Point";\n * var coordinates = [110, 50];\n * var geometry = turf.geometry(type, coordinates);\n * // => geometry\n */\nfunction geometry(type, coordinates, options) {\n if (options === void 0) { options = {}; }\n switch (type) {\n case "Point": return point(coordinates).geometry;\n case "LineString": return lineString(coordinates).geometry;\n case "Polygon": return polygon(coordinates).geometry;\n case "MultiPoint": return multiPoint(coordinates).geometry;\n case "MultiLineString": return multiLineString(coordinates).geometry;\n case "MultiPolygon": return multiPolygon(coordinates).geometry;\n default: throw new Error(type + " is invalid");\n }\n}\nexports.geometry = geometry;\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction point(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "Point",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.point = point;\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north]\n * associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction points(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n return featureCollection(coordinates.map(function (coords) {\n return point(coords, properties);\n }), options);\n}\nexports.points = points;\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: \'poly1\' });\n *\n * //=polygon\n */\nfunction polygon(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) {\n var ring = coordinates_1[_i];\n if (ring.length < 4) {\n throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error("First and last Position are not equivalent.");\n }\n }\n }\n var geom = {\n type: "Polygon",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.polygon = polygon;\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n return featureCollection(coordinates.map(function (coords) {\n return polygon(coords, properties);\n }), options);\n}\nexports.polygons = polygons;\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: \'line 1\'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: \'line 2\'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n if (coordinates.length < 2) {\n throw new Error("coordinates must be an array of two or more positions");\n }\n var geom = {\n type: "LineString",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.lineString = lineString;\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north]\n * associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\nexports.lineStrings = lineStrings;\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: \'Location A\'});\n * var locationB = turf.point([-75.833, 39.284], {name: \'Location B\'});\n * var locationC = turf.point([-75.534, 39.123], {name: \'Location C\'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n if (options === void 0) { options = {}; }\n var fc = { type: "FeatureCollection" };\n if (options.id) {\n fc.id = options.id;\n }\n if (options.bbox) {\n fc.bbox = options.bbox;\n }\n fc.features = features;\n return fc;\n}\nexports.featureCollection = featureCollection;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "MultiLineString",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.multiLineString = multiLineString;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "MultiPoint",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.multiPoint = multiPoint;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "MultiPolygon",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.multiPolygon = multiPolygon;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = turf.geometry("Point", [100, 0]);\n * var line = turf.geometry("LineString", [[101, 0], [102, 1]]);\n * var collection = turf.geometryCollection([pt, line]);\n *\n * // => collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "GeometryCollection",\n geometries: geometries,\n };\n return feature(geom, properties, options);\n}\nexports.geometryCollection = geometryCollection;\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (precision === void 0) { precision = 0; }\n if (precision && !(precision >= 0)) {\n throw new Error("precision must be a positive number");\n }\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\nexports.round = round;\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres,\n * meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (units === void 0) { units = "kilometers"; }\n var factor = exports.factors[units];\n if (!factor) {\n throw new Error(units + " units is invalid");\n }\n return radians * factor;\n}\nexports.radiansToLength = radiansToLength;\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres,\n * meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (units === void 0) { units = "kilometers"; }\n var factor = exports.factors[units];\n if (!factor) {\n throw new Error(units + " units is invalid");\n }\n return distance / factor;\n}\nexports.lengthToRadians = lengthToRadians;\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres,\n * meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\nexports.lengthToDegrees = lengthToDegrees;\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n var angle = bearing % 360;\n if (angle < 0) {\n angle += 360;\n }\n return angle;\n}\nexports.bearingToAzimuth = bearingToAzimuth;\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\nexports.radiansToDegrees = radiansToDegrees;\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\nexports.degreesToRadians = degreesToRadians;\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {Units} [originalUnit="kilometers"] of the length\n * @param {Units} [finalUnit="kilometers"] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (originalUnit === void 0) { originalUnit = "kilometers"; }\n if (finalUnit === void 0) { finalUnit = "kilometers"; }\n if (!(length >= 0)) {\n throw new Error("length must be a positive number");\n }\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);\n}\nexports.convertLength = convertLength;\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {Units} [originalUnit="meters"] of the distance\n * @param {Units} [finalUnit="kilometers"] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (originalUnit === void 0) { originalUnit = "meters"; }\n if (finalUnit === void 0) { finalUnit = "kilometers"; }\n if (!(area >= 0)) {\n throw new Error("area must be a positive number");\n }\n var startFactor = exports.areaFactors[originalUnit];\n if (!startFactor) {\n throw new Error("invalid original units");\n }\n var finalFactor = exports.areaFactors[finalUnit];\n if (!finalFactor) {\n throw new Error("invalid final units");\n }\n return (area / startFactor) * finalFactor;\n}\nexports.convertArea = convertArea;\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber(\'foo\')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num) && !/^\\s*$/.test(num);\n}\nexports.isNumber = isNumber;\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject(\'foo\')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\nexports.isObject = isObject;\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox(\'Foo\')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) {\n throw new Error("bbox is required");\n }\n if (!Array.isArray(bbox)) {\n throw new Error("bbox must be an Array");\n }\n if (bbox.length !== 4 && bbox.length !== 6) {\n throw new Error("bbox must be an Array of 4 or 6 numbers");\n }\n bbox.forEach(function (num) {\n if (!isNumber(num)) {\n throw new Error("bbox must only contain numbers");\n }\n });\n}\nexports.validateBBox = validateBBox;\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId(\'Foo\')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) {\n throw new Error("id is required");\n }\n if (["string", "number"].indexOf(typeof id) === -1) {\n throw new Error("id must be a number or a string");\n }\n}\nexports.validateId = validateId;\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error("method has been renamed to `radiansToDegrees`");\n}\nexports.radians2degrees = radians2degrees;\nfunction degrees2radians() {\n throw new Error("method has been renamed to `degreesToRadians`");\n}\nexports.degrees2radians = degrees2radians;\nfunction distanceToDegrees() {\n throw new Error("method has been renamed to `lengthToDegrees`");\n}\nexports.distanceToDegrees = distanceToDegrees;\nfunction distanceToRadians() {\n throw new Error("method has been renamed to `lengthToRadians`");\n}\nexports.distanceToRadians = distanceToRadians;\nfunction radiansToDistance() {\n throw new Error("method has been renamed to `radiansToLength`");\n}\nexports.radiansToDistance = radiansToDistance;\nfunction bearingToAngle() {\n throw new Error("method has been renamed to `bearingToAzimuth`");\n}\nexports.bearingToAngle = bearingToAngle;\nfunction convertDistance() {\n throw new Error("method has been renamed to `convertLength`");\n}\nexports.convertDistance = convertDistance;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/helpers/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate.\n *\n * @name getCoord\n * @param {Array|Geometry|Feature} coord GeoJSON Point or an Array of numbers\n * @returns {Array} coordinates\n * @example\n * var pt = turf.point([10, 10]);\n *\n * var coord = turf.getCoord(pt);\n * //= [10, 10]\n */\nfunction getCoord(coord) {\n if (!coord) throw new Error('coord is required');\n if (coord.type === 'Feature' && coord.geometry !== null && coord.geometry.type === 'Point') return coord.geometry.coordinates;\n if (coord.type === 'Point') return coord.coordinates;\n if (Array.isArray(coord) && coord.length >= 2 && coord[0].length === undefined && coord[1].length === undefined) return coord;\n\n throw new Error('coord must be GeoJSON Point or an Array of numbers');\n}\n\n/**\n * Unwrap coordinates from a Feature, Geometry Object or an Array\n *\n * @name getCoords\n * @param {Array|Geometry|Feature} coords Feature, Geometry Object or an Array\n * @returns {Array} coordinates\n * @example\n * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]);\n *\n * var coords = turf.getCoords(poly);\n * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]\n */\nfunction getCoords(coords) {\n if (!coords) throw new Error('coords is required');\n\n // Feature\n if (coords.type === 'Feature' && coords.geometry !== null) return coords.geometry.coordinates;\n\n // Geometry\n if (coords.coordinates) return coords.coordinates;\n\n // Array of numbers\n if (Array.isArray(coords)) return coords;\n\n throw new Error('coords must be GeoJSON Feature, Geometry Object or an Array');\n}\n\n/**\n * Checks if coordinates contains a number\n *\n * @name containsNumber\n * @param {Array} coordinates GeoJSON Coordinates\n * @returns {boolean} true if Array contains a number\n */\nfunction containsNumber(coordinates) {\n if (coordinates.length > 1 && helpers.isNumber(coordinates[0]) && helpers.isNumber(coordinates[1])) {\n return true;\n }\n\n if (Array.isArray(coordinates[0]) && coordinates[0].length) {\n return containsNumber(coordinates[0]);\n }\n throw new Error('coordinates must only contain numbers');\n}\n\n/**\n * Enforce expectations about types of GeoJSON objects for Turf.\n *\n * @name geojsonType\n * @param {GeoJSON} value any GeoJSON object\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction geojsonType(value, type, name) {\n if (!type || !name) throw new Error('type and name required');\n\n if (!value || value.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link Feature} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name featureOf\n * @param {Feature} feature a feature with an expected geometry type\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} error if value is not the expected type.\n */\nfunction featureOf(feature, type, name) {\n if (!feature) throw new Error('No feature passed');\n if (!name) throw new Error('.featureOf() requires a name');\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link FeatureCollection} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name collectionOf\n * @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction collectionOf(featureCollection, type, name) {\n if (!featureCollection) throw new Error('No featureCollection passed');\n if (!name) throw new Error('.collectionOf() requires a name');\n if (!featureCollection || featureCollection.type !== 'FeatureCollection') {\n throw new Error('Invalid input to ' + name + ', FeatureCollection required');\n }\n for (var i = 0; i < featureCollection.features.length; i++) {\n var feature = featureCollection.features[i];\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n }\n}\n\n/**\n * Get Geometry from Feature or Geometry Object\n *\n * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object\n * @returns {Geometry|null} GeoJSON Geometry Object\n * @throws {Error} if geojson is not a Feature or Geometry Object\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getGeom(point)\n * //={\"type\": \"Point\", \"coordinates\": [110, 40]}\n */\nfunction getGeom(geojson) {\n if (!geojson) throw new Error('geojson is required');\n if (geojson.geometry !== undefined) return geojson.geometry;\n if (geojson.coordinates || geojson.geometries) return geojson;\n throw new Error('geojson must be a valid Feature or Geometry Object');\n}\n\n/**\n * Get Geometry Type from Feature or Geometry Object\n *\n * @throws {Error} **DEPRECATED** in v5.0.0 in favor of getType\n */\nfunction getGeomType() {\n throw new Error('invariant.getGeomType has been deprecated in v5.0 in favor of invariant.getType');\n}\n\n/**\n * Get GeoJSON object's type, Geometry type is prioritize.\n *\n * @param {GeoJSON} geojson GeoJSON object\n * @param {string} [name=\"geojson\"] name of the variable to display in error message\n * @returns {string} GeoJSON type\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getType(point)\n * //=\"Point\"\n */\nfunction getType(geojson, name) {\n if (!geojson) throw new Error((name || 'geojson') + ' is required');\n // GeoJSON Feature & GeometryCollection\n if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type;\n // GeoJSON Geometry & FeatureCollection\n if (geojson.type) return geojson.type;\n throw new Error((name || 'geojson') + ' is invalid');\n}\n\nexports.getCoord = getCoord;\nexports.getCoords = getCoords;\nexports.containsNumber = containsNumber;\nexports.geojsonType = geojsonType;\nexports.featureOf = featureOf;\nexports.collectionOf = collectionOf;\nexports.getGeom = getGeom;\nexports.getGeomType = getGeomType;\nexports.getType = getType;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/invariant/index.js?")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _turf_meta__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n\n\n/**\n * Takes a set of features, calculates the bbox of all input features, and returns a bounding box.\n *\n * @name bbox\n * @param {GeoJSON} geojson any GeoJSON object\n * @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order\n * @example\n * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]);\n * var bbox = turf.bbox(line);\n * var bboxPolygon = turf.bboxPolygon(bbox);\n *\n * //addToMap\n * var addToMap = [line, bboxPolygon]\n */\nfunction bbox(geojson) {\n var BBox = [Infinity, Infinity, -Infinity, -Infinity];\n Object(_turf_meta__WEBPACK_IMPORTED_MODULE_0__[/* coordEach */ "a"])(geojson, function (coord) {\n if (BBox[0] > coord[0]) BBox[0] = coord[0];\n if (BBox[1] > coord[1]) BBox[1] = coord[1];\n if (BBox[2] < coord[0]) BBox[2] = coord[0];\n if (BBox[3] < coord[1]) BBox[3] = coord[1];\n });\n return BBox;\n}\n\n/* harmony default export */ __webpack_exports__["default"] = (bbox);\n\n\n//# sourceURL=webpack:///./node_modules/@turf/bbox/main.es.js?')},function(module,exports,__webpack_require__){eval('function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n/* The Agentmap class, which turns a Leaflet map into a simulation platform. */\nvar lineSlice = __webpack_require__(14).default,\n length = __webpack_require__(8).default;\n/**\r\n * The main class for building, storing, simulating, and manipulating agent-based models on Leaflet maps.\r\n *\r\n * @class Agentmap\r\n * @param {object} map - A Leaflet Map instance.\r\n * @param {number} [animation_interval=1] - The number of steps agents must move before being redrawn. Given 1, they will be redrawn after every step. Given 0, the animation will not update at all. 1 by default. Must be a nonnegative integer.\r\n * @property {object} map - A Leaflet Map instance.\r\n * @property {FeatureGroup} agents - A featureGroup containing all agents.\r\n * @property {FeatureGroup} units - A featureGroup containing all units.\r\n * @property {FeatureGroup} streets - A featureGroup containing all streets.\r\n * @property {object} state - Properties detailing the state of the simulation process.\r\n * @property {boolean} state.running - Whether the simulation is running or not.\r\n * @property {boolean} state.paused - Whether the simulation is paused.\r\n * @property {?number} state.animation_frame_id - The id of the agentmap\'s update function in the queue of functions to call for the coming animation frame.\r\n * @property {?number} state.ticks - The number of ticks elapsed since the start of the simulation.\r\n * @property {number} animation_interval - The number of steps agents must move before being redrawn. Given 1, they will be redrawn after every step. Given 0, the animation will not update at all. 1 by default. Will be a nonnegative integer.\r\n * @property {?function} controller - User-defined function to be called on each update.\r\n */\n\n\nAgentmap = function (_Agentmap) {\n function Agentmap(_x) {\n return _Agentmap.apply(this, arguments);\n }\n\n Agentmap.toString = function () {\n return _Agentmap.toString();\n };\n\n return Agentmap;\n}(function (map) {\n var animation_interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n Agentmap.checkAnimIntervalOption(animation_interval);\n this.map = map, this.units = null, this.streets = null, this.agents = null, this.pathfinder = null, this.state = {\n running: false,\n paused: false,\n animation_frame_id: null,\n ticks: null\n }, this.controller = function () {}, this.animation_interval = animation_interval;\n});\n/**\r\n * Change the animation interval of the simulation & redraw the agents.\r\n *\r\n * @param {number} animation_interval - The desired animation interval to give the simulation. Must be a nonnegative integer.\r\n */\n\n\nAgentmap.prototype.setAnimationInterval = function (animation_interval) {\n Agentmap.checkAnimIntervalOption(animation_interval);\n this.animation_interval = animation_interval;\n this.agents.eachLayer(function (agent) {\n return agent.setLatLng(agent._latlng);\n });\n};\n/**\r\n * Check whether the animation interval option provided is valid.\r\n * @private\r\n *\r\n * @param {number} animation_interval - An input specifying an animation interval distance.\r\n */\n\n\nAgentmap.checkAnimIntervalOption = function (animation_interval) {\n if (!Number.isInteger(animation_interval) && animation_interval >= 0) {\n throw new Error("The animation_interval must be a non-negative integer!");\n }\n};\n/**\r\n * Get an animation frame, have the agents update & get ready to be drawn, and keep doing that until paused or reset.\r\n */\n\n\nAgentmap.prototype.run = function () {\n if (this.state.running === false) {\n this.state.running = true;\n\n var animation_update = function (rAF_time) {\n if (this.state.paused === true) {\n this.state.paused = false;\n }\n\n this.state.animation_frame_id = L.Util.requestAnimFrame(animation_update);\n this.update();\n }.bind(this);\n\n this.state.animation_frame_id = L.Util.requestAnimFrame(animation_update);\n }\n};\n/**\r\n * Update the simulation at the given time.\r\n * @private\r\n */\n\n\nAgentmap.prototype.update = function () {\n if (this.state.ticks === null) {\n this.state.ticks = 0;\n } //Execute user-provided per-tick instructions for the agentmap.\n\n\n this.controller(); //Execute user-provided per-tick instructions for each agent.\n\n this.agents.eachLayer(function (agent) {\n agent.controller();\n });\n this.state.ticks += 1;\n};\n/**\r\n* Stop the animation, reset the animation state properties, and delete the features.\r\n*/\n\n\nAgentmap.prototype.clear = function () {\n L.Util.cancelAnimFrame(this.state.animation_frame_id);\n this.state.running = false, this.state.paused = false, this.state.animation_frame_id = null, this.state.ticks = null, this.agents.clearLayers();\n this.streets.clearLayers();\n this.units.clearLayers();\n};\n/** \r\n * Stop the animation, stop updating the agents.\r\n */\n\n\nAgentmap.prototype.pause = function () {\n L.Util.cancelAnimFrame(this.state.animation_frame_id);\n this.state.running = false, this.state.paused = true;\n};\n/**\r\n * Get a point through which an agent can exit/enter a unit.\r\n *\r\n * @param {number} unit_id - The unique ID of the unit whose door you want.\r\n * @returns {LatLng} - The coordinates of the center point of the segment of the unit parallel to the street.\r\n */\n\n\nAgentmap.prototype.getUnitDoor = function (unit_id) {\n var unit = this.units.getLayer(unit_id);\n\n if (typeof unit === "undefined") {\n throw new Error("No unit with the specified ID exists.");\n }\n\n var unit_spec = unit.getLatLngs()[0],\n corner_a = unit_spec[0],\n corner_b = unit_spec[1],\n door = L.latLngBounds(corner_a, corner_b).getCenter();\n return door;\n};\n/**\r\n * Get the point on the adjacent street in front of the unit\'s door.\r\n *\r\n * @param {number} unit_id - The unique ID of the unit whose door\'s corresponding point on the street you want.\r\n * @returns {LatLng} - The coordinates point of the adjacent street directly in front of unit\'s door.\r\n */\n\n\nAgentmap.prototype.getStreetNearDoor = function (unit_id) {\n var _L;\n\n var unit = this.units.getLayer(unit_id);\n\n if (typeof unit === "undefined") {\n throw new Error("No unit with the specified ID exists.");\n }\n\n var unit_anchors = L.A.reversedCoordinates(unit.street_anchors),\n street_point = (_L = L).latLngBounds.apply(_L, _toConsumableArray(unit_anchors)).getCenter();\n\n return street_point;\n};\n/**\r\n * Given a unit and a pair of coordinates between 0 and 1, return a corresponding point inside the unit, offset from its first corner along the street.\r\n * \r\n * @param {number} unit_id - The unique ID of the unit whose interior point you want.\r\n * @param {number} x - A point between 0 and 1 representing a position along the width of a unit.\r\n * @param {number} y - A point between 0 and 1 representing a position along the depth of a unit.\r\n * @returns {LatLng} - The global coordinates of the specified position within the unit.\r\n */\n\n\nAgentmap.prototype.getUnitPoint = function (unit_id, x, y) {\n if (x < 0 || x > 1 || y < 0 || y > 1) {\n throw new Error("x and y must both be between 0 and 1!");\n }\n\n var unit = this.units.getLayer(unit_id),\n unit_corners = unit.getLatLngs()[0],\n front_right = unit_corners[0],\n front_left = unit_corners[1],\n back_right = unit_corners[3],\n front_length = front_left.lng - front_right.lng,\n side_length = back_right.lng - front_right.lng,\n front_slope = (front_right.lat - front_left.lat) / (front_right.lng - front_left.lng),\n side_slope = (front_right.lat - back_right.lat) / (front_right.lng - back_right.lng); //Get the coordinate of the position along the front (x) axis.\n\n var lng_along_front = front_right.lng + front_length * x,\n lat_along_front = front_right.lat + front_length * x * front_slope,\n point_along_front = L.latLng(lat_along_front, lng_along_front); //From the position on the front axis, get the coordinate of a position along a line perpendicular to the front and \n //parallel to the side (y) axis.\n\n var lng_along_side = point_along_front.lng + side_length * y,\n lat_along_side = point_along_front.lat + side_length * y * side_slope,\n point_in_depth = L.latLng(lat_along_side, lng_along_side);\n return point_in_depth;\n};\n/**\r\n * Given a point on a street, find the nearest intersection on that street (with any other street).\r\n * \r\n * @param {LatLng} lat_lng - The coordinates of the point on the street to search from.\r\n * @param {Place} place - A place object corresponding to the street.\r\n * @returns {LatLng} - The coordinates of the nearest intersection.\r\n */\n\n\nAgentmap.prototype.getNearestIntersection = function (lat_lng, place) {\n var street_id, street_feature;\n\n if (place.type === "street") {\n street_id = place.id;\n } else {\n throw new Error("place must be a street!");\n }\n\n street_feature = this.streets.getLayer(street_id).toGeoJSON();\n var intersections = this.streets.getLayer(street_id).intersections,\n intersection_points = [],\n intersection_distances = [];\n\n for (var intersection in intersections) {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = intersections[intersection][Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var cross_point = _step.value;\n var intersection_point = cross_point[0],\n distance = lat_lng.distanceTo(intersection_point);\n /* More precise, but slower, distance detection -- not necessary yet. \r\n \tlet start_coords = L.A.pointToCoordinateArray(lat_lng);\r\n \tintersection_coords = L.A.pointToCoordinateArray(intersection_point),\r\n \tsegment = lineSlice(start_coords, intersection_coords, street_feature),\r\n \tdistance = length(segment); \r\n */\n\n intersection_points.push(intersection_point);\n intersection_distances.push(distance);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n }\n\n var smallest_distance = Math.min.apply(Math, intersection_distances),\n smallest_distance_index = intersection_distances.indexOf(smallest_distance),\n closest_intersection_point = L.latLng(intersection_points[smallest_distance_index]);\n return closest_intersection_point;\n};\n/**\r\n * Since units may take a noticeably long time to generate while typically staying the same over simulations,\r\n * downloadUnits makes it easy to get a JS file containing the units object, so it can be included with an\r\n * AgentMaps app and imported into Agentmap.buildingify so they will not need to be regenerated.\r\n */\n\n\nAgentmap.prototype.downloadUnits = function () {\n var file_content = "let units_data = ",\n units_json = this.units.toGeoJSON(20);\n file_content += JSON.stringify(units_json), file = new Blob([file_content]);\n var element = document.createElement("a");\n element.setAttribute("href", URL.createObjectURL(file)), element.setAttribute("download", "units_data.js"), element.style.display = "none";\n document.body.appendChild(element);\n element.click();\n document.body.removeChild(element);\n};\n/**\r\n * Generates an agentmap for the given map.\r\n *\r\n * @name agentmap\r\n * @param {object} map - A Leaflet Map instance.\r\n * @returns {object} - An Agentmap instance.\r\n */\n\n\nfunction agentmapFactory(map) {\n return new Agentmap(map);\n}\n/**\r\n * Returns the number of layers in a Leaflet layer group.\r\n *\r\n * @memberof L.LayerGroup\r\n */\n\n\nfunction layerCount() {\n return this.getLayers().length;\n}\n\nL.LayerGroup.include({\n count: layerCount\n});\nexports.Agentmap = Agentmap, exports.agentmap = agentmapFactory;\n\n//# sourceURL=webpack:///./src/agentmap.js?')},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n// http://en.wikipedia.org/wiki/Haversine_formula\n// http://www.movable-type.co.uk/scripts/latlong.html\n/**\n * Takes two {@link Point|points} and finds the geographic bearing between them,\n * i.e. the angle measured in degrees from the north line (0 degrees)\n *\n * @name bearing\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.final=false] calculates the final bearing if true\n * @returns {number} bearing in decimal degrees, between -180 and 180 degrees (positive clockwise)\n * @example\n * var point1 = turf.point([-75.343, 39.984]);\n * var point2 = turf.point([-75.534, 39.123]);\n *\n * var bearing = turf.bearing(point1, point2);\n *\n * //addToMap\n * var addToMap = [point1, point2]\n * point1.properties['marker-color'] = '#f00'\n * point2.properties['marker-color'] = '#0f0'\n * point1.properties.bearing = bearing\n */\nfunction bearing(start, end, options) {\n if (options === void 0) { options = {}; }\n // Reverse calculation\n if (options.final === true) {\n return calculateFinalBearing(start, end);\n }\n var coordinates1 = invariant_1.getCoord(start);\n var coordinates2 = invariant_1.getCoord(end);\n var lon1 = helpers_1.degreesToRadians(coordinates1[0]);\n var lon2 = helpers_1.degreesToRadians(coordinates2[0]);\n var lat1 = helpers_1.degreesToRadians(coordinates1[1]);\n var lat2 = helpers_1.degreesToRadians(coordinates2[1]);\n var a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n var b = Math.cos(lat1) * Math.sin(lat2) -\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n return helpers_1.radiansToDegrees(Math.atan2(a, b));\n}\n/**\n * Calculates Final Bearing\n *\n * @private\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @returns {number} bearing\n */\nfunction calculateFinalBearing(start, end) {\n // Swap start & end\n var bear = bearing(end, start);\n bear = (bear + 180) % 360;\n return bear;\n}\nexports.default = bearing;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/bearing/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// http://en.wikipedia.org/wiki/Haversine_formula\n// http://www.movable-type.co.uk/scripts/latlong.html\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n/**\n * Takes a {@link Point} and calculates the location of a destination point given a distance in\n * degrees, radians, miles, or kilometers; and bearing in degrees.\n * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature.\n *\n * @name destination\n * @param {Coord} origin starting point\n * @param {number} distance distance from the origin point\n * @param {number} bearing ranging from -180 to 180\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians\n * @param {Object} [options.properties={}] Translate properties to Point\n * @returns {Feature} destination point\n * @example\n * var point = turf.point([-75.343, 39.984]);\n * var distance = 50;\n * var bearing = 90;\n * var options = {units: 'miles'};\n *\n * var destination = turf.destination(point, distance, bearing, options);\n *\n * //addToMap\n * var addToMap = [point, destination]\n * destination.properties['marker-color'] = '#f00';\n * point.properties['marker-color'] = '#0f0';\n */\nfunction destination(origin, distance, bearing, options) {\n if (options === void 0) { options = {}; }\n // Handle input\n var coordinates1 = invariant_1.getCoord(origin);\n var longitude1 = helpers_1.degreesToRadians(coordinates1[0]);\n var latitude1 = helpers_1.degreesToRadians(coordinates1[1]);\n var bearingRad = helpers_1.degreesToRadians(bearing);\n var radians = helpers_1.lengthToRadians(distance, options.units);\n // Main\n var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +\n Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad));\n var longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1), Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));\n var lng = helpers_1.radiansToDegrees(longitude2);\n var lat = helpers_1.radiansToDegrees(latitude2);\n return helpers_1.point([lng, lat], options.properties);\n}\nexports.default = destination;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/destination/index.js?")},function(module,exports,__webpack_require__){eval('!function(t,e){ true?e(exports):undefined}(this,function(t){"use strict";function e(){}function n(t){this.message=t||""}function i(t){this.message=t||""}function r(t){this.message=t||""}function o(){}function s(t){return null===t?Mt:t.color}function a(t){return null===t?null:t.parent}function u(t,e){null!==t&&(t.color=e)}function l(t){return null===t?null:t.left}function c(t){return null===t?null:t.right}function p(){this.root_=null,this.size_=0}function h(){}function f(){this.array_=[],arguments[0]instanceof It&&this.addAll(arguments[0])}function g(){}function d(t){this.message=t||""}function y(){this.array_=[]}"fill"in Array.prototype||Object.defineProperty(Array.prototype,"fill",{configurable:!0,value:function(t){if(void 0===this||null===this)throw new TypeError(this+" is not an object");var e=Object(this),n=Math.max(Math.min(e.length,9007199254740991),0)||0,i=1 in arguments?parseInt(Number(arguments[1]),10)||0:0;i=i<0?Math.max(n+i,0):Math.min(i,n);var r=2 in arguments&&void 0!==arguments[2]?parseInt(Number(arguments[2]),10)||0:n;for(r=r<0?Math.max(n+arguments[2],0):Math.min(r,n);ie.x?1:this.ye.y?1:0},C.prototype.clone=function(){},C.prototype.copy=function(){return new C(this)},C.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},C.prototype.distance3D=function(t){var e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return Math.sqrt(e*e+n*n+i*i)},C.prototype.distance=function(t){var e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)},C.prototype.hashCode=function(){var t=17;return t=37*t+C.hashCode(this.x),t=37*t+C.hashCode(this.y)},C.prototype.setCoordinate=function(t){this.x=t.x,this.y=t.y,this.z=t.z},C.prototype.interfaces_=function(){return[E,x,e]},C.prototype.getClass=function(){return C},C.hashCode=function(){if(1===arguments.length){var t=arguments[0],e=v.doubleToLongBits(t);return Math.trunc((e^e)>>>32)}},S.DimensionalComparator.get=function(){return L},S.serialVersionUID.get=function(){return 0x5cbf2c235c7e5800},S.NULL_ORDINATE.get=function(){return v.NaN},S.X.get=function(){return 0},S.Y.get=function(){return 1},S.Z.get=function(){return 2},Object.defineProperties(C,S);var L=function(t){if(this._dimensionsToTest=2,0===arguments.length);else if(1===arguments.length){var e=arguments[0];if(2!==e&&3!==e)throw new m("only 2 or 3 dimensions may be specified");this._dimensionsToTest=e}};L.prototype.compare=function(t,e){var n=t,i=e,r=L.compare(n.x,i.x);if(0!==r)return r;var o=L.compare(n.y,i.y);if(0!==o)return o;if(this._dimensionsToTest<=2)return 0;return L.compare(n.z,i.z)},L.prototype.interfaces_=function(){return[N]},L.prototype.getClass=function(){return L},L.compare=function(t,e){return te?1:v.isNaN(t)?v.isNaN(e)?0:-1:v.isNaN(e)?1:0};var b=function(){};b.prototype.create=function(){},b.prototype.interfaces_=function(){return[]},b.prototype.getClass=function(){return b};var w=function(){},O={INTERIOR:{configurable:!0},BOUNDARY:{configurable:!0},EXTERIOR:{configurable:!0},NONE:{configurable:!0}};w.prototype.interfaces_=function(){return[]},w.prototype.getClass=function(){return w},w.toLocationSymbol=function(t){switch(t){case w.EXTERIOR:return"e";case w.BOUNDARY:return"b";case w.INTERIOR:return"i";case w.NONE:return"-"}throw new m("Unknown location value: "+t)},O.INTERIOR.get=function(){return 0},O.BOUNDARY.get=function(){return 1},O.EXTERIOR.get=function(){return 2},O.NONE.get=function(){return-1},Object.defineProperties(w,O);var T=function(t,e){return t.interfaces_&&t.interfaces_().indexOf(e)>-1},R=function(){},P={LOG_10:{configurable:!0}};R.prototype.interfaces_=function(){return[]},R.prototype.getClass=function(){return R},R.log10=function(t){var e=Math.log(t);return v.isInfinite(e)?e:v.isNaN(e)?e:e/R.LOG_10},R.min=function(t,e,n,i){var r=t;return en?n:t}if(Number.isInteger(arguments[2])&&Number.isInteger(arguments[0])&&Number.isInteger(arguments[1])){var i=arguments[0],r=arguments[1],o=arguments[2];return io?o:i}},R.wrap=function(t,e){return t<0?e- -t%e:t%e},R.max=function(){if(3===arguments.length){var t=arguments[0],e=arguments[1],n=arguments[2],i=t;return e>i&&(i=e),n>i&&(i=n),i}if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3],u=r;return o>u&&(u=o),s>u&&(u=s),a>u&&(u=a),u}},R.average=function(t,e){return(t+e)/2},P.LOG_10.get=function(){return Math.log(10)},Object.defineProperties(R,P);var D=function(t){this.str=t};D.prototype.append=function(t){this.str+=t},D.prototype.setCharAt=function(t,e){this.str=this.str.substr(0,t)+e+this.str.substr(t+1)},D.prototype.toString=function(t){return this.str};var M=function(t){this.value=t};M.prototype.intValue=function(){return this.value},M.prototype.compareTo=function(t){return this.valuet?1:0},M.isNaN=function(t){return Number.isNaN(t)};var A=function(){};A.isWhitespace=function(t){return t<=32&&t>=0||127===t},A.toUpperCase=function(t){return t.toUpperCase()};var F=function t(){if(this._hi=0,this._lo=0,0===arguments.length)this.init(0);else if(1===arguments.length){if("number"==typeof arguments[0]){var e=arguments[0];this.init(e)}else if(arguments[0]instanceof t){var n=arguments[0];this.init(n)}else if("string"==typeof arguments[0]){var i=arguments[0];t.call(this,t.parse(i))}}else if(2===arguments.length){var r=arguments[0],o=arguments[1];this.init(r,o)}},G={PI:{configurable:!0},TWO_PI:{configurable:!0},PI_2:{configurable:!0},E:{configurable:!0},NaN:{configurable:!0},EPS:{configurable:!0},SPLIT:{configurable:!0},MAX_PRINT_DIGITS:{configurable:!0},TEN:{configurable:!0},ONE:{configurable:!0},SCI_NOT_EXPONENT_CHAR:{configurable:!0},SCI_NOT_ZERO:{configurable:!0}};F.prototype.le=function(t){return(this._hi9?(c=!0,p="9"):p="0"+l,s.append(p),n=n.subtract(F.valueOf(l)).multiply(F.TEN),c&&n.selfAdd(F.TEN);var h=!0,f=F.magnitude(n._hi);if(f<0&&Math.abs(f)>=a-u&&(h=!1),!h)break}return e[0]=i,s.toString()},F.prototype.sqr=function(){return this.multiply(this)},F.prototype.doubleValue=function(){return this._hi+this._lo},F.prototype.subtract=function(){if(arguments[0]instanceof F){var t=arguments[0];return this.add(t.negate())}if("number"==typeof arguments[0]){var e=arguments[0];return this.add(-e)}},F.prototype.equals=function(){if(1===arguments.length){var t=arguments[0];return this._hi===t._hi&&this._lo===t._lo}},F.prototype.isZero=function(){return 0===this._hi&&0===this._lo},F.prototype.selfSubtract=function(){if(arguments[0]instanceof F){var t=arguments[0];return this.isNaN()?this:this.selfAdd(-t._hi,-t._lo)}if("number"==typeof arguments[0]){var e=arguments[0];return this.isNaN()?this:this.selfAdd(-e,0)}},F.prototype.getSpecialNumberString=function(){return this.isZero()?"0.0":this.isNaN()?"NaN ":null},F.prototype.min=function(t){return this.le(t)?this:t},F.prototype.selfDivide=function(){if(1===arguments.length){if(arguments[0]instanceof F){var t=arguments[0];return this.selfDivide(t._hi,t._lo)}if("number"==typeof arguments[0]){var e=arguments[0];return this.selfDivide(e,0)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1],r=null,o=null,s=null,a=null,u=null,l=null,c=null,p=null;return u=this._hi/n,l=F.SPLIT*u,r=l-u,p=F.SPLIT*n,r=l-r,o=u-r,s=p-n,c=u*n,s=p-s,a=n-s,p=r*s-c+r*a+o*s+o*a,l=(this._hi-c-p+this._lo-u*i)/n,p=u+l,this._hi=p,this._lo=u-p+l,this}},F.prototype.dump=function(){return"DD<"+this._hi+", "+this._lo+">"},F.prototype.divide=function(){if(arguments[0]instanceof F){var t=arguments[0],e=null,n=null,i=null,r=null,o=null,s=null,a=null,u=null;n=(o=this._hi/t._hi)-(e=(s=F.SPLIT*o)-(e=s-o)),u=e*(i=(u=F.SPLIT*t._hi)-(i=u-t._hi))-(a=o*t._hi)+e*(r=t._hi-i)+n*i+n*r,s=(this._hi-a-u+this._lo-o*t._lo)/t._hi;return new F(u=o+s,o-u+s)}if("number"==typeof arguments[0]){var l=arguments[0];return v.isNaN(l)?F.createNaN():F.copy(this).selfDivide(l,0)}},F.prototype.ge=function(t){return(this._hi>t._hi||this._hi===t._hi)&&this._lo>=t._lo},F.prototype.pow=function(t){if(0===t)return F.valueOf(1);var e=new F(this),n=F.valueOf(1),i=Math.abs(t);if(i>1)for(;i>0;)i%2==1&&n.selfMultiply(e),(i/=2)>0&&(e=e.sqr());else n=e;return t<0?n.reciprocal():n},F.prototype.ceil=function(){if(this.isNaN())return F.NaN;var t=Math.ceil(this._hi),e=0;return t===this._hi&&(e=Math.ceil(this._lo)),new F(t,e)},F.prototype.compareTo=function(t){var e=t;return this._hie._hi?1:this._loe._lo?1:0},F.prototype.rint=function(){if(this.isNaN())return this;return this.add(.5).floor()},F.prototype.setValue=function(){if(arguments[0]instanceof F){var t=arguments[0];return this.init(t),this}if("number"==typeof arguments[0]){var e=arguments[0];return this.init(e),this}},F.prototype.max=function(t){return this.ge(t)?this:t},F.prototype.sqrt=function(){if(this.isZero())return F.valueOf(0);if(this.isNegative())return F.NaN;var t=1/Math.sqrt(this._hi),e=this._hi*t,n=F.valueOf(e),i=this.subtract(n.sqr())._hi*(.5*t);return n.add(i)},F.prototype.selfAdd=function(){if(1===arguments.length){if(arguments[0]instanceof F){var t=arguments[0];return this.selfAdd(t._hi,t._lo)}if("number"==typeof arguments[0]){var e=arguments[0],n=null,i=null,r=null,o=null,s=null,a=null;return r=this._hi+e,s=r-this._hi,o=r-s,o=e-s+(this._hi-o),a=o+this._lo,n=r+a,i=a+(r-n),this._hi=n+i,this._lo=i+(n-this._hi),this}}else if(2===arguments.length){var u=arguments[0],l=arguments[1],c=null,p=null,h=null,f=null,g=null,d=null,y=null;f=this._hi+u,p=this._lo+l,g=f-(d=f-this._hi),h=p-(y=p-this._lo);var _=(c=f+(d=(g=u-d+(this._hi-g))+p))+(d=(h=l-y+(this._lo-h))+(d+(f-c))),m=d+(c-_);return this._hi=_,this._lo=m,this}},F.prototype.selfMultiply=function(){if(1===arguments.length){if(arguments[0]instanceof F){var t=arguments[0];return this.selfMultiply(t._hi,t._lo)}if("number"==typeof arguments[0]){var e=arguments[0];return this.selfMultiply(e,0)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1],r=null,o=null,s=null,a=null,u=null,l=null;r=(u=F.SPLIT*this._hi)-this._hi,l=F.SPLIT*n,r=u-r,o=this._hi-r,s=l-n;var c=(u=this._hi*n)+(l=r*(s=l-s)-u+r*(a=n-s)+o*s+o*a+(this._hi*i+this._lo*n)),p=l+(r=u-c);return this._hi=c,this._lo=p,this}},F.prototype.selfSqr=function(){return this.selfMultiply(this)},F.prototype.floor=function(){if(this.isNaN())return F.NaN;var t=Math.floor(this._hi),e=0;return t===this._hi&&(e=Math.floor(this._lo)),new F(t,e)},F.prototype.negate=function(){return this.isNaN()?this:new F(-this._hi,-this._lo)},F.prototype.clone=function(){},F.prototype.multiply=function(){if(arguments[0]instanceof F){var t=arguments[0];return t.isNaN()?F.createNaN():F.copy(this).selfMultiply(t)}if("number"==typeof arguments[0]){var e=arguments[0];return v.isNaN(e)?F.createNaN():F.copy(this).selfMultiply(e,0)}},F.prototype.isNaN=function(){return v.isNaN(this._hi)},F.prototype.intValue=function(){return Math.trunc(this._hi)},F.prototype.toString=function(){var t=F.magnitude(this._hi);return t>=-3&&t<=20?this.toStandardNotation():this.toSciNotation()},F.prototype.toStandardNotation=function(){var t=this.getSpecialNumberString();if(null!==t)return t;var e=new Array(1).fill(null),n=this.extractSignificantDigits(!0,e),i=e[0]+1,r=n;if("."===n.charAt(0))r="0"+n;else if(i<0)r="0."+F.stringOfChar("0",-i)+n;else if(-1===n.indexOf(".")){var o=i-n.length;r=n+F.stringOfChar("0",o)+".0"}return this.isNegative()?"-"+r:r},F.prototype.reciprocal=function(){var t=null,e=null,n=null,i=null,r=null,o=null,s=null,a=null;e=(r=1/this._hi)-(t=(o=F.SPLIT*r)-(t=o-r)),n=(a=F.SPLIT*this._hi)-this._hi;var u=r+(o=(1-(s=r*this._hi)-(a=t*(n=a-n)-s+t*(i=this._hi-n)+e*n+e*i)-r*this._lo)/this._hi);return new F(u,r-u+o)},F.prototype.toSciNotation=function(){if(this.isZero())return F.SCI_NOT_ZERO;var t=this.getSpecialNumberString();if(null!==t)return t;var e=new Array(1).fill(null),n=this.extractSignificantDigits(!1,e),i=F.SCI_NOT_EXPONENT_CHAR+e[0];if("0"===n.charAt(0))throw new Error("Found leading zero: "+n);var r="";n.length>1&&(r=n.substring(1));var o=n.charAt(0)+"."+r;return this.isNegative()?"-"+o+i:o+i},F.prototype.abs=function(){return this.isNaN()?F.NaN:this.isNegative()?this.negate():new F(this)},F.prototype.isPositive=function(){return(this._hi>0||0===this._hi)&&this._lo>0},F.prototype.lt=function(t){return(this._hit._hi||this._hi===t._hi)&&this._lo>t._lo},F.prototype.isNegative=function(){return(this._hi<0||0===this._hi)&&this._lo<0},F.prototype.trunc=function(){return this.isNaN()?F.NaN:this.isPositive()?this.floor():this.ceil()},F.prototype.signum=function(){return this._hi>0?1:this._hi<0?-1:this._lo>0?1:this._lo<0?-1:0},F.prototype.interfaces_=function(){return[e,E,x]},F.prototype.getClass=function(){return F},F.sqr=function(t){return F.valueOf(t).selfMultiply(t)},F.valueOf=function(){if("string"==typeof arguments[0]){var t=arguments[0];return F.parse(t)}if("number"==typeof arguments[0]){var e=arguments[0];return new F(e)}},F.sqrt=function(t){return F.valueOf(t).sqrt()},F.parse=function(t){for(var e=0,n=t.length;A.isWhitespace(t.charAt(e));)e++;var i=!1;if(e=n);){var l=t.charAt(e);if(e++,A.isDigit(l)){var c=l-"0";o.selfMultiply(F.TEN),o.selfAdd(c),s++}else{if("."!==l){if("e"===l||"E"===l){var p=t.substring(e);try{u=M.parseInt(p)}catch(e){throw e instanceof Error?new Error("Invalid exponent "+p+" in string "+t):e}break}throw new Error("Unexpected character \'"+l+"\' at position "+e+" in string "+t)}a=s}}var h=o,f=s-a-u;if(0===f)h=o;else if(f>0){var g=F.TEN.pow(f);h=o.divide(g)}else if(f<0){var d=F.TEN.pow(-f);h=o.multiply(d)}return i?h.negate():h},F.createNaN=function(){return new F(v.NaN,v.NaN)},F.copy=function(t){return new F(t)},F.magnitude=function(t){var e=Math.abs(t),n=Math.log(e)/Math.log(10),i=Math.trunc(Math.floor(n));return 10*Math.pow(10,i)<=e&&(i+=1),i},F.stringOfChar=function(t,e){for(var n=new D,i=0;i0){if(o<=0)return q.signum(s);i=r+o}else{if(!(r<0))return q.signum(s);if(o>=0)return q.signum(s);i=-r-o}var a=q.DP_SAFE_EPSILON*i;return s>=a||-s>=a?q.signum(s):2},q.signum=function(t){return t>0?1:t<0?-1:0},B.DP_SAFE_EPSILON.get=function(){return 1e-15},Object.defineProperties(q,B);var V=function(){},U={X:{configurable:!0},Y:{configurable:!0},Z:{configurable:!0},M:{configurable:!0}};U.X.get=function(){return 0},U.Y.get=function(){return 1},U.Z.get=function(){return 2},U.M.get=function(){return 3},V.prototype.setOrdinate=function(t,e,n){},V.prototype.size=function(){},V.prototype.getOrdinate=function(t,e){},V.prototype.getCoordinate=function(){},V.prototype.getCoordinateCopy=function(t){},V.prototype.getDimension=function(){},V.prototype.getX=function(t){},V.prototype.clone=function(){},V.prototype.expandEnvelope=function(t){},V.prototype.copy=function(){},V.prototype.getY=function(t){},V.prototype.toCoordinateArray=function(){},V.prototype.interfaces_=function(){return[x]},V.prototype.getClass=function(){return V},Object.defineProperties(V,U);var z=function(){},X=function(t){function e(){t.call(this,"Projective point not representable on the Cartesian plane.")}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(z),Y=function(){};Y.arraycopy=function(t,e,n,i,r){for(var o=0,s=e;st._minx?this._minx:t._minx,n=this._miny>t._miny?this._miny:t._miny,i=this._maxx=this._minx&&e.getMaxX()<=this._maxx&&e.getMinY()>=this._miny&&e.getMaxY()<=this._maxy)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];return!this.isNull()&&(n>=this._minx&&n<=this._maxx&&i>=this._miny&&i<=this._maxy)}},j.prototype.intersects=function(){if(1===arguments.length){if(arguments[0]instanceof j){var t=arguments[0];return!this.isNull()&&!t.isNull()&&!(t._minx>this._maxx||t._maxxthis._maxy||t._maxythis._maxx||nthis._maxy||ithis._maxx&&(this._maxx=e._maxx),e._minythis._maxy&&(this._maxy=e._maxy))}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];this.isNull()?(this._minx=n,this._maxx=n,this._miny=i,this._maxy=i):(nthis._maxx&&(this._maxx=n),ithis._maxy&&(this._maxy=i))}},j.prototype.minExtent=function(){if(this.isNull())return 0;var t=this.getWidth(),e=this.getHeight();return te._minx?1:this._minye._miny?1:this._maxxe._maxx?1:this._maxye._maxy?1:0},j.prototype.translate=function(t,e){if(this.isNull())return null;this.init(this.getMinX()+t,this.getMaxX()+t,this.getMinY()+e,this.getMaxY()+e)},j.prototype.toString=function(){return"Env["+this._minx+" : "+this._maxx+", "+this._miny+" : "+this._maxy+"]"},j.prototype.setToNull=function(){this._minx=0,this._maxx=-1,this._miny=0,this._maxy=-1},j.prototype.getHeight=function(){return this.isNull()?0:this._maxy-this._miny},j.prototype.maxExtent=function(){if(this.isNull())return 0;var t=this.getWidth(),e=this.getHeight();return t>e?t:e},j.prototype.expandBy=function(){if(1===arguments.length){var t=arguments[0];this.expandBy(t,t)}else if(2===arguments.length){var e=arguments[0],n=arguments[1];if(this.isNull())return null;this._minx-=e,this._maxx+=e,this._miny-=n,this._maxy+=n,(this._minx>this._maxx||this._miny>this._maxy)&&this.setToNull()}},j.prototype.contains=function(){if(1===arguments.length){if(arguments[0]instanceof j){var t=arguments[0];return this.covers(t)}if(arguments[0]instanceof C){var e=arguments[0];return this.covers(e)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];return this.covers(n,i)}},j.prototype.centre=function(){return this.isNull()?null:new C((this.getMinX()+this.getMaxX())/2,(this.getMinY()+this.getMaxY())/2)},j.prototype.init=function(){if(0===arguments.length)this.setToNull();else if(1===arguments.length){if(arguments[0]instanceof C){var t=arguments[0];this.init(t.x,t.x,t.y,t.y)}else if(arguments[0]instanceof j){var e=arguments[0];this._minx=e._minx,this._maxx=e._maxx,this._miny=e._miny,this._maxy=e._maxy}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];this.init(n.x,i.x,n.y,i.y)}else if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3];rt._maxx&&(e=this._minx-t._maxx);var n=0;return this._maxyt._maxy&&(n=this._miny-t._maxy),0===e?n:0===n?e:Math.sqrt(e*e+n*n)},j.prototype.hashCode=function(){var t=17;return t=37*t+C.hashCode(this._minx),t=37*t+C.hashCode(this._maxx),t=37*t+C.hashCode(this._miny),t=37*t+C.hashCode(this._maxy)},j.prototype.interfaces_=function(){return[E,e]},j.prototype.getClass=function(){return j},j.intersects=function(){if(3===arguments.length){var t=arguments[0],e=arguments[1],n=arguments[2];return n.x>=(t.xe.x?t.x:e.x)&&n.y>=(t.ye.y?t.y:e.y)}if(4===arguments.length){var i=arguments[0],r=arguments[1],o=arguments[2],s=arguments[3],a=Math.min(o.x,s.x),u=Math.max(o.x,s.x),l=Math.min(i.x,r.x),c=Math.max(i.x,r.x);return!(l>u)&&(!(cu)&&!(cthis.getEdgeDistance(t,1)?(this._intLineIndex[t][0]=0,this._intLineIndex[t][1]=1):(this._intLineIndex[t][0]=1,this._intLineIndex[t][1]=0)}},nt.prototype.isProper=function(){return this.hasIntersection()&&this._isProper},nt.prototype.setPrecisionModel=function(t){this._precisionModel=t},nt.prototype.isInteriorIntersection=function(){if(0===arguments.length)return!!this.isInteriorIntersection(0)||!!this.isInteriorIntersection(1);if(1===arguments.length){for(var t=arguments[0],e=0;er?i:r;else{var s=Math.abs(t.x-e.x),a=Math.abs(t.y-e.y);0!==(o=i>r?s:a)||t.equals(e)||(o=Math.max(s,a))}return et.isTrue(!(0===o&&!t.equals(e)),"Bad distance calculation"),o},nt.nonRobustComputeEdgeDistance=function(t,e,n){var i=t.x-e.x,r=t.y-e.y,o=Math.sqrt(i*i+r*r);return et.isTrue(!(0===o&&!t.equals(e)),"Invalid distance calculation"),o},it.DONT_INTERSECT.get=function(){return 0},it.DO_INTERSECT.get=function(){return 1},it.COLLINEAR.get=function(){return 2},it.NO_INTERSECTION.get=function(){return 0},it.POINT_INTERSECTION.get=function(){return 1},it.COLLINEAR_INTERSECTION.get=function(){return 2},Object.defineProperties(nt,it);var rt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.isInSegmentEnvelopes=function(t){var e=new j(this._inputLines[0][0],this._inputLines[0][1]),n=new j(this._inputLines[1][0],this._inputLines[1][1]);return e.contains(t)&&n.contains(t)},e.prototype.computeIntersection=function(){if(3!==arguments.length)return t.prototype.computeIntersection.apply(this,arguments);var e=arguments[0],n=arguments[1],i=arguments[2];if(this._isProper=!1,j.intersects(n,i,e)&&0===at.orientationIndex(n,i,e)&&0===at.orientationIndex(i,n,e))return this._isProper=!0,(e.equals(n)||e.equals(i))&&(this._isProper=!1),this._result=t.POINT_INTERSECTION,null;this._result=t.NO_INTERSECTION},e.prototype.normalizeToMinimum=function(t,e,n,i,r){r.x=this.smallestInAbsValue(t.x,e.x,n.x,i.x),r.y=this.smallestInAbsValue(t.y,e.y,n.y,i.y),t.x-=r.x,t.y-=r.y,e.x-=r.x,e.y-=r.y,n.x-=r.x,n.y-=r.y,i.x-=r.x,i.y-=r.y},e.prototype.safeHCoordinateIntersection=function(t,n,i,r){var o=null;try{o=k.intersection(t,n,i,r)}catch(s){if(!(s instanceof X))throw s;o=e.nearestEndpoint(t,n,i,r)}return o},e.prototype.intersection=function(t,n,i,r){var o=this.intersectionWithNormalization(t,n,i,r);return this.isInSegmentEnvelopes(o)||(o=new C(e.nearestEndpoint(t,n,i,r))),null!==this._precisionModel&&this._precisionModel.makePrecise(o),o},e.prototype.smallestInAbsValue=function(t,e,n,i){var r=t,o=Math.abs(r);return Math.abs(e)1e-4&&Y.out.println("Distance = "+r.distance(o))},e.prototype.intersectionWithNormalization=function(t,e,n,i){var r=new C(t),o=new C(e),s=new C(n),a=new C(i),u=new C;this.normalizeToEnvCentre(r,o,s,a,u);var l=this.safeHCoordinateIntersection(r,o,s,a);return l.x+=u.x,l.y+=u.y,l},e.prototype.computeCollinearIntersection=function(e,n,i,r){var o=j.intersects(e,n,i),s=j.intersects(e,n,r),a=j.intersects(i,r,e),u=j.intersects(i,r,n);return o&&s?(this._intPt[0]=i,this._intPt[1]=r,t.COLLINEAR_INTERSECTION):a&&u?(this._intPt[0]=e,this._intPt[1]=n,t.COLLINEAR_INTERSECTION):o&&a?(this._intPt[0]=i,this._intPt[1]=e,!i.equals(e)||s||u?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):o&&u?(this._intPt[0]=i,this._intPt[1]=n,!i.equals(n)||s||a?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):s&&a?(this._intPt[0]=r,this._intPt[1]=e,!r.equals(e)||o||u?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):s&&u?(this._intPt[0]=r,this._intPt[1]=n,!r.equals(n)||o||a?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):t.NO_INTERSECTION},e.prototype.normalizeToEnvCentre=function(t,e,n,i,r){var o=t.xe.x?t.x:e.x,u=t.y>e.y?t.y:e.y,l=n.xi.x?n.x:i.x,h=n.y>i.y?n.y:i.y,f=((o>l?o:l)+(ac?s:c)+(u0&&s>0||o<0&&s<0)return t.NO_INTERSECTION;var a=at.orientationIndex(i,r,e),u=at.orientationIndex(i,r,n);if(a>0&&u>0||a<0&&u<0)return t.NO_INTERSECTION;return 0===o&&0===s&&0===a&&0===u?this.computeCollinearIntersection(e,n,i,r):(0===o||0===s||0===a||0===u?(this._isProper=!1,e.equals2D(i)||e.equals2D(r)?this._intPt[0]=e:n.equals2D(i)||n.equals2D(r)?this._intPt[0]=n:0===o?this._intPt[0]=new C(i):0===s?this._intPt[0]=new C(r):0===a?this._intPt[0]=new C(e):0===u&&(this._intPt[0]=new C(n))):(this._isProper=!0,this._intPt[0]=this.intersection(e,n,i,r)),t.POINT_INTERSECTION)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e.nearestEndpoint=function(t,e,n,i){var r=t,o=at.distancePointLine(t,n,i),s=at.distancePointLine(e,n,i);return s0?n>0?-r:r:n>0?r:-r;if(0===e||0===n)return i>0?t>0?r:-r:t>0?-r:r;if(e>0?i>0?e<=i||(r=-r,o=t,t=n,n=o,o=e,e=i,i=o):e<=-i?(r=-r,n=-n,i=-i):(o=t,t=-n,n=o,o=e,e=-i,i=o):i>0?-e<=i?(r=-r,t=-t,e=-e):(o=-t,t=n,n=o,o=-e,e=i,i=o):e>=i?(t=-t,e=-e,n=-n,i=-i):(r=-r,o=-t,t=-n,n=o,o=-e,e=-i,i=o),t>0){if(!(n>0))return r;if(!(t<=n))return r}else{if(n>0)return-r;if(!(t>=n))return-r;r=-r,t=-t,n=-n}for(;;){if(s=Math.floor(n/t),n-=s*t,(i-=s*e)<0)return-r;if(i>e)return r;if(t>n+n){if(ei+i)return-r;n=t-n,i=e-i,r=-r}if(0===i)return 0===n?0:-r;if(0===n)return r;if(s=Math.floor(t/n),t-=s*n,(e-=s*i)<0)return r;if(e>i)return-r;if(n>t+t){if(ie+e)return r;t=n-t,e=i-e,r=-r}if(0===e)return 0===t?0:r;if(0===t)return-r}};var st=function(){this._p=null,this._crossingCount=0,this._isPointOnSegment=!1;var t=arguments[0];this._p=t};st.prototype.countSegment=function(t,e){if(t.xi&&(n=e.x,i=t.x),this._p.x>=n&&this._p.x<=i&&(this._isPointOnSegment=!0),null}if(t.y>this._p.y&&e.y<=this._p.y||e.y>this._p.y&&t.y<=this._p.y){var r=t.x-this._p.x,o=t.y-this._p.y,s=e.x-this._p.x,a=e.y-this._p.y,u=ot.signOfDet2x2(r,o,s,a);if(0===u)return this._isPointOnSegment=!0,null;a0&&this._crossingCount++}},st.prototype.isPointInPolygon=function(){return this.getLocation()!==w.EXTERIOR},st.prototype.getLocation=function(){return this._isPointOnSegment?w.BOUNDARY:this._crossingCount%2==1?w.INTERIOR:w.EXTERIOR},st.prototype.isOnSegment=function(){return this._isPointOnSegment},st.prototype.interfaces_=function(){return[]},st.prototype.getClass=function(){return st},st.locatePointInRing=function(){if(arguments[0]instanceof C&&T(arguments[1],V)){for(var t=arguments[0],e=arguments[1],n=new st(t),i=new C,r=new C,o=1;o1||a<0||a>1)&&(r=!0)}}else r=!0;return r?R.min(at.distancePointLine(t,n,i),at.distancePointLine(e,n,i),at.distancePointLine(n,t,e),at.distancePointLine(i,t,e)):0},at.isPointInRing=function(t,e){return at.locatePointInRing(t,e)!==w.EXTERIOR},at.computeLength=function(t){var e=t.size();if(e<=1)return 0;var n=0,i=new C;t.getCoordinate(0,i);for(var r=i.x,o=i.y,s=1;sn.y&&(n=o,i=r)}var s=i;do{(s-=1)<0&&(s=e)}while(t[s].equals2D(n)&&s!==i);var a=i;do{a=(a+1)%e}while(t[a].equals2D(n)&&a!==i);var u=t[s],l=t[a];if(u.equals2D(n)||l.equals2D(n)||u.equals2D(l))return!1;var c=at.computeOrientation(u,n,l),p=!1;return p=0===c?u.x>l.x:c>0,p},at.locatePointInRing=function(t,e){return st.locatePointInRing(t,e)},at.distancePointLinePerpendicular=function(t,e,n){var i=(n.x-e.x)*(n.x-e.x)+(n.y-e.y)*(n.y-e.y),r=((e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y))/i;return Math.abs(r)*Math.sqrt(i)},at.computeOrientation=function(t,e,n){return at.orientationIndex(t,e,n)},at.distancePointLine=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];if(0===e.length)throw new m("Line array must contain at least one vertex");for(var n=t.distance(e[0]),i=0;i=1)return o.distance(a);var c=((s.y-o.y)*(a.x-s.x)-(s.x-o.x)*(a.y-s.y))/u;return Math.abs(c)*Math.sqrt(u)}},at.isOnLine=function(t,e){for(var n=new rt,i=1;i0},_t.prototype.interfaces_=function(){return[gt]},_t.prototype.getClass=function(){return _t};var mt=function(){};mt.prototype.isInBoundary=function(t){return t>1},mt.prototype.interfaces_=function(){return[gt]},mt.prototype.getClass=function(){return mt};var vt=function(){};vt.prototype.isInBoundary=function(t){return 1===t},vt.prototype.interfaces_=function(){return[gt]},vt.prototype.getClass=function(){return vt};var It=function(){};It.prototype.add=function(){},It.prototype.addAll=function(){},It.prototype.isEmpty=function(){},It.prototype.iterator=function(){},It.prototype.size=function(){},It.prototype.toArray=function(){},It.prototype.remove=function(){},(n.prototype=new Error).name="IndexOutOfBoundsException";var Et=function(){};Et.prototype.hasNext=function(){},Et.prototype.next=function(){},Et.prototype.remove=function(){};var xt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(){},e.prototype.set=function(){},e.prototype.isEmpty=function(){},e}(It);(i.prototype=new Error).name="NoSuchElementException";var Nt=function(t){function e(){t.call(this),this.array_=[],arguments[0]instanceof It&&this.addAll(arguments[0])}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.ensureCapacity=function(){},e.prototype.interfaces_=function(){return[t,It]},e.prototype.add=function(t){return 1===arguments.length?this.array_.push(t):this.array_.splice(arguments[0],arguments[1]),!0},e.prototype.clear=function(){this.array_=[]},e.prototype.addAll=function(t){for(var e=t.iterator();e.hasNext();)this.add(e.next());return!0},e.prototype.set=function(t,e){var n=this.array_[t];return this.array_[t]=e,n},e.prototype.iterator=function(){return new Ct(this)},e.prototype.get=function(t){if(t<0||t>=this.size())throw new n;return this.array_[t]},e.prototype.isEmpty=function(){return 0===this.array_.length},e.prototype.size=function(){return this.array_.length},e.prototype.toArray=function(){for(var t=[],e=0,n=this.array_.length;e=1){if(this.get(this.size()-1).equals2D(r))return null}t.prototype.add.call(this,r)}else if(arguments[0]instanceof Object&&"boolean"==typeof arguments[1]){var o=arguments[0],s=arguments[1];return this.add(o,s),!0}}else if(3===arguments.length){if("boolean"==typeof arguments[2]&&arguments[0]instanceof Array&&"boolean"==typeof arguments[1]){var a=arguments[0],u=arguments[1];if(arguments[2])for(var l=0;l=0;c--)this.add(a[c],u);return!0}if("boolean"==typeof arguments[2]&&Number.isInteger(arguments[0])&&arguments[1]instanceof C){var p=arguments[0],h=arguments[1];if(!arguments[2]){var f=this.size();if(f>0){if(p>0){if(this.get(p-1).equals2D(h))return null}if(p_&&(m=-1);for(var v=y;v!==_;v+=m)this.add(g[v],d);return!0}},e.prototype.closeRing=function(){this.size()>0&&this.add(new C(this.get(0)),!1)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},Object.defineProperties(e,n),e}(Nt),Lt=function(){},bt={ForwardComparator:{configurable:!0},BidirectionalComparator:{configurable:!0},coordArrayType:{configurable:!0}};bt.ForwardComparator.get=function(){return wt},bt.BidirectionalComparator.get=function(){return Ot},bt.coordArrayType.get=function(){return new Array(0).fill(null)},Lt.prototype.interfaces_=function(){return[]},Lt.prototype.getClass=function(){return Lt},Lt.isRing=function(t){return!(t.length<4)&&!!t[0].equals2D(t[t.length-1])},Lt.ptNotInList=function(t,e){for(var n=0;n=t?e:[]},Lt.indexOf=function(t,e){for(var n=0;n0)&&(e=t[n]);return e},Lt.extract=function(t,e,n){e=R.clamp(e,0,t.length);var i=(n=R.clamp(n,-1,t.length))-e+1;n<0&&(i=0),e>=t.length&&(i=0),ni.length)return 1;if(0===n.length)return 0;var r=Lt.compare(n,i);return Lt.isEqualReversed(n,i)?0:r},Ot.prototype.OLDcompare=function(t,e){var n=t,i=e;if(n.lengthi.length)return 1;if(0===n.length)return 0;for(var r=Lt.increasingDirection(n),o=Lt.increasingDirection(i),s=r>0?0:n.length-1,a=o>0?0:n.length-1,u=0;u0))return e.value;e=e.right}}return null},p.prototype.put=function(t,e){if(null===this.root_)return this.root_={key:t,value:e,left:null,right:null,parent:null,color:Mt,getValue:function(){return this.value},getKey:function(){return this.key}},this.size_=1,null;var n,i,r=this.root_;do{if(n=r,(i=t.compareTo(r.key))<0)r=r.left;else{if(!(i>0)){var o=r.value;return r.value=e,o}r=r.right}}while(null!==r);var s={key:t,left:null,right:null,value:e,parent:n,color:Mt,getValue:function(){return this.value},getKey:function(){return this.key}};return i<0?n.left=s:n.right=s,this.fixAfterInsertion(s),this.size_++,null},p.prototype.fixAfterInsertion=function(t){for(t.color=1;null!=t&&t!==this.root_&&1===t.parent.color;)if(a(t)===l(a(a(t)))){var e=c(a(a(t)));1===s(e)?(u(a(t),Mt),u(e,Mt),u(a(a(t)),1),t=a(a(t))):(t===c(a(t))&&(t=a(t),this.rotateLeft(t)),u(a(t),Mt),u(a(a(t)),1),this.rotateRight(a(a(t))))}else{var n=l(a(a(t)));1===s(n)?(u(a(t),Mt),u(n,Mt),u(a(a(t)),1),t=a(a(t))):(t===l(a(t))&&(t=a(t),this.rotateRight(t)),u(a(t),Mt),u(a(a(t)),1),this.rotateLeft(a(a(t))))}this.root_.color=Mt},p.prototype.values=function(){var t=new Nt,e=this.getFirstEntry();if(null!==e)for(t.add(e.value);null!==(e=p.successor(e));)t.add(e.value);return t},p.prototype.entrySet=function(){var t=new Pt,e=this.getFirstEntry();if(null!==e)for(t.add(e);null!==(e=p.successor(e));)t.add(e);return t},p.prototype.rotateLeft=function(t){if(null!=t){var e=t.right;t.right=e.left,null!=e.left&&(e.left.parent=t),e.parent=t.parent,null===t.parent?this.root_=e:t.parent.left===t?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e}},p.prototype.rotateRight=function(t){if(null!=t){var e=t.left;t.left=e.right,null!=e.right&&(e.right.parent=t),e.parent=t.parent,null===t.parent?this.root_=e:t.parent.right===t?t.parent.right=e:t.parent.left=e,e.right=t,t.parent=e}},p.prototype.getFirstEntry=function(){var t=this.root_;if(null!=t)for(;null!=t.left;)t=t.left;return t},p.successor=function(t){if(null===t)return null;if(null!==t.right){for(var e=t.right;null!==e.left;)e=e.left;return e}for(var n=t.parent,i=t;null!==n&&i===n.right;)i=n,n=n.parent;return n},p.prototype.size=function(){return this.size_};var At=function(){};At.prototype.interfaces_=function(){return[]},At.prototype.getClass=function(){return At},h.prototype=new o,(f.prototype=new h).contains=function(t){for(var e=0,n=this.array_.length;e=0;){var s=r.substring(0,o);i.add(s),o=(r=r.substring(o+n)).indexOf(e)}r.length>0&&i.add(r);for(var a=new Array(i.size()).fill(null),u=0;u0)for(var o=r;o0&&i.append(" ");for(var o=0;o0&&i.append(","),i.append(jt.toString(t.getOrdinate(r,o)))}return i.append(")"),i.toString()}},Wt.ensureValidRing=function(t,e){var n=e.size();if(0===n)return e;if(n<=3)return Wt.createClosedRing(t,e,4);return e.getOrdinate(0,V.X)===e.getOrdinate(n-1,V.X)&&e.getOrdinate(0,V.Y)===e.getOrdinate(n-1,V.Y)?e:Wt.createClosedRing(t,e,n+1)},Wt.createClosedRing=function(t,e,n){var i=t.create(n,e.getDimension()),r=e.size();Wt.copy(e,0,i,0,r);for(var o=r;o0&&Wt.reverse(this._points),null}},e.prototype.getCoordinate=function(){return this.isEmpty()?null:this._points.getCoordinate(0)},e.prototype.getBoundaryDimension=function(){return this.isClosed()?qt.FALSE:0},e.prototype.isClosed=function(){return!this.isEmpty()&&this.getCoordinateN(0).equals2D(this.getCoordinateN(this.getNumPoints()-1))},e.prototype.getEndPoint=function(){return this.isEmpty()?null:this.getPointN(this.getNumPoints()-1)},e.prototype.getDimension=function(){return 1},e.prototype.getLength=function(){return at.computeLength(this._points)},e.prototype.getNumPoints=function(){return this._points.size()},e.prototype.reverse=function(){var t=this._points.copy();Wt.reverse(t);return this.getFactory().createLineString(t)},e.prototype.compareToSameClass=function(){if(1===arguments.length){for(var t=arguments[0],e=0,n=0;e= 2)");this._points=t},e.prototype.isCoordinate=function(t){for(var e=0;e=1&&this.getCoordinateSequence().size()= 4)")},e.prototype.getGeometryType=function(){return"LinearRing"},e.prototype.copy=function(){return new e(this._points.copy(),this._factory)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},n.MINIMUM_VALID_SIZE.get=function(){return 4},n.serialVersionUID.get=function(){return-0x3b229e262367a600},Object.defineProperties(e,n),e}(Kt),ne=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),(e.prototype=Object.create(t&&t.prototype)).constructor=e;var n={serialVersionUID:{configurable:!0}};return e.prototype.getSortIndex=function(){return ct.SORTINDEX_MULTIPOLYGON},e.prototype.equalsExact=function(){if(2===arguments.length){var e=arguments[0],n=arguments[1];return!!this.isEquivalentClass(e)&&t.prototype.equalsExact.call(this,e,n)}return t.prototype.equalsExact.apply(this,arguments)},e.prototype.getBoundaryDimension=function(){return 1},e.prototype.getDimension=function(){return 2},e.prototype.reverse=function(){for(var t=this._geometries.length,e=new Array(t).fill(null),n=0;n0?e.createPoint(n[0]):e.createPoint():t},se.prototype.interfaces_=function(){return[ie.GeometryEditorOperation]},se.prototype.getClass=function(){return se};var ae=function(){};ae.prototype.edit=function(t,e){return t instanceof ee?e.createLinearRing(this.edit(t.getCoordinateSequence(),t)):t instanceof Kt?e.createLineString(this.edit(t.getCoordinateSequence(),t)):t instanceof Qt?e.createPoint(this.edit(t.getCoordinateSequence(),t)):t},ae.prototype.interfaces_=function(){return[ie.GeometryEditorOperation]},ae.prototype.getClass=function(){return ae};var ue=function(){if(this._dimension=3,this._coordinates=null,1===arguments.length){if(arguments[0]instanceof Array)this._coordinates=arguments[0],this._dimension=3;else if(Number.isInteger(arguments[0])){var t=arguments[0];this._coordinates=new Array(t).fill(null);for(var e=0;e0){var t=new D(17*this._coordinates.length);t.append("("),t.append(this._coordinates[0]);for(var e=1;e3&&(i=3),i<2?new ue(n):new ue(n,i)}},ce.prototype.interfaces_=function(){return[b,e]},ce.prototype.getClass=function(){return ce},ce.instance=function(){return ce.instanceObject},pe.serialVersionUID.get=function(){return-0x38e49fa6cf6f2e00},pe.instanceObject.get=function(){return new ce},Object.defineProperties(ce,pe);var he=function(t){function e(){t.call(this),this.map_=new Map}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(t){return this.map_.get(t)||null},e.prototype.put=function(t,e){return this.map_.set(t,e),e},e.prototype.values=function(){for(var t=new Nt,e=this.map_.values(),n=e.next();!n.done;)t.add(n.value),n=e.next();return t},e.prototype.entrySet=function(){var t=new Pt;return this.map_.entries().forEach(function(e){return t.add(e)}),t},e.prototype.size=function(){return this.map_.size()},e}(Tt),fe=function t(){if(this._modelType=null,this._scale=null,0===arguments.length)this._modelType=t.FLOATING;else if(1===arguments.length)if(arguments[0]instanceof de){var e=arguments[0];this._modelType=e,e===t.FIXED&&this.setScale(1)}else if("number"==typeof arguments[0]){var n=arguments[0];this._modelType=t.FIXED,this.setScale(n)}else if(arguments[0]instanceof t){var i=arguments[0];this._modelType=i._modelType,this._scale=i._scale}},ge={serialVersionUID:{configurable:!0},maximumPreciseValue:{configurable:!0}};fe.prototype.equals=function(t){if(!(t instanceof fe))return!1;var e=t;return this._modelType===e._modelType&&this._scale===e._scale},fe.prototype.compareTo=function(t){var e=t,n=this.getMaximumSignificantDigits(),i=e.getMaximumSignificantDigits();return new M(n).compareTo(new M(i))},fe.prototype.getScale=function(){return this._scale},fe.prototype.isFloating=function(){return this._modelType===fe.FLOATING||this._modelType===fe.FLOATING_SINGLE},fe.prototype.getType=function(){return this._modelType},fe.prototype.toString=function(){var t="UNKNOWN";return this._modelType===fe.FLOATING?t="Floating":this._modelType===fe.FLOATING_SINGLE?t="Floating-Single":this._modelType===fe.FIXED&&(t="Fixed (Scale="+this.getScale()+")"),t},fe.prototype.makePrecise=function(){if("number"==typeof arguments[0]){var t=arguments[0];if(v.isNaN(t))return t;if(this._modelType===fe.FLOATING_SINGLE){return t}return this._modelType===fe.FIXED?Math.round(t*this._scale)/this._scale:t}if(arguments[0]instanceof C){var e=arguments[0];if(this._modelType===fe.FLOATING)return null;e.x=this.makePrecise(e.x),e.y=this.makePrecise(e.y)}},fe.prototype.getMaximumSignificantDigits=function(){var t=16;return this._modelType===fe.FLOATING?t=16:this._modelType===fe.FLOATING_SINGLE?t=6:this._modelType===fe.FIXED&&(t=1+Math.trunc(Math.ceil(Math.log(this.getScale())/Math.log(10)))),t},fe.prototype.setScale=function(t){this._scale=Math.abs(t)},fe.prototype.interfaces_=function(){return[e,E]},fe.prototype.getClass=function(){return fe},fe.mostPrecise=function(t,e){return t.compareTo(e)>=0?t:e},ge.serialVersionUID.get=function(){return 0x6bee6404e9a25c00},ge.maximumPreciseValue.get=function(){return 9007199254740992},Object.defineProperties(fe,ge);var de=function t(e){this._name=e||null,t.nameToTypeMap.put(e,this)},ye={serialVersionUID:{configurable:!0},nameToTypeMap:{configurable:!0}};de.prototype.readResolve=function(){return de.nameToTypeMap.get(this._name)},de.prototype.toString=function(){return this._name},de.prototype.interfaces_=function(){return[e]},de.prototype.getClass=function(){return de},ye.serialVersionUID.get=function(){return-552860263173159e4},ye.nameToTypeMap.get=function(){return new he},Object.defineProperties(de,ye),fe.Type=de,fe.FIXED=new de("FIXED"),fe.FLOATING=new de("FLOATING"),fe.FLOATING_SINGLE=new de("FLOATING SINGLE");var _e=function t(){this._precisionModel=new fe,this._SRID=0,this._coordinateSequenceFactory=t.getDefaultCoordinateSequenceFactory(),0===arguments.length||(1===arguments.length?T(arguments[0],b)?this._coordinateSequenceFactory=arguments[0]:arguments[0]instanceof fe&&(this._precisionModel=arguments[0]):2===arguments.length?(this._precisionModel=arguments[0],this._SRID=arguments[1]):3===arguments.length&&(this._precisionModel=arguments[0],this._SRID=arguments[1],this._coordinateSequenceFactory=arguments[2]))},me={serialVersionUID:{configurable:!0}};_e.prototype.toGeometry=function(t){return t.isNull()?this.createPoint(null):t.getMinX()===t.getMaxX()&&t.getMinY()===t.getMaxY()?this.createPoint(new C(t.getMinX(),t.getMinY())):t.getMinX()===t.getMaxX()||t.getMinY()===t.getMaxY()?this.createLineString([new C(t.getMinX(),t.getMinY()),new C(t.getMaxX(),t.getMaxY())]):this.createPolygon(this.createLinearRing([new C(t.getMinX(),t.getMinY()),new C(t.getMinX(),t.getMaxY()),new C(t.getMaxX(),t.getMaxY()),new C(t.getMaxX(),t.getMinY()),new C(t.getMinX(),t.getMinY())]),null)},_e.prototype.createLineString=function(t){return t?t instanceof Array?new Kt(this.getCoordinateSequenceFactory().create(t),this):T(t,V)?new Kt(t,this):void 0:new Kt(this.getCoordinateSequenceFactory().create([]),this)},_e.prototype.createMultiLineString=function(){if(0===arguments.length)return new Xt(null,this);if(1===arguments.length){var t=arguments[0];return new Xt(t,this)}},_e.prototype.buildGeometry=function(t){for(var e=null,n=!1,i=!1,r=t.iterator();r.hasNext();){var o=r.next(),s=o.getClass();null===e&&(e=s),s!==e&&(n=!0),o.isGeometryCollectionOrDerived()&&(i=!0)}if(null===e)return this.createGeometryCollection();if(n||i)return this.createGeometryCollection(_e.toGeometryArray(t));var a=t.iterator().next();if(t.size()>1){if(a instanceof $t)return this.createMultiPolygon(_e.toPolygonArray(t));if(a instanceof Kt)return this.createMultiLineString(_e.toLineStringArray(t));if(a instanceof Qt)return this.createMultiPoint(_e.toPointArray(t));et.shouldNeverReachHere("Unhandled class: "+a.getClass().getName())}return a},_e.prototype.createMultiPointFromCoords=function(t){return this.createMultiPoint(null!==t?this.getCoordinateSequenceFactory().create(t):null)},_e.prototype.createPoint=function(){if(0===arguments.length)return this.createPoint(this.getCoordinateSequenceFactory().create([]));if(1===arguments.length){if(arguments[0]instanceof C){var t=arguments[0];return this.createPoint(null!==t?this.getCoordinateSequenceFactory().create([t]):null)}if(T(arguments[0],V)){var e=arguments[0];return new Qt(e,this)}}},_e.prototype.getCoordinateSequenceFactory=function(){return this._coordinateSequenceFactory},_e.prototype.createPolygon=function(){if(0===arguments.length)return new $t(null,null,this);if(1===arguments.length){if(T(arguments[0],V)){var t=arguments[0];return this.createPolygon(this.createLinearRing(t))}if(arguments[0]instanceof Array){var e=arguments[0];return this.createPolygon(this.createLinearRing(e))}if(arguments[0]instanceof ee){var n=arguments[0];return this.createPolygon(n,null)}}else if(2===arguments.length){var i=arguments[0],r=arguments[1];return new $t(i,r,this)}},_e.prototype.getSRID=function(){return this._SRID},_e.prototype.createGeometryCollection=function(){if(0===arguments.length)return new zt(null,this);if(1===arguments.length){var t=arguments[0];return new zt(t,this)}},_e.prototype.createGeometry=function(t){return new ie(this).edit(t,{edit:function(){if(2===arguments.length){var t=arguments[0];return this._coordinateSequenceFactory.create(t)}}})},_e.prototype.getPrecisionModel=function(){return this._precisionModel},_e.prototype.createLinearRing=function(){if(0===arguments.length)return this.createLinearRing(this.getCoordinateSequenceFactory().create([]));if(1===arguments.length){if(arguments[0]instanceof Array){var t=arguments[0];return this.createLinearRing(null!==t?this.getCoordinateSequenceFactory().create(t):null)}if(T(arguments[0],V)){var e=arguments[0];return new ee(e,this)}}},_e.prototype.createMultiPolygon=function(){if(0===arguments.length)return new ne(null,this);if(1===arguments.length){var t=arguments[0];return new ne(t,this)}},_e.prototype.createMultiPoint=function(){if(0===arguments.length)return new te(null,this);if(1===arguments.length){if(arguments[0]instanceof Array){var t=arguments[0];return new te(t,this)}if(arguments[0]instanceof Array){var e=arguments[0];return this.createMultiPoint(null!==e?this.getCoordinateSequenceFactory().create(e):null)}if(T(arguments[0],V)){var n=arguments[0];if(null===n)return this.createMultiPoint(new Array(0).fill(null));for(var i=new Array(n.size()).fill(null),r=0;r=this.size())throw new Error;return this.array_[t]},y.prototype.push=function(t){return this.array_.push(t),t},y.prototype.pop=function(t){if(0===this.array_.length)throw new d;return this.array_.pop()},y.prototype.peek=function(){if(0===this.array_.length)throw new d;return this.array_[this.array_.length-1]},y.prototype.empty=function(){return 0===this.array_.length},y.prototype.isEmpty=function(){return this.empty()},y.prototype.search=function(t){return this.array_.indexOf(t)},y.prototype.size=function(){return this.array_.length},y.prototype.toArray=function(){for(var t=[],e=0,n=this.array_.length;e0&&this._minIndexthis._minCoord.y&&n.y>this._minCoord.y&&i===at.CLOCKWISE&&(r=!0),r&&(this._minIndex=this._minIndex-1)},be.prototype.getRightmostSideOfSegment=function(t,e){var n=t.getEdge().getCoordinates();if(e<0||e+1>=n.length)return-1;if(n[e].y===n[e+1].y)return-1;var i=Se.LEFT;return n[e].ythis._minCoord.x)&&(this._minDe=t,this._minIndex=n,this._minCoord=e[n])},be.prototype.findRightmostEdgeAtNode=function(){var t=this._minDe.getNode().getEdges();this._minDe=t.getRightmostEdge(),this._minDe.isForward()||(this._minDe=this._minDe.getSym(),this._minIndex=this._minDe.getEdge().getCoordinates().length-1)},be.prototype.findEdge=function(t){for(var e=t.iterator();e.hasNext();){var n=e.next();n.isForward()&&this.checkForRightmostCoordinate(n)}et.isTrue(0!==this._minIndex||this._minCoord.equals(this._minDe.getCoordinate()),"inconsistency in rightmost processing"),0===this._minIndex?this.findRightmostEdgeAtNode():this.findRightmostEdgeAtVertex(),this._orientedDe=this._minDe;this.getRightmostSide(this._minDe,this._minIndex)===Se.LEFT&&(this._orientedDe=this._minDe.getSym())},be.prototype.interfaces_=function(){return[]},be.prototype.getClass=function(){return be};var we=function(t){function e(n,i){t.call(this,e.msgWithCoord(n,i)),this.pt=i?new C(i):null,this.name="TopologyException"}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getCoordinate=function(){return this.pt},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e.msgWithCoord=function(t,e){return e?t:t+" [ "+e+" ]"},e}($),Oe=function(){this.array_=[]};Oe.prototype.addLast=function(t){this.array_.push(t)},Oe.prototype.removeFirst=function(){return this.array_.shift()},Oe.prototype.isEmpty=function(){return 0===this.array_.length};var Te=function(){this._finder=null,this._dirEdgeList=new Nt,this._nodes=new Nt,this._rightMostCoord=null,this._env=null,this._finder=new be};Te.prototype.clearVisitedEdges=function(){for(var t=this._dirEdgeList.iterator();t.hasNext();){t.next().setVisited(!1)}},Te.prototype.getRightmostCoordinate=function(){return this._rightMostCoord},Te.prototype.computeNodeDepth=function(t){for(var e=null,n=t.getEdges().iterator();n.hasNext();){var i=n.next();if(i.isVisited()||i.getSym().isVisited()){e=i;break}}if(null===e)throw new we("unable to find edge to compute depths at "+t.getCoordinate());t.getEdges().computeDepths(e);for(var r=t.getEdges().iterator();r.hasNext();){var o=r.next();o.setVisited(!0),this.copySymDepths(o)}},Te.prototype.computeDepth=function(t){this.clearVisitedEdges();var e=this._finder.getEdge();e.setEdgeDepths(Se.RIGHT,t),this.copySymDepths(e),this.computeDepths(e)},Te.prototype.create=function(t){this.addReachable(t),this._finder.findEdge(this._dirEdgeList),this._rightMostCoord=this._finder.getCoordinate()},Te.prototype.findResultEdges=function(){for(var t=this._dirEdgeList.iterator();t.hasNext();){var e=t.next();e.getDepth(Se.RIGHT)>=1&&e.getDepth(Se.LEFT)<=0&&!e.isInteriorAreaEdge()&&e.setInResult(!0)}},Te.prototype.computeDepths=function(t){var e=new Pt,n=new Oe,i=t.getNode();for(n.addLast(i),e.add(i),t.setVisited(!0);!n.isEmpty();){var r=n.removeFirst();e.add(r),this.computeNodeDepth(r);for(var o=r.getEdges().iterator();o.hasNext();){var s=o.next().getSym();if(!s.isVisited()){var a=s.getNode();e.contains(a)||(n.addLast(a),e.add(a))}}}},Te.prototype.compareTo=function(t){var e=t;return this._rightMostCoord.xe._rightMostCoord.x?1:0},Te.prototype.getEnvelope=function(){if(null===this._env){for(var t=new j,e=this._dirEdgeList.iterator();e.hasNext();)for(var n=e.next().getEdge().getCoordinates(),i=0;ithis.location.length){var e=new Array(3).fill(null);e[Se.ON]=this.location[Se.ON],e[Se.LEFT]=w.NONE,e[Se.RIGHT]=w.NONE,this.location=e}for(var n=0;n1&&t.append(w.toLocationSymbol(this.location[Se.LEFT])),t.append(w.toLocationSymbol(this.location[Se.ON])),this.location.length>1&&t.append(w.toLocationSymbol(this.location[Se.RIGHT])),t.toString()},Re.prototype.setLocations=function(t,e,n){this.location[Se.ON]=t,this.location[Se.LEFT]=e,this.location[Se.RIGHT]=n},Re.prototype.get=function(t){return t1},Re.prototype.isAnyNull=function(){for(var t=0;tthis._maxNodeDegree&&(this._maxNodeDegree=e),t=this.getNext(t)}while(t!==this._startDe);this._maxNodeDegree*=2},De.prototype.addPoints=function(t,e,n){var i=t.getCoordinates();if(e){var r=1;n&&(r=0);for(var o=r;o=0;a--)this._pts.add(i[a])}},De.prototype.isHole=function(){return this._isHole},De.prototype.setInResult=function(){var t=this._startDe;do{t.getEdge().setInResult(!0),t=t.getNext()}while(t!==this._startDe)},De.prototype.containsPoint=function(t){var e=this.getLinearRing();if(!e.getEnvelopeInternal().contains(t))return!1;if(!at.isPointInRing(t,e.getCoordinates()))return!1;for(var n=this._holes.iterator();n.hasNext();){if(n.next().containsPoint(t))return!1}return!0},De.prototype.addHole=function(t){this._holes.add(t)},De.prototype.isShell=function(){return null===this._shell},De.prototype.getLabel=function(){return this._label},De.prototype.getEdges=function(){return this._edges},De.prototype.getMaxNodeDegree=function(){return this._maxNodeDegree<0&&this.computeMaxNodeDegree(),this._maxNodeDegree},De.prototype.getShell=function(){return this._shell},De.prototype.mergeLabel=function(){if(1===arguments.length){var t=arguments[0];this.mergeLabel(t,0),this.mergeLabel(t,1)}else if(2===arguments.length){var e=arguments[0],n=arguments[1],i=e.getLocation(n,Se.RIGHT);if(i===w.NONE)return null;if(this._label.getLocation(n)===w.NONE)return this._label.setLocation(n,i),null}},De.prototype.setShell=function(t){this._shell=t,null!==t&&t.addHole(this)},De.prototype.toPolygon=function(t){for(var e=new Array(this._holes.size()).fill(null),n=0;n=2,"found partial label"),this.computeIM(t)},Fe.prototype.isInResult=function(){return this._isInResult},Fe.prototype.isVisited=function(){return this._isVisited},Fe.prototype.interfaces_=function(){return[]},Fe.prototype.getClass=function(){return Fe};var Ge=function(t){function e(){t.call(this),this._coord=null,this._edges=null;var e=arguments[0],n=arguments[1];this._coord=e,this._edges=n,this._label=new Pe(0,w.NONE)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.isIncidentEdgeInResult=function(){for(var t=this.getEdges().getEdges().iterator();t.hasNext();){if(t.next().getEdge().isInResult())return!0}return!1},e.prototype.isIsolated=function(){return 1===this._label.getGeometryCount()},e.prototype.getCoordinate=function(){return this._coord},e.prototype.print=function(t){t.println("node "+this._coord+" lbl: "+this._label)},e.prototype.computeIM=function(t){},e.prototype.computeMergedLocation=function(t,e){var n=w.NONE;if(n=this._label.getLocation(e),!t.isNull(e)){var i=t.getLocation(e);n!==w.BOUNDARY&&(n=i)}return n},e.prototype.setLabel=function(){if(2!==arguments.length)return t.prototype.setLabel.apply(this,arguments);var e=arguments[0],n=arguments[1];null===this._label?this._label=new Pe(e,n):this._label.setLocation(e,n)},e.prototype.getEdges=function(){return this._edges},e.prototype.mergeLabel=function(){if(arguments[0]instanceof e){var t=arguments[0];this.mergeLabel(t._label)}else if(arguments[0]instanceof Pe)for(var n=arguments[0],i=0;i<2;i++){var r=this.computeMergedLocation(n,i);this._label.getLocation(i)===w.NONE&&this._label.setLocation(i,r)}},e.prototype.add=function(t){this._edges.insert(t),t.setNode(this)},e.prototype.setLabelBoundary=function(t){if(null===this._label)return null;var e=w.NONE;null!==this._label&&(e=this._label.getLocation(t));var n=null;switch(e){case w.BOUNDARY:n=w.INTERIOR;break;case w.INTERIOR:default:n=w.BOUNDARY}this._label.setLocation(t,n)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Fe),qe=function(){this.nodeMap=new p,this.nodeFact=null;var t=arguments[0];this.nodeFact=t};qe.prototype.find=function(t){return this.nodeMap.get(t)},qe.prototype.addNode=function(){if(arguments[0]instanceof C){var t=arguments[0],e=this.nodeMap.get(t);return null===e&&(e=this.nodeFact.createNode(t),this.nodeMap.put(t,e)),e}if(arguments[0]instanceof Ge){var n=arguments[0],i=this.nodeMap.get(n.getCoordinate());return null===i?(this.nodeMap.put(n.getCoordinate(),n),n):(i.mergeLabel(n),i)}},qe.prototype.print=function(t){for(var e=this.iterator();e.hasNext();){e.next().print(t)}},qe.prototype.iterator=function(){return this.nodeMap.values().iterator()},qe.prototype.values=function(){return this.nodeMap.values()},qe.prototype.getBoundaryNodes=function(t){for(var e=new Nt,n=this.iterator();n.hasNext();){var i=n.next();i.getLabel().getLocation(t)===w.BOUNDARY&&e.add(i)}return e},qe.prototype.add=function(t){var e=t.getCoordinate();this.addNode(e).add(t)},qe.prototype.interfaces_=function(){return[]},qe.prototype.getClass=function(){return qe};var Be=function(){},Ve={NE:{configurable:!0},NW:{configurable:!0},SW:{configurable:!0},SE:{configurable:!0}};Be.prototype.interfaces_=function(){return[]},Be.prototype.getClass=function(){return Be},Be.isNorthern=function(t){return t===Be.NE||t===Be.NW},Be.isOpposite=function(t,e){if(t===e)return!1;return 2===(t-e+4)%4},Be.commonHalfPlane=function(t,e){if(t===e)return t;if(2===(t-e+4)%4)return-1;var n=te?t:e)?3:n},Be.isInHalfPlane=function(t,e){return e===Be.SE?t===Be.SE||t===Be.SW:t===e||t===e+1},Be.quadrant=function(){if("number"==typeof arguments[0]&&"number"==typeof arguments[1]){var t=arguments[0],e=arguments[1];if(0===t&&0===e)throw new m("Cannot compute the quadrant for point ( "+t+", "+e+" )");return t>=0?e>=0?Be.NE:Be.SE:e>=0?Be.NW:Be.SW}if(arguments[0]instanceof C&&arguments[1]instanceof C){var n=arguments[0],i=arguments[1];if(i.x===n.x&&i.y===n.y)throw new m("Cannot compute the quadrant for two identical points "+n);return i.x>=n.x?i.y>=n.y?Be.NE:Be.SE:i.y>=n.y?Be.NW:Be.SW}},Ve.NE.get=function(){return 0},Ve.NW.get=function(){return 1},Ve.SW.get=function(){return 2},Ve.SE.get=function(){return 3},Object.defineProperties(Be,Ve);var Ue=function(){if(this._edge=null,this._label=null,this._node=null,this._p0=null,this._p1=null,this._dx=null,this._dy=null,this._quadrant=null,1===arguments.length){var t=arguments[0];this._edge=t}else if(3===arguments.length){var e=arguments[0],n=arguments[1],i=arguments[2];this._edge=e,this.init(n,i),this._label=null}else if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3];this._edge=r,this.init(o,s),this._label=a}};Ue.prototype.compareDirection=function(t){return this._dx===t._dx&&this._dy===t._dy?0:this._quadrant>t._quadrant?1:this._quadrant2){o.linkDirectedEdgesForMinimalEdgeRings();var s=o.buildMinimalRings(),a=this.findShell(s);null!==a?(this.placePolygonHoles(a,s),e.add(a)):n.addAll(s)}else i.add(o)}return i},ke.prototype.containsPoint=function(t){for(var e=this._shellList.iterator();e.hasNext();){if(e.next().containsPoint(t))return!0}return!1},ke.prototype.buildMaximalEdgeRings=function(t){for(var e=new Nt,n=t.iterator();n.hasNext();){var i=n.next();if(i.isInResult()&&i.getLabel().isArea()&&null===i.getEdgeRing()){var r=new Ae(i,this._geometryFactory);e.add(r),r.setInResult()}}return e},ke.prototype.placePolygonHoles=function(t,e){for(var n=e.iterator();n.hasNext();){var i=n.next();i.isHole()&&i.setShell(t)}},ke.prototype.getPolygons=function(){return this.computePolygons(this._shellList)},ke.prototype.findEdgeRingContaining=function(t,e){for(var n=t.getLinearRing(),i=n.getEnvelopeInternal(),r=n.getCoordinateN(0),o=null,s=null,a=e.iterator();a.hasNext();){var u=a.next(),l=u.getLinearRing(),c=l.getEnvelopeInternal();null!==o&&(s=o.getLinearRing().getEnvelopeInternal());var p=!1;c.contains(i)&&at.isPointInRing(r,l.getCoordinates())&&(p=!0),p&&(null===o||s.contains(c))&&(o=u)}return o},ke.prototype.findShell=function(t){for(var e=0,n=null,i=t.iterator();i.hasNext();){var r=i.next();r.isHole()||(n=r,e++)}return et.isTrue(e<=1,"found two shells in MinimalEdgeRing list"),n},ke.prototype.add=function(){if(1===arguments.length){var t=arguments[0];this.add(t.getEdgeEnds(),t.getNodes())}else if(2===arguments.length){var e=arguments[0],n=arguments[1];Ye.linkResultDirectedEdges(n);var i=this.buildMaximalEdgeRings(e),r=new Nt,o=this.buildMinimalEdgeRings(i,this._shellList,r);this.sortShellsAndHoles(o,this._shellList,r),this.placeFreeHoles(this._shellList,r)}},ke.prototype.interfaces_=function(){return[]},ke.prototype.getClass=function(){return ke};var je=function(){};je.prototype.getBounds=function(){},je.prototype.interfaces_=function(){return[]},je.prototype.getClass=function(){return je};var He=function(){this._bounds=null,this._item=null;var t=arguments[0],e=arguments[1];this._bounds=t,this._item=e};He.prototype.getItem=function(){return this._item},He.prototype.getBounds=function(){return this._bounds},He.prototype.interfaces_=function(){return[je,e]},He.prototype.getClass=function(){return He};var We=function(){this._size=null,this._items=null,this._size=0,this._items=new Nt,this._items.add(null)};We.prototype.poll=function(){if(this.isEmpty())return null;var t=this._items.get(1);return this._items.set(1,this._items.get(this._size)),this._size-=1,this.reorder(1),t},We.prototype.size=function(){return this._size},We.prototype.reorder=function(t){for(var e=null,n=this._items.get(t);2*t<=this._size&&((e=2*t)!==this._size&&this._items.get(e+1).compareTo(this._items.get(e))<0&&e++,this._items.get(e).compareTo(n)<0);t=e)this._items.set(t,this._items.get(e));this._items.set(t,n)},We.prototype.clear=function(){this._size=0,this._items.clear()},We.prototype.isEmpty=function(){return 0===this._size},We.prototype.add=function(t){this._items.add(null),this._size+=1;var e=this._size;for(this._items.set(0,t);t.compareTo(this._items.get(Math.trunc(e/2)))<0;e/=2)this._items.set(e,this._items.get(Math.trunc(e/2)));this._items.set(e,t)},We.prototype.interfaces_=function(){return[]},We.prototype.getClass=function(){return We};var Ke=function(){};Ke.prototype.visitItem=function(t){},Ke.prototype.interfaces_=function(){return[]},Ke.prototype.getClass=function(){return Ke};var Je=function(){};Je.prototype.insert=function(t,e){},Je.prototype.remove=function(t,e){},Je.prototype.query=function(){},Je.prototype.interfaces_=function(){return[]},Je.prototype.getClass=function(){return Je};var Qe=function(){if(this._childBoundables=new Nt,this._bounds=null,this._level=null,0===arguments.length);else if(1===arguments.length){var t=arguments[0];this._level=t}},Ze={serialVersionUID:{configurable:!0}};Qe.prototype.getLevel=function(){return this._level},Qe.prototype.size=function(){return this._childBoundables.size()},Qe.prototype.getChildBoundables=function(){return this._childBoundables},Qe.prototype.addChildBoundable=function(t){et.isTrue(null===this._bounds),this._childBoundables.add(t)},Qe.prototype.isEmpty=function(){return this._childBoundables.isEmpty()},Qe.prototype.getBounds=function(){return null===this._bounds&&(this._bounds=this.computeBounds()),this._bounds},Qe.prototype.interfaces_=function(){return[je,e]},Qe.prototype.getClass=function(){return Qe},Ze.serialVersionUID.get=function(){return 0x5a1e55ec41369800},Object.defineProperties(Qe,Ze);var $e=function(){};$e.reverseOrder=function(){return{compare:function(t,e){return e.compareTo(t)}}},$e.min=function(t){return $e.sort(t),t.get(0)},$e.sort=function(t,e){var n=t.toArray();e?Gt.sort(n,e):Gt.sort(n);for(var i=t.iterator(),r=0,o=n.length;rtn.area(this._boundable2)?(this.expand(this._boundable1,this._boundable2,t,e),null):(this.expand(this._boundable2,this._boundable1,t,e),null);if(n)return this.expand(this._boundable1,this._boundable2,t,e),null;if(i)return this.expand(this._boundable2,this._boundable1,t,e),null;throw new m("neither boundable is composite")},tn.prototype.isLeaves=function(){return!(tn.isComposite(this._boundable1)||tn.isComposite(this._boundable2))},tn.prototype.compareTo=function(t){var e=t;return this._distancee._distance?1:0},tn.prototype.expand=function(t,e,n,i){for(var r=t.getChildBoundables().iterator();r.hasNext();){var o=r.next(),s=new tn(o,e,this._itemDistance);s.getDistance()1,"Node capacity must be greater than 1"),this._nodeCapacity=n}},nn={IntersectsOp:{configurable:!0},serialVersionUID:{configurable:!0},DEFAULT_NODE_CAPACITY:{configurable:!0}};en.prototype.getNodeCapacity=function(){return this._nodeCapacity},en.prototype.lastNode=function(t){return t.get(t.size()-1)},en.prototype.size=function(){if(0===arguments.length)return this.isEmpty()?0:(this.build(),this.size(this._root));if(1===arguments.length){for(var t=0,e=arguments[0].getChildBoundables().iterator();e.hasNext();){var n=e.next();n instanceof Qe?t+=this.size(n):n instanceof He&&(t+=1)}return t}},en.prototype.removeItem=function(t,e){for(var n=null,i=t.getChildBoundables().iterator();i.hasNext();){var r=i.next();r instanceof He&&r.getItem()===e&&(n=r)}return null!==n&&(t.getChildBoundables().remove(n),!0)},en.prototype.itemsTree=function(){if(0===arguments.length){this.build();var t=this.itemsTree(this._root);return null===t?new Nt:t}if(1===arguments.length){for(var e=arguments[0],n=new Nt,i=e.getChildBoundables().iterator();i.hasNext();){var r=i.next();if(r instanceof Qe){var o=this.itemsTree(r);null!==o&&n.add(o)}else r instanceof He?n.add(r.getItem()):et.shouldNeverReachHere()}return n.size()<=0?null:n}},en.prototype.insert=function(t,e){et.isTrue(!this._built,"Cannot insert items into an STR packed R-tree after it has been built."),this._itemBoundables.add(new He(t,e))},en.prototype.boundablesAtLevel=function(){if(1===arguments.length){var t=arguments[0],e=new Nt;return this.boundablesAtLevel(t,this._root,e),e}if(3===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[2];if(et.isTrue(n>-2),i.getLevel()===n)return r.add(i),null;for(var o=i.getChildBoundables().iterator();o.hasNext();){var s=o.next();s instanceof Qe?this.boundablesAtLevel(n,s,r):(et.isTrue(s instanceof He),-1===n&&r.add(s))}return null}},en.prototype.query=function(){if(1===arguments.length){var t=arguments[0];this.build();var e=new Nt;return this.isEmpty()?e:(this.getIntersectsOp().intersects(this._root.getBounds(),t)&&this.query(t,this._root,e),e)}if(2===arguments.length){var n=arguments[0],i=arguments[1];if(this.build(),this.isEmpty())return null;this.getIntersectsOp().intersects(this._root.getBounds(),n)&&this.query(n,this._root,i)}else if(3===arguments.length)if(T(arguments[2],Ke)&&arguments[0]instanceof Object&&arguments[1]instanceof Qe)for(var r=arguments[0],o=arguments[1],s=arguments[2],a=o.getChildBoundables(),u=0;ut&&(t=i)}}return t+1}},en.prototype.createParentBoundables=function(t,e){et.isTrue(!t.isEmpty());var n=new Nt;n.add(this.createNode(e));var i=new Nt(t);$e.sort(i,this.getComparator());for(var r=i.iterator();r.hasNext();){var o=r.next();this.lastNode(n).getChildBoundables().size()===this.getNodeCapacity()&&n.add(this.createNode(e)),this.lastNode(n).addChildBoundable(o)}return n},en.prototype.isEmpty=function(){return this._built?this._root.isEmpty():this._itemBoundables.isEmpty()},en.prototype.interfaces_=function(){return[e]},en.prototype.getClass=function(){return en},en.compareDoubles=function(t,e){return t>e?1:t0);for(var n=new Nt,i=0;i0;){var p=c.poll(),h=p.getDistance();if(h>=u)break;p.isLeaves()?(u=h,l=p):p.expandToQueue(c,u)}return[l.getBoundable(0).getItem(),l.getBoundable(1).getItem()]}}else if(3===arguments.length){var f=arguments[0],g=arguments[1],d=arguments[2],y=new He(f,g),_=new tn(this.getRoot(),y,d);return this.nearestNeighbour(_)[0]}},n.prototype.interfaces_=function(){return[Je,e]},n.prototype.getClass=function(){return n},n.centreX=function(t){return n.avg(t.getMinX(),t.getMaxX())},n.avg=function(t,e){return(t+e)/2},n.centreY=function(t){return n.avg(t.getMinY(),t.getMaxY())},i.STRtreeNode.get=function(){return an},i.serialVersionUID.get=function(){return 0x39920f7d5f261e0},i.xComparator.get=function(){return{interfaces_:function(){return[N]},compare:function(e,i){return t.compareDoubles(n.centreX(e.getBounds()),n.centreX(i.getBounds()))}}},i.yComparator.get=function(){return{interfaces_:function(){return[N]},compare:function(e,i){return t.compareDoubles(n.centreY(e.getBounds()),n.centreY(i.getBounds()))}}},i.intersectsOp.get=function(){return{interfaces_:function(){return[t.IntersectsOp]},intersects:function(t,e){return t.intersects(e)}}},i.DEFAULT_NODE_CAPACITY.get=function(){return 10},Object.defineProperties(n,i),n}(en),an=function(t){function e(){var e=arguments[0];t.call(this,e)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.computeBounds=function(){for(var t=null,e=this.getChildBoundables().iterator();e.hasNext();){var n=e.next();null===t?t=new j(n.getBounds()):t.expandToInclude(n.getBounds())}return t},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Qe),un=function(){};un.prototype.interfaces_=function(){return[]},un.prototype.getClass=function(){return un},un.relativeSign=function(t,e){return te?1:0},un.compare=function(t,e,n){if(e.equals2D(n))return 0;var i=un.relativeSign(e.x,n.x),r=un.relativeSign(e.y,n.y);switch(t){case 0:return un.compareValue(i,r);case 1:return un.compareValue(r,i);case 2:return un.compareValue(r,-i);case 3:return un.compareValue(-i,r);case 4:return un.compareValue(-i,-r);case 5:return un.compareValue(-r,-i);case 6:return un.compareValue(-r,i);case 7:return un.compareValue(i,-r)}return et.shouldNeverReachHere("invalid octant value"),0},un.compareValue=function(t,e){return t<0?-1:t>0?1:e<0?-1:e>0?1:0};var ln=function(){this._segString=null,this.coord=null,this.segmentIndex=null,this._segmentOctant=null,this._isInterior=null;var t=arguments[0],e=arguments[1],n=arguments[2],i=arguments[3];this._segString=t,this.coord=new C(e),this.segmentIndex=n,this._segmentOctant=i,this._isInterior=!e.equals2D(t.getCoordinate(n))};ln.prototype.getCoordinate=function(){return this.coord},ln.prototype.print=function(t){t.print(this.coord),t.print(" seg # = "+this.segmentIndex)},ln.prototype.compareTo=function(t){var e=t;return this.segmentIndexe.segmentIndex?1:this.coord.equals2D(e.coord)?0:un.compare(this._segmentOctant,this.coord,e.coord)},ln.prototype.isEndPoint=function(t){return 0===this.segmentIndex&&!this._isInterior||this.segmentIndex===t},ln.prototype.isInterior=function(){return this._isInterior},ln.prototype.interfaces_=function(){return[E]},ln.prototype.getClass=function(){return ln};var cn=function(){this._nodeMap=new p,this._edge=null;var t=arguments[0];this._edge=t};cn.prototype.getSplitCoordinates=function(){var t=new St;this.addEndpoints();for(var e=this.iterator(),n=e.next();e.hasNext();){var i=e.next();this.addEdgeCoordinates(n,i,t),n=i}return t.toCoordinateArray()},cn.prototype.addCollapsedNodes=function(){var t=new Nt;this.findCollapsesFromInsertedNodes(t),this.findCollapsesFromExistingVertices(t);for(var e=t.iterator();e.hasNext();){var n=e.next().intValue();this.add(this._edge.getCoordinate(n),n)}},cn.prototype.print=function(t){t.println("Intersections:");for(var e=this.iterator();e.hasNext();){e.next().print(t)}},cn.prototype.findCollapsesFromExistingVertices=function(t){for(var e=0;e=0?e>=0?n>=i?0:1:n>=i?7:6:e>=0?n>=i?3:2:n>=i?4:5}if(arguments[0]instanceof C&&arguments[1]instanceof C){var r=arguments[0],o=arguments[1],s=o.x-r.x,a=o.y-r.y;if(0===s&&0===a)throw new m("Cannot compute the octant for two identical points "+r);return pn.octant(s,a)}};var hn=function(){};hn.prototype.getCoordinates=function(){},hn.prototype.size=function(){},hn.prototype.getCoordinate=function(t){},hn.prototype.isClosed=function(){},hn.prototype.setData=function(t){},hn.prototype.getData=function(){},hn.prototype.interfaces_=function(){return[]},hn.prototype.getClass=function(){return hn};var fn=function(){};fn.prototype.addIntersection=function(t,e){},fn.prototype.interfaces_=function(){return[hn]},fn.prototype.getClass=function(){return fn};var gn=function(){this._nodeList=new cn(this),this._pts=null,this._data=null;var t=arguments[0],e=arguments[1];this._pts=t,this._data=e};gn.prototype.getCoordinates=function(){return this._pts},gn.prototype.size=function(){return this._pts.length},gn.prototype.getCoordinate=function(t){return this._pts[t]},gn.prototype.isClosed=function(){return this._pts[0].equals(this._pts[this._pts.length-1])},gn.prototype.getSegmentOctant=function(t){return t===this._pts.length-1?-1:this.safeOctant(this.getCoordinate(t),this.getCoordinate(t+1))},gn.prototype.setData=function(t){this._data=t},gn.prototype.safeOctant=function(t,e){return t.equals2D(e)?0:pn.octant(t,e)},gn.prototype.getData=function(){return this._data},gn.prototype.addIntersection=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];this.addIntersectionNode(t,e)}else if(4===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[3],o=new C(n.getIntersection(r));this.addIntersection(o,i)}},gn.prototype.toString=function(){return Z.toLineString(new ue(this._pts))},gn.prototype.getNodeList=function(){return this._nodeList},gn.prototype.addIntersectionNode=function(t,e){var n=e,i=n+1;if(i=0&&n>=0?Math.max(e,n):e<=0&&n<=0?Math.max(e,n):0}if(arguments[0]instanceof C){var i=arguments[0];return at.orientationIndex(this.p0,this.p1,i)}},dn.prototype.toGeometry=function(t){return t.createLineString([this.p0,this.p1])},dn.prototype.isVertical=function(){return this.p0.x===this.p1.x},dn.prototype.equals=function(t){if(!(t instanceof dn))return!1;var e=t;return this.p0.equals(e.p0)&&this.p1.equals(e.p1)},dn.prototype.intersection=function(t){var e=new rt;return e.computeIntersection(this.p0,this.p1,t.p0,t.p1),e.hasIntersection()?e.getIntersection(0):null},dn.prototype.project=function(){if(arguments[0]instanceof C){var t=arguments[0];if(t.equals(this.p0)||t.equals(this.p1))return new C(t);var e=this.projectionFactor(t),n=new C;return n.x=this.p0.x+e*(this.p1.x-this.p0.x),n.y=this.p0.y+e*(this.p1.y-this.p0.y),n}if(arguments[0]instanceof dn){var i=arguments[0],r=this.projectionFactor(i.p0),o=this.projectionFactor(i.p1);if(r>=1&&o>=1)return null;if(r<=0&&o<=0)return null;var s=this.project(i.p0);r<0&&(s=this.p0),r>1&&(s=this.p1);var a=this.project(i.p1);return o<0&&(a=this.p0),o>1&&(a=this.p1),new dn(s,a)}},dn.prototype.normalize=function(){this.p1.compareTo(this.p0)<0&&this.reverse()},dn.prototype.angle=function(){return Math.atan2(this.p1.y-this.p0.y,this.p1.x-this.p0.x)},dn.prototype.getCoordinate=function(t){return 0===t?this.p0:this.p1},dn.prototype.distancePerpendicular=function(t){return at.distancePointLinePerpendicular(t,this.p0,this.p1)},dn.prototype.minY=function(){return Math.min(this.p0.y,this.p1.y)},dn.prototype.midPoint=function(){return dn.midPoint(this.p0,this.p1)},dn.prototype.projectionFactor=function(t){if(t.equals(this.p0))return 0;if(t.equals(this.p1))return 1;var e=this.p1.x-this.p0.x,n=this.p1.y-this.p0.y,i=e*e+n*n;if(i<=0)return v.NaN;return((t.x-this.p0.x)*e+(t.y-this.p0.y)*n)/i},dn.prototype.closestPoints=function(t){var e=this.intersection(t);if(null!==e)return[e,e];var n=new Array(2).fill(null),i=v.MAX_VALUE,r=null,o=this.closestPoint(t.p0);i=o.distance(t.p0),n[0]=o,n[1]=t.p0;var s=this.closestPoint(t.p1);(r=s.distance(t.p1))0&&e<1)return this.project(t);return this.p0.distance(t)1||v.isNaN(e))&&(e=1),e},dn.prototype.toString=function(){return"LINESTRING( "+this.p0.x+" "+this.p0.y+", "+this.p1.x+" "+this.p1.y+")"},dn.prototype.isHorizontal=function(){return this.p0.y===this.p1.y},dn.prototype.distance=function(){if(arguments[0]instanceof dn){var t=arguments[0];return at.distanceLineLine(this.p0,this.p1,t.p0,t.p1)}if(arguments[0]instanceof C){var e=arguments[0];return at.distancePointLine(e,this.p0,this.p1)}},dn.prototype.pointAlong=function(t){var e=new C;return e.x=this.p0.x+t*(this.p1.x-this.p0.x),e.y=this.p0.y+t*(this.p1.y-this.p0.y),e},dn.prototype.hashCode=function(){var t=v.doubleToLongBits(this.p0.x);t^=31*v.doubleToLongBits(this.p0.y);var e=Math.trunc(t)^Math.trunc(t>>32),n=v.doubleToLongBits(this.p1.x);n^=31*v.doubleToLongBits(this.p1.y);return e^(Math.trunc(n)^Math.trunc(n>>32))},dn.prototype.interfaces_=function(){return[E,e]},dn.prototype.getClass=function(){return dn},dn.midPoint=function(t,e){return new C((t.x+e.x)/2,(t.y+e.y)/2)},yn.serialVersionUID.get=function(){return 0x2d2172135f411c00},Object.defineProperties(dn,yn);var _n=function(){this.tempEnv1=new j,this.tempEnv2=new j,this._overlapSeg1=new dn,this._overlapSeg2=new dn};_n.prototype.overlap=function(){if(2===arguments.length);else if(4===arguments.length){var t=arguments[0],e=arguments[1],n=arguments[2],i=arguments[3];t.getLineSegment(e,this._overlapSeg1),n.getLineSegment(i,this._overlapSeg2),this.overlap(this._overlapSeg1,this._overlapSeg2)}},_n.prototype.interfaces_=function(){return[]},_n.prototype.getClass=function(){return _n};var mn=function(){this._pts=null,this._start=null,this._end=null,this._env=null,this._context=null,this._id=null;var t=arguments[0],e=arguments[1],n=arguments[2],i=arguments[3];this._pts=t,this._start=e,this._end=n,this._context=i};mn.prototype.getLineSegment=function(t,e){e.p0=this._pts[t],e.p1=this._pts[t+1]},mn.prototype.computeSelect=function(t,e,n,i){var r=this._pts[e],o=this._pts[n];if(i.tempEnv1.init(r,o),n-e==1)return i.select(this,e),null;if(!t.intersects(i.tempEnv1))return null;var s=Math.trunc((e+n)/2);e=t.length-1)return t.length-1;for(var i=Be.quadrant(t[n],t[n+1]),r=e+1;rn.getId()&&(n.computeOverlaps(r,t),this._nOverlaps++),this._segInt.isDone())return null}},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},n.SegmentOverlapAction.get=function(){return Nn},Object.defineProperties(e,n),e}(En),Nn=function(t){function e(){t.call(this),this._si=null;var e=arguments[0];this._si=e}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.overlap=function(){if(4!==arguments.length)return t.prototype.overlap.apply(this,arguments);var e=arguments[0],n=arguments[1],i=arguments[2],r=arguments[3],o=e.getContext(),s=i.getContext();this._si.processIntersections(o,n,s,r)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(_n),Cn=function t(){if(this._quadrantSegments=t.DEFAULT_QUADRANT_SEGMENTS,this._endCapStyle=t.CAP_ROUND,this._joinStyle=t.JOIN_ROUND,this._mitreLimit=t.DEFAULT_MITRE_LIMIT,this._isSingleSided=!1,this._simplifyFactor=t.DEFAULT_SIMPLIFY_FACTOR,0===arguments.length);else if(1===arguments.length){var e=arguments[0];this.setQuadrantSegments(e)}else if(2===arguments.length){var n=arguments[0],i=arguments[1];this.setQuadrantSegments(n),this.setEndCapStyle(i)}else if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3];this.setQuadrantSegments(r),this.setEndCapStyle(o),this.setJoinStyle(s),this.setMitreLimit(a)}},Sn={CAP_ROUND:{configurable:!0},CAP_FLAT:{configurable:!0},CAP_SQUARE:{configurable:!0},JOIN_ROUND:{configurable:!0},JOIN_MITRE:{configurable:!0},JOIN_BEVEL:{configurable:!0},DEFAULT_QUADRANT_SEGMENTS:{configurable:!0},DEFAULT_MITRE_LIMIT:{configurable:!0},DEFAULT_SIMPLIFY_FACTOR:{configurable:!0}};Cn.prototype.getEndCapStyle=function(){return this._endCapStyle},Cn.prototype.isSingleSided=function(){return this._isSingleSided},Cn.prototype.setQuadrantSegments=function(t){this._quadrantSegments=t,0===this._quadrantSegments&&(this._joinStyle=Cn.JOIN_BEVEL),this._quadrantSegments<0&&(this._joinStyle=Cn.JOIN_MITRE,this._mitreLimit=Math.abs(this._quadrantSegments)),t<=0&&(this._quadrantSegments=1),this._joinStyle!==Cn.JOIN_ROUND&&(this._quadrantSegments=Cn.DEFAULT_QUADRANT_SEGMENTS)},Cn.prototype.getJoinStyle=function(){return this._joinStyle},Cn.prototype.setJoinStyle=function(t){this._joinStyle=t},Cn.prototype.setSimplifyFactor=function(t){this._simplifyFactor=t<0?0:t},Cn.prototype.getSimplifyFactor=function(){return this._simplifyFactor},Cn.prototype.getQuadrantSegments=function(){return this._quadrantSegments},Cn.prototype.setEndCapStyle=function(t){this._endCapStyle=t},Cn.prototype.getMitreLimit=function(){return this._mitreLimit},Cn.prototype.setMitreLimit=function(t){this._mitreLimit=t},Cn.prototype.setSingleSided=function(t){this._isSingleSided=t},Cn.prototype.interfaces_=function(){return[]},Cn.prototype.getClass=function(){return Cn},Cn.bufferDistanceError=function(t){var e=Math.PI/2/t;return 1-Math.cos(e/2)},Sn.CAP_ROUND.get=function(){return 1},Sn.CAP_FLAT.get=function(){return 2},Sn.CAP_SQUARE.get=function(){return 3},Sn.JOIN_ROUND.get=function(){return 1},Sn.JOIN_MITRE.get=function(){return 2},Sn.JOIN_BEVEL.get=function(){return 3},Sn.DEFAULT_QUADRANT_SEGMENTS.get=function(){return 8},Sn.DEFAULT_MITRE_LIMIT.get=function(){return 5},Sn.DEFAULT_SIMPLIFY_FACTOR.get=function(){return.01},Object.defineProperties(Cn,Sn);var Ln=function(t){this._distanceTol=null,this._isDeleted=null,this._angleOrientation=at.COUNTERCLOCKWISE,this._inputLine=t||null},bn={INIT:{configurable:!0},DELETE:{configurable:!0},KEEP:{configurable:!0},NUM_PTS_TO_CHECK:{configurable:!0}};Ln.prototype.isDeletable=function(t,e,n,i){var r=this._inputLine[t],o=this._inputLine[e],s=this._inputLine[n];return!!this.isConcave(r,o,s)&&(!!this.isShallow(r,o,s,i)&&this.isShallowSampled(r,o,t,n,i))},Ln.prototype.deleteShallowConcavities=function(){for(var t=1,e=this.findNextNonDeletedIndex(t),n=this.findNextNonDeletedIndex(e),i=!1;n=0;i--)this.addPt(t[i])},wn.prototype.isRedundant=function(t){if(this._ptList.size()<1)return!1;var e=this._ptList.get(this._ptList.size()-1);return t.distance(e)Math.PI;)t-=Tn.PI_TIMES_2;for(;t<=-Math.PI;)t+=Tn.PI_TIMES_2;return t},Tn.angle=function(){if(1===arguments.length){var t=arguments[0];return Math.atan2(t.y,t.x)}if(2===arguments.length){var e=arguments[0],n=arguments[1],i=n.x-e.x,r=n.y-e.y;return Math.atan2(r,i)}},Tn.isAcute=function(t,e,n){var i=t.x-e.x,r=t.y-e.y;return i*(n.x-e.x)+r*(n.y-e.y)>0},Tn.isObtuse=function(t,e,n){var i=t.x-e.x,r=t.y-e.y;return i*(n.x-e.x)+r*(n.y-e.y)<0},Tn.interiorAngle=function(t,e,n){var i=Tn.angle(e,t),r=Tn.angle(e,n);return Math.abs(r-i)},Tn.normalizePositive=function(t){if(t<0){for(;t<0;)t+=Tn.PI_TIMES_2;t>=Tn.PI_TIMES_2&&(t=0)}else{for(;t>=Tn.PI_TIMES_2;)t-=Tn.PI_TIMES_2;t<0&&(t=0)}return t},Tn.angleBetween=function(t,e,n){var i=Tn.angle(e,t),r=Tn.angle(e,n);return Tn.diff(i,r)},Tn.diff=function(t,e){var n=null;return(n=tMath.PI&&(n=2*Math.PI-n),n},Tn.toRadians=function(t){return t*Math.PI/180},Tn.getTurn=function(t,e){var n=Math.sin(e-t);return n>0?Tn.COUNTERCLOCKWISE:n<0?Tn.CLOCKWISE:Tn.NONE},Tn.angleBetweenOriented=function(t,e,n){var i=Tn.angle(e,t),r=Tn.angle(e,n)-i;return r<=-Math.PI?r+Tn.PI_TIMES_2:r>Math.PI?r-Tn.PI_TIMES_2:r},Rn.PI_TIMES_2.get=function(){return 2*Math.PI},Rn.PI_OVER_2.get=function(){return Math.PI/2},Rn.PI_OVER_4.get=function(){return Math.PI/4},Rn.COUNTERCLOCKWISE.get=function(){return at.COUNTERCLOCKWISE},Rn.CLOCKWISE.get=function(){return at.CLOCKWISE},Rn.NONE.get=function(){return at.COLLINEAR},Object.defineProperties(Tn,Rn);var Pn=function t(){this._maxCurveSegmentError=0,this._filletAngleQuantum=null,this._closingSegLengthFactor=1,this._segList=null,this._distance=0,this._precisionModel=null,this._bufParams=null,this._li=null,this._s0=null,this._s1=null,this._s2=null,this._seg0=new dn,this._seg1=new dn,this._offset0=new dn,this._offset1=new dn,this._side=0,this._hasNarrowConcaveAngle=!1;var e=arguments[0],n=arguments[1],i=arguments[2];this._precisionModel=e,this._bufParams=n,this._li=new rt,this._filletAngleQuantum=Math.PI/2/n.getQuadrantSegments(),n.getQuadrantSegments()>=8&&n.getJoinStyle()===Cn.JOIN_ROUND&&(this._closingSegLengthFactor=t.MAX_CLOSING_SEG_LEN_FACTOR),this.init(i)},Dn={OFFSET_SEGMENT_SEPARATION_FACTOR:{configurable:!0},INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR:{configurable:!0},CURVE_VERTEX_SNAP_DISTANCE_FACTOR:{configurable:!0},MAX_CLOSING_SEG_LEN_FACTOR:{configurable:!0}};Pn.prototype.addNextSegment=function(t,e){if(this._s0=this._s1,this._s1=this._s2,this._s2=t,this._seg0.setCoordinates(this._s0,this._s1),this.computeOffsetSegment(this._seg0,this._side,this._distance,this._offset0),this._seg1.setCoordinates(this._s1,this._s2),this.computeOffsetSegment(this._seg1,this._side,this._distance,this._offset1),this._s1.equals(this._s2))return null;var n=at.computeOrientation(this._s0,this._s1,this._s2),i=n===at.CLOCKWISE&&this._side===Se.LEFT||n===at.COUNTERCLOCKWISE&&this._side===Se.RIGHT;0===n?this.addCollinear(e):i?this.addOutsideTurn(n,e):this.addInsideTurn(n,e)},Pn.prototype.addLineEndCap=function(t,e){var n=new dn(t,e),i=new dn;this.computeOffsetSegment(n,Se.LEFT,this._distance,i);var r=new dn;this.computeOffsetSegment(n,Se.RIGHT,this._distance,r);var o=e.x-t.x,s=e.y-t.y,a=Math.atan2(s,o);switch(this._bufParams.getEndCapStyle()){case Cn.CAP_ROUND:this._segList.addPt(i.p1),this.addFilletArc(e,a+Math.PI/2,a-Math.PI/2,at.CLOCKWISE,this._distance),this._segList.addPt(r.p1);break;case Cn.CAP_FLAT:this._segList.addPt(i.p1),this._segList.addPt(r.p1);break;case Cn.CAP_SQUARE:var u=new C;u.x=Math.abs(this._distance)*Math.cos(a),u.y=Math.abs(this._distance)*Math.sin(a);var l=new C(i.p1.x+u.x,i.p1.y+u.y),c=new C(r.p1.x+u.x,r.p1.y+u.y);this._segList.addPt(l),this._segList.addPt(c)}},Pn.prototype.getCoordinates=function(){return this._segList.getCoordinates()},Pn.prototype.addMitreJoin=function(t,e,n,i){var r=!0,o=null;try{o=k.intersection(e.p0,e.p1,n.p0,n.p1);(i<=0?1:o.distance(t)/Math.abs(i))>this._bufParams.getMitreLimit()&&(r=!1)}catch(t){if(!(t instanceof X))throw t;o=new C(0,0),r=!1}r?this._segList.addPt(o):this.addLimitedMitreJoin(e,n,i,this._bufParams.getMitreLimit())},Pn.prototype.addFilletCorner=function(t,e,n,i,r){var o=e.x-t.x,s=e.y-t.y,a=Math.atan2(s,o),u=n.x-t.x,l=n.y-t.y,c=Math.atan2(l,u);i===at.CLOCKWISE?a<=c&&(a+=2*Math.PI):a>=c&&(a-=2*Math.PI),this._segList.addPt(e),this.addFilletArc(t,a,c,i,r),this._segList.addPt(n)},Pn.prototype.addOutsideTurn=function(t,e){if(this._offset0.p1.distance(this._offset1.p0)0){var n=new C((this._closingSegLengthFactor*this._offset0.p1.x+this._s1.x)/(this._closingSegLengthFactor+1),(this._closingSegLengthFactor*this._offset0.p1.y+this._s1.y)/(this._closingSegLengthFactor+1));this._segList.addPt(n);var i=new C((this._closingSegLengthFactor*this._offset1.p0.x+this._s1.x)/(this._closingSegLengthFactor+1),(this._closingSegLengthFactor*this._offset1.p0.y+this._s1.y)/(this._closingSegLengthFactor+1));this._segList.addPt(i)}else this._segList.addPt(this._s1);this._segList.addPt(this._offset1.p0)}},Pn.prototype.createCircle=function(t){var e=new C(t.x+this._distance,t.y);this._segList.addPt(e),this.addFilletArc(t,0,2*Math.PI,-1,this._distance),this._segList.closeRing()},Pn.prototype.addBevelJoin=function(t,e){this._segList.addPt(t.p1),this._segList.addPt(e.p0)},Pn.prototype.init=function(t){this._distance=t,this._maxCurveSegmentError=t*(1-Math.cos(this._filletAngleQuantum/2)),this._segList=new wn,this._segList.setPrecisionModel(this._precisionModel),this._segList.setMinimumVertexDistance(t*Pn.CURVE_VERTEX_SNAP_DISTANCE_FACTOR)},Pn.prototype.addCollinear=function(t){this._li.computeIntersection(this._s0,this._s1,this._s1,this._s2);this._li.getIntersectionNum()>=2&&(this._bufParams.getJoinStyle()===Cn.JOIN_BEVEL||this._bufParams.getJoinStyle()===Cn.JOIN_MITRE?(t&&this._segList.addPt(this._offset0.p1),this._segList.addPt(this._offset1.p0)):this.addFilletCorner(this._s1,this._offset0.p1,this._offset1.p0,at.CLOCKWISE,this._distance))},Pn.prototype.closeRing=function(){this._segList.closeRing()},Pn.prototype.hasNarrowConcaveAngle=function(){return this._hasNarrowConcaveAngle},Pn.prototype.interfaces_=function(){return[]},Pn.prototype.getClass=function(){return Pn},Dn.OFFSET_SEGMENT_SEPARATION_FACTOR.get=function(){return.001},Dn.INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR.get=function(){return.001},Dn.CURVE_VERTEX_SNAP_DISTANCE_FACTOR.get=function(){return 1e-6},Dn.MAX_CLOSING_SEG_LEN_FACTOR.get=function(){return 80},Object.defineProperties(Pn,Dn);var Mn=function(){this._distance=0,this._precisionModel=null,this._bufParams=null;var t=arguments[0],e=arguments[1];this._precisionModel=t,this._bufParams=e};Mn.prototype.getOffsetCurve=function(t,e){if(this._distance=e,0===e)return null;var n=e<0,i=Math.abs(e),r=this.getSegGen(i);t.length<=1?this.computePointCurve(t[0],r):this.computeOffsetCurve(t,n,r);var o=r.getCoordinates();return n&&Lt.reverse(o),o},Mn.prototype.computeSingleSidedBufferCurve=function(t,e,n){var i=this.simplifyTolerance(this._distance);if(e){n.addSegments(t,!0);var r=Ln.simplify(t,-i),o=r.length-1;n.initSideSegments(r[o],r[o-1],Se.LEFT),n.addFirstSegment();for(var s=o-2;s>=0;s--)n.addNextSegment(r[s],!0)}else{n.addSegments(t,!1);var a=Ln.simplify(t,i),u=a.length-1;n.initSideSegments(a[0],a[1],Se.LEFT),n.addFirstSegment();for(var l=2;l<=u;l++)n.addNextSegment(a[l],!0)}n.addLastSegment(),n.closeRing()},Mn.prototype.computeRingBufferCurve=function(t,e,n){var i=this.simplifyTolerance(this._distance);e===Se.RIGHT&&(i=-i);var r=Ln.simplify(t,i),o=r.length-1;n.initSideSegments(r[o-1],r[0],e);for(var s=1;s<=o;s++){var a=1!==s;n.addNextSegment(r[s],a)}n.closeRing()},Mn.prototype.computeLineBufferCurve=function(t,e){var n=this.simplifyTolerance(this._distance),i=Ln.simplify(t,n),r=i.length-1;e.initSideSegments(i[0],i[1],Se.LEFT);for(var o=2;o<=r;o++)e.addNextSegment(i[o],!0);e.addLastSegment(),e.addLineEndCap(i[r-1],i[r]);var s=Ln.simplify(t,-n),a=s.length-1;e.initSideSegments(s[a],s[a-1],Se.LEFT);for(var u=a-2;u>=0;u--)e.addNextSegment(s[u],!0);e.addLastSegment(),e.addLineEndCap(s[1],s[0]),e.closeRing()},Mn.prototype.computePointCurve=function(t,e){switch(this._bufParams.getEndCapStyle()){case Cn.CAP_ROUND:e.createCircle(t);break;case Cn.CAP_SQUARE:e.createSquare(t)}},Mn.prototype.getLineCurve=function(t,e){if(this._distance=e,e<0&&!this._bufParams.isSingleSided())return null;if(0===e)return null;var n=Math.abs(e),i=this.getSegGen(n);if(t.length<=1)this.computePointCurve(t[0],i);else if(this._bufParams.isSingleSided()){var r=e<0;this.computeSingleSidedBufferCurve(t,r,i)}else this.computeLineBufferCurve(t,i);return i.getCoordinates()},Mn.prototype.getBufferParameters=function(){return this._bufParams},Mn.prototype.simplifyTolerance=function(t){return t*this._bufParams.getSimplifyFactor()},Mn.prototype.getRingCurve=function(t,e,n){if(this._distance=n,t.length<=2)return this.getLineCurve(t,n);if(0===n)return Mn.copyCoordinates(t);var i=this.getSegGen(n);return this.computeRingBufferCurve(t,e,i),i.getCoordinates()},Mn.prototype.computeOffsetCurve=function(t,e,n){var i=this.simplifyTolerance(this._distance);if(e){var r=Ln.simplify(t,-i),o=r.length-1;n.initSideSegments(r[o],r[o-1],Se.LEFT),n.addFirstSegment();for(var s=o-2;s>=0;s--)n.addNextSegment(r[s],!0)}else{var a=Ln.simplify(t,i),u=a.length-1;n.initSideSegments(a[0],a[1],Se.LEFT),n.addFirstSegment();for(var l=2;l<=u;l++)n.addNextSegment(a[l],!0)}n.addLastSegment()},Mn.prototype.getSegGen=function(t){return new Pn(this._precisionModel,this._bufParams,t)},Mn.prototype.interfaces_=function(){return[]},Mn.prototype.getClass=function(){return Mn},Mn.copyCoordinates=function(t){for(var e=new Array(t.length).fill(null),n=0;nr.getMaxY()||this.findStabbedSegments(t,i.getDirectedEdges(),e)}return e}if(3===arguments.length)if(T(arguments[2],xt)&&arguments[0]instanceof C&&arguments[1]instanceof ze)for(var o=arguments[0],s=arguments[1],a=arguments[2],u=s.getEdge().getCoordinates(),l=0;lthis._seg.p1.y&&this._seg.reverse();if(!(Math.max(this._seg.p0.x,this._seg.p1.x)this._seg.p1.y||at.computeOrientation(this._seg.p0,this._seg.p1,o)===at.RIGHT)){var c=s.getDepth(Se.LEFT);this._seg.p0.equals(u[l])||(c=s.getDepth(Se.RIGHT));var p=new Gn(this._seg,c);a.add(p)}}else if(T(arguments[2],xt)&&arguments[0]instanceof C&&T(arguments[1],xt))for(var h=arguments[0],f=arguments[1],g=arguments[2],d=f.iterator();d.hasNext();){var y=d.next();y.isForward()&&this.findStabbedSegments(h,y,g)}},An.prototype.getDepth=function(t){var e=this.findStabbedSegments(t);if(0===e.size())return 0;return $e.min(e)._leftDepth},An.prototype.interfaces_=function(){return[]},An.prototype.getClass=function(){return An},Fn.DepthSegment.get=function(){return Gn},Object.defineProperties(An,Fn);var Gn=function(){this._upwardSeg=null,this._leftDepth=null;var t=arguments[0],e=arguments[1];this._upwardSeg=new dn(t),this._leftDepth=e};Gn.prototype.compareTo=function(t){var e=t;if(this._upwardSeg.minX()>=e._upwardSeg.maxX())return 1;if(this._upwardSeg.maxX()<=e._upwardSeg.minX())return-1;var n=this._upwardSeg.orientationIndex(e._upwardSeg);return 0!==n?n:0!=(n=-1*e._upwardSeg.orientationIndex(this._upwardSeg))?n:this._upwardSeg.compareTo(e._upwardSeg)},Gn.prototype.compareX=function(t,e){var n=t.p0.compareTo(e.p0);return 0!==n?n:t.p1.compareTo(e.p1)},Gn.prototype.toString=function(){return this._upwardSeg.toString()},Gn.prototype.interfaces_=function(){return[E]},Gn.prototype.getClass=function(){return Gn};var qn=function(t,e,n){this.p0=t||null,this.p1=e||null,this.p2=n||null};qn.prototype.area=function(){return qn.area(this.p0,this.p1,this.p2)},qn.prototype.signedArea=function(){return qn.signedArea(this.p0,this.p1,this.p2)},qn.prototype.interpolateZ=function(t){if(null===t)throw new m("Supplied point is null.");return qn.interpolateZ(t,this.p0,this.p1,this.p2)},qn.prototype.longestSideLength=function(){return qn.longestSideLength(this.p0,this.p1,this.p2)},qn.prototype.isAcute=function(){return qn.isAcute(this.p0,this.p1,this.p2)},qn.prototype.circumcentre=function(){return qn.circumcentre(this.p0,this.p1,this.p2)},qn.prototype.area3D=function(){return qn.area3D(this.p0,this.p1,this.p2)},qn.prototype.centroid=function(){return qn.centroid(this.p0,this.p1,this.p2)},qn.prototype.inCentre=function(){return qn.inCentre(this.p0,this.p1,this.p2)},qn.prototype.interfaces_=function(){return[]},qn.prototype.getClass=function(){return qn},qn.area=function(t,e,n){return Math.abs(((n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y))/2)},qn.signedArea=function(t,e,n){return((n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y))/2},qn.det=function(t,e,n,i){return t*i-e*n},qn.interpolateZ=function(t,e,n,i){var r=e.x,o=e.y,s=n.x-r,a=i.x-r,u=n.y-o,l=i.y-o,c=s*l-a*u,p=t.x-r,h=t.y-o,f=(l*p-a*h)/c,g=(-u*p+s*h)/c;return e.z+f*(n.z-e.z)+g*(i.z-e.z)},qn.longestSideLength=function(t,e,n){var i=t.distance(e),r=e.distance(n),o=n.distance(t),s=i;return r>s&&(s=r),o>s&&(s=o),s},qn.isAcute=function(t,e,n){return!!Tn.isAcute(t,e,n)&&(!!Tn.isAcute(e,n,t)&&!!Tn.isAcute(n,t,e))},qn.circumcentre=function(t,e,n){var i=n.x,r=n.y,o=t.x-i,s=t.y-r,a=e.x-i,u=e.y-r,l=2*qn.det(o,s,a,u),c=qn.det(s,o*o+s*s,u,a*a+u*u),p=qn.det(o,o*o+s*s,a,a*a+u*u);return new C(i-c/l,r+p/l)},qn.perpendicularBisector=function(t,e){var n=e.x-t.x,i=e.y-t.y,r=new k(t.x+n/2,t.y+i/2,1),o=new k(t.x-i+n/2,t.y+n+i/2,1);return new k(r,o)},qn.angleBisector=function(t,e,n){var i=e.distance(t),r=i/(i+e.distance(n)),o=n.x-t.x,s=n.y-t.y;return new C(t.x+r*o,t.y+r*s)},qn.area3D=function(t,e,n){var i=e.x-t.x,r=e.y-t.y,o=e.z-t.z,s=n.x-t.x,a=n.y-t.y,u=n.z-t.z,l=r*u-o*a,c=o*s-i*u,p=i*a-r*s,h=l*l+c*c+p*p,f=Math.sqrt(h)/2;return f},qn.centroid=function(t,e,n){var i=(t.x+e.x+n.x)/3,r=(t.y+e.y+n.y)/3;return new C(i,r)},qn.inCentre=function(t,e,n){var i=e.distance(n),r=t.distance(n),o=t.distance(e),s=i+r+o,a=(i*t.x+r*e.x+o*n.x)/s,u=(i*t.y+r*e.y+o*n.y)/s;return new C(a,u)};var Bn=function(){this._inputGeom=null,this._distance=null,this._curveBuilder=null,this._curveList=new Nt;var t=arguments[0],e=arguments[1],n=arguments[2];this._inputGeom=t,this._distance=e,this._curveBuilder=n};Bn.prototype.addPoint=function(t){if(this._distance<=0)return null;var e=t.getCoordinates(),n=this._curveBuilder.getLineCurve(e,this._distance);this.addCurve(n,w.EXTERIOR,w.INTERIOR)},Bn.prototype.addPolygon=function(t){var e=this._distance,n=Se.LEFT;this._distance<0&&(e=-this._distance,n=Se.RIGHT);var i=t.getExteriorRing(),r=Lt.removeRepeatedPoints(i.getCoordinates());if(this._distance<0&&this.isErodedCompletely(i,this._distance))return null;if(this._distance<=0&&r.length<3)return null;this.addPolygonRing(r,e,n,w.EXTERIOR,w.INTERIOR);for(var o=0;o0&&this.isErodedCompletely(s,-this._distance)||this.addPolygonRing(a,e,Se.opposite(n),w.INTERIOR,w.EXTERIOR)}},Bn.prototype.isTriangleErodedCompletely=function(t,e){var n=new qn(t[0],t[1],t[2]),i=n.inCentre();return at.distancePointLine(i,n.p0,n.p1)=ee.MINIMUM_VALID_SIZE&&at.isCCW(t)&&(o=r,s=i,n=Se.opposite(n));var a=this._curveBuilder.getRingCurve(t,n,e);this.addCurve(a,o,s)},Bn.prototype.add=function(t){if(t.isEmpty())return null;t instanceof $t?this.addPolygon(t):t instanceof Kt?this.addLineString(t):t instanceof Qt?this.addPoint(t):t instanceof te?this.addCollection(t):t instanceof Xt?this.addCollection(t):t instanceof ne?this.addCollection(t):t instanceof zt&&this.addCollection(t)},Bn.prototype.isErodedCompletely=function(t,e){var n=t.getCoordinates();if(n.length<4)return e<0;if(4===n.length)return this.isTriangleErodedCompletely(n,e);var i=t.getEnvelopeInternal(),r=Math.min(i.getHeight(),i.getWidth());return e<0&&2*Math.abs(e)>r},Bn.prototype.addCollection=function(t){for(var e=0;e=this._max)throw new i;var t=this._parent.getGeometryN(this._index++);return t instanceof zt?(this._subcollectionIterator=new Un(t),this._subcollectionIterator.next()):t},Un.prototype.remove=function(){throw new Error(this.getClass().getName())},Un.prototype.hasNext=function(){if(this._atStart)return!0;if(null!==this._subcollectionIterator){if(this._subcollectionIterator.hasNext())return!0;this._subcollectionIterator=null}return!(this._index>=this._max)},Un.prototype.interfaces_=function(){return[Et]},Un.prototype.getClass=function(){return Un},Un.isAtomic=function(t){return!(t instanceof zt)};var zn=function(){this._geom=null;var t=arguments[0];this._geom=t};zn.prototype.locate=function(t){return zn.locate(t,this._geom)},zn.prototype.interfaces_=function(){return[Vn]},zn.prototype.getClass=function(){return zn},zn.isPointInRing=function(t,e){return!!e.getEnvelopeInternal().intersects(t)&&at.isPointInRing(t,e.getCoordinates())},zn.containsPointInPolygon=function(t,e){if(e.isEmpty())return!1;var n=e.getExteriorRing();if(!zn.isPointInRing(t,n))return!1;for(var i=0;i=0;n--){var i=this._edgeList.get(n),r=i.getSym();null===e&&(e=r),null!==t&&r.setNext(t),t=i}e.setNext(t)},e.prototype.computeDepths=function(){if(1===arguments.length){var t=arguments[0],e=this.findIndex(t),n=t.getDepth(Se.LEFT),i=t.getDepth(Se.RIGHT),r=this.computeDepths(e+1,this._edgeList.size(),n);if(this.computeDepths(0,e,r)!==i)throw new we("depth mismatch at "+t.getCoordinate())}else if(3===arguments.length){for(var o=arguments[0],s=arguments[1],a=arguments[2],u=o;u=0;r--){var o=this._resultAreaEdgeList.get(r),s=o.getSym();switch(null===e&&o.getEdgeRing()===t&&(e=o),i){case this._SCANNING_FOR_INCOMING:if(s.getEdgeRing()!==t)continue;n=s,i=this._LINKING_TO_OUTGOING;break;case this._LINKING_TO_OUTGOING:if(o.getEdgeRing()!==t)continue;n.setNextMin(o),i=this._SCANNING_FOR_INCOMING}}i===this._LINKING_TO_OUTGOING&&(et.isTrue(null!==e,"found null for first outgoing dirEdge"),et.isTrue(e.getEdgeRing()===t,"unable to link last incoming dirEdge"),n.setNextMin(e))},e.prototype.getOutgoingDegree=function(){if(0===arguments.length){for(var t=0,e=this.iterator();e.hasNext();){e.next().isInResult()&&t++}return t}if(1===arguments.length){for(var n=arguments[0],i=0,r=this.iterator();r.hasNext();){r.next().getEdgeRing()===n&&i++}return i}},e.prototype.getLabel=function(){return this._label},e.prototype.findCoveredLineEdges=function(){for(var t=w.NONE,e=this.iterator();e.hasNext();){var n=e.next(),i=n.getSym();if(!n.isLineEdge()){if(n.isInResult()){t=w.INTERIOR;break}if(i.isInResult()){t=w.EXTERIOR;break}}}if(t===w.NONE)return null;for(var r=t,o=this.iterator();o.hasNext();){var s=o.next(),a=s.getSym();s.isLineEdge()?s.getEdge().setCovered(r===w.INTERIOR):(s.isInResult()&&(r=w.EXTERIOR),a.isInResult()&&(r=w.INTERIOR))}},e.prototype.computeLabelling=function(e){t.prototype.computeLabelling.call(this,e),this._label=new Pe(w.NONE);for(var n=this.iterator();n.hasNext();)for(var i=n.next().getEdge().getLabel(),r=0;r<2;r++){var o=i.getLocation(r);o!==w.INTERIOR&&o!==w.BOUNDARY||this._label.setLocation(r,w.INTERIOR)}},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Xn),kn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.createNode=function(t){return new Ge(t,new Yn)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Xe),jn=function t(){this._pts=null,this._orientation=null;var e=arguments[0];this._pts=e,this._orientation=t.orientation(e)};jn.prototype.compareTo=function(t){var e=t;return jn.compareOriented(this._pts,this._orientation,e._pts,e._orientation)},jn.prototype.interfaces_=function(){return[E]},jn.prototype.getClass=function(){return jn},jn.orientation=function(t){return 1===Lt.increasingDirection(t)},jn.compareOriented=function(t,e,n,i){for(var r=e?1:-1,o=i?1:-1,s=e?t.length:-1,a=i?n.length:-1,u=e?0:t.length-1,l=i?0:n.length-1;;){var c=t[u].compareTo(n[l]);if(0!==c)return c;var p=(u+=r)===s,h=(l+=o)===a;if(p&&!h)return-1;if(!p&&h)return 1;if(p&&h)return 0}};var Hn=function(){this._edges=new Nt,this._ocaMap=new p};Hn.prototype.print=function(t){t.print("MULTILINESTRING ( ");for(var e=0;e0&&t.print(","),t.print("(");for(var i=n.getCoordinates(),r=0;r0&&t.print(","),t.print(i[r].x+" "+i[r].y);t.println(")")}t.print(") ")},Hn.prototype.addAll=function(t){for(var e=t.iterator();e.hasNext();)this.add(e.next())},Hn.prototype.findEdgeIndex=function(t){for(var e=0;e0||!e.coord.equals2D(i);r||n--;var o=new Array(n).fill(null),s=0;o[s++]=new C(t.coord);for(var a=t.segmentIndex+1;a<=e.segmentIndex;a++)o[s++]=this.edge.pts[a];return r&&(o[s]=e.coord),new ni(o,new Pe(this.edge._label))},Qn.prototype.add=function(t,e,n){var i=new Jn(t,e,n),r=this._nodeMap.get(i);return null!==r?r:(this._nodeMap.put(i,i),i)},Qn.prototype.isIntersection=function(t){for(var e=this.iterator();e.hasNext();){if(e.next().coord.equals(t))return!0}return!1},Qn.prototype.interfaces_=function(){return[]},Qn.prototype.getClass=function(){return Qn};var Zn=function(){};Zn.prototype.getChainStartIndices=function(t){var e=0,n=new Nt;n.add(new M(e));do{var i=this.findChainEnd(t,e);n.add(new M(i)),e=i}while(en?e:n},$n.prototype.getMinX=function(t){var e=this.pts[this.startIndex[t]].x,n=this.pts[this.startIndex[t+1]].x;return ee&&(i=1),this._depth[t][n]=i}}},ti.prototype.getDelta=function(t){return this._depth[t][Se.RIGHT]-this._depth[t][Se.LEFT]},ti.prototype.getLocation=function(t,e){return this._depth[t][e]<=0?w.EXTERIOR:w.INTERIOR},ti.prototype.toString=function(){return"A: "+this._depth[0][1]+","+this._depth[0][2]+" B: "+this._depth[1][1]+","+this._depth[1][2]},ti.prototype.add=function(){if(1===arguments.length)for(var t=arguments[0],e=0;e<2;e++)for(var n=1;n<3;n++){var i=t.getLocation(e,n);i!==w.EXTERIOR&&i!==w.INTERIOR||(this.isNull(e,n)?this._depth[e][n]=ti.depthAtLocation(i):this._depth[e][n]+=ti.depthAtLocation(i))}else if(3===arguments.length){var r=arguments[0],o=arguments[1];arguments[2]===w.INTERIOR&&this._depth[r][o]++}},ti.prototype.interfaces_=function(){return[]},ti.prototype.getClass=function(){return ti},ti.depthAtLocation=function(t){return t===w.EXTERIOR?0:t===w.INTERIOR?1:ti.NULL_VALUE},ei.NULL_VALUE.get=function(){return-1},Object.defineProperties(ti,ei);var ni=function(t){function e(){if(t.call(this),this.pts=null,this._env=null,this.eiList=new Qn(this),this._name=null,this._mce=null,this._isIsolated=!0,this._depth=new ti,this._depthDelta=0,1===arguments.length){var n=arguments[0];e.call(this,n,null)}else if(2===arguments.length){var i=arguments[0],r=arguments[1];this.pts=i,this._label=r}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getDepth=function(){return this._depth},e.prototype.getCollapsedEdge=function(){var t=new Array(2).fill(null);t[0]=this.pts[0],t[1]=this.pts[1];return new e(t,Pe.toLineLabel(this._label))},e.prototype.isIsolated=function(){return this._isIsolated},e.prototype.getCoordinates=function(){return this.pts},e.prototype.setIsolated=function(t){this._isIsolated=t},e.prototype.setName=function(t){this._name=t},e.prototype.equals=function(t){if(!(t instanceof e))return!1;var n=t;if(this.pts.length!==n.pts.length)return!1;for(var i=!0,r=!0,o=this.pts.length,s=0;s0?this.pts[0]:null;if(1===arguments.length){var t=arguments[0];return this.pts[t]}},e.prototype.print=function(t){t.print("edge "+this._name+": "),t.print("LINESTRING (");for(var e=0;e0&&t.print(","),t.print(this.pts[e].x+" "+this.pts[e].y);t.print(") "+this._label+" "+this._depthDelta)},e.prototype.computeIM=function(t){e.updateIM(this._label,t)},e.prototype.isCollapsed=function(){return!!this._label.isArea()&&(3===this.pts.length&&!!this.pts[0].equals(this.pts[2]))},e.prototype.isClosed=function(){return this.pts[0].equals(this.pts[this.pts.length-1])},e.prototype.getMaximumSegmentIndex=function(){return this.pts.length-1},e.prototype.getDepthDelta=function(){return this._depthDelta},e.prototype.getNumPoints=function(){return this.pts.length},e.prototype.printReverse=function(t){t.print("edge "+this._name+": ");for(var e=this.pts.length-1;e>=0;e--)t.print(this.pts[e]+" ");t.println("")},e.prototype.getMonotoneChainEdge=function(){return null===this._mce&&(this._mce=new $n(this)),this._mce},e.prototype.getEnvelope=function(){if(null===this._env){this._env=new j;for(var t=0;t0&&t.append(","),t.append(this.pts[e].x+" "+this.pts[e].y);return t.append(") "+this._label+" "+this._depthDelta),t.toString()},e.prototype.isPointwiseEqual=function(t){if(this.pts.length!==t.pts.length)return!1;for(var e=0;ei||this._maxyo;if(s)return!1;var a=this.intersectsToleranceSquare(t,e);return et.isTrue(!(s&&a),"Found bad envelope test"),a},ai.prototype.initCorners=function(t){this._minx=t.x-.5,this._maxx=t.x+.5,this._miny=t.y-.5,this._maxy=t.y+.5,this._corner[0]=new C(this._maxx,this._maxy),this._corner[1]=new C(this._minx,this._maxy),this._corner[2]=new C(this._minx,this._miny),this._corner[3]=new C(this._maxx,this._miny)},ai.prototype.intersects=function(t,e){return 1===this._scaleFactor?this.intersectsScaled(t,e):(this.copyScaled(t,this._p0Scaled),this.copyScaled(e,this._p1Scaled),this.intersectsScaled(this._p0Scaled,this._p1Scaled))},ai.prototype.scale=function(t){return Math.round(t*this._scaleFactor)},ai.prototype.getCoordinate=function(){return this._originalPt},ai.prototype.copyScaled=function(t,e){e.x=this.scale(t.x),e.y=this.scale(t.y)},ai.prototype.getSafeEnvelope=function(){if(null===this._safeEnv){var t=ai.SAFE_ENV_EXPANSION_FACTOR/this._scaleFactor;this._safeEnv=new j(this._originalPt.x-t,this._originalPt.x+t,this._originalPt.y-t,this._originalPt.y+t)}return this._safeEnv},ai.prototype.intersectsPixelClosure=function(t,e){return this._li.computeIntersection(t,e,this._corner[0],this._corner[1]),!!this._li.hasIntersection()||(this._li.computeIntersection(t,e,this._corner[1],this._corner[2]),!!this._li.hasIntersection()||(this._li.computeIntersection(t,e,this._corner[2],this._corner[3]),!!this._li.hasIntersection()||(this._li.computeIntersection(t,e,this._corner[3],this._corner[0]),!!this._li.hasIntersection())))},ai.prototype.intersectsToleranceSquare=function(t,e){var n=!1,i=!1;return this._li.computeIntersection(t,e,this._corner[0],this._corner[1]),!!this._li.isProper()||(this._li.computeIntersection(t,e,this._corner[1],this._corner[2]),!!this._li.isProper()||(this._li.hasIntersection()&&(n=!0),this._li.computeIntersection(t,e,this._corner[2],this._corner[3]),!!this._li.isProper()||(this._li.hasIntersection()&&(i=!0),this._li.computeIntersection(t,e,this._corner[3],this._corner[0]),!!this._li.isProper()||(!(!n||!i)||(!!t.equals(this._pt)||!!e.equals(this._pt))))))},ai.prototype.addSnappedNode=function(t,e){var n=t.getCoordinate(e),i=t.getCoordinate(e+1);return!!this.intersects(n,i)&&(t.addIntersection(this.getCoordinate(),e),!0)},ai.prototype.interfaces_=function(){return[]},ai.prototype.getClass=function(){return ai},ui.SAFE_ENV_EXPANSION_FACTOR.get=function(){return.75},Object.defineProperties(ai,ui);var li=function(){this.tempEnv1=new j,this.selectedSegment=new dn};li.prototype.select=function(){if(1===arguments.length);else if(2===arguments.length){var t=arguments[0],e=arguments[1];t.getLineSegment(e,this.selectedSegment),this.select(this.selectedSegment)}},li.prototype.interfaces_=function(){return[]},li.prototype.getClass=function(){return li};var ci=function(){this._index=null;var t=arguments[0];this._index=t},pi={HotPixelSnapAction:{configurable:!0}};ci.prototype.snap=function(){if(1===arguments.length){var t=arguments[0];return this.snap(t,null,-1)}if(3===arguments.length){var e=arguments[0],n=arguments[1],i=arguments[2],r=e.getSafeEnvelope(),o=new hi(e,n,i);return this._index.query(r,{interfaces_:function(){return[Ke]},visitItem:function(t){t.select(r,o)}}),o.isNodeAdded()}},ci.prototype.interfaces_=function(){return[]},ci.prototype.getClass=function(){return ci},pi.HotPixelSnapAction.get=function(){return hi},Object.defineProperties(ci,pi);var hi=function(t){function e(){t.call(this),this._hotPixel=null,this._parentEdge=null,this._hotPixelVertexIndex=null,this._isNodeAdded=!1;var e=arguments[0],n=arguments[1],i=arguments[2];this._hotPixel=e,this._parentEdge=n,this._hotPixelVertexIndex=i}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.isNodeAdded=function(){return this._isNodeAdded},e.prototype.select=function(){if(2!==arguments.length)return t.prototype.select.apply(this,arguments);var e=arguments[0],n=arguments[1],i=e.getContext();if(null!==this._parentEdge&&i===this._parentEdge&&n===this._hotPixelVertexIndex)return null;this._isNodeAdded=this._hotPixel.addSnappedNode(i,n)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(li),fi=function(){this._li=null,this._interiorIntersections=null;var t=arguments[0];this._li=t,this._interiorIntersections=new Nt};fi.prototype.processIntersections=function(t,e,n,i){if(t===n&&e===i)return null;var r=t.getCoordinates()[e],o=t.getCoordinates()[e+1],s=n.getCoordinates()[i],a=n.getCoordinates()[i+1];if(this._li.computeIntersection(r,o,s,a),this._li.hasIntersection()&&this._li.isInteriorIntersection()){for(var u=0;u=0;e--){try{t.bufferReducedPrecision(e)}catch(e){if(!(e instanceof we))throw e;t._saveException=e}if(null!==t._resultGeometry)return null}throw this._saveException}if(1===arguments.length){var n=arguments[0],i=di.precisionScaleFactor(this._argGeom,this._distance,n),r=new fe(i);this.bufferFixedPrecision(r)}},di.prototype.computeGeometry=function(){if(this.bufferOriginalPrecision(),null!==this._resultGeometry)return null;var t=this._argGeom.getFactory().getPrecisionModel();t.getType()===fe.FIXED?this.bufferFixedPrecision(t):this.bufferReducedPrecision()},di.prototype.setQuadrantSegments=function(t){this._bufParams.setQuadrantSegments(t)},di.prototype.bufferOriginalPrecision=function(){try{var t=new ii(this._bufParams);this._resultGeometry=t.buffer(this._argGeom,this._distance)}catch(t){if(!(t instanceof $))throw t;this._saveException=t}},di.prototype.getResultGeometry=function(t){return this._distance=t,this.computeGeometry(),this._resultGeometry},di.prototype.setEndCapStyle=function(t){this._bufParams.setEndCapStyle(t)},di.prototype.interfaces_=function(){return[]},di.prototype.getClass=function(){return di},di.bufferOp=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];return new di(t).getResultGeometry(e)}if(3===arguments.length){if(Number.isInteger(arguments[2])&&arguments[0]instanceof ct&&"number"==typeof arguments[1]){var n=arguments[0],i=arguments[1],r=arguments[2],o=new di(n);o.setQuadrantSegments(r);return o.getResultGeometry(i)}if(arguments[2]instanceof Cn&&arguments[0]instanceof ct&&"number"==typeof arguments[1]){var s=arguments[0],a=arguments[1],u=arguments[2];return new di(s,u).getResultGeometry(a)}}else if(4===arguments.length){var l=arguments[0],c=arguments[1],p=arguments[2],h=arguments[3],f=new di(l);f.setQuadrantSegments(p),f.setEndCapStyle(h);return f.getResultGeometry(c)}},di.precisionScaleFactor=function(t,e,n){var i=t.getEnvelopeInternal(),r=R.max(Math.abs(i.getMaxX()),Math.abs(i.getMaxY()),Math.abs(i.getMinX()),Math.abs(i.getMinY()))+2*(e>0?e:0),o=n-Math.trunc(Math.log(r)/Math.log(10)+1);return Math.pow(10,o)},yi.CAP_ROUND.get=function(){return Cn.CAP_ROUND},yi.CAP_BUTT.get=function(){return Cn.CAP_FLAT},yi.CAP_FLAT.get=function(){return Cn.CAP_FLAT},yi.CAP_SQUARE.get=function(){return Cn.CAP_SQUARE},yi.MAX_PRECISION_DIGITS.get=function(){return 12},Object.defineProperties(di,yi);var _i=function(){this._pt=[new C,new C],this._distance=v.NaN,this._isNull=!0};_i.prototype.getCoordinates=function(){return this._pt},_i.prototype.getCoordinate=function(t){return this._pt[t]},_i.prototype.setMinimum=function(){if(1===arguments.length){var t=arguments[0];this.setMinimum(t._pt[0],t._pt[1])}else if(2===arguments.length){var e=arguments[0],n=arguments[1];if(this._isNull)return this.initialize(e,n),null;var i=e.distance(n);ithis._distance&&this.initialize(e,n,i)}},_i.prototype.interfaces_=function(){return[]},_i.prototype.getClass=function(){return _i};var mi=function(){};mi.prototype.interfaces_=function(){return[]},mi.prototype.getClass=function(){return mi},mi.computeDistance=function(){if(arguments[2]instanceof _i&&arguments[0]instanceof Kt&&arguments[1]instanceof C)for(var t=arguments[0],e=arguments[1],n=arguments[2],i=t.getCoordinates(),r=new dn,o=0;o0||this._isIn?w.INTERIOR:w.EXTERIOR)},Si.prototype.interfaces_=function(){return[]},Si.prototype.getClass=function(){return Si};var Li=function t(){if(this._component=null,this._segIndex=null,this._pt=null,2===arguments.length){var e=arguments[0],n=arguments[1];t.call(this,e,t.INSIDE_AREA,n)}else if(3===arguments.length){var i=arguments[0],r=arguments[1],o=arguments[2];this._component=i,this._segIndex=r,this._pt=o}},bi={INSIDE_AREA:{configurable:!0}};Li.prototype.isInsideArea=function(){return this._segIndex===Li.INSIDE_AREA},Li.prototype.getCoordinate=function(){return this._pt},Li.prototype.getGeometryComponent=function(){return this._component},Li.prototype.getSegmentIndex=function(){return this._segIndex},Li.prototype.interfaces_=function(){return[]},Li.prototype.getClass=function(){return Li},bi.INSIDE_AREA.get=function(){return-1},Object.defineProperties(Li,bi);var wi=function(t){this._pts=t||null};wi.prototype.filter=function(t){t instanceof Qt&&this._pts.add(t)},wi.prototype.interfaces_=function(){return[Vt]},wi.prototype.getClass=function(){return wi},wi.getPoints=function(){if(1===arguments.length){var t=arguments[0];return t instanceof Qt?$e.singletonList(t):wi.getPoints(t,new Nt)}if(2===arguments.length){var e=arguments[0],n=arguments[1];return e instanceof Qt?n.add(e):e instanceof zt&&e.apply(new wi(n)),n}};var Oi=function(){this._locations=null;var t=arguments[0];this._locations=t};Oi.prototype.filter=function(t){(t instanceof Qt||t instanceof Kt||t instanceof $t)&&this._locations.add(new Li(t,0,t.getCoordinate()))},Oi.prototype.interfaces_=function(){return[Vt]},Oi.prototype.getClass=function(){return Oi},Oi.getLocations=function(t){var e=new Nt;return t.apply(new Oi(e)),e};var Ti=function(){if(this._geom=null,this._terminateDistance=0,this._ptLocator=new Si,this._minDistanceLocation=null,this._minDistance=v.MAX_VALUE,2===arguments.length){var t=arguments[0],e=arguments[1];this._geom=[t,e],this._terminateDistance=0}else if(3===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[2];this._geom=new Array(2).fill(null),this._geom[0]=n,this._geom[1]=i,this._terminateDistance=r}};Ti.prototype.computeContainmentDistance=function(){if(0===arguments.length){var t=new Array(2).fill(null);if(this.computeContainmentDistance(0,t),this._minDistance<=this._terminateDistance)return null;this.computeContainmentDistance(1,t)}else if(2===arguments.length){var e=arguments[0],n=arguments[1],i=1-e,r=Ni.getPolygons(this._geom[e]);if(r.size()>0){var o=Oi.getLocations(this._geom[i]);if(this.computeContainmentDistance(o,r,n),this._minDistance<=this._terminateDistance)return this._minDistanceLocation[i]=n[0],this._minDistanceLocation[e]=n[1],null}}else if(3===arguments.length)if(arguments[2]instanceof Array&&T(arguments[0],xt)&&T(arguments[1],xt)){for(var s=arguments[0],a=arguments[1],u=arguments[2],l=0;lthis._minDistance)return null;for(var i=t.getCoordinates(),r=e.getCoordinate(),o=0;othis._minDistance)return null;for(var p=u.getCoordinates(),h=l.getCoordinates(),f=0;fthis._distance&&this.initialize(e,n,i)}},Ri.prototype.interfaces_=function(){return[]},Ri.prototype.getClass=function(){return Ri};var Pi=function(){};Pi.prototype.interfaces_=function(){return[]},Pi.prototype.getClass=function(){return Pi},Pi.computeDistance=function(){if(arguments[2]instanceof Ri&&arguments[0]instanceof Kt&&arguments[1]instanceof C)for(var t=arguments[0],e=arguments[1],n=arguments[2],i=new dn,r=t.getCoordinates(),o=0;o1||t<=0)throw new m("Fraction is not in range (0.0 - 1.0]");this._densifyFrac=t},Di.prototype.compute=function(t,e){this.computeOrientedDistance(t,e,this._ptDist),this.computeOrientedDistance(e,t,this._ptDist)},Di.prototype.distance=function(){return this.compute(this._g0,this._g1),this._ptDist.getDistance()},Di.prototype.computeOrientedDistance=function(t,e,n){var i=new Ai(e);if(t.apply(i),n.setMaximum(i.getMaxPointDistance()),this._densifyFrac>0){var r=new Fi(e,this._densifyFrac);t.apply(r),n.setMaximum(r.getMaxPointDistance())}},Di.prototype.orientedDistance=function(){return this.computeOrientedDistance(this._g0,this._g1,this._ptDist),this._ptDist.getDistance()},Di.prototype.interfaces_=function(){return[]},Di.prototype.getClass=function(){return Di},Di.distance=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];return new Di(t,e).distance()}if(3===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[2],o=new Di(n,i);return o.setDensifyFraction(r),o.distance()}},Mi.MaxPointDistanceFilter.get=function(){return Ai},Mi.MaxDensifiedByFractionDistanceFilter.get=function(){return Fi},Object.defineProperties(Di,Mi);var Ai=function(){this._maxPtDist=new Ri,this._minPtDist=new Ri,this._euclideanDist=new Pi,this._geom=null;var t=arguments[0];this._geom=t};Ai.prototype.filter=function(t){this._minPtDist.initialize(),Pi.computeDistance(this._geom,t,this._minPtDist),this._maxPtDist.setMaximum(this._minPtDist)},Ai.prototype.getMaxPointDistance=function(){return this._maxPtDist},Ai.prototype.interfaces_=function(){return[ft]},Ai.prototype.getClass=function(){return Ai};var Fi=function(){this._maxPtDist=new Ri,this._minPtDist=new Ri,this._geom=null,this._numSubSegs=0;var t=arguments[0],e=arguments[1];this._geom=t,this._numSubSegs=Math.trunc(Math.round(1/e))};Fi.prototype.filter=function(t,e){if(0===e)return null;for(var n=t.getCoordinate(e-1),i=t.getCoordinate(e),r=(i.x-n.x)/this._numSubSegs,o=(i.y-n.y)/this._numSubSegs,s=0;sn){this._isValid=!1;var r=i.getCoordinates();this._errorLocation=r[1],this._errorIndicator=t.getFactory().createLineString(r),this._errMsg="Distance between buffer curve and input is too large ("+this._maxDistanceFound+" at "+Z.toLineString(r[0],r[1])+")"}},Gi.prototype.isValid=function(){var t=Math.abs(this._bufDistance),e=Gi.MAX_DISTANCE_DIFF_FRAC*t;return this._minValidDistance=t-e,this._maxValidDistance=t+e,!(!this._input.isEmpty()&&!this._result.isEmpty())||(this._bufDistance>0?this.checkPositiveValid():this.checkNegativeValid(),Gi.VERBOSE&&Y.out.println("Min Dist= "+this._minDistanceFound+" err= "+(1-this._minDistanceFound/this._bufDistance)+" Max Dist= "+this._maxDistanceFound+" err= "+(this._maxDistanceFound/this._bufDistance-1)),this._isValid)},Gi.prototype.checkNegativeValid=function(){if(!(this._input instanceof $t||this._input instanceof ne||this._input instanceof zt))return null;var t=this.getPolygonLines(this._input);if(this.checkMinimumDistance(t,this._result,this._minValidDistance),!this._isValid)return null;this.checkMaximumDistance(t,this._result,this._maxValidDistance)},Gi.prototype.getErrorIndicator=function(){return this._errorIndicator},Gi.prototype.checkMinimumDistance=function(t,e,n){var i=new Ti(t,e,n);if(this._minDistanceFound=i.distance(),this._minDistanceFound0&&t>e&&(this._isValid=!1,this._errorMsg="Area of positive buffer is smaller than input",this._errorIndicator=this._result),this._distance<0&&t=2?null:this._distance>0?null:(this._result.isEmpty()||(this._isValid=!1,this._errorMsg="Result is non-empty",this._errorIndicator=this._result),void this.report("ExpectedEmpty"))},Bi.prototype.report=function(t){if(!Bi.VERBOSE)return null;Y.out.println("Check "+t+": "+(this._isValid?"passed":"FAILED"))},Bi.prototype.getErrorMessage=function(){return this._errorMsg},Bi.prototype.interfaces_=function(){return[]},Bi.prototype.getClass=function(){return Bi},Bi.isValidMsg=function(t,e,n){var i=new Bi(t,e,n);return i.isValid()?null:i.getErrorMessage()},Bi.isValid=function(t,e,n){return!!new Bi(t,e,n).isValid()},Vi.VERBOSE.get=function(){return!1},Vi.MAX_ENV_DIFF_FRAC.get=function(){return.012},Object.defineProperties(Bi,Vi);var Ui=function(){this._pts=null,this._data=null;var t=arguments[0],e=arguments[1];this._pts=t,this._data=e};Ui.prototype.getCoordinates=function(){return this._pts},Ui.prototype.size=function(){return this._pts.length},Ui.prototype.getCoordinate=function(t){return this._pts[t]},Ui.prototype.isClosed=function(){return this._pts[0].equals(this._pts[this._pts.length-1])},Ui.prototype.getSegmentOctant=function(t){return t===this._pts.length-1?-1:pn.octant(this.getCoordinate(t),this.getCoordinate(t+1))},Ui.prototype.setData=function(t){this._data=t},Ui.prototype.getData=function(){return this._data},Ui.prototype.toString=function(){return Z.toLineString(new ue(this._pts))},Ui.prototype.interfaces_=function(){return[hn]},Ui.prototype.getClass=function(){return Ui};var zi=function(){this._findAllIntersections=!1,this._isCheckEndSegmentsOnly=!1,this._li=null,this._interiorIntersection=null,this._intSegments=null,this._intersections=new Nt,this._intersectionCount=0,this._keepIntersections=!0;var t=arguments[0];this._li=t,this._interiorIntersection=null};zi.prototype.getInteriorIntersection=function(){return this._interiorIntersection},zi.prototype.setCheckEndSegmentsOnly=function(t){this._isCheckEndSegmentsOnly=t},zi.prototype.getIntersectionSegments=function(){return this._intSegments},zi.prototype.count=function(){return this._intersectionCount},zi.prototype.getIntersections=function(){return this._intersections},zi.prototype.setFindAllIntersections=function(t){this._findAllIntersections=t},zi.prototype.setKeepIntersections=function(t){this._keepIntersections=t},zi.prototype.processIntersections=function(t,e,n,i){if(!this._findAllIntersections&&this.hasIntersection())return null;if(t===n&&e===i)return null;if(this._isCheckEndSegmentsOnly){if(!(this.isEndSegment(t,e)||this.isEndSegment(n,i)))return null}var r=t.getCoordinates()[e],o=t.getCoordinates()[e+1],s=n.getCoordinates()[i],a=n.getCoordinates()[i+1];this._li.computeIntersection(r,o,s,a),this._li.hasIntersection()&&this._li.isInteriorIntersection()&&(this._intSegments=new Array(4).fill(null),this._intSegments[0]=r,this._intSegments[1]=o,this._intSegments[2]=s,this._intSegments[3]=a,this._interiorIntersection=this._li.getIntersection(0),this._keepIntersections&&this._intersections.add(this._interiorIntersection),this._intersectionCount++)},zi.prototype.isEndSegment=function(t,e){return 0===e||e>=t.size()-2},zi.prototype.hasIntersection=function(){return null!==this._interiorIntersection},zi.prototype.isDone=function(){return!this._findAllIntersections&&null!==this._interiorIntersection},zi.prototype.interfaces_=function(){return[Wn]},zi.prototype.getClass=function(){return zi},zi.createAllIntersectionsFinder=function(t){var e=new zi(t);return e.setFindAllIntersections(!0),e},zi.createAnyIntersectionFinder=function(t){return new zi(t)},zi.createIntersectionCounter=function(t){var e=new zi(t);return e.setFindAllIntersections(!0),e.setKeepIntersections(!1),e};var Xi=function(){this._li=new rt,this._segStrings=null,this._findAllIntersections=!1,this._segInt=null,this._isValid=!0;var t=arguments[0];this._segStrings=t};Xi.prototype.execute=function(){if(null!==this._segInt)return null;this.checkInteriorIntersections()},Xi.prototype.getIntersections=function(){return this._segInt.getIntersections()},Xi.prototype.isValid=function(){return this.execute(),this._isValid},Xi.prototype.setFindAllIntersections=function(t){this._findAllIntersections=t},Xi.prototype.checkInteriorIntersections=function(){this._isValid=!0,this._segInt=new zi(this._li),this._segInt.setFindAllIntersections(this._findAllIntersections);var t=new xn;if(t.setSegmentIntersector(this._segInt),t.computeNodes(this._segStrings),this._segInt.hasIntersection())return this._isValid=!1,null},Xi.prototype.checkValid=function(){if(this.execute(),!this._isValid)throw new we(this.getErrorMessage(),this._segInt.getInteriorIntersection())},Xi.prototype.getErrorMessage=function(){if(this._isValid)return"no intersections found";var t=this._segInt.getIntersectionSegments();return"found non-noded intersection between "+Z.toLineString(t[0],t[1])+" and "+Z.toLineString(t[2],t[3])},Xi.prototype.interfaces_=function(){return[]},Xi.prototype.getClass=function(){return Xi},Xi.computeIntersections=function(t){var e=new Xi(t);return e.setFindAllIntersections(!0),e.isValid(),e.getIntersections()};var Yi=function t(){this._nv=null;var e=arguments[0];this._nv=new Xi(t.toSegmentStrings(e))};Yi.prototype.checkValid=function(){this._nv.checkValid()},Yi.prototype.interfaces_=function(){return[]},Yi.prototype.getClass=function(){return Yi},Yi.toSegmentStrings=function(t){for(var e=new Nt,n=t.iterator();n.hasNext();){var i=n.next();e.add(new Ui(i.getCoordinates(),i))}return e},Yi.checkValid=function(t){new Yi(t).checkValid()};var ki=function(t){this._mapOp=t};ki.prototype.map=function(t){for(var e=new Nt,n=0;n0&&i<4&&!this._preserveType?this._factory.createLineString(n):this._factory.createLinearRing(n)},Wi.prototype.interfaces_=function(){return[]},Wi.prototype.getClass=function(){return Wi};var Ki=function t(){if(this._snapTolerance=0,this._srcPts=null,this._seg=new dn,this._allowSnappingToSourceVertices=!1,this._isClosed=!1,arguments[0]instanceof Kt&&"number"==typeof arguments[1]){var e=arguments[0],n=arguments[1];t.call(this,e.getCoordinates(),n)}else if(arguments[0]instanceof Array&&"number"==typeof arguments[1]){var i=arguments[0],r=arguments[1];this._srcPts=i,this._isClosed=t.isClosed(i),this._snapTolerance=r}};Ki.prototype.snapVertices=function(t,e){for(var n=this._isClosed?t.size()-1:t.size(),i=0;i=0&&t.add(o+1,new C(r),!1)}},Ki.prototype.findSegmentIndexToSnap=function(t,e){for(var n=v.MAX_VALUE,i=-1,r=0;re&&(e=i)}return e}if(2===arguments.length){var r=arguments[0],o=arguments[1];return Math.min(Ji.computeOverlaySnapTolerance(r),Ji.computeOverlaySnapTolerance(o))}},Ji.computeSizeBasedSnapTolerance=function(t){var e=t.getEnvelopeInternal();return Math.min(e.getHeight(),e.getWidth())*Ji.SNAP_PRECISION_FACTOR},Ji.snapToSelf=function(t,e,n){return new Ji(t).snapToSelf(e,n)},Qi.SNAP_PRECISION_FACTOR.get=function(){return 1e-9},Object.defineProperties(Ji,Qi);var Zi=function(t){function e(e,n,i){t.call(this),this._snapTolerance=e||null,this._snapPts=n||null,this._isSelfSnap=void 0!==i&&i}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.snapLine=function(t,e){var n=new Ki(t,this._snapTolerance);return n.setAllowSnappingToSourceVertices(this._isSelfSnap),n.snapTo(e)},e.prototype.transformCoordinates=function(t,e){var n=t.toCoordinateArray(),i=this.snapLine(n,this._snapPts);return this._factory.getCoordinateSequenceFactory().create(i)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Wi),$i=function(){this._isFirst=!0,this._commonMantissaBitsCount=53,this._commonBits=0,this._commonSignExp=null};$i.prototype.getCommon=function(){return v.longBitsToDouble(this._commonBits)},$i.prototype.add=function(t){var e=v.doubleToLongBits(t);if(this._isFirst)return this._commonBits=e,this._commonSignExp=$i.signExpBits(this._commonBits),this._isFirst=!1,null;if($i.signExpBits(e)!==this._commonSignExp)return this._commonBits=0,null;this._commonMantissaBitsCount=$i.numCommonMostSigMantissaBits(this._commonBits,e),this._commonBits=$i.zeroLowerBits(this._commonBits,64-(12+this._commonMantissaBitsCount))},$i.prototype.toString=function(){if(1===arguments.length){var t=arguments[0],e=v.longBitsToDouble(t),n="0000000000000000000000000000000000000000000000000000000000000000"+v.toBinaryString(t),i=n.substring(n.length-64);return i.substring(0,1)+" "+i.substring(1,12)+"(exp) "+i.substring(12)+" [ "+e+" ]"}},$i.prototype.interfaces_=function(){return[]},$i.prototype.getClass=function(){return $i},$i.getBit=function(t,e){return 0!=(t&1<>52},$i.zeroLowerBits=function(t,e){return t&~((1<=0;i--){if($i.getBit(t,i)!==$i.getBit(e,i))return n;n++}return 52};var tr=function(){this._commonCoord=null,this._ccFilter=new nr},er={CommonCoordinateFilter:{configurable:!0},Translater:{configurable:!0}};tr.prototype.addCommonBits=function(t){var e=new ir(this._commonCoord);t.apply(e),t.geometryChanged()},tr.prototype.removeCommonBits=function(t){if(0===this._commonCoord.x&&0===this._commonCoord.y)return t;var e=new C(this._commonCoord);e.x=-e.x,e.y=-e.y;var n=new ir(e);return t.apply(n),t.geometryChanged(),t},tr.prototype.getCommonCoordinate=function(){return this._commonCoord},tr.prototype.add=function(t){t.apply(this._ccFilter),this._commonCoord=this._ccFilter.getCommonCoordinate()},tr.prototype.interfaces_=function(){return[]},tr.prototype.getClass=function(){return tr},er.CommonCoordinateFilter.get=function(){return nr},er.Translater.get=function(){return ir},Object.defineProperties(tr,er);var nr=function(){this._commonBitsX=new $i,this._commonBitsY=new $i};nr.prototype.filter=function(t){this._commonBitsX.add(t.x),this._commonBitsY.add(t.y)},nr.prototype.getCommonCoordinate=function(){return new C(this._commonBitsX.getCommon(),this._commonBitsY.getCommon())},nr.prototype.interfaces_=function(){return[ft]},nr.prototype.getClass=function(){return nr};var ir=function(){this.trans=null;var t=arguments[0];this.trans=t};ir.prototype.filter=function(t,e){var n=t.getOrdinate(e,0)+this.trans.x,i=t.getOrdinate(e,1)+this.trans.y;t.setOrdinate(e,0,n),t.setOrdinate(e,1,i)},ir.prototype.isDone=function(){return!1},ir.prototype.isGeometryChanged=function(){return!0},ir.prototype.interfaces_=function(){return[Ut]},ir.prototype.getClass=function(){return ir};var rr=function(t,e){this._geom=new Array(2).fill(null),this._snapTolerance=null,this._cbr=null,this._geom[0]=t,this._geom[1]=e,this.computeSnapTolerance()};rr.prototype.selfSnap=function(t){return new Ji(t).snapTo(t,this._snapTolerance)},rr.prototype.removeCommonBits=function(t){this._cbr=new tr,this._cbr.add(t[0]),this._cbr.add(t[1]);var e=new Array(2).fill(null);return e[0]=this._cbr.removeCommonBits(t[0].copy()),e[1]=this._cbr.removeCommonBits(t[1].copy()),e},rr.prototype.prepareResult=function(t){return this._cbr.addCommonBits(t),t},rr.prototype.getResultGeometry=function(t){var e=this.snap(this._geom),n=Lr.overlayOp(e[0],e[1],t);return this.prepareResult(n)},rr.prototype.checkValid=function(t){t.isValid()||Y.out.println("Snapped geometry is invalid")},rr.prototype.computeSnapTolerance=function(){this._snapTolerance=Ji.computeOverlaySnapTolerance(this._geom[0],this._geom[1])},rr.prototype.snap=function(t){var e=this.removeCommonBits(t);return Ji.snap(e[0],e[1],this._snapTolerance)},rr.prototype.interfaces_=function(){return[]},rr.prototype.getClass=function(){return rr},rr.overlayOp=function(t,e,n){return new rr(t,e).getResultGeometry(n)},rr.union=function(t,e){return rr.overlayOp(t,e,Lr.UNION)},rr.intersection=function(t,e){return rr.overlayOp(t,e,Lr.INTERSECTION)},rr.symDifference=function(t,e){return rr.overlayOp(t,e,Lr.SYMDIFFERENCE)},rr.difference=function(t,e){return rr.overlayOp(t,e,Lr.DIFFERENCE)};var or=function(t,e){this._geom=new Array(2).fill(null),this._geom[0]=t,this._geom[1]=e};or.prototype.getResultGeometry=function(t){var e=null,n=!1,i=null;try{e=Lr.overlayOp(this._geom[0],this._geom[1],t);n=!0}catch(t){if(!(t instanceof $))throw t;i=t}if(!n)try{e=rr.overlayOp(this._geom[0],this._geom[1],t)}catch(t){throw t instanceof $?i:t}return e},or.prototype.interfaces_=function(){return[]},or.prototype.getClass=function(){return or},or.overlayOp=function(t,e,n){return new or(t,e).getResultGeometry(n)},or.union=function(t,e){return or.overlayOp(t,e,Lr.UNION)},or.intersection=function(t,e){return or.overlayOp(t,e,Lr.INTERSECTION)},or.symDifference=function(t,e){return or.overlayOp(t,e,Lr.SYMDIFFERENCE)},or.difference=function(t,e){return or.overlayOp(t,e,Lr.DIFFERENCE)};var sr=function(){this.mce=null,this.chainIndex=null;var t=arguments[0],e=arguments[1];this.mce=t,this.chainIndex=e};sr.prototype.computeIntersections=function(t,e){this.mce.computeIntersectsForChain(this.chainIndex,t.mce,t.chainIndex,e)},sr.prototype.interfaces_=function(){return[]},sr.prototype.getClass=function(){return sr};var ar=function t(){if(this._label=null,this._xValue=null,this._eventType=null,this._insertEvent=null,this._deleteEventIndex=null,this._obj=null,2===arguments.length){var e=arguments[0],n=arguments[1];this._eventType=t.DELETE,this._xValue=e,this._insertEvent=n}else if(3===arguments.length){var i=arguments[0],r=arguments[1],o=arguments[2];this._eventType=t.INSERT,this._label=i,this._xValue=r,this._obj=o}},ur={INSERT:{configurable:!0},DELETE:{configurable:!0}};ar.prototype.isDelete=function(){return this._eventType===ar.DELETE},ar.prototype.setDeleteEventIndex=function(t){this._deleteEventIndex=t},ar.prototype.getObject=function(){return this._obj},ar.prototype.compareTo=function(t){var e=t;return this._xValuee._xValue?1:this._eventTypee._eventType?1:0},ar.prototype.getInsertEvent=function(){return this._insertEvent},ar.prototype.isInsert=function(){return this._eventType===ar.INSERT},ar.prototype.isSameLabel=function(t){return null!==this._label&&this._label===t._label},ar.prototype.getDeleteEventIndex=function(){return this._deleteEventIndex},ar.prototype.interfaces_=function(){return[E]},ar.prototype.getClass=function(){return ar},ur.INSERT.get=function(){return 1},ur.DELETE.get=function(){return 2},Object.defineProperties(ar,ur);var lr=function(){};lr.prototype.interfaces_=function(){return[]},lr.prototype.getClass=function(){return lr};var cr=function(){this._hasIntersection=!1,this._hasProper=!1,this._hasProperInterior=!1,this._properIntersectionPoint=null,this._li=null,this._includeProper=null,this._recordIsolated=null,this._isSelfIntersection=null,this._numIntersections=0,this.numTests=0,this._bdyNodes=null,this._isDone=!1,this._isDoneWhenProperInt=!1;var t=arguments[0],e=arguments[1],n=arguments[2];this._li=t,this._includeProper=e,this._recordIsolated=n};cr.prototype.isTrivialIntersection=function(t,e,n,i){if(t===n&&1===this._li.getIntersectionNum()){if(cr.isAdjacentSegments(e,i))return!0;if(t.isClosed()){var r=t.getNumPoints()-1;if(0===e&&i===r||0===i&&e===r)return!0}}return!1},cr.prototype.getProperIntersectionPoint=function(){return this._properIntersectionPoint},cr.prototype.setIsDoneIfProperInt=function(t){this._isDoneWhenProperInt=t},cr.prototype.hasProperInteriorIntersection=function(){return this._hasProperInterior},cr.prototype.isBoundaryPointInternal=function(t,e){for(var n=e.iterator();n.hasNext();){var i=n.next().getCoordinate();if(t.isIntersection(i))return!0}return!1},cr.prototype.hasProperIntersection=function(){return this._hasProper},cr.prototype.hasIntersection=function(){return this._hasIntersection},cr.prototype.isDone=function(){return this._isDone},cr.prototype.isBoundaryPoint=function(t,e){return null!==e&&(!!this.isBoundaryPointInternal(t,e[0])||!!this.isBoundaryPointInternal(t,e[1]))},cr.prototype.setBoundaryNodes=function(t,e){this._bdyNodes=new Array(2).fill(null),this._bdyNodes[0]=t,this._bdyNodes[1]=e},cr.prototype.addIntersections=function(t,e,n,i){if(t===n&&e===i)return null;this.numTests++;var r=t.getCoordinates()[e],o=t.getCoordinates()[e+1],s=n.getCoordinates()[i],a=n.getCoordinates()[i+1];this._li.computeIntersection(r,o,s,a),this._li.hasIntersection()&&(this._recordIsolated&&(t.setIsolated(!1),n.setIsolated(!1)),this._numIntersections++,this.isTrivialIntersection(t,e,n,i)||(this._hasIntersection=!0,!this._includeProper&&this._li.isProper()||(t.addIntersections(this._li,e,0),n.addIntersections(this._li,i,1)),this._li.isProper()&&(this._properIntersectionPoint=this._li.getIntersection(0).copy(),this._hasProper=!0,this._isDoneWhenProperInt&&(this._isDone=!0),this.isBoundaryPoint(this._li,this._bdyNodes)||(this._hasProperInterior=!0))))},cr.prototype.interfaces_=function(){return[]},cr.prototype.getClass=function(){return cr},cr.isAdjacentSegments=function(t,e){return 1===Math.abs(t-e)};var pr=function(t){function e(){t.call(this),this.events=new Nt,this.nOverlaps=null}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.prepareEvents=function(){$e.sort(this.events);for(var t=0;te||this._maxo?1:0},gr.prototype.interfaces_=function(){return[N]},gr.prototype.getClass=function(){return gr};var dr=function(t){function e(){t.call(this),this._item=null;var e=arguments[0],n=arguments[1],i=arguments[2];this._min=e,this._max=n,this._item=i}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.query=function(t,e,n){if(!this.intersects(t,e))return null;n.visitItem(this._item)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(hr),yr=function(t){function e(){t.call(this),this._node1=null,this._node2=null;var e=arguments[0],n=arguments[1];this._node1=e,this._node2=n,this.buildExtent(this._node1,this._node2)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.buildExtent=function(t,e){this._min=Math.min(t._min,e._min),this._max=Math.max(t._max,e._max)},e.prototype.query=function(t,e,n){if(!this.intersects(t,e))return null;null!==this._node1&&this._node1.query(t,e,n),null!==this._node2&&this._node2.query(t,e,n)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(hr),_r=function(){this._leaves=new Nt,this._root=null,this._level=0};_r.prototype.buildTree=function(){$e.sort(this._leaves,new hr.NodeComparator);for(var t=this._leaves,e=null,n=new Nt;;){if(this.buildLevel(t,n),1===n.size())return n.get(0);e=t,t=n,n=e}},_r.prototype.insert=function(t,e,n){if(null!==this._root)throw new Error("Index cannot be added to once it has been queried");this._leaves.add(new dr(t,e,n))},_r.prototype.query=function(t,e,n){this.init(),this._root.query(t,e,n)},_r.prototype.buildRoot=function(){if(null!==this._root)return null;this._root=this.buildTree()},_r.prototype.printNode=function(t){Y.out.println(Z.toLineString(new C(t._min,this._level),new C(t._max,this._level)))},_r.prototype.init=function(){if(null!==this._root)return null;this.buildRoot()},_r.prototype.buildLevel=function(t,e){this._level++,e.clear();for(var n=0;n=2,"found LineString with single point"),this.insertBoundaryPoint(this._argIndex,e[0]),this.insertBoundaryPoint(this._argIndex,e[e.length-1])},e.prototype.getInvalidPoint=function(){return this._invalidPoint},e.prototype.getBoundaryPoints=function(){for(var t=this.getBoundaryNodes(),e=new Array(t.size()).fill(null),n=0,i=t.iterator();i.hasNext();){var r=i.next();e[n++]=r.getCoordinate().copy()}return e},e.prototype.getBoundaryNodes=function(){return null===this._boundaryNodes&&(this._boundaryNodes=this._nodes.getBoundaryNodes(this._argIndex)),this._boundaryNodes},e.prototype.addSelfIntersectionNode=function(t,e,n){if(this.isBoundaryNode(t,e))return null;n===w.BOUNDARY&&this._useBoundaryDeterminationRule?this.insertBoundaryPoint(t,e):this.insertPoint(t,e,n)},e.prototype.addPolygonRing=function(t,e,n){if(t.isEmpty())return null;var i=Lt.removeRepeatedPoints(t.getCoordinates());if(i.length<4)return this._hasTooFewPoints=!0,this._invalidPoint=i[0],null;var r=e,o=n;at.isCCW(i)&&(r=n,o=e);var s=new ni(i,new Pe(this._argIndex,w.BOUNDARY,r,o));this._lineEdgeMap.put(t,s),this.insertEdge(s),this.insertPoint(this._argIndex,i[0],w.BOUNDARY)},e.prototype.insertPoint=function(t,e,n){var i=this._nodes.addNode(e),r=i.getLabel();null===r?i._label=new Pe(t,n):r.setLocation(t,n)},e.prototype.createEdgeSetIntersector=function(){return new pr},e.prototype.addSelfIntersectionNodes=function(t){for(var e=this._edges.iterator();e.hasNext();)for(var n=e.next(),i=n.getLabel().getLocation(t),r=n.eiList.iterator();r.hasNext();){var o=r.next();this.addSelfIntersectionNode(t,o.coord,i)}},e.prototype.add=function(){if(1!==arguments.length)return t.prototype.add.apply(this,arguments);var e=arguments[0];if(e.isEmpty())return null;if(e instanceof ne&&(this._useBoundaryDeterminationRule=!1),e instanceof $t)this.addPolygon(e);else if(e instanceof Kt)this.addLineString(e);else if(e instanceof Qt)this.addPoint(e);else if(e instanceof te)this.addCollection(e);else if(e instanceof Xt)this.addCollection(e);else if(e instanceof ne)this.addCollection(e);else{if(!(e instanceof zt))throw new Error(e.getClass().getName());this.addCollection(e)}},e.prototype.addCollection=function(t){for(var e=0;e50?(null===this._areaPtLocator&&(this._areaPtLocator=new vr(this._parentGeom)),this._areaPtLocator.locate(t)):this._ptLocator.locate(t,this._parentGeom)},e.prototype.findEdge=function(){if(1===arguments.length){var e=arguments[0];return this._lineEdgeMap.get(e)}return t.prototype.findEdge.apply(this,arguments)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e.determineBoundary=function(t,e){return t.isInBoundary(e)?w.BOUNDARY:w.INTERIOR},e}(Ye),Cr=function(){if(this._li=new rt,this._resultPrecisionModel=null,this._arg=null,1===arguments.length){var t=arguments[0];this.setComputationPrecision(t.getPrecisionModel()),this._arg=new Array(1).fill(null),this._arg[0]=new Nr(0,t)}else if(2===arguments.length){var e=arguments[0],n=arguments[1],i=gt.OGC_SFS_BOUNDARY_RULE;e.getPrecisionModel().compareTo(n.getPrecisionModel())>=0?this.setComputationPrecision(e.getPrecisionModel()):this.setComputationPrecision(n.getPrecisionModel()),this._arg=new Array(2).fill(null),this._arg[0]=new Nr(0,e,i),this._arg[1]=new Nr(1,n,i)}else if(3===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2];r.getPrecisionModel().compareTo(o.getPrecisionModel())>=0?this.setComputationPrecision(r.getPrecisionModel()):this.setComputationPrecision(o.getPrecisionModel()),this._arg=new Array(2).fill(null),this._arg[0]=new Nr(0,r,s),this._arg[1]=new Nr(1,o,s)}};Cr.prototype.getArgGeometry=function(t){return this._arg[t].getGeometry()},Cr.prototype.setComputationPrecision=function(t){this._resultPrecisionModel=t,this._li.setPrecisionModel(this._resultPrecisionModel)},Cr.prototype.interfaces_=function(){return[]},Cr.prototype.getClass=function(){return Cr};var Sr=function(){};Sr.prototype.interfaces_=function(){return[]},Sr.prototype.getClass=function(){return Sr},Sr.map=function(){if(arguments[0]instanceof ct&&T(arguments[1],Sr.MapOp)){for(var t=arguments[0],e=arguments[1],n=new Nt,i=0;i=t.size()?null:t.get(e)},Dr.union=function(t){return new Dr(t).union()},Mr.STRTREE_NODE_CAPACITY.get=function(){return 4},Object.defineProperties(Dr,Mr);var Ar=function(){};Ar.prototype.interfaces_=function(){return[]},Ar.prototype.getClass=function(){return Ar},Ar.union=function(t,e){if(t.isEmpty()||e.isEmpty()){if(t.isEmpty()&&e.isEmpty())return Lr.createEmptyResult(Lr.UNION,t,e,t.getFactory());if(t.isEmpty())return e.copy();if(e.isEmpty())return t.copy()}return t.checkNotGeometryCollection(t),t.checkNotGeometryCollection(e),or.overlayOp(t,e,Lr.UNION)},t.GeoJSONReader=Ne,t.GeoJSONWriter=Ce,t.OverlayOp=Lr,t.UnionOp=Ar,t.BufferOp=di,Object.defineProperty(t,"__esModule",{value:!0})});\n\n\n//# sourceURL=webpack:///./node_modules/turf-jsts/jsts.min.js?')},function(module,exports,__webpack_require__){"use strict";eval('\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { "default": mod };\n}\nObject.defineProperty(exports, "__esModule", { value: true });\nvar distance_1 = __importDefault(__webpack_require__(9));\nvar meta_1 = __webpack_require__(19);\n/**\n * Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point}\'s distance are ignored.\n *\n * @name length\n * @param {Feature} geojson GeoJSON to measure\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units=kilometers] can be degrees, radians, miles, or kilometers\n * @returns {number} length of GeoJSON\n * @example\n * var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]);\n * var length = turf.length(line, {units: \'miles\'});\n *\n * //addToMap\n * var addToMap = [line];\n * line.properties.distance = length;\n */\nfunction length(geojson, options) {\n if (options === void 0) { options = {}; }\n // Calculate distance from 2-vertex line segments\n return meta_1.segmentReduce(geojson, function (previousValue, segment) {\n var coords = segment.geometry.coordinates;\n return previousValue + distance_1.default(coords[0], coords[1], options);\n }, 0);\n}\nexports.default = length;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/length/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar invariant_1 = __webpack_require__(2);\nvar helpers_1 = __webpack_require__(1);\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n/**\n * Calculates the distance between two {@link Point|points} in degrees, radians, miles, or kilometers.\n * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature.\n *\n * @name distance\n * @param {Coord} from origin point\n * @param {Coord} to destination point\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {number} distance between the two points\n * @example\n * var from = turf.point([-75.343, 39.984]);\n * var to = turf.point([-75.534, 39.123]);\n * var options = {units: 'miles'};\n *\n * var distance = turf.distance(from, to, options);\n *\n * //addToMap\n * var addToMap = [from, to];\n * from.properties.distance = distance;\n * to.properties.distance = distance;\n */\nfunction distance(from, to, options) {\n if (options === void 0) { options = {}; }\n var coordinates1 = invariant_1.getCoord(from);\n var coordinates2 = invariant_1.getCoord(to);\n var dLat = helpers_1.degreesToRadians((coordinates2[1] - coordinates1[1]));\n var dLon = helpers_1.degreesToRadians((coordinates2[0] - coordinates1[0]));\n var lat1 = helpers_1.degreesToRadians(coordinates1[1]);\n var lat2 = helpers_1.degreesToRadians(coordinates2[1]);\n var a = Math.pow(Math.sin(dLat / 2), 2) +\n Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);\n return helpers_1.radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), options.units);\n}\nexports.default = distance;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/distance/index.js?")},function(module,exports,__webpack_require__){eval('/* Here we have utilities to convert OSM geojson data into a distance-weighted graph and find the shortest path between two points. */\nvar path = __webpack_require__(33),\n createGraph = __webpack_require__(38),\n lineSlice = __webpack_require__(14).default,\n length = __webpack_require__(8).default,\n Agentmap = __webpack_require__(4).Agentmap;\n/**\r\n * Convert a layerGroup of streets into a graph. Useful if you modify the street layers during the simulation\r\n * and want routing to work with the new street network.\r\n *\r\n * @param {LayerGroup} streets - A Leaflet layerGroup of streets, forming a street network.\r\n * @returns {Object} - A graph representing the street network, operable by the ngraph pathfinder. \r\n */\n\n\nfunction streetsToGraph(streets) {\n var graph = createGraph(),\n streetToGraphBound = streetToGraph.bind(this, graph); //For each street, get an array of indices for the start, intersections, and end coordinates, in order from\n //start to end. Then, add the coordinates at each index as a node, and an edge between each adjacent node in the array,\n //associating the distance between the nodes (between their coordinates) with each edge.\n\n streets.eachLayer(streetToGraphBound);\n return graph;\n}\n/**\r\n * Process a street layer and add it into a graph.\r\n *\r\n * @param {ngraph.graph} graph - An ngraph.graph representing a street network.\r\n * @param {L.Polyline} street - A Leaflet Polyline layer for a street.\r\n */\n\n\nfunction streetToGraph(graph, street) {\n var street_id = street._leaflet_id,\n intersection_indices = [],\n street_points = street.getLatLngs(); //Populate intersection_indices with the indices of all of the street\'s intersections in its coordinate array.\n\n for (var cross_street in street.intersections) {\n var intersections = street.intersections[cross_street];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n var _loop = function _loop() {\n var intersection = _step.value;\n var intersection_index = intersection[1][street_id]; //Ignore duplicate intersection points (caused by 3-way intersections).\n\n if (!intersection_indices.some(function (other_intersection_index) {\n return other_intersection_index === intersection_index;\n })) {\n intersection_indices.push(intersection_index);\n }\n };\n\n for (var _iterator = intersections[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n _loop();\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n } //Sort the intersection_indices so that they are in order from the start of the street\'s coordinate array to the end;\n //this is why we\'re not getting the raw coordinates, but their indices first, so they can be sorted.\n\n\n intersection_indices = intersection_indices.sort(function (a, b) {\n return a - b;\n }); //Check if beginning and end points of the street are in the intersection_incides; if not, add them.\n\n if (!intersection_indices.some(function (intersection_index) {\n return intersection_index === 0;\n })) {\n intersection_indices.unshift(0);\n }\n\n if (!intersection_indices.some(function (intersection_index) {\n return intersection_index === street_points.length - 1;\n })) {\n intersection_indices.push(street_points.length - 1);\n } //Make a graph out of segments of the street between the start, intersections, and end of the street,\n //so that the nodes are the coordinates of the start, end, and intersection points, and the edges are\n //the segments between successive nodes. Each edge is associated with the geographic distance between its nodes.\n\n\n for (var i = 0; i <= intersection_indices.length - 2; i++) {\n var node_a = street_points[intersection_indices[i]],\n node_b = street_points[intersection_indices[i + 1]],\n a_string = encodeLatLng(node_a),\n b_string = encodeLatLng(node_b),\n start_coords = L.A.pointToCoordinateArray(node_a),\n end_coords = L.A.pointToCoordinateArray(node_b),\n segment = lineSlice(start_coords, end_coords, street.toGeoJSON()),\n distance = length(segment);\n graph.addLink(a_string, b_string, {\n distance: distance,\n place: {\n type: "street",\n id: street_id\n }\n });\n }\n}\n/**\r\n * Given a street network (graph), return a pathfinder that can operate on it.\r\n * Useful if you modify the street graph during the simulation.\r\n * \r\n * @param {object} graph - An ngraph graph representing an OSM street network.\r\n * @returns {object} - An A* pathfinder for the graph.\r\n */\n\n\nfunction getPathFinder(graph) {\n return path.aStar(graph, {\n distance: function distance(fromNode, toNode, link) {\n return link.data.distance;\n }\n });\n}\n/**\r\n * Get a path between two points on a graph.\r\n * @memberof Agentmap\r\n * @instance\r\n * @private\r\n *\r\n * @param start_int_lat_lng {LatLng} - The coordinates of the nearest intersection on the same street at the start_lat_lng.\r\n * @param goal_int_lat_lng {LatLng} - The coordinates of the nearest intersection on the same street as the goal_lat_lng.\r\n * @param start_lat_lng {LatLng} - The coordinates of the point on the street from which the agent will be traveling.\r\n * @param goal_lat_lng {LatLng} - The coordinates of the point on the street to which the agent should travel.\r\n * @param {Boolean} [sparse=false] - Whether to exclude intersections between the first and last along a street-specific path (which are superfluous for extracting the necessary sub-street).\r\n * @return {Array>} - An array of points along the graph, leading from the start to the end.\r\n */\n\n\nfunction getPath(start_int_lat_lng, goal_int_lat_lng, start_lat_lng, goal_lat_lng) {\n var sparse = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n var start_coord = encodeLatLng(start_int_lat_lng),\n end_coord = encodeLatLng(goal_int_lat_lng),\n encoded_path = this.pathfinder.find(start_coord, end_coord),\n path = [];\n\n if (encoded_path.length > 0 && decodeCoordString(encoded_path[0].id).distanceTo(start_int_lat_lng) > decodeCoordString(encoded_path[0].id).distanceTo(goal_int_lat_lng)) {\n encoded_path = encoded_path.reverse();\n }\n\n if (sparse === true && encoded_path.length >= 2) {\n var sparse_path = [],\n recent_street = null,\n current_street = null;\n\n for (var i = 0; i <= encoded_path.length - 2; i++) {\n current_street = this.streets.graph.getLink(encoded_path[i].id, encoded_path[i + 1].id) || this.streets.graph.getLink(encoded_path[i + 1].id, encoded_path[i].id);\n\n if (recent_street === null || current_street.data.place.id !== recent_street.data.place.id) {\n var decoded_coords = decodeCoordString(encoded_path[i].id, current_street.data.place);\n sparse_path.push(decoded_coords);\n } //If the last place on the path to the goal is labeled with a different street id than the goal,\n //add it to the sparse path.\t\n\n\n if (i === encoded_path.length - 2) {\n var _decoded_coords = decodeCoordString(encoded_path[i + 1].id, current_street.data.place);\n\n sparse_path.push(_decoded_coords);\n }\n }\n\n path = sparse_path;\n } else {\n path = encoded_path.map(function (point) {\n return decodeCoordString(point.id, 0);\n });\n }\n\n path.unshift(start_lat_lng);\n path.push(goal_lat_lng); //If the goal point lies before the first intersection of the goal street, then the 2nd to last point in the\n //path will have the previous street\'s id attached to it. If the goal lies on a different street, make\n //sure the 2nd to last point (the street path intersection point before the goal) has the same street id as the goal.\n\n if (path[path.length - 2].new_place.id !== goal_lat_lng.new_place.id) {\n path[path.length - 2].new_place = goal_lat_lng.new_place;\n } //If the second [to last] point--namely the intersection closest to the start [goal]--is further from the third\n //[to last] point than the goal, and all three points are on the same street, remove the second [to last] point.\n\n\n if (path.length >= 3) {\n checkStartExcess.call(this, path);\n checkEndExcess.call(this, path);\n }\n\n return path;\n} //checkStartExcess and checkEndExcess are _much_ easier to follow given distinct variable names,\n//and so they are not abstracted into one more general function.\n\n/** \r\n * If the first two points after the start point share the same street as the start point, and the\r\n * third point is closer to the first (start) point than it is to the second point, remove the \r\n * second point, as it\'s a superfluous detour.

\r\n *\r\n * Typically happens when the start point\'s nearest intersection is beyond it on the street,\r\n * and so the path would have an agent travel from the start, then to the intersection,\r\n * then backwards to the third point.\r\n * @private\r\n *\r\n * @param {Array} path - An array of LatLngs representing a path for an agent to travel along.\r\n */\n\n\nfunction checkStartExcess(path) {\n var start_street = this.streets.getLayer(path[0].new_place.id),\n second_street_id = path[1].new_place.id,\n start_second_intersections = start_street.intersections[second_street_id],\n second_is_intersection = typeof start_second_intersections === "undefined" ? false : start_second_intersections.some(function (intersection) {\n return intersection[0].lat === path[1].lat && intersection[0].lng === path[1].lng;\n }),\n third_street_id = path[2].new_place.id,\n start_third_intersections = start_street.intersections[third_street_id],\n third_is_intersection = typeof start_third_intersections === "undefined" ? false : start_third_intersections.some(function (intersection) {\n return intersection[0].lat === path[2].lat && intersection[0].lng === path[2].lng;\n });\n\n if ((second_is_intersection || second_street_id === path[0].new_place.id) && (third_is_intersection || third_street_id === path[0].new_place.id)) {\n if (path[2].distanceTo(path[0]) < path[2].distanceTo(path[1])) {\n path.splice(1, 1);\n }\n }\n}\n/** \r\n * If the last two points before the goal point share the same street as the goal point, and the\r\n * first point is closer to the third (goal) point than it is to the second point, remove the \r\n * second point, as it\'s a superfluous detour.

\r\n *\r\n * Typically happens when the goal point\'s nearest intersection is beyond it on the street,\r\n * and so the path would have an agent travel from the first point, then to the intersection (second point),\r\n * then backwards to the (third) goal point.

\r\n *\r\n * @private\r\n *\r\n * @param {Array} path - An array of LatLngs representing a path for an agent to travel along.\r\n */\n\n\nfunction checkEndExcess(path) {\n var goal_street = this.streets.getLayer(path[path.length - 1].new_place.id),\n second_to_last_street_id = path[path.length - 2].new_place.id,\n goal_second_to_last_intersections = goal_street.intersections[second_to_last_street_id],\n second_to_last_is_intersection = typeof goal_second_to_last_intersections === "undefined" ? false : goal_second_to_last_intersections.some(function (intersection) {\n return intersection[0].lat === path[path.length - 1].lat && intersection[0].lng === path[path.length - 1].lng;\n }),\n third_last_street_id = path[path.length - 3].new_place.id,\n goal_third_last_intersections = goal_street.intersections[third_last_street_id],\n third_last_is_intersection = typeof goal_third_last_intersections === "undefined" ? false : goal_third_last_intersections.some(function (intersection) {\n return intersection[0].lat === path[path.length - 3].lat && intersection[0].lng === path[path.length - 3].lng;\n });\n\n if ((second_to_last_is_intersection || second_to_last_street_id === path[path.length - 1].new_place.id) && (third_last_is_intersection || third_last_street_id === path[path.length - 1].new_place.id) && path.length >= 3) {\n if (path[path.length - 3].distanceTo(path[path.length - 1]) < path[path.length - 3].distanceTo(path[path.length - 2])) {\n path.splice(path.length - 2, 1);\n }\n }\n}\n/**\r\n * Turn a LatLng object into a string representing its coordinates (to act as a graph node\'s ID).\r\n * @private\r\n *\r\n * @param {LatLng} lat_lng - The coordinates to encode into a string.\r\n * @returns {string} - A string containing coordinates in the format of "Latitude,Longitude".\r\n */\n\n\nfunction encodeLatLng(lat_lng) {\n return lat_lng.lat.toString() + "," + lat_lng.lng.toString();\n}\n/**\r\n * Turn a string containing coordinates (a graph node\'s ID) into a LatLng object.\r\n * @private\r\n *\r\n * @param {string} coord_string - A string containing coordinates in the format of "Latitude,Longitude".\r\n * @param {object} place - An object specifying the place of the coordinate string.\r\n * @returns {LatLng} - The coordinates encoded by the coord_string.\r\n */\n\n\nfunction decodeCoordString(coord_string, place) {\n var coord_strings = coord_string.split(","),\n lat_lng = L.latLng(coord_strings);\n lat_lng.new_place = place;\n return lat_lng;\n}\n\nAgentmap.prototype.getPath = getPath;\nexports.streetsToGraph = streetsToGraph;\nexports.getPathFinder = getPathFinder;\nexports.encodeLatLng = encodeLatLng;\n\n//# sourceURL=webpack:///./src/routing.js?')},function(module,exports){eval("/**\n * Based on https://github.com/mourner/tinyqueue\n * Copyright (c) 2017, Vladimir Agafonkin https://github.com/mourner/tinyqueue/blob/master/LICENSE\n * \n * Adapted for PathFinding needs by @anvaka\n * Copyright (c) 2017, Andrei Kashcha\n */\nmodule.exports = NodeHeap;\n\nfunction NodeHeap(data, options) {\n if (!(this instanceof NodeHeap)) return new NodeHeap(data, options);\n\n if (!Array.isArray(data)) {\n // assume first argument is our config object;\n options = data;\n data = [];\n }\n\n options = options || {};\n\n this.data = data || [];\n this.length = this.data.length;\n this.compare = options.compare || defaultCompare;\n this.setNodeId = options.setNodeId || noop;\n\n if (this.length > 0) {\n for (var i = (this.length >> 1); i >= 0; i--) this._down(i);\n }\n\n if (options.setNodeId) {\n for (var i = 0; i < this.length; ++i) {\n this.setNodeId(this.data[i], i);\n }\n }\n}\n\nfunction noop() {}\n\nfunction defaultCompare(a, b) {\n return a - b;\n}\n\nNodeHeap.prototype = {\n\n push: function (item) {\n this.data.push(item);\n this.setNodeId(item, this.length);\n this.length++;\n this._up(this.length - 1);\n },\n\n pop: function () {\n if (this.length === 0) return undefined;\n\n var top = this.data[0];\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = this.data[this.length];\n this.setNodeId(this.data[0], 0);\n this._down(0);\n }\n this.data.pop();\n\n return top;\n },\n\n peek: function () {\n return this.data[0];\n },\n\n updateItem: function (pos) {\n this._down(pos);\n this._up(pos);\n },\n\n _up: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var setNodeId = this.setNodeId;\n var item = data[pos];\n\n while (pos > 0) {\n var parent = (pos - 1) >> 1;\n var current = data[parent];\n if (compare(item, current) >= 0) break;\n data[pos] = current;\n\n setNodeId(current, pos);\n pos = parent;\n }\n\n data[pos] = item;\n setNodeId(item, pos);\n },\n\n _down: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var halfLength = this.length >> 1;\n var item = data[pos];\n var setNodeId = this.setNodeId;\n\n while (pos < halfLength) {\n var left = (pos << 1) + 1;\n var right = left + 1;\n var best = data[left];\n\n if (right < this.length && compare(data[right], best) < 0) {\n left = right;\n best = data[right];\n }\n if (compare(best, item) >= 0) break;\n\n data[pos] = best;\n setNodeId(best, pos);\n pos = left;\n }\n\n data[pos] = item;\n setNodeId(item, pos);\n }\n};\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/NodeHeap.js?")},function(module,exports){eval("module.exports = {\n l2: l2,\n l1: l1\n};\n\n/**\n * Euclid distance (l2 norm);\n * \n * @param {*} a \n * @param {*} b \n */\nfunction l2(a, b) {\n var dx = a.x - b.x;\n var dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * Manhattan distance (l1 norm);\n * @param {*} a \n * @param {*} b \n */\nfunction l1(a, b) {\n var dx = a.x - b.x;\n var dy = a.y - b.y;\n return Math.abs(dx) + Math.abs(dy);\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/heuristics.js?")},function(module,exports){eval("// We reuse instance of array, but we trie to freeze it as well,\n// so that consumers don't modify it. Maybe it's a bad idea.\nvar NO_PATH = [];\nif (typeof Object.freeze === 'function') Object.freeze(NO_PATH);\n\nmodule.exports = {\n // Path search settings\n heuristic: blindHeuristic,\n distance: constantDistance,\n compareFScore: compareFScore,\n NO_PATH: NO_PATH,\n\n // heap settings\n setHeapIndex: setHeapIndex,\n\n // nba:\n setH1: setH1,\n setH2: setH2,\n compareF1Score: compareF1Score,\n compareF2Score: compareF2Score,\n}\n\nfunction blindHeuristic(/* a, b */) {\n // blind heuristic makes this search equal to plain Dijkstra path search.\n return 0;\n}\n\nfunction constantDistance(/* a, b */) {\n return 1;\n}\n\nfunction compareFScore(a, b) {\n var result = a.fScore - b.fScore;\n // TODO: Can I improve speed with smarter ties-breaking?\n // I tried distanceToSource, but it didn't seem to have much effect\n return result;\n}\n\nfunction setHeapIndex(nodeSearchState, heapIndex) {\n nodeSearchState.heapIndex = heapIndex;\n}\n\nfunction compareF1Score(a, b) {\n return a.f1 - b.f1;\n}\n\nfunction compareF2Score(a, b) {\n return a.f2 - b.f2;\n}\n\nfunction setH1(node, heapIndex) {\n node.h1 = heapIndex;\n}\n\nfunction setH2(node, heapIndex) {\n node.h2 = heapIndex;\n}\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/defaultSettings.js?")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar factors = {\n meters: earthRadius,\n metres: earthRadius,\n millimeters: earthRadius * 1000,\n millimetres: earthRadius * 1000,\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n kilometers: earthRadius / 1000,\n kilometres: earthRadius / 1000,\n miles: earthRadius / 1609.344,\n nauticalmiles: earthRadius / 1852,\n inches: earthRadius * 39.370,\n yards: earthRadius / 1.0936,\n feet: earthRadius * 3.28084,\n radians: 1,\n degrees: earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = point(coordinates).geometry; break;\n case 'LineString': geom = lineString(coordinates).geometry; break;\n case 'Polygon': geom = polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/invariant/main.es.js\n\n\n/**\n * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate.\n *\n * @name getCoord\n * @param {Array|Geometry|Feature} coord GeoJSON Point or an Array of numbers\n * @returns {Array} coordinates\n * @example\n * var pt = turf.point([10, 10]);\n *\n * var coord = turf.getCoord(pt);\n * //= [10, 10]\n */\nfunction getCoord(coord) {\n if (!coord) throw new Error('coord is required');\n if (coord.type === 'Feature' && coord.geometry !== null && coord.geometry.type === 'Point') return coord.geometry.coordinates;\n if (coord.type === 'Point') return coord.coordinates;\n if (Array.isArray(coord) && coord.length >= 2 && coord[0].length === undefined && coord[1].length === undefined) return coord;\n\n throw new Error('coord must be GeoJSON Point or an Array of numbers');\n}\n\n/**\n * Unwrap coordinates from a Feature, Geometry Object or an Array\n *\n * @name getCoords\n * @param {Array|Geometry|Feature} coords Feature, Geometry Object or an Array\n * @returns {Array} coordinates\n * @example\n * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]);\n *\n * var coords = turf.getCoords(poly);\n * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]\n */\nfunction getCoords(coords) {\n if (!coords) throw new Error('coords is required');\n\n // Feature\n if (coords.type === 'Feature' && coords.geometry !== null) return coords.geometry.coordinates;\n\n // Geometry\n if (coords.coordinates) return coords.coordinates;\n\n // Array of numbers\n if (Array.isArray(coords)) return coords;\n\n throw new Error('coords must be GeoJSON Feature, Geometry Object or an Array');\n}\n\n/**\n * Checks if coordinates contains a number\n *\n * @name containsNumber\n * @param {Array} coordinates GeoJSON Coordinates\n * @returns {boolean} true if Array contains a number\n */\nfunction containsNumber(coordinates) {\n if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) {\n return true;\n }\n\n if (Array.isArray(coordinates[0]) && coordinates[0].length) {\n return containsNumber(coordinates[0]);\n }\n throw new Error('coordinates must only contain numbers');\n}\n\n/**\n * Enforce expectations about types of GeoJSON objects for Turf.\n *\n * @name geojsonType\n * @param {GeoJSON} value any GeoJSON object\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction geojsonType(value, type, name) {\n if (!type || !name) throw new Error('type and name required');\n\n if (!value || value.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link Feature} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name featureOf\n * @param {Feature} feature a feature with an expected geometry type\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} error if value is not the expected type.\n */\nfunction featureOf(feature, type, name) {\n if (!feature) throw new Error('No feature passed');\n if (!name) throw new Error('.featureOf() requires a name');\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link FeatureCollection} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name collectionOf\n * @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction collectionOf(featureCollection, type, name) {\n if (!featureCollection) throw new Error('No featureCollection passed');\n if (!name) throw new Error('.collectionOf() requires a name');\n if (!featureCollection || featureCollection.type !== 'FeatureCollection') {\n throw new Error('Invalid input to ' + name + ', FeatureCollection required');\n }\n for (var i = 0; i < featureCollection.features.length; i++) {\n var feature = featureCollection.features[i];\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n }\n}\n\n/**\n * Get Geometry from Feature or Geometry Object\n *\n * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object\n * @returns {Geometry|null} GeoJSON Geometry Object\n * @throws {Error} if geojson is not a Feature or Geometry Object\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getGeom(point)\n * //={\"type\": \"Point\", \"coordinates\": [110, 40]}\n */\nfunction getGeom(geojson) {\n if (!geojson) throw new Error('geojson is required');\n if (geojson.geometry !== undefined) return geojson.geometry;\n if (geojson.coordinates || geojson.geometries) return geojson;\n throw new Error('geojson must be a valid Feature or Geometry Object');\n}\n\n/**\n * Get Geometry Type from Feature or Geometry Object\n *\n * @throws {Error} **DEPRECATED** in v5.0.0 in favor of getType\n */\nfunction getGeomType() {\n throw new Error('invariant.getGeomType has been deprecated in v5.0 in favor of invariant.getType');\n}\n\n/**\n * Get GeoJSON object's type, Geometry type is prioritize.\n *\n * @param {GeoJSON} geojson GeoJSON object\n * @param {string} [name=\"geojson\"] name of the variable to display in error message\n * @returns {string} GeoJSON type\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getType(point)\n * //=\"Point\"\n */\nfunction getType(geojson, name) {\n if (!geojson) throw new Error((name || 'geojson') + ' is required');\n // GeoJSON Feature & GeometryCollection\n if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type;\n // GeoJSON Geometry & FeatureCollection\n if (geojson.type) return geojson.type;\n throw new Error((name || 'geojson') + ' is invalid');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/bearing/main.es.js\n\n\n\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n\n/**\n * Takes two {@link Point|points} and finds the geographic bearing between them,\n * i.e. the angle measured in degrees from the north line (0 degrees)\n *\n * @name bearing\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.final=false] calculates the final bearing if true\n * @returns {number} bearing in decimal degrees, between -180 and 180 degrees (positive clockwise)\n * @example\n * var point1 = turf.point([-75.343, 39.984]);\n * var point2 = turf.point([-75.534, 39.123]);\n *\n * var bearing = turf.bearing(point1, point2);\n *\n * //addToMap\n * var addToMap = [point1, point2]\n * point1.properties['marker-color'] = '#f00'\n * point2.properties['marker-color'] = '#0f0'\n * point1.properties.bearing = bearing\n */\nfunction main_es_bearing(start, end, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var final = options.final;\n\n // Reverse calculation\n if (final === true) return calculateFinalBearing(start, end);\n\n var coordinates1 = getCoord(start);\n var coordinates2 = getCoord(end);\n\n var lon1 = degreesToRadians(coordinates1[0]);\n var lon2 = degreesToRadians(coordinates2[0]);\n var lat1 = degreesToRadians(coordinates1[1]);\n var lat2 = degreesToRadians(coordinates2[1]);\n var a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n var b = Math.cos(lat1) * Math.sin(lat2) -\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n\n return radiansToDegrees(Math.atan2(a, b));\n}\n\n/**\n * Calculates Final Bearing\n *\n * @private\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @returns {number} bearing\n */\nfunction calculateFinalBearing(start, end) {\n // Swap start & end\n var bear = main_es_bearing(end, start);\n bear = (bear + 180) % 360;\n return bear;\n}\n\n/* harmony default export */ var main_es = (main_es_bearing);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/distance/main.es.js\n\n\n\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n\n/**\n * Calculates the distance between two {@link Point|points} in degrees, radians,\n * miles, or kilometers. This uses the\n * [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula)\n * to account for global curvature.\n *\n * @name distance\n * @param {Coord} from origin point\n * @param {Coord} to destination point\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {number} distance between the two points\n * @example\n * var from = turf.point([-75.343, 39.984]);\n * var to = turf.point([-75.534, 39.123]);\n * var options = {units: 'miles'};\n *\n * var distance = turf.distance(from, to, options);\n *\n * //addToMap\n * var addToMap = [from, to];\n * from.properties.distance = distance;\n * to.properties.distance = distance;\n */\nfunction main_es_distance(from, to, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var units = options.units;\n\n var coordinates1 = getCoord(from);\n var coordinates2 = getCoord(to);\n var dLat = degreesToRadians((coordinates2[1] - coordinates1[1]));\n var dLon = degreesToRadians((coordinates2[0] - coordinates1[0]));\n var lat1 = degreesToRadians(coordinates1[1]);\n var lat2 = degreesToRadians(coordinates2[1]);\n\n var a = Math.pow(Math.sin(dLat / 2), 2) +\n Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);\n\n return radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), units);\n}\n\n/* harmony default export */ var distance_main_es = (main_es_distance);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/destination/main.es.js\n\n\n\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n/**\n * Takes a {@link Point} and calculates the location of a destination point given a distance in degrees, radians, miles, or kilometers; and bearing in degrees. This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature.\n *\n * @name destination\n * @param {Coord} origin starting point\n * @param {number} distance distance from the origin point\n * @param {number} bearing ranging from -180 to 180\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians\n * @param {Object} [options.properties={}] Translate properties to Point\n * @returns {Feature} destination point\n * @example\n * var point = turf.point([-75.343, 39.984]);\n * var distance = 50;\n * var bearing = 90;\n * var options = {units: 'miles'};\n *\n * var destination = turf.destination(point, distance, bearing, options);\n *\n * //addToMap\n * var addToMap = [point, destination]\n * destination.properties['marker-color'] = '#f00';\n * point.properties['marker-color'] = '#0f0';\n */\nfunction destination(origin, distance, bearing, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var units = options.units;\n var properties = options.properties;\n\n // Handle input\n var coordinates1 = getCoord(origin);\n var longitude1 = degreesToRadians(coordinates1[0]);\n var latitude1 = degreesToRadians(coordinates1[1]);\n var bearing_rad = degreesToRadians(bearing);\n var radians = lengthToRadians(distance, units);\n\n // Main\n var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +\n Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearing_rad));\n var longitude2 = longitude1 + Math.atan2(Math.sin(bearing_rad) * Math.sin(radians) * Math.cos(latitude1),\n Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));\n var lng = radiansToDegrees(longitude2);\n var lat = radiansToDegrees(latitude2);\n\n return point([lng, lat], properties);\n}\n\n/* harmony default export */ var destination_main_es = (destination);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/geojson-rbush/quickselect.js\nfunction quickselect(arr, k, left, right, compare) {\n quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);\n}\n\nfunction quickselectStep(arr, k, left, right, compare) {\n\n while (right > left) {\n if (right - left > 600) {\n var n = right - left + 1;\n var m = k - left + 1;\n var z = Math.log(n);\n var s = 0.5 * Math.exp(2 * z / 3);\n var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselectStep(arr, k, newLeft, newRight, compare);\n }\n\n var t = arr[k];\n var i = left;\n var j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap(arr, i, j) {\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/* harmony default export */ var geojson_rbush_quickselect = (quickselect);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/geojson-rbush/rbush.js\n\n\nfunction rbush(maxEntries, format) {\n if (!(this instanceof rbush)) return new rbush(maxEntries, format);\n\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries || 9);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\n if (format) {\n this._initFormat(format);\n }\n\n this.clear();\n}\n\nrbush.prototype = {\n\n all: function () {\n return this._all(this.data, []);\n },\n\n search: function (bbox) {\n\n var node = this.data,\n result = [],\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return result;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return result;\n },\n\n collides: function (bbox) {\n\n var node = this.data,\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return false;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) return true;\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return false;\n },\n\n load: function (data) {\n if (!(data && data.length)) return this;\n\n if (data.length < this._minEntries) {\n for (var i = 0, len = data.length; i < len; i++) {\n this.insert(data[i]);\n }\n return this;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n var node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n var tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n\n return this;\n },\n\n insert: function (item) {\n if (item) this._insert(item, this.data.height - 1);\n return this;\n },\n\n clear: function () {\n this.data = createNode([]);\n return this;\n },\n\n remove: function (item, equalsFn) {\n if (!item) return this;\n\n var node = this.data,\n bbox = this.toBBox(item),\n path = [],\n indexes = [],\n i, parent, index, goingUp;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n\n if (!node) { // go up\n node = path.pop();\n parent = path[path.length - 1];\n i = indexes.pop();\n goingUp = true;\n }\n\n if (node.leaf) { // check current node\n index = findItem(item, node.children, equalsFn);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n return this;\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n path.push(node);\n indexes.push(i);\n i = 0;\n parent = node;\n node = node.children[0];\n\n } else if (parent) { // go right\n i++;\n node = parent.children[i];\n goingUp = false;\n\n } else node = null; // nothing found\n }\n\n return this;\n },\n\n toBBox: function (item) { return item; },\n\n compareMinX: compareNodeMinX,\n compareMinY: compareNodeMinY,\n\n toJSON: function () { return this.data; },\n\n fromJSON: function (data) {\n this.data = data;\n return this;\n },\n\n _all: function (node, result) {\n var nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push.apply(result, node.children);\n else nodesToSearch.push.apply(nodesToSearch, node.children);\n\n node = nodesToSearch.pop();\n }\n return result;\n },\n\n _build: function (items, left, right, height) {\n\n var N = right - left + 1,\n M = this._maxEntries,\n node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n var N2 = Math.ceil(N / M),\n N1 = N2 * Math.ceil(Math.sqrt(M)),\n i, j, right2, right3;\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (i = left; i <= right; i += N1) {\n\n right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (j = i; j <= right2; j += N2) {\n\n right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n },\n\n _chooseSubtree: function (bbox, node, level, path) {\n\n var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;\n\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) break;\n\n minArea = minEnlargement = Infinity;\n\n for (i = 0, len = node.children.length; i < len; i++) {\n child = node.children[i];\n area = bboxArea(child);\n enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n },\n\n _insert: function (item, level, isNode) {\n\n var toBBox = this.toBBox,\n bbox = isNode ? item : toBBox(item),\n insertPath = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n var node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n },\n\n // split overflowed node into two\n _split: function (insertPath, level) {\n\n var node = insertPath[level],\n M = node.children.length,\n m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n var splitIndex = this._chooseSplitIndex(node, m, M);\n\n var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n },\n\n _splitRoot: function (node, newNode) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n },\n\n _chooseSplitIndex: function (node, m, M) {\n\n var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;\n\n minOverlap = minArea = Infinity;\n\n for (i = m; i <= M - m; i++) {\n bbox1 = distBBox(node, 0, i, this.toBBox);\n bbox2 = distBBox(node, i, M, this.toBBox);\n\n overlap = intersectionArea(bbox1, bbox2);\n area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index;\n },\n\n // sorts node children by the best axis for split\n _chooseSplitAxis: function (node, m, M) {\n\n var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,\n compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,\n xMargin = this._allDistMargin(node, m, M, compareMinX),\n yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) node.children.sort(compareMinX);\n },\n\n // total margin of all possible split distributions where each node is at least m full\n _allDistMargin: function (node, m, M, compare) {\n\n node.children.sort(compare);\n\n var toBBox = this.toBBox,\n leftBBox = distBBox(node, 0, m, toBBox),\n rightBBox = distBBox(node, M - m, M, toBBox),\n margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),\n i, child;\n\n for (i = m; i < M - m; i++) {\n child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (i = M - m - 1; i >= m; i--) {\n child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n },\n\n _adjustParentBBoxes: function (bbox, path, level) {\n // adjust bboxes along the given tree path\n for (var i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n },\n\n _condense: function (path) {\n // go through the path, removing empty nodes and updating bboxes\n for (var i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n\n } else this.clear();\n\n } else calcBBox(path[i], this.toBBox);\n }\n },\n\n _initFormat: function (format) {\n // data format (minX, minY, maxX, maxY accessors)\n\n // uses eval-type function compilation instead of just accepting a toBBox function\n // because the algorithms are very sensitive to sorting functions performance,\n // so they should be dead simple and without inner calls\n\n var compareArr = ['return a', ' - b', ';'];\n\n this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));\n this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));\n\n this.toBBox = new Function('a',\n 'return {minX: a' + format[0] +\n ', minY: a' + format[1] +\n ', maxX: a' + format[2] +\n ', maxY: a' + format[3] + '};');\n }\n};\n\nfunction findItem(item, items, equalsFn) {\n if (!equalsFn) return items.indexOf(item);\n\n for (var i = 0; i < items.length; i++) {\n if (equalsFn(item, items[i])) return i;\n }\n return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n if (!destNode) destNode = createNode(null);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (var i = k, child; i < p; i++) {\n child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a, b) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n var minX = Math.max(a.minX, b.minX),\n minY = Math.max(a.minY, b.minY),\n maxX = Math.min(a.maxX, b.maxX),\n maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) *\n Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n return a.minX <= b.minX &&\n a.minY <= b.minY &&\n b.maxX <= a.maxX &&\n b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n return b.minX <= a.maxX &&\n b.minY <= a.maxY &&\n b.maxX >= a.minX &&\n b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n return {\n children: children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n var stack = [left, right],\n mid;\n\n while (stack.length) {\n right = stack.pop();\n left = stack.pop();\n\n if (right - left <= n) continue;\n\n mid = left + Math.ceil((right - left) / n / 2) * n;\n geojson_rbush_quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n\n/* harmony default export */ var geojson_rbush_rbush = (rbush);\n\n// EXTERNAL MODULE: ./node_modules/@turf/meta/main.es.js + 1 modules\nvar meta_main_es = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/geojson-rbush/index.js\n\n\n\n/**\n * GeoJSON implementation of [RBush](https://github.com/mourner/rbush#rbush) spatial index.\n *\n * @name rbush\n * @param {number} [maxEntries=9] defines the maximum number of entries in a tree node. 9 (used by default) is a\n * reasonable choice for most applications. Higher value means faster insertion and slower search, and vice versa.\n * @returns {RBush} GeoJSON RBush\n * @example\n * import geojsonRbush from 'geojson-rbush';\n * var tree = geojsonRbush();\n */\nfunction geojsonRbush(maxEntries) {\n var tree = geojson_rbush_rbush(maxEntries);\n /**\n * [insert](https://github.com/mourner/rbush#data-format)\n *\n * @param {Feature} feature insert single GeoJSON Feature\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.insert(polygon)\n */\n tree.insert = function (feature) {\n if (Array.isArray(feature)) {\n var bbox = feature;\n feature = bboxPolygon(bbox);\n feature.bbox = bbox;\n } else {\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n }\n return geojson_rbush_rbush.prototype.insert.call(this, feature);\n };\n\n /**\n * [load](https://github.com/mourner/rbush#bulk-inserting-data)\n *\n * @param {BBox[]|FeatureCollection} features load entire GeoJSON FeatureCollection\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polygons = {\n * \"type\": \"FeatureCollection\",\n * \"features\": [\n * {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * },\n * {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]]\n * }\n * }\n * ]\n * }\n * tree.load(polygons)\n */\n tree.load = function (features) {\n var load = [];\n // Load an Array of BBox\n if (Array.isArray(features)) {\n features.forEach(function (bbox) {\n var feature = bboxPolygon(bbox);\n feature.bbox = bbox;\n load.push(feature);\n });\n } else {\n // Load FeatureCollection\n Object(meta_main_es[\"b\" /* featureEach */])(features, function (feature) {\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n load.push(feature);\n });\n }\n return geojson_rbush_rbush.prototype.load.call(this, load);\n };\n\n /**\n * [remove](https://github.com/mourner/rbush#removing-data)\n *\n * @param {BBox|Feature} feature remove single GeoJSON Feature\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.remove(polygon)\n */\n tree.remove = function (feature) {\n if (Array.isArray(feature)) {\n var bbox = feature;\n feature = bboxPolygon(bbox);\n feature.bbox = bbox;\n }\n return geojson_rbush_rbush.prototype.remove.call(this, feature);\n };\n\n /**\n * [clear](https://github.com/mourner/rbush#removing-data)\n *\n * @returns {RBush} GeoJSON Rbush\n * @example\n * tree.clear()\n */\n tree.clear = function () {\n return geojson_rbush_rbush.prototype.clear.call(this);\n };\n\n /**\n * [search](https://github.com/mourner/rbush#search)\n *\n * @param {BBox|FeatureCollection|Feature} geojson search with GeoJSON\n * @returns {FeatureCollection} all features that intersects with the given GeoJSON.\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.search(polygon)\n */\n tree.search = function (geojson) {\n var features = geojson_rbush_rbush.prototype.search.call(this, this.toBBox(geojson));\n return {\n type: 'FeatureCollection',\n features: features\n };\n };\n\n /**\n * [collides](https://github.com/mourner/rbush#collisions)\n *\n * @param {BBox|FeatureCollection|Feature} geojson collides with GeoJSON\n * @returns {boolean} true if there are any items intersecting the given GeoJSON, otherwise false.\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.collides(polygon)\n */\n tree.collides = function (geojson) {\n return geojson_rbush_rbush.prototype.collides.call(this, this.toBBox(geojson));\n };\n\n /**\n * [all](https://github.com/mourner/rbush#search)\n *\n * @returns {FeatureCollection} all the features in RBush\n * @example\n * tree.all()\n * //=FeatureCollection\n */\n tree.all = function () {\n var features = geojson_rbush_rbush.prototype.all.call(this);\n return {\n type: 'FeatureCollection',\n features: features\n };\n };\n\n /**\n * [toJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @returns {any} export data as JSON object\n * @example\n * var exported = tree.toJSON()\n * //=JSON object\n */\n tree.toJSON = function () {\n return geojson_rbush_rbush.prototype.toJSON.call(this);\n };\n\n /**\n * [fromJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @param {any} json import previously exported data\n * @returns {RBush} GeoJSON RBush\n * @example\n * var exported = {\n * \"children\": [\n * {\n * \"type\": \"Feature\",\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * },\n * \"properties\": {},\n * \"bbox\": [110, 50, 110, 50]\n * }\n * ],\n * \"height\": 1,\n * \"leaf\": true,\n * \"minX\": 110,\n * \"minY\": 50,\n * \"maxX\": 110,\n * \"maxY\": 50\n * }\n * tree.fromJSON(exported)\n */\n tree.fromJSON = function (json) {\n return geojson_rbush_rbush.prototype.fromJSON.call(this, json);\n };\n\n /**\n * Converts GeoJSON to {minX, minY, maxX, maxY} schema\n *\n * @private\n * @param {BBox|FeatureCollectio|Feature} geojson feature(s) to retrieve BBox from\n * @returns {Object} converted to {minX, minY, maxX, maxY}\n */\n tree.toBBox = function (geojson) {\n var bbox;\n if (geojson.bbox) bbox = geojson.bbox;\n else if (Array.isArray(geojson) && geojson.length === 4) bbox = geojson;\n else bbox = turfBBox(geojson);\n\n return {\n minX: bbox[0],\n minY: bbox[1],\n maxX: bbox[2],\n maxY: bbox[3]\n };\n };\n return tree;\n}\n\n/**\n * Takes a bbox and returns an equivalent {@link Polygon|polygon}.\n *\n * @private\n * @name bboxPolygon\n * @param {Array} bbox extent in [minX, minY, maxX, maxY] order\n * @returns {Feature} a Polygon representation of the bounding box\n * @example\n * var bbox = [0, 0, 10, 10];\n *\n * var poly = turf.bboxPolygon(bbox);\n *\n * //addToMap\n * var addToMap = [poly]\n */\nfunction bboxPolygon(bbox) {\n var lowLeft = [bbox[0], bbox[1]];\n var topLeft = [bbox[0], bbox[3]];\n var topRight = [bbox[2], bbox[3]];\n var lowRight = [bbox[2], bbox[1]];\n var coordinates = [[lowLeft, lowRight, topRight, topLeft, lowLeft]];\n\n return {\n type: 'Feature',\n bbox: bbox,\n properties: {},\n geometry: {\n type: 'Polygon',\n coordinates: coordinates\n }\n };\n}\n\n/**\n * Takes a set of features, calculates the bbox of all input features, and returns a bounding box.\n *\n * @private\n * @name bbox\n * @param {FeatureCollection|Feature} geojson input features\n * @returns {Array} bbox extent in [minX, minY, maxX, maxY] order\n * @example\n * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]);\n * var bbox = turf.bbox(line);\n * var bboxPolygon = turf.bboxPolygon(bbox);\n *\n * //addToMap\n * var addToMap = [line, bboxPolygon]\n */\nfunction turfBBox(geojson) {\n var bbox = [Infinity, Infinity, -Infinity, -Infinity];\n Object(meta_main_es[\"a\" /* coordEach */])(geojson, function (coord) {\n if (bbox[0] > coord[0]) bbox[0] = coord[0];\n if (bbox[1] > coord[1]) bbox[1] = coord[1];\n if (bbox[2] < coord[0]) bbox[2] = coord[0];\n if (bbox[3] < coord[1]) bbox[3] = coord[1];\n });\n return bbox;\n}\n\n/* harmony default export */ var geojson_rbush = (geojsonRbush);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/line-segment/main.es.js\n\n\n\n\n/**\n * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}.\n *\n * @name lineSegment\n * @param {Geometry|FeatureCollection|Feature} geojson GeoJSON Polygon or LineString\n * @returns {FeatureCollection} 2-vertex line segments\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n * var segments = turf.lineSegment(polygon);\n *\n * //addToMap\n * var addToMap = [polygon, segments]\n */\nfunction lineSegment(geojson) {\n if (!geojson) throw new Error('geojson is required');\n\n var results = [];\n Object(meta_main_es[\"c\" /* flattenEach */])(geojson, function (feature) {\n lineSegmentFeature(feature, results);\n });\n return featureCollection(results);\n}\n\n/**\n * Line Segment\n *\n * @private\n * @param {Feature} geojson Line or polygon feature\n * @param {Array} results push to results\n * @returns {void}\n */\nfunction lineSegmentFeature(geojson, results) {\n var coords = [];\n var geometry = geojson.geometry;\n switch (geometry.type) {\n case 'Polygon':\n coords = getCoords(geometry);\n break;\n case 'LineString':\n coords = [getCoords(geometry)];\n }\n coords.forEach(function (coord) {\n var segments = createSegments(coord, geojson.properties);\n segments.forEach(function (segment) {\n segment.id = results.length;\n results.push(segment);\n });\n });\n}\n\n/**\n * Create Segments from LineString coordinates\n *\n * @private\n * @param {LineString} coords LineString coordinates\n * @param {*} properties GeoJSON properties\n * @returns {Array>} line segments\n */\nfunction createSegments(coords, properties) {\n var segments = [];\n coords.reduce(function (previousCoords, currentCoords) {\n var segment = lineString([previousCoords, currentCoords], properties);\n segment.bbox = main_es_bbox(previousCoords, currentCoords);\n segments.push(segment);\n return currentCoords;\n });\n return segments;\n}\n\n/**\n * Create BBox between two coordinates (faster than @turf/bbox)\n *\n * @private\n * @param {Array} coords1 Point coordinate\n * @param {Array} coords2 Point coordinate\n * @returns {BBox} [west, south, east, north]\n */\nfunction main_es_bbox(coords1, coords2) {\n var x1 = coords1[0];\n var y1 = coords1[1];\n var x2 = coords2[0];\n var y2 = coords2[1];\n var west = (x1 < x2) ? x1 : x2;\n var south = (y1 < y2) ? y1 : y2;\n var east = (x1 > x2) ? x1 : x2;\n var north = (y1 > y2) ? y1 : y2;\n return [west, south, east, north];\n}\n\n/* harmony default export */ var line_segment_main_es = (lineSegment);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/line-intersect/main.es.js\n\n\n\n\n\n\n/**\n * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s).\n *\n * @name lineIntersect\n * @param {Geometry|FeatureCollection|Feature} line1 any LineString or Polygon\n * @param {Geometry|FeatureCollection|Feature} line2 any LineString or Polygon\n * @returns {FeatureCollection} point(s) that intersect both\n * @example\n * var line1 = turf.lineString([[126, -11], [129, -21]]);\n * var line2 = turf.lineString([[123, -18], [131, -14]]);\n * var intersects = turf.lineIntersect(line1, line2);\n *\n * //addToMap\n * var addToMap = [line1, line2, intersects]\n */\nfunction lineIntersect(line1, line2) {\n var unique = {};\n var results = [];\n\n // First, normalize geometries to features\n // Then, handle simple 2-vertex segments\n if (line1.type === 'LineString') line1 = main_es_feature(line1);\n if (line2.type === 'LineString') line2 = main_es_feature(line2);\n if (line1.type === 'Feature' &&\n line2.type === 'Feature' &&\n line1.geometry.type === 'LineString' &&\n line2.geometry.type === 'LineString' &&\n line1.geometry.coordinates.length === 2 &&\n line2.geometry.coordinates.length === 2) {\n var intersect = main_es_intersects(line1, line2);\n if (intersect) results.push(intersect);\n return featureCollection(results);\n }\n\n // Handles complex GeoJSON Geometries\n var tree = geojson_rbush();\n tree.load(line_segment_main_es(line2));\n Object(meta_main_es[\"b\" /* featureEach */])(line_segment_main_es(line1), function (segment) {\n Object(meta_main_es[\"b\" /* featureEach */])(tree.search(segment), function (match) {\n var intersect = main_es_intersects(segment, match);\n if (intersect) {\n // prevent duplicate points https://github.com/Turfjs/turf/issues/688\n var key = getCoords(intersect).join(',');\n if (!unique[key]) {\n unique[key] = true;\n results.push(intersect);\n }\n }\n });\n });\n return featureCollection(results);\n}\n\n/**\n * Find a point that intersects LineStrings with two coordinates each\n *\n * @private\n * @param {Feature} line1 GeoJSON LineString (Must only contain 2 coordinates)\n * @param {Feature} line2 GeoJSON LineString (Must only contain 2 coordinates)\n * @returns {Feature} intersecting GeoJSON Point\n */\nfunction main_es_intersects(line1, line2) {\n var coords1 = getCoords(line1);\n var coords2 = getCoords(line2);\n if (coords1.length !== 2) {\n throw new Error(' line1 must only contain 2 coordinates');\n }\n if (coords2.length !== 2) {\n throw new Error(' line2 must only contain 2 coordinates');\n }\n var x1 = coords1[0][0];\n var y1 = coords1[0][1];\n var x2 = coords1[1][0];\n var y2 = coords1[1][1];\n var x3 = coords2[0][0];\n var y3 = coords2[0][1];\n var x4 = coords2[1][0];\n var y4 = coords2[1][1];\n var denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));\n var numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));\n var numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));\n\n if (denom === 0) {\n if (numeA === 0 && numeB === 0) {\n return null;\n }\n return null;\n }\n\n var uA = numeA / denom;\n var uB = numeB / denom;\n\n if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {\n var x = x1 + (uA * (x2 - x1));\n var y = y1 + (uA * (y2 - y1));\n return point([x, y]);\n }\n return null;\n}\n\n/* harmony default export */ var line_intersect_main_es = (lineIntersect);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/nearest-point-on-line/main.es.js\n\n\n\n\n\n\n\n\n/**\n * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.\n *\n * @name nearestPointOnLine\n * @param {Geometry|Feature} lines lines to snap to\n * @param {Geometry|Feature|number[]} pt point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {Feature} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var pt = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, pt, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine(lines, pt, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n\n // validation\n var type = (lines.geometry) ? lines.geometry.type : lines.type;\n if (type !== 'LineString' && type !== 'MultiLineString') {\n throw new Error('lines must be LineString or MultiLineString');\n }\n\n var closestPt = point([Infinity, Infinity], {\n dist: Infinity\n });\n\n var length = 0.0;\n Object(meta_main_es[\"c\" /* flattenEach */])(lines, function (line) {\n var coords = getCoords(line);\n\n for (var i = 0; i < coords.length - 1; i++) {\n //start\n var start = point(coords[i]);\n start.properties.dist = distance_main_es(pt, start, options);\n //stop\n var stop = point(coords[i + 1]);\n stop.properties.dist = distance_main_es(pt, stop, options);\n // sectionLength\n var sectionLength = distance_main_es(start, stop, options);\n //perpendicular\n var heightDistance = Math.max(start.properties.dist, stop.properties.dist);\n var direction = main_es(start, stop);\n var perpendicularPt1 = destination_main_es(pt, heightDistance, direction + 90, options);\n var perpendicularPt2 = destination_main_es(pt, heightDistance, direction - 90, options);\n var intersect = line_intersect_main_es(\n lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]),\n lineString([start.geometry.coordinates, stop.geometry.coordinates])\n );\n var intersectPt = null;\n if (intersect.features.length > 0) {\n intersectPt = intersect.features[0];\n intersectPt.properties.dist = distance_main_es(pt, intersectPt, options);\n intersectPt.properties.location = length + distance_main_es(start, intersectPt, options);\n }\n\n if (start.properties.dist < closestPt.properties.dist) {\n closestPt = start;\n closestPt.properties.index = i;\n closestPt.properties.location = length;\n }\n if (stop.properties.dist < closestPt.properties.dist) {\n closestPt = stop;\n closestPt.properties.index = i + 1;\n closestPt.properties.location = length + sectionLength;\n }\n if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {\n closestPt = intersectPt;\n closestPt.properties.index = i;\n }\n // update length\n length += sectionLength;\n }\n\n });\n\n return closestPt;\n}\n\n/* harmony default export */ var nearest_point_on_line_main_es = (nearestPointOnLine);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/main.es.js\n\n\n\n\n/**\n * Takes a {@link LineString|line}, a start {@link Point}, and a stop point\n * and returns a subsection of the line in-between those points.\n * The start & stop points don't need to fall exactly on the line.\n *\n * This can be useful for extracting only the part of a route between waypoints.\n *\n * @name lineSlice\n * @param {Coord} startPt starting point\n * @param {Coord} stopPt stopping point\n * @param {Feature|LineString} line line to slice\n * @returns {Feature} sliced line\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var start = turf.point([-77.029609, 38.881946]);\n * var stop = turf.point([-77.021884, 38.889563]);\n *\n * var sliced = turf.lineSlice(start, stop, line);\n *\n * //addToMap\n * var addToMap = [start, stop, line]\n */\nfunction lineSlice(startPt, stopPt, line) {\n // Validation\n var coords = getCoords(line);\n if (getType(line) !== 'LineString') throw new Error('line must be a LineString');\n\n var startVertex = nearest_point_on_line_main_es(line, startPt);\n var stopVertex = nearest_point_on_line_main_es(line, stopPt);\n var ends;\n if (startVertex.properties.index <= stopVertex.properties.index) {\n ends = [startVertex, stopVertex];\n } else {\n ends = [stopVertex, startVertex];\n }\n var clipCoords = [ends[0].geometry.coordinates];\n for (var i = ends[0].properties.index + 1; i < ends[1].properties.index + 1; i++) {\n clipCoords.push(coords[i]);\n }\n clipCoords.push(ends[1].geometry.coordinates);\n return lineString(clipCoords, line.properties);\n}\n\n/* harmony default export */ var line_slice_main_es = __webpack_exports__[\"default\"] = (lineSlice);\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-slice/main.es.js_+_11_modules?")},function(module,exports,__webpack_require__){"use strict";eval('\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { "default": mod };\n}\nObject.defineProperty(exports, "__esModule", { value: true });\nvar bearing_1 = __importDefault(__webpack_require__(5));\nvar destination_1 = __importDefault(__webpack_require__(6));\nvar distance_1 = __importDefault(__webpack_require__(9));\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n/**\n * Takes a {@link LineString} and returns a {@link Point} at a specified distance along the line.\n *\n * @name along\n * @param {Feature} line input line\n * @param {number} distance distance along the line\n * @param {Object} [options] Optional parameters\n * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers\n * @returns {Feature} Point `distance` `units` along the line\n * @example\n * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]);\n * var options = {units: \'miles\'};\n *\n * var along = turf.along(line, 200, options);\n *\n * //addToMap\n * var addToMap = [along, line]\n */\nfunction along(line, distance, options) {\n if (options === void 0) { options = {}; }\n // Get Coords\n var geom = invariant_1.getGeom(line);\n var coords = geom.coordinates;\n var travelled = 0;\n for (var i = 0; i < coords.length; i++) {\n if (distance >= travelled && i === coords.length - 1) {\n break;\n }\n else if (travelled >= distance) {\n var overshot = distance - travelled;\n if (!overshot) {\n return helpers_1.point(coords[i]);\n }\n else {\n var direction = bearing_1.default(coords[i], coords[i - 1]) - 180;\n var interpolated = destination_1.default(coords[i], overshot, direction, options);\n return interpolated;\n }\n }\n else {\n travelled += distance_1.default(coords[i], coords[i + 1], options);\n }\n }\n return helpers_1.point(coords[coords.length - 1]);\n}\nexports.default = along;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/along/index.js?')},function(module,exports,__webpack_require__){"use strict";eval('\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { "default": mod };\n}\nObject.defineProperty(exports, "__esModule", { value: true });\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\nvar line_segment_1 = __importDefault(__webpack_require__(25));\nvar meta_1 = __webpack_require__(27);\nvar geojson_rbush_1 = __importDefault(__webpack_require__(28));\n/**\n * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s).\n *\n * @name lineIntersect\n * @param {GeoJSON} line1 any LineString or Polygon\n * @param {GeoJSON} line2 any LineString or Polygon\n * @returns {FeatureCollection} point(s) that intersect both\n * @example\n * var line1 = turf.lineString([[126, -11], [129, -21]]);\n * var line2 = turf.lineString([[123, -18], [131, -14]]);\n * var intersects = turf.lineIntersect(line1, line2);\n *\n * //addToMap\n * var addToMap = [line1, line2, intersects]\n */\nfunction lineIntersect(line1, line2) {\n var unique = {};\n var results = [];\n // First, normalize geometries to features\n // Then, handle simple 2-vertex segments\n if (line1.type === "LineString") {\n line1 = helpers_1.feature(line1);\n }\n if (line2.type === "LineString") {\n line2 = helpers_1.feature(line2);\n }\n if (line1.type === "Feature" &&\n line2.type === "Feature" &&\n line1.geometry !== null &&\n line2.geometry !== null &&\n line1.geometry.type === "LineString" &&\n line2.geometry.type === "LineString" &&\n line1.geometry.coordinates.length === 2 &&\n line2.geometry.coordinates.length === 2) {\n var intersect = intersects(line1, line2);\n if (intersect) {\n results.push(intersect);\n }\n return helpers_1.featureCollection(results);\n }\n // Handles complex GeoJSON Geometries\n var tree = geojson_rbush_1.default();\n tree.load(line_segment_1.default(line2));\n meta_1.featureEach(line_segment_1.default(line1), function (segment) {\n meta_1.featureEach(tree.search(segment), function (match) {\n var intersect = intersects(segment, match);\n if (intersect) {\n // prevent duplicate points https://github.com/Turfjs/turf/issues/688\n var key = invariant_1.getCoords(intersect).join(",");\n if (!unique[key]) {\n unique[key] = true;\n results.push(intersect);\n }\n }\n });\n });\n return helpers_1.featureCollection(results);\n}\n/**\n * Find a point that intersects LineStrings with two coordinates each\n *\n * @private\n * @param {Feature} line1 GeoJSON LineString (Must only contain 2 coordinates)\n * @param {Feature} line2 GeoJSON LineString (Must only contain 2 coordinates)\n * @returns {Feature} intersecting GeoJSON Point\n */\nfunction intersects(line1, line2) {\n var coords1 = invariant_1.getCoords(line1);\n var coords2 = invariant_1.getCoords(line2);\n if (coords1.length !== 2) {\n throw new Error(" line1 must only contain 2 coordinates");\n }\n if (coords2.length !== 2) {\n throw new Error(" line2 must only contain 2 coordinates");\n }\n var x1 = coords1[0][0];\n var y1 = coords1[0][1];\n var x2 = coords1[1][0];\n var y2 = coords1[1][1];\n var x3 = coords2[0][0];\n var y3 = coords2[0][1];\n var x4 = coords2[1][0];\n var y4 = coords2[1][1];\n var denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));\n var numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));\n var numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));\n if (denom === 0) {\n if (numeA === 0 && numeB === 0) {\n return null;\n }\n return null;\n }\n var uA = numeA / denom;\n var uB = numeB / denom;\n if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {\n var x = x1 + (uA * (x2 - x1));\n var y = y1 + (uA * (y2 - y1));\n return helpers_1.point([x, y]);\n }\n return null;\n}\nexports.default = lineIntersect;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-intersect/index.js?')},function(module,exports){eval("/**\n * This class represents a single search node in the exploration tree for\n * A* algorithm.\n * \n * @param {Object} node original node in the graph\n */\nfunction NodeSearchState(node) {\n this.node = node;\n\n // How we came to this node?\n this.parent = null;\n\n this.closed = false;\n this.open = 0;\n\n this.distanceToSource = Number.POSITIVE_INFINITY;\n // the f(n) = g(n) + h(n) value\n this.fScore = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated.\n this.heapIndex = -1;\n};\n\nfunction makeSearchStatePool() {\n var currentInCache = 0;\n var nodeCache = [];\n\n return {\n createNewState: createNewState,\n reset: reset\n };\n\n function reset() {\n currentInCache = 0;\n }\n\n function createNewState(node) {\n var cached = nodeCache[currentInCache];\n if (cached) {\n // TODO: This almost duplicates constructor code. Not sure if\n // it would impact performance if I move this code into a function\n cached.node = node;\n // How we came to this node?\n cached.parent = null;\n\n cached.closed = false;\n cached.open = 0;\n\n cached.distanceToSource = Number.POSITIVE_INFINITY;\n // the f(n) = g(n) + h(n) value\n cached.fScore = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated.\n cached.heapIndex = -1;\n\n } else {\n cached = new NodeSearchState(node);\n nodeCache[currentInCache] = cached;\n }\n currentInCache++;\n return cached;\n }\n}\nmodule.exports = makeSearchStatePool;\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/makeSearchStatePool.js?")},function(module,exports,__webpack_require__){eval("var agentmap = __webpack_require__(4),\n agents = __webpack_require__(20),\n buildings = __webpack_require__(40),\n utils = __webpack_require__(43);\n\nL.A = Object.assign({}, agentmap, agents, buildings, utils);\n\n//# sourceURL=webpack:///./src/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/length/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){eval('function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n/* Here we define agentify, the agent base class, and everything they uniquely rely on. */\nvar centroid = __webpack_require__(21).default,\n buffer = __webpack_require__(44).default,\n booleanPointInPolygon = __webpack_require__(23).default,\n along = __webpack_require__(15).default,\n nearestPointOnLine = __webpack_require__(24).default,\n lineSlice = __webpack_require__(14).default,\n length = __webpack_require__(8).default,\n lineString = __webpack_require__(1).lineString,\n bearing = __webpack_require__(5).default,\n destination = __webpack_require__(6).default,\n Agentmap = __webpack_require__(4).Agentmap,\n encodeLatLng = __webpack_require__(10).encodeLatLng;\n/**\r\n * The main class representing individual agents, using Leaflet class system.\r\n * @private\r\n *\r\n * @class Agent\r\n */\n\n\nvar Agent = {};\n/**\r\n * Constructor for the Agent class, using Leaflet class system.\r\n * \r\n * @name Agent\r\n * @constructor \r\n * @param {LatLng} lat_lng - A pair of coordinates to place the agent at.\r\n * @param {Object} options - An array of options for the agent, namely its layer.\r\n * @param {Agentmap} agentmap - The agentmap instance in which the agent exists.\r\n * @property {Agentmap} agentmap - The agentmap instance in which the agent exists.\r\n * @property {Place} place - A place object specifying where the agent is currently at.\r\n * @property {number} [steps_made=0] - The number of steps the agent has moved since the beginning.\r\n * @property {Object} this.trip - Properties detailing information about the agent\'s trip that change sometimes, but needs to be accessed by future updates.\r\n * @property {boolean} this.trip.moving - Whether the agent currently moving.\r\n * @property {boolean} this.trip.paused - Whether the agent should be allowed to move along its trip.\r\n * @property {?Point} this.trip.current_point - The point where the agent is currently located.\r\n * @property {?Point} this.trip.goal_point - The point where the agent is traveling to.\r\n * @property {?number} this.trip.lat_dir - The latitudinal direction. -1 if traveling to lower latitude (down), 1 if traveling to higher latitude (up).\r\n * @property {?number} this.trip.lng_dir - The longitudinal direction. -1 if traveling to lesser longitude (left), 1 if traveling to greater longitude (right).\r\n * @property {?number} this.trip.speed - The speed that the agent should travel, in meters per tick.\r\n * @property {?number} this.trip.angle - The angle between the current point and the goal.\r\n * @property {?number} this.trip.slope - The slope of the line segment formed by the two points between which the agent is traveling at this time during its trip.\r\n * @property {Array} this.trip.path - A sequence of LatLngs; the agent will move from one to the next, popping each one off after it arrives until the end of the street; or, until the trip is changed/reset.\r\n * @property {?function} controller - User-defined function to be called on each update (each tick).\r\n * @property {?function} fine_controller - User-defined function to be called before & after each movemnt (on each step an agent performs during a tick).\r\n */\n\nAgent.initialize = function (lat_lng, options, agentmap) {\n this.agentmap = agentmap, this.place = null, this.steps_made = 0, this.trip = {\n paused: false,\n moving: false,\n current_point: null,\n goal_point: null,\n lat_dir: null,\n lng_dir: null,\n slope: null,\n angle: null,\n speed: null,\n path: []\n }, this.controller = function () {}, this.fine_controller = function () {};\n L.CircleMarker.prototype.initialize.call(this, lat_lng, options);\n};\n/**\r\n * Reset all the properties of its trip, but don\'t change whether it\'s allowed to be traveling or not.\r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.resetTrip = function () {\n for (var key in this.trip) {\n this.trip[key] = key === "paused" ? false : key === "moving" ? false : key === "path" ? [] : null;\n }\n};\n/**\r\n * Set the agent up to start traveling along the path specified in the agent\'s trip..\r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.startTrip = function () {\n if (this.trip.path.length > 0) {\n this.travelTo(this.trip.path[0]);\n }\n};\n/**\r\n * Stop the agent where it is along its trip. \r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.pauseTrip = function () {\n this.trip.paused = true;\n};\n/**\r\n * Have the agent continue from where it was left off along its trip. \r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.resumeTrip = function () {\n this.trip.paused = false;\n};\n/**\r\n * Set the agent to travel to some point on the map.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} goal_point - The point to which the agent should travel.\r\n */\n\n\nAgent.travelTo = function (goal_point) {\n this.trip.current_point = this.getLatLng(), this.trip.goal_point = goal_point, //Negating so that neg result corresponds to the goal being rightward/above, pos result to it being leftward/below.\n this.trip.lat_dir = Math.sign(-(this.trip.current_point.lat - this.trip.goal_point.lat)), this.trip.lng_dir = Math.sign(-(this.trip.current_point.lng - this.trip.goal_point.lng)), this.trip.angle = bearing(L.A.pointToCoordinateArray(this.trip.current_point), L.A.pointToCoordinateArray(this.trip.goal_point));\n this.trip.slope = Math.abs((this.trip.current_point.lat - this.trip.goal_point.lat) / (this.trip.current_point.lng - this.trip.goal_point.lng));\n this.trip.speed = this.trip.goal_point.speed; //If the agent won\'t be at any particular place at least until it reaches its next goal, mark its place as unanchored.\n\n if (this.trip.path[0].new_place.type === "unanchored" || this.trip.path[0].move_directly === true) {\n this.place = {\n type: "unanchored"\n };\n }\n};\n/**\r\n * Given the agent\'s currently scheduledthis.trips (its path), get the place from which a newthis.trip should start (namely, the end of the current path).\r\n * That is: If there\'s already a path in queue, start the new path from the end of the existing one.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @returns {Place} - The place where a newthis.trip should start.\r\n */\n\n\nAgent.newTripStartPlace = function () {\n if (this.trip.path.length === 0) {\n start_place = this.place;\n } else {\n start_place = this.trip.path[this.trip.path.length - 1].new_place;\n }\n\n return start_place;\n};\n/**\r\n * Schedule the agent to travel to a point within the unit he is in.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} goal_lat_lng - LatLng coordinate object for a point in the same unit the agent is in.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\n\nAgent.setTravelInUnit = function (goal_lat_lng, goal_place, speed) {\n goal_lat_lng.new_place = goal_place, goal_lat_lng.speed = speed;\n this.trip.path.push(goal_lat_lng);\n};\n/**\r\n * Schedule the agent to travel directly from any point (e.g. of a street or unit) to a point (e.g. of another street or unit).\r\n * @name scheduleTrip\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {LatLng} goal_lat_lng - The point within the place to which the agent is to travel.\r\n * @param {Place} goal_place - The place to which the agent will travel.\r\n * @param {number} [speed=1] - The speed in meters per tick that the agent should try to travel. Must be >= .1.\r\n * @param {Boolean} [move_directly=false] - Whether to ignore the streets & roads and move directly to the goal.\r\n * @param {Boolean} [replace_trip=false] - Whether to empty the currently scheduled path and replace it with this new trip; false by default (the new trip is\r\n * simply appended to the current scheduled path).\r\n */\n\n\nAgent.setTravelToPlace = function (goal_lat_lng, goal_place) {\n var speed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var move_directly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n var replace_trip = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n this.checkSpeed(speed);\n var start_place = this.newTripStartPlace();\n goal_lat_lng = L.latLng(goal_lat_lng);\n\n if (replace_trip === true) {\n start_place = this.place;\n this.resetTrip();\n } //If either the agent is already unanchored or its goal is unanchored, just schedule it to move directly to its goal.\n\n\n if (start_place.type === "unanchored" || goal_place.type === "unanchored" || move_directly === true) {\n var goal = goal_lat_lng;\n goal.new_place = goal_place, goal.move_directly = true, goal.speed = speed;\n this.trip.path.push(goal);\n return;\n }\n\n var goal_layer = this.agentmap.units.getLayer(goal_place.id) || this.agentmap.streets.getLayer(goal_place.id); //If the goal isn\'t unanchored, see if it\'s a street or a unit and schedule the agent appropriately.\n\n if (goal_layer) {\n var goal_coords = L.A.pointToCoordinateArray(goal_lat_lng); //Buffering so that points on the perimeter, like the door, are captured. \n //Also expands street lines into thin polygons (booleanPointInPolygon requires polys).\n //Might be more efficient to generate the door so that it\'s slightly inside the area.\n\n var goal_polygon = buffer(goal_layer.toGeoJSON(), .001);\n\n if (booleanPointInPolygon(goal_coords, goal_polygon)) {\n if (start_place.type === "unit" && goal_place.type === "unit" && start_place.id === goal_place.id) {\n this.setTravelInUnit(goal_lat_lng, goal_place, speed);\n return;\n } //Move to the street if it\'s starting at a unit and its goal is elsewhere.\n else if (start_place.type === "unit") {\n var start_unit_door = this.agentmap.getUnitDoor(start_place.id);\n start_unit_door.new_place = start_place, start_unit_door.speed = speed;\n this.trip.path.push(start_unit_door);\n var start_unit_street_id = this.agentmap.units.getLayer(start_place.id).street_id,\n start_unit_street_point = this.agentmap.getStreetNearDoor(start_place.id);\n start_unit_street_point.new_place = {\n type: "street",\n id: start_unit_street_id\n }, start_unit_street_point.speed = speed;\n this.trip.path.push(start_unit_street_point);\n }\n\n if (goal_place.type === "unit") {\n var goal_street_point = this.agentmap.getStreetNearDoor(goal_place.id),\n goal_street_point_place = {\n type: "street",\n id: this.agentmap.units.getLayer(goal_place.id).street_id\n }; //Move to the point on the street closest to the goal unit...\n\n this.setTravelAlongStreet(goal_street_point, goal_street_point_place, speed); //Move from that point into the unit.\n\n var goal_door = this.agentmap.getUnitDoor(goal_place.id);\n goal_door.new_place = goal_place, goal_door.speed = speed;\n this.trip.path.push(goal_door);\n this.setTravelInUnit(goal_lat_lng, goal_place, speed);\n } else if (goal_place.street === "number") {\n this.setTravelAlongStreet(goal_lat_lng, goal_place, speed);\n }\n } else {\n throw new Error("The goal_lat_lng is not inside of the polygon of the goal_place!");\n }\n } else {\n throw new Error("No place exists matching the specified goal_place!");\n }\n};\n\nAgent.scheduleTrip = Agent.setTravelToPlace;\n/**\r\n * Schedule the agent to travel to a point along the streets, via streets.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} goal_lat_lng - The coordinates of a point on a street to which the agent should travel.\r\n * @param {Place} goal_place - The place to which the agent will travel. Must be a street.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\nAgent.setTravelAlongStreet = function (goal_lat_lng, goal_place, speed) {\n var goal_coords,\n goal_street_id,\n goal_street_point,\n goal_street_feature,\n start_place = this.newTripStartPlace(),\n start_street_id,\n start_street_point,\n start_street_feature;\n\n if (start_place.type === "street" && goal_place.type === "street") {\n start_street_id = start_place.id, start_street_point = this.trip.path.length !== 0 ? this.trip.path[this.trip.path.length - 1] : this.getLatLng();\n start_street_point.new_place = {\n type: "street",\n id: start_street_id\n };\n goal_street_id = goal_place.id, goal_street_feature = this.agentmap.streets.getLayer(goal_street_id).feature, goal_coords = L.A.pointToCoordinateArray(goal_lat_lng), goal_street_point = L.latLng(nearestPointOnLine(goal_street_feature, goal_coords).geometry.coordinates.reverse());\n goal_street_point.new_place = goal_place;\n } else {\n throw new Error("Both the start and end places must be streets!");\n }\n\n if (start_street_id === goal_street_id) {\n this.setTravelOnSameStreet(start_street_point, goal_street_point, goal_street_feature, goal_street_id, speed);\n } //If the start and end points are on different streets, move from the start to its nearest intersection, then from there\n //to the intersection nearest to the end, and finally to the end.\n else {\n var start_nearest_intersection = this.agentmap.getNearestIntersection(start_street_point, start_place),\n goal_nearest_intersection = this.agentmap.getNearestIntersection(goal_street_point, goal_place);\n start_street_feature = this.agentmap.streets.getLayer(start_street_id).feature;\n this.setTravelOnStreetNetwork(start_street_point, goal_street_point, start_nearest_intersection, goal_nearest_intersection, speed);\n }\n};\n/**\r\n * Schedule the agent to travel between two points on the same street.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param start_lat_lng {LatLng} - The coordinates of the point on the street from which the agent will be traveling.\r\n * @param goal_lat_lng {LatLng} - The coordinates of the point on the street to which the agent should travel.\r\n * @param street_feature {Feature} - A GeoJSON object representing an OpenStreetMap street.\r\n * @param street_id {number} - The ID of the street in the streets layerGroup.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\n\nAgent.setTravelOnSameStreet = function (start_lat_lng, goal_lat_lng, street_feature, street_id, speed) {\n var _this$trip$path;\n\n //lineSlice, regardless of the specified starting point, will give a segment with the same coordinate order \n //as the original lineString array. So, if the goal point comes earlier in the array (e.g. it\'s on the far left),\n //it\'ll end up being the first point in the path, instead of the last, and the agent will move to it directly,\n //ignoring the street points that should come before it. It would then travel along the street from the goal point \n //to its original point (backwards).\n //To fix this, I\'m reversing the order of the coordinates in the segment if the last point in the line is closer\n //to the agent\'s starting point than the first point on the line (implying the last point in the array is the starting \n //point, not the goal). \n var start_coords = L.A.pointToCoordinateArray(start_lat_lng),\n goal_coords = L.A.pointToCoordinateArray(goal_lat_lng),\n street_path_unordered = L.A.reversedCoordinates(lineSlice(start_coords, goal_coords, street_feature).geometry.coordinates);\n var start_to_path_beginning = start_lat_lng.distanceTo(L.latLng(street_path_unordered[0])),\n start_to_path_end = start_lat_lng.distanceTo(L.latLng(street_path_unordered[street_path_unordered.length - 1]));\n var street_path = start_to_path_beginning < start_to_path_end ? street_path_unordered : street_path_unordered.reverse();\n var street_path_lat_lngs = street_path.map(function (coords) {\n var lat_lng = L.latLng(coords);\n lat_lng.new_place = {\n type: "street",\n id: street_id\n }, lat_lng.speed = speed;\n return lat_lng;\n });\n var first_lat = street_path_lat_lngs[0].lat,\n first_lng = street_path_lat_lngs[0].lng; //Exclude the last point if it\'s the same as the second to last point of this proposed segment,\n //and the second of it\'s the same as the first.\n //(since lineSlice adds a point for each other street in an intersection).\n\n if (street_path_lat_lngs.length > 1) {\n var second_lat = street_path_lat_lngs[1].lat,\n second_lng = street_path_lat_lngs[1].lng,\n final_lat = street_path_lat_lngs[street_path_lat_lngs.length - 1].lat,\n final_lng = street_path_lat_lngs[street_path_lat_lngs.length - 1].lng,\n penultimate_lat = street_path_lat_lngs[street_path_lat_lngs.length - 2].lat,\n penultimate_lng = street_path_lat_lngs[street_path_lat_lngs.length - 2].lng;\n\n if (first_lat === second_lat && first_lng === second_lng) {\n street_path_lat_lngs.shift();\n }\n\n if (final_lat === penultimate_lat && final_lng === penultimate_lng) {\n street_path_lat_lngs.pop();\n }\n } //Exclude the first point if it\'s already the last point of the already scheduled path.\n\n\n if (this.trip.path.length > 0) {\n var prev_lat = this.trip.path[this.trip.path.length - 1].lat,\n prev_lng = this.trip.path[this.trip.path.length - 1].lng;\n\n if (prev_lat === first_lat && prev_lng === first_lng) {\n street_path_lat_lngs.shift();\n }\n }\n\n (_this$trip$path = this.trip.path).push.apply(_this$trip$path, _toConsumableArray(street_path_lat_lngs));\n};\n/**\r\n * Schedule the agent up to travel between two points on a street network.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} start_lat_lng - The coordinates of the point on the street from which the agent will be traveling.\r\n * @param {LatLng} goal_lat_lng - The coordinates of the point on the street to which the agent should travel.\r\n * @param {LatLng} start_int_lat_lng - The coordinates of the nearest intersection on the same street at the start_lat_lng.\r\n * @param {LatLng} goal_int_lat_lng - The coordinates of the nearest intersection on the same street as the goal_lat_lng.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\n\nAgent.setTravelOnStreetNetwork = function (start_lat_lng, goal_lat_lng, start_int_lat_lng, goal_int_lat_lng, speed) {\n var path = this.agentmap.getPath(start_int_lat_lng, goal_int_lat_lng, start_lat_lng, goal_lat_lng, true);\n\n for (var i = 0; i <= path.length - 2; i++) {\n var current_street_id = path[i].new_place.id,\n current_street_feature = this.agentmap.streets.getLayer(current_street_id).feature;\n this.setTravelOnSameStreet(path[i], path[i + 1], current_street_feature, current_street_id, speed);\n }\n};\n/**\r\n * Set a new, constant speed for the agent to move along its currently scheduled path.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} speed - The speed (in meters per tick) that the agent should move. Must be >= .1.\r\n */\n\n\nAgent.setSpeed = function (speed) {\n this.checkSpeed(speed);\n\n if (this.trip.goal_point !== null) {\n this.trip.speed = speed;\n }\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = this.trip.path[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var spot = _step.value;\n this.trip.speed = speed;\n spot.speed = speed;\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n};\n/**\r\n * Multiply the speed the agent moves along its currently scheduled path by a constant.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} multiplier - The number to multiply the agent\'s scheduled speed by. \r\n * All scheduled speeds must be >= .1.\r\n */\n\n\nAgent.multiplySpeed = function (multiplier) {\n if (this.trip.goal_point !== null) {\n this.trip.speed *= multiplier;\n this.checkSpeed(this.trip.speed);\n }\n\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = this.trip.path[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var spot = _step2.value;\n spot.speed *= multiplier;\n this.checkSpeed(spot.speed);\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n};\n/**\r\n * Increase the speed the agent moves along its currently scheduled path by a constant.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} magnitude - The number to add to the agent\'s scheduled speed.\r\n * All scheduled speeds must be >= .1\r\n */\n\n\nAgent.increaseSpeed = function (magnitude) {\n if (this.trip.goal_point !== null) {\n this.trip.speed += magnitude;\n this.checkSpeed(this.trip.speed);\n }\n\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = this.trip.path[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var spot = _step3.value;\n spot.speed += magnitude;\n this.checkSpeed(spot.speed);\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return != null) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n};\n/**\r\n * Check whether a given speed is greater than the minimum.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} speed - A number representing the speed of an agent in meters per second.\r\n */\n\n\nAgent.checkSpeed = function (speed) {\n if (speed < .1) {\n throw new Error("Cannot assign speed below .1 to agent!");\n }\n};\n/**\r\n * Continue to move the agent directly along the points in its path, at approximately the speed associated with each point in the path.\r\n * Since two points along the path may be far apart, the agent will make multiple intermediary movements too, splitting up its transfer\r\n * from its current point to its goal point into a sub-path with multiple sub-goals.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {number} override_speed - Have the agent step this distance, instead of the distance suggested by the current state\'s speed property.\r\n */\n\n\nAgent.travel = function (override_speed) {\n var current_coords = L.A.pointToCoordinateArray(this.trip.current_point),\n sub_goal_distance = override_speed || this.trip.speed,\n sub_goal_coords = destination(current_coords, sub_goal_distance * .001, this.trip.angle).geometry.coordinates,\n sub_goal_lat_lng = L.latLng(L.A.reversedCoordinates(sub_goal_coords));\n var segment_to_goal = lineString([this.trip.current_point, this.trip.goal_point].map(function (point) {\n return L.A.pointToCoordinateArray(point);\n })),\n segment_to_sub_goal = lineString([this.trip.current_point, sub_goal_lat_lng].map(function (point) {\n return L.A.pointToCoordinateArray(point);\n }));\n var goal_lat_dist = Math.abs(this.trip.current_point.lat - this.trip.goal_point.lat),\n goal_lng_dist = Math.abs(this.trip.current_point.lng - this.trip.goal_point.lng);\n var dist_to_goal = length(segment_to_goal) * 1000,\n dist_to_sub_goal = length(segment_to_sub_goal) * 1000,\n leftover_after_goal; //Check if the distance to the sub_goal is greater than the distance to the goal, and if so, make the sub_goal equal the goal\n //and change the number of meters to the sub_goal to the number of meters to the goal.\n\n if (dist_to_goal < dist_to_sub_goal) {\n sub_goal_lat_lng = this.trip.goal_point, sub_goal_distance = dist_to_goal, leftover_after_goal = dist_to_sub_goal - dist_to_goal;\n }\n\n if (this.checkArrival(sub_goal_lat_lng, leftover_after_goal)) {\n return;\n } //Lat/Lng distance between current point and sub_goal point.\n\n\n var sub_goal_lat_dist = Math.abs(sub_goal_lat_lng.lat - this.trip.current_point.lat),\n sub_goal_lng_dist = Math.abs(sub_goal_lat_lng.lng - this.trip.current_point.lng);\n var half_meters = sub_goal_distance * 2,\n int_half_meters = Math.floor(half_meters),\n int_lat_step_value = this.trip.lat_dir * (sub_goal_lat_dist / half_meters),\n int_lng_step_value = this.trip.lng_dir * (sub_goal_lng_dist / half_meters),\n final_lat_step_value = this.trip.lat_dir * (sub_goal_lat_dist - Math.abs(int_lat_step_value * int_half_meters)),\n final_lng_step_value = this.trip.lng_dir * (sub_goal_lng_dist - Math.abs(int_lng_step_value * int_half_meters)); //Intermediary movements.\n\n for (var i = 0; i < int_half_meters; ++i) {\n this.step(int_lat_step_value, int_lng_step_value); //If the agent is moving directly from a large distance, redirect it back towards the goal if it appears off course.\n\n if (this.trip.goal_point.move_directly === true) {\n var new_goal_lat_dist = Math.abs(this.trip.current_point.lat - this.trip.goal_point.lat),\n new_goal_lng_dist = Math.abs(this.trip.current_point.lng - this.trip.goal_point.lng);\n\n if (new_goal_lat_dist > goal_lat_dist || new_goal_lng_dist > goal_lng_dist) {\n this.travelTo(this.trip.goal_point);\n }\n }\n\n if (this.checkArrival(sub_goal_lat_lng, leftover_after_goal)) {\n return;\n }\n } //Last movement after intermediary movements.\n\n\n this.step(final_lat_step_value, final_lng_step_value, true);\n\n if (this.checkArrival(sub_goal_lat_lng, leftover_after_goal)) {\n return;\n }\n};\n/** \r\n * Move the agent a given latitude and longitude.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {number} lat_step_value - The number to add to the agent\'s latitude.\r\n * @param {number} lng_step_value - The number to add to the agent\'s longitude.\r\n */\n\n\nAgent.step = function (lat_step_value, lng_step_value) {\n var new_lat_lng = L.latLng([this.trip.current_point.lat + lat_step_value, this.trip.current_point.lng + lng_step_value]);\n this.trip.current_point = new_lat_lng, this.steps_made++; //Only redraw the Agent\'s position if the number of steps the agent has moved is a multiple of the agentmap.animation_interval.\n\n if (this.agentmap.animation_interval > 0 && this.steps_made % this.agentmap.animation_interval === 0) {\n this.setLatLng(new_lat_lng);\n } else {\n this._latlng = new_lat_lng;\n }\n};\n/**\r\n * Check if the agent has arrived at the next goal in its path or to a sub_goal along the way and perform appropriate arrival operations.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} sub_goal_lat_lng - A sub_goal on the way to the goal (possibly the goal itself).\r\n * @param {number} leftover_after_goal - If the agent arrives at its goal during the tick, the number of meters, according to its speed,\r\n * leftover beyond the goal that it should still move during the tick.\r\n */\n\n\nAgent.checkArrival = function (sub_goal_lat_lng, leftover_after_goal) {\n if (this.trip.goal_point.distanceTo(this.trip.current_point) < .1) {\n this.place = this.trip.path[0].new_place;\n arrived = true;\n this.trip.path.shift();\n\n if (this.trip.path.length === 0) {\n this.resetTrip();\n } else {\n this.travelTo(this.trip.path[0]); //If it still needs to move a certain distance during this tick, move it that distance towards the next goal before returning.\n\n if (leftover_after_goal > 0) {\n this.travel(leftover_after_goal);\n }\n }\n\n this.trip.moving = false;\n return true;\n } else if (sub_goal_lat_lng.distanceTo(this.trip.current_point) < .1) {\n this.trip.moving = false;\n return true;\n }\n};\n/**\r\n * Make the agent proceed along its trip.\r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.moveIt = function () {\n //Make sure the agent isn\'t paused or already moving.\n if (!this.trip.paused && !this.trip.moving) {\n //Call the agent\'s fine_controller before it begins moving.\n this.fine_controller(); //Check if the agent has a goal point, and if so travel towards it.\n\n if (this.trip.goal_point !== null) {\n this.trip.moving = true;\n this.travel();\n } //Otherwise, if there\'s a scheduled path that the agent hasn\'t started traveling on yet,\n //start traveling on it.\n else if (this.trip.path.length !== 0) {\n this.trip.moving = true;\n this.startTrip();\n this.travel();\n }\n }\n};\n\nAgent = L.CircleMarker.extend(Agent);\n/**\r\n * Returns an agent object.\r\n *\r\n * @param {LatLng} lat_lng - A pair of coordinates to locate the agent at.\r\n * @param {Object} options - An array of options for the agent, namely its layer.\r\n * @param {Agentmap} agentmap - The agentmap instance in which the agent exists.\r\n */\n\nfunction agent(lat_lng, options, agentmap) {\n return new Agent(lat_lng, options, agentmap);\n}\n/**\r\n * A user-defined callback function that returns a feature with appropriate geometry and properties to represent an agent.\r\n *\r\n * @callback agentFeatureMaker\r\n * @param {number} id - The agent\'s Leaflet layer ID.\r\n * @returns {Point} - A GeoJSON Point object with geometry and other properties for the agent, including\r\n * a "place" property that will set the agent\'s initial {@link Place} and a "layer_options" property\r\n * that will specify the feature\'s Leaflet options (like its color, size, etc.). All other provided properties \r\n * will be transferred to the Agent object once it is created.\r\n * See {@link https://leafletjs.com/reference-1.3.2.html#circlemarker} for all possible layer options.\r\n *\r\n * @example\r\n * let point = {\t\t\t\t\t\r\n * \t"type": "Feature",\t\t\t\t \r\n * \t"properties": {\t\t\t\t\t\r\n * \t\t"layer_options": {\t\t\t\r\n * \t\t\t"color": "red",\t\t\t\r\n * \t\t\t"radius": .5,\t\t\t\r\n * \t\t},\t\t\t\t\t\r\n * \t\t"place": {\t\t\t\t\r\n * \t\t\t"type": "unit",\t\t\t\r\n * \t\t\t"id": 89\t\t\t\r\n * \t\t},\t\t\t\t\t\r\n * \t\t\t\t\t\t\t\r\n * \t\tage: 72,\t\t\t\t\r\n * \t\thome_city: "LA"\t\t\t\t\r\n * \t},\t\t\t\t\t\t\r\n * \t"geometry" {\t\t\t\t\t\r\n * \t\t"type": "Point",\t\t\t\r\n * \t\t"coordinates": [\t\t\t\r\n * \t\t\t14.54589,\t\t\t\r\n * \t\t\t57.136239\t\t\t\r\n * \t\t]\t\t\t\t\t\r\n * \t}\t\t\t\t\t\t\r\n * }\t\t\t\t\t\t\t\r\n */\n\n/**\r\n * A standard {@link agentFeatureMaker}, which sets an agent\'s location to be the point near the center of the iᵗʰ unit of the map,\r\n * its place property to be that unit\'s, and its layer_options to be red and of radius .5 meters.\r\n * @memberof Agentmap\r\n * @instance\r\n * @type {agentFeatureMaker}\r\n */\n\n\nfunction seqUnitAgentMaker(id) {\n var index = this.agents.count();\n\n if (index > this.units.getLayers().length - 1) {\n throw new Error("seqUnitAgentMaker cannot accommodate more agents than there are units.");\n }\n\n var unit = this.units.getLayers()[index],\n unit_id = this.units.getLayerId(unit),\n center_point = centroid(unit.feature);\n center_point.properties.place = {\n "type": "unit",\n "id": unit_id\n }, center_point.properties.layer_options = {\n radius: .5,\n color: "red",\n fillColor: "red"\n };\n return center_point;\n}\n/**\r\n * Generate some number of agents and place them on the map.\r\n * @memberof Agentmap\r\n * @instance\r\n *\r\n * @param {number} count - The desired number of agents.\r\n * @param {agentFeatureMaker} agentFeatureMaker - A callback that determines an agent i\'s feature properties and geometry (always a Point).\r\n */\n\n\nfunction agentify(count, agentFeatureMaker) {\n var agentmap = this;\n\n if (!(this.agents instanceof L.LayerGroup)) {\n this.agents = L.featureGroup().addTo(this.map);\n }\n\n var agents_existing = agentmap.agents.getLayers().length;\n\n for (var i = agents_existing; i < agents_existing + count; i++) {\n var new_agent = agent(null, null, agentmap); //Callback function aren\'t automatically bound to the agentmap.\n\n var boundFeatureMaker = agentFeatureMaker.bind(agentmap),\n agent_feature = boundFeatureMaker(new_agent._leaflet_id);\n var coordinates = L.A.reversedCoordinates(agent_feature.geometry.coordinates),\n place = agent_feature.properties.place,\n layer_options = agent_feature.properties.layer_options; //Make sure the agent feature is valid and has everything we need.\n\n if (!L.A.isPointCoordinates(coordinates)) {\n throw new Error("Invalid feature returned from agentFeatureMaker: geometry.coordinates must be a 2-element array of numbers.");\n } else if (typeof place.id !== "number") {\n throw new Error("Invalid feature returned from agentFeatureMaker: properties.place must be a {unit: unit_id} or {street: street_id} with an existing layer\'s ID.");\n }\n\n new_agent.setLatLng(coordinates);\n new_agent.setStyle(layer_options);\n delete agent_feature.properties.layer_options;\n Object.assign(new_agent, agent_feature.properties);\n this.agents.addLayer(new_agent);\n }\n}\n\nAgentmap.prototype.agent = agent, Agentmap.prototype.agentify = agentify, Agentmap.prototype.seqUnitAgentMaker = seqUnitAgentMaker;\nexports.Agent = Agent, exports.agent = agent;\n\n//# sourceURL=webpack:///./src/agents.js?')},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nvar meta_1 = __webpack_require__(22);\nvar helpers_1 = __webpack_require__(1);\n/**\n * Takes one or more features and calculates the centroid using the mean of all vertices.\n * This lessens the effect of small islands and artifacts when calculating the centroid of a set of polygons.\n *\n * @name centroid\n * @param {GeoJSON} geojson GeoJSON to be centered\n * @param {Object} [options={}] Optional Parameters\n * @param {Object} [options.properties={}] an Object that is used as the {@link Feature}\'s properties\n * @returns {Feature} the centroid of the input features\n * @example\n * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]);\n *\n * var centroid = turf.centroid(polygon);\n *\n * //addToMap\n * var addToMap = [polygon, centroid]\n */\nfunction centroid(geojson, options) {\n if (options === void 0) { options = {}; }\n var xSum = 0;\n var ySum = 0;\n var len = 0;\n meta_1.coordEach(geojson, function (coord) {\n xSum += coord[0];\n ySum += coord[1];\n len++;\n });\n return helpers_1.point([xSum / len, ySum / len], options.properties);\n}\nexports.default = centroid;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/centroid/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/centroid/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nvar invariant_1 = __webpack_require__(2);\n// http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule\n// modified from: https://github.com/substack/point-in-polygon/blob/master/index.js\n// which was modified from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n/**\n * Takes a {@link Point} and a {@link Polygon} or {@link MultiPolygon} and determines if the point\n * resides inside the polygon. The polygon can be convex or concave. The function accounts for holes.\n *\n * @name booleanPointInPolygon\n * @param {Coord} point input point\n * @param {Feature} polygon input polygon or multipolygon\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.ignoreBoundary=false] True if polygon boundary should be ignored when determining if\n * the point is inside the polygon otherwise false.\n * @returns {boolean} `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon\n * @example\n * var pt = turf.point([-77, 44]);\n * var poly = turf.polygon([[\n * [-81, 41],\n * [-81, 47],\n * [-72, 47],\n * [-72, 41],\n * [-81, 41]\n * ]]);\n *\n * turf.booleanPointInPolygon(pt, poly);\n * //= true\n */\nfunction booleanPointInPolygon(point, polygon, options) {\n if (options === void 0) { options = {}; }\n // validation\n if (!point) {\n throw new Error("point is required");\n }\n if (!polygon) {\n throw new Error("polygon is required");\n }\n var pt = invariant_1.getCoord(point);\n var geom = invariant_1.getGeom(polygon);\n var type = geom.type;\n var bbox = polygon.bbox;\n var polys = geom.coordinates;\n // Quick elimination if point is not inside bbox\n if (bbox && inBBox(pt, bbox) === false) {\n return false;\n }\n // normalize to multipolygon\n if (type === "Polygon") {\n polys = [polys];\n }\n var insidePoly = false;\n for (var i = 0; i < polys.length && !insidePoly; i++) {\n // check if it is in the outer ring first\n if (inRing(pt, polys[i][0], options.ignoreBoundary)) {\n var inHole = false;\n var k = 1;\n // check for the point in any of the holes\n while (k < polys[i].length && !inHole) {\n if (inRing(pt, polys[i][k], !options.ignoreBoundary)) {\n inHole = true;\n }\n k++;\n }\n if (!inHole) {\n insidePoly = true;\n }\n }\n }\n return insidePoly;\n}\nexports.default = booleanPointInPolygon;\n/**\n * inRing\n *\n * @private\n * @param {Array} pt [x,y]\n * @param {Array>} ring [[x,y], [x,y],..]\n * @param {boolean} ignoreBoundary ignoreBoundary\n * @returns {boolean} inRing\n */\nfunction inRing(pt, ring, ignoreBoundary) {\n var isInside = false;\n if (ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1]) {\n ring = ring.slice(0, ring.length - 1);\n }\n for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n var xi = ring[i][0];\n var yi = ring[i][1];\n var xj = ring[j][0];\n var yj = ring[j][1];\n var onBoundary = (pt[1] * (xi - xj) + yi * (xj - pt[0]) + yj * (pt[0] - xi) === 0) &&\n ((xi - pt[0]) * (xj - pt[0]) <= 0) && ((yi - pt[1]) * (yj - pt[1]) <= 0);\n if (onBoundary) {\n return !ignoreBoundary;\n }\n var intersect = ((yi > pt[1]) !== (yj > pt[1])) &&\n (pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi);\n if (intersect) {\n isInside = !isInside;\n }\n }\n return isInside;\n}\n/**\n * inBBox\n *\n * @private\n * @param {Position} pt point [x,y]\n * @param {BBox} bbox BBox [west, south, east, north]\n * @returns {boolean} true/false if point is inside BBox\n */\nfunction inBBox(pt, bbox) {\n return bbox[0] <= pt[0] &&\n bbox[1] <= pt[1] &&\n bbox[2] >= pt[0] &&\n bbox[3] >= pt[1];\n}\n\n\n//# sourceURL=webpack:///./node_modules/@turf/boolean-point-in-polygon/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar bearing_1 = __webpack_require__(5);\nvar distance_1 = __webpack_require__(9);\nvar destination_1 = __webpack_require__(6);\nvar line_intersect_1 = __webpack_require__(16);\nvar meta_1 = __webpack_require__(32);\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n/**\n * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.\n *\n * @name nearestPointOnLine\n * @param {Geometry|Feature} lines lines to snap to\n * @param {Geometry|Feature|number[]} pt point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {Feature} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var pt = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, pt, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine(lines, pt, options) {\n if (options === void 0) { options = {}; }\n var closestPt = helpers_1.point([Infinity, Infinity], {\n dist: Infinity\n });\n var length = 0.0;\n meta_1.flattenEach(lines, function (line) {\n var coords = invariant_1.getCoords(line);\n for (var i = 0; i < coords.length - 1; i++) {\n //start\n var start = helpers_1.point(coords[i]);\n start.properties.dist = distance_1.default(pt, start, options);\n //stop\n var stop_1 = helpers_1.point(coords[i + 1]);\n stop_1.properties.dist = distance_1.default(pt, stop_1, options);\n // sectionLength\n var sectionLength = distance_1.default(start, stop_1, options);\n //perpendicular\n var heightDistance = Math.max(start.properties.dist, stop_1.properties.dist);\n var direction = bearing_1.default(start, stop_1);\n var perpendicularPt1 = destination_1.default(pt, heightDistance, direction + 90, options);\n var perpendicularPt2 = destination_1.default(pt, heightDistance, direction - 90, options);\n var intersect = line_intersect_1.default(helpers_1.lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]), helpers_1.lineString([start.geometry.coordinates, stop_1.geometry.coordinates]));\n var intersectPt = null;\n if (intersect.features.length > 0) {\n intersectPt = intersect.features[0];\n intersectPt.properties.dist = distance_1.default(pt, intersectPt, options);\n intersectPt.properties.location = length + distance_1.default(start, intersectPt, options);\n }\n if (start.properties.dist < closestPt.properties.dist) {\n closestPt = start;\n closestPt.properties.index = i;\n closestPt.properties.location = length;\n }\n if (stop_1.properties.dist < closestPt.properties.dist) {\n closestPt = stop_1;\n closestPt.properties.index = i + 1;\n closestPt.properties.location = length + sectionLength;\n }\n if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {\n closestPt = intersectPt;\n closestPt.properties.index = i;\n }\n // update length\n length += sectionLength;\n }\n });\n return closestPt;\n}\nexports.default = nearestPointOnLine;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/nearest-point-on-line/index.js?")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\nvar meta_1 = __webpack_require__(26);\n/**\n * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a\n * {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}.\n *\n * @name lineSegment\n * @param {GeoJSON} geojson GeoJSON Polygon or LineString\n * @returns {FeatureCollection} 2-vertex line segments\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n * var segments = turf.lineSegment(polygon);\n *\n * //addToMap\n * var addToMap = [polygon, segments]\n */\nfunction lineSegment(geojson) {\n if (!geojson) {\n throw new Error("geojson is required");\n }\n var results = [];\n meta_1.flattenEach(geojson, function (feature) {\n lineSegmentFeature(feature, results);\n });\n return helpers_1.featureCollection(results);\n}\n/**\n * Line Segment\n *\n * @private\n * @param {Feature} geojson Line or polygon feature\n * @param {Array} results push to results\n * @returns {void}\n */\nfunction lineSegmentFeature(geojson, results) {\n var coords = [];\n var geometry = geojson.geometry;\n if (geometry !== null) {\n switch (geometry.type) {\n case "Polygon":\n coords = invariant_1.getCoords(geometry);\n break;\n case "LineString":\n coords = [invariant_1.getCoords(geometry)];\n }\n coords.forEach(function (coord) {\n var segments = createSegments(coord, geojson.properties);\n segments.forEach(function (segment) {\n segment.id = results.length;\n results.push(segment);\n });\n });\n }\n}\n/**\n * Create Segments from LineString coordinates\n *\n * @private\n * @param {Array>} coords LineString coordinates\n * @param {*} properties GeoJSON properties\n * @returns {Array>} line segments\n */\nfunction createSegments(coords, properties) {\n var segments = [];\n coords.reduce(function (previousCoords, currentCoords) {\n var segment = helpers_1.lineString([previousCoords, currentCoords], properties);\n segment.bbox = bbox(previousCoords, currentCoords);\n segments.push(segment);\n return currentCoords;\n });\n return segments;\n}\n/**\n * Create BBox between two coordinates (faster than @turf/bbox)\n *\n * @private\n * @param {Array} coords1 Point coordinate\n * @param {Array} coords2 Point coordinate\n * @returns {BBox} [west, south, east, north]\n */\nfunction bbox(coords1, coords2) {\n var x1 = coords1[0];\n var y1 = coords1[1];\n var x2 = coords2[0];\n var y2 = coords2[1];\n var west = (x1 < x2) ? x1 : x2;\n var south = (y1 < y2) ? y1 : y2;\n var east = (x1 > x2) ? x1 : x2;\n var north = (y1 > y2) ? y1 : y2;\n return [west, south, east, north];\n}\nexports.default = lineSegment;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-segment/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-segment/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-intersect/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){eval('var rbush = __webpack_require__(29);\nvar helpers = __webpack_require__(1);\nvar meta = __webpack_require__(31);\nvar turfBBox = __webpack_require__(3).default;\nvar featureEach = meta.featureEach;\nvar coordEach = meta.coordEach;\nvar polygon = helpers.polygon;\nvar featureCollection = helpers.featureCollection;\n\n/**\n * GeoJSON implementation of [RBush](https://github.com/mourner/rbush#rbush) spatial index.\n *\n * @name rbush\n * @param {number} [maxEntries=9] defines the maximum number of entries in a tree node. 9 (used by default) is a\n * reasonable choice for most applications. Higher value means faster insertion and slower search, and vice versa.\n * @returns {RBush} GeoJSON RBush\n * @example\n * var geojsonRbush = require(\'geojson-rbush\').default;\n * var tree = geojsonRbush();\n */\nfunction geojsonRbush(maxEntries) {\n var tree = rbush(maxEntries);\n /**\n * [insert](https://github.com/mourner/rbush#data-format)\n *\n * @param {Feature} feature insert single GeoJSON Feature\n * @returns {RBush} GeoJSON RBush\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n * tree.insert(poly)\n */\n tree.insert = function (feature) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid feature\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n return rbush.prototype.insert.call(this, feature);\n };\n\n /**\n * [load](https://github.com/mourner/rbush#bulk-inserting-data)\n *\n * @param {FeatureCollection|Array} features load entire GeoJSON FeatureCollection\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polys = turf.polygons([\n * [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]],\n * [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]]\n * ]);\n * tree.load(polys);\n */\n tree.load = function (features) {\n var load = [];\n // Load an Array of Features\n if (Array.isArray(features)) {\n features.forEach(function (feature) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid features\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n load.push(feature);\n });\n } else {\n // Load a FeatureCollection\n featureEach(features, function (feature) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid features\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n load.push(feature);\n });\n }\n return rbush.prototype.load.call(this, load);\n };\n\n /**\n * [remove](https://github.com/mourner/rbush#removing-data)\n *\n * @param {Feature} feature remove single GeoJSON Feature\n * @param {Function} equals Pass a custom equals function to compare by value for removal.\n * @returns {RBush} GeoJSON RBush\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n *\n * tree.remove(poly);\n */\n tree.remove = function (feature, equals) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid feature\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n return rbush.prototype.remove.call(this, feature, equals);\n };\n\n /**\n * [clear](https://github.com/mourner/rbush#removing-data)\n *\n * @returns {RBush} GeoJSON Rbush\n * @example\n * tree.clear()\n */\n tree.clear = function () {\n return rbush.prototype.clear.call(this);\n };\n\n /**\n * [search](https://github.com/mourner/rbush#search)\n *\n * @param {BBox|FeatureCollection|Feature} geojson search with GeoJSON\n * @returns {FeatureCollection} all features that intersects with the given GeoJSON.\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n *\n * tree.search(poly);\n */\n tree.search = function (geojson) {\n var features = rbush.prototype.search.call(this, this.toBBox(geojson));\n return featureCollection(features);\n };\n\n /**\n * [collides](https://github.com/mourner/rbush#collisions)\n *\n * @param {BBox|FeatureCollection|Feature} geojson collides with GeoJSON\n * @returns {boolean} true if there are any items intersecting the given GeoJSON, otherwise false.\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n *\n * tree.collides(poly);\n */\n tree.collides = function (geojson) {\n return rbush.prototype.collides.call(this, this.toBBox(geojson));\n };\n\n /**\n * [all](https://github.com/mourner/rbush#search)\n *\n * @returns {FeatureCollection} all the features in RBush\n * @example\n * tree.all()\n */\n tree.all = function () {\n var features = rbush.prototype.all.call(this);\n return featureCollection(features);\n };\n\n /**\n * [toJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @returns {any} export data as JSON object\n * @example\n * var exported = tree.toJSON()\n */\n tree.toJSON = function () {\n return rbush.prototype.toJSON.call(this);\n };\n\n /**\n * [fromJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @param {any} json import previously exported data\n * @returns {RBush} GeoJSON RBush\n * @example\n * var exported = {\n * "children": [\n * {\n * "type": "Feature",\n * "geometry": {\n * "type": "Point",\n * "coordinates": [110, 50]\n * },\n * "properties": {},\n * "bbox": [110, 50, 110, 50]\n * }\n * ],\n * "height": 1,\n * "leaf": true,\n * "minX": 110,\n * "minY": 50,\n * "maxX": 110,\n * "maxY": 50\n * }\n * tree.fromJSON(exported)\n */\n tree.fromJSON = function (json) {\n return rbush.prototype.fromJSON.call(this, json);\n };\n\n /**\n * Converts GeoJSON to {minX, minY, maxX, maxY} schema\n *\n * @private\n * @param {BBox|FeatureCollection|Feature} geojson feature(s) to retrieve BBox from\n * @returns {Object} converted to {minX, minY, maxX, maxY}\n */\n tree.toBBox = function (geojson) {\n var bbox;\n if (geojson.bbox) bbox = geojson.bbox;\n else if (Array.isArray(geojson) && geojson.length === 4) bbox = geojson;\n else if (Array.isArray(geojson) && geojson.length === 6) bbox = [geojson[0], geojson[1], geojson[3], geojson[4]];\n else if (geojson.type === \'Feature\') bbox = turfBBox(geojson);\n else if (geojson.type === \'FeatureCollection\') bbox = turfBBox(geojson);\n else throw new Error(\'invalid geojson\')\n\n return {\n minX: bbox[0],\n minY: bbox[1],\n maxX: bbox[2],\n maxY: bbox[3]\n };\n };\n return tree;\n}\n\nmodule.exports = geojsonRbush;\nmodule.exports.default = geojsonRbush;\n\n\n//# sourceURL=webpack:///./node_modules/geojson-rbush/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = rbush;\nmodule.exports.default = rbush;\n\nvar quickselect = __webpack_require__(30);\n\nfunction rbush(maxEntries, format) {\n if (!(this instanceof rbush)) return new rbush(maxEntries, format);\n\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries || 9);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\n if (format) {\n this._initFormat(format);\n }\n\n this.clear();\n}\n\nrbush.prototype = {\n\n all: function () {\n return this._all(this.data, []);\n },\n\n search: function (bbox) {\n\n var node = this.data,\n result = [],\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return result;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return result;\n },\n\n collides: function (bbox) {\n\n var node = this.data,\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return false;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) return true;\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return false;\n },\n\n load: function (data) {\n if (!(data && data.length)) return this;\n\n if (data.length < this._minEntries) {\n for (var i = 0, len = data.length; i < len; i++) {\n this.insert(data[i]);\n }\n return this;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n var node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n var tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n\n return this;\n },\n\n insert: function (item) {\n if (item) this._insert(item, this.data.height - 1);\n return this;\n },\n\n clear: function () {\n this.data = createNode([]);\n return this;\n },\n\n remove: function (item, equalsFn) {\n if (!item) return this;\n\n var node = this.data,\n bbox = this.toBBox(item),\n path = [],\n indexes = [],\n i, parent, index, goingUp;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n\n if (!node) { // go up\n node = path.pop();\n parent = path[path.length - 1];\n i = indexes.pop();\n goingUp = true;\n }\n\n if (node.leaf) { // check current node\n index = findItem(item, node.children, equalsFn);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n return this;\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n path.push(node);\n indexes.push(i);\n i = 0;\n parent = node;\n node = node.children[0];\n\n } else if (parent) { // go right\n i++;\n node = parent.children[i];\n goingUp = false;\n\n } else node = null; // nothing found\n }\n\n return this;\n },\n\n toBBox: function (item) { return item; },\n\n compareMinX: compareNodeMinX,\n compareMinY: compareNodeMinY,\n\n toJSON: function () { return this.data; },\n\n fromJSON: function (data) {\n this.data = data;\n return this;\n },\n\n _all: function (node, result) {\n var nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push.apply(result, node.children);\n else nodesToSearch.push.apply(nodesToSearch, node.children);\n\n node = nodesToSearch.pop();\n }\n return result;\n },\n\n _build: function (items, left, right, height) {\n\n var N = right - left + 1,\n M = this._maxEntries,\n node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n var N2 = Math.ceil(N / M),\n N1 = N2 * Math.ceil(Math.sqrt(M)),\n i, j, right2, right3;\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (i = left; i <= right; i += N1) {\n\n right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (j = i; j <= right2; j += N2) {\n\n right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n },\n\n _chooseSubtree: function (bbox, node, level, path) {\n\n var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;\n\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) break;\n\n minArea = minEnlargement = Infinity;\n\n for (i = 0, len = node.children.length; i < len; i++) {\n child = node.children[i];\n area = bboxArea(child);\n enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n },\n\n _insert: function (item, level, isNode) {\n\n var toBBox = this.toBBox,\n bbox = isNode ? item : toBBox(item),\n insertPath = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n var node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n },\n\n // split overflowed node into two\n _split: function (insertPath, level) {\n\n var node = insertPath[level],\n M = node.children.length,\n m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n var splitIndex = this._chooseSplitIndex(node, m, M);\n\n var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n },\n\n _splitRoot: function (node, newNode) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n },\n\n _chooseSplitIndex: function (node, m, M) {\n\n var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;\n\n minOverlap = minArea = Infinity;\n\n for (i = m; i <= M - m; i++) {\n bbox1 = distBBox(node, 0, i, this.toBBox);\n bbox2 = distBBox(node, i, M, this.toBBox);\n\n overlap = intersectionArea(bbox1, bbox2);\n area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index;\n },\n\n // sorts node children by the best axis for split\n _chooseSplitAxis: function (node, m, M) {\n\n var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,\n compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,\n xMargin = this._allDistMargin(node, m, M, compareMinX),\n yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) node.children.sort(compareMinX);\n },\n\n // total margin of all possible split distributions where each node is at least m full\n _allDistMargin: function (node, m, M, compare) {\n\n node.children.sort(compare);\n\n var toBBox = this.toBBox,\n leftBBox = distBBox(node, 0, m, toBBox),\n rightBBox = distBBox(node, M - m, M, toBBox),\n margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),\n i, child;\n\n for (i = m; i < M - m; i++) {\n child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (i = M - m - 1; i >= m; i--) {\n child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n },\n\n _adjustParentBBoxes: function (bbox, path, level) {\n // adjust bboxes along the given tree path\n for (var i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n },\n\n _condense: function (path) {\n // go through the path, removing empty nodes and updating bboxes\n for (var i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n\n } else this.clear();\n\n } else calcBBox(path[i], this.toBBox);\n }\n },\n\n _initFormat: function (format) {\n // data format (minX, minY, maxX, maxY accessors)\n\n // uses eval-type function compilation instead of just accepting a toBBox function\n // because the algorithms are very sensitive to sorting functions performance,\n // so they should be dead simple and without inner calls\n\n var compareArr = ['return a', ' - b', ';'];\n\n this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));\n this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));\n\n this.toBBox = new Function('a',\n 'return {minX: a' + format[0] +\n ', minY: a' + format[1] +\n ', maxX: a' + format[2] +\n ', maxY: a' + format[3] + '};');\n }\n};\n\nfunction findItem(item, items, equalsFn) {\n if (!equalsFn) return items.indexOf(item);\n\n for (var i = 0; i < items.length; i++) {\n if (equalsFn(item, items[i])) return i;\n }\n return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n if (!destNode) destNode = createNode(null);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (var i = k, child; i < p; i++) {\n child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a, b) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n var minX = Math.max(a.minX, b.minX),\n minY = Math.max(a.minY, b.minY),\n maxX = Math.min(a.maxX, b.maxX),\n maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) *\n Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n return a.minX <= b.minX &&\n a.minY <= b.minY &&\n b.maxX <= a.maxX &&\n b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n return b.minX <= a.maxX &&\n b.minY <= a.maxY &&\n b.maxX >= a.minX &&\n b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n return {\n children: children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n var stack = [left, right],\n mid;\n\n while (stack.length) {\n right = stack.pop();\n left = stack.pop();\n\n if (right - left <= n) continue;\n\n mid = left + Math.ceil((right - left) / n / 2) * n;\n quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/rbush/index.js?")},function(module,exports,__webpack_require__){eval("(function (global, factory) {\n\t true ? module.exports = factory() :\n\tundefined;\n}(this, (function () { 'use strict';\n\nfunction quickselect(arr, k, left, right, compare) {\n quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);\n}\n\nfunction quickselectStep(arr, k, left, right, compare) {\n\n while (right > left) {\n if (right - left > 600) {\n var n = right - left + 1;\n var m = k - left + 1;\n var z = Math.log(n);\n var s = 0.5 * Math.exp(2 * z / 3);\n var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselectStep(arr, k, newLeft, newRight, compare);\n }\n\n var t = arr[k];\n var i = left;\n var j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap(arr, i, j) {\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nreturn quickselect;\n\n})));\n\n\n//# sourceURL=webpack:///./node_modules/quickselect/quickselect.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/geojson-rbush/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/nearest-point-on-line/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){eval("module.exports = {\n aStar: __webpack_require__(34),\n aGreedy: __webpack_require__(35),\n nba: __webpack_require__(36),\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/index.js?")},function(module,exports,__webpack_require__){eval("/**\n * Performs a uni-directional A Star search on graph.\n * \n * We will try to minimize f(n) = g(n) + h(n), where\n * g(n) is actual distance from source node to `n`, and\n * h(n) is heuristic distance from `n` to target node.\n */\nmodule.exports = aStarPathSearch;\n\nvar NodeHeap = __webpack_require__(11);\nvar makeSearchStatePool = __webpack_require__(17);\nvar heuristics = __webpack_require__(12);\nvar defaultSettings = __webpack_require__(13);\n\nvar NO_PATH = defaultSettings.NO_PATH;\n\nmodule.exports.l2 = heuristics.l2;\nmodule.exports.l1 = heuristics.l1;\n\n/**\n * Creates a new instance of pathfinder. A pathfinder has just one method:\n * `find(fromId, toId)`, it may be extended in future.\n * \n * @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph\n * @param {Object} options that configures search\n * @param {Function(a, b)} options.heuristic - a function that returns estimated distance between\n * nodes `a` and `b`. This function should never overestimate actual distance between two\n * nodes (otherwise the found path will not be the shortest). Defaults function returns 0,\n * which makes this search equivalent to Dijkstra search.\n * @param {Function(a, b)} options.distance - a function that returns actual distance between two\n * nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);\n * \n * @returns {Object} A pathfinder with single method `find()`.\n */\nfunction aStarPathSearch(graph, options) {\n options = options || {};\n // whether traversal should be considered over oriented graph.\n var oriented = options.oriented;\n\n var heuristic = options.heuristic;\n if (!heuristic) heuristic = defaultSettings.heuristic;\n\n var distance = options.distance;\n if (!distance) distance = defaultSettings.distance;\n var pool = makeSearchStatePool();\n\n return {\n /**\n * Finds a path between node `fromId` and `toId`.\n * @returns {Array} of nodes between `toId` and `fromId`. Empty array is returned\n * if no path is found.\n */\n find: find\n };\n\n function find(fromId, toId) {\n var from = graph.getNode(fromId);\n if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);\n var to = graph.getNode(toId);\n if (!to) throw new Error('toId is not defined in this graph: ' + toId);\n pool.reset();\n\n // Maps nodeId to NodeSearchState.\n var nodeState = new Map();\n\n // the nodes that we still need to evaluate\n var openSet = new NodeHeap({\n compare: defaultSettings.compareFScore,\n setNodeId: defaultSettings.setHeapIndex\n });\n\n var startNode = pool.createNewState(from);\n nodeState.set(fromId, startNode);\n\n // For the first node, fScore is completely heuristic.\n startNode.fScore = heuristic(from, to);\n\n // The cost of going from start to start is zero.\n startNode.distanceToSource = 0;\n openSet.push(startNode);\n startNode.open = 1;\n\n var cameFrom;\n\n while (openSet.length > 0) {\n cameFrom = openSet.pop();\n if (goalReached(cameFrom, to)) return reconstructPath(cameFrom);\n\n // no need to visit this node anymore\n cameFrom.closed = true;\n graph.forEachLinkedNode(cameFrom.node.id, visitNeighbour, oriented);\n }\n\n // If we got here, then there is no path.\n return NO_PATH;\n\n function visitNeighbour(otherNode, link) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) {\n // Already processed this node.\n return;\n }\n if (otherSearchState.open === 0) {\n // Remember this node.\n openSet.push(otherSearchState);\n otherSearchState.open = 1;\n }\n\n var tentativeDistance = cameFrom.distanceToSource + distance(otherNode, cameFrom.node, link);\n if (tentativeDistance >= otherSearchState.distanceToSource) {\n // This would only make our path longer. Ignore this route.\n return;\n }\n\n // bingo! we found shorter path:\n otherSearchState.parent = cameFrom;\n otherSearchState.distanceToSource = tentativeDistance;\n otherSearchState.fScore = tentativeDistance + heuristic(otherSearchState.node, to);\n\n openSet.updateItem(otherSearchState.heapIndex);\n }\n }\n}\n\nfunction goalReached(searchState, targetNode) {\n return searchState.node === targetNode;\n}\n\nfunction reconstructPath(searchState) {\n var path = [searchState.node];\n var parent = searchState.parent;\n\n while (parent) {\n path.push(parent.node);\n parent = parent.parent;\n }\n\n return path;\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/a-star.js?")},function(module,exports,__webpack_require__){eval("/**\n * Performs suboptimal, greed A Star path finding.\n * This finder does not necessary finds the shortest path. The path\n * that it finds is very close to the shortest one. It is very fast though.\n */\nmodule.exports = aStarBi;\n\nvar NodeHeap = __webpack_require__(11);\nvar makeSearchStatePool = __webpack_require__(17);\nvar heuristics = __webpack_require__(12);\nvar defaultSettings = __webpack_require__(13);\n\nvar BY_FROM = 1;\nvar BY_TO = 2;\nvar NO_PATH = defaultSettings.NO_PATH;\n\nmodule.exports.l2 = heuristics.l2;\nmodule.exports.l1 = heuristics.l1;\n\n/**\n * Creates a new instance of pathfinder. A pathfinder has just one method:\n * `find(fromId, toId)`, it may be extended in future.\n * \n * NOTE: Algorithm implemented in this code DOES NOT find optimal path.\n * Yet the path that it finds is always near optimal, and it finds it very fast.\n * \n * @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph\n * \n * @param {Object} options that configures search\n * @param {Function(a, b)} options.heuristic - a function that returns estimated distance between\n * nodes `a` and `b`. Defaults function returns 0, which makes this search equivalent to Dijkstra search.\n * @param {Function(a, b)} options.distance - a function that returns actual distance between two\n * nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);\n * \n * @returns {Object} A pathfinder with single method `find()`.\n */\nfunction aStarBi(graph, options) {\n options = options || {};\n // whether traversal should be considered over oriented graph.\n var oriented = options.oriented;\n\n var heuristic = options.heuristic;\n if (!heuristic) heuristic = defaultSettings.heuristic;\n\n var distance = options.distance;\n if (!distance) distance = defaultSettings.distance;\n var pool = makeSearchStatePool();\n\n return {\n find: find\n };\n\n function find(fromId, toId) {\n // Not sure if we should return NO_PATH or throw. Throw seem to be more\n // helpful to debug errors. So, throwing.\n var from = graph.getNode(fromId);\n if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);\n var to = graph.getNode(toId);\n if (!to) throw new Error('toId is not defined in this graph: ' + toId);\n\n if (from === to) return [from]; // trivial case.\n\n pool.reset();\n\n var callVisitor = oriented ? orientedVisitor : nonOrientedVisitor;\n\n // Maps nodeId to NodeSearchState.\n var nodeState = new Map();\n\n var openSetFrom = new NodeHeap({\n compare: defaultSettings.compareFScore,\n setNodeId: defaultSettings.setHeapIndex\n });\n\n var openSetTo = new NodeHeap({\n compare: defaultSettings.compareFScore,\n setNodeId: defaultSettings.setHeapIndex\n });\n\n\n var startNode = pool.createNewState(from);\n nodeState.set(fromId, startNode);\n\n // For the first node, fScore is completely heuristic.\n startNode.fScore = heuristic(from, to);\n // The cost of going from start to start is zero.\n startNode.distanceToSource = 0;\n openSetFrom.push(startNode);\n startNode.open = BY_FROM;\n\n var endNode = pool.createNewState(to);\n endNode.fScore = heuristic(to, from);\n endNode.distanceToSource = 0;\n openSetTo.push(endNode);\n endNode.open = BY_TO;\n\n // Cost of the best solution found so far. Used for accurate termination\n var lMin = Number.POSITIVE_INFINITY;\n var minFrom;\n var minTo;\n\n var currentSet = openSetFrom;\n var currentOpener = BY_FROM;\n\n while (openSetFrom.length > 0 && openSetTo.length > 0) {\n if (openSetFrom.length < openSetTo.length) {\n // we pick a set with less elements\n currentOpener = BY_FROM;\n currentSet = openSetFrom;\n } else {\n currentOpener = BY_TO;\n currentSet = openSetTo;\n }\n\n var current = currentSet.pop();\n\n // no need to visit this node anymore\n current.closed = true;\n\n if (current.distanceToSource > lMin) continue;\n\n graph.forEachLinkedNode(current.node.id, callVisitor);\n\n if (minFrom && minTo) {\n // This is not necessary the best path, but we are so greedy that we\n // can't resist:\n return reconstructBiDirectionalPath(minFrom, minTo);\n }\n }\n\n return NO_PATH; // No path.\n\n function nonOrientedVisitor(otherNode, link) {\n return visitNode(otherNode, link, current);\n }\n\n function orientedVisitor(otherNode, link) {\n // For oritned graphs we need to reverse graph, when traveling\n // backwards. So, we use non-oriented ngraph's traversal, and \n // filter link orientation here.\n if (currentOpener === BY_FROM) {\n if (link.fromId === current.node.id) return visitNode(otherNode, link, current)\n } else if (currentOpener === BY_TO) {\n if (link.toId === current.node.id) return visitNode(otherNode, link, current);\n }\n }\n\n function canExit(currentNode) {\n var opener = currentNode.open\n if (opener && opener !== currentOpener) {\n return true;\n }\n\n return false;\n }\n\n function reconstructBiDirectionalPath(a, b) {\n var pathOfNodes = [];\n var aParent = a;\n while(aParent) {\n pathOfNodes.push(aParent.node);\n aParent = aParent.parent;\n }\n var bParent = b;\n while (bParent) {\n pathOfNodes.unshift(bParent.node);\n bParent = bParent.parent\n }\n return pathOfNodes;\n }\n\n function visitNode(otherNode, link, cameFrom) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) {\n // Already processed this node.\n return;\n }\n\n if (canExit(otherSearchState, cameFrom)) {\n // this node was opened by alternative opener. The sets intersect now,\n // we found an optimal path, that goes through *this* node. However, there\n // is no guarantee that this is the global optimal solution path.\n\n var potentialLMin = otherSearchState.distanceToSource + cameFrom.distanceToSource;\n if (potentialLMin < lMin) {\n minFrom = otherSearchState;\n minTo = cameFrom\n lMin = potentialLMin;\n }\n // we are done with this node.\n return;\n }\n\n var tentativeDistance = cameFrom.distanceToSource + distance(otherSearchState.node, cameFrom.node, link);\n\n if (tentativeDistance >= otherSearchState.distanceToSource) {\n // This would only make our path longer. Ignore this route.\n return;\n }\n\n // Choose target based on current working set:\n var target = (currentOpener === BY_FROM) ? to : from;\n var newFScore = tentativeDistance + heuristic(otherSearchState.node, target);\n if (newFScore >= lMin) {\n // this can't be optimal path, as we have already found a shorter path.\n return;\n }\n otherSearchState.fScore = newFScore;\n\n if (otherSearchState.open === 0) {\n // Remember this node in the current set\n currentSet.push(otherSearchState);\n currentSet.updateItem(otherSearchState.heapIndex);\n\n otherSearchState.open = currentOpener;\n }\n\n // bingo! we found shorter path:\n otherSearchState.parent = cameFrom;\n otherSearchState.distanceToSource = tentativeDistance;\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/a-greedy-star.js?")},function(module,exports,__webpack_require__){eval("module.exports = nba;\n\nvar NodeHeap = __webpack_require__(11);\nvar heuristics = __webpack_require__(12);\nvar defaultSettings = __webpack_require__(13);\nvar makeNBASearchStatePool = __webpack_require__(37);\n\nvar NO_PATH = defaultSettings.NO_PATH;\n\nmodule.exports.l2 = heuristics.l2;\nmodule.exports.l1 = heuristics.l1;\n\n/**\n * Creates a new instance of pathfinder. A pathfinder has just one method:\n * `find(fromId, toId)`.\n * \n * This is implementation of the NBA* algorithm described in \n * \n * \"Yet another bidirectional algorithm for shortest paths\" paper by Wim Pijls and Henk Post\n * \n * The paper is available here: https://repub.eur.nl/pub/16100/ei2009-10.pdf\n * \n * @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph\n * @param {Object} options that configures search\n * @param {Function(a, b)} options.heuristic - a function that returns estimated distance between\n * nodes `a` and `b`. This function should never overestimate actual distance between two\n * nodes (otherwise the found path will not be the shortest). Defaults function returns 0,\n * which makes this search equivalent to Dijkstra search.\n * @param {Function(a, b)} options.distance - a function that returns actual distance between two\n * nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);\n * \n * @returns {Object} A pathfinder with single method `find()`.\n */\nfunction nba(graph, options) {\n options = options || {};\n // whether traversal should be considered over oriented graph.\n var oriented = options.oriented;\n var quitFast = options.quitFast;\n\n var heuristic = options.heuristic;\n if (!heuristic) heuristic = defaultSettings.heuristic;\n\n var distance = options.distance;\n if (!distance) distance = defaultSettings.distance;\n\n // During stress tests I noticed that garbage collection was one of the heaviest\n // contributors to the algorithm's speed. So I'm using an object pool to recycle nodes.\n var pool = makeNBASearchStatePool();\n\n return {\n /**\n * Finds a path between node `fromId` and `toId`.\n * @returns {Array} of nodes between `toId` and `fromId`. Empty array is returned\n * if no path is found.\n */\n find: find\n };\n\n function find(fromId, toId) {\n // I must apologize for the code duplication. This was the easiest way for me to\n // implement the algorithm fast.\n var from = graph.getNode(fromId);\n if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);\n var to = graph.getNode(toId);\n if (!to) throw new Error('toId is not defined in this graph: ' + toId);\n\n pool.reset();\n\n // I must also apologize for somewhat cryptic names. The NBA* is bi-directional\n // search algorithm, which means it runs two searches in parallel. One runs\n // from source node to target, while the other one runs from target to source.\n // Everywhere where you see `1` it means it's for the forward search. `2` is for \n // backward search.\n\n // For oriented graph path finding, we need to reverse the graph, so that\n // backward search visits correct link. Obviously we don't want to duplicate\n // the graph, instead we always traverse the graph as non-oriented, and filter\n // edges in `visitN1Oriented/visitN2Oritented`\n var forwardVisitor = oriented ? visitN1Oriented : visitN1;\n var reverseVisitor = oriented ? visitN2Oriented : visitN2;\n\n // Maps nodeId to NBASearchState.\n var nodeState = new Map();\n\n // These two heaps store nodes by their underestimated values.\n var open1Set = new NodeHeap({\n compare: defaultSettings.compareF1Score,\n setNodeId: defaultSettings.setH1\n });\n var open2Set = new NodeHeap({\n compare: defaultSettings.compareF2Score,\n setNodeId: defaultSettings.setH2\n });\n\n // This is where both searches will meet.\n var minNode;\n\n // The smallest path length seen so far is stored here:\n var lMin = Number.POSITIVE_INFINITY;\n\n // We start by putting start/end nodes to the corresponding heaps\n var startNode = pool.createNewState(from);\n nodeState.set(fromId, startNode); \n startNode.g1 = 0;\n var f1 = heuristic(from, to);\n startNode.f1 = f1;\n open1Set.push(startNode);\n\n var endNode = pool.createNewState(to);\n nodeState.set(toId, endNode);\n endNode.g2 = 0;\n var f2 = f1; // they should agree originally\n endNode.f2 = f2;\n open2Set.push(endNode)\n\n // the `cameFrom` variable is accessed by both searches, so that we can store parents.\n var cameFrom;\n\n // this is the main algorithm loop:\n while (open2Set.length && open1Set.length) {\n if (open1Set.length < open2Set.length) {\n forwardSearch();\n } else {\n reverseSearch();\n }\n\n if (quitFast && minNode) break;\n }\n\n // If we got here, then there is no path.\n var path = reconstructPath(minNode);\n return path; // the public API is over\n\n function forwardSearch() {\n cameFrom = open1Set.pop();\n if (cameFrom.closed) {\n return;\n }\n\n cameFrom.closed = true;\n\n if (cameFrom.f1 < lMin && (cameFrom.g1 + f2 - heuristic(from, cameFrom.node)) < lMin) {\n graph.forEachLinkedNode(cameFrom.node.id, forwardVisitor);\n }\n\n if (open1Set.length > 0) {\n f1 = open1Set.peek().f1;\n } \n }\n\n function reverseSearch() {\n cameFrom = open2Set.pop();\n if (cameFrom.closed) {\n return;\n }\n cameFrom.closed = true;\n\n if (cameFrom.f2 < lMin && (cameFrom.g2 + f1 - heuristic(cameFrom.node, to)) < lMin) {\n graph.forEachLinkedNode(cameFrom.node.id, reverseVisitor);\n }\n\n if (open2Set.length > 0) {\n f2 = open2Set.peek().f2;\n }\n }\n\n function visitN1(otherNode, link) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) return;\n\n var tentativeDistance = cameFrom.g1 + distance(cameFrom.node, otherNode, link);\n\n if (tentativeDistance < otherSearchState.g1) {\n otherSearchState.g1 = tentativeDistance;\n otherSearchState.f1 = tentativeDistance + heuristic(otherSearchState.node, to);\n otherSearchState.p1 = cameFrom;\n if (otherSearchState.h1 < 0) {\n open1Set.push(otherSearchState);\n } else {\n open1Set.updateItem(otherSearchState.h1);\n }\n }\n var potentialMin = otherSearchState.g1 + otherSearchState.g2;\n if (potentialMin < lMin) { \n lMin = potentialMin;\n minNode = otherSearchState;\n }\n }\n\n function visitN2(otherNode, link) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) return;\n\n var tentativeDistance = cameFrom.g2 + distance(cameFrom.node, otherNode, link);\n\n if (tentativeDistance < otherSearchState.g2) {\n otherSearchState.g2 = tentativeDistance;\n otherSearchState.f2 = tentativeDistance + heuristic(from, otherSearchState.node);\n otherSearchState.p2 = cameFrom;\n if (otherSearchState.h2 < 0) {\n open2Set.push(otherSearchState);\n } else {\n open2Set.updateItem(otherSearchState.h2);\n }\n }\n var potentialMin = otherSearchState.g1 + otherSearchState.g2;\n if (potentialMin < lMin) {\n lMin = potentialMin;\n minNode = otherSearchState;\n }\n }\n\n function visitN2Oriented(otherNode, link) {\n // we are going backwards, graph needs to be reversed. \n if (link.toId === cameFrom.node.id) return visitN2(otherNode, link);\n }\n function visitN1Oriented(otherNode, link) {\n // this is forward direction, so we should be coming FROM:\n if (link.fromId === cameFrom.node.id) return visitN1(otherNode, link);\n }\n }\n}\n\nfunction reconstructPath(searchState) {\n if (!searchState) return NO_PATH;\n\n var path = [searchState.node];\n var parent = searchState.p1;\n\n while (parent) {\n path.push(parent.node);\n parent = parent.p1;\n }\n\n var child = searchState.p2;\n\n while (child) {\n path.unshift(child.node);\n child = child.p2;\n }\n return path;\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/nba/index.js?")},function(module,exports){eval("module.exports = makeNBASearchStatePool;\n\n/**\n * Creates new instance of NBASearchState. The instance stores information\n * about search state, and is used by NBA* algorithm.\n *\n * @param {Object} node - original graph node\n */\nfunction NBASearchState(node) {\n /**\n * Original graph node.\n */\n this.node = node;\n\n /**\n * Parent of this node in forward search\n */\n this.p1 = null;\n\n /**\n * Parent of this node in reverse search\n */\n this.p2 = null;\n\n /**\n * If this is set to true, then the node was already processed\n * and we should not touch it anymore.\n */\n this.closed = false;\n\n /**\n * Actual distance from this node to its parent in forward search\n */\n this.g1 = Number.POSITIVE_INFINITY;\n\n /**\n * Actual distance from this node to its parent in reverse search\n */\n this.g2 = Number.POSITIVE_INFINITY;\n\n\n /**\n * Underestimated distance from this node to the path-finding source.\n */\n this.f1 = Number.POSITIVE_INFINITY;\n\n /**\n * Underestimated distance from this node to the path-finding target.\n */\n this.f2 = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated. TODO: do I need them both?\n\n /**\n * Index of this node in the forward heap.\n */\n this.h1 = -1;\n\n /**\n * Index of this node in the reverse heap.\n */\n this.h2 = -1;\n}\n\n/**\n * As path-finding is memory-intensive process, we want to reduce pressure on\n * garbage collector. This class helps us to recycle path-finding nodes and significantly\n * reduces the search time (~20% faster than without it).\n */\nfunction makeNBASearchStatePool() {\n var currentInCache = 0;\n var nodeCache = [];\n\n return {\n /**\n * Creates a new NBASearchState instance\n */\n createNewState: createNewState,\n\n /**\n * Marks all created instances available for recycling.\n */\n reset: reset\n };\n\n function reset() {\n currentInCache = 0;\n }\n\n function createNewState(node) {\n var cached = nodeCache[currentInCache];\n if (cached) {\n // TODO: This almost duplicates constructor code. Not sure if\n // it would impact performance if I move this code into a function\n cached.node = node;\n\n // How we came to this node?\n cached.p1 = null;\n cached.p2 = null;\n\n cached.closed = false;\n\n cached.g1 = Number.POSITIVE_INFINITY;\n cached.g2 = Number.POSITIVE_INFINITY;\n cached.f1 = Number.POSITIVE_INFINITY;\n cached.f2 = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated.\n cached.h1 = -1;\n cached.h2 = -1;\n } else {\n cached = new NBASearchState(node);\n nodeCache[currentInCache] = cached;\n }\n currentInCache++;\n return cached;\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/nba/makeNBASearchStatePool.js?")},function(module,exports,__webpack_require__){eval("/**\n * @fileOverview Contains definition of the core graph object.\n */\n\n// TODO: need to change storage layer:\n// 1. Be able to get all nodes O(1)\n// 2. Be able to get number of links O(1)\n\n/**\n * @example\n * var graph = require('ngraph.graph')();\n * graph.addNode(1); // graph has one node.\n * graph.addLink(2, 3); // now graph contains three nodes and one link.\n *\n */\nmodule.exports = createGraph;\n\nvar eventify = __webpack_require__(39);\n\n/**\n * Creates a new graph\n */\nfunction createGraph(options) {\n // Graph structure is maintained as dictionary of nodes\n // and array of links. Each node has 'links' property which\n // hold all links related to that node. And general links\n // array is used to speed up all links enumeration. This is inefficient\n // in terms of memory, but simplifies coding.\n options = options || {};\n if ('uniqueLinkId' in options) {\n console.warn(\n 'ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\\n' +\n 'Use `multigraph` option instead\\n',\n '\\n',\n 'Note: there is also change in default behavior: From now own each graph\\n'+\n 'is considered to be not a multigraph by default (each edge is unique).'\n );\n\n options.multigraph = options.uniqueLinkId;\n }\n\n // Dear reader, the non-multigraphs do not guarantee that there is only\n // one link for a given pair of node. When this option is set to false\n // we can save some memory and CPU (18% faster for non-multigraph);\n if (options.multigraph === undefined) options.multigraph = false;\n\n var nodes = typeof Object.create === 'function' ? Object.create(null) : {},\n links = [],\n // Hash of multi-edges. Used to track ids of edges between same nodes\n multiEdges = {},\n nodesCount = 0,\n suspendEvents = 0,\n\n forEachNode = createNodeIterator(),\n createLink = options.multigraph ? createUniqueLink : createSingleLink,\n\n // Our graph API provides means to listen to graph changes. Users can subscribe\n // to be notified about changes in the graph by using `on` method. However\n // in some cases they don't use it. To avoid unnecessary memory consumption\n // we will not record graph changes until we have at least one subscriber.\n // Code below supports this optimization.\n //\n // Accumulates all changes made during graph updates.\n // Each change element contains:\n // changeType - one of the strings: 'add', 'remove' or 'update';\n // node - if change is related to node this property is set to changed graph's node;\n // link - if change is related to link this property is set to changed graph's link;\n changes = [],\n recordLinkChange = noop,\n recordNodeChange = noop,\n enterModification = noop,\n exitModification = noop;\n\n // this is our public API:\n var graphPart = {\n /**\n * Adds node to the graph. If node with given id already exists in the graph\n * its data is extended with whatever comes in 'data' argument.\n *\n * @param nodeId the node's identifier. A string or number is preferred.\n * @param [data] additional data for the node being added. If node already\n * exists its data object is augmented with the new one.\n *\n * @return {node} The newly added node or node with given id if it already exists.\n */\n addNode: addNode,\n\n /**\n * Adds a link to the graph. The function always create a new\n * link between two nodes. If one of the nodes does not exists\n * a new node is created.\n *\n * @param fromId link start node id;\n * @param toId link end node id;\n * @param [data] additional data to be set on the new link;\n *\n * @return {link} The newly created link\n */\n addLink: addLink,\n\n /**\n * Removes link from the graph. If link does not exist does nothing.\n *\n * @param link - object returned by addLink() or getLinks() methods.\n *\n * @returns true if link was removed; false otherwise.\n */\n removeLink: removeLink,\n\n /**\n * Removes node with given id from the graph. If node does not exist in the graph\n * does nothing.\n *\n * @param nodeId node's identifier passed to addNode() function.\n *\n * @returns true if node was removed; false otherwise.\n */\n removeNode: removeNode,\n\n /**\n * Gets node with given identifier. If node does not exist undefined value is returned.\n *\n * @param nodeId requested node identifier;\n *\n * @return {node} in with requested identifier or undefined if no such node exists.\n */\n getNode: getNode,\n\n /**\n * Gets number of nodes in this graph.\n *\n * @return number of nodes in the graph.\n */\n getNodesCount: function () {\n return nodesCount;\n },\n\n /**\n * Gets total number of links in the graph.\n */\n getLinksCount: function () {\n return links.length;\n },\n\n /**\n * Gets all links (inbound and outbound) from the node with given id.\n * If node with given id is not found null is returned.\n *\n * @param nodeId requested node identifier.\n *\n * @return Array of links from and to requested node if such node exists;\n * otherwise null is returned.\n */\n getLinks: getLinks,\n\n /**\n * Invokes callback on each node of the graph.\n *\n * @param {Function(node)} callback Function to be invoked. The function\n * is passed one argument: visited node.\n */\n forEachNode: forEachNode,\n\n /**\n * Invokes callback on every linked (adjacent) node to the given one.\n *\n * @param nodeId Identifier of the requested node.\n * @param {Function(node, link)} callback Function to be called on all linked nodes.\n * The function is passed two parameters: adjacent node and link object itself.\n * @param oriented if true graph treated as oriented.\n */\n forEachLinkedNode: forEachLinkedNode,\n\n /**\n * Enumerates all links in the graph\n *\n * @param {Function(link)} callback Function to be called on all links in the graph.\n * The function is passed one parameter: graph's link object.\n *\n * Link object contains at least the following fields:\n * fromId - node id where link starts;\n * toId - node id where link ends,\n * data - additional data passed to graph.addLink() method.\n */\n forEachLink: forEachLink,\n\n /**\n * Suspend all notifications about graph changes until\n * endUpdate is called.\n */\n beginUpdate: enterModification,\n\n /**\n * Resumes all notifications about graph changes and fires\n * graph 'changed' event in case there are any pending changes.\n */\n endUpdate: exitModification,\n\n /**\n * Removes all nodes and links from the graph.\n */\n clear: clear,\n\n /**\n * Detects whether there is a link between two nodes.\n * Operation complexity is O(n) where n - number of links of a node.\n * NOTE: this function is synonim for getLink()\n *\n * @returns link if there is one. null otherwise.\n */\n hasLink: getLink,\n\n /**\n * Detects whether there is a node with given id\n * \n * Operation complexity is O(1)\n * NOTE: this function is synonim for getNode()\n *\n * @returns node if there is one; Falsy value otherwise.\n */\n hasNode: getNode,\n\n /**\n * Gets an edge between two nodes.\n * Operation complexity is O(n) where n - number of links of a node.\n *\n * @param {string} fromId link start identifier\n * @param {string} toId link end identifier\n *\n * @returns link if there is one. null otherwise.\n */\n getLink: getLink\n };\n\n // this will add `on()` and `fire()` methods.\n eventify(graphPart);\n\n monitorSubscribers();\n\n return graphPart;\n\n function monitorSubscribers() {\n var realOn = graphPart.on;\n\n // replace real `on` with our temporary on, which will trigger change\n // modification monitoring:\n graphPart.on = on;\n\n function on() {\n // now it's time to start tracking stuff:\n graphPart.beginUpdate = enterModification = enterModificationReal;\n graphPart.endUpdate = exitModification = exitModificationReal;\n recordLinkChange = recordLinkChangeReal;\n recordNodeChange = recordNodeChangeReal;\n\n // this will replace current `on` method with real pub/sub from `eventify`.\n graphPart.on = realOn;\n // delegate to real `on` handler:\n return realOn.apply(graphPart, arguments);\n }\n }\n\n function recordLinkChangeReal(link, changeType) {\n changes.push({\n link: link,\n changeType: changeType\n });\n }\n\n function recordNodeChangeReal(node, changeType) {\n changes.push({\n node: node,\n changeType: changeType\n });\n }\n\n function addNode(nodeId, data) {\n if (nodeId === undefined) {\n throw new Error('Invalid node identifier');\n }\n\n enterModification();\n\n var node = getNode(nodeId);\n if (!node) {\n node = new Node(nodeId, data);\n nodesCount++;\n recordNodeChange(node, 'add');\n } else {\n node.data = data;\n recordNodeChange(node, 'update');\n }\n\n nodes[nodeId] = node;\n\n exitModification();\n return node;\n }\n\n function getNode(nodeId) {\n return nodes[nodeId];\n }\n\n function removeNode(nodeId) {\n var node = getNode(nodeId);\n if (!node) {\n return false;\n }\n\n enterModification();\n\n var prevLinks = node.links;\n if (prevLinks) {\n node.links = null;\n for(var i = 0; i < prevLinks.length; ++i) {\n removeLink(prevLinks[i]);\n }\n }\n\n delete nodes[nodeId];\n nodesCount--;\n\n recordNodeChange(node, 'remove');\n\n exitModification();\n\n return true;\n }\n\n\n function addLink(fromId, toId, data) {\n enterModification();\n\n var fromNode = getNode(fromId) || addNode(fromId);\n var toNode = getNode(toId) || addNode(toId);\n\n var link = createLink(fromId, toId, data);\n\n links.push(link);\n\n // TODO: this is not cool. On large graphs potentially would consume more memory.\n addLinkToNode(fromNode, link);\n if (fromId !== toId) {\n // make sure we are not duplicating links for self-loops\n addLinkToNode(toNode, link);\n }\n\n recordLinkChange(link, 'add');\n\n exitModification();\n\n return link;\n }\n\n function createSingleLink(fromId, toId, data) {\n var linkId = makeLinkId(fromId, toId);\n return new Link(fromId, toId, data, linkId);\n }\n\n function createUniqueLink(fromId, toId, data) {\n // TODO: Get rid of this method.\n var linkId = makeLinkId(fromId, toId);\n var isMultiEdge = multiEdges.hasOwnProperty(linkId);\n if (isMultiEdge || getLink(fromId, toId)) {\n if (!isMultiEdge) {\n multiEdges[linkId] = 0;\n }\n var suffix = '@' + (++multiEdges[linkId]);\n linkId = makeLinkId(fromId + suffix, toId + suffix);\n }\n\n return new Link(fromId, toId, data, linkId);\n }\n\n function getLinks(nodeId) {\n var node = getNode(nodeId);\n return node ? node.links : null;\n }\n\n function removeLink(link) {\n if (!link) {\n return false;\n }\n var idx = indexOfElementInArray(link, links);\n if (idx < 0) {\n return false;\n }\n\n enterModification();\n\n links.splice(idx, 1);\n\n var fromNode = getNode(link.fromId);\n var toNode = getNode(link.toId);\n\n if (fromNode) {\n idx = indexOfElementInArray(link, fromNode.links);\n if (idx >= 0) {\n fromNode.links.splice(idx, 1);\n }\n }\n\n if (toNode) {\n idx = indexOfElementInArray(link, toNode.links);\n if (idx >= 0) {\n toNode.links.splice(idx, 1);\n }\n }\n\n recordLinkChange(link, 'remove');\n\n exitModification();\n\n return true;\n }\n\n function getLink(fromNodeId, toNodeId) {\n // TODO: Use sorted links to speed this up\n var node = getNode(fromNodeId),\n i;\n if (!node || !node.links) {\n return null;\n }\n\n for (i = 0; i < node.links.length; ++i) {\n var link = node.links[i];\n if (link.fromId === fromNodeId && link.toId === toNodeId) {\n return link;\n }\n }\n\n return null; // no link.\n }\n\n function clear() {\n enterModification();\n forEachNode(function(node) {\n removeNode(node.id);\n });\n exitModification();\n }\n\n function forEachLink(callback) {\n var i, length;\n if (typeof callback === 'function') {\n for (i = 0, length = links.length; i < length; ++i) {\n callback(links[i]);\n }\n }\n }\n\n function forEachLinkedNode(nodeId, callback, oriented) {\n var node = getNode(nodeId);\n\n if (node && node.links && typeof callback === 'function') {\n if (oriented) {\n return forEachOrientedLink(node.links, nodeId, callback);\n } else {\n return forEachNonOrientedLink(node.links, nodeId, callback);\n }\n }\n }\n\n function forEachNonOrientedLink(links, nodeId, callback) {\n var quitFast;\n for (var i = 0; i < links.length; ++i) {\n var link = links[i];\n var linkedNodeId = link.fromId === nodeId ? link.toId : link.fromId;\n\n quitFast = callback(nodes[linkedNodeId], link);\n if (quitFast) {\n return true; // Client does not need more iterations. Break now.\n }\n }\n }\n\n function forEachOrientedLink(links, nodeId, callback) {\n var quitFast;\n for (var i = 0; i < links.length; ++i) {\n var link = links[i];\n if (link.fromId === nodeId) {\n quitFast = callback(nodes[link.toId], link);\n if (quitFast) {\n return true; // Client does not need more iterations. Break now.\n }\n }\n }\n }\n\n // we will not fire anything until users of this library explicitly call `on()`\n // method.\n function noop() {}\n\n // Enter, Exit modification allows bulk graph updates without firing events.\n function enterModificationReal() {\n suspendEvents += 1;\n }\n\n function exitModificationReal() {\n suspendEvents -= 1;\n if (suspendEvents === 0 && changes.length > 0) {\n graphPart.fire('changed', changes);\n changes.length = 0;\n }\n }\n\n function createNodeIterator() {\n // Object.keys iterator is 1.3x faster than `for in` loop.\n // See `https://github.com/anvaka/ngraph.graph/tree/bench-for-in-vs-obj-keys`\n // branch for perf test\n return Object.keys ? objectKeysIterator : forInIterator;\n }\n\n function objectKeysIterator(callback) {\n if (typeof callback !== 'function') {\n return;\n }\n\n var keys = Object.keys(nodes);\n for (var i = 0; i < keys.length; ++i) {\n if (callback(nodes[keys[i]])) {\n return true; // client doesn't want to proceed. Return.\n }\n }\n }\n\n function forInIterator(callback) {\n if (typeof callback !== 'function') {\n return;\n }\n var node;\n\n for (node in nodes) {\n if (callback(nodes[node])) {\n return true; // client doesn't want to proceed. Return.\n }\n }\n }\n}\n\n// need this for old browsers. Should this be a separate module?\nfunction indexOfElementInArray(element, array) {\n if (!array) return -1;\n\n if (array.indexOf) {\n return array.indexOf(element);\n }\n\n var len = array.length,\n i;\n\n for (i = 0; i < len; i += 1) {\n if (array[i] === element) {\n return i;\n }\n }\n\n return -1;\n}\n\n/**\n * Internal structure to represent node;\n */\nfunction Node(id, data) {\n this.id = id;\n this.links = null;\n this.data = data;\n}\n\nfunction addLinkToNode(node, link) {\n if (node.links) {\n node.links.push(link);\n } else {\n node.links = [link];\n }\n}\n\n/**\n * Internal structure to represent links;\n */\nfunction Link(fromId, toId, data, id) {\n this.fromId = fromId;\n this.toId = toId;\n this.data = data;\n this.id = id;\n}\n\nfunction hashCode(str) {\n var hash = 0, i, chr, len;\n if (str.length == 0) return hash;\n for (i = 0, len = str.length; i < len; i++) {\n chr = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n}\n\nfunction makeLinkId(fromId, toId) {\n return fromId.toString() + '👉 ' + toId.toString();\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.graph/index.js?")},function(module,exports){eval("module.exports = function(subject) {\n validateSubject(subject);\n\n var eventsStorage = createEventsStorage(subject);\n subject.on = eventsStorage.on;\n subject.off = eventsStorage.off;\n subject.fire = eventsStorage.fire;\n return subject;\n};\n\nfunction createEventsStorage(subject) {\n // Store all event listeners to this hash. Key is event name, value is array\n // of callback records.\n //\n // A callback record consists of callback function and its optional context:\n // { 'eventName' => [{callback: function, ctx: object}] }\n var registeredEvents = Object.create(null);\n\n return {\n on: function (eventName, callback, ctx) {\n if (typeof callback !== 'function') {\n throw new Error('callback is expected to be a function');\n }\n var handlers = registeredEvents[eventName];\n if (!handlers) {\n handlers = registeredEvents[eventName] = [];\n }\n handlers.push({callback: callback, ctx: ctx});\n\n return subject;\n },\n\n off: function (eventName, callback) {\n var wantToRemoveAll = (typeof eventName === 'undefined');\n if (wantToRemoveAll) {\n // Killing old events storage should be enough in this case:\n registeredEvents = Object.create(null);\n return subject;\n }\n\n if (registeredEvents[eventName]) {\n var deleteAllCallbacksForEvent = (typeof callback !== 'function');\n if (deleteAllCallbacksForEvent) {\n delete registeredEvents[eventName];\n } else {\n var callbacks = registeredEvents[eventName];\n for (var i = 0; i < callbacks.length; ++i) {\n if (callbacks[i].callback === callback) {\n callbacks.splice(i, 1);\n }\n }\n }\n }\n\n return subject;\n },\n\n fire: function (eventName) {\n var callbacks = registeredEvents[eventName];\n if (!callbacks) {\n return subject;\n }\n\n var fireArguments;\n if (arguments.length > 1) {\n fireArguments = Array.prototype.splice.call(arguments, 1);\n }\n for(var i = 0; i < callbacks.length; ++i) {\n var callbackInfo = callbacks[i];\n callbackInfo.callback.apply(callbackInfo.ctx, fireArguments);\n }\n\n return subject;\n }\n };\n}\n\nfunction validateSubject(subject) {\n if (!subject) {\n throw new Error('Eventify cannot use falsy object as events subject');\n }\n var reservedWords = ['on', 'fire', 'off'];\n for (var i = 0; i < reservedWords.length; ++i) {\n if (subject.hasOwnProperty(reservedWords[i])) {\n throw new Error(\"Subject cannot be eventified, since it already has property '\" + reservedWords[i] + \"'\");\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.events/index.js?")},function(module,exports,__webpack_require__){eval('function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n/* Functions that help design and generate building units onto the map. */\nvar bearing = __webpack_require__(5).default,\n destination = __webpack_require__(6).default,\n along = __webpack_require__(15).default,\n lineIntersect = __webpack_require__(16).default,\n intersect = __webpack_require__(41).default,\n Agentmap = __webpack_require__(4).Agentmap,\n streetsToGraph = __webpack_require__(10).streetsToGraph,\n getPathFinder = __webpack_require__(10).getPathFinder;\n/**\r\n * Generate and setup the desired map features (e.g. streets, houses).\r\n * @memberof Agentmap\r\n * @instance\r\n *\r\n * @param {Array.>} bounding_box - The map\'s top-left and bottom-right coordinates.\r\n * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} [street_options] - An object containing the Leaflet styling options for streets. See available options here: {@link https://leafletjs.com/reference-1.3.2.html#polyline-l-polyline}.\r\n * @param {object} [unit_options] - An object containing the Leaflet & AgentMaps styling options for units.
See available Leaflet options here: {@link https://leafletjs.com/reference-1.3.2.html#polygon-l-polygon}
Additional AgentMaps-specific options are described below.\r\n * @param {number} [unit_options.front_buffer = 6] - The number of meters beetween the front of unit and its street.\r\n * @param {number} [unit_options.side_buffer = 3] - The number of meters between two units on the same street.\r\n * @param {number} [unit_options.length = 14] - The length of the unit in meters along the street.\r\n * @param {number} [unit_options.depth = 18] - The depth of the unit in meters out from its front.\r\n * @param {object} [units_data]- If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup.\r\n */\n\n\nfunction buildingify(bounding_box, streets_data, street_options, unit_options, units_data) {\n setupStreetFeatures.call(this, streets_data, street_options);\n setupUnitFeatures.call(this, bounding_box, streets_data, unit_options, units_data);\n}\n/**\r\n * Generate and setup streets based on the provided GeoJSON data.\r\n *\r\n * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} street_options - An object containing the Leaflet styling options for streets.\r\n */\n\n\nfunction setupStreetFeatures(streets_data, street_options) {\n var street_features = getStreetFeatures(streets_data);\n default_options = {\n "color": "yellow",\n "weight": 4,\n "opacity": .5\n };\n street_options = Object.assign(default_options, street_options);\n var street_feature_collection = {\n type: "FeatureCollection",\n features: street_features\n };\n this.streets = L.geoJSON(street_feature_collection, street_options).addTo(this.map); //Map streets\' OSM IDs to their Leaflet IDs.\n\n this.streets.id_map = {}; //Having added the streets as layers to the map, do any processing that requires access to those layers.\n\n this.streets.eachLayer(function (street) {\n this.streets.id_map[street.feature.id] = street._leaflet_id;\n addStreetLayerIntersections.call(this, street);\n }, this); //Add general graph-making and path-finder-making methods to Agentmap, in case streets are added, removed, or modified mid-simulation.\n\n this.streetsToGraph = streetsToGraph, this.getPathFinder = getPathFinder;\n this.streets.graph = streetsToGraph(this.streets), this.pathfinder = getPathFinder(this.streets.graph);\n}\n/**\r\n * Get all streets from the GeoJSON data.\r\n * @private\r\n *\r\n * @param {Object} streets_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box.\r\n * @returns {Array} - array of street features.\r\n */\n\n\nfunction getStreetFeatures(streets_data) {\n var street_features = [];\n\n for (var i = 0; i < streets_data.features.length; ++i) {\n var feature = streets_data.features[i];\n\n if (feature.geometry.type === "LineString" && feature.properties.highway) {\n var street_feature = feature;\n street_features.push(street_feature);\n }\n }\n\n return street_features;\n}\n/**\r\n * Gets the intersections of all the streets on the map and adds them as properties to the street layers.\r\n * @private\r\n * \r\n * @param {object} street - A Leaflet polyline representing a street.\r\n */\n\n\nfunction addStreetLayerIntersections(street) {\n var street_id = street._leaflet_id;\n street.intersections = typeof street.intersections === "undefined" ? {} : street.intersections;\n this.streets.eachLayer(function (other_street) {\n var other_street_id = other_street._leaflet_id; //Skip if both streets are the same, or if the street already has its intersections with the other street.\n\n if (typeof street.intersections[other_street_id] === "undefined" && street_id !== other_street_id) {\n var street_coords = street.getLatLngs().map(L.A.pointToCoordinateArray),\n other_street_coords = other_street.getLatLngs().map(L.A.pointToCoordinateArray),\n identified_intersections = L.A.getIntersections(street_coords, other_street_coords, [street_id, other_street_id]).map(function (identified_intersection) {\n return [L.latLng(L.A.reversedCoordinates(identified_intersection[0])), identified_intersection[1]];\n });\n\n if (identified_intersections.length > 0) {\n street.intersections[other_street_id] = identified_intersections, other_street.intersections = typeof other_street.intersections === "undefined" ? {} : other_street.intersections, other_street.intersections[street_id] = identified_intersections;\n }\n }\n });\n}\n/**\r\n * Generate and setup building units based on the provided GeoJSON data.\r\n *\r\n * @param {Array.>} bounding_box - The map\'s top-left and bottom-right coordinates.\r\n * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} unit_options - An object containing the Leaflet & AgentMaps styling options for units.\r\n * @param {object} [units_data] - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup.\r\n */\n\n\nfunction setupUnitFeatures(bounding_box, streets_data) {\n var unit_options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var units_data = arguments.length > 3 ? arguments[3] : undefined;\n var default_options = {\n "color": "green",\n "weight": 1,\n "opacity": .87,\n "front_buffer": 6,\n "side_buffer": 3,\n "length": 14,\n "depth": 18\n };\n unit_options = Object.assign(default_options, unit_options);\n var unit_feature_collection; //If no units_data is supplied, generate the units from scratch.\n\n if (typeof units_data === "undefined") {\n //Bind getUnitFeatures to "this" so it can access the agentmap as "this.agentmap".\n var _unit_features = getUnitFeatures.bind(this)(bounding_box, streets_data, unit_options);\n\n unit_feature_collection = {\n type: "FeatureCollection",\n features: _unit_features\n };\n } else {\n unit_feature_collection = units_data;\n }\n\n this.units = L.geoJSON(unit_feature_collection, unit_options).addTo(this.map); //Having added the units as layers to the map, do any processing that requires access to those layers.\n\n this.units.eachLayer(function (unit) {\n if (typeof units_data === "undefined") {\n unit.street_id = unit.feature.properties.street_id;\n } else {\n unit.street_id = this.streets.id_map[unit.feature.properties.OSM_street_id];\n }\n\n unit.street_anchors = unit.feature.properties.street_anchors, //Change the IDs of each unit in this unit\'s neighbours array into the appropriate Leaflet IDs.\n unit.neighbors = getUnitNeighborLayerIDs.call(this, unit.feature.properties.neighbors);\n }, this);\n}\n/**\r\n * Given an array of pre-layer IDs, check if any of them correspond to the pre-layer IDs of unit layers, and if so\r\n * return an array of the corresponding layer IDs.\r\n * @private\r\n *\r\n * @param {Array} - An array of pre-layer feature IDs for a unit\'s neighbors.\r\n * @returns {Array} - An array of Leaflet layer IDs corresponding to the unit\'s neighbors.\r\n */\n\n\nfunction getUnitNeighborLayerIDs(neighbors) {\n var neighbor_layer_ids = neighbors.map(function (neighbor) {\n if (neighbor !== null) {\n var neighbor_layer_id = null;\n this.units.eachLayer(function (possible_neighbor_layer) {\n if (possible_neighbor_layer.feature.properties.id === neighbor) {\n neighbor_layer_id = this.units.getLayerId(possible_neighbor_layer);\n }\n }, this);\n return neighbor_layer_id;\n } else {\n return null;\n }\n }, this);\n return neighbor_layer_ids;\n}\n/**\r\n * Get all appropriate units within the desired bounding box.\r\n * @private\r\n *\r\n * @param {Array.>} bounding_box - The map\'s top-left and bottom-right coordinates.\r\n * @param {Object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} unit_options - An object containing the AgentMaps styling options for units.\r\n * @returns {Array} - array of features representing real estate units.\r\n */\n\n\nfunction getUnitFeatures(bounding_box, streets_data, unit_options) {\n var proposed_unit_features = [];\n this.streets.eachLayer(function (layer) {\n var street_feature = layer.feature,\n street_id = layer._leaflet_id,\n street_OSM_id = layer.feature.id,\n proposed_anchors = getUnitAnchors(street_feature, bounding_box, unit_options),\n new_proposed_unit_features = generateUnitFeatures(proposed_anchors, proposed_unit_features, street_id, street_OSM_id, unit_options);\n proposed_unit_features.push.apply(proposed_unit_features, _toConsumableArray(new_proposed_unit_features));\n });\n unit_features = unitsOutOfStreets(proposed_unit_features, this.streets);\n return unit_features;\n}\n/**\r\n * Given an array of anchor pairs, for each anchor pair find four \r\n * nearby points on either side of the street appropriate to build a unit(s) on.\r\n * @private\r\n *\r\n * @param {Array>} unit_anchors - Array of pairs of points around which to anchor units along a street.\r\n * @param {Array} proposed_unit_features - Array of features representing building units already proposed for construction.\r\n * @param {string} street_leaflet_id - The Leaflet layer ID of the street feature along which the unit is being constructed.\r\n * @param {string} street_OSM_id - The OSM feature ID of the street feature along which the unit is being constructed.\r\n * @param {object} unit_options - An object containing the AgentMaps styling options for units.\r\n * @returns {Array} unit_features - Array of features representing units.\r\n */\n\n\nfunction generateUnitFeatures(unit_anchors, proposed_unit_features, street_leaflet_id, street_OSM_id, unit_options) {\n var _ref;\n\n //One sub-array of unit features for each side of the road.\n var unit_features = [[], []],\n starting_id = proposed_unit_features.length,\n increment = 1;\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = unit_anchors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var anchor_pair = _step.value;\n //Pair of unit_features opposite each other on a street.\n var unit_pair = [null, null];\n var _arr = [1, -1];\n\n for (var _i = 0; _i < _arr.length; _i++) {\n var i = _arr[_i];\n var anchor_a = anchor_pair[0].geometry.coordinates,\n anchor_b = anchor_pair[1].geometry.coordinates,\n anchor_latLng_pair = [anchor_a, anchor_b],\n street_buffer = unit_options.front_buffer / 1000,\n //Distance between center of street and start of unit.\n house_depth = unit_options.depth / 1000,\n angle = bearing(anchor_a, anchor_b),\n new_angle = angle + i * 90,\n //Angle of line perpendicular to the anchor segment.\n unit_feature = {\n type: "Feature",\n properties: {\n street: "none"\n },\n geometry: {\n type: "Polygon",\n coordinates: [[]]\n }\n };\n unit_feature.geometry.coordinates[0][0] = destination(anchor_a, street_buffer, new_angle).geometry.coordinates, unit_feature.geometry.coordinates[0][1] = destination(anchor_b, street_buffer, new_angle).geometry.coordinates, unit_feature.geometry.coordinates[0][2] = destination(anchor_b, street_buffer + house_depth, new_angle).geometry.coordinates, unit_feature.geometry.coordinates[0][3] = destination(anchor_a, street_buffer + house_depth, new_angle).geometry.coordinates;\n unit_feature.geometry.coordinates[0][4] = unit_feature.geometry.coordinates[0][0]; //Exclude the unit if it overlaps with any of the other proposed units.\n\n var all_proposed_unit_features = unit_features[0].concat(unit_features[1]).concat(proposed_unit_features);\n\n if (noOverlaps(unit_feature, all_proposed_unit_features)) {\n //Recode index so that it\'s useful here.\n i = i === 1 ? 0 : 1;\n unit_feature.properties.street_id = street_leaflet_id, unit_feature.properties.OSM_street_id = street_OSM_id, unit_feature.properties.street_anchors = anchor_latLng_pair, unit_feature.properties.neighbors = [null, null, null], unit_feature.properties.id = starting_id + increment, increment += 1;\n\n if (unit_features[i].length !== 0) {\n //Make previous unit_feature this unit_feature\'s first neighbor.\n unit_feature.properties.neighbors[0] = unit_features[i][unit_features[i].length - 1].properties.id, //Make this unit_feature the previous unit_feature\'s second neighbor.\n unit_features[i][unit_features[i].length - 1].properties.neighbors[1] = unit_feature.properties.id;\n }\n\n if (i === 0) {\n unit_pair[0] = unit_feature;\n } else {\n if (unit_pair[0] !== null) {\n //Make unit_feature opposite to this unit_feature on the street its third neighbor.\n unit_feature.properties.neighbors[2] = unit_pair[0].properties.id, //Make unit_feature opposite to this unit_feature on the street\'s third neighbor this unit_feature.\n unit_pair[0].properties.neighbors[2] = unit_feature.properties.id;\n }\n\n unit_pair[1] = unit_feature;\n }\n }\n }\n\n if (unit_pair[0] !== null) {\n unit_features[0].push(unit_pair[0]);\n }\n\n if (unit_pair[1] !== null) {\n unit_features[1].push(unit_pair[1]);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n var unit_features_merged = (_ref = []).concat.apply(_ref, unit_features);\n\n return unit_features_merged;\n}\n/**\r\n * Find anchors for potential units. chors are the pairs of start \r\n * and end points along the street from which units may be constructed.\r\n * @private\r\n * \r\n * @param {Feature} street_feature - A GeoJSON feature object representing a street.\r\n * @param {object} unit_options - An object containing the AgentMaps styling options for units.\r\n * @returns {Array>} - Array of pairs of points around which to anchor units along a street. \r\n */\n\n\nfunction getUnitAnchors(street_feature, bounding_box, unit_options) {\n var unit_anchors = [],\n unit_length = unit_options.length / 1000,\n //Kilometers.\n unit_buffer = unit_options.side_buffer / 1000,\n //Distance between units, kilometers.\n endpoint = street_feature.geometry.coordinates[street_feature.geometry.coordinates.length - 1],\n start_anchor = along(street_feature, 0),\n end_anchor = along(street_feature, unit_length),\n distance_along = unit_length;\n\n while (end_anchor.geometry.coordinates != endpoint) {\n //Exclude proposed anchors if they\'re outside of the bounding box.\n start_coord = L.A.reversedCoordinates(start_anchor.geometry.coordinates), end_coord = L.A.reversedCoordinates(end_anchor.geometry.coordinates);\n\n if (L.latLngBounds(bounding_box).contains(start_coord) && L.latLngBounds(bounding_box).contains(end_coord)) {\n unit_anchors.push([start_anchor, end_anchor]);\n } //Find next pair of anchors.\n\n\n start_anchor = along(street_feature, distance_along + unit_buffer);\n end_anchor = along(street_feature, distance_along + unit_buffer + unit_length);\n distance_along += unit_buffer + unit_length;\n }\n\n return unit_anchors;\n}\n/**\r\n * Get an array of units excluding units that overlap with streets.\r\n * @private\r\n *\r\n * @param {Array} unit_features - Array of features representing units.\r\n * @param {Array} street_layers - Array of Leaflet layers representing streets.\r\n * @returns {Array} - unit_features, but with all units that intersect any streets removed.\r\n */\n\n\nfunction unitsOutOfStreets(unit_features, street_layers) {\n var processed_unit_features = unit_features.slice();\n street_layers.eachLayer(function (street_layer) {\n var street_feature = street_layer.feature;\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = processed_unit_features[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var unit_feature = _step2.value;\n var intersection_exists = lineIntersect(street_feature, unit_feature).features.length > 0;\n\n if (intersection_exists) {\n processed_unit_features.splice(processed_unit_features.indexOf(unit_feature), 1, null);\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n processed_unit_features = processed_unit_features.filter(function (feature) {\n return feature === null ? false : true;\n });\n });\n return processed_unit_features;\n}\n/**\r\n * Check whether a polygon overlaps with any member of an array of polygons.\r\n * @private\r\n *\r\n * @param {Feature} reference_polygon_feature - A geoJSON polygon feature.\r\n * @param {Array} polygon_feature_array - Array of geoJSON polygon features.\r\n * @returns {boolean} - Whether the polygon_feature overlaps with any one in the array.\r\n */\n\n\nfunction noOverlaps(reference_polygon_feature, polygon_feature_array) {\n //return true;\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = polygon_feature_array[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n feature_array_element = _step3.value;\n var overlap_exists = intersect(reference_polygon_feature, feature_array_element);\n\n if (overlap_exists) {\n return false;\n }\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return != null) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n return true;\n}\n\nAgentmap.prototype.buildingify = buildingify;\n\n//# sourceURL=webpack:///./src/buildings.js?')},function(module,exports,__webpack_require__){"use strict";eval('\r\nvar __importStar = (this && this.__importStar) || function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result["default"] = mod;\r\n return result;\r\n};\r\nObject.defineProperty(exports, "__esModule", { value: true });\r\nvar helpers_1 = __webpack_require__(1);\r\nvar invariant_1 = __webpack_require__(2);\r\nvar martinez = __importStar(__webpack_require__(42));\r\n/**\r\n * Takes two {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and\r\n * finds their polygonal intersection. If they don\'t intersect, returns null.\r\n *\r\n * @name intersect\r\n * @param {Feature} poly1 the first polygon or multipolygon\r\n * @param {Feature} poly2 the second polygon or multipolygon\r\n * @param {Object} [options={}] Optional Parameters\r\n * @param {Object} [options.properties={}] Translate GeoJSON Properties to Feature\r\n * @returns {Feature|null} returns a feature representing the area they share (either a {@link Polygon} or\r\n * {@link MultiPolygon}). If they do not share any area, returns `null`.\r\n * @example\r\n * var poly1 = turf.polygon([[\r\n * [-122.801742, 45.48565],\r\n * [-122.801742, 45.60491],\r\n * [-122.584762, 45.60491],\r\n * [-122.584762, 45.48565],\r\n * [-122.801742, 45.48565]\r\n * ]]);\r\n *\r\n * var poly2 = turf.polygon([[\r\n * [-122.520217, 45.535693],\r\n * [-122.64038, 45.553967],\r\n * [-122.720031, 45.526554],\r\n * [-122.669906, 45.507309],\r\n * [-122.723464, 45.446643],\r\n * [-122.532577, 45.408574],\r\n * [-122.487258, 45.477466],\r\n * [-122.520217, 45.535693]\r\n * ]]);\r\n *\r\n * var intersection = turf.intersect(poly1, poly2);\r\n *\r\n * //addToMap\r\n * var addToMap = [poly1, poly2, intersection];\r\n */\r\nfunction intersect(poly1, poly2, options) {\r\n if (options === void 0) { options = {}; }\r\n var geom1 = invariant_1.getGeom(poly1);\r\n var geom2 = invariant_1.getGeom(poly2);\r\n if (geom1.type === "Polygon" && geom2.type === "Polygon") {\r\n var intersection = martinez.intersection(geom1.coordinates, geom2.coordinates);\r\n if (intersection === null || intersection.length === 0) {\r\n return null;\r\n }\r\n if (intersection.length === 1) {\r\n var start = intersection[0][0][0];\r\n var end = intersection[0][0][intersection[0][0].length - 1];\r\n if (start[0] === end[0] && start[1] === end[1]) {\r\n return helpers_1.polygon(intersection[0], options.properties);\r\n }\r\n return null;\r\n }\r\n return helpers_1.multiPolygon(intersection, options.properties);\r\n }\r\n else if (geom1.type === "MultiPolygon") {\r\n var resultCoords = [];\r\n // iterate through the polygon and run intersect with each part, adding to the resultCoords.\r\n for (var _i = 0, _a = geom1.coordinates; _i < _a.length; _i++) {\r\n var coords = _a[_i];\r\n var subGeom = invariant_1.getGeom(helpers_1.polygon(coords));\r\n var subIntersection = intersect(subGeom, geom2);\r\n if (subIntersection) {\r\n var subIntGeom = invariant_1.getGeom(subIntersection);\r\n if (subIntGeom.type === "Polygon") {\r\n resultCoords.push(subIntGeom.coordinates);\r\n }\r\n else if (subIntGeom.type === "MultiPolygon") {\r\n resultCoords = resultCoords.concat(subIntGeom.coordinates);\r\n }\r\n else {\r\n throw new Error("intersection is invalid");\r\n }\r\n }\r\n }\r\n // Make a polygon with the result\r\n if (resultCoords.length === 0) {\r\n return null;\r\n }\r\n if (resultCoords.length === 1) {\r\n return helpers_1.polygon(resultCoords[0], options.properties);\r\n }\r\n else {\r\n return helpers_1.multiPolygon(resultCoords, options.properties);\r\n }\r\n }\r\n else if (geom2.type === "MultiPolygon") {\r\n // geom1 is a polygon and geom2 a multiPolygon,\r\n // put the multiPolygon first and fallback to the previous case.\r\n return intersect(geom2, geom1);\r\n }\r\n else {\r\n // handle invalid geometry types\r\n throw new Error("poly1 and poly2 must be either polygons or multiPolygons");\r\n }\r\n}\r\nexports.default = intersect;\r\n\n\n//# sourceURL=webpack:///./node_modules/@turf/intersect/index.js?')},function(module,exports,__webpack_require__){eval("/**\n * martinez v0.4.3\n * Martinez polygon clipping algorithm, does boolean operation on polygons (multipolygons, polygons with holes etc): intersection, union, difference, xor\n *\n * @author Alex Milevski \n * @license MIT\n * @preserve\n */\n\n(function (global, factory) {\n true ? factory(exports) :\n undefined;\n}(this, (function (exports) { 'use strict';\n\n function DEFAULT_COMPARE (a, b) { return a > b ? 1 : a < b ? -1 : 0; }\n\n var SplayTree = function SplayTree(compare, noDuplicates) {\n if ( compare === void 0 ) compare = DEFAULT_COMPARE;\n if ( noDuplicates === void 0 ) noDuplicates = false;\n\n this._compare = compare;\n this._root = null;\n this._size = 0;\n this._noDuplicates = !!noDuplicates;\n };\n\n var prototypeAccessors = { size: { configurable: true } };\n\n\n SplayTree.prototype.rotateLeft = function rotateLeft (x) {\n var y = x.right;\n if (y) {\n x.right = y.left;\n if (y.left) { y.left.parent = x; }\n y.parent = x.parent;\n }\n\n if (!x.parent) { this._root = y; }\n else if (x === x.parent.left) { x.parent.left = y; }\n else { x.parent.right = y; }\n if (y) { y.left = x; }\n x.parent = y;\n };\n\n\n SplayTree.prototype.rotateRight = function rotateRight (x) {\n var y = x.left;\n if (y) {\n x.left = y.right;\n if (y.right) { y.right.parent = x; }\n y.parent = x.parent;\n }\n\n if (!x.parent) { this._root = y; }\n else if(x === x.parent.left) { x.parent.left = y; }\n else { x.parent.right = y; }\n if (y) { y.right = x; }\n x.parent = y;\n };\n\n\n SplayTree.prototype._splay = function _splay (x) {\n var this$1 = this;\n\n while (x.parent) {\n var p = x.parent;\n if (!p.parent) {\n if (p.left === x) { this$1.rotateRight(p); }\n else { this$1.rotateLeft(p); }\n } else if (p.left === x && p.parent.left === p) {\n this$1.rotateRight(p.parent);\n this$1.rotateRight(p);\n } else if (p.right === x && p.parent.right === p) {\n this$1.rotateLeft(p.parent);\n this$1.rotateLeft(p);\n } else if (p.left === x && p.parent.right === p) {\n this$1.rotateRight(p);\n this$1.rotateLeft(p);\n } else {\n this$1.rotateLeft(p);\n this$1.rotateRight(p);\n }\n }\n };\n\n\n SplayTree.prototype.splay = function splay (x) {\n var this$1 = this;\n\n var p, gp, ggp, l, r;\n\n while (x.parent) {\n p = x.parent;\n gp = p.parent;\n\n if (gp && gp.parent) {\n ggp = gp.parent;\n if (ggp.left === gp) { ggp.left= x; }\n else { ggp.right = x; }\n x.parent = ggp;\n } else {\n x.parent = null;\n this$1._root = x;\n }\n\n l = x.left; r = x.right;\n\n if (x === p.left) { // left\n if (gp) {\n if (gp.left === p) {\n /* zig-zig */\n if (p.right) {\n gp.left = p.right;\n gp.left.parent = gp;\n } else { gp.left = null; }\n\n p.right = gp;\n gp.parent = p;\n } else {\n /* zig-zag */\n if (l) {\n gp.right = l;\n l.parent = gp;\n } else { gp.right = null; }\n\n x.left = gp;\n gp.parent = x;\n }\n }\n if (r) {\n p.left = r;\n r.parent = p;\n } else { p.left = null; }\n\n x.right= p;\n p.parent = x;\n } else { // right\n if (gp) {\n if (gp.right === p) {\n /* zig-zig */\n if (p.left) {\n gp.right = p.left;\n gp.right.parent = gp;\n } else { gp.right = null; }\n\n p.left = gp;\n gp.parent = p;\n } else {\n /* zig-zag */\n if (r) {\n gp.left = r;\n r.parent = gp;\n } else { gp.left = null; }\n\n x.right = gp;\n gp.parent = x;\n }\n }\n if (l) {\n p.right = l;\n l.parent = p;\n } else { p.right = null; }\n\n x.left = p;\n p.parent = x;\n }\n }\n };\n\n\n SplayTree.prototype.replace = function replace (u, v) {\n if (!u.parent) { this._root = v; }\n else if (u === u.parent.left) { u.parent.left = v; }\n else { u.parent.right = v; }\n if (v) { v.parent = u.parent; }\n };\n\n\n SplayTree.prototype.minNode = function minNode (u) {\n if ( u === void 0 ) u = this._root;\n\n if (u) { while (u.left) { u = u.left; } }\n return u;\n };\n\n\n SplayTree.prototype.maxNode = function maxNode (u) {\n if ( u === void 0 ) u = this._root;\n\n if (u) { while (u.right) { u = u.right; } }\n return u;\n };\n\n\n SplayTree.prototype.insert = function insert (key, data) {\n var z = this._root;\n var p = null;\n var comp = this._compare;\n var cmp;\n\n if (this._noDuplicates) {\n while (z) {\n p = z;\n cmp = comp(z.key, key);\n if (cmp === 0) { return; }\n else if (comp(z.key, key) < 0) { z = z.right; }\n else { z = z.left; }\n }\n } else {\n while (z) {\n p = z;\n if (comp(z.key, key) < 0) { z = z.right; }\n else { z = z.left; }\n }\n }\n\n z = { key: key, data: data, left: null, right: null, parent: p };\n\n if (!p) { this._root = z; }\n else if (comp(p.key, z.key) < 0) { p.right = z; }\n else { p.left= z; }\n\n this.splay(z);\n this._size++;\n return z;\n };\n\n\n SplayTree.prototype.find = function find (key) {\n var z = this._root;\n var comp = this._compare;\n while (z) {\n var cmp = comp(z.key, key);\n if (cmp < 0) { z = z.right; }\n else if (cmp > 0) { z = z.left; }\n else { return z; }\n }\n return null;\n };\n\n /**\n * Whether the tree contains a node with the given key\n * @param{Key} key\n * @return {boolean} true/false\n */\n SplayTree.prototype.contains = function contains (key) {\n var node = this._root;\n var comparator = this._compare;\n while (node){\n var cmp = comparator(key, node.key);\n if (cmp === 0) { return true; }\n else if (cmp < 0) { node = node.left; }\n else { node = node.right; }\n }\n\n return false;\n };\n\n\n SplayTree.prototype.remove = function remove (key) {\n var z = this.find(key);\n\n if (!z) { return false; }\n\n this.splay(z);\n\n if (!z.left) { this.replace(z, z.right); }\n else if (!z.right) { this.replace(z, z.left); }\n else {\n var y = this.minNode(z.right);\n if (y.parent !== z) {\n this.replace(y, y.right);\n y.right = z.right;\n y.right.parent = y;\n }\n this.replace(z, y);\n y.left = z.left;\n y.left.parent = y;\n }\n\n this._size--;\n return true;\n };\n\n\n SplayTree.prototype.removeNode = function removeNode (z) {\n if (!z) { return false; }\n\n this.splay(z);\n\n if (!z.left) { this.replace(z, z.right); }\n else if (!z.right) { this.replace(z, z.left); }\n else {\n var y = this.minNode(z.right);\n if (y.parent !== z) {\n this.replace(y, y.right);\n y.right = z.right;\n y.right.parent = y;\n }\n this.replace(z, y);\n y.left = z.left;\n y.left.parent = y;\n }\n\n this._size--;\n return true;\n };\n\n\n SplayTree.prototype.erase = function erase (key) {\n var z = this.find(key);\n if (!z) { return; }\n\n this.splay(z);\n\n var s = z.left;\n var t = z.right;\n\n var sMax = null;\n if (s) {\n s.parent = null;\n sMax = this.maxNode(s);\n this.splay(sMax);\n this._root = sMax;\n }\n if (t) {\n if (s) { sMax.right = t; }\n else { this._root = t; }\n t.parent = sMax;\n }\n\n this._size--;\n };\n\n /**\n * Removes and returns the node with smallest key\n * @return {?Node}\n */\n SplayTree.prototype.pop = function pop () {\n var node = this._root, returnValue = null;\n if (node) {\n while (node.left) { node = node.left; }\n returnValue = { key: node.key, data: node.data };\n this.remove(node.key);\n }\n return returnValue;\n };\n\n\n /* eslint-disable class-methods-use-this */\n\n /**\n * Successor node\n * @param{Node} node\n * @return {?Node}\n */\n SplayTree.prototype.next = function next (node) {\n var successor = node;\n if (successor) {\n if (successor.right) {\n successor = successor.right;\n while (successor && successor.left) { successor = successor.left; }\n } else {\n successor = node.parent;\n while (successor && successor.right === node) {\n node = successor; successor = successor.parent;\n }\n }\n }\n return successor;\n };\n\n\n /**\n * Predecessor node\n * @param{Node} node\n * @return {?Node}\n */\n SplayTree.prototype.prev = function prev (node) {\n var predecessor = node;\n if (predecessor) {\n if (predecessor.left) {\n predecessor = predecessor.left;\n while (predecessor && predecessor.right) { predecessor = predecessor.right; }\n } else {\n predecessor = node.parent;\n while (predecessor && predecessor.left === node) {\n node = predecessor;\n predecessor = predecessor.parent;\n }\n }\n }\n return predecessor;\n };\n /* eslint-enable class-methods-use-this */\n\n\n /**\n * @param{forEachCallback} callback\n * @return {SplayTree}\n */\n SplayTree.prototype.forEach = function forEach (callback) {\n var current = this._root;\n var s = [], done = false, i = 0;\n\n while (!done) {\n // Reach the left most Node of the current Node\n if (current) {\n // Place pointer to a tree node on the stack\n // before traversing the node's left subtree\n s.push(current);\n current = current.left;\n } else {\n // BackTrack from the empty subtree and visit the Node\n // at the top of the stack; however, if the stack is\n // empty you are done\n if (s.length > 0) {\n current = s.pop();\n callback(current, i++);\n\n // We have visited the node and its left\n // subtree. Now, it's right subtree's turn\n current = current.right;\n } else { done = true; }\n }\n }\n return this;\n };\n\n\n /**\n * Walk key range from `low` to `high`. Stops if `fn` returns a value.\n * @param{Key} low\n * @param{Key} high\n * @param{Function} fn\n * @param{*?} ctx\n * @return {SplayTree}\n */\n SplayTree.prototype.range = function range (low, high, fn, ctx) {\n var this$1 = this;\n\n var Q = [];\n var compare = this._compare;\n var node = this._root, cmp;\n\n while (Q.length !== 0 || node) {\n if (node) {\n Q.push(node);\n node = node.left;\n } else {\n node = Q.pop();\n cmp = compare(node.key, high);\n if (cmp > 0) {\n break;\n } else if (compare(node.key, low) >= 0) {\n if (fn.call(ctx, node)) { return this$1; } // stop if smth is returned\n }\n node = node.right;\n }\n }\n return this;\n };\n\n /**\n * Returns all keys in order\n * @return {Array}\n */\n SplayTree.prototype.keys = function keys () {\n var current = this._root;\n var s = [], r = [], done = false;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n r.push(current.key);\n current = current.right;\n } else { done = true; }\n }\n }\n return r;\n };\n\n\n /**\n * Returns `data` fields of all nodes in order.\n * @return {Array}\n */\n SplayTree.prototype.values = function values () {\n var current = this._root;\n var s = [], r = [], done = false;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n r.push(current.data);\n current = current.right;\n } else { done = true; }\n }\n }\n return r;\n };\n\n\n /**\n * Returns node at given index\n * @param{number} index\n * @return {?Node}\n */\n SplayTree.prototype.at = function at (index) {\n // removed after a consideration, more misleading than useful\n // index = index % this.size;\n // if (index < 0) index = this.size - index;\n\n var current = this._root;\n var s = [], done = false, i = 0;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n if (i === index) { return current; }\n i++;\n current = current.right;\n } else { done = true; }\n }\n }\n return null;\n };\n\n /**\n * Bulk-load items. Both array have to be same size\n * @param{Array} keys\n * @param{Array}[values]\n * @param{Boolean} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @return {AVLTree}\n */\n SplayTree.prototype.load = function load (keys, values, presort) {\n if ( keys === void 0 ) keys = [];\n if ( values === void 0 ) values = [];\n if ( presort === void 0 ) presort = false;\n\n if (this._size !== 0) { throw new Error('bulk-load: tree is not empty'); }\n var size = keys.length;\n if (presort) { sort(keys, values, 0, size - 1, this._compare); }\n this._root = loadRecursive(null, keys, values, 0, size);\n this._size = size;\n return this;\n };\n\n\n SplayTree.prototype.min = function min () {\n var node = this.minNode(this._root);\n if (node) { return node.key; }\n else { return null; }\n };\n\n\n SplayTree.prototype.max = function max () {\n var node = this.maxNode(this._root);\n if (node) { return node.key; }\n else { return null; }\n };\n\n SplayTree.prototype.isEmpty = function isEmpty () { return this._root === null; };\n prototypeAccessors.size.get = function () { return this._size; };\n\n\n /**\n * Create a tree and load it with items\n * @param{Array} keys\n * @param{Array?} [values]\n\n * @param{Function?} [comparator]\n * @param{Boolean?} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @param{Boolean?} [noDuplicates=false] Allow duplicates\n * @return {SplayTree}\n */\n SplayTree.createTree = function createTree (keys, values, comparator, presort, noDuplicates) {\n return new SplayTree(comparator, noDuplicates).load(keys, values, presort);\n };\n\n Object.defineProperties( SplayTree.prototype, prototypeAccessors );\n\n\n function loadRecursive (parent, keys, values, start, end) {\n var size = end - start;\n if (size > 0) {\n var middle = start + Math.floor(size / 2);\n var key = keys[middle];\n var data = values[middle];\n var node = { key: key, data: data, parent: parent };\n node.left = loadRecursive(node, keys, values, start, middle);\n node.right = loadRecursive(node, keys, values, middle + 1, end);\n return node;\n }\n return null;\n }\n\n\n function sort(keys, values, left, right, compare) {\n if (left >= right) { return; }\n\n var pivot = keys[(left + right) >> 1];\n var i = left - 1;\n var j = right + 1;\n\n while (true) {\n do { i++; } while (compare(keys[i], pivot) < 0);\n do { j--; } while (compare(keys[j], pivot) > 0);\n if (i >= j) { break; }\n\n var tmp = keys[i];\n keys[i] = keys[j];\n keys[j] = tmp;\n\n tmp = values[i];\n values[i] = values[j];\n values[j] = tmp;\n }\n\n sort(keys, values, left, j, compare);\n sort(keys, values, j + 1, right, compare);\n }\n\n var NORMAL = 0;\n var NON_CONTRIBUTING = 1;\n var SAME_TRANSITION = 2;\n var DIFFERENT_TRANSITION = 3;\n\n var INTERSECTION = 0;\n var UNION = 1;\n var DIFFERENCE = 2;\n var XOR = 3;\n\n /**\n * @param {SweepEvent} event\n * @param {SweepEvent} prev\n * @param {Operation} operation\n */\n function computeFields (event, prev, operation) {\n // compute inOut and otherInOut fields\n if (prev === null) {\n event.inOut = false;\n event.otherInOut = true;\n\n // previous line segment in sweepline belongs to the same polygon\n } else {\n if (event.isSubject === prev.isSubject) {\n event.inOut = !prev.inOut;\n event.otherInOut = prev.otherInOut;\n\n // previous line segment in sweepline belongs to the clipping polygon\n } else {\n event.inOut = !prev.otherInOut;\n event.otherInOut = prev.isVertical() ? !prev.inOut : prev.inOut;\n }\n\n // compute prevInResult field\n if (prev) {\n event.prevInResult = (!inResult(prev, operation) || prev.isVertical())\n ? prev.prevInResult : prev;\n }\n }\n\n // check if the line segment belongs to the Boolean operation\n event.inResult = inResult(event, operation);\n }\n\n\n /* eslint-disable indent */\n function inResult(event, operation) {\n switch (event.type) {\n case NORMAL:\n switch (operation) {\n case INTERSECTION:\n return !event.otherInOut;\n case UNION:\n return event.otherInOut;\n case DIFFERENCE:\n // return (event.isSubject && !event.otherInOut) ||\n // (!event.isSubject && event.otherInOut);\n return (event.isSubject && event.otherInOut) ||\n (!event.isSubject && !event.otherInOut);\n case XOR:\n return true;\n }\n break;\n case SAME_TRANSITION:\n return operation === INTERSECTION || operation === UNION;\n case DIFFERENT_TRANSITION:\n return operation === DIFFERENCE;\n case NON_CONTRIBUTING:\n return false;\n }\n return false;\n }\n /* eslint-enable indent */\n\n var SweepEvent = function SweepEvent (point, left, otherEvent, isSubject, edgeType) {\n\n /**\n * Is left endpoint?\n * @type {Boolean}\n */\n this.left = left;\n\n /**\n * @type {Array.}\n */\n this.point = point;\n\n /**\n * Other edge reference\n * @type {SweepEvent}\n */\n this.otherEvent = otherEvent;\n\n /**\n * Belongs to source or clipping polygon\n * @type {Boolean}\n */\n this.isSubject = isSubject;\n\n /**\n * Edge contribution type\n * @type {Number}\n */\n this.type = edgeType || NORMAL;\n\n\n /**\n * In-out transition for the sweepline crossing polygon\n * @type {Boolean}\n */\n this.inOut = false;\n\n\n /**\n * @type {Boolean}\n */\n this.otherInOut = false;\n\n /**\n * Previous event in result?\n * @type {SweepEvent}\n */\n this.prevInResult = null;\n\n /**\n * Does event belong to result?\n * @type {Boolean}\n */\n this.inResult = false;\n\n\n // connection step\n\n /**\n * @type {Boolean}\n */\n this.resultInOut = false;\n\n this.isExteriorRing = true;\n };\n\n\n /**\n * @param{Array.}p\n * @return {Boolean}\n */\n SweepEvent.prototype.isBelow = function isBelow (p) {\n var p0 = this.point, p1 = this.otherEvent.point;\n return this.left\n ? (p0[0] - p[0]) * (p1[1] - p[1]) - (p1[0] - p[0]) * (p0[1] - p[1]) > 0\n // signedArea(this.point, this.otherEvent.point, p) > 0 :\n : (p1[0] - p[0]) * (p0[1] - p[1]) - (p0[0] - p[0]) * (p1[1] - p[1]) > 0;\n //signedArea(this.otherEvent.point, this.point, p) > 0;\n };\n\n\n /**\n * @param{Array.}p\n * @return {Boolean}\n */\n SweepEvent.prototype.isAbove = function isAbove (p) {\n return !this.isBelow(p);\n };\n\n\n /**\n * @return {Boolean}\n */\n SweepEvent.prototype.isVertical = function isVertical () {\n return this.point[0] === this.otherEvent.point[0];\n };\n\n\n SweepEvent.prototype.clone = function clone () {\n var copy = new SweepEvent(\n this.point, this.left, this.otherEvent, this.isSubject, this.type);\n\n copy.inResult = this.inResult;\n copy.prevInResult = this.prevInResult;\n copy.isExteriorRing = this.isExteriorRing;\n copy.inOut = this.inOut;\n copy.otherInOut = this.otherInOut;\n\n return copy;\n };\n\n function equals(p1, p2) {\n if (p1[0] === p2[0]) {\n if (p1[1] === p2[1]) {\n return true;\n } else {\n return false;\n }\n }\n return false;\n }\n\n // const EPSILON = 1e-9;\n // const abs = Math.abs;\n // TODO https://github.com/w8r/martinez/issues/6#issuecomment-262847164\n // Precision problem.\n //\n // module.exports = function equals(p1, p2) {\n // return abs(p1[0] - p2[0]) <= EPSILON && abs(p1[1] - p2[1]) <= EPSILON;\n // };\n\n /**\n * Signed area of the triangle (p0, p1, p2)\n * @param {Array.} p0\n * @param {Array.} p1\n * @param {Array.} p2\n * @return {Number}\n */\n function signedArea(p0, p1, p2) {\n return (p0[0] - p2[0]) * (p1[1] - p2[1]) - (p1[0] - p2[0]) * (p0[1] - p2[1]);\n }\n\n /**\n * @param {SweepEvent} e1\n * @param {SweepEvent} e2\n * @return {Number}\n */\n function compareEvents(e1, e2) {\n var p1 = e1.point;\n var p2 = e2.point;\n\n // Different x-coordinate\n if (p1[0] > p2[0]) { return 1; }\n if (p1[0] < p2[0]) { return -1; }\n\n // Different points, but same x-coordinate\n // Event with lower y-coordinate is processed first\n if (p1[1] !== p2[1]) { return p1[1] > p2[1] ? 1 : -1; }\n\n return specialCases(e1, e2, p1, p2);\n }\n\n\n /* eslint-disable no-unused-vars */\n function specialCases(e1, e2, p1, p2) {\n // Same coordinates, but one is a left endpoint and the other is\n // a right endpoint. The right endpoint is processed first\n if (e1.left !== e2.left)\n { return e1.left ? 1 : -1; }\n\n // const p2 = e1.otherEvent.point, p3 = e2.otherEvent.point;\n // const sa = (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1])\n // Same coordinates, both events\n // are left endpoints or right endpoints.\n // not collinear\n if (signedArea(p1, e1.otherEvent.point, e2.otherEvent.point) !== 0) {\n // the event associate to the bottom segment is processed first\n return (!e1.isBelow(e2.otherEvent.point)) ? 1 : -1;\n }\n\n return (!e1.isSubject && e2.isSubject) ? 1 : -1;\n }\n /* eslint-enable no-unused-vars */\n\n /**\n * @param {SweepEvent} se\n * @param {Array.} p\n * @param {Queue} queue\n * @return {Queue}\n */\n function divideSegment(se, p, queue) {\n var r = new SweepEvent(p, false, se, se.isSubject);\n var l = new SweepEvent(p, true, se.otherEvent, se.isSubject);\n\n /* eslint-disable no-console */\n if (equals(se.point, se.otherEvent.point)) {\n\n console.warn('what is that, a collapsed segment?', se);\n }\n /* eslint-enable no-console */\n\n r.contourId = l.contourId = se.contourId;\n\n // avoid a rounding error. The left event would be processed after the right event\n if (compareEvents(l, se.otherEvent) > 0) {\n se.otherEvent.left = true;\n l.left = false;\n }\n\n // avoid a rounding error. The left event would be processed after the right event\n // if (compareEvents(se, r) > 0) {}\n\n se.otherEvent.otherEvent = l;\n se.otherEvent = r;\n\n queue.push(l);\n queue.push(r);\n\n return queue;\n }\n\n //const EPS = 1e-9;\n\n /**\n * Finds the magnitude of the cross product of two vectors (if we pretend\n * they're in three dimensions)\n *\n * @param {Object} a First vector\n * @param {Object} b Second vector\n * @private\n * @returns {Number} The magnitude of the cross product\n */\n function crossProduct(a, b) {\n return (a[0] * b[1]) - (a[1] * b[0]);\n }\n\n /**\n * Finds the dot product of two vectors.\n *\n * @param {Object} a First vector\n * @param {Object} b Second vector\n * @private\n * @returns {Number} The dot product\n */\n function dotProduct(a, b) {\n return (a[0] * b[0]) + (a[1] * b[1]);\n }\n\n /**\n * Finds the intersection (if any) between two line segments a and b, given the\n * line segments' end points a1, a2 and b1, b2.\n *\n * This algorithm is based on Schneider and Eberly.\n * http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf\n * Page 244.\n *\n * @param {Array.} a1 point of first line\n * @param {Array.} a2 point of first line\n * @param {Array.} b1 point of second line\n * @param {Array.} b2 point of second line\n * @param {Boolean=} noEndpointTouch whether to skip single touchpoints\n * (meaning connected segments) as\n * intersections\n * @returns {Array.>|Null} If the lines intersect, the point of\n * intersection. If they overlap, the two end points of the overlapping segment.\n * Otherwise, null.\n */\n function intersection (a1, a2, b1, b2, noEndpointTouch) {\n // The algorithm expects our lines in the form P + sd, where P is a point,\n // s is on the interval [0, 1], and d is a vector.\n // We are passed two points. P can be the first point of each pair. The\n // vector, then, could be thought of as the distance (in x and y components)\n // from the first point to the second point.\n // So first, let's make our vectors:\n var va = [a2[0] - a1[0], a2[1] - a1[1]];\n var vb = [b2[0] - b1[0], b2[1] - b1[1]];\n // We also define a function to convert back to regular point form:\n\n /* eslint-disable arrow-body-style */\n\n function toPoint(p, s, d) {\n return [\n p[0] + s * d[0],\n p[1] + s * d[1]\n ];\n }\n\n /* eslint-enable arrow-body-style */\n\n // The rest is pretty much a straight port of the algorithm.\n var e = [b1[0] - a1[0], b1[1] - a1[1]];\n var kross = crossProduct(va, vb);\n var sqrKross = kross * kross;\n var sqrLenA = dotProduct(va, va);\n //const sqrLenB = dotProduct(vb, vb);\n\n // Check for line intersection. This works because of the properties of the\n // cross product -- specifically, two vectors are parallel if and only if the\n // cross product is the 0 vector. The full calculation involves relative error\n // to account for possible very small line segments. See Schneider & Eberly\n // for details.\n if (sqrKross > 0/* EPS * sqrLenB * sqLenA */) {\n // If they're not parallel, then (because these are line segments) they\n // still might not actually intersect. This code checks that the\n // intersection point of the lines is actually on both line segments.\n var s = crossProduct(e, vb) / kross;\n if (s < 0 || s > 1) {\n // not on line segment a\n return null;\n }\n var t = crossProduct(e, va) / kross;\n if (t < 0 || t > 1) {\n // not on line segment b\n return null;\n }\n if (s === 0 || s === 1) {\n // on an endpoint of line segment a\n return noEndpointTouch ? null : [toPoint(a1, s, va)];\n }\n if (t === 0 || t === 1) {\n // on an endpoint of line segment b\n return noEndpointTouch ? null : [toPoint(b1, t, vb)];\n }\n return [toPoint(a1, s, va)];\n }\n\n // If we've reached this point, then the lines are either parallel or the\n // same, but the segments could overlap partially or fully, or not at all.\n // So we need to find the overlap, if any. To do that, we can use e, which is\n // the (vector) difference between the two initial points. If this is parallel\n // with the line itself, then the two lines are the same line, and there will\n // be overlap.\n //const sqrLenE = dotProduct(e, e);\n kross = crossProduct(e, va);\n sqrKross = kross * kross;\n\n if (sqrKross > 0 /* EPS * sqLenB * sqLenE */) {\n // Lines are just parallel, not the same. No overlap.\n return null;\n }\n\n var sa = dotProduct(va, e) / sqrLenA;\n var sb = sa + dotProduct(va, vb) / sqrLenA;\n var smin = Math.min(sa, sb);\n var smax = Math.max(sa, sb);\n\n // this is, essentially, the FindIntersection acting on floats from\n // Schneider & Eberly, just inlined into this function.\n if (smin <= 1 && smax >= 0) {\n\n // overlap on an end point\n if (smin === 1) {\n return noEndpointTouch ? null : [toPoint(a1, smin > 0 ? smin : 0, va)];\n }\n\n if (smax === 0) {\n return noEndpointTouch ? null : [toPoint(a1, smax < 1 ? smax : 1, va)];\n }\n\n if (noEndpointTouch && smin === 0 && smax === 1) { return null; }\n\n // There's overlap on a segment -- two points of intersection. Return both.\n return [\n toPoint(a1, smin > 0 ? smin : 0, va),\n toPoint(a1, smax < 1 ? smax : 1, va)\n ];\n }\n\n return null;\n }\n\n /**\n * @param {SweepEvent} se1\n * @param {SweepEvent} se2\n * @param {Queue} queue\n * @return {Number}\n */\n function possibleIntersection (se1, se2, queue) {\n // that disallows self-intersecting polygons,\n // did cost us half a day, so I'll leave it\n // out of respect\n // if (se1.isSubject === se2.isSubject) return;\n var inter = intersection(\n se1.point, se1.otherEvent.point,\n se2.point, se2.otherEvent.point\n );\n\n var nintersections = inter ? inter.length : 0;\n if (nintersections === 0) { return 0; } // no intersection\n\n // the line segments intersect at an endpoint of both line segments\n if ((nintersections === 1) &&\n (equals(se1.point, se2.point) ||\n equals(se1.otherEvent.point, se2.otherEvent.point))) {\n return 0;\n }\n\n if (nintersections === 2 && se1.isSubject === se2.isSubject) {\n // if(se1.contourId === se2.contourId){\n // console.warn('Edges of the same polygon overlap',\n // se1.point, se1.otherEvent.point, se2.point, se2.otherEvent.point);\n // }\n //throw new Error('Edges of the same polygon overlap');\n return 0;\n }\n\n // The line segments associated to se1 and se2 intersect\n if (nintersections === 1) {\n\n // if the intersection point is not an endpoint of se1\n if (!equals(se1.point, inter[0]) && !equals(se1.otherEvent.point, inter[0])) {\n divideSegment(se1, inter[0], queue);\n }\n\n // if the intersection point is not an endpoint of se2\n if (!equals(se2.point, inter[0]) && !equals(se2.otherEvent.point, inter[0])) {\n divideSegment(se2, inter[0], queue);\n }\n return 1;\n }\n\n // The line segments associated to se1 and se2 overlap\n var events = [];\n var leftCoincide = false;\n var rightCoincide = false;\n\n if (equals(se1.point, se2.point)) {\n leftCoincide = true; // linked\n } else if (compareEvents(se1, se2) === 1) {\n events.push(se2, se1);\n } else {\n events.push(se1, se2);\n }\n\n if (equals(se1.otherEvent.point, se2.otherEvent.point)) {\n rightCoincide = true;\n } else if (compareEvents(se1.otherEvent, se2.otherEvent) === 1) {\n events.push(se2.otherEvent, se1.otherEvent);\n } else {\n events.push(se1.otherEvent, se2.otherEvent);\n }\n\n if ((leftCoincide && rightCoincide) || leftCoincide) {\n // both line segments are equal or share the left endpoint\n se2.type = NON_CONTRIBUTING;\n se1.type = (se2.inOut === se1.inOut)\n ? SAME_TRANSITION : DIFFERENT_TRANSITION;\n\n if (leftCoincide && !rightCoincide) {\n // honestly no idea, but changing events selection from [2, 1]\n // to [0, 1] fixes the overlapping self-intersecting polygons issue\n divideSegment(events[1].otherEvent, events[0].point, queue);\n }\n return 2;\n }\n\n // the line segments share the right endpoint\n if (rightCoincide) {\n divideSegment(events[0], events[1].point, queue);\n return 3;\n }\n\n // no line segment includes totally the other one\n if (events[0] !== events[3].otherEvent) {\n divideSegment(events[0], events[1].point, queue);\n divideSegment(events[1], events[2].point, queue);\n return 3;\n }\n\n // one line segment includes the other one\n divideSegment(events[0], events[1].point, queue);\n divideSegment(events[3].otherEvent, events[2].point, queue);\n\n return 3;\n }\n\n /**\n * @param {SweepEvent} le1\n * @param {SweepEvent} le2\n * @return {Number}\n */\n function compareSegments(le1, le2) {\n if (le1 === le2) { return 0; }\n\n // Segments are not collinear\n if (signedArea(le1.point, le1.otherEvent.point, le2.point) !== 0 ||\n signedArea(le1.point, le1.otherEvent.point, le2.otherEvent.point) !== 0) {\n\n // If they share their left endpoint use the right endpoint to sort\n if (equals(le1.point, le2.point)) { return le1.isBelow(le2.otherEvent.point) ? -1 : 1; }\n\n // Different left endpoint: use the left endpoint to sort\n if (le1.point[0] === le2.point[0]) { return le1.point[1] < le2.point[1] ? -1 : 1; }\n\n // has the line segment associated to e1 been inserted\n // into S after the line segment associated to e2 ?\n if (compareEvents(le1, le2) === 1) { return le2.isAbove(le1.point) ? -1 : 1; }\n\n // The line segment associated to e2 has been inserted\n // into S after the line segment associated to e1\n return le1.isBelow(le2.point) ? -1 : 1;\n }\n\n if (le1.isSubject === le2.isSubject) { // same polygon\n var p1 = le1.point, p2 = le2.point;\n if (p1[0] === p2[0] && p1[1] === p2[1]/*equals(le1.point, le2.point)*/) {\n p1 = le1.otherEvent.point; p2 = le2.otherEvent.point;\n if (p1[0] === p2[0] && p1[1] === p2[1]) { return 0; }\n else { return le1.contourId > le2.contourId ? 1 : -1; }\n }\n } else { // Segments are collinear, but belong to separate polygons\n return le1.isSubject ? -1 : 1;\n }\n\n return compareEvents(le1, le2) === 1 ? 1 : -1;\n }\n\n function subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation) {\n var sweepLine = new SplayTree(compareSegments);\n var sortedEvents = [];\n\n var rightbound = Math.min(sbbox[2], cbbox[2]);\n\n var prev, next, begin;\n\n while (eventQueue.length !== 0) {\n var event = eventQueue.pop();\n sortedEvents.push(event);\n\n // optimization by bboxes for intersection and difference goes here\n if ((operation === INTERSECTION && event.point[0] > rightbound) ||\n (operation === DIFFERENCE && event.point[0] > sbbox[2])) {\n break;\n }\n\n if (event.left) {\n next = prev = sweepLine.insert(event);\n begin = sweepLine.minNode();\n\n if (prev !== begin) { prev = sweepLine.prev(prev); }\n else { prev = null; }\n\n next = sweepLine.next(next);\n\n var prevEvent = prev ? prev.key : null;\n var prevprevEvent = (void 0);\n computeFields(event, prevEvent, operation);\n if (next) {\n if (possibleIntersection(event, next.key, eventQueue) === 2) {\n computeFields(event, prevEvent, operation);\n computeFields(event, next.key, operation);\n }\n }\n\n if (prev) {\n if (possibleIntersection(prev.key, event, eventQueue) === 2) {\n var prevprev = prev;\n if (prevprev !== begin) { prevprev = sweepLine.prev(prevprev); }\n else { prevprev = null; }\n\n prevprevEvent = prevprev ? prevprev.key : null;\n computeFields(prevEvent, prevprevEvent, operation);\n computeFields(event, prevEvent, operation);\n }\n }\n } else {\n event = event.otherEvent;\n next = prev = sweepLine.find(event);\n\n if (prev && next) {\n\n if (prev !== begin) { prev = sweepLine.prev(prev); }\n else { prev = null; }\n\n next = sweepLine.next(next);\n sweepLine.remove(event);\n\n if (next && prev) {\n possibleIntersection(prev.key, next.key, eventQueue);\n }\n }\n }\n }\n return sortedEvents;\n }\n\n /**\n * @param {Array.} sortedEvents\n * @return {Array.}\n */\n function orderEvents(sortedEvents) {\n var event, i, len, tmp;\n var resultEvents = [];\n for (i = 0, len = sortedEvents.length; i < len; i++) {\n event = sortedEvents[i];\n if ((event.left && event.inResult) ||\n (!event.left && event.otherEvent.inResult)) {\n resultEvents.push(event);\n }\n }\n // Due to overlapping edges the resultEvents array can be not wholly sorted\n var sorted = false;\n while (!sorted) {\n sorted = true;\n for (i = 0, len = resultEvents.length; i < len; i++) {\n if ((i + 1) < len &&\n compareEvents(resultEvents[i], resultEvents[i + 1]) === 1) {\n tmp = resultEvents[i];\n resultEvents[i] = resultEvents[i + 1];\n resultEvents[i + 1] = tmp;\n sorted = false;\n }\n }\n }\n\n\n for (i = 0, len = resultEvents.length; i < len; i++) {\n event = resultEvents[i];\n event.pos = i;\n }\n\n // imagine, the right event is found in the beginning of the queue,\n // when his left counterpart is not marked yet\n for (i = 0, len = resultEvents.length; i < len; i++) {\n event = resultEvents[i];\n if (!event.left) {\n tmp = event.pos;\n event.pos = event.otherEvent.pos;\n event.otherEvent.pos = tmp;\n }\n }\n\n return resultEvents;\n }\n\n\n /**\n * @param {Number} pos\n * @param {Array.} resultEvents\n * @param {Object>} processed\n * @return {Number}\n */\n function nextPos(pos, resultEvents, processed, origIndex) {\n var newPos = pos + 1;\n var length = resultEvents.length;\n if (newPos > length - 1) { return pos - 1; }\n var p = resultEvents[pos].point;\n var p1 = resultEvents[newPos].point;\n\n\n // while in range and not the current one by value\n while (newPos < length && p1[0] === p[0] && p1[1] === p[1]) {\n if (!processed[newPos]) {\n return newPos;\n } else {\n newPos++;\n }\n p1 = resultEvents[newPos].point;\n }\n\n newPos = pos - 1;\n\n while (processed[newPos] && newPos >= origIndex) {\n newPos--;\n }\n return newPos;\n }\n\n\n /**\n * @param {Array.} sortedEvents\n * @return {Array.<*>} polygons\n */\n function connectEdges(sortedEvents, operation) {\n var i, len;\n var resultEvents = orderEvents(sortedEvents);\n\n // \"false\"-filled array\n var processed = {};\n var result = [];\n var event;\n\n for (i = 0, len = resultEvents.length; i < len; i++) {\n if (processed[i]) { continue; }\n var contour = [[]];\n\n if (!resultEvents[i].isExteriorRing) {\n if (operation === DIFFERENCE && !resultEvents[i].isSubject && result.length === 0) {\n result.push(contour);\n } else if (result.length === 0) {\n result.push([[contour]]);\n } else {\n result[result.length - 1].push(contour[0]);\n }\n } else if (operation === DIFFERENCE && !resultEvents[i].isSubject && result.length > 1) {\n result[result.length - 1].push(contour[0]);\n } else {\n result.push(contour);\n }\n\n var ringId = result.length - 1;\n var pos = i;\n\n var initial = resultEvents[i].point;\n contour[0].push(initial);\n\n while (pos >= i) {\n event = resultEvents[pos];\n processed[pos] = true;\n\n if (event.left) {\n event.resultInOut = false;\n event.contourId = ringId;\n } else {\n event.otherEvent.resultInOut = true;\n event.otherEvent.contourId = ringId;\n }\n\n pos = event.pos;\n processed[pos] = true;\n contour[0].push(resultEvents[pos].point);\n pos = nextPos(pos, resultEvents, processed, i);\n }\n\n pos = pos === -1 ? i : pos;\n\n event = resultEvents[pos];\n processed[pos] = processed[event.pos] = true;\n event.otherEvent.resultInOut = true;\n event.otherEvent.contourId = ringId;\n }\n\n // Handle if the result is a polygon (eg not multipoly)\n // Commented it again, let's see what do we mean by that\n // if (result.length === 1) result = result[0];\n return result;\n }\n\n var tinyqueue = TinyQueue;\n var default_1 = TinyQueue;\n\n function TinyQueue(data, compare) {\n var this$1 = this;\n\n if (!(this instanceof TinyQueue)) { return new TinyQueue(data, compare); }\n\n this.data = data || [];\n this.length = this.data.length;\n this.compare = compare || defaultCompare;\n\n if (this.length > 0) {\n for (var i = (this.length >> 1) - 1; i >= 0; i--) { this$1._down(i); }\n }\n }\n\n function defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n }\n\n TinyQueue.prototype = {\n\n push: function (item) {\n this.data.push(item);\n this.length++;\n this._up(this.length - 1);\n },\n\n pop: function () {\n if (this.length === 0) { return undefined; }\n\n var top = this.data[0];\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = this.data[this.length];\n this._down(0);\n }\n this.data.pop();\n\n return top;\n },\n\n peek: function () {\n return this.data[0];\n },\n\n _up: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var item = data[pos];\n\n while (pos > 0) {\n var parent = (pos - 1) >> 1;\n var current = data[parent];\n if (compare(item, current) >= 0) { break; }\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n },\n\n _down: function (pos) {\n var this$1 = this;\n\n var data = this.data;\n var compare = this.compare;\n var halfLength = this.length >> 1;\n var item = data[pos];\n\n while (pos < halfLength) {\n var left = (pos << 1) + 1;\n var right = left + 1;\n var best = data[left];\n\n if (right < this$1.length && compare(data[right], best) < 0) {\n left = right;\n best = data[right];\n }\n if (compare(best, item) >= 0) { break; }\n\n data[pos] = best;\n pos = left;\n }\n\n data[pos] = item;\n }\n };\n tinyqueue.default = default_1;\n\n var max = Math.max;\n var min = Math.min;\n\n var contourId = 0;\n\n\n function processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing) {\n var i, len, s1, s2, e1, e2;\n for (i = 0, len = contourOrHole.length - 1; i < len; i++) {\n s1 = contourOrHole[i];\n s2 = contourOrHole[i + 1];\n e1 = new SweepEvent(s1, false, undefined, isSubject);\n e2 = new SweepEvent(s2, false, e1, isSubject);\n e1.otherEvent = e2;\n\n if (s1[0] === s2[0] && s1[1] === s2[1]) {\n continue; // skip collapsed edges, or it breaks\n }\n\n e1.contourId = e2.contourId = depth;\n if (!isExteriorRing) {\n e1.isExteriorRing = false;\n e2.isExteriorRing = false;\n }\n if (compareEvents(e1, e2) > 0) {\n e2.left = true;\n } else {\n e1.left = true;\n }\n\n var x = s1[0], y = s1[1];\n bbox[0] = min(bbox[0], x);\n bbox[1] = min(bbox[1], y);\n bbox[2] = max(bbox[2], x);\n bbox[3] = max(bbox[3], y);\n\n // Pushing it so the queue is sorted from left to right,\n // with object on the left having the highest priority.\n Q.push(e1);\n Q.push(e2);\n }\n }\n\n\n function fillQueue(subject, clipping, sbbox, cbbox, operation) {\n var eventQueue = new tinyqueue(null, compareEvents);\n var polygonSet, isExteriorRing, i, ii, j, jj; //, k, kk;\n\n for (i = 0, ii = subject.length; i < ii; i++) {\n polygonSet = subject[i];\n for (j = 0, jj = polygonSet.length; j < jj; j++) {\n isExteriorRing = j === 0;\n if (isExteriorRing) { contourId++; }\n processPolygon(polygonSet[j], true, contourId, eventQueue, sbbox, isExteriorRing);\n }\n }\n\n for (i = 0, ii = clipping.length; i < ii; i++) {\n polygonSet = clipping[i];\n for (j = 0, jj = polygonSet.length; j < jj; j++) {\n isExteriorRing = j === 0;\n if (operation === DIFFERENCE) { isExteriorRing = false; }\n if (isExteriorRing) { contourId++; }\n processPolygon(polygonSet[j], false, contourId, eventQueue, cbbox, isExteriorRing);\n }\n }\n\n return eventQueue;\n }\n\n var EMPTY = [];\n\n\n function trivialOperation(subject, clipping, operation) {\n var result = null;\n if (subject.length * clipping.length === 0) {\n if (operation === INTERSECTION) {\n result = EMPTY;\n } else if (operation === DIFFERENCE) {\n result = subject;\n } else if (operation === UNION ||\n operation === XOR) {\n result = (subject.length === 0) ? clipping : subject;\n }\n }\n return result;\n }\n\n\n function compareBBoxes(subject, clipping, sbbox, cbbox, operation) {\n var result = null;\n if (sbbox[0] > cbbox[2] ||\n cbbox[0] > sbbox[2] ||\n sbbox[1] > cbbox[3] ||\n cbbox[1] > sbbox[3]) {\n if (operation === INTERSECTION) {\n result = EMPTY;\n } else if (operation === DIFFERENCE) {\n result = subject;\n } else if (operation === UNION ||\n operation === XOR) {\n result = subject.concat(clipping);\n }\n }\n return result;\n }\n\n\n function boolean(subject, clipping, operation) {\n if (typeof subject[0][0][0] === 'number') {\n subject = [subject];\n }\n if (typeof clipping[0][0][0] === 'number') {\n clipping = [clipping];\n }\n var trivial = trivialOperation(subject, clipping, operation);\n if (trivial) {\n return trivial === EMPTY ? null : trivial;\n }\n var sbbox = [Infinity, Infinity, -Infinity, -Infinity];\n var cbbox = [Infinity, Infinity, -Infinity, -Infinity];\n\n //console.time('fill queue');\n var eventQueue = fillQueue(subject, clipping, sbbox, cbbox, operation);\n //console.timeEnd('fill queue');\n\n trivial = compareBBoxes(subject, clipping, sbbox, cbbox, operation);\n if (trivial) {\n return trivial === EMPTY ? null : trivial;\n }\n //console.time('subdivide edges');\n var sortedEvents = subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation);\n //console.timeEnd('subdivide edges');\n\n //console.time('connect vertices');\n var result = connectEdges(sortedEvents, operation);\n //console.timeEnd('connect vertices');\n return result;\n }\n\n function union (subject, clipping) {\n return boolean(subject, clipping, UNION);\n }\n\n function diff (subject, clipping) {\n return boolean(subject, clipping, DIFFERENCE);\n }\n\n function xor (subject, clipping){\n return boolean(subject, clipping, XOR);\n }\n\n function intersection$1 (subject, clipping) {\n return boolean(subject, clipping, INTERSECTION);\n }\n\n /**\n * @enum {Number}\n */\n var operations = { UNION: UNION, DIFFERENCE: DIFFERENCE, INTERSECTION: INTERSECTION, XOR: XOR };\n\n exports.union = union;\n exports.diff = diff;\n exports.xor = xor;\n exports.intersection = intersection$1;\n exports.operations = operations;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n//# sourceMappingURL=martinez.umd.js.map\n\n\n//# sourceURL=webpack:///./node_modules/martinez-polygon-clipping/dist/martinez.umd.js?")},function(module,exports){eval('/* A few functions that may be useful in other modules. */\n\n/**\r\n * Given a geoJSON geometry object\'s coordinates, return the object, but with\r\n * all the coordinates reversed.
\r\n * \r\n * Why? GeoJSON coordinates are in lngLat format by default, while Leaflet uses latLng.\r\n * L.geoJSON will auto-reverse the order of a GeoJSON object\'s coordinates, as it\r\n * expects geoJSON coordinates to be lngLat. However, normal, non-GeoJSON-specific Leaflet\r\n * methods expect Leaflet\'s latLng pairs and won\'t auto-reverse, so we have to do that\r\n * manually if we\'re preprocessing the GeoJSON data before passing it to L.geoJSON.\r\n * \r\n * @param {Array>>} coordinates - GeoJSON coordinates for a point, (multi-)line, or (multi-)polygon.\r\n * @returns {Array>>} - Reversed geoJSON coordinates for a point, (multi-)line, or (multi-)polygon.\r\n */\nfunction reversedCoordinates(coordinates) {\n var reversed = coordinates.slice();\n\n if (typeof coordinates[0] != "number") {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = coordinates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var inner_coordinates = _step.value;\n reversed.splice(reversed.indexOf(inner_coordinates), 1, reversedCoordinates(inner_coordinates));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n } else {\n reversed = [coordinates[1], coordinates[0]];\n }\n\n return reversed;\n}\n/**\r\n * Given an array, check whether it can represent the coordinates of a point.\r\n *\r\n * @param {Array} array - Array to check.\r\n * @returns {boolean} - Whether the array can be the coordinates of a point.\r\n */\n\n\nfunction isPointCoordinates(array) {\n if (array.length !== 2 || typeof array[0] !== "number" || typeof array[1] !== "number") {\n return false;\n }\n\n return true;\n}\n/**\r\n * Given either a GeoJSON feature, L.latLng, or coordinate array containing the coordinates of a point,\r\n * return an array of the coordinates.\r\n *\r\n * @param {Point|Array|LatLng} point - The data containing the point\'s coordinates (latitude & longitude).\r\n * @returns {Array} - Array of the point\'s coordinates. I.e.: [lng, lat].\r\n */\n\n\nfunction pointToCoordinateArray(point) {\n var coordinate_array;\n\n if (typeof point.lat === "number" && typeof point.lng === "number") {\n coordinate_array = [point.lng, point.lat];\n } else if (point.geometry && point.geometry.coordinates && isPointCoordinates(point.geometry.coordinates)) {\n coordinate_array = point.geometry.coordinates;\n } else if (isPointCoordinates(point)) {\n coordinate_array = point;\n } else {\n throw new Error("Invalid point: point must either be array of 2 coordinates, or an L.latLng.");\n }\n\n return coordinate_array;\n}\n/**\r\n * Given two coordinate arrays, get their intersections.\r\n * \r\n * @param {array>} arr_a - Array of coordinate pairs.\r\n * @param {array>} arr_b - Array of coordinate pairs.\r\n * @param {array} ids - 2-element array whose elements are IDs for arr_a and arr_b respectively.\r\n *\r\n * @returns {Array>>} - Array whose elements are the intersections\' cooridinate-pairs if\r\n * ids is empty, or otherwise whose elements are arrays each of whose first element is an\r\n * intersection\'s coordinate-pair and whose second element is an object mapping each array\'s ID (supplied by ids) \r\n * to the index of the intersection\'s coordinate-pair in that array.\r\n */\n\n\nfunction getIntersections(arr_a, arr_b) {\n var ids = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n var intersections = [];\n\n for (var i = 0; i < arr_a.length; i++) {\n var el_a = arr_a[i];\n\n for (var j = 0; j < arr_b.length; j++) {\n var el_b = arr_b[j];\n\n if (isPointCoordinates(el_a) && isPointCoordinates(el_b)) {\n if (el_a[0] === el_b[0] && el_a[1] === el_b[1]) {\n var new_intersection = void 0;\n\n if (ids.length === 2) {\n var identified_intersections = {};\n identified_intersections[ids[0]] = i, identified_intersections[ids[1]] = j, new_intersection = [el_a, identified_intersections];\n } else {\n new_intersection = el_a;\n }\n\n intersections.push(new_intersection);\n }\n } else {\n throw new Error("Every element of each array must be a coordinate pair array.");\n }\n }\n }\n\n return intersections;\n}\n\nexports.getIntersections = getIntersections;\nexports.reversedCoordinates = reversedCoordinates;\nexports.isPointCoordinates = isPointCoordinates;\nexports.pointToCoordinateArray = pointToCoordinateArray;\n\n//# sourceURL=webpack:///./src/utils.js?')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n\n// EXTERNAL MODULE: ./node_modules/@turf/bbox/main.es.js\nvar main_es = __webpack_require__(3);\n\n// CONCATENATED MODULE: ./node_modules/@turf/center/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar factors = {\n meters: earthRadius,\n metres: earthRadius,\n millimeters: earthRadius * 1000,\n millimetres: earthRadius * 1000,\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n kilometers: earthRadius / 1000,\n kilometres: earthRadius / 1000,\n miles: earthRadius / 1609.344,\n nauticalmiles: earthRadius / 1852,\n inches: earthRadius * 39.370,\n yards: earthRadius / 1.0936,\n feet: earthRadius * 3.28084,\n radians: 1,\n degrees: earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = main_es_point(coordinates).geometry; break;\n case 'LineString': geom = lineString(coordinates).geometry; break;\n case 'Polygon': geom = main_es_polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction main_es_point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction main_es_points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return main_es_point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction main_es_polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return main_es_polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/center/main.es.js\n\n\n\n/**\n * Takes a {@link Feature} or {@link FeatureCollection} and returns the absolute center point of all features.\n *\n * @name center\n * @param {GeoJSON} geojson GeoJSON to be centered\n * @param {Object} [options={}] Optional parameters\n * @param {Object} [options.properties={}] an Object that is used as the {@link Feature}'s properties\n * @returns {Feature} a Point feature at the absolute center point of all input features\n * @example\n * var features = turf.featureCollection([\n * turf.point( [-97.522259, 35.4691]),\n * turf.point( [-97.502754, 35.463455]),\n * turf.point( [-97.508269, 35.463245])\n * ]);\n *\n * var center = turf.center(features);\n *\n * //addToMap\n * var addToMap = [features, center]\n * center.properties['marker-size'] = 'large';\n * center.properties['marker-color'] = '#000';\n */\nfunction main_es_center(geojson, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var properties = options.properties;\n\n // Input validation\n if (!geojson) throw new Error('geojson is required');\n\n var ext = Object(main_es[\"default\"])(geojson);\n var x = (ext[0] + ext[2]) / 2;\n var y = (ext[1] + ext[3]) / 2;\n return main_es_point([x, y], properties);\n}\n\n/* harmony default export */ var center_main_es = (main_es_center);\n\n// EXTERNAL MODULE: ./node_modules/turf-jsts/jsts.min.js\nvar jsts_min = __webpack_require__(7);\n\n// EXTERNAL MODULE: ./node_modules/@turf/meta/main.es.js + 1 modules\nvar meta_main_es = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./node_modules/@turf/projection/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar main_es_earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar main_es_factors = {\n meters: main_es_earthRadius,\n metres: main_es_earthRadius,\n millimeters: main_es_earthRadius * 1000,\n millimetres: main_es_earthRadius * 1000,\n centimeters: main_es_earthRadius * 100,\n centimetres: main_es_earthRadius * 100,\n kilometers: main_es_earthRadius / 1000,\n kilometres: main_es_earthRadius / 1000,\n miles: main_es_earthRadius / 1609.344,\n nauticalmiles: main_es_earthRadius / 1852,\n inches: main_es_earthRadius * 39.370,\n yards: main_es_earthRadius / 1.0936,\n feet: main_es_earthRadius * 3.28084,\n radians: 1,\n degrees: main_es_earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar main_es_unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / main_es_earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar main_es_areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction helpers_main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) main_es_validateBBox(bbox);\n if (id) main_es_validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction helpers_main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) main_es_validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = helpers_main_es_point(coordinates).geometry; break;\n case 'LineString': geom = main_es_lineString(coordinates).geometry; break;\n case 'Polygon': geom = helpers_main_es_polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = main_es_multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = main_es_multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = main_es_multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction helpers_main_es_point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!main_es_isNumber(coordinates[0]) || !main_es_isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return helpers_main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction helpers_main_es_points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return main_es_featureCollection(coordinates.map(function (coords) {\n return helpers_main_es_point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction helpers_main_es_polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !main_es_isNumber(ring[0][0]) || !main_es_isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return helpers_main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction main_es_polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return main_es_featureCollection(coordinates.map(function (coords) {\n return helpers_main_es_polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction main_es_lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!main_es_isNumber(coordinates[0][1]) || !main_es_isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return helpers_main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction main_es_lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return main_es_featureCollection(coordinates.map(function (coords) {\n return main_es_lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction main_es_featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) main_es_validateBBox(bbox);\n if (id) main_es_validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction main_es_multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return helpers_main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction main_es_multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return helpers_main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction main_es_multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return helpers_main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction main_es_geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return helpers_main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction main_es_round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction main_es_radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction main_es_lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction main_es_lengthToDegrees(distance, units) {\n return main_es_radiansToDegrees(main_es_lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction main_es_bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction main_es_radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction main_es_degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction main_es_convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return main_es_radiansToLength(main_es_lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction main_es_convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = main_es_areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = main_es_areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction main_es_isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction main_es_isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction main_es_validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!main_es_isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction main_es_validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction main_es_radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction main_es_degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction main_es_distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction main_es_distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction main_es_radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction main_es_bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction main_es_convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/clone/main.es.js\n/**\n * Returns a cloned copy of the passed GeoJSON Object, including possible 'Foreign Members'.\n * ~3-5x faster than the common JSON.parse + JSON.stringify combo method.\n *\n * @name clone\n * @param {GeoJSON} geojson GeoJSON Object\n * @returns {GeoJSON} cloned GeoJSON Object\n * @example\n * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]], {color: 'red'});\n *\n * var lineCloned = turf.clone(line);\n */\nfunction clone(geojson) {\n if (!geojson) throw new Error('geojson is required');\n\n switch (geojson.type) {\n case 'Feature':\n return cloneFeature(geojson);\n case 'FeatureCollection':\n return cloneFeatureCollection(geojson);\n case 'Point':\n case 'LineString':\n case 'Polygon':\n case 'MultiPoint':\n case 'MultiLineString':\n case 'MultiPolygon':\n case 'GeometryCollection':\n return cloneGeometry(geojson);\n default:\n throw new Error('unknown GeoJSON type');\n }\n}\n\n/**\n * Clone Feature\n *\n * @private\n * @param {Feature} geojson GeoJSON Feature\n * @returns {Feature} cloned Feature\n */\nfunction cloneFeature(geojson) {\n var cloned = {type: 'Feature'};\n // Preserve Foreign Members\n Object.keys(geojson).forEach(function (key) {\n switch (key) {\n case 'type':\n case 'properties':\n case 'geometry':\n return;\n default:\n cloned[key] = geojson[key];\n }\n });\n // Add properties & geometry last\n cloned.properties = cloneProperties(geojson.properties);\n cloned.geometry = cloneGeometry(geojson.geometry);\n return cloned;\n}\n\n/**\n * Clone Properties\n *\n * @private\n * @param {Object} properties GeoJSON Properties\n * @returns {Object} cloned Properties\n */\nfunction cloneProperties(properties) {\n var cloned = {};\n if (!properties) return cloned;\n Object.keys(properties).forEach(function (key) {\n var value = properties[key];\n if (typeof value === 'object') {\n if (value === null) {\n // handle null\n cloned[key] = null;\n } else if (value.length) {\n // handle Array\n cloned[key] = value.map(function (item) {\n return item;\n });\n } else {\n // handle generic Object\n cloned[key] = cloneProperties(value);\n }\n } else cloned[key] = value;\n });\n return cloned;\n}\n\n/**\n * Clone Feature Collection\n *\n * @private\n * @param {FeatureCollection} geojson GeoJSON Feature Collection\n * @returns {FeatureCollection} cloned Feature Collection\n */\nfunction cloneFeatureCollection(geojson) {\n var cloned = {type: 'FeatureCollection'};\n\n // Preserve Foreign Members\n Object.keys(geojson).forEach(function (key) {\n switch (key) {\n case 'type':\n case 'features':\n return;\n default:\n cloned[key] = geojson[key];\n }\n });\n // Add features\n cloned.features = geojson.features.map(function (feature) {\n return cloneFeature(feature);\n });\n return cloned;\n}\n\n/**\n * Clone Geometry\n *\n * @private\n * @param {Geometry} geometry GeoJSON Geometry\n * @returns {Geometry} cloned Geometry\n */\nfunction cloneGeometry(geometry) {\n var geom = {type: geometry.type};\n if (geometry.bbox) geom.bbox = geometry.bbox;\n\n if (geometry.type === 'GeometryCollection') {\n geom.geometries = geometry.geometries.map(function (geom) {\n return cloneGeometry(geom);\n });\n return geom;\n }\n geom.coordinates = deepSlice(geometry.coordinates);\n return geom;\n}\n\n/**\n * Deep Slice coordinates\n *\n * @private\n * @param {Coordinates} coords Coordinates\n * @returns {Coordinates} all coordinates sliced\n */\nfunction deepSlice(coords) {\n if (typeof coords[0] !== 'object') { return coords.slice(); }\n return coords.map(function (coord) {\n return deepSlice(coord);\n });\n}\n\n/* harmony default export */ var clone_main_es = (clone);\n\n// CONCATENATED MODULE: ./node_modules/@turf/projection/main.es.js\n\n\n\n\n/**\n * Converts a WGS84 GeoJSON object into Mercator (EPSG:900913) projection\n *\n * @name toMercator\n * @param {GeoJSON|Position} geojson WGS84 GeoJSON object\n * @param {Object} [options] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)\n * @returns {GeoJSON} true/false\n * @example\n * var pt = turf.point([-71,41]);\n * var converted = turf.toMercator(pt);\n *\n * //addToMap\n * var addToMap = [pt, converted];\n */\nfunction toMercator(geojson, options) {\n return convert(geojson, 'mercator', options);\n}\n\n/**\n * Converts a Mercator (EPSG:900913) GeoJSON object into WGS84 projection\n *\n * @name toWgs84\n * @param {GeoJSON|Position} geojson Mercator GeoJSON object\n * @param {Object} [options] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)\n * @returns {GeoJSON} true/false\n * @example\n * var pt = turf.point([-7903683.846322424, 5012341.663847514]);\n * var converted = turf.toWgs84(pt);\n *\n * //addToMap\n * var addToMap = [pt, converted];\n */\nfunction toWgs84(geojson, options) {\n return convert(geojson, 'wgs84', options);\n}\n\n\n/**\n * Converts a GeoJSON coordinates to the defined `projection`\n *\n * @private\n * @param {GeoJSON} geojson GeoJSON Feature or Geometry\n * @param {string} projection defines the projection system to convert the coordinates to\n * @param {Object} [options] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)\n * @returns {GeoJSON} true/false\n */\nfunction convert(geojson, projection, options) {\n // Optional parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var mutate = options.mutate;\n\n // Validation\n if (!geojson) throw new Error('geojson is required');\n\n // Handle Position\n if (Array.isArray(geojson) && main_es_isNumber(geojson[0])) geojson = (projection === 'mercator') ? convertToMercator(geojson) : convertToWgs84(geojson);\n\n // Handle GeoJSON\n else {\n // Handle possible data mutation\n if (mutate !== true) geojson = clone_main_es(geojson);\n\n Object(meta_main_es[\"a\" /* coordEach */])(geojson, function (coord) {\n var newCoord = (projection === 'mercator') ? convertToMercator(coord) : convertToWgs84(coord);\n coord[0] = newCoord[0];\n coord[1] = newCoord[1];\n });\n }\n return geojson;\n}\n\n/**\n * Convert lon/lat values to 900913 x/y.\n * (from https://github.com/mapbox/sphericalmercator)\n *\n * @private\n * @param {Array} lonLat WGS84 point\n * @returns {Array} Mercator [x, y] point\n */\nfunction convertToMercator(lonLat) {\n var D2R = Math.PI / 180,\n // 900913 properties\n A = 6378137.0,\n MAXEXTENT = 20037508.342789244;\n\n // compensate longitudes passing the 180th meridian\n // from https://github.com/proj4js/proj4js/blob/master/lib/common/adjust_lon.js\n var adjusted = (Math.abs(lonLat[0]) <= 180) ? lonLat[0] : (lonLat[0] - (main_es_sign(lonLat[0]) * 360));\n var xy = [\n A * adjusted * D2R,\n A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lonLat[1] * D2R)))\n ];\n\n // if xy value is beyond maxextent (e.g. poles), return maxextent\n if (xy[0] > MAXEXTENT) xy[0] = MAXEXTENT;\n if (xy[0] < -MAXEXTENT) xy[0] = -MAXEXTENT;\n if (xy[1] > MAXEXTENT) xy[1] = MAXEXTENT;\n if (xy[1] < -MAXEXTENT) xy[1] = -MAXEXTENT;\n\n return xy;\n}\n\n/**\n * Convert 900913 x/y values to lon/lat.\n * (from https://github.com/mapbox/sphericalmercator)\n *\n * @private\n * @param {Array} xy Mercator [x, y] point\n * @returns {Array} WGS84 [lon, lat] point\n */\nfunction convertToWgs84(xy) {\n // 900913 properties.\n var R2D = 180 / Math.PI;\n var A = 6378137.0;\n\n return [\n (xy[0] * R2D / A),\n ((Math.PI * 0.5) - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D\n ];\n}\n\n/**\n * Returns the sign of the input, or zero\n *\n * @private\n * @param {number} x input\n * @returns {number} -1|0|1 output\n */\nfunction main_es_sign(x) {\n return (x < 0) ? -1 : (x > 0) ? 1 : 0;\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/adder.js\n// Adds floating point numbers with twice the normal precision.\n// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and\n// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)\n// 305–363 (1997).\n// Code adapted from GeographicLib by Charles F. F. Karney,\n// http://geographiclib.sourceforge.net/\n\n/* harmony default export */ var adder = (function() {\n return new Adder;\n});\n\nfunction Adder() {\n this.reset();\n}\n\nAdder.prototype = {\n constructor: Adder,\n reset: function() {\n this.s = // rounded value\n this.t = 0; // exact error\n },\n add: function(y) {\n add(temp, y, this.t);\n add(this, temp.s, this.s);\n if (this.s) this.t += temp.t;\n else this.s = temp.t;\n },\n valueOf: function() {\n return this.s;\n }\n};\n\nvar temp = new Adder;\n\nfunction add(adder, a, b) {\n var x = adder.s = a + b,\n bv = x - a,\n av = x - bv;\n adder.t = (a - av) + (b - bv);\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/math.js\nvar epsilon = 1e-6;\nvar epsilon2 = 1e-12;\nvar pi = Math.PI;\nvar halfPi = pi / 2;\nvar quarterPi = pi / 4;\nvar tau = pi * 2;\n\nvar degrees = 180 / pi;\nvar radians = pi / 180;\n\nvar abs = Math.abs;\nvar atan = Math.atan;\nvar atan2 = Math.atan2;\nvar cos = Math.cos;\nvar ceil = Math.ceil;\nvar exp = Math.exp;\nvar floor = Math.floor;\nvar log = Math.log;\nvar pow = Math.pow;\nvar sin = Math.sin;\nvar math_sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };\nvar sqrt = Math.sqrt;\nvar tan = Math.tan;\n\nfunction acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nfunction asin(x) {\n return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);\n}\n\nfunction haversin(x) {\n return (x = sin(x / 2)) * x;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/noop.js\nfunction noop() {}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/stream.js\nfunction streamGeometry(geometry, stream) {\n if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {\n streamGeometryType[geometry.type](geometry, stream);\n }\n}\n\nvar streamObjectType = {\n Feature: function(object, stream) {\n streamGeometry(object.geometry, stream);\n },\n FeatureCollection: function(object, stream) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) streamGeometry(features[i].geometry, stream);\n }\n};\n\nvar streamGeometryType = {\n Sphere: function(object, stream) {\n stream.sphere();\n },\n Point: function(object, stream) {\n object = object.coordinates;\n stream.point(object[0], object[1], object[2]);\n },\n MultiPoint: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);\n },\n LineString: function(object, stream) {\n streamLine(object.coordinates, stream, 0);\n },\n MultiLineString: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamLine(coordinates[i], stream, 0);\n },\n Polygon: function(object, stream) {\n streamPolygon(object.coordinates, stream);\n },\n MultiPolygon: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamPolygon(coordinates[i], stream);\n },\n GeometryCollection: function(object, stream) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) streamGeometry(geometries[i], stream);\n }\n};\n\nfunction streamLine(coordinates, stream, closed) {\n var i = -1, n = coordinates.length - closed, coordinate;\n stream.lineStart();\n while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);\n stream.lineEnd();\n}\n\nfunction streamPolygon(coordinates, stream) {\n var i = -1, n = coordinates.length;\n stream.polygonStart();\n while (++i < n) streamLine(coordinates[i], stream, 1);\n stream.polygonEnd();\n}\n\n/* harmony default export */ var src_stream = (function(object, stream) {\n if (object && streamObjectType.hasOwnProperty(object.type)) {\n streamObjectType[object.type](object, stream);\n } else {\n streamGeometry(object, stream);\n }\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/area.js\n\n\n\n\n\nvar areaRingSum = adder();\n\nvar areaSum = adder(),\n area_lambda00,\n phi00,\n area_lambda0,\n area_cosPhi0,\n area_sinPhi0;\n\nvar areaStream = {\n point: noop,\n lineStart: noop,\n lineEnd: noop,\n polygonStart: function() {\n areaRingSum.reset();\n areaStream.lineStart = areaRingStart;\n areaStream.lineEnd = areaRingEnd;\n },\n polygonEnd: function() {\n var areaRing = +areaRingSum;\n areaSum.add(areaRing < 0 ? tau + areaRing : areaRing);\n this.lineStart = this.lineEnd = this.point = noop;\n },\n sphere: function() {\n areaSum.add(tau);\n }\n};\n\nfunction areaRingStart() {\n areaStream.point = areaPointFirst;\n}\n\nfunction areaRingEnd() {\n areaPoint(area_lambda00, phi00);\n}\n\nfunction areaPointFirst(lambda, phi) {\n areaStream.point = areaPoint;\n area_lambda00 = lambda, phi00 = phi;\n lambda *= radians, phi *= radians;\n area_lambda0 = lambda, area_cosPhi0 = cos(phi = phi / 2 + quarterPi), area_sinPhi0 = sin(phi);\n}\n\nfunction areaPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n phi = phi / 2 + quarterPi; // half the angular distance from south pole\n\n // Spherical excess E for a spherical triangle with vertices: south pole,\n // previous point, current point. Uses a formula derived from Cagnoli’s\n // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).\n var dLambda = lambda - area_lambda0,\n sdLambda = dLambda >= 0 ? 1 : -1,\n adLambda = sdLambda * dLambda,\n cosPhi = cos(phi),\n sinPhi = sin(phi),\n k = area_sinPhi0 * sinPhi,\n u = area_cosPhi0 * cosPhi + k * cos(adLambda),\n v = k * sdLambda * sin(adLambda);\n areaRingSum.add(atan2(v, u));\n\n // Advance the previous points.\n area_lambda0 = lambda, area_cosPhi0 = cosPhi, area_sinPhi0 = sinPhi;\n}\n\n/* harmony default export */ var src_area = (function(object) {\n areaSum.reset();\n src_stream(object, areaStream);\n return areaSum * 2;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/cartesian.js\n\n\nfunction cartesian_spherical(cartesian) {\n return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];\n}\n\nfunction cartesian_cartesian(spherical) {\n var lambda = spherical[0], phi = spherical[1], cosPhi = cos(phi);\n return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)];\n}\n\nfunction cartesianDot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\nfunction cartesianCross(a, b) {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n}\n\n// TODO return a\nfunction cartesianAddInPlace(a, b) {\n a[0] += b[0], a[1] += b[1], a[2] += b[2];\n}\n\nfunction cartesianScale(vector, k) {\n return [vector[0] * k, vector[1] * k, vector[2] * k];\n}\n\n// TODO return d\nfunction cartesianNormalizeInPlace(d) {\n var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);\n d[0] /= l, d[1] /= l, d[2] /= l;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/bounds.js\n\n\n\n\n\n\nvar bounds_lambda0, bounds_phi0, bounds_lambda1, bounds_phi1, // bounds\n bounds_lambda2, // previous lambda-coordinate\n bounds_lambda00, bounds_phi00, // first point\n bounds_p0, // previous 3D point\n deltaSum = adder(),\n ranges,\n range;\n\nvar boundsStream = {\n point: boundsPoint,\n lineStart: boundsLineStart,\n lineEnd: boundsLineEnd,\n polygonStart: function() {\n boundsStream.point = boundsRingPoint;\n boundsStream.lineStart = boundsRingStart;\n boundsStream.lineEnd = boundsRingEnd;\n deltaSum.reset();\n areaStream.polygonStart();\n },\n polygonEnd: function() {\n areaStream.polygonEnd();\n boundsStream.point = boundsPoint;\n boundsStream.lineStart = boundsLineStart;\n boundsStream.lineEnd = boundsLineEnd;\n if (areaRingSum < 0) bounds_lambda0 = -(bounds_lambda1 = 180), bounds_phi0 = -(bounds_phi1 = 90);\n else if (deltaSum > epsilon) bounds_phi1 = 90;\n else if (deltaSum < -epsilon) bounds_phi0 = -90;\n range[0] = bounds_lambda0, range[1] = bounds_lambda1;\n }\n};\n\nfunction boundsPoint(lambda, phi) {\n ranges.push(range = [bounds_lambda0 = lambda, bounds_lambda1 = lambda]);\n if (phi < bounds_phi0) bounds_phi0 = phi;\n if (phi > bounds_phi1) bounds_phi1 = phi;\n}\n\nfunction bounds_linePoint(lambda, phi) {\n var p = cartesian_cartesian([lambda * radians, phi * radians]);\n if (bounds_p0) {\n var normal = cartesianCross(bounds_p0, p),\n equatorial = [normal[1], -normal[0], 0],\n inflection = cartesianCross(equatorial, normal);\n cartesianNormalizeInPlace(inflection);\n inflection = cartesian_spherical(inflection);\n var delta = lambda - bounds_lambda2,\n sign = delta > 0 ? 1 : -1,\n lambdai = inflection[0] * degrees * sign,\n phii,\n antimeridian = abs(delta) > 180;\n if (antimeridian ^ (sign * bounds_lambda2 < lambdai && lambdai < sign * lambda)) {\n phii = inflection[1] * degrees;\n if (phii > bounds_phi1) bounds_phi1 = phii;\n } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * bounds_lambda2 < lambdai && lambdai < sign * lambda)) {\n phii = -inflection[1] * degrees;\n if (phii < bounds_phi0) bounds_phi0 = phii;\n } else {\n if (phi < bounds_phi0) bounds_phi0 = phi;\n if (phi > bounds_phi1) bounds_phi1 = phi;\n }\n if (antimeridian) {\n if (lambda < bounds_lambda2) {\n if (bounds_angle(bounds_lambda0, lambda) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda1 = lambda;\n } else {\n if (bounds_angle(lambda, bounds_lambda1) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda0 = lambda;\n }\n } else {\n if (bounds_lambda1 >= bounds_lambda0) {\n if (lambda < bounds_lambda0) bounds_lambda0 = lambda;\n if (lambda > bounds_lambda1) bounds_lambda1 = lambda;\n } else {\n if (lambda > bounds_lambda2) {\n if (bounds_angle(bounds_lambda0, lambda) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda1 = lambda;\n } else {\n if (bounds_angle(lambda, bounds_lambda1) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda0 = lambda;\n }\n }\n }\n } else {\n ranges.push(range = [bounds_lambda0 = lambda, bounds_lambda1 = lambda]);\n }\n if (phi < bounds_phi0) bounds_phi0 = phi;\n if (phi > bounds_phi1) bounds_phi1 = phi;\n bounds_p0 = p, bounds_lambda2 = lambda;\n}\n\nfunction boundsLineStart() {\n boundsStream.point = bounds_linePoint;\n}\n\nfunction boundsLineEnd() {\n range[0] = bounds_lambda0, range[1] = bounds_lambda1;\n boundsStream.point = boundsPoint;\n bounds_p0 = null;\n}\n\nfunction boundsRingPoint(lambda, phi) {\n if (bounds_p0) {\n var delta = lambda - bounds_lambda2;\n deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);\n } else {\n bounds_lambda00 = lambda, bounds_phi00 = phi;\n }\n areaStream.point(lambda, phi);\n bounds_linePoint(lambda, phi);\n}\n\nfunction boundsRingStart() {\n areaStream.lineStart();\n}\n\nfunction boundsRingEnd() {\n boundsRingPoint(bounds_lambda00, bounds_phi00);\n areaStream.lineEnd();\n if (abs(deltaSum) > epsilon) bounds_lambda0 = -(bounds_lambda1 = 180);\n range[0] = bounds_lambda0, range[1] = bounds_lambda1;\n bounds_p0 = null;\n}\n\n// Finds the left-right distance between two longitudes.\n// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want\n// the distance between ±180° to be 360°.\nfunction bounds_angle(lambda0, lambda1) {\n return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;\n}\n\nfunction rangeCompare(a, b) {\n return a[0] - b[0];\n}\n\nfunction rangeContains(range, x) {\n return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;\n}\n\n/* harmony default export */ var bounds = (function(feature) {\n var i, n, a, b, merged, deltaMax, delta;\n\n bounds_phi1 = bounds_lambda1 = -(bounds_lambda0 = bounds_phi0 = Infinity);\n ranges = [];\n src_stream(feature, boundsStream);\n\n // First, sort ranges by their minimum longitudes.\n if (n = ranges.length) {\n ranges.sort(rangeCompare);\n\n // Then, merge any ranges that overlap.\n for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {\n b = ranges[i];\n if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {\n if (bounds_angle(a[0], b[1]) > bounds_angle(a[0], a[1])) a[1] = b[1];\n if (bounds_angle(b[0], a[1]) > bounds_angle(a[0], a[1])) a[0] = b[0];\n } else {\n merged.push(a = b);\n }\n }\n\n // Finally, find the largest gap between the merged ranges.\n // The final bounding box will be the inverse of this gap.\n for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {\n b = merged[i];\n if ((delta = bounds_angle(a[1], b[0])) > deltaMax) deltaMax = delta, bounds_lambda0 = b[0], bounds_lambda1 = a[1];\n }\n }\n\n ranges = range = null;\n\n return bounds_lambda0 === Infinity || bounds_phi0 === Infinity\n ? [[NaN, NaN], [NaN, NaN]]\n : [[bounds_lambda0, bounds_phi0], [bounds_lambda1, bounds_phi1]];\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/centroid.js\n\n\n\n\nvar W0, W1,\n centroid_X0, centroid_Y0, Z0,\n centroid_X1, centroid_Y1, Z1,\n X2, Y2, Z2,\n centroid_lambda00, centroid_phi00, // first point\n centroid_x0, centroid_y0, z0; // previous point\n\nvar centroidStream = {\n sphere: noop,\n point: centroidPoint,\n lineStart: centroidLineStart,\n lineEnd: centroidLineEnd,\n polygonStart: function() {\n centroidStream.lineStart = centroidRingStart;\n centroidStream.lineEnd = centroidRingEnd;\n },\n polygonEnd: function() {\n centroidStream.lineStart = centroidLineStart;\n centroidStream.lineEnd = centroidLineEnd;\n }\n};\n\n// Arithmetic mean of Cartesian vectors.\nfunction centroidPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi);\n centroidPointCartesian(cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi));\n}\n\nfunction centroidPointCartesian(x, y, z) {\n ++W0;\n centroid_X0 += (x - centroid_X0) / W0;\n centroid_Y0 += (y - centroid_Y0) / W0;\n Z0 += (z - Z0) / W0;\n}\n\nfunction centroidLineStart() {\n centroidStream.point = centroidLinePointFirst;\n}\n\nfunction centroidLinePointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi);\n centroid_x0 = cosPhi * cos(lambda);\n centroid_y0 = cosPhi * sin(lambda);\n z0 = sin(phi);\n centroidStream.point = centroidLinePoint;\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\nfunction centroidLinePoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi),\n x = cosPhi * cos(lambda),\n y = cosPhi * sin(lambda),\n z = sin(phi),\n w = atan2(sqrt((w = centroid_y0 * z - z0 * y) * w + (w = z0 * x - centroid_x0 * z) * w + (w = centroid_x0 * y - centroid_y0 * x) * w), centroid_x0 * x + centroid_y0 * y + z0 * z);\n W1 += w;\n centroid_X1 += w * (centroid_x0 + (centroid_x0 = x));\n centroid_Y1 += w * (centroid_y0 + (centroid_y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\nfunction centroidLineEnd() {\n centroidStream.point = centroidPoint;\n}\n\n// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,\n// J. Applied Mechanics 42, 239 (1975).\nfunction centroidRingStart() {\n centroidStream.point = centroidRingPointFirst;\n}\n\nfunction centroidRingEnd() {\n centroidRingPoint(centroid_lambda00, centroid_phi00);\n centroidStream.point = centroidPoint;\n}\n\nfunction centroidRingPointFirst(lambda, phi) {\n centroid_lambda00 = lambda, centroid_phi00 = phi;\n lambda *= radians, phi *= radians;\n centroidStream.point = centroidRingPoint;\n var cosPhi = cos(phi);\n centroid_x0 = cosPhi * cos(lambda);\n centroid_y0 = cosPhi * sin(lambda);\n z0 = sin(phi);\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\nfunction centroidRingPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi),\n x = cosPhi * cos(lambda),\n y = cosPhi * sin(lambda),\n z = sin(phi),\n cx = centroid_y0 * z - z0 * y,\n cy = z0 * x - centroid_x0 * z,\n cz = centroid_x0 * y - centroid_y0 * x,\n m = sqrt(cx * cx + cy * cy + cz * cz),\n w = asin(m), // line weight = angle\n v = m && -w / m; // area weight multiplier\n X2 += v * cx;\n Y2 += v * cy;\n Z2 += v * cz;\n W1 += w;\n centroid_X1 += w * (centroid_x0 + (centroid_x0 = x));\n centroid_Y1 += w * (centroid_y0 + (centroid_y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\n/* harmony default export */ var centroid = (function(object) {\n W0 = W1 =\n centroid_X0 = centroid_Y0 = Z0 =\n centroid_X1 = centroid_Y1 = Z1 =\n X2 = Y2 = Z2 = 0;\n src_stream(object, centroidStream);\n\n var x = X2,\n y = Y2,\n z = Z2,\n m = x * x + y * y + z * z;\n\n // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.\n if (m < epsilon2) {\n x = centroid_X1, y = centroid_Y1, z = Z1;\n // If the feature has zero length, fall back to arithmetic mean of point vectors.\n if (W1 < epsilon) x = centroid_X0, y = centroid_Y0, z = Z0;\n m = x * x + y * y + z * z;\n // If the feature still has an undefined ccentroid, then return.\n if (m < epsilon2) return [NaN, NaN];\n }\n\n return [atan2(y, x) * degrees, asin(z / sqrt(m)) * degrees];\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/constant.js\n/* harmony default export */ var constant = (function(x) {\n return function() {\n return x;\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/compose.js\n/* harmony default export */ var compose = (function(a, b) {\n\n function compose(x, y) {\n return x = a(x, y), b(x[0], x[1]);\n }\n\n if (a.invert && b.invert) compose.invert = function(x, y) {\n return x = b.invert(x, y), x && a.invert(x[0], x[1]);\n };\n\n return compose;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/rotation.js\n\n\n\nfunction rotationIdentity(lambda, phi) {\n return [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi];\n}\n\nrotationIdentity.invert = rotationIdentity;\n\nfunction rotateRadians(deltaLambda, deltaPhi, deltaGamma) {\n return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))\n : rotationLambda(deltaLambda))\n : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)\n : rotationIdentity);\n}\n\nfunction forwardRotationLambda(deltaLambda) {\n return function(lambda, phi) {\n return lambda += deltaLambda, [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi];\n };\n}\n\nfunction rotationLambda(deltaLambda) {\n var rotation = forwardRotationLambda(deltaLambda);\n rotation.invert = forwardRotationLambda(-deltaLambda);\n return rotation;\n}\n\nfunction rotationPhiGamma(deltaPhi, deltaGamma) {\n var cosDeltaPhi = cos(deltaPhi),\n sinDeltaPhi = sin(deltaPhi),\n cosDeltaGamma = cos(deltaGamma),\n sinDeltaGamma = sin(deltaGamma);\n\n function rotation(lambda, phi) {\n var cosPhi = cos(phi),\n x = cos(lambda) * cosPhi,\n y = sin(lambda) * cosPhi,\n z = sin(phi),\n k = z * cosDeltaPhi + x * sinDeltaPhi;\n return [\n atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),\n asin(k * cosDeltaGamma + y * sinDeltaGamma)\n ];\n }\n\n rotation.invert = function(lambda, phi) {\n var cosPhi = cos(phi),\n x = cos(lambda) * cosPhi,\n y = sin(lambda) * cosPhi,\n z = sin(phi),\n k = z * cosDeltaGamma - y * sinDeltaGamma;\n return [\n atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),\n asin(k * cosDeltaPhi - x * sinDeltaPhi)\n ];\n };\n\n return rotation;\n}\n\n/* harmony default export */ var src_rotation = (function(rotate) {\n rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);\n\n function forward(coordinates) {\n coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;\n }\n\n forward.invert = function(coordinates) {\n coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;\n };\n\n return forward;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/circle.js\n\n\n\n\n\n// Generates a circle centered at [0°, 0°], with a given radius and precision.\nfunction circleStream(stream, radius, delta, direction, t0, t1) {\n if (!delta) return;\n var cosRadius = cos(radius),\n sinRadius = sin(radius),\n step = direction * delta;\n if (t0 == null) {\n t0 = radius + direction * tau;\n t1 = radius - step / 2;\n } else {\n t0 = circleRadius(cosRadius, t0);\n t1 = circleRadius(cosRadius, t1);\n if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau;\n }\n for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {\n point = cartesian_spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]);\n stream.point(point[0], point[1]);\n }\n}\n\n// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].\nfunction circleRadius(cosRadius, point) {\n point = cartesian_cartesian(point), point[0] -= cosRadius;\n cartesianNormalizeInPlace(point);\n var radius = acos(-point[1]);\n return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau;\n}\n\n/* harmony default export */ var src_circle = (function() {\n var center = constant([0, 0]),\n radius = constant(90),\n precision = constant(6),\n ring,\n rotate,\n stream = {point: point};\n\n function point(x, y) {\n ring.push(x = rotate(x, y));\n x[0] *= degrees, x[1] *= degrees;\n }\n\n function circle() {\n var c = center.apply(this, arguments),\n r = radius.apply(this, arguments) * radians,\n p = precision.apply(this, arguments) * radians;\n ring = [];\n rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;\n circleStream(stream, r, p, 1);\n c = {type: \"Polygon\", coordinates: [ring]};\n ring = rotate = null;\n return c;\n }\n\n circle.center = function(_) {\n return arguments.length ? (center = typeof _ === \"function\" ? _ : constant([+_[0], +_[1]]), circle) : center;\n };\n\n circle.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant(+_), circle) : radius;\n };\n\n circle.precision = function(_) {\n return arguments.length ? (precision = typeof _ === \"function\" ? _ : constant(+_), circle) : precision;\n };\n\n return circle;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/buffer.js\n\n\n/* harmony default export */ var buffer = (function() {\n var lines = [],\n line;\n return {\n point: function(x, y) {\n line.push([x, y]);\n },\n lineStart: function() {\n lines.push(line = []);\n },\n lineEnd: noop,\n rejoin: function() {\n if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));\n },\n result: function() {\n var result = lines;\n lines = [];\n line = null;\n return result;\n }\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/line.js\n/* harmony default export */ var clip_line = (function(a, b, x0, y0, x1, y1) {\n var ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1],\n t0 = 0,\n t1 = 1,\n dx = bx - ax,\n dy = by - ay,\n r;\n\n r = x0 - ax;\n if (!dx && r > 0) return;\n r /= dx;\n if (dx < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dx > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = x1 - ax;\n if (!dx && r < 0) return;\n r /= dx;\n if (dx < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dx > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n r = y0 - ay;\n if (!dy && r > 0) return;\n r /= dy;\n if (dy < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dy > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = y1 - ay;\n if (!dy && r < 0) return;\n r /= dy;\n if (dy < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dy > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;\n if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;\n return true;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/pointEqual.js\n\n\n/* harmony default export */ var pointEqual = (function(a, b) {\n return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/polygon.js\n\n\nfunction Intersection(point, points, other, entry) {\n this.x = point;\n this.z = points;\n this.o = other; // another intersection\n this.e = entry; // is an entry?\n this.v = false; // visited\n this.n = this.p = null; // next & previous\n}\n\n// A generalized polygon clipping algorithm: given a polygon that has been cut\n// into its visible line segments, and rejoins the segments by interpolating\n// along the clip edge.\n/* harmony default export */ var clip_polygon = (function(segments, compareIntersection, startInside, interpolate, stream) {\n var subject = [],\n clip = [],\n i,\n n;\n\n segments.forEach(function(segment) {\n if ((n = segment.length - 1) <= 0) return;\n var n, p0 = segment[0], p1 = segment[n], x;\n\n // If the first and last points of a segment are coincident, then treat as a\n // closed ring. TODO if all rings are closed, then the winding order of the\n // exterior ring should be checked.\n if (pointEqual(p0, p1)) {\n stream.lineStart();\n for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);\n stream.lineEnd();\n return;\n }\n\n subject.push(x = new Intersection(p0, segment, null, true));\n clip.push(x.o = new Intersection(p0, null, x, false));\n subject.push(x = new Intersection(p1, segment, null, false));\n clip.push(x.o = new Intersection(p1, null, x, true));\n });\n\n if (!subject.length) return;\n\n clip.sort(compareIntersection);\n polygon_link(subject);\n polygon_link(clip);\n\n for (i = 0, n = clip.length; i < n; ++i) {\n clip[i].e = startInside = !startInside;\n }\n\n var start = subject[0],\n points,\n point;\n\n while (1) {\n // Find first unvisited intersection.\n var current = start,\n isSubject = true;\n while (current.v) if ((current = current.n) === start) return;\n points = current.z;\n stream.lineStart();\n do {\n current.v = current.o.v = true;\n if (current.e) {\n if (isSubject) {\n for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.n.x, 1, stream);\n }\n current = current.n;\n } else {\n if (isSubject) {\n points = current.p.z;\n for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.p.x, -1, stream);\n }\n current = current.p;\n }\n current = current.o;\n points = current.z;\n isSubject = !isSubject;\n } while (!current.v);\n stream.lineEnd();\n }\n});\n\nfunction polygon_link(array) {\n if (!(n = array.length)) return;\n var n,\n i = 0,\n a = array[0],\n b;\n while (++i < n) {\n a.n = b = array[i];\n b.p = a;\n a = b;\n }\n a.n = b = array[0];\n b.p = a;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/ascending.js\n/* harmony default export */ var ascending = (function(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/bisector.js\n\n\n/* harmony default export */ var bisector = (function(compare) {\n if (compare.length === 1) compare = ascendingComparator(compare);\n return {\n left: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n },\n right: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) > 0) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n };\n});\n\nfunction ascendingComparator(f) {\n return function(d, x) {\n return ascending(f(d), x);\n };\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/bisect.js\n\n\n\nvar ascendingBisect = bisector(ascending);\nvar bisectRight = ascendingBisect.right;\nvar bisectLeft = ascendingBisect.left;\n/* harmony default export */ var bisect = (bisectRight);\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/pairs.js\n/* harmony default export */ var pairs = (function(array, f) {\n if (f == null) f = pair;\n var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);\n while (i < n) pairs[i] = f(p, p = array[++i]);\n return pairs;\n});\n\nfunction pair(a, b) {\n return [a, b];\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/cross.js\n\n\n/* harmony default export */ var cross = (function(values0, values1, reduce) {\n var n0 = values0.length,\n n1 = values1.length,\n values = new Array(n0 * n1),\n i0,\n i1,\n i,\n value0;\n\n if (reduce == null) reduce = pair;\n\n for (i0 = i = 0; i0 < n0; ++i0) {\n for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n values[i] = reduce(value0, values1[i1]);\n }\n }\n\n return values;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/descending.js\n/* harmony default export */ var descending = (function(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/number.js\n/* harmony default export */ var number = (function(x) {\n return x === null ? NaN : +x;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/variance.js\n\n\n/* harmony default export */ var variance = (function(values, valueof) {\n var n = values.length,\n m = 0,\n i = -1,\n mean = 0,\n value,\n delta,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n if (m > 1) return sum / (m - 1);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/deviation.js\n\n\n/* harmony default export */ var deviation = (function(array, f) {\n var v = variance(array, f);\n return v ? Math.sqrt(v) : v;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/extent.js\n/* harmony default export */ var src_extent = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n return [min, max];\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/array.js\nvar array_array = Array.prototype;\n\nvar slice = array_array.slice;\nvar map = array_array.map;\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/constant.js\n/* harmony default export */ var src_constant = (function(x) {\n return function() {\n return x;\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/identity.js\n/* harmony default export */ var identity = (function(x) {\n return x;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/range.js\n/* harmony default export */ var src_range = (function(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/ticks.js\nvar e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\n/* harmony default export */ var ticks = (function(start, stop, count) {\n var reverse,\n i = -1,\n n,\n ticks,\n step;\n\n stop = +stop, start = +start, count = +count;\n if (start === stop && count > 0) return [start];\n if (reverse = stop < start) n = start, start = stop, stop = n;\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n start = Math.ceil(start / step);\n stop = Math.floor(stop / step);\n ticks = new Array(n = Math.ceil(stop - start + 1));\n while (++i < n) ticks[i] = (start + i) * step;\n } else {\n start = Math.floor(start * step);\n stop = Math.ceil(stop * step);\n ticks = new Array(n = Math.ceil(start - stop + 1));\n while (++i < n) ticks[i] = (start - i) / step;\n }\n\n if (reverse) ticks.reverse();\n\n return ticks;\n});\n\nfunction tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0\n ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nfunction tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;\n else if (error >= e5) step1 *= 5;\n else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/threshold/sturges.js\n/* harmony default export */ var sturges = (function(values) {\n return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/histogram.js\n\n\n\n\n\n\n\n\n\n/* harmony default export */ var src_histogram = (function() {\n var value = identity,\n domain = src_extent,\n threshold = sturges;\n\n function histogram(data) {\n var i,\n n = data.length,\n x,\n values = new Array(n);\n\n for (i = 0; i < n; ++i) {\n values[i] = value(data[i], i, data);\n }\n\n var xz = domain(values),\n x0 = xz[0],\n x1 = xz[1],\n tz = threshold(values, x0, x1);\n\n // Convert number of thresholds into uniform thresholds.\n if (!Array.isArray(tz)) {\n tz = tickStep(x0, x1, tz);\n tz = src_range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive\n }\n\n // Remove any thresholds outside the domain.\n var m = tz.length;\n while (tz[0] <= x0) tz.shift(), --m;\n while (tz[m - 1] > x1) tz.pop(), --m;\n\n var bins = new Array(m + 1),\n bin;\n\n // Initialize bins.\n for (i = 0; i <= m; ++i) {\n bin = bins[i] = [];\n bin.x0 = i > 0 ? tz[i - 1] : x0;\n bin.x1 = i < m ? tz[i] : x1;\n }\n\n // Assign data to bins by value, ignoring any outside the domain.\n for (i = 0; i < n; ++i) {\n x = values[i];\n if (x0 <= x && x <= x1) {\n bins[bisect(tz, x, 0, m)].push(data[i]);\n }\n }\n\n return bins;\n }\n\n histogram.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : src_constant(_), histogram) : value;\n };\n\n histogram.domain = function(_) {\n return arguments.length ? (domain = typeof _ === \"function\" ? _ : src_constant([_[0], _[1]]), histogram) : domain;\n };\n\n histogram.thresholds = function(_) {\n return arguments.length ? (threshold = typeof _ === \"function\" ? _ : Array.isArray(_) ? src_constant(slice.call(_)) : src_constant(_), histogram) : threshold;\n };\n\n return histogram;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/quantile.js\n\n\n/* harmony default export */ var quantile = (function(values, p, valueof) {\n if (valueof == null) valueof = number;\n if (!(n = values.length)) return;\n if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/threshold/freedmanDiaconis.js\n\n\n\n\n\n/* harmony default export */ var freedmanDiaconis = (function(values, min, max) {\n values = map.call(values, number).sort(ascending);\n return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(values.length, -1 / 3)));\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/threshold/scott.js\n\n\n/* harmony default export */ var scott = (function(values, min, max) {\n return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/max.js\n/* harmony default export */ var src_max = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n return max;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/mean.js\n\n\n/* harmony default export */ var src_mean = (function(values, valueof) {\n var n = values.length,\n m = n,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) sum += value;\n else --m;\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;\n else --m;\n }\n }\n\n if (m) return sum / m;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/median.js\n\n\n\n\n/* harmony default export */ var median = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n numbers = [];\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n numbers.push(value);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n numbers.push(value);\n }\n }\n }\n\n return quantile(numbers.sort(ascending), 0.5);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/merge.js\n/* harmony default export */ var merge = (function(arrays) {\n var n = arrays.length,\n m,\n i = -1,\n j = 0,\n merged,\n array;\n\n while (++i < n) j += arrays[i].length;\n merged = new Array(j);\n\n while (--n >= 0) {\n array = arrays[n];\n m = array.length;\n while (--m >= 0) {\n merged[--j] = array[m];\n }\n }\n\n return merged;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/min.js\n/* harmony default export */ var src_min = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n return min;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/permute.js\n/* harmony default export */ var permute = (function(array, indexes) {\n var i = indexes.length, permutes = new Array(i);\n while (i--) permutes[i] = array[indexes[i]];\n return permutes;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/scan.js\n\n\n/* harmony default export */ var scan = (function(values, compare) {\n if (!(n = values.length)) return;\n var n,\n i = 0,\n j = 0,\n xi,\n xj = values[j];\n\n if (compare == null) compare = ascending;\n\n while (++i < n) {\n if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {\n xj = xi, j = i;\n }\n }\n\n if (compare(xj, xj) === 0) return j;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/shuffle.js\n/* harmony default export */ var shuffle = (function(array, i0, i1) {\n var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m + i0];\n array[m + i0] = array[i + i0];\n array[i + i0] = t;\n }\n\n return array;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/sum.js\n/* harmony default export */ var src_sum = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (value = +values[i]) sum += value; // Note: zero and null are equivalent.\n }\n }\n\n else {\n while (++i < n) {\n if (value = +valueof(values[i], i, values)) sum += value;\n }\n }\n\n return sum;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/transpose.js\n\n\n/* harmony default export */ var src_transpose = (function(matrix) {\n if (!(n = matrix.length)) return [];\n for (var i = -1, m = src_min(matrix, transpose_length), transpose = new Array(m); ++i < m;) {\n for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {\n row[j] = matrix[j][i];\n }\n }\n return transpose;\n});\n\nfunction transpose_length(d) {\n return d.length;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/zip.js\n\n\n/* harmony default export */ var zip = (function() {\n return src_transpose(arguments);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/extent.js\n\n\n\n\n\n\nvar clipMax = 1e9, clipMin = -clipMax;\n\n// TODO Use d3-polygon’s polygonContains here for the ring check?\n// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?\n\nfunction extent_clipExtent(x0, y0, x1, y1) {\n\n function visible(x, y) {\n return x0 <= x && x <= x1 && y0 <= y && y <= y1;\n }\n\n function interpolate(from, to, direction, stream) {\n var a = 0, a1 = 0;\n if (from == null\n || (a = corner(from, direction)) !== (a1 = corner(to, direction))\n || comparePoint(from, to) < 0 ^ direction > 0) {\n do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);\n while ((a = (a + direction + 4) % 4) !== a1);\n } else {\n stream.point(to[0], to[1]);\n }\n }\n\n function corner(p, direction) {\n return abs(p[0] - x0) < epsilon ? direction > 0 ? 0 : 3\n : abs(p[0] - x1) < epsilon ? direction > 0 ? 2 : 1\n : abs(p[1] - y0) < epsilon ? direction > 0 ? 1 : 0\n : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon\n }\n\n function compareIntersection(a, b) {\n return comparePoint(a.x, b.x);\n }\n\n function comparePoint(a, b) {\n var ca = corner(a, 1),\n cb = corner(b, 1);\n return ca !== cb ? ca - cb\n : ca === 0 ? b[1] - a[1]\n : ca === 1 ? a[0] - b[0]\n : ca === 2 ? a[1] - b[1]\n : b[0] - a[0];\n }\n\n return function(stream) {\n var activeStream = stream,\n bufferStream = buffer(),\n segments,\n polygon,\n ring,\n x__, y__, v__, // first point\n x_, y_, v_, // previous point\n first,\n clean;\n\n var clipStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: polygonStart,\n polygonEnd: polygonEnd\n };\n\n function point(x, y) {\n if (visible(x, y)) activeStream.point(x, y);\n }\n\n function polygonInside() {\n var winding = 0;\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {\n a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];\n if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }\n else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }\n }\n }\n\n return winding;\n }\n\n // Buffer geometry within a polygon and then clip it en masse.\n function polygonStart() {\n activeStream = bufferStream, segments = [], polygon = [], clean = true;\n }\n\n function polygonEnd() {\n var startInside = polygonInside(),\n cleanInside = clean && startInside,\n visible = (segments = merge(segments)).length;\n if (cleanInside || visible) {\n stream.polygonStart();\n if (cleanInside) {\n stream.lineStart();\n interpolate(null, null, 1, stream);\n stream.lineEnd();\n }\n if (visible) {\n clip_polygon(segments, compareIntersection, startInside, interpolate, stream);\n }\n stream.polygonEnd();\n }\n activeStream = stream, segments = polygon = ring = null;\n }\n\n function lineStart() {\n clipStream.point = linePoint;\n if (polygon) polygon.push(ring = []);\n first = true;\n v_ = false;\n x_ = y_ = NaN;\n }\n\n // TODO rather than special-case polygons, simply handle them separately.\n // Ideally, coincident intersection points should be jittered to avoid\n // clipping issues.\n function lineEnd() {\n if (segments) {\n linePoint(x__, y__);\n if (v__ && v_) bufferStream.rejoin();\n segments.push(bufferStream.result());\n }\n clipStream.point = point;\n if (v_) activeStream.lineEnd();\n }\n\n function linePoint(x, y) {\n var v = visible(x, y);\n if (polygon) ring.push([x, y]);\n if (first) {\n x__ = x, y__ = y, v__ = v;\n first = false;\n if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n }\n } else {\n if (v && v_) activeStream.point(x, y);\n else {\n var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],\n b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];\n if (clip_line(a, b, x0, y0, x1, y1)) {\n if (!v_) {\n activeStream.lineStart();\n activeStream.point(a[0], a[1]);\n }\n activeStream.point(b[0], b[1]);\n if (!v) activeStream.lineEnd();\n clean = false;\n } else if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n clean = false;\n }\n }\n }\n x_ = x, y_ = y, v_ = v;\n }\n\n return clipStream;\n };\n}\n\n/* harmony default export */ var clip_extent = (function() {\n var x0 = 0,\n y0 = 0,\n x1 = 960,\n y1 = 500,\n cache,\n cacheStream,\n clip;\n\n return clip = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = extent_clipExtent(x0, y0, x1, y1)(cacheStream = stream);\n },\n extent: function(_) {\n return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];\n }\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/polygonContains.js\n\n\n\n\nvar polygonContains_sum = adder();\n\n/* harmony default export */ var polygonContains = (function(polygon, point) {\n var lambda = point[0],\n phi = point[1],\n normal = [sin(lambda), -cos(lambda), 0],\n angle = 0,\n winding = 0;\n\n polygonContains_sum.reset();\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n if (!(m = (ring = polygon[i]).length)) continue;\n var ring,\n m,\n point0 = ring[m - 1],\n lambda0 = point0[0],\n phi0 = point0[1] / 2 + quarterPi,\n sinPhi0 = sin(phi0),\n cosPhi0 = cos(phi0);\n\n for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {\n var point1 = ring[j],\n lambda1 = point1[0],\n phi1 = point1[1] / 2 + quarterPi,\n sinPhi1 = sin(phi1),\n cosPhi1 = cos(phi1),\n delta = lambda1 - lambda0,\n sign = delta >= 0 ? 1 : -1,\n absDelta = sign * delta,\n antimeridian = absDelta > pi,\n k = sinPhi0 * sinPhi1;\n\n polygonContains_sum.add(atan2(k * sign * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta)));\n angle += antimeridian ? delta + sign * tau : delta;\n\n // Are the longitudes either side of the point’s meridian (lambda),\n // and are the latitudes smaller than the parallel (phi)?\n if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {\n var arc = cartesianCross(cartesian_cartesian(point0), cartesian_cartesian(point1));\n cartesianNormalizeInPlace(arc);\n var intersection = cartesianCross(normal, arc);\n cartesianNormalizeInPlace(intersection);\n var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);\n if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {\n winding += antimeridian ^ delta >= 0 ? 1 : -1;\n }\n }\n }\n }\n\n // First, determine whether the South pole is inside or outside:\n //\n // It is inside if:\n // * the polygon winds around it in a clockwise direction.\n // * the polygon does not (cumulatively) wind around it, but has a negative\n // (counter-clockwise) area.\n //\n // Second, count the (signed) number of times a segment crosses a lambda\n // from the point to the South pole. If it is zero, then the point is the\n // same side as the South pole.\n\n return (angle < -epsilon || angle < epsilon && polygonContains_sum < -epsilon) ^ (winding & 1);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/length.js\n\n\n\n\n\nvar lengthSum = adder(),\n length_lambda0,\n length_sinPhi0,\n length_cosPhi0;\n\nvar lengthStream = {\n sphere: noop,\n point: noop,\n lineStart: lengthLineStart,\n lineEnd: noop,\n polygonStart: noop,\n polygonEnd: noop\n};\n\nfunction lengthLineStart() {\n lengthStream.point = lengthPointFirst;\n lengthStream.lineEnd = lengthLineEnd;\n}\n\nfunction lengthLineEnd() {\n lengthStream.point = lengthStream.lineEnd = noop;\n}\n\nfunction lengthPointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n length_lambda0 = lambda, length_sinPhi0 = sin(phi), length_cosPhi0 = cos(phi);\n lengthStream.point = lengthPoint;\n}\n\nfunction lengthPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var sinPhi = sin(phi),\n cosPhi = cos(phi),\n delta = abs(lambda - length_lambda0),\n cosDelta = cos(delta),\n sinDelta = sin(delta),\n x = cosPhi * sinDelta,\n y = length_cosPhi0 * sinPhi - length_sinPhi0 * cosPhi * cosDelta,\n z = length_sinPhi0 * sinPhi + length_cosPhi0 * cosPhi * cosDelta;\n lengthSum.add(atan2(sqrt(x * x + y * y), z));\n length_lambda0 = lambda, length_sinPhi0 = sinPhi, length_cosPhi0 = cosPhi;\n}\n\n/* harmony default export */ var src_length = (function(object) {\n lengthSum.reset();\n src_stream(object, lengthStream);\n return +lengthSum;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/distance.js\n\n\nvar distance_coordinates = [null, null],\n distance_object = {type: \"LineString\", coordinates: distance_coordinates};\n\n/* harmony default export */ var src_distance = (function(a, b) {\n distance_coordinates[0] = a;\n distance_coordinates[1] = b;\n return src_length(distance_object);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/contains.js\n\n\n\n\nvar containsObjectType = {\n Feature: function(object, point) {\n return containsGeometry(object.geometry, point);\n },\n FeatureCollection: function(object, point) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;\n return false;\n }\n};\n\nvar containsGeometryType = {\n Sphere: function() {\n return true;\n },\n Point: function(object, point) {\n return containsPoint(object.coordinates, point);\n },\n MultiPoint: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPoint(coordinates[i], point)) return true;\n return false;\n },\n LineString: function(object, point) {\n return containsLine(object.coordinates, point);\n },\n MultiLineString: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsLine(coordinates[i], point)) return true;\n return false;\n },\n Polygon: function(object, point) {\n return containsPolygon(object.coordinates, point);\n },\n MultiPolygon: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPolygon(coordinates[i], point)) return true;\n return false;\n },\n GeometryCollection: function(object, point) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) if (containsGeometry(geometries[i], point)) return true;\n return false;\n }\n};\n\nfunction containsGeometry(geometry, point) {\n return geometry && containsGeometryType.hasOwnProperty(geometry.type)\n ? containsGeometryType[geometry.type](geometry, point)\n : false;\n}\n\nfunction containsPoint(coordinates, point) {\n return src_distance(coordinates, point) === 0;\n}\n\nfunction containsLine(coordinates, point) {\n var ab = src_distance(coordinates[0], coordinates[1]),\n ao = src_distance(coordinates[0], point),\n ob = src_distance(point, coordinates[1]);\n return ao + ob <= ab + epsilon;\n}\n\nfunction containsPolygon(coordinates, point) {\n return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));\n}\n\nfunction ringRadians(ring) {\n return ring = ring.map(pointRadians), ring.pop(), ring;\n}\n\nfunction pointRadians(point) {\n return [point[0] * radians, point[1] * radians];\n}\n\n/* harmony default export */ var contains = (function(object, point) {\n return (object && containsObjectType.hasOwnProperty(object.type)\n ? containsObjectType[object.type]\n : containsGeometry)(object, point);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/graticule.js\n\n\n\nfunction graticuleX(y0, y1, dy) {\n var y = src_range(y0, y1 - epsilon, dy).concat(y1);\n return function(x) { return y.map(function(y) { return [x, y]; }); };\n}\n\nfunction graticuleY(x0, x1, dx) {\n var x = src_range(x0, x1 - epsilon, dx).concat(x1);\n return function(y) { return x.map(function(x) { return [x, y]; }); };\n}\n\nfunction graticule_graticule() {\n var x1, x0, X1, X0,\n y1, y0, Y1, Y0,\n dx = 10, dy = dx, DX = 90, DY = 360,\n x, y, X, Y,\n precision = 2.5;\n\n function graticule() {\n return {type: \"MultiLineString\", coordinates: lines()};\n }\n\n function lines() {\n return src_range(ceil(X0 / DX) * DX, X1, DX).map(X)\n .concat(src_range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))\n .concat(src_range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon; }).map(x))\n .concat(src_range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon; }).map(y));\n }\n\n graticule.lines = function() {\n return lines().map(function(coordinates) { return {type: \"LineString\", coordinates: coordinates}; });\n };\n\n graticule.outline = function() {\n return {\n type: \"Polygon\",\n coordinates: [\n X(X0).concat(\n Y(Y1).slice(1),\n X(X1).reverse().slice(1),\n Y(Y0).reverse().slice(1))\n ]\n };\n };\n\n graticule.extent = function(_) {\n if (!arguments.length) return graticule.extentMinor();\n return graticule.extentMajor(_).extentMinor(_);\n };\n\n graticule.extentMajor = function(_) {\n if (!arguments.length) return [[X0, Y0], [X1, Y1]];\n X0 = +_[0][0], X1 = +_[1][0];\n Y0 = +_[0][1], Y1 = +_[1][1];\n if (X0 > X1) _ = X0, X0 = X1, X1 = _;\n if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.extentMinor = function(_) {\n if (!arguments.length) return [[x0, y0], [x1, y1]];\n x0 = +_[0][0], x1 = +_[1][0];\n y0 = +_[0][1], y1 = +_[1][1];\n if (x0 > x1) _ = x0, x0 = x1, x1 = _;\n if (y0 > y1) _ = y0, y0 = y1, y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.step = function(_) {\n if (!arguments.length) return graticule.stepMinor();\n return graticule.stepMajor(_).stepMinor(_);\n };\n\n graticule.stepMajor = function(_) {\n if (!arguments.length) return [DX, DY];\n DX = +_[0], DY = +_[1];\n return graticule;\n };\n\n graticule.stepMinor = function(_) {\n if (!arguments.length) return [dx, dy];\n dx = +_[0], dy = +_[1];\n return graticule;\n };\n\n graticule.precision = function(_) {\n if (!arguments.length) return precision;\n precision = +_;\n x = graticuleX(y0, y1, 90);\n y = graticuleY(x0, x1, precision);\n X = graticuleX(Y0, Y1, 90);\n Y = graticuleY(X0, X1, precision);\n return graticule;\n };\n\n return graticule\n .extentMajor([[-180, -90 + epsilon], [180, 90 - epsilon]])\n .extentMinor([[-180, -80 - epsilon], [180, 80 + epsilon]]);\n}\n\nfunction graticule10() {\n return graticule_graticule()();\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/interpolate.js\n\n\n/* harmony default export */ var src_interpolate = (function(a, b) {\n var x0 = a[0] * radians,\n y0 = a[1] * radians,\n x1 = b[0] * radians,\n y1 = b[1] * radians,\n cy0 = cos(y0),\n sy0 = sin(y0),\n cy1 = cos(y1),\n sy1 = sin(y1),\n kx0 = cy0 * cos(x0),\n ky0 = cy0 * sin(x0),\n kx1 = cy1 * cos(x1),\n ky1 = cy1 * sin(x1),\n d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),\n k = sin(d);\n\n var interpolate = d ? function(t) {\n var B = sin(t *= d) / k,\n A = sin(d - t) / k,\n x = A * kx0 + B * kx1,\n y = A * ky0 + B * ky1,\n z = A * sy0 + B * sy1;\n return [\n atan2(y, x) * degrees,\n atan2(z, sqrt(x * x + y * y)) * degrees\n ];\n } : function() {\n return [x0 * degrees, y0 * degrees];\n };\n\n interpolate.distance = d;\n\n return interpolate;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/identity.js\n/* harmony default export */ var src_identity = (function(x) {\n return x;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/area.js\n\n\n\n\nvar area_areaSum = adder(),\n area_areaRingSum = adder(),\n area_x00,\n area_y00,\n area_x0,\n area_y0;\n\nvar area_areaStream = {\n point: noop,\n lineStart: noop,\n lineEnd: noop,\n polygonStart: function() {\n area_areaStream.lineStart = area_areaRingStart;\n area_areaStream.lineEnd = area_areaRingEnd;\n },\n polygonEnd: function() {\n area_areaStream.lineStart = area_areaStream.lineEnd = area_areaStream.point = noop;\n area_areaSum.add(abs(area_areaRingSum));\n area_areaRingSum.reset();\n },\n result: function() {\n var area = area_areaSum / 2;\n area_areaSum.reset();\n return area;\n }\n};\n\nfunction area_areaRingStart() {\n area_areaStream.point = area_areaPointFirst;\n}\n\nfunction area_areaPointFirst(x, y) {\n area_areaStream.point = area_areaPoint;\n area_x00 = area_x0 = x, area_y00 = area_y0 = y;\n}\n\nfunction area_areaPoint(x, y) {\n area_areaRingSum.add(area_y0 * x - area_x0 * y);\n area_x0 = x, area_y0 = y;\n}\n\nfunction area_areaRingEnd() {\n area_areaPoint(area_x00, area_y00);\n}\n\n/* harmony default export */ var path_area = (area_areaStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/bounds.js\n\n\nvar bounds_x0 = Infinity,\n bounds_y0 = bounds_x0,\n bounds_x1 = -bounds_x0,\n bounds_y1 = bounds_x1;\n\nvar bounds_boundsStream = {\n point: bounds_boundsPoint,\n lineStart: noop,\n lineEnd: noop,\n polygonStart: noop,\n polygonEnd: noop,\n result: function() {\n var bounds = [[bounds_x0, bounds_y0], [bounds_x1, bounds_y1]];\n bounds_x1 = bounds_y1 = -(bounds_y0 = bounds_x0 = Infinity);\n return bounds;\n }\n};\n\nfunction bounds_boundsPoint(x, y) {\n if (x < bounds_x0) bounds_x0 = x;\n if (x > bounds_x1) bounds_x1 = x;\n if (y < bounds_y0) bounds_y0 = y;\n if (y > bounds_y1) bounds_y1 = y;\n}\n\n/* harmony default export */ var path_bounds = (bounds_boundsStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/centroid.js\n\n\n// TODO Enforce positive area for exterior, negative area for interior?\n\nvar path_centroid_X0 = 0,\n path_centroid_Y0 = 0,\n centroid_Z0 = 0,\n path_centroid_X1 = 0,\n path_centroid_Y1 = 0,\n centroid_Z1 = 0,\n centroid_X2 = 0,\n centroid_Y2 = 0,\n centroid_Z2 = 0,\n centroid_x00,\n centroid_y00,\n path_centroid_x0,\n path_centroid_y0;\n\nvar centroid_centroidStream = {\n point: centroid_centroidPoint,\n lineStart: centroid_centroidLineStart,\n lineEnd: centroid_centroidLineEnd,\n polygonStart: function() {\n centroid_centroidStream.lineStart = centroid_centroidRingStart;\n centroid_centroidStream.lineEnd = centroid_centroidRingEnd;\n },\n polygonEnd: function() {\n centroid_centroidStream.point = centroid_centroidPoint;\n centroid_centroidStream.lineStart = centroid_centroidLineStart;\n centroid_centroidStream.lineEnd = centroid_centroidLineEnd;\n },\n result: function() {\n var centroid = centroid_Z2 ? [centroid_X2 / centroid_Z2, centroid_Y2 / centroid_Z2]\n : centroid_Z1 ? [path_centroid_X1 / centroid_Z1, path_centroid_Y1 / centroid_Z1]\n : centroid_Z0 ? [path_centroid_X0 / centroid_Z0, path_centroid_Y0 / centroid_Z0]\n : [NaN, NaN];\n path_centroid_X0 = path_centroid_Y0 = centroid_Z0 =\n path_centroid_X1 = path_centroid_Y1 = centroid_Z1 =\n centroid_X2 = centroid_Y2 = centroid_Z2 = 0;\n return centroid;\n }\n};\n\nfunction centroid_centroidPoint(x, y) {\n path_centroid_X0 += x;\n path_centroid_Y0 += y;\n ++centroid_Z0;\n}\n\nfunction centroid_centroidLineStart() {\n centroid_centroidStream.point = centroidPointFirstLine;\n}\n\nfunction centroidPointFirstLine(x, y) {\n centroid_centroidStream.point = centroidPointLine;\n centroid_centroidPoint(path_centroid_x0 = x, path_centroid_y0 = y);\n}\n\nfunction centroidPointLine(x, y) {\n var dx = x - path_centroid_x0, dy = y - path_centroid_y0, z = sqrt(dx * dx + dy * dy);\n path_centroid_X1 += z * (path_centroid_x0 + x) / 2;\n path_centroid_Y1 += z * (path_centroid_y0 + y) / 2;\n centroid_Z1 += z;\n centroid_centroidPoint(path_centroid_x0 = x, path_centroid_y0 = y);\n}\n\nfunction centroid_centroidLineEnd() {\n centroid_centroidStream.point = centroid_centroidPoint;\n}\n\nfunction centroid_centroidRingStart() {\n centroid_centroidStream.point = centroidPointFirstRing;\n}\n\nfunction centroid_centroidRingEnd() {\n centroidPointRing(centroid_x00, centroid_y00);\n}\n\nfunction centroidPointFirstRing(x, y) {\n centroid_centroidStream.point = centroidPointRing;\n centroid_centroidPoint(centroid_x00 = path_centroid_x0 = x, centroid_y00 = path_centroid_y0 = y);\n}\n\nfunction centroidPointRing(x, y) {\n var dx = x - path_centroid_x0,\n dy = y - path_centroid_y0,\n z = sqrt(dx * dx + dy * dy);\n\n path_centroid_X1 += z * (path_centroid_x0 + x) / 2;\n path_centroid_Y1 += z * (path_centroid_y0 + y) / 2;\n centroid_Z1 += z;\n\n z = path_centroid_y0 * x - path_centroid_x0 * y;\n centroid_X2 += z * (path_centroid_x0 + x);\n centroid_Y2 += z * (path_centroid_y0 + y);\n centroid_Z2 += z * 3;\n centroid_centroidPoint(path_centroid_x0 = x, path_centroid_y0 = y);\n}\n\n/* harmony default export */ var path_centroid = (centroid_centroidStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/context.js\n\n\n\nfunction PathContext(context) {\n this._context = context;\n}\n\nPathContext.prototype = {\n _radius: 4.5,\n pointRadius: function(_) {\n return this._radius = _, this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._context.closePath();\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._context.moveTo(x, y);\n this._point = 1;\n break;\n }\n case 1: {\n this._context.lineTo(x, y);\n break;\n }\n default: {\n this._context.moveTo(x + this._radius, y);\n this._context.arc(x, y, this._radius, 0, tau);\n break;\n }\n }\n },\n result: noop\n};\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/measure.js\n\n\n\n\nvar measure_lengthSum = adder(),\n lengthRing,\n measure_x00,\n measure_y00,\n measure_x0,\n measure_y0;\n\nvar measure_lengthStream = {\n point: noop,\n lineStart: function() {\n measure_lengthStream.point = measure_lengthPointFirst;\n },\n lineEnd: function() {\n if (lengthRing) measure_lengthPoint(measure_x00, measure_y00);\n measure_lengthStream.point = noop;\n },\n polygonStart: function() {\n lengthRing = true;\n },\n polygonEnd: function() {\n lengthRing = null;\n },\n result: function() {\n var length = +measure_lengthSum;\n measure_lengthSum.reset();\n return length;\n }\n};\n\nfunction measure_lengthPointFirst(x, y) {\n measure_lengthStream.point = measure_lengthPoint;\n measure_x00 = measure_x0 = x, measure_y00 = measure_y0 = y;\n}\n\nfunction measure_lengthPoint(x, y) {\n measure_x0 -= x, measure_y0 -= y;\n measure_lengthSum.add(sqrt(measure_x0 * measure_x0 + measure_y0 * measure_y0));\n measure_x0 = x, measure_y0 = y;\n}\n\n/* harmony default export */ var measure = (measure_lengthStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/string.js\nfunction PathString() {\n this._string = [];\n}\n\nPathString.prototype = {\n _radius: 4.5,\n _circle: string_circle(4.5),\n pointRadius: function(_) {\n if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;\n return this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._string.push(\"Z\");\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._string.push(\"M\", x, \",\", y);\n this._point = 1;\n break;\n }\n case 1: {\n this._string.push(\"L\", x, \",\", y);\n break;\n }\n default: {\n if (this._circle == null) this._circle = string_circle(this._radius);\n this._string.push(\"M\", x, \",\", y, this._circle);\n break;\n }\n }\n },\n result: function() {\n if (this._string.length) {\n var result = this._string.join(\"\");\n this._string = [];\n return result;\n } else {\n return null;\n }\n }\n};\n\nfunction string_circle(radius) {\n return \"m0,\" + radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + -2 * radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + 2 * radius\n + \"z\";\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/index.js\n\n\n\n\n\n\n\n\n\n/* harmony default export */ var src_path = (function(projection, context) {\n var pointRadius = 4.5,\n projectionStream,\n contextStream;\n\n function path(object) {\n if (object) {\n if (typeof pointRadius === \"function\") contextStream.pointRadius(+pointRadius.apply(this, arguments));\n src_stream(object, projectionStream(contextStream));\n }\n return contextStream.result();\n }\n\n path.area = function(object) {\n src_stream(object, projectionStream(path_area));\n return path_area.result();\n };\n\n path.measure = function(object) {\n src_stream(object, projectionStream(measure));\n return measure.result();\n };\n\n path.bounds = function(object) {\n src_stream(object, projectionStream(path_bounds));\n return path_bounds.result();\n };\n\n path.centroid = function(object) {\n src_stream(object, projectionStream(path_centroid));\n return path_centroid.result();\n };\n\n path.projection = function(_) {\n return arguments.length ? (projectionStream = _ == null ? (projection = null, src_identity) : (projection = _).stream, path) : projection;\n };\n\n path.context = function(_) {\n if (!arguments.length) return context;\n contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);\n if (typeof pointRadius !== \"function\") contextStream.pointRadius(pointRadius);\n return path;\n };\n\n path.pointRadius = function(_) {\n if (!arguments.length) return pointRadius;\n pointRadius = typeof _ === \"function\" ? _ : (contextStream.pointRadius(+_), +_);\n return path;\n };\n\n return path.projection(projection).context(context);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/index.js\n\n\n\n\n\n\n/* harmony default export */ var src_clip = (function(pointVisible, clipLine, interpolate, start) {\n return function(rotate, sink) {\n var line = clipLine(sink),\n rotatedStart = rotate.invert(start[0], start[1]),\n ringBuffer = buffer(),\n ringSink = clipLine(ringBuffer),\n polygonStarted = false,\n polygon,\n segments,\n ring;\n\n var clip = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() {\n clip.point = pointRing;\n clip.lineStart = ringStart;\n clip.lineEnd = ringEnd;\n segments = [];\n polygon = [];\n },\n polygonEnd: function() {\n clip.point = point;\n clip.lineStart = lineStart;\n clip.lineEnd = lineEnd;\n segments = merge(segments);\n var startInside = polygonContains(polygon, rotatedStart);\n if (segments.length) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n clip_polygon(segments, clip_compareIntersection, startInside, interpolate, sink);\n } else if (startInside) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n }\n if (polygonStarted) sink.polygonEnd(), polygonStarted = false;\n segments = polygon = null;\n },\n sphere: function() {\n sink.polygonStart();\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n sink.polygonEnd();\n }\n };\n\n function point(lambda, phi) {\n var point = rotate(lambda, phi);\n if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);\n }\n\n function pointLine(lambda, phi) {\n var point = rotate(lambda, phi);\n line.point(point[0], point[1]);\n }\n\n function lineStart() {\n clip.point = pointLine;\n line.lineStart();\n }\n\n function lineEnd() {\n clip.point = point;\n line.lineEnd();\n }\n\n function pointRing(lambda, phi) {\n ring.push([lambda, phi]);\n var point = rotate(lambda, phi);\n ringSink.point(point[0], point[1]);\n }\n\n function ringStart() {\n ringSink.lineStart();\n ring = [];\n }\n\n function ringEnd() {\n pointRing(ring[0][0], ring[0][1]);\n ringSink.lineEnd();\n\n var clean = ringSink.clean(),\n ringSegments = ringBuffer.result(),\n i, n = ringSegments.length, m,\n segment,\n point;\n\n ring.pop();\n polygon.push(ring);\n ring = null;\n\n if (!n) return;\n\n // No intersections.\n if (clean & 1) {\n segment = ringSegments[0];\n if ((m = segment.length - 1) > 0) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);\n sink.lineEnd();\n }\n return;\n }\n\n // Rejoin connected segments.\n // TODO reuse ringBuffer.rejoin()?\n if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));\n\n segments.push(ringSegments.filter(validSegment));\n }\n\n return clip;\n };\n});\n\nfunction validSegment(segment) {\n return segment.length > 1;\n}\n\n// Intersections are sorted along the clip edge. For both antimeridian cutting\n// and circle clipping, the same comparison is used.\nfunction clip_compareIntersection(a, b) {\n return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1])\n - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]);\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/antimeridian.js\n\n\n\n/* harmony default export */ var clip_antimeridian = (src_clip(\n function() { return true; },\n clipAntimeridianLine,\n clipAntimeridianInterpolate,\n [-pi, -halfPi]\n));\n\n// Takes a line and cuts into visible segments. Return values: 0 - there were\n// intersections or the line was empty; 1 - no intersections; 2 - there were\n// intersections, and the first and last segments should be rejoined.\nfunction clipAntimeridianLine(stream) {\n var lambda0 = NaN,\n phi0 = NaN,\n sign0 = NaN,\n clean; // no intersections\n\n return {\n lineStart: function() {\n stream.lineStart();\n clean = 1;\n },\n point: function(lambda1, phi1) {\n var sign1 = lambda1 > 0 ? pi : -pi,\n delta = abs(lambda1 - lambda0);\n if (abs(delta - pi) < epsilon) { // line crosses a pole\n stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi : -halfPi);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n stream.point(lambda1, phi0);\n clean = 0;\n } else if (sign0 !== sign1 && delta >= pi) { // line crosses antimeridian\n if (abs(lambda0 - sign0) < epsilon) lambda0 -= sign0 * epsilon; // handle degeneracies\n if (abs(lambda1 - sign1) < epsilon) lambda1 -= sign1 * epsilon;\n phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n clean = 0;\n }\n stream.point(lambda0 = lambda1, phi0 = phi1);\n sign0 = sign1;\n },\n lineEnd: function() {\n stream.lineEnd();\n lambda0 = phi0 = NaN;\n },\n clean: function() {\n return 2 - clean; // if intersections, rejoin first and last segments\n }\n };\n}\n\nfunction clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {\n var cosPhi0,\n cosPhi1,\n sinLambda0Lambda1 = sin(lambda0 - lambda1);\n return abs(sinLambda0Lambda1) > epsilon\n ? atan((sin(phi0) * (cosPhi1 = cos(phi1)) * sin(lambda1)\n - sin(phi1) * (cosPhi0 = cos(phi0)) * sin(lambda0))\n / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))\n : (phi0 + phi1) / 2;\n}\n\nfunction clipAntimeridianInterpolate(from, to, direction, stream) {\n var phi;\n if (from == null) {\n phi = direction * halfPi;\n stream.point(-pi, phi);\n stream.point(0, phi);\n stream.point(pi, phi);\n stream.point(pi, 0);\n stream.point(pi, -phi);\n stream.point(0, -phi);\n stream.point(-pi, -phi);\n stream.point(-pi, 0);\n stream.point(-pi, phi);\n } else if (abs(from[0] - to[0]) > epsilon) {\n var lambda = from[0] < to[0] ? pi : -pi;\n phi = direction * lambda / 2;\n stream.point(-lambda, phi);\n stream.point(0, phi);\n stream.point(lambda, phi);\n } else {\n stream.point(to[0], to[1]);\n }\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/circle.js\n\n\n\n\n\n\n/* harmony default export */ var clip_circle = (function(radius, delta) {\n var cr = cos(radius),\n smallRadius = cr > 0,\n notHemisphere = abs(cr) > epsilon; // TODO optimise for this common case\n\n function interpolate(from, to, direction, stream) {\n circleStream(stream, radius, delta, direction, from, to);\n }\n\n function visible(lambda, phi) {\n return cos(lambda) * cos(phi) > cr;\n }\n\n // Takes a line and cuts into visible segments. Return values used for polygon\n // clipping: 0 - there were intersections or the line was empty; 1 - no\n // intersections 2 - there were intersections, and the first and last segments\n // should be rejoined.\n function clipLine(stream) {\n var point0, // previous point\n c0, // code for previous point\n v0, // visibility of previous point\n v00, // visibility of first point\n clean; // no intersections\n return {\n lineStart: function() {\n v00 = v0 = false;\n clean = 1;\n },\n point: function(lambda, phi) {\n var point1 = [lambda, phi],\n point2,\n v = visible(lambda, phi),\n c = smallRadius\n ? v ? 0 : code(lambda, phi)\n : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0;\n if (!point0 && (v00 = v0 = v)) stream.lineStart();\n // Handle degeneracies.\n // TODO ignore if not clipping polygons.\n if (v !== v0) {\n point2 = intersect(point0, point1);\n if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {\n point1[0] += epsilon;\n point1[1] += epsilon;\n v = visible(point1[0], point1[1]);\n }\n }\n if (v !== v0) {\n clean = 0;\n if (v) {\n // outside going in\n stream.lineStart();\n point2 = intersect(point1, point0);\n stream.point(point2[0], point2[1]);\n } else {\n // inside going out\n point2 = intersect(point0, point1);\n stream.point(point2[0], point2[1]);\n stream.lineEnd();\n }\n point0 = point2;\n } else if (notHemisphere && point0 && smallRadius ^ v) {\n var t;\n // If the codes for two points are different, or are both zero,\n // and there this segment intersects with the small circle.\n if (!(c & c0) && (t = intersect(point1, point0, true))) {\n clean = 0;\n if (smallRadius) {\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n } else {\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n }\n }\n }\n if (v && (!point0 || !pointEqual(point0, point1))) {\n stream.point(point1[0], point1[1]);\n }\n point0 = point1, v0 = v, c0 = c;\n },\n lineEnd: function() {\n if (v0) stream.lineEnd();\n point0 = null;\n },\n // Rejoin first and last segments if there were intersections and the first\n // and last points were visible.\n clean: function() {\n return clean | ((v00 && v0) << 1);\n }\n };\n }\n\n // Intersects the great circle between a and b with the clip circle.\n function intersect(a, b, two) {\n var pa = cartesian_cartesian(a),\n pb = cartesian_cartesian(b);\n\n // We have two planes, n1.p = d1 and n2.p = d2.\n // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).\n var n1 = [1, 0, 0], // normal\n n2 = cartesianCross(pa, pb),\n n2n2 = cartesianDot(n2, n2),\n n1n2 = n2[0], // cartesianDot(n1, n2),\n determinant = n2n2 - n1n2 * n1n2;\n\n // Two polar points.\n if (!determinant) return !two && a;\n\n var c1 = cr * n2n2 / determinant,\n c2 = -cr * n1n2 / determinant,\n n1xn2 = cartesianCross(n1, n2),\n A = cartesianScale(n1, c1),\n B = cartesianScale(n2, c2);\n cartesianAddInPlace(A, B);\n\n // Solve |p(t)|^2 = 1.\n var u = n1xn2,\n w = cartesianDot(A, u),\n uu = cartesianDot(u, u),\n t2 = w * w - uu * (cartesianDot(A, A) - 1);\n\n if (t2 < 0) return;\n\n var t = sqrt(t2),\n q = cartesianScale(u, (-w - t) / uu);\n cartesianAddInPlace(q, A);\n q = cartesian_spherical(q);\n\n if (!two) return q;\n\n // Two intersection points.\n var lambda0 = a[0],\n lambda1 = b[0],\n phi0 = a[1],\n phi1 = b[1],\n z;\n\n if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;\n\n var delta = lambda1 - lambda0,\n polar = abs(delta - pi) < epsilon,\n meridian = polar || delta < epsilon;\n\n if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;\n\n // Check that the first point is between a and b.\n if (meridian\n ? polar\n ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon ? phi0 : phi1)\n : phi0 <= q[1] && q[1] <= phi1\n : delta > pi ^ (lambda0 <= q[0] && q[0] <= lambda1)) {\n var q1 = cartesianScale(u, (-w + t) / uu);\n cartesianAddInPlace(q1, A);\n return [q, cartesian_spherical(q1)];\n }\n }\n\n // Generates a 4-bit vector representing the location of a point relative to\n // the small circle's bounding box.\n function code(lambda, phi) {\n var r = smallRadius ? radius : pi - radius,\n code = 0;\n if (lambda < -r) code |= 1; // left\n else if (lambda > r) code |= 2; // right\n if (phi < -r) code |= 4; // below\n else if (phi > r) code |= 8; // above\n return code;\n }\n\n return src_clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/transform.js\n/* harmony default export */ var src_transform = (function(methods) {\n return {\n stream: transformer(methods)\n };\n});\n\nfunction transformer(methods) {\n return function(stream) {\n var s = new TransformStream;\n for (var key in methods) s[key] = methods[key];\n s.stream = stream;\n return s;\n };\n}\n\nfunction TransformStream() {}\n\nTransformStream.prototype = {\n constructor: TransformStream,\n point: function(x, y) { this.stream.point(x, y); },\n sphere: function() { this.stream.sphere(); },\n lineStart: function() { this.stream.lineStart(); },\n lineEnd: function() { this.stream.lineEnd(); },\n polygonStart: function() { this.stream.polygonStart(); },\n polygonEnd: function() { this.stream.polygonEnd(); }\n};\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/fit.js\n\n\n\nfunction fitExtent(projection, extent, object) {\n var w = extent[1][0] - extent[0][0],\n h = extent[1][1] - extent[0][1],\n clip = projection.clipExtent && projection.clipExtent();\n\n projection\n .scale(150)\n .translate([0, 0]);\n\n if (clip != null) projection.clipExtent(null);\n\n src_stream(object, projection.stream(path_bounds));\n\n var b = path_bounds.result(),\n k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),\n x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,\n y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;\n\n if (clip != null) projection.clipExtent(clip);\n\n return projection\n .scale(k * 150)\n .translate([x, y]);\n}\n\nfunction fitSize(projection, size, object) {\n return fitExtent(projection, [[0, 0], size], object);\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/resample.js\n\n\n\n\nvar maxDepth = 16, // maximum depth of subdivision\n cosMinDistance = cos(30 * radians); // cos(minimum angular distance)\n\n/* harmony default export */ var resample = (function(project, delta2) {\n return +delta2 ? resample_resample(project, delta2) : resampleNone(project);\n});\n\nfunction resampleNone(project) {\n return transformer({\n point: function(x, y) {\n x = project(x, y);\n this.stream.point(x[0], x[1]);\n }\n });\n}\n\nfunction resample_resample(project, delta2) {\n\n function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {\n var dx = x1 - x0,\n dy = y1 - y0,\n d2 = dx * dx + dy * dy;\n if (d2 > 4 * delta2 && depth--) {\n var a = a0 + a1,\n b = b0 + b1,\n c = c0 + c1,\n m = sqrt(a * a + b * b + c * c),\n phi2 = asin(c /= m),\n lambda2 = abs(abs(c) - 1) < epsilon || abs(lambda0 - lambda1) < epsilon ? (lambda0 + lambda1) / 2 : atan2(b, a),\n p = project(lambda2, phi2),\n x2 = p[0],\n y2 = p[1],\n dx2 = x2 - x0,\n dy2 = y2 - y0,\n dz = dy * dx2 - dx * dy2;\n if (dz * dz / d2 > delta2 // perpendicular projected distance\n || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end\n || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);\n stream.point(x2, y2);\n resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);\n }\n }\n }\n return function(stream) {\n var lambda00, x00, y00, a00, b00, c00, // first point\n lambda0, x0, y0, a0, b0, c0; // previous point\n\n var resampleStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },\n polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }\n };\n\n function point(x, y) {\n x = project(x, y);\n stream.point(x[0], x[1]);\n }\n\n function lineStart() {\n x0 = NaN;\n resampleStream.point = linePoint;\n stream.lineStart();\n }\n\n function linePoint(lambda, phi) {\n var c = cartesian_cartesian([lambda, phi]), p = project(lambda, phi);\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);\n stream.point(x0, y0);\n }\n\n function lineEnd() {\n resampleStream.point = point;\n stream.lineEnd();\n }\n\n function ringStart() {\n lineStart();\n resampleStream.point = ringPoint;\n resampleStream.lineEnd = ringEnd;\n }\n\n function ringPoint(lambda, phi) {\n linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;\n resampleStream.point = linePoint;\n }\n\n function ringEnd() {\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);\n resampleStream.lineEnd = lineEnd;\n lineEnd();\n }\n\n return resampleStream;\n };\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/index.js\n\n\n\n\n\n\n\n\n\n\n\nvar transformRadians = transformer({\n point: function(x, y) {\n this.stream.point(x * radians, y * radians);\n }\n});\n\nfunction projection_projection(project) {\n return projectionMutator(function() { return project; })();\n}\n\nfunction projectionMutator(projectAt) {\n var project,\n k = 150, // scale\n x = 480, y = 250, // translate\n dx, dy, lambda = 0, phi = 0, // center\n deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate\n theta = null, preclip = clip_antimeridian, // clip angle\n x0 = null, y0, x1, y1, postclip = src_identity, // clip extent\n delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision\n cache,\n cacheStream;\n\n function projection(point) {\n point = projectRotate(point[0] * radians, point[1] * radians);\n return [point[0] * k + dx, dy - point[1] * k];\n }\n\n function invert(point) {\n point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);\n return point && [point[0] * degrees, point[1] * degrees];\n }\n\n function projectTransform(x, y) {\n return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];\n }\n\n projection.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));\n };\n\n projection.clipAngle = function(_) {\n return arguments.length ? (preclip = +_ ? clip_circle(theta = _ * radians, 6 * radians) : (theta = null, clip_antimeridian), reset()) : theta * degrees;\n };\n\n projection.clipExtent = function(_) {\n return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, src_identity) : extent_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n projection.scale = function(_) {\n return arguments.length ? (k = +_, recenter()) : k;\n };\n\n projection.translate = function(_) {\n return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];\n };\n\n projection.center = function(_) {\n return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees];\n };\n\n projection.rotate = function(_) {\n return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees];\n };\n\n projection.precision = function(_) {\n return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);\n };\n\n projection.fitExtent = function(extent, object) {\n return fitExtent(projection, extent, object);\n };\n\n projection.fitSize = function(size, object) {\n return fitSize(projection, size, object);\n };\n\n function recenter() {\n projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);\n var center = project(lambda, phi);\n dx = x - center[0] * k;\n dy = y + center[1] * k;\n return reset();\n }\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return function() {\n project = projectAt.apply(this, arguments);\n projection.invert = project.invert && invert;\n return recenter();\n };\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conic.js\n\n\n\nfunction conicProjection(projectAt) {\n var phi0 = 0,\n phi1 = pi / 3,\n m = projectionMutator(projectAt),\n p = m(phi0, phi1);\n\n p.parallels = function(_) {\n return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees, phi1 * degrees];\n };\n\n return p;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/cylindricalEqualArea.js\n\n\nfunction cylindricalEqualAreaRaw(phi0) {\n var cosPhi0 = cos(phi0);\n\n function forward(lambda, phi) {\n return [lambda * cosPhi0, sin(phi) / cosPhi0];\n }\n\n forward.invert = function(x, y) {\n return [x / cosPhi0, asin(y * cosPhi0)];\n };\n\n return forward;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conicEqualArea.js\n\n\n\n\nfunction conicEqualAreaRaw(y0, y1) {\n var sy0 = sin(y0), n = (sy0 + sin(y1)) / 2;\n\n // Are the parallels symmetrical around the Equator?\n if (abs(n) < epsilon) return cylindricalEqualAreaRaw(y0);\n\n var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;\n\n function project(x, y) {\n var r = sqrt(c - 2 * n * sin(y)) / n;\n return [r * sin(x *= n), r0 - r * cos(x)];\n }\n\n project.invert = function(x, y) {\n var r0y = r0 - y;\n return [atan2(x, abs(r0y)) / n * math_sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];\n };\n\n return project;\n}\n\n/* harmony default export */ var conicEqualArea = (function() {\n return conicProjection(conicEqualAreaRaw)\n .scale(155.424)\n .center([0, 33.6442]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/albers.js\n\n\n/* harmony default export */ var albers = (function() {\n return conicEqualArea()\n .parallels([29.5, 45.5])\n .scale(1070)\n .translate([480, 250])\n .rotate([96, 0])\n .center([-0.6, 38.7]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/albersUsa.js\n\n\n\n\n\n// The projections must have mutually exclusive clip regions on the sphere,\n// as this will avoid emitting interleaving lines and polygons.\nfunction multiplex(streams) {\n var n = streams.length;\n return {\n point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },\n sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },\n lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },\n lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },\n polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },\n polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }\n };\n}\n\n// A composite projection for the United States, configured by default for\n// 960×500. The projection also works quite well at 960×600 if you change the\n// scale to 1285 and adjust the translate accordingly. The set of standard\n// parallels for each region comes from USGS, which is published here:\n// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers\n/* harmony default export */ var projection_albersUsa = (function() {\n var cache,\n cacheStream,\n lower48 = albers(), lower48Point,\n alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338\n hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007\n point, pointStream = {point: function(x, y) { point = [x, y]; }};\n\n function albersUsa(coordinates) {\n var x = coordinates[0], y = coordinates[1];\n return point = null,\n (lower48Point.point(x, y), point)\n || (alaskaPoint.point(x, y), point)\n || (hawaiiPoint.point(x, y), point);\n }\n\n albersUsa.invert = function(coordinates) {\n var k = lower48.scale(),\n t = lower48.translate(),\n x = (coordinates[0] - t[0]) / k,\n y = (coordinates[1] - t[1]) / k;\n return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska\n : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii\n : lower48).invert(coordinates);\n };\n\n albersUsa.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);\n };\n\n albersUsa.precision = function(_) {\n if (!arguments.length) return lower48.precision();\n lower48.precision(_), alaska.precision(_), hawaii.precision(_);\n return reset();\n };\n\n albersUsa.scale = function(_) {\n if (!arguments.length) return lower48.scale();\n lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);\n return albersUsa.translate(lower48.translate());\n };\n\n albersUsa.translate = function(_) {\n if (!arguments.length) return lower48.translate();\n var k = lower48.scale(), x = +_[0], y = +_[1];\n\n lower48Point = lower48\n .translate(_)\n .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])\n .stream(pointStream);\n\n alaskaPoint = alaska\n .translate([x - 0.307 * k, y + 0.201 * k])\n .clipExtent([[x - 0.425 * k + epsilon, y + 0.120 * k + epsilon], [x - 0.214 * k - epsilon, y + 0.234 * k - epsilon]])\n .stream(pointStream);\n\n hawaiiPoint = hawaii\n .translate([x - 0.205 * k, y + 0.212 * k])\n .clipExtent([[x - 0.214 * k + epsilon, y + 0.166 * k + epsilon], [x - 0.115 * k - epsilon, y + 0.234 * k - epsilon]])\n .stream(pointStream);\n\n return reset();\n };\n\n albersUsa.fitExtent = function(extent, object) {\n return fitExtent(albersUsa, extent, object);\n };\n\n albersUsa.fitSize = function(size, object) {\n return fitSize(albersUsa, size, object);\n };\n\n function reset() {\n cache = cacheStream = null;\n return albersUsa;\n }\n\n return albersUsa.scale(1070);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/azimuthal.js\n\n\nfunction azimuthalRaw(scale) {\n return function(x, y) {\n var cx = cos(x),\n cy = cos(y),\n k = scale(cx * cy);\n return [\n k * cy * sin(x),\n k * sin(y)\n ];\n }\n}\n\nfunction azimuthalInvert(angle) {\n return function(x, y) {\n var z = sqrt(x * x + y * y),\n c = angle(z),\n sc = sin(c),\n cc = cos(c);\n return [\n atan2(x * sc, z * cc),\n asin(z && y * sc / z)\n ];\n }\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/azimuthalEqualArea.js\n\n\n\n\nvar azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {\n return sqrt(2 / (1 + cxcy));\n});\n\nazimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {\n return 2 * asin(z / 2);\n});\n\n/* harmony default export */ var azimuthalEqualArea = (function() {\n return projection_projection(azimuthalEqualAreaRaw)\n .scale(124.75)\n .clipAngle(180 - 1e-3);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/azimuthalEquidistant.js\n\n\n\n\nvar azimuthalEquidistantRaw = azimuthalRaw(function(c) {\n return (c = acos(c)) && c / sin(c);\n});\n\nazimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {\n return z;\n});\n\n/* harmony default export */ var azimuthalEquidistant = (function() {\n return projection_projection(azimuthalEquidistantRaw)\n .scale(79.4188)\n .clipAngle(180 - 1e-3);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/mercator.js\n\n\n\n\nfunction mercatorRaw(lambda, phi) {\n return [lambda, log(tan((halfPi + phi) / 2))];\n}\n\nmercatorRaw.invert = function(x, y) {\n return [x, 2 * atan(exp(y)) - halfPi];\n};\n\n/* harmony default export */ var mercator = (function() {\n return mercatorProjection(mercatorRaw)\n .scale(961 / tau);\n});\n\nfunction mercatorProjection(project) {\n var m = projection_projection(project),\n center = m.center,\n scale = m.scale,\n translate = m.translate,\n clipExtent = m.clipExtent,\n x0 = null, y0, x1, y1; // clip extent\n\n m.scale = function(_) {\n return arguments.length ? (scale(_), reclip()) : scale();\n };\n\n m.translate = function(_) {\n return arguments.length ? (translate(_), reclip()) : translate();\n };\n\n m.center = function(_) {\n return arguments.length ? (center(_), reclip()) : center();\n };\n\n m.clipExtent = function(_) {\n return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n function reclip() {\n var k = pi * scale(),\n t = m(src_rotation(m.rotate()).invert([0, 0]));\n return clipExtent(x0 == null\n ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw\n ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]\n : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);\n }\n\n return reclip();\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conicConformal.js\n\n\n\n\nfunction tany(y) {\n return tan((halfPi + y) / 2);\n}\n\nfunction conicConformalRaw(y0, y1) {\n var cy0 = cos(y0),\n n = y0 === y1 ? sin(y0) : log(cy0 / cos(y1)) / log(tany(y1) / tany(y0)),\n f = cy0 * pow(tany(y0), n) / n;\n\n if (!n) return mercatorRaw;\n\n function project(x, y) {\n if (f > 0) { if (y < -halfPi + epsilon) y = -halfPi + epsilon; }\n else { if (y > halfPi - epsilon) y = halfPi - epsilon; }\n var r = f / pow(tany(y), n);\n return [r * sin(n * x), f - r * cos(n * x)];\n }\n\n project.invert = function(x, y) {\n var fy = f - y, r = math_sign(n) * sqrt(x * x + fy * fy);\n return [atan2(x, abs(fy)) / n * math_sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi];\n };\n\n return project;\n}\n\n/* harmony default export */ var conicConformal = (function() {\n return conicProjection(conicConformalRaw)\n .scale(109.5)\n .parallels([30, 30]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/equirectangular.js\n\n\nfunction equirectangularRaw(lambda, phi) {\n return [lambda, phi];\n}\n\nequirectangularRaw.invert = equirectangularRaw;\n\n/* harmony default export */ var equirectangular = (function() {\n return projection_projection(equirectangularRaw)\n .scale(152.63);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conicEquidistant.js\n\n\n\n\nfunction conicEquidistantRaw(y0, y1) {\n var cy0 = cos(y0),\n n = y0 === y1 ? sin(y0) : (cy0 - cos(y1)) / (y1 - y0),\n g = cy0 / n + y0;\n\n if (abs(n) < epsilon) return equirectangularRaw;\n\n function project(x, y) {\n var gy = g - y, nx = n * x;\n return [gy * sin(nx), g - gy * cos(nx)];\n }\n\n project.invert = function(x, y) {\n var gy = g - y;\n return [atan2(x, abs(gy)) / n * math_sign(gy), g - math_sign(n) * sqrt(x * x + gy * gy)];\n };\n\n return project;\n}\n\n/* harmony default export */ var conicEquidistant = (function() {\n return conicProjection(conicEquidistantRaw)\n .scale(131.154)\n .center([0, 13.9389]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/gnomonic.js\n\n\n\n\nfunction gnomonicRaw(x, y) {\n var cy = cos(y), k = cos(x) * cy;\n return [cy * sin(x) / k, sin(y) / k];\n}\n\ngnomonicRaw.invert = azimuthalInvert(atan);\n\n/* harmony default export */ var gnomonic = (function() {\n return projection_projection(gnomonicRaw)\n .scale(144.049)\n .clipAngle(60);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/identity.js\n\n\n\n\n\nfunction scaleTranslate(kx, ky, tx, ty) {\n return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? src_identity : transformer({\n point: function(x, y) {\n this.stream.point(x * kx + tx, y * ky + ty);\n }\n });\n}\n\n/* harmony default export */ var projection_identity = (function() {\n var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = src_identity, // scale, translate and reflect\n x0 = null, y0, x1, y1, clip = src_identity, // clip extent\n cache,\n cacheStream,\n projection;\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return projection = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));\n },\n clipExtent: function(_) {\n return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, src_identity) : extent_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n },\n scale: function(_) {\n return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;\n },\n translate: function(_) {\n return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];\n },\n reflectX: function(_) {\n return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;\n },\n reflectY: function(_) {\n return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;\n },\n fitExtent: function(extent, object) {\n return fitExtent(projection, extent, object);\n },\n fitSize: function(size, object) {\n return fitSize(projection, size, object);\n }\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/naturalEarth1.js\n\n\n\nfunction naturalEarth1Raw(lambda, phi) {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n return [\n lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),\n phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))\n ];\n}\n\nnaturalEarth1Raw.invert = function(x, y) {\n var phi = y, i = 25, delta;\n do {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /\n (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));\n } while (abs(delta) > epsilon && --i > 0);\n return [\n x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),\n phi\n ];\n};\n\n/* harmony default export */ var naturalEarth1 = (function() {\n return projection_projection(naturalEarth1Raw)\n .scale(175.295);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/orthographic.js\n\n\n\n\nfunction orthographicRaw(x, y) {\n return [cos(y) * sin(x), sin(y)];\n}\n\northographicRaw.invert = azimuthalInvert(asin);\n\n/* harmony default export */ var orthographic = (function() {\n return projection_projection(orthographicRaw)\n .scale(249.5)\n .clipAngle(90 + epsilon);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/stereographic.js\n\n\n\n\nfunction stereographicRaw(x, y) {\n var cy = cos(y), k = 1 + cos(x) * cy;\n return [cy * sin(x) / k, sin(y) / k];\n}\n\nstereographicRaw.invert = azimuthalInvert(function(z) {\n return 2 * atan(z);\n});\n\n/* harmony default export */ var stereographic = (function() {\n return projection_projection(stereographicRaw)\n .scale(250)\n .clipAngle(142);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/transverseMercator.js\n\n\n\nfunction transverseMercatorRaw(lambda, phi) {\n return [log(tan((halfPi + phi) / 2)), -lambda];\n}\n\ntransverseMercatorRaw.invert = function(x, y) {\n return [-y, 2 * atan(exp(x)) - halfPi];\n};\n\n/* harmony default export */ var transverseMercator = (function() {\n var m = mercatorProjection(transverseMercatorRaw),\n center = m.center,\n rotate = m.rotate;\n\n m.center = function(_) {\n return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);\n };\n\n m.rotate = function(_) {\n return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);\n };\n\n return rotate([0, 0, 90])\n .scale(159.155);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/index.js\n\n\n\n\n // DEPRECATED! Use d3.geoIdentity().clipExtent(…).\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/buffer/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar helpers_main_es_earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar helpers_main_es_factors = {\n meters: helpers_main_es_earthRadius,\n metres: helpers_main_es_earthRadius,\n millimeters: helpers_main_es_earthRadius * 1000,\n millimetres: helpers_main_es_earthRadius * 1000,\n centimeters: helpers_main_es_earthRadius * 100,\n centimetres: helpers_main_es_earthRadius * 100,\n kilometers: helpers_main_es_earthRadius / 1000,\n kilometres: helpers_main_es_earthRadius / 1000,\n miles: helpers_main_es_earthRadius / 1609.344,\n nauticalmiles: helpers_main_es_earthRadius / 1852,\n inches: helpers_main_es_earthRadius * 39.370,\n yards: helpers_main_es_earthRadius / 1.0936,\n feet: helpers_main_es_earthRadius * 3.28084,\n radians: 1,\n degrees: helpers_main_es_earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar helpers_main_es_unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / helpers_main_es_earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar helpers_main_es_areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction _turf_helpers_main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers_main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) helpers_main_es_validateBBox(bbox);\n if (id) helpers_main_es_validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction _turf_helpers_main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers_main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) helpers_main_es_validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = _turf_helpers_main_es_point(coordinates).geometry; break;\n case 'LineString': geom = helpers_main_es_lineString(coordinates).geometry; break;\n case 'Polygon': geom = _turf_helpers_main_es_polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = helpers_main_es_multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = helpers_main_es_multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = helpers_main_es_multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction _turf_helpers_main_es_point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!helpers_main_es_isNumber(coordinates[0]) || !helpers_main_es_isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return _turf_helpers_main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction _turf_helpers_main_es_points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return helpers_main_es_featureCollection(coordinates.map(function (coords) {\n return _turf_helpers_main_es_point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction _turf_helpers_main_es_polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !helpers_main_es_isNumber(ring[0][0]) || !helpers_main_es_isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return _turf_helpers_main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction helpers_main_es_polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return helpers_main_es_featureCollection(coordinates.map(function (coords) {\n return _turf_helpers_main_es_polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction helpers_main_es_lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!helpers_main_es_isNumber(coordinates[0][1]) || !helpers_main_es_isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return _turf_helpers_main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction helpers_main_es_lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return helpers_main_es_featureCollection(coordinates.map(function (coords) {\n return helpers_main_es_lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction helpers_main_es_featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers_main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) helpers_main_es_validateBBox(bbox);\n if (id) helpers_main_es_validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction helpers_main_es_multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return _turf_helpers_main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction helpers_main_es_multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return _turf_helpers_main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction helpers_main_es_multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return _turf_helpers_main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction helpers_main_es_geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return _turf_helpers_main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction helpers_main_es_round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction helpers_main_es_radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = helpers_main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction helpers_main_es_lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = helpers_main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction helpers_main_es_lengthToDegrees(distance, units) {\n return helpers_main_es_radiansToDegrees(helpers_main_es_lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction helpers_main_es_bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction helpers_main_es_radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction helpers_main_es_degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction helpers_main_es_convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return helpers_main_es_radiansToLength(helpers_main_es_lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction helpers_main_es_convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = helpers_main_es_areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = helpers_main_es_areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction helpers_main_es_isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction helpers_main_es_isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction helpers_main_es_validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!helpers_main_es_isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction helpers_main_es_validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction helpers_main_es_radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction helpers_main_es_degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction helpers_main_es_distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction helpers_main_es_distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction helpers_main_es_radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction helpers_main_es_bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction helpers_main_es_convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/buffer/main.es.js\n\n\n\n\n\n\n\n\n/**\n * Calculates a buffer for input features for a given radius. Units supported are miles, kilometers, and degrees.\n *\n * When using a negative radius, the resulting geometry may be invalid if\n * it's too small compared to the radius magnitude. If the input is a\n * FeatureCollection, only valid members will be returned in the output\n * FeatureCollection - i.e., the output collection may have fewer members than\n * the input, or even be empty.\n *\n * @name buffer\n * @param {FeatureCollection|Geometry|Feature} geojson input to be buffered\n * @param {number} radius distance to draw the buffer (negative values are allowed)\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units=\"kilometers\"] any of the options supported by turf units\n * @param {number} [options.steps=64] number of steps\n * @returns {FeatureCollection|Feature|undefined} buffered features\n * @example\n * var point = turf.point([-90.548630, 14.616599]);\n * var buffered = turf.buffer(point, 500, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [point, buffered]\n */\nfunction main_es_buffer(geojson, radius, options) {\n // Optional params\n options = options || {};\n var units = options.units;\n var steps = options.steps || 64;\n\n // validation\n if (!geojson) throw new Error('geojson is required');\n if (typeof options !== 'object') throw new Error('options must be an object');\n if (typeof steps !== 'number') throw new Error('steps must be an number');\n\n // Allow negative buffers (\"erosion\") or zero-sized buffers (\"repair geometry\")\n if (radius === undefined) throw new Error('radius is required');\n if (steps <= 0) throw new Error('steps must be greater than 0');\n\n // default params\n steps = steps || 64;\n units = units || 'kilometers';\n\n var results = [];\n switch (geojson.type) {\n case 'GeometryCollection':\n Object(meta_main_es[\"d\" /* geomEach */])(geojson, function (geometry) {\n var buffered = bufferFeature(geometry, radius, units, steps);\n if (buffered) results.push(buffered);\n });\n return helpers_main_es_featureCollection(results);\n case 'FeatureCollection':\n Object(meta_main_es[\"b\" /* featureEach */])(geojson, function (feature$$1) {\n var multiBuffered = bufferFeature(feature$$1, radius, units, steps);\n if (multiBuffered) {\n Object(meta_main_es[\"b\" /* featureEach */])(multiBuffered, function (buffered) {\n if (buffered) results.push(buffered);\n });\n }\n });\n return helpers_main_es_featureCollection(results);\n }\n return bufferFeature(geojson, radius, units, steps);\n}\n\n/**\n * Buffer single Feature/Geometry\n *\n * @private\n * @param {Feature} geojson input to be buffered\n * @param {number} radius distance to draw the buffer\n * @param {string} [units='kilometers'] any of the options supported by turf units\n * @param {number} [steps=64] number of steps\n * @returns {Feature} buffered feature\n */\nfunction bufferFeature(geojson, radius, units, steps) {\n var properties = geojson.properties || {};\n var geometry = (geojson.type === 'Feature') ? geojson.geometry : geojson;\n\n // Geometry Types faster than jsts\n if (geometry.type === 'GeometryCollection') {\n var results = [];\n Object(meta_main_es[\"d\" /* geomEach */])(geojson, function (geometry) {\n var buffered = bufferFeature(geometry, radius, units, steps);\n if (buffered) results.push(buffered);\n });\n return helpers_main_es_featureCollection(results);\n }\n\n // Project GeoJSON to Transverse Mercator projection (convert to Meters)\n var projected;\n var bbox = Object(main_es[\"default\"])(geojson);\n var needsTransverseMercator = bbox[1] > 50 && bbox[3] > 50;\n\n if (needsTransverseMercator) {\n projected = {\n type: geometry.type,\n coordinates: projectCoords(geometry.coordinates, defineProjection(geometry))\n };\n } else {\n projected = toMercator(geometry);\n }\n\n // JSTS buffer operation\n var reader = new jsts_min[\"GeoJSONReader\"]();\n var geom = reader.read(projected);\n var distance = helpers_main_es_radiansToLength(helpers_main_es_lengthToRadians(radius, units), 'meters');\n var buffered = jsts_min[\"BufferOp\"].bufferOp(geom, distance);\n var writer = new jsts_min[\"GeoJSONWriter\"]();\n buffered = writer.write(buffered);\n\n // Detect if empty geometries\n if (coordsIsNaN(buffered.coordinates)) return undefined;\n\n // Unproject coordinates (convert to Degrees)\n var result;\n if (needsTransverseMercator) {\n result = {\n type: buffered.type,\n coordinates: unprojectCoords(buffered.coordinates, defineProjection(geometry))\n };\n } else {\n result = toWgs84(buffered);\n }\n\n return (result.geometry) ? result : _turf_helpers_main_es_feature(result, properties);\n}\n\n/**\n * Coordinates isNaN\n *\n * @private\n * @param {Array} coords GeoJSON Coordinates\n * @returns {boolean} if NaN exists\n */\nfunction coordsIsNaN(coords) {\n if (Array.isArray(coords[0])) return coordsIsNaN(coords[0]);\n return isNaN(coords[0]);\n}\n\n/**\n * Project coordinates to projection\n *\n * @private\n * @param {Array} coords to project\n * @param {GeoProjection} proj D3 Geo Projection\n * @returns {Array} projected coordinates\n */\nfunction projectCoords(coords, proj) {\n if (typeof coords[0] !== 'object') return proj(coords);\n return coords.map(function (coord) {\n return projectCoords(coord, proj);\n });\n}\n\n/**\n * Un-Project coordinates to projection\n *\n * @private\n * @param {Array} coords to un-project\n * @param {GeoProjection} proj D3 Geo Projection\n * @returns {Array} un-projected coordinates\n */\nfunction unprojectCoords(coords, proj) {\n if (typeof coords[0] !== 'object') return proj.invert(coords);\n return coords.map(function (coord) {\n return unprojectCoords(coord, proj);\n });\n}\n\n/**\n * Define Transverse Mercator projection\n *\n * @private\n * @param {Geometry|Feature} geojson Base projection on center of GeoJSON\n * @returns {GeoProjection} D3 Geo Transverse Mercator Projection\n */\nfunction defineProjection(geojson) {\n var coords = center_main_es(geojson).geometry.coordinates.reverse();\n var rotate = coords.map(function (coord) { return -coord; });\n return transverseMercator()\n .center(coords)\n .rotate(rotate)\n .scale(helpers_main_es_earthRadius);\n}\n\n/* harmony default export */ var buffer_main_es = __webpack_exports__[\"default\"] = (main_es_buffer);\n\n\n//# sourceURL=webpack:///./node_modules/@turf/buffer/main.es.js_+_95_modules?")}]); \ No newline at end of file +!function(e){var n={};function t(r){if(n[r])return n[r].exports;var o=n[r]={i:r,l:!1,exports:{}};return e[r].call(o.exports,o,o.exports,t),o.l=!0,o.exports}t.m=e,t.c=n,t.d=function(e,n,r){t.o(e,n)||Object.defineProperty(e,n,{enumerable:!0,get:r})},t.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},t.t=function(e,n){if(1&n&&(e=t(e)),8&n)return e;if(4&n&&"object"==typeof e&&e&&e.__esModule)return e;var r=Object.create(null);if(t.r(r),Object.defineProperty(r,"default",{enumerable:!0,value:e}),2&n&&"string"!=typeof e)for(var o in e)t.d(r,o,function(n){return e[n]}.bind(null,o));return 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,n){return Object.prototype.hasOwnProperty.call(e,n)},t.p="",t(t.s=18)}([function(module,__webpack_exports__,__webpack_require__){"use strict";eval("\n// CONCATENATED MODULE: ./node_modules/@turf/meta/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar factors = {\n meters: earthRadius,\n metres: earthRadius,\n millimeters: earthRadius * 1000,\n millimetres: earthRadius * 1000,\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n kilometers: earthRadius / 1000,\n kilometres: earthRadius / 1000,\n miles: earthRadius / 1609.344,\n nauticalmiles: earthRadius / 1852,\n inches: earthRadius * 39.370,\n yards: earthRadius / 1.0936,\n feet: earthRadius * 3.28084,\n radians: 1,\n degrees: earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = point(coordinates).geometry; break;\n case 'LineString': geom = lineString(coordinates).geometry; break;\n case 'Polygon': geom = polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/meta/main.es.js\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"a\", function() { return coordEach; });\n/* unused harmony export coordReduce */\n/* unused harmony export propEach */\n/* unused harmony export propReduce */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"b\", function() { return featureEach; });\n/* unused harmony export featureReduce */\n/* unused harmony export coordAll */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"d\", function() { return geomEach; });\n/* unused harmony export geomReduce */\n/* harmony export (binding) */ __webpack_require__.d(__webpack_exports__, \"c\", function() { return flattenEach; });\n/* unused harmony export flattenReduce */\n/* unused harmony export segmentEach */\n/* unused harmony export segmentReduce */\n/* unused harmony export lineEach */\n/* unused harmony export lineReduce */\n/* unused harmony export findSegment */\n/* unused harmony export findPoint */\n\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n if (geomType === 'MultiPolygon') geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature$$1, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature$$1.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature$$1.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n if (coordEach(feature$$1, function (currentCoord, coordIndex, featureIndexCoord, mutliPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined) {\n previousCoords = currentCoord;\n return;\n }\n var currentSegment = lineString([previousCoords, currentCoord], feature$$1.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature$$1, featureIndex, multiFeatureIndex) {\n if (feature$$1.geometry === null) return;\n var type = feature$$1.geometry.type;\n var coords = feature$$1.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature$$1, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(lineString(coords[geometryIndex], feature$$1.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n\n\n\n//# sourceURL=webpack:///./node_modules/@turf/meta/main.es.js_+_1_modules?")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\n/**\n * @module helpers\n */\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n *\n * @memberof helpers\n * @type {number}\n */\nexports.earthRadius = 6371008.8;\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n *\n * @memberof helpers\n * @type {Object}\n */\nexports.factors = {\n centimeters: exports.earthRadius * 100,\n centimetres: exports.earthRadius * 100,\n degrees: exports.earthRadius / 111325,\n feet: exports.earthRadius * 3.28084,\n inches: exports.earthRadius * 39.370,\n kilometers: exports.earthRadius / 1000,\n kilometres: exports.earthRadius / 1000,\n meters: exports.earthRadius,\n metres: exports.earthRadius,\n miles: exports.earthRadius / 1609.344,\n millimeters: exports.earthRadius * 1000,\n millimetres: exports.earthRadius * 1000,\n nauticalmiles: exports.earthRadius / 1852,\n radians: 1,\n yards: exports.earthRadius / 1.0936,\n};\n/**\n * Units of measurement factors based on 1 meter.\n *\n * @memberof helpers\n * @type {Object}\n */\nexports.unitsFactors = {\n centimeters: 100,\n centimetres: 100,\n degrees: 1 / 111325,\n feet: 3.28084,\n inches: 39.370,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n meters: 1,\n metres: 1,\n miles: 1 / 1609.344,\n millimeters: 1000,\n millimetres: 1000,\n nauticalmiles: 1 / 1852,\n radians: 1 / exports.earthRadius,\n yards: 1 / 1.0936,\n};\n/**\n * Area of measurement factors based on 1 square meter.\n *\n * @memberof helpers\n * @type {Object}\n */\nexports.areaFactors = {\n acres: 0.000247105,\n centimeters: 10000,\n centimetres: 10000,\n feet: 10.763910417,\n inches: 1550.003100006,\n kilometers: 0.000001,\n kilometres: 0.000001,\n meters: 1,\n metres: 1,\n miles: 3.86e-7,\n millimeters: 1000000,\n millimetres: 1000000,\n yards: 1.195990046,\n};\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * "type": "Point",\n * "coordinates": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction feature(geom, properties, options) {\n if (options === void 0) { options = {}; }\n var feat = { type: "Feature" };\n if (options.id === 0 || options.id) {\n feat.id = options.id;\n }\n if (options.bbox) {\n feat.bbox = options.bbox;\n }\n feat.properties = properties || {};\n feat.geometry = geom;\n return feat;\n}\nexports.feature = feature;\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = "Point";\n * var coordinates = [110, 50];\n * var geometry = turf.geometry(type, coordinates);\n * // => geometry\n */\nfunction geometry(type, coordinates, options) {\n if (options === void 0) { options = {}; }\n switch (type) {\n case "Point": return point(coordinates).geometry;\n case "LineString": return lineString(coordinates).geometry;\n case "Polygon": return polygon(coordinates).geometry;\n case "MultiPoint": return multiPoint(coordinates).geometry;\n case "MultiLineString": return multiLineString(coordinates).geometry;\n case "MultiPolygon": return multiPolygon(coordinates).geometry;\n default: throw new Error(type + " is invalid");\n }\n}\nexports.geometry = geometry;\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction point(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "Point",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.point = point;\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north]\n * associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction points(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n return featureCollection(coordinates.map(function (coords) {\n return point(coords, properties);\n }), options);\n}\nexports.points = points;\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: \'poly1\' });\n *\n * //=polygon\n */\nfunction polygon(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n for (var _i = 0, coordinates_1 = coordinates; _i < coordinates_1.length; _i++) {\n var ring = coordinates_1[_i];\n if (ring.length < 4) {\n throw new Error("Each LinearRing of a Polygon must have 4 or more Positions.");\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error("First and last Position are not equivalent.");\n }\n }\n }\n var geom = {\n type: "Polygon",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.polygon = polygon;\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n return featureCollection(coordinates.map(function (coords) {\n return polygon(coords, properties);\n }), options);\n}\nexports.polygons = polygons;\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: \'line 1\'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: \'line 2\'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n if (coordinates.length < 2) {\n throw new Error("coordinates must be an array of two or more positions");\n }\n var geom = {\n type: "LineString",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.lineString = lineString;\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north]\n * associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\nexports.lineStrings = lineStrings;\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: \'Location A\'});\n * var locationB = turf.point([-75.833, 39.284], {name: \'Location B\'});\n * var locationC = turf.point([-75.534, 39.123], {name: \'Location C\'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n if (options === void 0) { options = {}; }\n var fc = { type: "FeatureCollection" };\n if (options.id) {\n fc.id = options.id;\n }\n if (options.bbox) {\n fc.bbox = options.bbox;\n }\n fc.features = features;\n return fc;\n}\nexports.featureCollection = featureCollection;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "MultiLineString",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.multiLineString = multiLineString;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "MultiPoint",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.multiPoint = multiPoint;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "MultiPolygon",\n coordinates: coordinates,\n };\n return feature(geom, properties, options);\n}\nexports.multiPolygon = multiPolygon;\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = turf.geometry("Point", [100, 0]);\n * var line = turf.geometry("LineString", [[101, 0], [102, 1]]);\n * var collection = turf.geometryCollection([pt, line]);\n *\n * // => collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (options === void 0) { options = {}; }\n var geom = {\n type: "GeometryCollection",\n geometries: geometries,\n };\n return feature(geom, properties, options);\n}\nexports.geometryCollection = geometryCollection;\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (precision === void 0) { precision = 0; }\n if (precision && !(precision >= 0)) {\n throw new Error("precision must be a positive number");\n }\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\nexports.round = round;\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres,\n * meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (units === void 0) { units = "kilometers"; }\n var factor = exports.factors[units];\n if (!factor) {\n throw new Error(units + " units is invalid");\n }\n return radians * factor;\n}\nexports.radiansToLength = radiansToLength;\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres,\n * meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (units === void 0) { units = "kilometers"; }\n var factor = exports.factors[units];\n if (!factor) {\n throw new Error(units + " units is invalid");\n }\n return distance / factor;\n}\nexports.lengthToRadians = lengthToRadians;\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units="kilometers"] can be degrees, radians, miles, or kilometers inches, yards, metres,\n * meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\nexports.lengthToDegrees = lengthToDegrees;\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n var angle = bearing % 360;\n if (angle < 0) {\n angle += 360;\n }\n return angle;\n}\nexports.bearingToAzimuth = bearingToAzimuth;\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\nexports.radiansToDegrees = radiansToDegrees;\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\nexports.degreesToRadians = degreesToRadians;\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {Units} [originalUnit="kilometers"] of the length\n * @param {Units} [finalUnit="kilometers"] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (originalUnit === void 0) { originalUnit = "kilometers"; }\n if (finalUnit === void 0) { finalUnit = "kilometers"; }\n if (!(length >= 0)) {\n throw new Error("length must be a positive number");\n }\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit);\n}\nexports.convertLength = convertLength;\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {Units} [originalUnit="meters"] of the distance\n * @param {Units} [finalUnit="kilometers"] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (originalUnit === void 0) { originalUnit = "meters"; }\n if (finalUnit === void 0) { finalUnit = "kilometers"; }\n if (!(area >= 0)) {\n throw new Error("area must be a positive number");\n }\n var startFactor = exports.areaFactors[originalUnit];\n if (!startFactor) {\n throw new Error("invalid original units");\n }\n var finalFactor = exports.areaFactors[finalUnit];\n if (!finalFactor) {\n throw new Error("invalid final units");\n }\n return (area / startFactor) * finalFactor;\n}\nexports.convertArea = convertArea;\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber(\'foo\')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num) && !/^\\s*$/.test(num);\n}\nexports.isNumber = isNumber;\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject(\'foo\')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\nexports.isObject = isObject;\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox(\'Foo\')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) {\n throw new Error("bbox is required");\n }\n if (!Array.isArray(bbox)) {\n throw new Error("bbox must be an Array");\n }\n if (bbox.length !== 4 && bbox.length !== 6) {\n throw new Error("bbox must be an Array of 4 or 6 numbers");\n }\n bbox.forEach(function (num) {\n if (!isNumber(num)) {\n throw new Error("bbox must only contain numbers");\n }\n });\n}\nexports.validateBBox = validateBBox;\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId(\'Foo\')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) {\n throw new Error("id is required");\n }\n if (["string", "number"].indexOf(typeof id) === -1) {\n throw new Error("id must be a number or a string");\n }\n}\nexports.validateId = validateId;\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error("method has been renamed to `radiansToDegrees`");\n}\nexports.radians2degrees = radians2degrees;\nfunction degrees2radians() {\n throw new Error("method has been renamed to `degreesToRadians`");\n}\nexports.degrees2radians = degrees2radians;\nfunction distanceToDegrees() {\n throw new Error("method has been renamed to `lengthToDegrees`");\n}\nexports.distanceToDegrees = distanceToDegrees;\nfunction distanceToRadians() {\n throw new Error("method has been renamed to `lengthToRadians`");\n}\nexports.distanceToRadians = distanceToRadians;\nfunction radiansToDistance() {\n throw new Error("method has been renamed to `radiansToLength`");\n}\nexports.radiansToDistance = radiansToDistance;\nfunction bearingToAngle() {\n throw new Error("method has been renamed to `bearingToAzimuth`");\n}\nexports.bearingToAngle = bearingToAngle;\nfunction convertDistance() {\n throw new Error("method has been renamed to `convertLength`");\n}\nexports.convertDistance = convertDistance;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/helpers/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate.\n *\n * @name getCoord\n * @param {Array|Geometry|Feature} coord GeoJSON Point or an Array of numbers\n * @returns {Array} coordinates\n * @example\n * var pt = turf.point([10, 10]);\n *\n * var coord = turf.getCoord(pt);\n * //= [10, 10]\n */\nfunction getCoord(coord) {\n if (!coord) throw new Error('coord is required');\n if (coord.type === 'Feature' && coord.geometry !== null && coord.geometry.type === 'Point') return coord.geometry.coordinates;\n if (coord.type === 'Point') return coord.coordinates;\n if (Array.isArray(coord) && coord.length >= 2 && coord[0].length === undefined && coord[1].length === undefined) return coord;\n\n throw new Error('coord must be GeoJSON Point or an Array of numbers');\n}\n\n/**\n * Unwrap coordinates from a Feature, Geometry Object or an Array\n *\n * @name getCoords\n * @param {Array|Geometry|Feature} coords Feature, Geometry Object or an Array\n * @returns {Array} coordinates\n * @example\n * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]);\n *\n * var coords = turf.getCoords(poly);\n * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]\n */\nfunction getCoords(coords) {\n if (!coords) throw new Error('coords is required');\n\n // Feature\n if (coords.type === 'Feature' && coords.geometry !== null) return coords.geometry.coordinates;\n\n // Geometry\n if (coords.coordinates) return coords.coordinates;\n\n // Array of numbers\n if (Array.isArray(coords)) return coords;\n\n throw new Error('coords must be GeoJSON Feature, Geometry Object or an Array');\n}\n\n/**\n * Checks if coordinates contains a number\n *\n * @name containsNumber\n * @param {Array} coordinates GeoJSON Coordinates\n * @returns {boolean} true if Array contains a number\n */\nfunction containsNumber(coordinates) {\n if (coordinates.length > 1 && helpers.isNumber(coordinates[0]) && helpers.isNumber(coordinates[1])) {\n return true;\n }\n\n if (Array.isArray(coordinates[0]) && coordinates[0].length) {\n return containsNumber(coordinates[0]);\n }\n throw new Error('coordinates must only contain numbers');\n}\n\n/**\n * Enforce expectations about types of GeoJSON objects for Turf.\n *\n * @name geojsonType\n * @param {GeoJSON} value any GeoJSON object\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction geojsonType(value, type, name) {\n if (!type || !name) throw new Error('type and name required');\n\n if (!value || value.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link Feature} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name featureOf\n * @param {Feature} feature a feature with an expected geometry type\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} error if value is not the expected type.\n */\nfunction featureOf(feature, type, name) {\n if (!feature) throw new Error('No feature passed');\n if (!name) throw new Error('.featureOf() requires a name');\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link FeatureCollection} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name collectionOf\n * @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction collectionOf(featureCollection, type, name) {\n if (!featureCollection) throw new Error('No featureCollection passed');\n if (!name) throw new Error('.collectionOf() requires a name');\n if (!featureCollection || featureCollection.type !== 'FeatureCollection') {\n throw new Error('Invalid input to ' + name + ', FeatureCollection required');\n }\n for (var i = 0; i < featureCollection.features.length; i++) {\n var feature = featureCollection.features[i];\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n }\n}\n\n/**\n * Get Geometry from Feature or Geometry Object\n *\n * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object\n * @returns {Geometry|null} GeoJSON Geometry Object\n * @throws {Error} if geojson is not a Feature or Geometry Object\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getGeom(point)\n * //={\"type\": \"Point\", \"coordinates\": [110, 40]}\n */\nfunction getGeom(geojson) {\n if (!geojson) throw new Error('geojson is required');\n if (geojson.geometry !== undefined) return geojson.geometry;\n if (geojson.coordinates || geojson.geometries) return geojson;\n throw new Error('geojson must be a valid Feature or Geometry Object');\n}\n\n/**\n * Get Geometry Type from Feature or Geometry Object\n *\n * @throws {Error} **DEPRECATED** in v5.0.0 in favor of getType\n */\nfunction getGeomType() {\n throw new Error('invariant.getGeomType has been deprecated in v5.0 in favor of invariant.getType');\n}\n\n/**\n * Get GeoJSON object's type, Geometry type is prioritize.\n *\n * @param {GeoJSON} geojson GeoJSON object\n * @param {string} [name=\"geojson\"] name of the variable to display in error message\n * @returns {string} GeoJSON type\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getType(point)\n * //=\"Point\"\n */\nfunction getType(geojson, name) {\n if (!geojson) throw new Error((name || 'geojson') + ' is required');\n // GeoJSON Feature & GeometryCollection\n if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type;\n // GeoJSON Geometry & FeatureCollection\n if (geojson.type) return geojson.type;\n throw new Error((name || 'geojson') + ' is invalid');\n}\n\nexports.getCoord = getCoord;\nexports.getCoords = getCoords;\nexports.containsNumber = containsNumber;\nexports.geojsonType = geojsonType;\nexports.featureOf = featureOf;\nexports.collectionOf = collectionOf;\nexports.getGeom = getGeom;\nexports.getGeomType = getGeomType;\nexports.getType = getType;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/invariant/index.js?")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval('__webpack_require__.r(__webpack_exports__);\n/* harmony import */ var _turf_meta__WEBPACK_IMPORTED_MODULE_0__ = __webpack_require__(0);\n\n\n/**\n * Takes a set of features, calculates the bbox of all input features, and returns a bounding box.\n *\n * @name bbox\n * @param {GeoJSON} geojson any GeoJSON object\n * @returns {BBox} bbox extent in [minX, minY, maxX, maxY] order\n * @example\n * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]);\n * var bbox = turf.bbox(line);\n * var bboxPolygon = turf.bboxPolygon(bbox);\n *\n * //addToMap\n * var addToMap = [line, bboxPolygon]\n */\nfunction bbox(geojson) {\n var BBox = [Infinity, Infinity, -Infinity, -Infinity];\n Object(_turf_meta__WEBPACK_IMPORTED_MODULE_0__[/* coordEach */ "a"])(geojson, function (coord) {\n if (BBox[0] > coord[0]) BBox[0] = coord[0];\n if (BBox[1] > coord[1]) BBox[1] = coord[1];\n if (BBox[2] < coord[0]) BBox[2] = coord[0];\n if (BBox[3] < coord[1]) BBox[3] = coord[1];\n });\n return BBox;\n}\n\n/* harmony default export */ __webpack_exports__["default"] = (bbox);\n\n\n//# sourceURL=webpack:///./node_modules/@turf/bbox/main.es.js?')},function(module,exports,__webpack_require__){eval('function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n/* The Agentmap class, which turns a Leaflet map into a simulation platform. */\nvar lineSlice = __webpack_require__(14).default,\n length = __webpack_require__(8).default;\n/**\r\n * The main class for building, storing, simulating, and manipulating agent-based models on Leaflet maps.\r\n *\r\n * @class Agentmap\r\n * @param {object} map - A Leaflet Map instance.\r\n * @param {number} [animation_interval=1] - The number of steps agents must move before being redrawn. Given 1, they will be redrawn after every step. Given 0, the animation will not update at all. 1 by default. Must be a nonnegative integer.\r\n * @property {object} map - A Leaflet Map instance.\r\n * @property {FeatureGroup} agents - A featureGroup containing all agents.\r\n * @property {FeatureGroup} units - A featureGroup containing all units.\r\n * @property {FeatureGroup} streets - A featureGroup containing all streets.\r\n * @property {object} state - Properties detailing the state of the simulation process.\r\n * @property {boolean} state.running - Whether the simulation is running or not.\r\n * @property {boolean} state.paused - Whether the simulation is paused.\r\n * @property {?number} state.animation_frame_id - The id of the agentmap\'s update function in the queue of functions to call for the coming animation frame.\r\n * @property {?number} state.ticks - The number of ticks elapsed since the start of the simulation.\r\n * @property {number} animation_interval - The number of steps agents must move before being redrawn. Given 1, they will be redrawn after every step. Given 0, the animation will not update at all. 1 by default. Will be a nonnegative integer.\r\n * @property {?function} controller - User-defined function to be called on each update.\r\n */\n\n\nAgentmap = function (_Agentmap) {\n function Agentmap(_x) {\n return _Agentmap.apply(this, arguments);\n }\n\n Agentmap.toString = function () {\n return _Agentmap.toString();\n };\n\n return Agentmap;\n}(function (map) {\n var animation_interval = arguments.length > 1 && arguments[1] !== undefined ? arguments[1] : 1;\n Agentmap.checkAnimIntervalOption(animation_interval);\n this.map = map, this.units = null, this.streets = null, this.agents = null, this.pathfinder = null, this.state = {\n running: false,\n paused: false,\n animation_frame_id: null,\n ticks: null\n }, this.controller = function () {}, this.animation_interval = animation_interval;\n});\n/**\r\n * Change the animation interval of the simulation & redraw the agents.\r\n *\r\n * @param {number} animation_interval - The desired animation interval to give the simulation. Must be a nonnegative integer.\r\n */\n\n\nAgentmap.prototype.setAnimationInterval = function (animation_interval) {\n Agentmap.checkAnimIntervalOption(animation_interval);\n this.animation_interval = animation_interval;\n this.agents.eachLayer(function (agent) {\n return agent.setLatLng(agent._latlng);\n });\n};\n/**\r\n * Check whether the animation interval option provided is valid.\r\n * @private\r\n *\r\n * @param {number} animation_interval - An input specifying an animation interval distance.\r\n */\n\n\nAgentmap.checkAnimIntervalOption = function (animation_interval) {\n if (!Number.isInteger(animation_interval) && animation_interval >= 0) {\n throw new Error("The animation_interval must be a non-negative integer!");\n }\n};\n/**\r\n * Get an animation frame, have the agents update & get ready to be drawn, and keep doing that until paused or reset.\r\n */\n\n\nAgentmap.prototype.run = function () {\n if (this.state.running === false) {\n this.state.running = true;\n\n var animation_update = function (rAF_time) {\n if (this.state.paused === true) {\n this.state.paused = false;\n }\n\n this.state.animation_frame_id = L.Util.requestAnimFrame(animation_update);\n this.update();\n }.bind(this);\n\n this.state.animation_frame_id = L.Util.requestAnimFrame(animation_update);\n }\n};\n/**\r\n * Update the simulation at the given time.\r\n * @private\r\n */\n\n\nAgentmap.prototype.update = function () {\n if (this.state.ticks === null) {\n this.state.ticks = 0;\n } //Execute user-provided per-tick instructions for the agentmap.\n\n\n this.controller(); //Execute user-provided per-tick instructions for each agent.\n\n this.agents.eachLayer(function (agent) {\n agent.controller();\n });\n this.state.ticks += 1;\n};\n/**\r\n* Stop the animation, reset the animation state properties, and delete the features.\r\n*/\n\n\nAgentmap.prototype.clear = function () {\n L.Util.cancelAnimFrame(this.state.animation_frame_id);\n this.state.running = false, this.state.paused = false, this.state.animation_frame_id = null, this.state.ticks = null, this.agents.clearLayers();\n this.streets.clearLayers();\n this.units.clearLayers();\n};\n/** \r\n * Stop the animation, stop updating the agents.\r\n */\n\n\nAgentmap.prototype.pause = function () {\n L.Util.cancelAnimFrame(this.state.animation_frame_id);\n this.state.running = false, this.state.paused = true;\n};\n/**\r\n * Get a point through which an agent can exit/enter a unit.\r\n *\r\n * @param {number} unit_id - The unique ID of the unit whose door you want.\r\n * @returns {LatLng} - The coordinates of the center point of the segment of the unit parallel to the street.\r\n */\n\n\nAgentmap.prototype.getUnitDoor = function (unit_id) {\n var unit = this.units.getLayer(unit_id);\n\n if (typeof unit === "undefined") {\n throw new Error("No unit with the specified ID exists.");\n }\n\n var unit_spec = unit.getLatLngs()[0],\n corner_a = unit_spec[0],\n corner_b = unit_spec[1],\n door = L.latLngBounds(corner_a, corner_b).getCenter();\n return door;\n};\n/**\r\n * Get the point on the adjacent street in front of the unit\'s door.\r\n *\r\n * @param {number} unit_id - The unique ID of the unit whose door\'s corresponding point on the street you want.\r\n * @returns {LatLng} - The coordinates point of the adjacent street directly in front of unit\'s door.\r\n */\n\n\nAgentmap.prototype.getStreetNearDoor = function (unit_id) {\n var _L;\n\n var unit = this.units.getLayer(unit_id);\n\n if (typeof unit === "undefined") {\n throw new Error("No unit with the specified ID exists.");\n }\n\n var unit_anchors = L.A.reversedCoordinates(unit.street_anchors),\n street_point = (_L = L).latLngBounds.apply(_L, _toConsumableArray(unit_anchors)).getCenter();\n\n return street_point;\n};\n/**\r\n * Given a unit and a pair of coordinates between 0 and 1, return a corresponding point inside the unit, offset from its first corner along the street.\r\n * \r\n * @param {number} unit_id - The unique ID of the unit whose interior point you want.\r\n * @param {number} x - A point between 0 and 1 representing a position along the width of a unit.\r\n * @param {number} y - A point between 0 and 1 representing a position along the depth of a unit.\r\n * @returns {LatLng} - The global coordinates of the specified position within the unit.\r\n */\n\n\nAgentmap.prototype.getUnitPoint = function (unit_id, x, y) {\n if (x < 0 || x > 1 || y < 0 || y > 1) {\n throw new Error("x and y must both be between 0 and 1!");\n }\n\n var unit = this.units.getLayer(unit_id),\n unit_corners = unit.getLatLngs()[0],\n front_right = unit_corners[0],\n front_left = unit_corners[1],\n back_right = unit_corners[3],\n front_length = front_left.lng - front_right.lng,\n side_length = back_right.lng - front_right.lng,\n front_slope = (front_right.lat - front_left.lat) / (front_right.lng - front_left.lng),\n side_slope = (front_right.lat - back_right.lat) / (front_right.lng - back_right.lng); //Get the coordinate of the position along the front (x) axis.\n\n var lng_along_front = front_right.lng + front_length * x,\n lat_along_front = front_right.lat + front_length * x * front_slope,\n point_along_front = L.latLng(lat_along_front, lng_along_front); //From the position on the front axis, get the coordinate of a position along a line perpendicular to the front and \n //parallel to the side (y) axis.\n\n var lng_along_side = point_along_front.lng + side_length * y,\n lat_along_side = point_along_front.lat + side_length * y * side_slope,\n point_in_depth = L.latLng(lat_along_side, lng_along_side);\n return point_in_depth;\n};\n/**\r\n * Given a point on a street, find the nearest intersection on that street (with any other street).\r\n * \r\n * @param {LatLng} lat_lng - The coordinates of the point on the street to search from.\r\n * @param {Place} place - A place object corresponding to the street.\r\n * @returns {LatLng} - The coordinates of the nearest intersection.\r\n */\n\n\nAgentmap.prototype.getNearestIntersection = function (lat_lng, place) {\n var street_id, street_feature;\n\n if (place.type === "street") {\n street_id = place.id;\n } else {\n throw new Error("place must be a street!");\n }\n\n street_feature = this.streets.getLayer(street_id).toGeoJSON();\n var intersections = this.streets.getLayer(street_id).intersections,\n intersection_points = [],\n intersection_distances = [];\n\n for (var intersection in intersections) {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = intersections[intersection][Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var cross_point = _step.value;\n var intersection_point = cross_point[0],\n distance = lat_lng.distanceTo(intersection_point);\n /* More precise, but slower, distance detection -- not necessary yet. \r\n \tlet start_coords = L.A.pointToCoordinateArray(lat_lng);\r\n \tintersection_coords = L.A.pointToCoordinateArray(intersection_point),\r\n \tsegment = lineSlice(start_coords, intersection_coords, street_feature),\r\n \tdistance = length(segment); \r\n */\n\n intersection_points.push(intersection_point);\n intersection_distances.push(distance);\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n }\n\n var smallest_distance = Math.min.apply(Math, intersection_distances),\n smallest_distance_index = intersection_distances.indexOf(smallest_distance),\n closest_intersection_point = L.latLng(intersection_points[smallest_distance_index]);\n return closest_intersection_point;\n};\n/**\r\n * Since units may take a noticeably long time to generate while typically staying the same over simulations,\r\n * downloadUnits makes it easy to get a JS file containing the units object, so it can be included with an\r\n * AgentMaps app and imported into Agentmap.buildingify so they will not need to be regenerated.\r\n */\n\n\nAgentmap.prototype.downloadUnits = function () {\n var file_content = "let units_data = ",\n units_json = this.units.toGeoJSON(20);\n file_content += JSON.stringify(units_json), file = new Blob([file_content]);\n var element = document.createElement("a");\n element.setAttribute("href", URL.createObjectURL(file)), element.setAttribute("download", "units_data.js"), element.style.display = "none";\n document.body.appendChild(element);\n element.click();\n document.body.removeChild(element);\n};\n/**\r\n * Generates an agentmap for the given map.\r\n *\r\n * @name agentmap\r\n * @param {object} map - A Leaflet Map instance.\r\n * @returns {object} - An Agentmap instance.\r\n */\n\n\nfunction agentmapFactory(map) {\n return new Agentmap(map);\n}\n/**\r\n * Returns the number of layers in a Leaflet layer group.\r\n *\r\n * @memberof L.LayerGroup\r\n */\n\n\nfunction layerCount() {\n return this.getLayers().length;\n}\n\nL.LayerGroup.include({\n count: layerCount\n});\nexports.Agentmap = Agentmap, exports.agentmap = agentmapFactory;\n\n//# sourceURL=webpack:///./src/agentmap.js?')},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n// http://en.wikipedia.org/wiki/Haversine_formula\n// http://www.movable-type.co.uk/scripts/latlong.html\n/**\n * Takes two {@link Point|points} and finds the geographic bearing between them,\n * i.e. the angle measured in degrees from the north line (0 degrees)\n *\n * @name bearing\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.final=false] calculates the final bearing if true\n * @returns {number} bearing in decimal degrees, between -180 and 180 degrees (positive clockwise)\n * @example\n * var point1 = turf.point([-75.343, 39.984]);\n * var point2 = turf.point([-75.534, 39.123]);\n *\n * var bearing = turf.bearing(point1, point2);\n *\n * //addToMap\n * var addToMap = [point1, point2]\n * point1.properties['marker-color'] = '#f00'\n * point2.properties['marker-color'] = '#0f0'\n * point1.properties.bearing = bearing\n */\nfunction bearing(start, end, options) {\n if (options === void 0) { options = {}; }\n // Reverse calculation\n if (options.final === true) {\n return calculateFinalBearing(start, end);\n }\n var coordinates1 = invariant_1.getCoord(start);\n var coordinates2 = invariant_1.getCoord(end);\n var lon1 = helpers_1.degreesToRadians(coordinates1[0]);\n var lon2 = helpers_1.degreesToRadians(coordinates2[0]);\n var lat1 = helpers_1.degreesToRadians(coordinates1[1]);\n var lat2 = helpers_1.degreesToRadians(coordinates2[1]);\n var a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n var b = Math.cos(lat1) * Math.sin(lat2) -\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n return helpers_1.radiansToDegrees(Math.atan2(a, b));\n}\n/**\n * Calculates Final Bearing\n *\n * @private\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @returns {number} bearing\n */\nfunction calculateFinalBearing(start, end) {\n // Swap start & end\n var bear = bearing(end, start);\n bear = (bear + 180) % 360;\n return bear;\n}\nexports.default = bearing;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/bearing/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\n// http://en.wikipedia.org/wiki/Haversine_formula\n// http://www.movable-type.co.uk/scripts/latlong.html\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n/**\n * Takes a {@link Point} and calculates the location of a destination point given a distance in\n * degrees, radians, miles, or kilometers; and bearing in degrees.\n * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature.\n *\n * @name destination\n * @param {Coord} origin starting point\n * @param {number} distance distance from the origin point\n * @param {number} bearing ranging from -180 to 180\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians\n * @param {Object} [options.properties={}] Translate properties to Point\n * @returns {Feature} destination point\n * @example\n * var point = turf.point([-75.343, 39.984]);\n * var distance = 50;\n * var bearing = 90;\n * var options = {units: 'miles'};\n *\n * var destination = turf.destination(point, distance, bearing, options);\n *\n * //addToMap\n * var addToMap = [point, destination]\n * destination.properties['marker-color'] = '#f00';\n * point.properties['marker-color'] = '#0f0';\n */\nfunction destination(origin, distance, bearing, options) {\n if (options === void 0) { options = {}; }\n // Handle input\n var coordinates1 = invariant_1.getCoord(origin);\n var longitude1 = helpers_1.degreesToRadians(coordinates1[0]);\n var latitude1 = helpers_1.degreesToRadians(coordinates1[1]);\n var bearingRad = helpers_1.degreesToRadians(bearing);\n var radians = helpers_1.lengthToRadians(distance, options.units);\n // Main\n var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +\n Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearingRad));\n var longitude2 = longitude1 + Math.atan2(Math.sin(bearingRad) * Math.sin(radians) * Math.cos(latitude1), Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));\n var lng = helpers_1.radiansToDegrees(longitude2);\n var lat = helpers_1.radiansToDegrees(latitude2);\n return helpers_1.point([lng, lat], options.properties);\n}\nexports.default = destination;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/destination/index.js?")},function(module,exports,__webpack_require__){eval('!function(t,e){ true?e(exports):undefined}(this,function(t){"use strict";function e(){}function n(t){this.message=t||""}function i(t){this.message=t||""}function r(t){this.message=t||""}function o(){}function s(t){return null===t?Mt:t.color}function a(t){return null===t?null:t.parent}function u(t,e){null!==t&&(t.color=e)}function l(t){return null===t?null:t.left}function c(t){return null===t?null:t.right}function p(){this.root_=null,this.size_=0}function h(){}function f(){this.array_=[],arguments[0]instanceof It&&this.addAll(arguments[0])}function g(){}function d(t){this.message=t||""}function y(){this.array_=[]}"fill"in Array.prototype||Object.defineProperty(Array.prototype,"fill",{configurable:!0,value:function(t){if(void 0===this||null===this)throw new TypeError(this+" is not an object");var e=Object(this),n=Math.max(Math.min(e.length,9007199254740991),0)||0,i=1 in arguments?parseInt(Number(arguments[1]),10)||0:0;i=i<0?Math.max(n+i,0):Math.min(i,n);var r=2 in arguments&&void 0!==arguments[2]?parseInt(Number(arguments[2]),10)||0:n;for(r=r<0?Math.max(n+arguments[2],0):Math.min(r,n);ie.x?1:this.ye.y?1:0},C.prototype.clone=function(){},C.prototype.copy=function(){return new C(this)},C.prototype.toString=function(){return"("+this.x+", "+this.y+", "+this.z+")"},C.prototype.distance3D=function(t){var e=this.x-t.x,n=this.y-t.y,i=this.z-t.z;return Math.sqrt(e*e+n*n+i*i)},C.prototype.distance=function(t){var e=this.x-t.x,n=this.y-t.y;return Math.sqrt(e*e+n*n)},C.prototype.hashCode=function(){var t=17;return t=37*t+C.hashCode(this.x),t=37*t+C.hashCode(this.y)},C.prototype.setCoordinate=function(t){this.x=t.x,this.y=t.y,this.z=t.z},C.prototype.interfaces_=function(){return[E,x,e]},C.prototype.getClass=function(){return C},C.hashCode=function(){if(1===arguments.length){var t=arguments[0],e=v.doubleToLongBits(t);return Math.trunc((e^e)>>>32)}},S.DimensionalComparator.get=function(){return L},S.serialVersionUID.get=function(){return 0x5cbf2c235c7e5800},S.NULL_ORDINATE.get=function(){return v.NaN},S.X.get=function(){return 0},S.Y.get=function(){return 1},S.Z.get=function(){return 2},Object.defineProperties(C,S);var L=function(t){if(this._dimensionsToTest=2,0===arguments.length);else if(1===arguments.length){var e=arguments[0];if(2!==e&&3!==e)throw new m("only 2 or 3 dimensions may be specified");this._dimensionsToTest=e}};L.prototype.compare=function(t,e){var n=t,i=e,r=L.compare(n.x,i.x);if(0!==r)return r;var o=L.compare(n.y,i.y);if(0!==o)return o;if(this._dimensionsToTest<=2)return 0;return L.compare(n.z,i.z)},L.prototype.interfaces_=function(){return[N]},L.prototype.getClass=function(){return L},L.compare=function(t,e){return te?1:v.isNaN(t)?v.isNaN(e)?0:-1:v.isNaN(e)?1:0};var b=function(){};b.prototype.create=function(){},b.prototype.interfaces_=function(){return[]},b.prototype.getClass=function(){return b};var w=function(){},O={INTERIOR:{configurable:!0},BOUNDARY:{configurable:!0},EXTERIOR:{configurable:!0},NONE:{configurable:!0}};w.prototype.interfaces_=function(){return[]},w.prototype.getClass=function(){return w},w.toLocationSymbol=function(t){switch(t){case w.EXTERIOR:return"e";case w.BOUNDARY:return"b";case w.INTERIOR:return"i";case w.NONE:return"-"}throw new m("Unknown location value: "+t)},O.INTERIOR.get=function(){return 0},O.BOUNDARY.get=function(){return 1},O.EXTERIOR.get=function(){return 2},O.NONE.get=function(){return-1},Object.defineProperties(w,O);var T=function(t,e){return t.interfaces_&&t.interfaces_().indexOf(e)>-1},R=function(){},P={LOG_10:{configurable:!0}};R.prototype.interfaces_=function(){return[]},R.prototype.getClass=function(){return R},R.log10=function(t){var e=Math.log(t);return v.isInfinite(e)?e:v.isNaN(e)?e:e/R.LOG_10},R.min=function(t,e,n,i){var r=t;return en?n:t}if(Number.isInteger(arguments[2])&&Number.isInteger(arguments[0])&&Number.isInteger(arguments[1])){var i=arguments[0],r=arguments[1],o=arguments[2];return io?o:i}},R.wrap=function(t,e){return t<0?e- -t%e:t%e},R.max=function(){if(3===arguments.length){var t=arguments[0],e=arguments[1],n=arguments[2],i=t;return e>i&&(i=e),n>i&&(i=n),i}if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3],u=r;return o>u&&(u=o),s>u&&(u=s),a>u&&(u=a),u}},R.average=function(t,e){return(t+e)/2},P.LOG_10.get=function(){return Math.log(10)},Object.defineProperties(R,P);var D=function(t){this.str=t};D.prototype.append=function(t){this.str+=t},D.prototype.setCharAt=function(t,e){this.str=this.str.substr(0,t)+e+this.str.substr(t+1)},D.prototype.toString=function(t){return this.str};var M=function(t){this.value=t};M.prototype.intValue=function(){return this.value},M.prototype.compareTo=function(t){return this.valuet?1:0},M.isNaN=function(t){return Number.isNaN(t)};var A=function(){};A.isWhitespace=function(t){return t<=32&&t>=0||127===t},A.toUpperCase=function(t){return t.toUpperCase()};var F=function t(){if(this._hi=0,this._lo=0,0===arguments.length)this.init(0);else if(1===arguments.length){if("number"==typeof arguments[0]){var e=arguments[0];this.init(e)}else if(arguments[0]instanceof t){var n=arguments[0];this.init(n)}else if("string"==typeof arguments[0]){var i=arguments[0];t.call(this,t.parse(i))}}else if(2===arguments.length){var r=arguments[0],o=arguments[1];this.init(r,o)}},G={PI:{configurable:!0},TWO_PI:{configurable:!0},PI_2:{configurable:!0},E:{configurable:!0},NaN:{configurable:!0},EPS:{configurable:!0},SPLIT:{configurable:!0},MAX_PRINT_DIGITS:{configurable:!0},TEN:{configurable:!0},ONE:{configurable:!0},SCI_NOT_EXPONENT_CHAR:{configurable:!0},SCI_NOT_ZERO:{configurable:!0}};F.prototype.le=function(t){return(this._hi9?(c=!0,p="9"):p="0"+l,s.append(p),n=n.subtract(F.valueOf(l)).multiply(F.TEN),c&&n.selfAdd(F.TEN);var h=!0,f=F.magnitude(n._hi);if(f<0&&Math.abs(f)>=a-u&&(h=!1),!h)break}return e[0]=i,s.toString()},F.prototype.sqr=function(){return this.multiply(this)},F.prototype.doubleValue=function(){return this._hi+this._lo},F.prototype.subtract=function(){if(arguments[0]instanceof F){var t=arguments[0];return this.add(t.negate())}if("number"==typeof arguments[0]){var e=arguments[0];return this.add(-e)}},F.prototype.equals=function(){if(1===arguments.length){var t=arguments[0];return this._hi===t._hi&&this._lo===t._lo}},F.prototype.isZero=function(){return 0===this._hi&&0===this._lo},F.prototype.selfSubtract=function(){if(arguments[0]instanceof F){var t=arguments[0];return this.isNaN()?this:this.selfAdd(-t._hi,-t._lo)}if("number"==typeof arguments[0]){var e=arguments[0];return this.isNaN()?this:this.selfAdd(-e,0)}},F.prototype.getSpecialNumberString=function(){return this.isZero()?"0.0":this.isNaN()?"NaN ":null},F.prototype.min=function(t){return this.le(t)?this:t},F.prototype.selfDivide=function(){if(1===arguments.length){if(arguments[0]instanceof F){var t=arguments[0];return this.selfDivide(t._hi,t._lo)}if("number"==typeof arguments[0]){var e=arguments[0];return this.selfDivide(e,0)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1],r=null,o=null,s=null,a=null,u=null,l=null,c=null,p=null;return u=this._hi/n,l=F.SPLIT*u,r=l-u,p=F.SPLIT*n,r=l-r,o=u-r,s=p-n,c=u*n,s=p-s,a=n-s,p=r*s-c+r*a+o*s+o*a,l=(this._hi-c-p+this._lo-u*i)/n,p=u+l,this._hi=p,this._lo=u-p+l,this}},F.prototype.dump=function(){return"DD<"+this._hi+", "+this._lo+">"},F.prototype.divide=function(){if(arguments[0]instanceof F){var t=arguments[0],e=null,n=null,i=null,r=null,o=null,s=null,a=null,u=null;n=(o=this._hi/t._hi)-(e=(s=F.SPLIT*o)-(e=s-o)),u=e*(i=(u=F.SPLIT*t._hi)-(i=u-t._hi))-(a=o*t._hi)+e*(r=t._hi-i)+n*i+n*r,s=(this._hi-a-u+this._lo-o*t._lo)/t._hi;return new F(u=o+s,o-u+s)}if("number"==typeof arguments[0]){var l=arguments[0];return v.isNaN(l)?F.createNaN():F.copy(this).selfDivide(l,0)}},F.prototype.ge=function(t){return(this._hi>t._hi||this._hi===t._hi)&&this._lo>=t._lo},F.prototype.pow=function(t){if(0===t)return F.valueOf(1);var e=new F(this),n=F.valueOf(1),i=Math.abs(t);if(i>1)for(;i>0;)i%2==1&&n.selfMultiply(e),(i/=2)>0&&(e=e.sqr());else n=e;return t<0?n.reciprocal():n},F.prototype.ceil=function(){if(this.isNaN())return F.NaN;var t=Math.ceil(this._hi),e=0;return t===this._hi&&(e=Math.ceil(this._lo)),new F(t,e)},F.prototype.compareTo=function(t){var e=t;return this._hie._hi?1:this._loe._lo?1:0},F.prototype.rint=function(){if(this.isNaN())return this;return this.add(.5).floor()},F.prototype.setValue=function(){if(arguments[0]instanceof F){var t=arguments[0];return this.init(t),this}if("number"==typeof arguments[0]){var e=arguments[0];return this.init(e),this}},F.prototype.max=function(t){return this.ge(t)?this:t},F.prototype.sqrt=function(){if(this.isZero())return F.valueOf(0);if(this.isNegative())return F.NaN;var t=1/Math.sqrt(this._hi),e=this._hi*t,n=F.valueOf(e),i=this.subtract(n.sqr())._hi*(.5*t);return n.add(i)},F.prototype.selfAdd=function(){if(1===arguments.length){if(arguments[0]instanceof F){var t=arguments[0];return this.selfAdd(t._hi,t._lo)}if("number"==typeof arguments[0]){var e=arguments[0],n=null,i=null,r=null,o=null,s=null,a=null;return r=this._hi+e,s=r-this._hi,o=r-s,o=e-s+(this._hi-o),a=o+this._lo,n=r+a,i=a+(r-n),this._hi=n+i,this._lo=i+(n-this._hi),this}}else if(2===arguments.length){var u=arguments[0],l=arguments[1],c=null,p=null,h=null,f=null,g=null,d=null,y=null;f=this._hi+u,p=this._lo+l,g=f-(d=f-this._hi),h=p-(y=p-this._lo);var _=(c=f+(d=(g=u-d+(this._hi-g))+p))+(d=(h=l-y+(this._lo-h))+(d+(f-c))),m=d+(c-_);return this._hi=_,this._lo=m,this}},F.prototype.selfMultiply=function(){if(1===arguments.length){if(arguments[0]instanceof F){var t=arguments[0];return this.selfMultiply(t._hi,t._lo)}if("number"==typeof arguments[0]){var e=arguments[0];return this.selfMultiply(e,0)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1],r=null,o=null,s=null,a=null,u=null,l=null;r=(u=F.SPLIT*this._hi)-this._hi,l=F.SPLIT*n,r=u-r,o=this._hi-r,s=l-n;var c=(u=this._hi*n)+(l=r*(s=l-s)-u+r*(a=n-s)+o*s+o*a+(this._hi*i+this._lo*n)),p=l+(r=u-c);return this._hi=c,this._lo=p,this}},F.prototype.selfSqr=function(){return this.selfMultiply(this)},F.prototype.floor=function(){if(this.isNaN())return F.NaN;var t=Math.floor(this._hi),e=0;return t===this._hi&&(e=Math.floor(this._lo)),new F(t,e)},F.prototype.negate=function(){return this.isNaN()?this:new F(-this._hi,-this._lo)},F.prototype.clone=function(){},F.prototype.multiply=function(){if(arguments[0]instanceof F){var t=arguments[0];return t.isNaN()?F.createNaN():F.copy(this).selfMultiply(t)}if("number"==typeof arguments[0]){var e=arguments[0];return v.isNaN(e)?F.createNaN():F.copy(this).selfMultiply(e,0)}},F.prototype.isNaN=function(){return v.isNaN(this._hi)},F.prototype.intValue=function(){return Math.trunc(this._hi)},F.prototype.toString=function(){var t=F.magnitude(this._hi);return t>=-3&&t<=20?this.toStandardNotation():this.toSciNotation()},F.prototype.toStandardNotation=function(){var t=this.getSpecialNumberString();if(null!==t)return t;var e=new Array(1).fill(null),n=this.extractSignificantDigits(!0,e),i=e[0]+1,r=n;if("."===n.charAt(0))r="0"+n;else if(i<0)r="0."+F.stringOfChar("0",-i)+n;else if(-1===n.indexOf(".")){var o=i-n.length;r=n+F.stringOfChar("0",o)+".0"}return this.isNegative()?"-"+r:r},F.prototype.reciprocal=function(){var t=null,e=null,n=null,i=null,r=null,o=null,s=null,a=null;e=(r=1/this._hi)-(t=(o=F.SPLIT*r)-(t=o-r)),n=(a=F.SPLIT*this._hi)-this._hi;var u=r+(o=(1-(s=r*this._hi)-(a=t*(n=a-n)-s+t*(i=this._hi-n)+e*n+e*i)-r*this._lo)/this._hi);return new F(u,r-u+o)},F.prototype.toSciNotation=function(){if(this.isZero())return F.SCI_NOT_ZERO;var t=this.getSpecialNumberString();if(null!==t)return t;var e=new Array(1).fill(null),n=this.extractSignificantDigits(!1,e),i=F.SCI_NOT_EXPONENT_CHAR+e[0];if("0"===n.charAt(0))throw new Error("Found leading zero: "+n);var r="";n.length>1&&(r=n.substring(1));var o=n.charAt(0)+"."+r;return this.isNegative()?"-"+o+i:o+i},F.prototype.abs=function(){return this.isNaN()?F.NaN:this.isNegative()?this.negate():new F(this)},F.prototype.isPositive=function(){return(this._hi>0||0===this._hi)&&this._lo>0},F.prototype.lt=function(t){return(this._hit._hi||this._hi===t._hi)&&this._lo>t._lo},F.prototype.isNegative=function(){return(this._hi<0||0===this._hi)&&this._lo<0},F.prototype.trunc=function(){return this.isNaN()?F.NaN:this.isPositive()?this.floor():this.ceil()},F.prototype.signum=function(){return this._hi>0?1:this._hi<0?-1:this._lo>0?1:this._lo<0?-1:0},F.prototype.interfaces_=function(){return[e,E,x]},F.prototype.getClass=function(){return F},F.sqr=function(t){return F.valueOf(t).selfMultiply(t)},F.valueOf=function(){if("string"==typeof arguments[0]){var t=arguments[0];return F.parse(t)}if("number"==typeof arguments[0]){var e=arguments[0];return new F(e)}},F.sqrt=function(t){return F.valueOf(t).sqrt()},F.parse=function(t){for(var e=0,n=t.length;A.isWhitespace(t.charAt(e));)e++;var i=!1;if(e=n);){var l=t.charAt(e);if(e++,A.isDigit(l)){var c=l-"0";o.selfMultiply(F.TEN),o.selfAdd(c),s++}else{if("."!==l){if("e"===l||"E"===l){var p=t.substring(e);try{u=M.parseInt(p)}catch(e){throw e instanceof Error?new Error("Invalid exponent "+p+" in string "+t):e}break}throw new Error("Unexpected character \'"+l+"\' at position "+e+" in string "+t)}a=s}}var h=o,f=s-a-u;if(0===f)h=o;else if(f>0){var g=F.TEN.pow(f);h=o.divide(g)}else if(f<0){var d=F.TEN.pow(-f);h=o.multiply(d)}return i?h.negate():h},F.createNaN=function(){return new F(v.NaN,v.NaN)},F.copy=function(t){return new F(t)},F.magnitude=function(t){var e=Math.abs(t),n=Math.log(e)/Math.log(10),i=Math.trunc(Math.floor(n));return 10*Math.pow(10,i)<=e&&(i+=1),i},F.stringOfChar=function(t,e){for(var n=new D,i=0;i0){if(o<=0)return q.signum(s);i=r+o}else{if(!(r<0))return q.signum(s);if(o>=0)return q.signum(s);i=-r-o}var a=q.DP_SAFE_EPSILON*i;return s>=a||-s>=a?q.signum(s):2},q.signum=function(t){return t>0?1:t<0?-1:0},B.DP_SAFE_EPSILON.get=function(){return 1e-15},Object.defineProperties(q,B);var V=function(){},U={X:{configurable:!0},Y:{configurable:!0},Z:{configurable:!0},M:{configurable:!0}};U.X.get=function(){return 0},U.Y.get=function(){return 1},U.Z.get=function(){return 2},U.M.get=function(){return 3},V.prototype.setOrdinate=function(t,e,n){},V.prototype.size=function(){},V.prototype.getOrdinate=function(t,e){},V.prototype.getCoordinate=function(){},V.prototype.getCoordinateCopy=function(t){},V.prototype.getDimension=function(){},V.prototype.getX=function(t){},V.prototype.clone=function(){},V.prototype.expandEnvelope=function(t){},V.prototype.copy=function(){},V.prototype.getY=function(t){},V.prototype.toCoordinateArray=function(){},V.prototype.interfaces_=function(){return[x]},V.prototype.getClass=function(){return V},Object.defineProperties(V,U);var z=function(){},X=function(t){function e(){t.call(this,"Projective point not representable on the Cartesian plane.")}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(z),Y=function(){};Y.arraycopy=function(t,e,n,i,r){for(var o=0,s=e;st._minx?this._minx:t._minx,n=this._miny>t._miny?this._miny:t._miny,i=this._maxx=this._minx&&e.getMaxX()<=this._maxx&&e.getMinY()>=this._miny&&e.getMaxY()<=this._maxy)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];return!this.isNull()&&(n>=this._minx&&n<=this._maxx&&i>=this._miny&&i<=this._maxy)}},j.prototype.intersects=function(){if(1===arguments.length){if(arguments[0]instanceof j){var t=arguments[0];return!this.isNull()&&!t.isNull()&&!(t._minx>this._maxx||t._maxxthis._maxy||t._maxythis._maxx||nthis._maxy||ithis._maxx&&(this._maxx=e._maxx),e._minythis._maxy&&(this._maxy=e._maxy))}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];this.isNull()?(this._minx=n,this._maxx=n,this._miny=i,this._maxy=i):(nthis._maxx&&(this._maxx=n),ithis._maxy&&(this._maxy=i))}},j.prototype.minExtent=function(){if(this.isNull())return 0;var t=this.getWidth(),e=this.getHeight();return te._minx?1:this._minye._miny?1:this._maxxe._maxx?1:this._maxye._maxy?1:0},j.prototype.translate=function(t,e){if(this.isNull())return null;this.init(this.getMinX()+t,this.getMaxX()+t,this.getMinY()+e,this.getMaxY()+e)},j.prototype.toString=function(){return"Env["+this._minx+" : "+this._maxx+", "+this._miny+" : "+this._maxy+"]"},j.prototype.setToNull=function(){this._minx=0,this._maxx=-1,this._miny=0,this._maxy=-1},j.prototype.getHeight=function(){return this.isNull()?0:this._maxy-this._miny},j.prototype.maxExtent=function(){if(this.isNull())return 0;var t=this.getWidth(),e=this.getHeight();return t>e?t:e},j.prototype.expandBy=function(){if(1===arguments.length){var t=arguments[0];this.expandBy(t,t)}else if(2===arguments.length){var e=arguments[0],n=arguments[1];if(this.isNull())return null;this._minx-=e,this._maxx+=e,this._miny-=n,this._maxy+=n,(this._minx>this._maxx||this._miny>this._maxy)&&this.setToNull()}},j.prototype.contains=function(){if(1===arguments.length){if(arguments[0]instanceof j){var t=arguments[0];return this.covers(t)}if(arguments[0]instanceof C){var e=arguments[0];return this.covers(e)}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];return this.covers(n,i)}},j.prototype.centre=function(){return this.isNull()?null:new C((this.getMinX()+this.getMaxX())/2,(this.getMinY()+this.getMaxY())/2)},j.prototype.init=function(){if(0===arguments.length)this.setToNull();else if(1===arguments.length){if(arguments[0]instanceof C){var t=arguments[0];this.init(t.x,t.x,t.y,t.y)}else if(arguments[0]instanceof j){var e=arguments[0];this._minx=e._minx,this._maxx=e._maxx,this._miny=e._miny,this._maxy=e._maxy}}else if(2===arguments.length){var n=arguments[0],i=arguments[1];this.init(n.x,i.x,n.y,i.y)}else if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3];rt._maxx&&(e=this._minx-t._maxx);var n=0;return this._maxyt._maxy&&(n=this._miny-t._maxy),0===e?n:0===n?e:Math.sqrt(e*e+n*n)},j.prototype.hashCode=function(){var t=17;return t=37*t+C.hashCode(this._minx),t=37*t+C.hashCode(this._maxx),t=37*t+C.hashCode(this._miny),t=37*t+C.hashCode(this._maxy)},j.prototype.interfaces_=function(){return[E,e]},j.prototype.getClass=function(){return j},j.intersects=function(){if(3===arguments.length){var t=arguments[0],e=arguments[1],n=arguments[2];return n.x>=(t.xe.x?t.x:e.x)&&n.y>=(t.ye.y?t.y:e.y)}if(4===arguments.length){var i=arguments[0],r=arguments[1],o=arguments[2],s=arguments[3],a=Math.min(o.x,s.x),u=Math.max(o.x,s.x),l=Math.min(i.x,r.x),c=Math.max(i.x,r.x);return!(l>u)&&(!(cu)&&!(cthis.getEdgeDistance(t,1)?(this._intLineIndex[t][0]=0,this._intLineIndex[t][1]=1):(this._intLineIndex[t][0]=1,this._intLineIndex[t][1]=0)}},nt.prototype.isProper=function(){return this.hasIntersection()&&this._isProper},nt.prototype.setPrecisionModel=function(t){this._precisionModel=t},nt.prototype.isInteriorIntersection=function(){if(0===arguments.length)return!!this.isInteriorIntersection(0)||!!this.isInteriorIntersection(1);if(1===arguments.length){for(var t=arguments[0],e=0;er?i:r;else{var s=Math.abs(t.x-e.x),a=Math.abs(t.y-e.y);0!==(o=i>r?s:a)||t.equals(e)||(o=Math.max(s,a))}return et.isTrue(!(0===o&&!t.equals(e)),"Bad distance calculation"),o},nt.nonRobustComputeEdgeDistance=function(t,e,n){var i=t.x-e.x,r=t.y-e.y,o=Math.sqrt(i*i+r*r);return et.isTrue(!(0===o&&!t.equals(e)),"Invalid distance calculation"),o},it.DONT_INTERSECT.get=function(){return 0},it.DO_INTERSECT.get=function(){return 1},it.COLLINEAR.get=function(){return 2},it.NO_INTERSECTION.get=function(){return 0},it.POINT_INTERSECTION.get=function(){return 1},it.COLLINEAR_INTERSECTION.get=function(){return 2},Object.defineProperties(nt,it);var rt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.isInSegmentEnvelopes=function(t){var e=new j(this._inputLines[0][0],this._inputLines[0][1]),n=new j(this._inputLines[1][0],this._inputLines[1][1]);return e.contains(t)&&n.contains(t)},e.prototype.computeIntersection=function(){if(3!==arguments.length)return t.prototype.computeIntersection.apply(this,arguments);var e=arguments[0],n=arguments[1],i=arguments[2];if(this._isProper=!1,j.intersects(n,i,e)&&0===at.orientationIndex(n,i,e)&&0===at.orientationIndex(i,n,e))return this._isProper=!0,(e.equals(n)||e.equals(i))&&(this._isProper=!1),this._result=t.POINT_INTERSECTION,null;this._result=t.NO_INTERSECTION},e.prototype.normalizeToMinimum=function(t,e,n,i,r){r.x=this.smallestInAbsValue(t.x,e.x,n.x,i.x),r.y=this.smallestInAbsValue(t.y,e.y,n.y,i.y),t.x-=r.x,t.y-=r.y,e.x-=r.x,e.y-=r.y,n.x-=r.x,n.y-=r.y,i.x-=r.x,i.y-=r.y},e.prototype.safeHCoordinateIntersection=function(t,n,i,r){var o=null;try{o=k.intersection(t,n,i,r)}catch(s){if(!(s instanceof X))throw s;o=e.nearestEndpoint(t,n,i,r)}return o},e.prototype.intersection=function(t,n,i,r){var o=this.intersectionWithNormalization(t,n,i,r);return this.isInSegmentEnvelopes(o)||(o=new C(e.nearestEndpoint(t,n,i,r))),null!==this._precisionModel&&this._precisionModel.makePrecise(o),o},e.prototype.smallestInAbsValue=function(t,e,n,i){var r=t,o=Math.abs(r);return Math.abs(e)1e-4&&Y.out.println("Distance = "+r.distance(o))},e.prototype.intersectionWithNormalization=function(t,e,n,i){var r=new C(t),o=new C(e),s=new C(n),a=new C(i),u=new C;this.normalizeToEnvCentre(r,o,s,a,u);var l=this.safeHCoordinateIntersection(r,o,s,a);return l.x+=u.x,l.y+=u.y,l},e.prototype.computeCollinearIntersection=function(e,n,i,r){var o=j.intersects(e,n,i),s=j.intersects(e,n,r),a=j.intersects(i,r,e),u=j.intersects(i,r,n);return o&&s?(this._intPt[0]=i,this._intPt[1]=r,t.COLLINEAR_INTERSECTION):a&&u?(this._intPt[0]=e,this._intPt[1]=n,t.COLLINEAR_INTERSECTION):o&&a?(this._intPt[0]=i,this._intPt[1]=e,!i.equals(e)||s||u?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):o&&u?(this._intPt[0]=i,this._intPt[1]=n,!i.equals(n)||s||a?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):s&&a?(this._intPt[0]=r,this._intPt[1]=e,!r.equals(e)||o||u?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):s&&u?(this._intPt[0]=r,this._intPt[1]=n,!r.equals(n)||o||a?t.COLLINEAR_INTERSECTION:t.POINT_INTERSECTION):t.NO_INTERSECTION},e.prototype.normalizeToEnvCentre=function(t,e,n,i,r){var o=t.xe.x?t.x:e.x,u=t.y>e.y?t.y:e.y,l=n.xi.x?n.x:i.x,h=n.y>i.y?n.y:i.y,f=((o>l?o:l)+(ac?s:c)+(u0&&s>0||o<0&&s<0)return t.NO_INTERSECTION;var a=at.orientationIndex(i,r,e),u=at.orientationIndex(i,r,n);if(a>0&&u>0||a<0&&u<0)return t.NO_INTERSECTION;return 0===o&&0===s&&0===a&&0===u?this.computeCollinearIntersection(e,n,i,r):(0===o||0===s||0===a||0===u?(this._isProper=!1,e.equals2D(i)||e.equals2D(r)?this._intPt[0]=e:n.equals2D(i)||n.equals2D(r)?this._intPt[0]=n:0===o?this._intPt[0]=new C(i):0===s?this._intPt[0]=new C(r):0===a?this._intPt[0]=new C(e):0===u&&(this._intPt[0]=new C(n))):(this._isProper=!0,this._intPt[0]=this.intersection(e,n,i,r)),t.POINT_INTERSECTION)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e.nearestEndpoint=function(t,e,n,i){var r=t,o=at.distancePointLine(t,n,i),s=at.distancePointLine(e,n,i);return s0?n>0?-r:r:n>0?r:-r;if(0===e||0===n)return i>0?t>0?r:-r:t>0?-r:r;if(e>0?i>0?e<=i||(r=-r,o=t,t=n,n=o,o=e,e=i,i=o):e<=-i?(r=-r,n=-n,i=-i):(o=t,t=-n,n=o,o=e,e=-i,i=o):i>0?-e<=i?(r=-r,t=-t,e=-e):(o=-t,t=n,n=o,o=-e,e=i,i=o):e>=i?(t=-t,e=-e,n=-n,i=-i):(r=-r,o=-t,t=-n,n=o,o=-e,e=-i,i=o),t>0){if(!(n>0))return r;if(!(t<=n))return r}else{if(n>0)return-r;if(!(t>=n))return-r;r=-r,t=-t,n=-n}for(;;){if(s=Math.floor(n/t),n-=s*t,(i-=s*e)<0)return-r;if(i>e)return r;if(t>n+n){if(ei+i)return-r;n=t-n,i=e-i,r=-r}if(0===i)return 0===n?0:-r;if(0===n)return r;if(s=Math.floor(t/n),t-=s*n,(e-=s*i)<0)return r;if(e>i)return-r;if(n>t+t){if(ie+e)return r;t=n-t,e=i-e,r=-r}if(0===e)return 0===t?0:r;if(0===t)return-r}};var st=function(){this._p=null,this._crossingCount=0,this._isPointOnSegment=!1;var t=arguments[0];this._p=t};st.prototype.countSegment=function(t,e){if(t.xi&&(n=e.x,i=t.x),this._p.x>=n&&this._p.x<=i&&(this._isPointOnSegment=!0),null}if(t.y>this._p.y&&e.y<=this._p.y||e.y>this._p.y&&t.y<=this._p.y){var r=t.x-this._p.x,o=t.y-this._p.y,s=e.x-this._p.x,a=e.y-this._p.y,u=ot.signOfDet2x2(r,o,s,a);if(0===u)return this._isPointOnSegment=!0,null;a0&&this._crossingCount++}},st.prototype.isPointInPolygon=function(){return this.getLocation()!==w.EXTERIOR},st.prototype.getLocation=function(){return this._isPointOnSegment?w.BOUNDARY:this._crossingCount%2==1?w.INTERIOR:w.EXTERIOR},st.prototype.isOnSegment=function(){return this._isPointOnSegment},st.prototype.interfaces_=function(){return[]},st.prototype.getClass=function(){return st},st.locatePointInRing=function(){if(arguments[0]instanceof C&&T(arguments[1],V)){for(var t=arguments[0],e=arguments[1],n=new st(t),i=new C,r=new C,o=1;o1||a<0||a>1)&&(r=!0)}}else r=!0;return r?R.min(at.distancePointLine(t,n,i),at.distancePointLine(e,n,i),at.distancePointLine(n,t,e),at.distancePointLine(i,t,e)):0},at.isPointInRing=function(t,e){return at.locatePointInRing(t,e)!==w.EXTERIOR},at.computeLength=function(t){var e=t.size();if(e<=1)return 0;var n=0,i=new C;t.getCoordinate(0,i);for(var r=i.x,o=i.y,s=1;sn.y&&(n=o,i=r)}var s=i;do{(s-=1)<0&&(s=e)}while(t[s].equals2D(n)&&s!==i);var a=i;do{a=(a+1)%e}while(t[a].equals2D(n)&&a!==i);var u=t[s],l=t[a];if(u.equals2D(n)||l.equals2D(n)||u.equals2D(l))return!1;var c=at.computeOrientation(u,n,l),p=!1;return p=0===c?u.x>l.x:c>0,p},at.locatePointInRing=function(t,e){return st.locatePointInRing(t,e)},at.distancePointLinePerpendicular=function(t,e,n){var i=(n.x-e.x)*(n.x-e.x)+(n.y-e.y)*(n.y-e.y),r=((e.y-t.y)*(n.x-e.x)-(e.x-t.x)*(n.y-e.y))/i;return Math.abs(r)*Math.sqrt(i)},at.computeOrientation=function(t,e,n){return at.orientationIndex(t,e,n)},at.distancePointLine=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];if(0===e.length)throw new m("Line array must contain at least one vertex");for(var n=t.distance(e[0]),i=0;i=1)return o.distance(a);var c=((s.y-o.y)*(a.x-s.x)-(s.x-o.x)*(a.y-s.y))/u;return Math.abs(c)*Math.sqrt(u)}},at.isOnLine=function(t,e){for(var n=new rt,i=1;i0},_t.prototype.interfaces_=function(){return[gt]},_t.prototype.getClass=function(){return _t};var mt=function(){};mt.prototype.isInBoundary=function(t){return t>1},mt.prototype.interfaces_=function(){return[gt]},mt.prototype.getClass=function(){return mt};var vt=function(){};vt.prototype.isInBoundary=function(t){return 1===t},vt.prototype.interfaces_=function(){return[gt]},vt.prototype.getClass=function(){return vt};var It=function(){};It.prototype.add=function(){},It.prototype.addAll=function(){},It.prototype.isEmpty=function(){},It.prototype.iterator=function(){},It.prototype.size=function(){},It.prototype.toArray=function(){},It.prototype.remove=function(){},(n.prototype=new Error).name="IndexOutOfBoundsException";var Et=function(){};Et.prototype.hasNext=function(){},Et.prototype.next=function(){},Et.prototype.remove=function(){};var xt=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(){},e.prototype.set=function(){},e.prototype.isEmpty=function(){},e}(It);(i.prototype=new Error).name="NoSuchElementException";var Nt=function(t){function e(){t.call(this),this.array_=[],arguments[0]instanceof It&&this.addAll(arguments[0])}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.ensureCapacity=function(){},e.prototype.interfaces_=function(){return[t,It]},e.prototype.add=function(t){return 1===arguments.length?this.array_.push(t):this.array_.splice(arguments[0],arguments[1]),!0},e.prototype.clear=function(){this.array_=[]},e.prototype.addAll=function(t){for(var e=t.iterator();e.hasNext();)this.add(e.next());return!0},e.prototype.set=function(t,e){var n=this.array_[t];return this.array_[t]=e,n},e.prototype.iterator=function(){return new Ct(this)},e.prototype.get=function(t){if(t<0||t>=this.size())throw new n;return this.array_[t]},e.prototype.isEmpty=function(){return 0===this.array_.length},e.prototype.size=function(){return this.array_.length},e.prototype.toArray=function(){for(var t=[],e=0,n=this.array_.length;e=1){if(this.get(this.size()-1).equals2D(r))return null}t.prototype.add.call(this,r)}else if(arguments[0]instanceof Object&&"boolean"==typeof arguments[1]){var o=arguments[0],s=arguments[1];return this.add(o,s),!0}}else if(3===arguments.length){if("boolean"==typeof arguments[2]&&arguments[0]instanceof Array&&"boolean"==typeof arguments[1]){var a=arguments[0],u=arguments[1];if(arguments[2])for(var l=0;l=0;c--)this.add(a[c],u);return!0}if("boolean"==typeof arguments[2]&&Number.isInteger(arguments[0])&&arguments[1]instanceof C){var p=arguments[0],h=arguments[1];if(!arguments[2]){var f=this.size();if(f>0){if(p>0){if(this.get(p-1).equals2D(h))return null}if(p_&&(m=-1);for(var v=y;v!==_;v+=m)this.add(g[v],d);return!0}},e.prototype.closeRing=function(){this.size()>0&&this.add(new C(this.get(0)),!1)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},Object.defineProperties(e,n),e}(Nt),Lt=function(){},bt={ForwardComparator:{configurable:!0},BidirectionalComparator:{configurable:!0},coordArrayType:{configurable:!0}};bt.ForwardComparator.get=function(){return wt},bt.BidirectionalComparator.get=function(){return Ot},bt.coordArrayType.get=function(){return new Array(0).fill(null)},Lt.prototype.interfaces_=function(){return[]},Lt.prototype.getClass=function(){return Lt},Lt.isRing=function(t){return!(t.length<4)&&!!t[0].equals2D(t[t.length-1])},Lt.ptNotInList=function(t,e){for(var n=0;n=t?e:[]},Lt.indexOf=function(t,e){for(var n=0;n0)&&(e=t[n]);return e},Lt.extract=function(t,e,n){e=R.clamp(e,0,t.length);var i=(n=R.clamp(n,-1,t.length))-e+1;n<0&&(i=0),e>=t.length&&(i=0),ni.length)return 1;if(0===n.length)return 0;var r=Lt.compare(n,i);return Lt.isEqualReversed(n,i)?0:r},Ot.prototype.OLDcompare=function(t,e){var n=t,i=e;if(n.lengthi.length)return 1;if(0===n.length)return 0;for(var r=Lt.increasingDirection(n),o=Lt.increasingDirection(i),s=r>0?0:n.length-1,a=o>0?0:n.length-1,u=0;u0))return e.value;e=e.right}}return null},p.prototype.put=function(t,e){if(null===this.root_)return this.root_={key:t,value:e,left:null,right:null,parent:null,color:Mt,getValue:function(){return this.value},getKey:function(){return this.key}},this.size_=1,null;var n,i,r=this.root_;do{if(n=r,(i=t.compareTo(r.key))<0)r=r.left;else{if(!(i>0)){var o=r.value;return r.value=e,o}r=r.right}}while(null!==r);var s={key:t,left:null,right:null,value:e,parent:n,color:Mt,getValue:function(){return this.value},getKey:function(){return this.key}};return i<0?n.left=s:n.right=s,this.fixAfterInsertion(s),this.size_++,null},p.prototype.fixAfterInsertion=function(t){for(t.color=1;null!=t&&t!==this.root_&&1===t.parent.color;)if(a(t)===l(a(a(t)))){var e=c(a(a(t)));1===s(e)?(u(a(t),Mt),u(e,Mt),u(a(a(t)),1),t=a(a(t))):(t===c(a(t))&&(t=a(t),this.rotateLeft(t)),u(a(t),Mt),u(a(a(t)),1),this.rotateRight(a(a(t))))}else{var n=l(a(a(t)));1===s(n)?(u(a(t),Mt),u(n,Mt),u(a(a(t)),1),t=a(a(t))):(t===l(a(t))&&(t=a(t),this.rotateRight(t)),u(a(t),Mt),u(a(a(t)),1),this.rotateLeft(a(a(t))))}this.root_.color=Mt},p.prototype.values=function(){var t=new Nt,e=this.getFirstEntry();if(null!==e)for(t.add(e.value);null!==(e=p.successor(e));)t.add(e.value);return t},p.prototype.entrySet=function(){var t=new Pt,e=this.getFirstEntry();if(null!==e)for(t.add(e);null!==(e=p.successor(e));)t.add(e);return t},p.prototype.rotateLeft=function(t){if(null!=t){var e=t.right;t.right=e.left,null!=e.left&&(e.left.parent=t),e.parent=t.parent,null===t.parent?this.root_=e:t.parent.left===t?t.parent.left=e:t.parent.right=e,e.left=t,t.parent=e}},p.prototype.rotateRight=function(t){if(null!=t){var e=t.left;t.left=e.right,null!=e.right&&(e.right.parent=t),e.parent=t.parent,null===t.parent?this.root_=e:t.parent.right===t?t.parent.right=e:t.parent.left=e,e.right=t,t.parent=e}},p.prototype.getFirstEntry=function(){var t=this.root_;if(null!=t)for(;null!=t.left;)t=t.left;return t},p.successor=function(t){if(null===t)return null;if(null!==t.right){for(var e=t.right;null!==e.left;)e=e.left;return e}for(var n=t.parent,i=t;null!==n&&i===n.right;)i=n,n=n.parent;return n},p.prototype.size=function(){return this.size_};var At=function(){};At.prototype.interfaces_=function(){return[]},At.prototype.getClass=function(){return At},h.prototype=new o,(f.prototype=new h).contains=function(t){for(var e=0,n=this.array_.length;e=0;){var s=r.substring(0,o);i.add(s),o=(r=r.substring(o+n)).indexOf(e)}r.length>0&&i.add(r);for(var a=new Array(i.size()).fill(null),u=0;u0)for(var o=r;o0&&i.append(" ");for(var o=0;o0&&i.append(","),i.append(jt.toString(t.getOrdinate(r,o)))}return i.append(")"),i.toString()}},Wt.ensureValidRing=function(t,e){var n=e.size();if(0===n)return e;if(n<=3)return Wt.createClosedRing(t,e,4);return e.getOrdinate(0,V.X)===e.getOrdinate(n-1,V.X)&&e.getOrdinate(0,V.Y)===e.getOrdinate(n-1,V.Y)?e:Wt.createClosedRing(t,e,n+1)},Wt.createClosedRing=function(t,e,n){var i=t.create(n,e.getDimension()),r=e.size();Wt.copy(e,0,i,0,r);for(var o=r;o0&&Wt.reverse(this._points),null}},e.prototype.getCoordinate=function(){return this.isEmpty()?null:this._points.getCoordinate(0)},e.prototype.getBoundaryDimension=function(){return this.isClosed()?qt.FALSE:0},e.prototype.isClosed=function(){return!this.isEmpty()&&this.getCoordinateN(0).equals2D(this.getCoordinateN(this.getNumPoints()-1))},e.prototype.getEndPoint=function(){return this.isEmpty()?null:this.getPointN(this.getNumPoints()-1)},e.prototype.getDimension=function(){return 1},e.prototype.getLength=function(){return at.computeLength(this._points)},e.prototype.getNumPoints=function(){return this._points.size()},e.prototype.reverse=function(){var t=this._points.copy();Wt.reverse(t);return this.getFactory().createLineString(t)},e.prototype.compareToSameClass=function(){if(1===arguments.length){for(var t=arguments[0],e=0,n=0;e= 2)");this._points=t},e.prototype.isCoordinate=function(t){for(var e=0;e=1&&this.getCoordinateSequence().size()= 4)")},e.prototype.getGeometryType=function(){return"LinearRing"},e.prototype.copy=function(){return new e(this._points.copy(),this._factory)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},n.MINIMUM_VALID_SIZE.get=function(){return 4},n.serialVersionUID.get=function(){return-0x3b229e262367a600},Object.defineProperties(e,n),e}(Kt),ne=function(t){function e(){t.apply(this,arguments)}t&&(e.__proto__=t),(e.prototype=Object.create(t&&t.prototype)).constructor=e;var n={serialVersionUID:{configurable:!0}};return e.prototype.getSortIndex=function(){return ct.SORTINDEX_MULTIPOLYGON},e.prototype.equalsExact=function(){if(2===arguments.length){var e=arguments[0],n=arguments[1];return!!this.isEquivalentClass(e)&&t.prototype.equalsExact.call(this,e,n)}return t.prototype.equalsExact.apply(this,arguments)},e.prototype.getBoundaryDimension=function(){return 1},e.prototype.getDimension=function(){return 2},e.prototype.reverse=function(){for(var t=this._geometries.length,e=new Array(t).fill(null),n=0;n0?e.createPoint(n[0]):e.createPoint():t},se.prototype.interfaces_=function(){return[ie.GeometryEditorOperation]},se.prototype.getClass=function(){return se};var ae=function(){};ae.prototype.edit=function(t,e){return t instanceof ee?e.createLinearRing(this.edit(t.getCoordinateSequence(),t)):t instanceof Kt?e.createLineString(this.edit(t.getCoordinateSequence(),t)):t instanceof Qt?e.createPoint(this.edit(t.getCoordinateSequence(),t)):t},ae.prototype.interfaces_=function(){return[ie.GeometryEditorOperation]},ae.prototype.getClass=function(){return ae};var ue=function(){if(this._dimension=3,this._coordinates=null,1===arguments.length){if(arguments[0]instanceof Array)this._coordinates=arguments[0],this._dimension=3;else if(Number.isInteger(arguments[0])){var t=arguments[0];this._coordinates=new Array(t).fill(null);for(var e=0;e0){var t=new D(17*this._coordinates.length);t.append("("),t.append(this._coordinates[0]);for(var e=1;e3&&(i=3),i<2?new ue(n):new ue(n,i)}},ce.prototype.interfaces_=function(){return[b,e]},ce.prototype.getClass=function(){return ce},ce.instance=function(){return ce.instanceObject},pe.serialVersionUID.get=function(){return-0x38e49fa6cf6f2e00},pe.instanceObject.get=function(){return new ce},Object.defineProperties(ce,pe);var he=function(t){function e(){t.call(this),this.map_=new Map}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.get=function(t){return this.map_.get(t)||null},e.prototype.put=function(t,e){return this.map_.set(t,e),e},e.prototype.values=function(){for(var t=new Nt,e=this.map_.values(),n=e.next();!n.done;)t.add(n.value),n=e.next();return t},e.prototype.entrySet=function(){var t=new Pt;return this.map_.entries().forEach(function(e){return t.add(e)}),t},e.prototype.size=function(){return this.map_.size()},e}(Tt),fe=function t(){if(this._modelType=null,this._scale=null,0===arguments.length)this._modelType=t.FLOATING;else if(1===arguments.length)if(arguments[0]instanceof de){var e=arguments[0];this._modelType=e,e===t.FIXED&&this.setScale(1)}else if("number"==typeof arguments[0]){var n=arguments[0];this._modelType=t.FIXED,this.setScale(n)}else if(arguments[0]instanceof t){var i=arguments[0];this._modelType=i._modelType,this._scale=i._scale}},ge={serialVersionUID:{configurable:!0},maximumPreciseValue:{configurable:!0}};fe.prototype.equals=function(t){if(!(t instanceof fe))return!1;var e=t;return this._modelType===e._modelType&&this._scale===e._scale},fe.prototype.compareTo=function(t){var e=t,n=this.getMaximumSignificantDigits(),i=e.getMaximumSignificantDigits();return new M(n).compareTo(new M(i))},fe.prototype.getScale=function(){return this._scale},fe.prototype.isFloating=function(){return this._modelType===fe.FLOATING||this._modelType===fe.FLOATING_SINGLE},fe.prototype.getType=function(){return this._modelType},fe.prototype.toString=function(){var t="UNKNOWN";return this._modelType===fe.FLOATING?t="Floating":this._modelType===fe.FLOATING_SINGLE?t="Floating-Single":this._modelType===fe.FIXED&&(t="Fixed (Scale="+this.getScale()+")"),t},fe.prototype.makePrecise=function(){if("number"==typeof arguments[0]){var t=arguments[0];if(v.isNaN(t))return t;if(this._modelType===fe.FLOATING_SINGLE){return t}return this._modelType===fe.FIXED?Math.round(t*this._scale)/this._scale:t}if(arguments[0]instanceof C){var e=arguments[0];if(this._modelType===fe.FLOATING)return null;e.x=this.makePrecise(e.x),e.y=this.makePrecise(e.y)}},fe.prototype.getMaximumSignificantDigits=function(){var t=16;return this._modelType===fe.FLOATING?t=16:this._modelType===fe.FLOATING_SINGLE?t=6:this._modelType===fe.FIXED&&(t=1+Math.trunc(Math.ceil(Math.log(this.getScale())/Math.log(10)))),t},fe.prototype.setScale=function(t){this._scale=Math.abs(t)},fe.prototype.interfaces_=function(){return[e,E]},fe.prototype.getClass=function(){return fe},fe.mostPrecise=function(t,e){return t.compareTo(e)>=0?t:e},ge.serialVersionUID.get=function(){return 0x6bee6404e9a25c00},ge.maximumPreciseValue.get=function(){return 9007199254740992},Object.defineProperties(fe,ge);var de=function t(e){this._name=e||null,t.nameToTypeMap.put(e,this)},ye={serialVersionUID:{configurable:!0},nameToTypeMap:{configurable:!0}};de.prototype.readResolve=function(){return de.nameToTypeMap.get(this._name)},de.prototype.toString=function(){return this._name},de.prototype.interfaces_=function(){return[e]},de.prototype.getClass=function(){return de},ye.serialVersionUID.get=function(){return-552860263173159e4},ye.nameToTypeMap.get=function(){return new he},Object.defineProperties(de,ye),fe.Type=de,fe.FIXED=new de("FIXED"),fe.FLOATING=new de("FLOATING"),fe.FLOATING_SINGLE=new de("FLOATING SINGLE");var _e=function t(){this._precisionModel=new fe,this._SRID=0,this._coordinateSequenceFactory=t.getDefaultCoordinateSequenceFactory(),0===arguments.length||(1===arguments.length?T(arguments[0],b)?this._coordinateSequenceFactory=arguments[0]:arguments[0]instanceof fe&&(this._precisionModel=arguments[0]):2===arguments.length?(this._precisionModel=arguments[0],this._SRID=arguments[1]):3===arguments.length&&(this._precisionModel=arguments[0],this._SRID=arguments[1],this._coordinateSequenceFactory=arguments[2]))},me={serialVersionUID:{configurable:!0}};_e.prototype.toGeometry=function(t){return t.isNull()?this.createPoint(null):t.getMinX()===t.getMaxX()&&t.getMinY()===t.getMaxY()?this.createPoint(new C(t.getMinX(),t.getMinY())):t.getMinX()===t.getMaxX()||t.getMinY()===t.getMaxY()?this.createLineString([new C(t.getMinX(),t.getMinY()),new C(t.getMaxX(),t.getMaxY())]):this.createPolygon(this.createLinearRing([new C(t.getMinX(),t.getMinY()),new C(t.getMinX(),t.getMaxY()),new C(t.getMaxX(),t.getMaxY()),new C(t.getMaxX(),t.getMinY()),new C(t.getMinX(),t.getMinY())]),null)},_e.prototype.createLineString=function(t){return t?t instanceof Array?new Kt(this.getCoordinateSequenceFactory().create(t),this):T(t,V)?new Kt(t,this):void 0:new Kt(this.getCoordinateSequenceFactory().create([]),this)},_e.prototype.createMultiLineString=function(){if(0===arguments.length)return new Xt(null,this);if(1===arguments.length){var t=arguments[0];return new Xt(t,this)}},_e.prototype.buildGeometry=function(t){for(var e=null,n=!1,i=!1,r=t.iterator();r.hasNext();){var o=r.next(),s=o.getClass();null===e&&(e=s),s!==e&&(n=!0),o.isGeometryCollectionOrDerived()&&(i=!0)}if(null===e)return this.createGeometryCollection();if(n||i)return this.createGeometryCollection(_e.toGeometryArray(t));var a=t.iterator().next();if(t.size()>1){if(a instanceof $t)return this.createMultiPolygon(_e.toPolygonArray(t));if(a instanceof Kt)return this.createMultiLineString(_e.toLineStringArray(t));if(a instanceof Qt)return this.createMultiPoint(_e.toPointArray(t));et.shouldNeverReachHere("Unhandled class: "+a.getClass().getName())}return a},_e.prototype.createMultiPointFromCoords=function(t){return this.createMultiPoint(null!==t?this.getCoordinateSequenceFactory().create(t):null)},_e.prototype.createPoint=function(){if(0===arguments.length)return this.createPoint(this.getCoordinateSequenceFactory().create([]));if(1===arguments.length){if(arguments[0]instanceof C){var t=arguments[0];return this.createPoint(null!==t?this.getCoordinateSequenceFactory().create([t]):null)}if(T(arguments[0],V)){var e=arguments[0];return new Qt(e,this)}}},_e.prototype.getCoordinateSequenceFactory=function(){return this._coordinateSequenceFactory},_e.prototype.createPolygon=function(){if(0===arguments.length)return new $t(null,null,this);if(1===arguments.length){if(T(arguments[0],V)){var t=arguments[0];return this.createPolygon(this.createLinearRing(t))}if(arguments[0]instanceof Array){var e=arguments[0];return this.createPolygon(this.createLinearRing(e))}if(arguments[0]instanceof ee){var n=arguments[0];return this.createPolygon(n,null)}}else if(2===arguments.length){var i=arguments[0],r=arguments[1];return new $t(i,r,this)}},_e.prototype.getSRID=function(){return this._SRID},_e.prototype.createGeometryCollection=function(){if(0===arguments.length)return new zt(null,this);if(1===arguments.length){var t=arguments[0];return new zt(t,this)}},_e.prototype.createGeometry=function(t){return new ie(this).edit(t,{edit:function(){if(2===arguments.length){var t=arguments[0];return this._coordinateSequenceFactory.create(t)}}})},_e.prototype.getPrecisionModel=function(){return this._precisionModel},_e.prototype.createLinearRing=function(){if(0===arguments.length)return this.createLinearRing(this.getCoordinateSequenceFactory().create([]));if(1===arguments.length){if(arguments[0]instanceof Array){var t=arguments[0];return this.createLinearRing(null!==t?this.getCoordinateSequenceFactory().create(t):null)}if(T(arguments[0],V)){var e=arguments[0];return new ee(e,this)}}},_e.prototype.createMultiPolygon=function(){if(0===arguments.length)return new ne(null,this);if(1===arguments.length){var t=arguments[0];return new ne(t,this)}},_e.prototype.createMultiPoint=function(){if(0===arguments.length)return new te(null,this);if(1===arguments.length){if(arguments[0]instanceof Array){var t=arguments[0];return new te(t,this)}if(arguments[0]instanceof Array){var e=arguments[0];return this.createMultiPoint(null!==e?this.getCoordinateSequenceFactory().create(e):null)}if(T(arguments[0],V)){var n=arguments[0];if(null===n)return this.createMultiPoint(new Array(0).fill(null));for(var i=new Array(n.size()).fill(null),r=0;r=this.size())throw new Error;return this.array_[t]},y.prototype.push=function(t){return this.array_.push(t),t},y.prototype.pop=function(t){if(0===this.array_.length)throw new d;return this.array_.pop()},y.prototype.peek=function(){if(0===this.array_.length)throw new d;return this.array_[this.array_.length-1]},y.prototype.empty=function(){return 0===this.array_.length},y.prototype.isEmpty=function(){return this.empty()},y.prototype.search=function(t){return this.array_.indexOf(t)},y.prototype.size=function(){return this.array_.length},y.prototype.toArray=function(){for(var t=[],e=0,n=this.array_.length;e0&&this._minIndexthis._minCoord.y&&n.y>this._minCoord.y&&i===at.CLOCKWISE&&(r=!0),r&&(this._minIndex=this._minIndex-1)},be.prototype.getRightmostSideOfSegment=function(t,e){var n=t.getEdge().getCoordinates();if(e<0||e+1>=n.length)return-1;if(n[e].y===n[e+1].y)return-1;var i=Se.LEFT;return n[e].ythis._minCoord.x)&&(this._minDe=t,this._minIndex=n,this._minCoord=e[n])},be.prototype.findRightmostEdgeAtNode=function(){var t=this._minDe.getNode().getEdges();this._minDe=t.getRightmostEdge(),this._minDe.isForward()||(this._minDe=this._minDe.getSym(),this._minIndex=this._minDe.getEdge().getCoordinates().length-1)},be.prototype.findEdge=function(t){for(var e=t.iterator();e.hasNext();){var n=e.next();n.isForward()&&this.checkForRightmostCoordinate(n)}et.isTrue(0!==this._minIndex||this._minCoord.equals(this._minDe.getCoordinate()),"inconsistency in rightmost processing"),0===this._minIndex?this.findRightmostEdgeAtNode():this.findRightmostEdgeAtVertex(),this._orientedDe=this._minDe;this.getRightmostSide(this._minDe,this._minIndex)===Se.LEFT&&(this._orientedDe=this._minDe.getSym())},be.prototype.interfaces_=function(){return[]},be.prototype.getClass=function(){return be};var we=function(t){function e(n,i){t.call(this,e.msgWithCoord(n,i)),this.pt=i?new C(i):null,this.name="TopologyException"}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getCoordinate=function(){return this.pt},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e.msgWithCoord=function(t,e){return e?t:t+" [ "+e+" ]"},e}($),Oe=function(){this.array_=[]};Oe.prototype.addLast=function(t){this.array_.push(t)},Oe.prototype.removeFirst=function(){return this.array_.shift()},Oe.prototype.isEmpty=function(){return 0===this.array_.length};var Te=function(){this._finder=null,this._dirEdgeList=new Nt,this._nodes=new Nt,this._rightMostCoord=null,this._env=null,this._finder=new be};Te.prototype.clearVisitedEdges=function(){for(var t=this._dirEdgeList.iterator();t.hasNext();){t.next().setVisited(!1)}},Te.prototype.getRightmostCoordinate=function(){return this._rightMostCoord},Te.prototype.computeNodeDepth=function(t){for(var e=null,n=t.getEdges().iterator();n.hasNext();){var i=n.next();if(i.isVisited()||i.getSym().isVisited()){e=i;break}}if(null===e)throw new we("unable to find edge to compute depths at "+t.getCoordinate());t.getEdges().computeDepths(e);for(var r=t.getEdges().iterator();r.hasNext();){var o=r.next();o.setVisited(!0),this.copySymDepths(o)}},Te.prototype.computeDepth=function(t){this.clearVisitedEdges();var e=this._finder.getEdge();e.setEdgeDepths(Se.RIGHT,t),this.copySymDepths(e),this.computeDepths(e)},Te.prototype.create=function(t){this.addReachable(t),this._finder.findEdge(this._dirEdgeList),this._rightMostCoord=this._finder.getCoordinate()},Te.prototype.findResultEdges=function(){for(var t=this._dirEdgeList.iterator();t.hasNext();){var e=t.next();e.getDepth(Se.RIGHT)>=1&&e.getDepth(Se.LEFT)<=0&&!e.isInteriorAreaEdge()&&e.setInResult(!0)}},Te.prototype.computeDepths=function(t){var e=new Pt,n=new Oe,i=t.getNode();for(n.addLast(i),e.add(i),t.setVisited(!0);!n.isEmpty();){var r=n.removeFirst();e.add(r),this.computeNodeDepth(r);for(var o=r.getEdges().iterator();o.hasNext();){var s=o.next().getSym();if(!s.isVisited()){var a=s.getNode();e.contains(a)||(n.addLast(a),e.add(a))}}}},Te.prototype.compareTo=function(t){var e=t;return this._rightMostCoord.xe._rightMostCoord.x?1:0},Te.prototype.getEnvelope=function(){if(null===this._env){for(var t=new j,e=this._dirEdgeList.iterator();e.hasNext();)for(var n=e.next().getEdge().getCoordinates(),i=0;ithis.location.length){var e=new Array(3).fill(null);e[Se.ON]=this.location[Se.ON],e[Se.LEFT]=w.NONE,e[Se.RIGHT]=w.NONE,this.location=e}for(var n=0;n1&&t.append(w.toLocationSymbol(this.location[Se.LEFT])),t.append(w.toLocationSymbol(this.location[Se.ON])),this.location.length>1&&t.append(w.toLocationSymbol(this.location[Se.RIGHT])),t.toString()},Re.prototype.setLocations=function(t,e,n){this.location[Se.ON]=t,this.location[Se.LEFT]=e,this.location[Se.RIGHT]=n},Re.prototype.get=function(t){return t1},Re.prototype.isAnyNull=function(){for(var t=0;tthis._maxNodeDegree&&(this._maxNodeDegree=e),t=this.getNext(t)}while(t!==this._startDe);this._maxNodeDegree*=2},De.prototype.addPoints=function(t,e,n){var i=t.getCoordinates();if(e){var r=1;n&&(r=0);for(var o=r;o=0;a--)this._pts.add(i[a])}},De.prototype.isHole=function(){return this._isHole},De.prototype.setInResult=function(){var t=this._startDe;do{t.getEdge().setInResult(!0),t=t.getNext()}while(t!==this._startDe)},De.prototype.containsPoint=function(t){var e=this.getLinearRing();if(!e.getEnvelopeInternal().contains(t))return!1;if(!at.isPointInRing(t,e.getCoordinates()))return!1;for(var n=this._holes.iterator();n.hasNext();){if(n.next().containsPoint(t))return!1}return!0},De.prototype.addHole=function(t){this._holes.add(t)},De.prototype.isShell=function(){return null===this._shell},De.prototype.getLabel=function(){return this._label},De.prototype.getEdges=function(){return this._edges},De.prototype.getMaxNodeDegree=function(){return this._maxNodeDegree<0&&this.computeMaxNodeDegree(),this._maxNodeDegree},De.prototype.getShell=function(){return this._shell},De.prototype.mergeLabel=function(){if(1===arguments.length){var t=arguments[0];this.mergeLabel(t,0),this.mergeLabel(t,1)}else if(2===arguments.length){var e=arguments[0],n=arguments[1],i=e.getLocation(n,Se.RIGHT);if(i===w.NONE)return null;if(this._label.getLocation(n)===w.NONE)return this._label.setLocation(n,i),null}},De.prototype.setShell=function(t){this._shell=t,null!==t&&t.addHole(this)},De.prototype.toPolygon=function(t){for(var e=new Array(this._holes.size()).fill(null),n=0;n=2,"found partial label"),this.computeIM(t)},Fe.prototype.isInResult=function(){return this._isInResult},Fe.prototype.isVisited=function(){return this._isVisited},Fe.prototype.interfaces_=function(){return[]},Fe.prototype.getClass=function(){return Fe};var Ge=function(t){function e(){t.call(this),this._coord=null,this._edges=null;var e=arguments[0],n=arguments[1];this._coord=e,this._edges=n,this._label=new Pe(0,w.NONE)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.isIncidentEdgeInResult=function(){for(var t=this.getEdges().getEdges().iterator();t.hasNext();){if(t.next().getEdge().isInResult())return!0}return!1},e.prototype.isIsolated=function(){return 1===this._label.getGeometryCount()},e.prototype.getCoordinate=function(){return this._coord},e.prototype.print=function(t){t.println("node "+this._coord+" lbl: "+this._label)},e.prototype.computeIM=function(t){},e.prototype.computeMergedLocation=function(t,e){var n=w.NONE;if(n=this._label.getLocation(e),!t.isNull(e)){var i=t.getLocation(e);n!==w.BOUNDARY&&(n=i)}return n},e.prototype.setLabel=function(){if(2!==arguments.length)return t.prototype.setLabel.apply(this,arguments);var e=arguments[0],n=arguments[1];null===this._label?this._label=new Pe(e,n):this._label.setLocation(e,n)},e.prototype.getEdges=function(){return this._edges},e.prototype.mergeLabel=function(){if(arguments[0]instanceof e){var t=arguments[0];this.mergeLabel(t._label)}else if(arguments[0]instanceof Pe)for(var n=arguments[0],i=0;i<2;i++){var r=this.computeMergedLocation(n,i);this._label.getLocation(i)===w.NONE&&this._label.setLocation(i,r)}},e.prototype.add=function(t){this._edges.insert(t),t.setNode(this)},e.prototype.setLabelBoundary=function(t){if(null===this._label)return null;var e=w.NONE;null!==this._label&&(e=this._label.getLocation(t));var n=null;switch(e){case w.BOUNDARY:n=w.INTERIOR;break;case w.INTERIOR:default:n=w.BOUNDARY}this._label.setLocation(t,n)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Fe),qe=function(){this.nodeMap=new p,this.nodeFact=null;var t=arguments[0];this.nodeFact=t};qe.prototype.find=function(t){return this.nodeMap.get(t)},qe.prototype.addNode=function(){if(arguments[0]instanceof C){var t=arguments[0],e=this.nodeMap.get(t);return null===e&&(e=this.nodeFact.createNode(t),this.nodeMap.put(t,e)),e}if(arguments[0]instanceof Ge){var n=arguments[0],i=this.nodeMap.get(n.getCoordinate());return null===i?(this.nodeMap.put(n.getCoordinate(),n),n):(i.mergeLabel(n),i)}},qe.prototype.print=function(t){for(var e=this.iterator();e.hasNext();){e.next().print(t)}},qe.prototype.iterator=function(){return this.nodeMap.values().iterator()},qe.prototype.values=function(){return this.nodeMap.values()},qe.prototype.getBoundaryNodes=function(t){for(var e=new Nt,n=this.iterator();n.hasNext();){var i=n.next();i.getLabel().getLocation(t)===w.BOUNDARY&&e.add(i)}return e},qe.prototype.add=function(t){var e=t.getCoordinate();this.addNode(e).add(t)},qe.prototype.interfaces_=function(){return[]},qe.prototype.getClass=function(){return qe};var Be=function(){},Ve={NE:{configurable:!0},NW:{configurable:!0},SW:{configurable:!0},SE:{configurable:!0}};Be.prototype.interfaces_=function(){return[]},Be.prototype.getClass=function(){return Be},Be.isNorthern=function(t){return t===Be.NE||t===Be.NW},Be.isOpposite=function(t,e){if(t===e)return!1;return 2===(t-e+4)%4},Be.commonHalfPlane=function(t,e){if(t===e)return t;if(2===(t-e+4)%4)return-1;var n=te?t:e)?3:n},Be.isInHalfPlane=function(t,e){return e===Be.SE?t===Be.SE||t===Be.SW:t===e||t===e+1},Be.quadrant=function(){if("number"==typeof arguments[0]&&"number"==typeof arguments[1]){var t=arguments[0],e=arguments[1];if(0===t&&0===e)throw new m("Cannot compute the quadrant for point ( "+t+", "+e+" )");return t>=0?e>=0?Be.NE:Be.SE:e>=0?Be.NW:Be.SW}if(arguments[0]instanceof C&&arguments[1]instanceof C){var n=arguments[0],i=arguments[1];if(i.x===n.x&&i.y===n.y)throw new m("Cannot compute the quadrant for two identical points "+n);return i.x>=n.x?i.y>=n.y?Be.NE:Be.SE:i.y>=n.y?Be.NW:Be.SW}},Ve.NE.get=function(){return 0},Ve.NW.get=function(){return 1},Ve.SW.get=function(){return 2},Ve.SE.get=function(){return 3},Object.defineProperties(Be,Ve);var Ue=function(){if(this._edge=null,this._label=null,this._node=null,this._p0=null,this._p1=null,this._dx=null,this._dy=null,this._quadrant=null,1===arguments.length){var t=arguments[0];this._edge=t}else if(3===arguments.length){var e=arguments[0],n=arguments[1],i=arguments[2];this._edge=e,this.init(n,i),this._label=null}else if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3];this._edge=r,this.init(o,s),this._label=a}};Ue.prototype.compareDirection=function(t){return this._dx===t._dx&&this._dy===t._dy?0:this._quadrant>t._quadrant?1:this._quadrant2){o.linkDirectedEdgesForMinimalEdgeRings();var s=o.buildMinimalRings(),a=this.findShell(s);null!==a?(this.placePolygonHoles(a,s),e.add(a)):n.addAll(s)}else i.add(o)}return i},ke.prototype.containsPoint=function(t){for(var e=this._shellList.iterator();e.hasNext();){if(e.next().containsPoint(t))return!0}return!1},ke.prototype.buildMaximalEdgeRings=function(t){for(var e=new Nt,n=t.iterator();n.hasNext();){var i=n.next();if(i.isInResult()&&i.getLabel().isArea()&&null===i.getEdgeRing()){var r=new Ae(i,this._geometryFactory);e.add(r),r.setInResult()}}return e},ke.prototype.placePolygonHoles=function(t,e){for(var n=e.iterator();n.hasNext();){var i=n.next();i.isHole()&&i.setShell(t)}},ke.prototype.getPolygons=function(){return this.computePolygons(this._shellList)},ke.prototype.findEdgeRingContaining=function(t,e){for(var n=t.getLinearRing(),i=n.getEnvelopeInternal(),r=n.getCoordinateN(0),o=null,s=null,a=e.iterator();a.hasNext();){var u=a.next(),l=u.getLinearRing(),c=l.getEnvelopeInternal();null!==o&&(s=o.getLinearRing().getEnvelopeInternal());var p=!1;c.contains(i)&&at.isPointInRing(r,l.getCoordinates())&&(p=!0),p&&(null===o||s.contains(c))&&(o=u)}return o},ke.prototype.findShell=function(t){for(var e=0,n=null,i=t.iterator();i.hasNext();){var r=i.next();r.isHole()||(n=r,e++)}return et.isTrue(e<=1,"found two shells in MinimalEdgeRing list"),n},ke.prototype.add=function(){if(1===arguments.length){var t=arguments[0];this.add(t.getEdgeEnds(),t.getNodes())}else if(2===arguments.length){var e=arguments[0],n=arguments[1];Ye.linkResultDirectedEdges(n);var i=this.buildMaximalEdgeRings(e),r=new Nt,o=this.buildMinimalEdgeRings(i,this._shellList,r);this.sortShellsAndHoles(o,this._shellList,r),this.placeFreeHoles(this._shellList,r)}},ke.prototype.interfaces_=function(){return[]},ke.prototype.getClass=function(){return ke};var je=function(){};je.prototype.getBounds=function(){},je.prototype.interfaces_=function(){return[]},je.prototype.getClass=function(){return je};var He=function(){this._bounds=null,this._item=null;var t=arguments[0],e=arguments[1];this._bounds=t,this._item=e};He.prototype.getItem=function(){return this._item},He.prototype.getBounds=function(){return this._bounds},He.prototype.interfaces_=function(){return[je,e]},He.prototype.getClass=function(){return He};var We=function(){this._size=null,this._items=null,this._size=0,this._items=new Nt,this._items.add(null)};We.prototype.poll=function(){if(this.isEmpty())return null;var t=this._items.get(1);return this._items.set(1,this._items.get(this._size)),this._size-=1,this.reorder(1),t},We.prototype.size=function(){return this._size},We.prototype.reorder=function(t){for(var e=null,n=this._items.get(t);2*t<=this._size&&((e=2*t)!==this._size&&this._items.get(e+1).compareTo(this._items.get(e))<0&&e++,this._items.get(e).compareTo(n)<0);t=e)this._items.set(t,this._items.get(e));this._items.set(t,n)},We.prototype.clear=function(){this._size=0,this._items.clear()},We.prototype.isEmpty=function(){return 0===this._size},We.prototype.add=function(t){this._items.add(null),this._size+=1;var e=this._size;for(this._items.set(0,t);t.compareTo(this._items.get(Math.trunc(e/2)))<0;e/=2)this._items.set(e,this._items.get(Math.trunc(e/2)));this._items.set(e,t)},We.prototype.interfaces_=function(){return[]},We.prototype.getClass=function(){return We};var Ke=function(){};Ke.prototype.visitItem=function(t){},Ke.prototype.interfaces_=function(){return[]},Ke.prototype.getClass=function(){return Ke};var Je=function(){};Je.prototype.insert=function(t,e){},Je.prototype.remove=function(t,e){},Je.prototype.query=function(){},Je.prototype.interfaces_=function(){return[]},Je.prototype.getClass=function(){return Je};var Qe=function(){if(this._childBoundables=new Nt,this._bounds=null,this._level=null,0===arguments.length);else if(1===arguments.length){var t=arguments[0];this._level=t}},Ze={serialVersionUID:{configurable:!0}};Qe.prototype.getLevel=function(){return this._level},Qe.prototype.size=function(){return this._childBoundables.size()},Qe.prototype.getChildBoundables=function(){return this._childBoundables},Qe.prototype.addChildBoundable=function(t){et.isTrue(null===this._bounds),this._childBoundables.add(t)},Qe.prototype.isEmpty=function(){return this._childBoundables.isEmpty()},Qe.prototype.getBounds=function(){return null===this._bounds&&(this._bounds=this.computeBounds()),this._bounds},Qe.prototype.interfaces_=function(){return[je,e]},Qe.prototype.getClass=function(){return Qe},Ze.serialVersionUID.get=function(){return 0x5a1e55ec41369800},Object.defineProperties(Qe,Ze);var $e=function(){};$e.reverseOrder=function(){return{compare:function(t,e){return e.compareTo(t)}}},$e.min=function(t){return $e.sort(t),t.get(0)},$e.sort=function(t,e){var n=t.toArray();e?Gt.sort(n,e):Gt.sort(n);for(var i=t.iterator(),r=0,o=n.length;rtn.area(this._boundable2)?(this.expand(this._boundable1,this._boundable2,t,e),null):(this.expand(this._boundable2,this._boundable1,t,e),null);if(n)return this.expand(this._boundable1,this._boundable2,t,e),null;if(i)return this.expand(this._boundable2,this._boundable1,t,e),null;throw new m("neither boundable is composite")},tn.prototype.isLeaves=function(){return!(tn.isComposite(this._boundable1)||tn.isComposite(this._boundable2))},tn.prototype.compareTo=function(t){var e=t;return this._distancee._distance?1:0},tn.prototype.expand=function(t,e,n,i){for(var r=t.getChildBoundables().iterator();r.hasNext();){var o=r.next(),s=new tn(o,e,this._itemDistance);s.getDistance()1,"Node capacity must be greater than 1"),this._nodeCapacity=n}},nn={IntersectsOp:{configurable:!0},serialVersionUID:{configurable:!0},DEFAULT_NODE_CAPACITY:{configurable:!0}};en.prototype.getNodeCapacity=function(){return this._nodeCapacity},en.prototype.lastNode=function(t){return t.get(t.size()-1)},en.prototype.size=function(){if(0===arguments.length)return this.isEmpty()?0:(this.build(),this.size(this._root));if(1===arguments.length){for(var t=0,e=arguments[0].getChildBoundables().iterator();e.hasNext();){var n=e.next();n instanceof Qe?t+=this.size(n):n instanceof He&&(t+=1)}return t}},en.prototype.removeItem=function(t,e){for(var n=null,i=t.getChildBoundables().iterator();i.hasNext();){var r=i.next();r instanceof He&&r.getItem()===e&&(n=r)}return null!==n&&(t.getChildBoundables().remove(n),!0)},en.prototype.itemsTree=function(){if(0===arguments.length){this.build();var t=this.itemsTree(this._root);return null===t?new Nt:t}if(1===arguments.length){for(var e=arguments[0],n=new Nt,i=e.getChildBoundables().iterator();i.hasNext();){var r=i.next();if(r instanceof Qe){var o=this.itemsTree(r);null!==o&&n.add(o)}else r instanceof He?n.add(r.getItem()):et.shouldNeverReachHere()}return n.size()<=0?null:n}},en.prototype.insert=function(t,e){et.isTrue(!this._built,"Cannot insert items into an STR packed R-tree after it has been built."),this._itemBoundables.add(new He(t,e))},en.prototype.boundablesAtLevel=function(){if(1===arguments.length){var t=arguments[0],e=new Nt;return this.boundablesAtLevel(t,this._root,e),e}if(3===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[2];if(et.isTrue(n>-2),i.getLevel()===n)return r.add(i),null;for(var o=i.getChildBoundables().iterator();o.hasNext();){var s=o.next();s instanceof Qe?this.boundablesAtLevel(n,s,r):(et.isTrue(s instanceof He),-1===n&&r.add(s))}return null}},en.prototype.query=function(){if(1===arguments.length){var t=arguments[0];this.build();var e=new Nt;return this.isEmpty()?e:(this.getIntersectsOp().intersects(this._root.getBounds(),t)&&this.query(t,this._root,e),e)}if(2===arguments.length){var n=arguments[0],i=arguments[1];if(this.build(),this.isEmpty())return null;this.getIntersectsOp().intersects(this._root.getBounds(),n)&&this.query(n,this._root,i)}else if(3===arguments.length)if(T(arguments[2],Ke)&&arguments[0]instanceof Object&&arguments[1]instanceof Qe)for(var r=arguments[0],o=arguments[1],s=arguments[2],a=o.getChildBoundables(),u=0;ut&&(t=i)}}return t+1}},en.prototype.createParentBoundables=function(t,e){et.isTrue(!t.isEmpty());var n=new Nt;n.add(this.createNode(e));var i=new Nt(t);$e.sort(i,this.getComparator());for(var r=i.iterator();r.hasNext();){var o=r.next();this.lastNode(n).getChildBoundables().size()===this.getNodeCapacity()&&n.add(this.createNode(e)),this.lastNode(n).addChildBoundable(o)}return n},en.prototype.isEmpty=function(){return this._built?this._root.isEmpty():this._itemBoundables.isEmpty()},en.prototype.interfaces_=function(){return[e]},en.prototype.getClass=function(){return en},en.compareDoubles=function(t,e){return t>e?1:t0);for(var n=new Nt,i=0;i0;){var p=c.poll(),h=p.getDistance();if(h>=u)break;p.isLeaves()?(u=h,l=p):p.expandToQueue(c,u)}return[l.getBoundable(0).getItem(),l.getBoundable(1).getItem()]}}else if(3===arguments.length){var f=arguments[0],g=arguments[1],d=arguments[2],y=new He(f,g),_=new tn(this.getRoot(),y,d);return this.nearestNeighbour(_)[0]}},n.prototype.interfaces_=function(){return[Je,e]},n.prototype.getClass=function(){return n},n.centreX=function(t){return n.avg(t.getMinX(),t.getMaxX())},n.avg=function(t,e){return(t+e)/2},n.centreY=function(t){return n.avg(t.getMinY(),t.getMaxY())},i.STRtreeNode.get=function(){return an},i.serialVersionUID.get=function(){return 0x39920f7d5f261e0},i.xComparator.get=function(){return{interfaces_:function(){return[N]},compare:function(e,i){return t.compareDoubles(n.centreX(e.getBounds()),n.centreX(i.getBounds()))}}},i.yComparator.get=function(){return{interfaces_:function(){return[N]},compare:function(e,i){return t.compareDoubles(n.centreY(e.getBounds()),n.centreY(i.getBounds()))}}},i.intersectsOp.get=function(){return{interfaces_:function(){return[t.IntersectsOp]},intersects:function(t,e){return t.intersects(e)}}},i.DEFAULT_NODE_CAPACITY.get=function(){return 10},Object.defineProperties(n,i),n}(en),an=function(t){function e(){var e=arguments[0];t.call(this,e)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.computeBounds=function(){for(var t=null,e=this.getChildBoundables().iterator();e.hasNext();){var n=e.next();null===t?t=new j(n.getBounds()):t.expandToInclude(n.getBounds())}return t},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Qe),un=function(){};un.prototype.interfaces_=function(){return[]},un.prototype.getClass=function(){return un},un.relativeSign=function(t,e){return te?1:0},un.compare=function(t,e,n){if(e.equals2D(n))return 0;var i=un.relativeSign(e.x,n.x),r=un.relativeSign(e.y,n.y);switch(t){case 0:return un.compareValue(i,r);case 1:return un.compareValue(r,i);case 2:return un.compareValue(r,-i);case 3:return un.compareValue(-i,r);case 4:return un.compareValue(-i,-r);case 5:return un.compareValue(-r,-i);case 6:return un.compareValue(-r,i);case 7:return un.compareValue(i,-r)}return et.shouldNeverReachHere("invalid octant value"),0},un.compareValue=function(t,e){return t<0?-1:t>0?1:e<0?-1:e>0?1:0};var ln=function(){this._segString=null,this.coord=null,this.segmentIndex=null,this._segmentOctant=null,this._isInterior=null;var t=arguments[0],e=arguments[1],n=arguments[2],i=arguments[3];this._segString=t,this.coord=new C(e),this.segmentIndex=n,this._segmentOctant=i,this._isInterior=!e.equals2D(t.getCoordinate(n))};ln.prototype.getCoordinate=function(){return this.coord},ln.prototype.print=function(t){t.print(this.coord),t.print(" seg # = "+this.segmentIndex)},ln.prototype.compareTo=function(t){var e=t;return this.segmentIndexe.segmentIndex?1:this.coord.equals2D(e.coord)?0:un.compare(this._segmentOctant,this.coord,e.coord)},ln.prototype.isEndPoint=function(t){return 0===this.segmentIndex&&!this._isInterior||this.segmentIndex===t},ln.prototype.isInterior=function(){return this._isInterior},ln.prototype.interfaces_=function(){return[E]},ln.prototype.getClass=function(){return ln};var cn=function(){this._nodeMap=new p,this._edge=null;var t=arguments[0];this._edge=t};cn.prototype.getSplitCoordinates=function(){var t=new St;this.addEndpoints();for(var e=this.iterator(),n=e.next();e.hasNext();){var i=e.next();this.addEdgeCoordinates(n,i,t),n=i}return t.toCoordinateArray()},cn.prototype.addCollapsedNodes=function(){var t=new Nt;this.findCollapsesFromInsertedNodes(t),this.findCollapsesFromExistingVertices(t);for(var e=t.iterator();e.hasNext();){var n=e.next().intValue();this.add(this._edge.getCoordinate(n),n)}},cn.prototype.print=function(t){t.println("Intersections:");for(var e=this.iterator();e.hasNext();){e.next().print(t)}},cn.prototype.findCollapsesFromExistingVertices=function(t){for(var e=0;e=0?e>=0?n>=i?0:1:n>=i?7:6:e>=0?n>=i?3:2:n>=i?4:5}if(arguments[0]instanceof C&&arguments[1]instanceof C){var r=arguments[0],o=arguments[1],s=o.x-r.x,a=o.y-r.y;if(0===s&&0===a)throw new m("Cannot compute the octant for two identical points "+r);return pn.octant(s,a)}};var hn=function(){};hn.prototype.getCoordinates=function(){},hn.prototype.size=function(){},hn.prototype.getCoordinate=function(t){},hn.prototype.isClosed=function(){},hn.prototype.setData=function(t){},hn.prototype.getData=function(){},hn.prototype.interfaces_=function(){return[]},hn.prototype.getClass=function(){return hn};var fn=function(){};fn.prototype.addIntersection=function(t,e){},fn.prototype.interfaces_=function(){return[hn]},fn.prototype.getClass=function(){return fn};var gn=function(){this._nodeList=new cn(this),this._pts=null,this._data=null;var t=arguments[0],e=arguments[1];this._pts=t,this._data=e};gn.prototype.getCoordinates=function(){return this._pts},gn.prototype.size=function(){return this._pts.length},gn.prototype.getCoordinate=function(t){return this._pts[t]},gn.prototype.isClosed=function(){return this._pts[0].equals(this._pts[this._pts.length-1])},gn.prototype.getSegmentOctant=function(t){return t===this._pts.length-1?-1:this.safeOctant(this.getCoordinate(t),this.getCoordinate(t+1))},gn.prototype.setData=function(t){this._data=t},gn.prototype.safeOctant=function(t,e){return t.equals2D(e)?0:pn.octant(t,e)},gn.prototype.getData=function(){return this._data},gn.prototype.addIntersection=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];this.addIntersectionNode(t,e)}else if(4===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[3],o=new C(n.getIntersection(r));this.addIntersection(o,i)}},gn.prototype.toString=function(){return Z.toLineString(new ue(this._pts))},gn.prototype.getNodeList=function(){return this._nodeList},gn.prototype.addIntersectionNode=function(t,e){var n=e,i=n+1;if(i=0&&n>=0?Math.max(e,n):e<=0&&n<=0?Math.max(e,n):0}if(arguments[0]instanceof C){var i=arguments[0];return at.orientationIndex(this.p0,this.p1,i)}},dn.prototype.toGeometry=function(t){return t.createLineString([this.p0,this.p1])},dn.prototype.isVertical=function(){return this.p0.x===this.p1.x},dn.prototype.equals=function(t){if(!(t instanceof dn))return!1;var e=t;return this.p0.equals(e.p0)&&this.p1.equals(e.p1)},dn.prototype.intersection=function(t){var e=new rt;return e.computeIntersection(this.p0,this.p1,t.p0,t.p1),e.hasIntersection()?e.getIntersection(0):null},dn.prototype.project=function(){if(arguments[0]instanceof C){var t=arguments[0];if(t.equals(this.p0)||t.equals(this.p1))return new C(t);var e=this.projectionFactor(t),n=new C;return n.x=this.p0.x+e*(this.p1.x-this.p0.x),n.y=this.p0.y+e*(this.p1.y-this.p0.y),n}if(arguments[0]instanceof dn){var i=arguments[0],r=this.projectionFactor(i.p0),o=this.projectionFactor(i.p1);if(r>=1&&o>=1)return null;if(r<=0&&o<=0)return null;var s=this.project(i.p0);r<0&&(s=this.p0),r>1&&(s=this.p1);var a=this.project(i.p1);return o<0&&(a=this.p0),o>1&&(a=this.p1),new dn(s,a)}},dn.prototype.normalize=function(){this.p1.compareTo(this.p0)<0&&this.reverse()},dn.prototype.angle=function(){return Math.atan2(this.p1.y-this.p0.y,this.p1.x-this.p0.x)},dn.prototype.getCoordinate=function(t){return 0===t?this.p0:this.p1},dn.prototype.distancePerpendicular=function(t){return at.distancePointLinePerpendicular(t,this.p0,this.p1)},dn.prototype.minY=function(){return Math.min(this.p0.y,this.p1.y)},dn.prototype.midPoint=function(){return dn.midPoint(this.p0,this.p1)},dn.prototype.projectionFactor=function(t){if(t.equals(this.p0))return 0;if(t.equals(this.p1))return 1;var e=this.p1.x-this.p0.x,n=this.p1.y-this.p0.y,i=e*e+n*n;if(i<=0)return v.NaN;return((t.x-this.p0.x)*e+(t.y-this.p0.y)*n)/i},dn.prototype.closestPoints=function(t){var e=this.intersection(t);if(null!==e)return[e,e];var n=new Array(2).fill(null),i=v.MAX_VALUE,r=null,o=this.closestPoint(t.p0);i=o.distance(t.p0),n[0]=o,n[1]=t.p0;var s=this.closestPoint(t.p1);(r=s.distance(t.p1))0&&e<1)return this.project(t);return this.p0.distance(t)1||v.isNaN(e))&&(e=1),e},dn.prototype.toString=function(){return"LINESTRING( "+this.p0.x+" "+this.p0.y+", "+this.p1.x+" "+this.p1.y+")"},dn.prototype.isHorizontal=function(){return this.p0.y===this.p1.y},dn.prototype.distance=function(){if(arguments[0]instanceof dn){var t=arguments[0];return at.distanceLineLine(this.p0,this.p1,t.p0,t.p1)}if(arguments[0]instanceof C){var e=arguments[0];return at.distancePointLine(e,this.p0,this.p1)}},dn.prototype.pointAlong=function(t){var e=new C;return e.x=this.p0.x+t*(this.p1.x-this.p0.x),e.y=this.p0.y+t*(this.p1.y-this.p0.y),e},dn.prototype.hashCode=function(){var t=v.doubleToLongBits(this.p0.x);t^=31*v.doubleToLongBits(this.p0.y);var e=Math.trunc(t)^Math.trunc(t>>32),n=v.doubleToLongBits(this.p1.x);n^=31*v.doubleToLongBits(this.p1.y);return e^(Math.trunc(n)^Math.trunc(n>>32))},dn.prototype.interfaces_=function(){return[E,e]},dn.prototype.getClass=function(){return dn},dn.midPoint=function(t,e){return new C((t.x+e.x)/2,(t.y+e.y)/2)},yn.serialVersionUID.get=function(){return 0x2d2172135f411c00},Object.defineProperties(dn,yn);var _n=function(){this.tempEnv1=new j,this.tempEnv2=new j,this._overlapSeg1=new dn,this._overlapSeg2=new dn};_n.prototype.overlap=function(){if(2===arguments.length);else if(4===arguments.length){var t=arguments[0],e=arguments[1],n=arguments[2],i=arguments[3];t.getLineSegment(e,this._overlapSeg1),n.getLineSegment(i,this._overlapSeg2),this.overlap(this._overlapSeg1,this._overlapSeg2)}},_n.prototype.interfaces_=function(){return[]},_n.prototype.getClass=function(){return _n};var mn=function(){this._pts=null,this._start=null,this._end=null,this._env=null,this._context=null,this._id=null;var t=arguments[0],e=arguments[1],n=arguments[2],i=arguments[3];this._pts=t,this._start=e,this._end=n,this._context=i};mn.prototype.getLineSegment=function(t,e){e.p0=this._pts[t],e.p1=this._pts[t+1]},mn.prototype.computeSelect=function(t,e,n,i){var r=this._pts[e],o=this._pts[n];if(i.tempEnv1.init(r,o),n-e==1)return i.select(this,e),null;if(!t.intersects(i.tempEnv1))return null;var s=Math.trunc((e+n)/2);e=t.length-1)return t.length-1;for(var i=Be.quadrant(t[n],t[n+1]),r=e+1;rn.getId()&&(n.computeOverlaps(r,t),this._nOverlaps++),this._segInt.isDone())return null}},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},n.SegmentOverlapAction.get=function(){return Nn},Object.defineProperties(e,n),e}(En),Nn=function(t){function e(){t.call(this),this._si=null;var e=arguments[0];this._si=e}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.overlap=function(){if(4!==arguments.length)return t.prototype.overlap.apply(this,arguments);var e=arguments[0],n=arguments[1],i=arguments[2],r=arguments[3],o=e.getContext(),s=i.getContext();this._si.processIntersections(o,n,s,r)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(_n),Cn=function t(){if(this._quadrantSegments=t.DEFAULT_QUADRANT_SEGMENTS,this._endCapStyle=t.CAP_ROUND,this._joinStyle=t.JOIN_ROUND,this._mitreLimit=t.DEFAULT_MITRE_LIMIT,this._isSingleSided=!1,this._simplifyFactor=t.DEFAULT_SIMPLIFY_FACTOR,0===arguments.length);else if(1===arguments.length){var e=arguments[0];this.setQuadrantSegments(e)}else if(2===arguments.length){var n=arguments[0],i=arguments[1];this.setQuadrantSegments(n),this.setEndCapStyle(i)}else if(4===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2],a=arguments[3];this.setQuadrantSegments(r),this.setEndCapStyle(o),this.setJoinStyle(s),this.setMitreLimit(a)}},Sn={CAP_ROUND:{configurable:!0},CAP_FLAT:{configurable:!0},CAP_SQUARE:{configurable:!0},JOIN_ROUND:{configurable:!0},JOIN_MITRE:{configurable:!0},JOIN_BEVEL:{configurable:!0},DEFAULT_QUADRANT_SEGMENTS:{configurable:!0},DEFAULT_MITRE_LIMIT:{configurable:!0},DEFAULT_SIMPLIFY_FACTOR:{configurable:!0}};Cn.prototype.getEndCapStyle=function(){return this._endCapStyle},Cn.prototype.isSingleSided=function(){return this._isSingleSided},Cn.prototype.setQuadrantSegments=function(t){this._quadrantSegments=t,0===this._quadrantSegments&&(this._joinStyle=Cn.JOIN_BEVEL),this._quadrantSegments<0&&(this._joinStyle=Cn.JOIN_MITRE,this._mitreLimit=Math.abs(this._quadrantSegments)),t<=0&&(this._quadrantSegments=1),this._joinStyle!==Cn.JOIN_ROUND&&(this._quadrantSegments=Cn.DEFAULT_QUADRANT_SEGMENTS)},Cn.prototype.getJoinStyle=function(){return this._joinStyle},Cn.prototype.setJoinStyle=function(t){this._joinStyle=t},Cn.prototype.setSimplifyFactor=function(t){this._simplifyFactor=t<0?0:t},Cn.prototype.getSimplifyFactor=function(){return this._simplifyFactor},Cn.prototype.getQuadrantSegments=function(){return this._quadrantSegments},Cn.prototype.setEndCapStyle=function(t){this._endCapStyle=t},Cn.prototype.getMitreLimit=function(){return this._mitreLimit},Cn.prototype.setMitreLimit=function(t){this._mitreLimit=t},Cn.prototype.setSingleSided=function(t){this._isSingleSided=t},Cn.prototype.interfaces_=function(){return[]},Cn.prototype.getClass=function(){return Cn},Cn.bufferDistanceError=function(t){var e=Math.PI/2/t;return 1-Math.cos(e/2)},Sn.CAP_ROUND.get=function(){return 1},Sn.CAP_FLAT.get=function(){return 2},Sn.CAP_SQUARE.get=function(){return 3},Sn.JOIN_ROUND.get=function(){return 1},Sn.JOIN_MITRE.get=function(){return 2},Sn.JOIN_BEVEL.get=function(){return 3},Sn.DEFAULT_QUADRANT_SEGMENTS.get=function(){return 8},Sn.DEFAULT_MITRE_LIMIT.get=function(){return 5},Sn.DEFAULT_SIMPLIFY_FACTOR.get=function(){return.01},Object.defineProperties(Cn,Sn);var Ln=function(t){this._distanceTol=null,this._isDeleted=null,this._angleOrientation=at.COUNTERCLOCKWISE,this._inputLine=t||null},bn={INIT:{configurable:!0},DELETE:{configurable:!0},KEEP:{configurable:!0},NUM_PTS_TO_CHECK:{configurable:!0}};Ln.prototype.isDeletable=function(t,e,n,i){var r=this._inputLine[t],o=this._inputLine[e],s=this._inputLine[n];return!!this.isConcave(r,o,s)&&(!!this.isShallow(r,o,s,i)&&this.isShallowSampled(r,o,t,n,i))},Ln.prototype.deleteShallowConcavities=function(){for(var t=1,e=this.findNextNonDeletedIndex(t),n=this.findNextNonDeletedIndex(e),i=!1;n=0;i--)this.addPt(t[i])},wn.prototype.isRedundant=function(t){if(this._ptList.size()<1)return!1;var e=this._ptList.get(this._ptList.size()-1);return t.distance(e)Math.PI;)t-=Tn.PI_TIMES_2;for(;t<=-Math.PI;)t+=Tn.PI_TIMES_2;return t},Tn.angle=function(){if(1===arguments.length){var t=arguments[0];return Math.atan2(t.y,t.x)}if(2===arguments.length){var e=arguments[0],n=arguments[1],i=n.x-e.x,r=n.y-e.y;return Math.atan2(r,i)}},Tn.isAcute=function(t,e,n){var i=t.x-e.x,r=t.y-e.y;return i*(n.x-e.x)+r*(n.y-e.y)>0},Tn.isObtuse=function(t,e,n){var i=t.x-e.x,r=t.y-e.y;return i*(n.x-e.x)+r*(n.y-e.y)<0},Tn.interiorAngle=function(t,e,n){var i=Tn.angle(e,t),r=Tn.angle(e,n);return Math.abs(r-i)},Tn.normalizePositive=function(t){if(t<0){for(;t<0;)t+=Tn.PI_TIMES_2;t>=Tn.PI_TIMES_2&&(t=0)}else{for(;t>=Tn.PI_TIMES_2;)t-=Tn.PI_TIMES_2;t<0&&(t=0)}return t},Tn.angleBetween=function(t,e,n){var i=Tn.angle(e,t),r=Tn.angle(e,n);return Tn.diff(i,r)},Tn.diff=function(t,e){var n=null;return(n=tMath.PI&&(n=2*Math.PI-n),n},Tn.toRadians=function(t){return t*Math.PI/180},Tn.getTurn=function(t,e){var n=Math.sin(e-t);return n>0?Tn.COUNTERCLOCKWISE:n<0?Tn.CLOCKWISE:Tn.NONE},Tn.angleBetweenOriented=function(t,e,n){var i=Tn.angle(e,t),r=Tn.angle(e,n)-i;return r<=-Math.PI?r+Tn.PI_TIMES_2:r>Math.PI?r-Tn.PI_TIMES_2:r},Rn.PI_TIMES_2.get=function(){return 2*Math.PI},Rn.PI_OVER_2.get=function(){return Math.PI/2},Rn.PI_OVER_4.get=function(){return Math.PI/4},Rn.COUNTERCLOCKWISE.get=function(){return at.COUNTERCLOCKWISE},Rn.CLOCKWISE.get=function(){return at.CLOCKWISE},Rn.NONE.get=function(){return at.COLLINEAR},Object.defineProperties(Tn,Rn);var Pn=function t(){this._maxCurveSegmentError=0,this._filletAngleQuantum=null,this._closingSegLengthFactor=1,this._segList=null,this._distance=0,this._precisionModel=null,this._bufParams=null,this._li=null,this._s0=null,this._s1=null,this._s2=null,this._seg0=new dn,this._seg1=new dn,this._offset0=new dn,this._offset1=new dn,this._side=0,this._hasNarrowConcaveAngle=!1;var e=arguments[0],n=arguments[1],i=arguments[2];this._precisionModel=e,this._bufParams=n,this._li=new rt,this._filletAngleQuantum=Math.PI/2/n.getQuadrantSegments(),n.getQuadrantSegments()>=8&&n.getJoinStyle()===Cn.JOIN_ROUND&&(this._closingSegLengthFactor=t.MAX_CLOSING_SEG_LEN_FACTOR),this.init(i)},Dn={OFFSET_SEGMENT_SEPARATION_FACTOR:{configurable:!0},INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR:{configurable:!0},CURVE_VERTEX_SNAP_DISTANCE_FACTOR:{configurable:!0},MAX_CLOSING_SEG_LEN_FACTOR:{configurable:!0}};Pn.prototype.addNextSegment=function(t,e){if(this._s0=this._s1,this._s1=this._s2,this._s2=t,this._seg0.setCoordinates(this._s0,this._s1),this.computeOffsetSegment(this._seg0,this._side,this._distance,this._offset0),this._seg1.setCoordinates(this._s1,this._s2),this.computeOffsetSegment(this._seg1,this._side,this._distance,this._offset1),this._s1.equals(this._s2))return null;var n=at.computeOrientation(this._s0,this._s1,this._s2),i=n===at.CLOCKWISE&&this._side===Se.LEFT||n===at.COUNTERCLOCKWISE&&this._side===Se.RIGHT;0===n?this.addCollinear(e):i?this.addOutsideTurn(n,e):this.addInsideTurn(n,e)},Pn.prototype.addLineEndCap=function(t,e){var n=new dn(t,e),i=new dn;this.computeOffsetSegment(n,Se.LEFT,this._distance,i);var r=new dn;this.computeOffsetSegment(n,Se.RIGHT,this._distance,r);var o=e.x-t.x,s=e.y-t.y,a=Math.atan2(s,o);switch(this._bufParams.getEndCapStyle()){case Cn.CAP_ROUND:this._segList.addPt(i.p1),this.addFilletArc(e,a+Math.PI/2,a-Math.PI/2,at.CLOCKWISE,this._distance),this._segList.addPt(r.p1);break;case Cn.CAP_FLAT:this._segList.addPt(i.p1),this._segList.addPt(r.p1);break;case Cn.CAP_SQUARE:var u=new C;u.x=Math.abs(this._distance)*Math.cos(a),u.y=Math.abs(this._distance)*Math.sin(a);var l=new C(i.p1.x+u.x,i.p1.y+u.y),c=new C(r.p1.x+u.x,r.p1.y+u.y);this._segList.addPt(l),this._segList.addPt(c)}},Pn.prototype.getCoordinates=function(){return this._segList.getCoordinates()},Pn.prototype.addMitreJoin=function(t,e,n,i){var r=!0,o=null;try{o=k.intersection(e.p0,e.p1,n.p0,n.p1);(i<=0?1:o.distance(t)/Math.abs(i))>this._bufParams.getMitreLimit()&&(r=!1)}catch(t){if(!(t instanceof X))throw t;o=new C(0,0),r=!1}r?this._segList.addPt(o):this.addLimitedMitreJoin(e,n,i,this._bufParams.getMitreLimit())},Pn.prototype.addFilletCorner=function(t,e,n,i,r){var o=e.x-t.x,s=e.y-t.y,a=Math.atan2(s,o),u=n.x-t.x,l=n.y-t.y,c=Math.atan2(l,u);i===at.CLOCKWISE?a<=c&&(a+=2*Math.PI):a>=c&&(a-=2*Math.PI),this._segList.addPt(e),this.addFilletArc(t,a,c,i,r),this._segList.addPt(n)},Pn.prototype.addOutsideTurn=function(t,e){if(this._offset0.p1.distance(this._offset1.p0)0){var n=new C((this._closingSegLengthFactor*this._offset0.p1.x+this._s1.x)/(this._closingSegLengthFactor+1),(this._closingSegLengthFactor*this._offset0.p1.y+this._s1.y)/(this._closingSegLengthFactor+1));this._segList.addPt(n);var i=new C((this._closingSegLengthFactor*this._offset1.p0.x+this._s1.x)/(this._closingSegLengthFactor+1),(this._closingSegLengthFactor*this._offset1.p0.y+this._s1.y)/(this._closingSegLengthFactor+1));this._segList.addPt(i)}else this._segList.addPt(this._s1);this._segList.addPt(this._offset1.p0)}},Pn.prototype.createCircle=function(t){var e=new C(t.x+this._distance,t.y);this._segList.addPt(e),this.addFilletArc(t,0,2*Math.PI,-1,this._distance),this._segList.closeRing()},Pn.prototype.addBevelJoin=function(t,e){this._segList.addPt(t.p1),this._segList.addPt(e.p0)},Pn.prototype.init=function(t){this._distance=t,this._maxCurveSegmentError=t*(1-Math.cos(this._filletAngleQuantum/2)),this._segList=new wn,this._segList.setPrecisionModel(this._precisionModel),this._segList.setMinimumVertexDistance(t*Pn.CURVE_VERTEX_SNAP_DISTANCE_FACTOR)},Pn.prototype.addCollinear=function(t){this._li.computeIntersection(this._s0,this._s1,this._s1,this._s2);this._li.getIntersectionNum()>=2&&(this._bufParams.getJoinStyle()===Cn.JOIN_BEVEL||this._bufParams.getJoinStyle()===Cn.JOIN_MITRE?(t&&this._segList.addPt(this._offset0.p1),this._segList.addPt(this._offset1.p0)):this.addFilletCorner(this._s1,this._offset0.p1,this._offset1.p0,at.CLOCKWISE,this._distance))},Pn.prototype.closeRing=function(){this._segList.closeRing()},Pn.prototype.hasNarrowConcaveAngle=function(){return this._hasNarrowConcaveAngle},Pn.prototype.interfaces_=function(){return[]},Pn.prototype.getClass=function(){return Pn},Dn.OFFSET_SEGMENT_SEPARATION_FACTOR.get=function(){return.001},Dn.INSIDE_TURN_VERTEX_SNAP_DISTANCE_FACTOR.get=function(){return.001},Dn.CURVE_VERTEX_SNAP_DISTANCE_FACTOR.get=function(){return 1e-6},Dn.MAX_CLOSING_SEG_LEN_FACTOR.get=function(){return 80},Object.defineProperties(Pn,Dn);var Mn=function(){this._distance=0,this._precisionModel=null,this._bufParams=null;var t=arguments[0],e=arguments[1];this._precisionModel=t,this._bufParams=e};Mn.prototype.getOffsetCurve=function(t,e){if(this._distance=e,0===e)return null;var n=e<0,i=Math.abs(e),r=this.getSegGen(i);t.length<=1?this.computePointCurve(t[0],r):this.computeOffsetCurve(t,n,r);var o=r.getCoordinates();return n&&Lt.reverse(o),o},Mn.prototype.computeSingleSidedBufferCurve=function(t,e,n){var i=this.simplifyTolerance(this._distance);if(e){n.addSegments(t,!0);var r=Ln.simplify(t,-i),o=r.length-1;n.initSideSegments(r[o],r[o-1],Se.LEFT),n.addFirstSegment();for(var s=o-2;s>=0;s--)n.addNextSegment(r[s],!0)}else{n.addSegments(t,!1);var a=Ln.simplify(t,i),u=a.length-1;n.initSideSegments(a[0],a[1],Se.LEFT),n.addFirstSegment();for(var l=2;l<=u;l++)n.addNextSegment(a[l],!0)}n.addLastSegment(),n.closeRing()},Mn.prototype.computeRingBufferCurve=function(t,e,n){var i=this.simplifyTolerance(this._distance);e===Se.RIGHT&&(i=-i);var r=Ln.simplify(t,i),o=r.length-1;n.initSideSegments(r[o-1],r[0],e);for(var s=1;s<=o;s++){var a=1!==s;n.addNextSegment(r[s],a)}n.closeRing()},Mn.prototype.computeLineBufferCurve=function(t,e){var n=this.simplifyTolerance(this._distance),i=Ln.simplify(t,n),r=i.length-1;e.initSideSegments(i[0],i[1],Se.LEFT);for(var o=2;o<=r;o++)e.addNextSegment(i[o],!0);e.addLastSegment(),e.addLineEndCap(i[r-1],i[r]);var s=Ln.simplify(t,-n),a=s.length-1;e.initSideSegments(s[a],s[a-1],Se.LEFT);for(var u=a-2;u>=0;u--)e.addNextSegment(s[u],!0);e.addLastSegment(),e.addLineEndCap(s[1],s[0]),e.closeRing()},Mn.prototype.computePointCurve=function(t,e){switch(this._bufParams.getEndCapStyle()){case Cn.CAP_ROUND:e.createCircle(t);break;case Cn.CAP_SQUARE:e.createSquare(t)}},Mn.prototype.getLineCurve=function(t,e){if(this._distance=e,e<0&&!this._bufParams.isSingleSided())return null;if(0===e)return null;var n=Math.abs(e),i=this.getSegGen(n);if(t.length<=1)this.computePointCurve(t[0],i);else if(this._bufParams.isSingleSided()){var r=e<0;this.computeSingleSidedBufferCurve(t,r,i)}else this.computeLineBufferCurve(t,i);return i.getCoordinates()},Mn.prototype.getBufferParameters=function(){return this._bufParams},Mn.prototype.simplifyTolerance=function(t){return t*this._bufParams.getSimplifyFactor()},Mn.prototype.getRingCurve=function(t,e,n){if(this._distance=n,t.length<=2)return this.getLineCurve(t,n);if(0===n)return Mn.copyCoordinates(t);var i=this.getSegGen(n);return this.computeRingBufferCurve(t,e,i),i.getCoordinates()},Mn.prototype.computeOffsetCurve=function(t,e,n){var i=this.simplifyTolerance(this._distance);if(e){var r=Ln.simplify(t,-i),o=r.length-1;n.initSideSegments(r[o],r[o-1],Se.LEFT),n.addFirstSegment();for(var s=o-2;s>=0;s--)n.addNextSegment(r[s],!0)}else{var a=Ln.simplify(t,i),u=a.length-1;n.initSideSegments(a[0],a[1],Se.LEFT),n.addFirstSegment();for(var l=2;l<=u;l++)n.addNextSegment(a[l],!0)}n.addLastSegment()},Mn.prototype.getSegGen=function(t){return new Pn(this._precisionModel,this._bufParams,t)},Mn.prototype.interfaces_=function(){return[]},Mn.prototype.getClass=function(){return Mn},Mn.copyCoordinates=function(t){for(var e=new Array(t.length).fill(null),n=0;nr.getMaxY()||this.findStabbedSegments(t,i.getDirectedEdges(),e)}return e}if(3===arguments.length)if(T(arguments[2],xt)&&arguments[0]instanceof C&&arguments[1]instanceof ze)for(var o=arguments[0],s=arguments[1],a=arguments[2],u=s.getEdge().getCoordinates(),l=0;lthis._seg.p1.y&&this._seg.reverse();if(!(Math.max(this._seg.p0.x,this._seg.p1.x)this._seg.p1.y||at.computeOrientation(this._seg.p0,this._seg.p1,o)===at.RIGHT)){var c=s.getDepth(Se.LEFT);this._seg.p0.equals(u[l])||(c=s.getDepth(Se.RIGHT));var p=new Gn(this._seg,c);a.add(p)}}else if(T(arguments[2],xt)&&arguments[0]instanceof C&&T(arguments[1],xt))for(var h=arguments[0],f=arguments[1],g=arguments[2],d=f.iterator();d.hasNext();){var y=d.next();y.isForward()&&this.findStabbedSegments(h,y,g)}},An.prototype.getDepth=function(t){var e=this.findStabbedSegments(t);if(0===e.size())return 0;return $e.min(e)._leftDepth},An.prototype.interfaces_=function(){return[]},An.prototype.getClass=function(){return An},Fn.DepthSegment.get=function(){return Gn},Object.defineProperties(An,Fn);var Gn=function(){this._upwardSeg=null,this._leftDepth=null;var t=arguments[0],e=arguments[1];this._upwardSeg=new dn(t),this._leftDepth=e};Gn.prototype.compareTo=function(t){var e=t;if(this._upwardSeg.minX()>=e._upwardSeg.maxX())return 1;if(this._upwardSeg.maxX()<=e._upwardSeg.minX())return-1;var n=this._upwardSeg.orientationIndex(e._upwardSeg);return 0!==n?n:0!=(n=-1*e._upwardSeg.orientationIndex(this._upwardSeg))?n:this._upwardSeg.compareTo(e._upwardSeg)},Gn.prototype.compareX=function(t,e){var n=t.p0.compareTo(e.p0);return 0!==n?n:t.p1.compareTo(e.p1)},Gn.prototype.toString=function(){return this._upwardSeg.toString()},Gn.prototype.interfaces_=function(){return[E]},Gn.prototype.getClass=function(){return Gn};var qn=function(t,e,n){this.p0=t||null,this.p1=e||null,this.p2=n||null};qn.prototype.area=function(){return qn.area(this.p0,this.p1,this.p2)},qn.prototype.signedArea=function(){return qn.signedArea(this.p0,this.p1,this.p2)},qn.prototype.interpolateZ=function(t){if(null===t)throw new m("Supplied point is null.");return qn.interpolateZ(t,this.p0,this.p1,this.p2)},qn.prototype.longestSideLength=function(){return qn.longestSideLength(this.p0,this.p1,this.p2)},qn.prototype.isAcute=function(){return qn.isAcute(this.p0,this.p1,this.p2)},qn.prototype.circumcentre=function(){return qn.circumcentre(this.p0,this.p1,this.p2)},qn.prototype.area3D=function(){return qn.area3D(this.p0,this.p1,this.p2)},qn.prototype.centroid=function(){return qn.centroid(this.p0,this.p1,this.p2)},qn.prototype.inCentre=function(){return qn.inCentre(this.p0,this.p1,this.p2)},qn.prototype.interfaces_=function(){return[]},qn.prototype.getClass=function(){return qn},qn.area=function(t,e,n){return Math.abs(((n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y))/2)},qn.signedArea=function(t,e,n){return((n.x-t.x)*(e.y-t.y)-(e.x-t.x)*(n.y-t.y))/2},qn.det=function(t,e,n,i){return t*i-e*n},qn.interpolateZ=function(t,e,n,i){var r=e.x,o=e.y,s=n.x-r,a=i.x-r,u=n.y-o,l=i.y-o,c=s*l-a*u,p=t.x-r,h=t.y-o,f=(l*p-a*h)/c,g=(-u*p+s*h)/c;return e.z+f*(n.z-e.z)+g*(i.z-e.z)},qn.longestSideLength=function(t,e,n){var i=t.distance(e),r=e.distance(n),o=n.distance(t),s=i;return r>s&&(s=r),o>s&&(s=o),s},qn.isAcute=function(t,e,n){return!!Tn.isAcute(t,e,n)&&(!!Tn.isAcute(e,n,t)&&!!Tn.isAcute(n,t,e))},qn.circumcentre=function(t,e,n){var i=n.x,r=n.y,o=t.x-i,s=t.y-r,a=e.x-i,u=e.y-r,l=2*qn.det(o,s,a,u),c=qn.det(s,o*o+s*s,u,a*a+u*u),p=qn.det(o,o*o+s*s,a,a*a+u*u);return new C(i-c/l,r+p/l)},qn.perpendicularBisector=function(t,e){var n=e.x-t.x,i=e.y-t.y,r=new k(t.x+n/2,t.y+i/2,1),o=new k(t.x-i+n/2,t.y+n+i/2,1);return new k(r,o)},qn.angleBisector=function(t,e,n){var i=e.distance(t),r=i/(i+e.distance(n)),o=n.x-t.x,s=n.y-t.y;return new C(t.x+r*o,t.y+r*s)},qn.area3D=function(t,e,n){var i=e.x-t.x,r=e.y-t.y,o=e.z-t.z,s=n.x-t.x,a=n.y-t.y,u=n.z-t.z,l=r*u-o*a,c=o*s-i*u,p=i*a-r*s,h=l*l+c*c+p*p,f=Math.sqrt(h)/2;return f},qn.centroid=function(t,e,n){var i=(t.x+e.x+n.x)/3,r=(t.y+e.y+n.y)/3;return new C(i,r)},qn.inCentre=function(t,e,n){var i=e.distance(n),r=t.distance(n),o=t.distance(e),s=i+r+o,a=(i*t.x+r*e.x+o*n.x)/s,u=(i*t.y+r*e.y+o*n.y)/s;return new C(a,u)};var Bn=function(){this._inputGeom=null,this._distance=null,this._curveBuilder=null,this._curveList=new Nt;var t=arguments[0],e=arguments[1],n=arguments[2];this._inputGeom=t,this._distance=e,this._curveBuilder=n};Bn.prototype.addPoint=function(t){if(this._distance<=0)return null;var e=t.getCoordinates(),n=this._curveBuilder.getLineCurve(e,this._distance);this.addCurve(n,w.EXTERIOR,w.INTERIOR)},Bn.prototype.addPolygon=function(t){var e=this._distance,n=Se.LEFT;this._distance<0&&(e=-this._distance,n=Se.RIGHT);var i=t.getExteriorRing(),r=Lt.removeRepeatedPoints(i.getCoordinates());if(this._distance<0&&this.isErodedCompletely(i,this._distance))return null;if(this._distance<=0&&r.length<3)return null;this.addPolygonRing(r,e,n,w.EXTERIOR,w.INTERIOR);for(var o=0;o0&&this.isErodedCompletely(s,-this._distance)||this.addPolygonRing(a,e,Se.opposite(n),w.INTERIOR,w.EXTERIOR)}},Bn.prototype.isTriangleErodedCompletely=function(t,e){var n=new qn(t[0],t[1],t[2]),i=n.inCentre();return at.distancePointLine(i,n.p0,n.p1)=ee.MINIMUM_VALID_SIZE&&at.isCCW(t)&&(o=r,s=i,n=Se.opposite(n));var a=this._curveBuilder.getRingCurve(t,n,e);this.addCurve(a,o,s)},Bn.prototype.add=function(t){if(t.isEmpty())return null;t instanceof $t?this.addPolygon(t):t instanceof Kt?this.addLineString(t):t instanceof Qt?this.addPoint(t):t instanceof te?this.addCollection(t):t instanceof Xt?this.addCollection(t):t instanceof ne?this.addCollection(t):t instanceof zt&&this.addCollection(t)},Bn.prototype.isErodedCompletely=function(t,e){var n=t.getCoordinates();if(n.length<4)return e<0;if(4===n.length)return this.isTriangleErodedCompletely(n,e);var i=t.getEnvelopeInternal(),r=Math.min(i.getHeight(),i.getWidth());return e<0&&2*Math.abs(e)>r},Bn.prototype.addCollection=function(t){for(var e=0;e=this._max)throw new i;var t=this._parent.getGeometryN(this._index++);return t instanceof zt?(this._subcollectionIterator=new Un(t),this._subcollectionIterator.next()):t},Un.prototype.remove=function(){throw new Error(this.getClass().getName())},Un.prototype.hasNext=function(){if(this._atStart)return!0;if(null!==this._subcollectionIterator){if(this._subcollectionIterator.hasNext())return!0;this._subcollectionIterator=null}return!(this._index>=this._max)},Un.prototype.interfaces_=function(){return[Et]},Un.prototype.getClass=function(){return Un},Un.isAtomic=function(t){return!(t instanceof zt)};var zn=function(){this._geom=null;var t=arguments[0];this._geom=t};zn.prototype.locate=function(t){return zn.locate(t,this._geom)},zn.prototype.interfaces_=function(){return[Vn]},zn.prototype.getClass=function(){return zn},zn.isPointInRing=function(t,e){return!!e.getEnvelopeInternal().intersects(t)&&at.isPointInRing(t,e.getCoordinates())},zn.containsPointInPolygon=function(t,e){if(e.isEmpty())return!1;var n=e.getExteriorRing();if(!zn.isPointInRing(t,n))return!1;for(var i=0;i=0;n--){var i=this._edgeList.get(n),r=i.getSym();null===e&&(e=r),null!==t&&r.setNext(t),t=i}e.setNext(t)},e.prototype.computeDepths=function(){if(1===arguments.length){var t=arguments[0],e=this.findIndex(t),n=t.getDepth(Se.LEFT),i=t.getDepth(Se.RIGHT),r=this.computeDepths(e+1,this._edgeList.size(),n);if(this.computeDepths(0,e,r)!==i)throw new we("depth mismatch at "+t.getCoordinate())}else if(3===arguments.length){for(var o=arguments[0],s=arguments[1],a=arguments[2],u=o;u=0;r--){var o=this._resultAreaEdgeList.get(r),s=o.getSym();switch(null===e&&o.getEdgeRing()===t&&(e=o),i){case this._SCANNING_FOR_INCOMING:if(s.getEdgeRing()!==t)continue;n=s,i=this._LINKING_TO_OUTGOING;break;case this._LINKING_TO_OUTGOING:if(o.getEdgeRing()!==t)continue;n.setNextMin(o),i=this._SCANNING_FOR_INCOMING}}i===this._LINKING_TO_OUTGOING&&(et.isTrue(null!==e,"found null for first outgoing dirEdge"),et.isTrue(e.getEdgeRing()===t,"unable to link last incoming dirEdge"),n.setNextMin(e))},e.prototype.getOutgoingDegree=function(){if(0===arguments.length){for(var t=0,e=this.iterator();e.hasNext();){e.next().isInResult()&&t++}return t}if(1===arguments.length){for(var n=arguments[0],i=0,r=this.iterator();r.hasNext();){r.next().getEdgeRing()===n&&i++}return i}},e.prototype.getLabel=function(){return this._label},e.prototype.findCoveredLineEdges=function(){for(var t=w.NONE,e=this.iterator();e.hasNext();){var n=e.next(),i=n.getSym();if(!n.isLineEdge()){if(n.isInResult()){t=w.INTERIOR;break}if(i.isInResult()){t=w.EXTERIOR;break}}}if(t===w.NONE)return null;for(var r=t,o=this.iterator();o.hasNext();){var s=o.next(),a=s.getSym();s.isLineEdge()?s.getEdge().setCovered(r===w.INTERIOR):(s.isInResult()&&(r=w.EXTERIOR),a.isInResult()&&(r=w.INTERIOR))}},e.prototype.computeLabelling=function(e){t.prototype.computeLabelling.call(this,e),this._label=new Pe(w.NONE);for(var n=this.iterator();n.hasNext();)for(var i=n.next().getEdge().getLabel(),r=0;r<2;r++){var o=i.getLocation(r);o!==w.INTERIOR&&o!==w.BOUNDARY||this._label.setLocation(r,w.INTERIOR)}},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Xn),kn=function(t){function e(){t.apply(this,arguments)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.createNode=function(t){return new Ge(t,new Yn)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Xe),jn=function t(){this._pts=null,this._orientation=null;var e=arguments[0];this._pts=e,this._orientation=t.orientation(e)};jn.prototype.compareTo=function(t){var e=t;return jn.compareOriented(this._pts,this._orientation,e._pts,e._orientation)},jn.prototype.interfaces_=function(){return[E]},jn.prototype.getClass=function(){return jn},jn.orientation=function(t){return 1===Lt.increasingDirection(t)},jn.compareOriented=function(t,e,n,i){for(var r=e?1:-1,o=i?1:-1,s=e?t.length:-1,a=i?n.length:-1,u=e?0:t.length-1,l=i?0:n.length-1;;){var c=t[u].compareTo(n[l]);if(0!==c)return c;var p=(u+=r)===s,h=(l+=o)===a;if(p&&!h)return-1;if(!p&&h)return 1;if(p&&h)return 0}};var Hn=function(){this._edges=new Nt,this._ocaMap=new p};Hn.prototype.print=function(t){t.print("MULTILINESTRING ( ");for(var e=0;e0&&t.print(","),t.print("(");for(var i=n.getCoordinates(),r=0;r0&&t.print(","),t.print(i[r].x+" "+i[r].y);t.println(")")}t.print(") ")},Hn.prototype.addAll=function(t){for(var e=t.iterator();e.hasNext();)this.add(e.next())},Hn.prototype.findEdgeIndex=function(t){for(var e=0;e0||!e.coord.equals2D(i);r||n--;var o=new Array(n).fill(null),s=0;o[s++]=new C(t.coord);for(var a=t.segmentIndex+1;a<=e.segmentIndex;a++)o[s++]=this.edge.pts[a];return r&&(o[s]=e.coord),new ni(o,new Pe(this.edge._label))},Qn.prototype.add=function(t,e,n){var i=new Jn(t,e,n),r=this._nodeMap.get(i);return null!==r?r:(this._nodeMap.put(i,i),i)},Qn.prototype.isIntersection=function(t){for(var e=this.iterator();e.hasNext();){if(e.next().coord.equals(t))return!0}return!1},Qn.prototype.interfaces_=function(){return[]},Qn.prototype.getClass=function(){return Qn};var Zn=function(){};Zn.prototype.getChainStartIndices=function(t){var e=0,n=new Nt;n.add(new M(e));do{var i=this.findChainEnd(t,e);n.add(new M(i)),e=i}while(en?e:n},$n.prototype.getMinX=function(t){var e=this.pts[this.startIndex[t]].x,n=this.pts[this.startIndex[t+1]].x;return ee&&(i=1),this._depth[t][n]=i}}},ti.prototype.getDelta=function(t){return this._depth[t][Se.RIGHT]-this._depth[t][Se.LEFT]},ti.prototype.getLocation=function(t,e){return this._depth[t][e]<=0?w.EXTERIOR:w.INTERIOR},ti.prototype.toString=function(){return"A: "+this._depth[0][1]+","+this._depth[0][2]+" B: "+this._depth[1][1]+","+this._depth[1][2]},ti.prototype.add=function(){if(1===arguments.length)for(var t=arguments[0],e=0;e<2;e++)for(var n=1;n<3;n++){var i=t.getLocation(e,n);i!==w.EXTERIOR&&i!==w.INTERIOR||(this.isNull(e,n)?this._depth[e][n]=ti.depthAtLocation(i):this._depth[e][n]+=ti.depthAtLocation(i))}else if(3===arguments.length){var r=arguments[0],o=arguments[1];arguments[2]===w.INTERIOR&&this._depth[r][o]++}},ti.prototype.interfaces_=function(){return[]},ti.prototype.getClass=function(){return ti},ti.depthAtLocation=function(t){return t===w.EXTERIOR?0:t===w.INTERIOR?1:ti.NULL_VALUE},ei.NULL_VALUE.get=function(){return-1},Object.defineProperties(ti,ei);var ni=function(t){function e(){if(t.call(this),this.pts=null,this._env=null,this.eiList=new Qn(this),this._name=null,this._mce=null,this._isIsolated=!0,this._depth=new ti,this._depthDelta=0,1===arguments.length){var n=arguments[0];e.call(this,n,null)}else if(2===arguments.length){var i=arguments[0],r=arguments[1];this.pts=i,this._label=r}}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.getDepth=function(){return this._depth},e.prototype.getCollapsedEdge=function(){var t=new Array(2).fill(null);t[0]=this.pts[0],t[1]=this.pts[1];return new e(t,Pe.toLineLabel(this._label))},e.prototype.isIsolated=function(){return this._isIsolated},e.prototype.getCoordinates=function(){return this.pts},e.prototype.setIsolated=function(t){this._isIsolated=t},e.prototype.setName=function(t){this._name=t},e.prototype.equals=function(t){if(!(t instanceof e))return!1;var n=t;if(this.pts.length!==n.pts.length)return!1;for(var i=!0,r=!0,o=this.pts.length,s=0;s0?this.pts[0]:null;if(1===arguments.length){var t=arguments[0];return this.pts[t]}},e.prototype.print=function(t){t.print("edge "+this._name+": "),t.print("LINESTRING (");for(var e=0;e0&&t.print(","),t.print(this.pts[e].x+" "+this.pts[e].y);t.print(") "+this._label+" "+this._depthDelta)},e.prototype.computeIM=function(t){e.updateIM(this._label,t)},e.prototype.isCollapsed=function(){return!!this._label.isArea()&&(3===this.pts.length&&!!this.pts[0].equals(this.pts[2]))},e.prototype.isClosed=function(){return this.pts[0].equals(this.pts[this.pts.length-1])},e.prototype.getMaximumSegmentIndex=function(){return this.pts.length-1},e.prototype.getDepthDelta=function(){return this._depthDelta},e.prototype.getNumPoints=function(){return this.pts.length},e.prototype.printReverse=function(t){t.print("edge "+this._name+": ");for(var e=this.pts.length-1;e>=0;e--)t.print(this.pts[e]+" ");t.println("")},e.prototype.getMonotoneChainEdge=function(){return null===this._mce&&(this._mce=new $n(this)),this._mce},e.prototype.getEnvelope=function(){if(null===this._env){this._env=new j;for(var t=0;t0&&t.append(","),t.append(this.pts[e].x+" "+this.pts[e].y);return t.append(") "+this._label+" "+this._depthDelta),t.toString()},e.prototype.isPointwiseEqual=function(t){if(this.pts.length!==t.pts.length)return!1;for(var e=0;ei||this._maxyo;if(s)return!1;var a=this.intersectsToleranceSquare(t,e);return et.isTrue(!(s&&a),"Found bad envelope test"),a},ai.prototype.initCorners=function(t){this._minx=t.x-.5,this._maxx=t.x+.5,this._miny=t.y-.5,this._maxy=t.y+.5,this._corner[0]=new C(this._maxx,this._maxy),this._corner[1]=new C(this._minx,this._maxy),this._corner[2]=new C(this._minx,this._miny),this._corner[3]=new C(this._maxx,this._miny)},ai.prototype.intersects=function(t,e){return 1===this._scaleFactor?this.intersectsScaled(t,e):(this.copyScaled(t,this._p0Scaled),this.copyScaled(e,this._p1Scaled),this.intersectsScaled(this._p0Scaled,this._p1Scaled))},ai.prototype.scale=function(t){return Math.round(t*this._scaleFactor)},ai.prototype.getCoordinate=function(){return this._originalPt},ai.prototype.copyScaled=function(t,e){e.x=this.scale(t.x),e.y=this.scale(t.y)},ai.prototype.getSafeEnvelope=function(){if(null===this._safeEnv){var t=ai.SAFE_ENV_EXPANSION_FACTOR/this._scaleFactor;this._safeEnv=new j(this._originalPt.x-t,this._originalPt.x+t,this._originalPt.y-t,this._originalPt.y+t)}return this._safeEnv},ai.prototype.intersectsPixelClosure=function(t,e){return this._li.computeIntersection(t,e,this._corner[0],this._corner[1]),!!this._li.hasIntersection()||(this._li.computeIntersection(t,e,this._corner[1],this._corner[2]),!!this._li.hasIntersection()||(this._li.computeIntersection(t,e,this._corner[2],this._corner[3]),!!this._li.hasIntersection()||(this._li.computeIntersection(t,e,this._corner[3],this._corner[0]),!!this._li.hasIntersection())))},ai.prototype.intersectsToleranceSquare=function(t,e){var n=!1,i=!1;return this._li.computeIntersection(t,e,this._corner[0],this._corner[1]),!!this._li.isProper()||(this._li.computeIntersection(t,e,this._corner[1],this._corner[2]),!!this._li.isProper()||(this._li.hasIntersection()&&(n=!0),this._li.computeIntersection(t,e,this._corner[2],this._corner[3]),!!this._li.isProper()||(this._li.hasIntersection()&&(i=!0),this._li.computeIntersection(t,e,this._corner[3],this._corner[0]),!!this._li.isProper()||(!(!n||!i)||(!!t.equals(this._pt)||!!e.equals(this._pt))))))},ai.prototype.addSnappedNode=function(t,e){var n=t.getCoordinate(e),i=t.getCoordinate(e+1);return!!this.intersects(n,i)&&(t.addIntersection(this.getCoordinate(),e),!0)},ai.prototype.interfaces_=function(){return[]},ai.prototype.getClass=function(){return ai},ui.SAFE_ENV_EXPANSION_FACTOR.get=function(){return.75},Object.defineProperties(ai,ui);var li=function(){this.tempEnv1=new j,this.selectedSegment=new dn};li.prototype.select=function(){if(1===arguments.length);else if(2===arguments.length){var t=arguments[0],e=arguments[1];t.getLineSegment(e,this.selectedSegment),this.select(this.selectedSegment)}},li.prototype.interfaces_=function(){return[]},li.prototype.getClass=function(){return li};var ci=function(){this._index=null;var t=arguments[0];this._index=t},pi={HotPixelSnapAction:{configurable:!0}};ci.prototype.snap=function(){if(1===arguments.length){var t=arguments[0];return this.snap(t,null,-1)}if(3===arguments.length){var e=arguments[0],n=arguments[1],i=arguments[2],r=e.getSafeEnvelope(),o=new hi(e,n,i);return this._index.query(r,{interfaces_:function(){return[Ke]},visitItem:function(t){t.select(r,o)}}),o.isNodeAdded()}},ci.prototype.interfaces_=function(){return[]},ci.prototype.getClass=function(){return ci},pi.HotPixelSnapAction.get=function(){return hi},Object.defineProperties(ci,pi);var hi=function(t){function e(){t.call(this),this._hotPixel=null,this._parentEdge=null,this._hotPixelVertexIndex=null,this._isNodeAdded=!1;var e=arguments[0],n=arguments[1],i=arguments[2];this._hotPixel=e,this._parentEdge=n,this._hotPixelVertexIndex=i}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.isNodeAdded=function(){return this._isNodeAdded},e.prototype.select=function(){if(2!==arguments.length)return t.prototype.select.apply(this,arguments);var e=arguments[0],n=arguments[1],i=e.getContext();if(null!==this._parentEdge&&i===this._parentEdge&&n===this._hotPixelVertexIndex)return null;this._isNodeAdded=this._hotPixel.addSnappedNode(i,n)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(li),fi=function(){this._li=null,this._interiorIntersections=null;var t=arguments[0];this._li=t,this._interiorIntersections=new Nt};fi.prototype.processIntersections=function(t,e,n,i){if(t===n&&e===i)return null;var r=t.getCoordinates()[e],o=t.getCoordinates()[e+1],s=n.getCoordinates()[i],a=n.getCoordinates()[i+1];if(this._li.computeIntersection(r,o,s,a),this._li.hasIntersection()&&this._li.isInteriorIntersection()){for(var u=0;u=0;e--){try{t.bufferReducedPrecision(e)}catch(e){if(!(e instanceof we))throw e;t._saveException=e}if(null!==t._resultGeometry)return null}throw this._saveException}if(1===arguments.length){var n=arguments[0],i=di.precisionScaleFactor(this._argGeom,this._distance,n),r=new fe(i);this.bufferFixedPrecision(r)}},di.prototype.computeGeometry=function(){if(this.bufferOriginalPrecision(),null!==this._resultGeometry)return null;var t=this._argGeom.getFactory().getPrecisionModel();t.getType()===fe.FIXED?this.bufferFixedPrecision(t):this.bufferReducedPrecision()},di.prototype.setQuadrantSegments=function(t){this._bufParams.setQuadrantSegments(t)},di.prototype.bufferOriginalPrecision=function(){try{var t=new ii(this._bufParams);this._resultGeometry=t.buffer(this._argGeom,this._distance)}catch(t){if(!(t instanceof $))throw t;this._saveException=t}},di.prototype.getResultGeometry=function(t){return this._distance=t,this.computeGeometry(),this._resultGeometry},di.prototype.setEndCapStyle=function(t){this._bufParams.setEndCapStyle(t)},di.prototype.interfaces_=function(){return[]},di.prototype.getClass=function(){return di},di.bufferOp=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];return new di(t).getResultGeometry(e)}if(3===arguments.length){if(Number.isInteger(arguments[2])&&arguments[0]instanceof ct&&"number"==typeof arguments[1]){var n=arguments[0],i=arguments[1],r=arguments[2],o=new di(n);o.setQuadrantSegments(r);return o.getResultGeometry(i)}if(arguments[2]instanceof Cn&&arguments[0]instanceof ct&&"number"==typeof arguments[1]){var s=arguments[0],a=arguments[1],u=arguments[2];return new di(s,u).getResultGeometry(a)}}else if(4===arguments.length){var l=arguments[0],c=arguments[1],p=arguments[2],h=arguments[3],f=new di(l);f.setQuadrantSegments(p),f.setEndCapStyle(h);return f.getResultGeometry(c)}},di.precisionScaleFactor=function(t,e,n){var i=t.getEnvelopeInternal(),r=R.max(Math.abs(i.getMaxX()),Math.abs(i.getMaxY()),Math.abs(i.getMinX()),Math.abs(i.getMinY()))+2*(e>0?e:0),o=n-Math.trunc(Math.log(r)/Math.log(10)+1);return Math.pow(10,o)},yi.CAP_ROUND.get=function(){return Cn.CAP_ROUND},yi.CAP_BUTT.get=function(){return Cn.CAP_FLAT},yi.CAP_FLAT.get=function(){return Cn.CAP_FLAT},yi.CAP_SQUARE.get=function(){return Cn.CAP_SQUARE},yi.MAX_PRECISION_DIGITS.get=function(){return 12},Object.defineProperties(di,yi);var _i=function(){this._pt=[new C,new C],this._distance=v.NaN,this._isNull=!0};_i.prototype.getCoordinates=function(){return this._pt},_i.prototype.getCoordinate=function(t){return this._pt[t]},_i.prototype.setMinimum=function(){if(1===arguments.length){var t=arguments[0];this.setMinimum(t._pt[0],t._pt[1])}else if(2===arguments.length){var e=arguments[0],n=arguments[1];if(this._isNull)return this.initialize(e,n),null;var i=e.distance(n);ithis._distance&&this.initialize(e,n,i)}},_i.prototype.interfaces_=function(){return[]},_i.prototype.getClass=function(){return _i};var mi=function(){};mi.prototype.interfaces_=function(){return[]},mi.prototype.getClass=function(){return mi},mi.computeDistance=function(){if(arguments[2]instanceof _i&&arguments[0]instanceof Kt&&arguments[1]instanceof C)for(var t=arguments[0],e=arguments[1],n=arguments[2],i=t.getCoordinates(),r=new dn,o=0;o0||this._isIn?w.INTERIOR:w.EXTERIOR)},Si.prototype.interfaces_=function(){return[]},Si.prototype.getClass=function(){return Si};var Li=function t(){if(this._component=null,this._segIndex=null,this._pt=null,2===arguments.length){var e=arguments[0],n=arguments[1];t.call(this,e,t.INSIDE_AREA,n)}else if(3===arguments.length){var i=arguments[0],r=arguments[1],o=arguments[2];this._component=i,this._segIndex=r,this._pt=o}},bi={INSIDE_AREA:{configurable:!0}};Li.prototype.isInsideArea=function(){return this._segIndex===Li.INSIDE_AREA},Li.prototype.getCoordinate=function(){return this._pt},Li.prototype.getGeometryComponent=function(){return this._component},Li.prototype.getSegmentIndex=function(){return this._segIndex},Li.prototype.interfaces_=function(){return[]},Li.prototype.getClass=function(){return Li},bi.INSIDE_AREA.get=function(){return-1},Object.defineProperties(Li,bi);var wi=function(t){this._pts=t||null};wi.prototype.filter=function(t){t instanceof Qt&&this._pts.add(t)},wi.prototype.interfaces_=function(){return[Vt]},wi.prototype.getClass=function(){return wi},wi.getPoints=function(){if(1===arguments.length){var t=arguments[0];return t instanceof Qt?$e.singletonList(t):wi.getPoints(t,new Nt)}if(2===arguments.length){var e=arguments[0],n=arguments[1];return e instanceof Qt?n.add(e):e instanceof zt&&e.apply(new wi(n)),n}};var Oi=function(){this._locations=null;var t=arguments[0];this._locations=t};Oi.prototype.filter=function(t){(t instanceof Qt||t instanceof Kt||t instanceof $t)&&this._locations.add(new Li(t,0,t.getCoordinate()))},Oi.prototype.interfaces_=function(){return[Vt]},Oi.prototype.getClass=function(){return Oi},Oi.getLocations=function(t){var e=new Nt;return t.apply(new Oi(e)),e};var Ti=function(){if(this._geom=null,this._terminateDistance=0,this._ptLocator=new Si,this._minDistanceLocation=null,this._minDistance=v.MAX_VALUE,2===arguments.length){var t=arguments[0],e=arguments[1];this._geom=[t,e],this._terminateDistance=0}else if(3===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[2];this._geom=new Array(2).fill(null),this._geom[0]=n,this._geom[1]=i,this._terminateDistance=r}};Ti.prototype.computeContainmentDistance=function(){if(0===arguments.length){var t=new Array(2).fill(null);if(this.computeContainmentDistance(0,t),this._minDistance<=this._terminateDistance)return null;this.computeContainmentDistance(1,t)}else if(2===arguments.length){var e=arguments[0],n=arguments[1],i=1-e,r=Ni.getPolygons(this._geom[e]);if(r.size()>0){var o=Oi.getLocations(this._geom[i]);if(this.computeContainmentDistance(o,r,n),this._minDistance<=this._terminateDistance)return this._minDistanceLocation[i]=n[0],this._minDistanceLocation[e]=n[1],null}}else if(3===arguments.length)if(arguments[2]instanceof Array&&T(arguments[0],xt)&&T(arguments[1],xt)){for(var s=arguments[0],a=arguments[1],u=arguments[2],l=0;lthis._minDistance)return null;for(var i=t.getCoordinates(),r=e.getCoordinate(),o=0;othis._minDistance)return null;for(var p=u.getCoordinates(),h=l.getCoordinates(),f=0;fthis._distance&&this.initialize(e,n,i)}},Ri.prototype.interfaces_=function(){return[]},Ri.prototype.getClass=function(){return Ri};var Pi=function(){};Pi.prototype.interfaces_=function(){return[]},Pi.prototype.getClass=function(){return Pi},Pi.computeDistance=function(){if(arguments[2]instanceof Ri&&arguments[0]instanceof Kt&&arguments[1]instanceof C)for(var t=arguments[0],e=arguments[1],n=arguments[2],i=new dn,r=t.getCoordinates(),o=0;o1||t<=0)throw new m("Fraction is not in range (0.0 - 1.0]");this._densifyFrac=t},Di.prototype.compute=function(t,e){this.computeOrientedDistance(t,e,this._ptDist),this.computeOrientedDistance(e,t,this._ptDist)},Di.prototype.distance=function(){return this.compute(this._g0,this._g1),this._ptDist.getDistance()},Di.prototype.computeOrientedDistance=function(t,e,n){var i=new Ai(e);if(t.apply(i),n.setMaximum(i.getMaxPointDistance()),this._densifyFrac>0){var r=new Fi(e,this._densifyFrac);t.apply(r),n.setMaximum(r.getMaxPointDistance())}},Di.prototype.orientedDistance=function(){return this.computeOrientedDistance(this._g0,this._g1,this._ptDist),this._ptDist.getDistance()},Di.prototype.interfaces_=function(){return[]},Di.prototype.getClass=function(){return Di},Di.distance=function(){if(2===arguments.length){var t=arguments[0],e=arguments[1];return new Di(t,e).distance()}if(3===arguments.length){var n=arguments[0],i=arguments[1],r=arguments[2],o=new Di(n,i);return o.setDensifyFraction(r),o.distance()}},Mi.MaxPointDistanceFilter.get=function(){return Ai},Mi.MaxDensifiedByFractionDistanceFilter.get=function(){return Fi},Object.defineProperties(Di,Mi);var Ai=function(){this._maxPtDist=new Ri,this._minPtDist=new Ri,this._euclideanDist=new Pi,this._geom=null;var t=arguments[0];this._geom=t};Ai.prototype.filter=function(t){this._minPtDist.initialize(),Pi.computeDistance(this._geom,t,this._minPtDist),this._maxPtDist.setMaximum(this._minPtDist)},Ai.prototype.getMaxPointDistance=function(){return this._maxPtDist},Ai.prototype.interfaces_=function(){return[ft]},Ai.prototype.getClass=function(){return Ai};var Fi=function(){this._maxPtDist=new Ri,this._minPtDist=new Ri,this._geom=null,this._numSubSegs=0;var t=arguments[0],e=arguments[1];this._geom=t,this._numSubSegs=Math.trunc(Math.round(1/e))};Fi.prototype.filter=function(t,e){if(0===e)return null;for(var n=t.getCoordinate(e-1),i=t.getCoordinate(e),r=(i.x-n.x)/this._numSubSegs,o=(i.y-n.y)/this._numSubSegs,s=0;sn){this._isValid=!1;var r=i.getCoordinates();this._errorLocation=r[1],this._errorIndicator=t.getFactory().createLineString(r),this._errMsg="Distance between buffer curve and input is too large ("+this._maxDistanceFound+" at "+Z.toLineString(r[0],r[1])+")"}},Gi.prototype.isValid=function(){var t=Math.abs(this._bufDistance),e=Gi.MAX_DISTANCE_DIFF_FRAC*t;return this._minValidDistance=t-e,this._maxValidDistance=t+e,!(!this._input.isEmpty()&&!this._result.isEmpty())||(this._bufDistance>0?this.checkPositiveValid():this.checkNegativeValid(),Gi.VERBOSE&&Y.out.println("Min Dist= "+this._minDistanceFound+" err= "+(1-this._minDistanceFound/this._bufDistance)+" Max Dist= "+this._maxDistanceFound+" err= "+(this._maxDistanceFound/this._bufDistance-1)),this._isValid)},Gi.prototype.checkNegativeValid=function(){if(!(this._input instanceof $t||this._input instanceof ne||this._input instanceof zt))return null;var t=this.getPolygonLines(this._input);if(this.checkMinimumDistance(t,this._result,this._minValidDistance),!this._isValid)return null;this.checkMaximumDistance(t,this._result,this._maxValidDistance)},Gi.prototype.getErrorIndicator=function(){return this._errorIndicator},Gi.prototype.checkMinimumDistance=function(t,e,n){var i=new Ti(t,e,n);if(this._minDistanceFound=i.distance(),this._minDistanceFound0&&t>e&&(this._isValid=!1,this._errorMsg="Area of positive buffer is smaller than input",this._errorIndicator=this._result),this._distance<0&&t=2?null:this._distance>0?null:(this._result.isEmpty()||(this._isValid=!1,this._errorMsg="Result is non-empty",this._errorIndicator=this._result),void this.report("ExpectedEmpty"))},Bi.prototype.report=function(t){if(!Bi.VERBOSE)return null;Y.out.println("Check "+t+": "+(this._isValid?"passed":"FAILED"))},Bi.prototype.getErrorMessage=function(){return this._errorMsg},Bi.prototype.interfaces_=function(){return[]},Bi.prototype.getClass=function(){return Bi},Bi.isValidMsg=function(t,e,n){var i=new Bi(t,e,n);return i.isValid()?null:i.getErrorMessage()},Bi.isValid=function(t,e,n){return!!new Bi(t,e,n).isValid()},Vi.VERBOSE.get=function(){return!1},Vi.MAX_ENV_DIFF_FRAC.get=function(){return.012},Object.defineProperties(Bi,Vi);var Ui=function(){this._pts=null,this._data=null;var t=arguments[0],e=arguments[1];this._pts=t,this._data=e};Ui.prototype.getCoordinates=function(){return this._pts},Ui.prototype.size=function(){return this._pts.length},Ui.prototype.getCoordinate=function(t){return this._pts[t]},Ui.prototype.isClosed=function(){return this._pts[0].equals(this._pts[this._pts.length-1])},Ui.prototype.getSegmentOctant=function(t){return t===this._pts.length-1?-1:pn.octant(this.getCoordinate(t),this.getCoordinate(t+1))},Ui.prototype.setData=function(t){this._data=t},Ui.prototype.getData=function(){return this._data},Ui.prototype.toString=function(){return Z.toLineString(new ue(this._pts))},Ui.prototype.interfaces_=function(){return[hn]},Ui.prototype.getClass=function(){return Ui};var zi=function(){this._findAllIntersections=!1,this._isCheckEndSegmentsOnly=!1,this._li=null,this._interiorIntersection=null,this._intSegments=null,this._intersections=new Nt,this._intersectionCount=0,this._keepIntersections=!0;var t=arguments[0];this._li=t,this._interiorIntersection=null};zi.prototype.getInteriorIntersection=function(){return this._interiorIntersection},zi.prototype.setCheckEndSegmentsOnly=function(t){this._isCheckEndSegmentsOnly=t},zi.prototype.getIntersectionSegments=function(){return this._intSegments},zi.prototype.count=function(){return this._intersectionCount},zi.prototype.getIntersections=function(){return this._intersections},zi.prototype.setFindAllIntersections=function(t){this._findAllIntersections=t},zi.prototype.setKeepIntersections=function(t){this._keepIntersections=t},zi.prototype.processIntersections=function(t,e,n,i){if(!this._findAllIntersections&&this.hasIntersection())return null;if(t===n&&e===i)return null;if(this._isCheckEndSegmentsOnly){if(!(this.isEndSegment(t,e)||this.isEndSegment(n,i)))return null}var r=t.getCoordinates()[e],o=t.getCoordinates()[e+1],s=n.getCoordinates()[i],a=n.getCoordinates()[i+1];this._li.computeIntersection(r,o,s,a),this._li.hasIntersection()&&this._li.isInteriorIntersection()&&(this._intSegments=new Array(4).fill(null),this._intSegments[0]=r,this._intSegments[1]=o,this._intSegments[2]=s,this._intSegments[3]=a,this._interiorIntersection=this._li.getIntersection(0),this._keepIntersections&&this._intersections.add(this._interiorIntersection),this._intersectionCount++)},zi.prototype.isEndSegment=function(t,e){return 0===e||e>=t.size()-2},zi.prototype.hasIntersection=function(){return null!==this._interiorIntersection},zi.prototype.isDone=function(){return!this._findAllIntersections&&null!==this._interiorIntersection},zi.prototype.interfaces_=function(){return[Wn]},zi.prototype.getClass=function(){return zi},zi.createAllIntersectionsFinder=function(t){var e=new zi(t);return e.setFindAllIntersections(!0),e},zi.createAnyIntersectionFinder=function(t){return new zi(t)},zi.createIntersectionCounter=function(t){var e=new zi(t);return e.setFindAllIntersections(!0),e.setKeepIntersections(!1),e};var Xi=function(){this._li=new rt,this._segStrings=null,this._findAllIntersections=!1,this._segInt=null,this._isValid=!0;var t=arguments[0];this._segStrings=t};Xi.prototype.execute=function(){if(null!==this._segInt)return null;this.checkInteriorIntersections()},Xi.prototype.getIntersections=function(){return this._segInt.getIntersections()},Xi.prototype.isValid=function(){return this.execute(),this._isValid},Xi.prototype.setFindAllIntersections=function(t){this._findAllIntersections=t},Xi.prototype.checkInteriorIntersections=function(){this._isValid=!0,this._segInt=new zi(this._li),this._segInt.setFindAllIntersections(this._findAllIntersections);var t=new xn;if(t.setSegmentIntersector(this._segInt),t.computeNodes(this._segStrings),this._segInt.hasIntersection())return this._isValid=!1,null},Xi.prototype.checkValid=function(){if(this.execute(),!this._isValid)throw new we(this.getErrorMessage(),this._segInt.getInteriorIntersection())},Xi.prototype.getErrorMessage=function(){if(this._isValid)return"no intersections found";var t=this._segInt.getIntersectionSegments();return"found non-noded intersection between "+Z.toLineString(t[0],t[1])+" and "+Z.toLineString(t[2],t[3])},Xi.prototype.interfaces_=function(){return[]},Xi.prototype.getClass=function(){return Xi},Xi.computeIntersections=function(t){var e=new Xi(t);return e.setFindAllIntersections(!0),e.isValid(),e.getIntersections()};var Yi=function t(){this._nv=null;var e=arguments[0];this._nv=new Xi(t.toSegmentStrings(e))};Yi.prototype.checkValid=function(){this._nv.checkValid()},Yi.prototype.interfaces_=function(){return[]},Yi.prototype.getClass=function(){return Yi},Yi.toSegmentStrings=function(t){for(var e=new Nt,n=t.iterator();n.hasNext();){var i=n.next();e.add(new Ui(i.getCoordinates(),i))}return e},Yi.checkValid=function(t){new Yi(t).checkValid()};var ki=function(t){this._mapOp=t};ki.prototype.map=function(t){for(var e=new Nt,n=0;n0&&i<4&&!this._preserveType?this._factory.createLineString(n):this._factory.createLinearRing(n)},Wi.prototype.interfaces_=function(){return[]},Wi.prototype.getClass=function(){return Wi};var Ki=function t(){if(this._snapTolerance=0,this._srcPts=null,this._seg=new dn,this._allowSnappingToSourceVertices=!1,this._isClosed=!1,arguments[0]instanceof Kt&&"number"==typeof arguments[1]){var e=arguments[0],n=arguments[1];t.call(this,e.getCoordinates(),n)}else if(arguments[0]instanceof Array&&"number"==typeof arguments[1]){var i=arguments[0],r=arguments[1];this._srcPts=i,this._isClosed=t.isClosed(i),this._snapTolerance=r}};Ki.prototype.snapVertices=function(t,e){for(var n=this._isClosed?t.size()-1:t.size(),i=0;i=0&&t.add(o+1,new C(r),!1)}},Ki.prototype.findSegmentIndexToSnap=function(t,e){for(var n=v.MAX_VALUE,i=-1,r=0;re&&(e=i)}return e}if(2===arguments.length){var r=arguments[0],o=arguments[1];return Math.min(Ji.computeOverlaySnapTolerance(r),Ji.computeOverlaySnapTolerance(o))}},Ji.computeSizeBasedSnapTolerance=function(t){var e=t.getEnvelopeInternal();return Math.min(e.getHeight(),e.getWidth())*Ji.SNAP_PRECISION_FACTOR},Ji.snapToSelf=function(t,e,n){return new Ji(t).snapToSelf(e,n)},Qi.SNAP_PRECISION_FACTOR.get=function(){return 1e-9},Object.defineProperties(Ji,Qi);var Zi=function(t){function e(e,n,i){t.call(this),this._snapTolerance=e||null,this._snapPts=n||null,this._isSelfSnap=void 0!==i&&i}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.snapLine=function(t,e){var n=new Ki(t,this._snapTolerance);return n.setAllowSnappingToSourceVertices(this._isSelfSnap),n.snapTo(e)},e.prototype.transformCoordinates=function(t,e){var n=t.toCoordinateArray(),i=this.snapLine(n,this._snapPts);return this._factory.getCoordinateSequenceFactory().create(i)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(Wi),$i=function(){this._isFirst=!0,this._commonMantissaBitsCount=53,this._commonBits=0,this._commonSignExp=null};$i.prototype.getCommon=function(){return v.longBitsToDouble(this._commonBits)},$i.prototype.add=function(t){var e=v.doubleToLongBits(t);if(this._isFirst)return this._commonBits=e,this._commonSignExp=$i.signExpBits(this._commonBits),this._isFirst=!1,null;if($i.signExpBits(e)!==this._commonSignExp)return this._commonBits=0,null;this._commonMantissaBitsCount=$i.numCommonMostSigMantissaBits(this._commonBits,e),this._commonBits=$i.zeroLowerBits(this._commonBits,64-(12+this._commonMantissaBitsCount))},$i.prototype.toString=function(){if(1===arguments.length){var t=arguments[0],e=v.longBitsToDouble(t),n="0000000000000000000000000000000000000000000000000000000000000000"+v.toBinaryString(t),i=n.substring(n.length-64);return i.substring(0,1)+" "+i.substring(1,12)+"(exp) "+i.substring(12)+" [ "+e+" ]"}},$i.prototype.interfaces_=function(){return[]},$i.prototype.getClass=function(){return $i},$i.getBit=function(t,e){return 0!=(t&1<>52},$i.zeroLowerBits=function(t,e){return t&~((1<=0;i--){if($i.getBit(t,i)!==$i.getBit(e,i))return n;n++}return 52};var tr=function(){this._commonCoord=null,this._ccFilter=new nr},er={CommonCoordinateFilter:{configurable:!0},Translater:{configurable:!0}};tr.prototype.addCommonBits=function(t){var e=new ir(this._commonCoord);t.apply(e),t.geometryChanged()},tr.prototype.removeCommonBits=function(t){if(0===this._commonCoord.x&&0===this._commonCoord.y)return t;var e=new C(this._commonCoord);e.x=-e.x,e.y=-e.y;var n=new ir(e);return t.apply(n),t.geometryChanged(),t},tr.prototype.getCommonCoordinate=function(){return this._commonCoord},tr.prototype.add=function(t){t.apply(this._ccFilter),this._commonCoord=this._ccFilter.getCommonCoordinate()},tr.prototype.interfaces_=function(){return[]},tr.prototype.getClass=function(){return tr},er.CommonCoordinateFilter.get=function(){return nr},er.Translater.get=function(){return ir},Object.defineProperties(tr,er);var nr=function(){this._commonBitsX=new $i,this._commonBitsY=new $i};nr.prototype.filter=function(t){this._commonBitsX.add(t.x),this._commonBitsY.add(t.y)},nr.prototype.getCommonCoordinate=function(){return new C(this._commonBitsX.getCommon(),this._commonBitsY.getCommon())},nr.prototype.interfaces_=function(){return[ft]},nr.prototype.getClass=function(){return nr};var ir=function(){this.trans=null;var t=arguments[0];this.trans=t};ir.prototype.filter=function(t,e){var n=t.getOrdinate(e,0)+this.trans.x,i=t.getOrdinate(e,1)+this.trans.y;t.setOrdinate(e,0,n),t.setOrdinate(e,1,i)},ir.prototype.isDone=function(){return!1},ir.prototype.isGeometryChanged=function(){return!0},ir.prototype.interfaces_=function(){return[Ut]},ir.prototype.getClass=function(){return ir};var rr=function(t,e){this._geom=new Array(2).fill(null),this._snapTolerance=null,this._cbr=null,this._geom[0]=t,this._geom[1]=e,this.computeSnapTolerance()};rr.prototype.selfSnap=function(t){return new Ji(t).snapTo(t,this._snapTolerance)},rr.prototype.removeCommonBits=function(t){this._cbr=new tr,this._cbr.add(t[0]),this._cbr.add(t[1]);var e=new Array(2).fill(null);return e[0]=this._cbr.removeCommonBits(t[0].copy()),e[1]=this._cbr.removeCommonBits(t[1].copy()),e},rr.prototype.prepareResult=function(t){return this._cbr.addCommonBits(t),t},rr.prototype.getResultGeometry=function(t){var e=this.snap(this._geom),n=Lr.overlayOp(e[0],e[1],t);return this.prepareResult(n)},rr.prototype.checkValid=function(t){t.isValid()||Y.out.println("Snapped geometry is invalid")},rr.prototype.computeSnapTolerance=function(){this._snapTolerance=Ji.computeOverlaySnapTolerance(this._geom[0],this._geom[1])},rr.prototype.snap=function(t){var e=this.removeCommonBits(t);return Ji.snap(e[0],e[1],this._snapTolerance)},rr.prototype.interfaces_=function(){return[]},rr.prototype.getClass=function(){return rr},rr.overlayOp=function(t,e,n){return new rr(t,e).getResultGeometry(n)},rr.union=function(t,e){return rr.overlayOp(t,e,Lr.UNION)},rr.intersection=function(t,e){return rr.overlayOp(t,e,Lr.INTERSECTION)},rr.symDifference=function(t,e){return rr.overlayOp(t,e,Lr.SYMDIFFERENCE)},rr.difference=function(t,e){return rr.overlayOp(t,e,Lr.DIFFERENCE)};var or=function(t,e){this._geom=new Array(2).fill(null),this._geom[0]=t,this._geom[1]=e};or.prototype.getResultGeometry=function(t){var e=null,n=!1,i=null;try{e=Lr.overlayOp(this._geom[0],this._geom[1],t);n=!0}catch(t){if(!(t instanceof $))throw t;i=t}if(!n)try{e=rr.overlayOp(this._geom[0],this._geom[1],t)}catch(t){throw t instanceof $?i:t}return e},or.prototype.interfaces_=function(){return[]},or.prototype.getClass=function(){return or},or.overlayOp=function(t,e,n){return new or(t,e).getResultGeometry(n)},or.union=function(t,e){return or.overlayOp(t,e,Lr.UNION)},or.intersection=function(t,e){return or.overlayOp(t,e,Lr.INTERSECTION)},or.symDifference=function(t,e){return or.overlayOp(t,e,Lr.SYMDIFFERENCE)},or.difference=function(t,e){return or.overlayOp(t,e,Lr.DIFFERENCE)};var sr=function(){this.mce=null,this.chainIndex=null;var t=arguments[0],e=arguments[1];this.mce=t,this.chainIndex=e};sr.prototype.computeIntersections=function(t,e){this.mce.computeIntersectsForChain(this.chainIndex,t.mce,t.chainIndex,e)},sr.prototype.interfaces_=function(){return[]},sr.prototype.getClass=function(){return sr};var ar=function t(){if(this._label=null,this._xValue=null,this._eventType=null,this._insertEvent=null,this._deleteEventIndex=null,this._obj=null,2===arguments.length){var e=arguments[0],n=arguments[1];this._eventType=t.DELETE,this._xValue=e,this._insertEvent=n}else if(3===arguments.length){var i=arguments[0],r=arguments[1],o=arguments[2];this._eventType=t.INSERT,this._label=i,this._xValue=r,this._obj=o}},ur={INSERT:{configurable:!0},DELETE:{configurable:!0}};ar.prototype.isDelete=function(){return this._eventType===ar.DELETE},ar.prototype.setDeleteEventIndex=function(t){this._deleteEventIndex=t},ar.prototype.getObject=function(){return this._obj},ar.prototype.compareTo=function(t){var e=t;return this._xValuee._xValue?1:this._eventTypee._eventType?1:0},ar.prototype.getInsertEvent=function(){return this._insertEvent},ar.prototype.isInsert=function(){return this._eventType===ar.INSERT},ar.prototype.isSameLabel=function(t){return null!==this._label&&this._label===t._label},ar.prototype.getDeleteEventIndex=function(){return this._deleteEventIndex},ar.prototype.interfaces_=function(){return[E]},ar.prototype.getClass=function(){return ar},ur.INSERT.get=function(){return 1},ur.DELETE.get=function(){return 2},Object.defineProperties(ar,ur);var lr=function(){};lr.prototype.interfaces_=function(){return[]},lr.prototype.getClass=function(){return lr};var cr=function(){this._hasIntersection=!1,this._hasProper=!1,this._hasProperInterior=!1,this._properIntersectionPoint=null,this._li=null,this._includeProper=null,this._recordIsolated=null,this._isSelfIntersection=null,this._numIntersections=0,this.numTests=0,this._bdyNodes=null,this._isDone=!1,this._isDoneWhenProperInt=!1;var t=arguments[0],e=arguments[1],n=arguments[2];this._li=t,this._includeProper=e,this._recordIsolated=n};cr.prototype.isTrivialIntersection=function(t,e,n,i){if(t===n&&1===this._li.getIntersectionNum()){if(cr.isAdjacentSegments(e,i))return!0;if(t.isClosed()){var r=t.getNumPoints()-1;if(0===e&&i===r||0===i&&e===r)return!0}}return!1},cr.prototype.getProperIntersectionPoint=function(){return this._properIntersectionPoint},cr.prototype.setIsDoneIfProperInt=function(t){this._isDoneWhenProperInt=t},cr.prototype.hasProperInteriorIntersection=function(){return this._hasProperInterior},cr.prototype.isBoundaryPointInternal=function(t,e){for(var n=e.iterator();n.hasNext();){var i=n.next().getCoordinate();if(t.isIntersection(i))return!0}return!1},cr.prototype.hasProperIntersection=function(){return this._hasProper},cr.prototype.hasIntersection=function(){return this._hasIntersection},cr.prototype.isDone=function(){return this._isDone},cr.prototype.isBoundaryPoint=function(t,e){return null!==e&&(!!this.isBoundaryPointInternal(t,e[0])||!!this.isBoundaryPointInternal(t,e[1]))},cr.prototype.setBoundaryNodes=function(t,e){this._bdyNodes=new Array(2).fill(null),this._bdyNodes[0]=t,this._bdyNodes[1]=e},cr.prototype.addIntersections=function(t,e,n,i){if(t===n&&e===i)return null;this.numTests++;var r=t.getCoordinates()[e],o=t.getCoordinates()[e+1],s=n.getCoordinates()[i],a=n.getCoordinates()[i+1];this._li.computeIntersection(r,o,s,a),this._li.hasIntersection()&&(this._recordIsolated&&(t.setIsolated(!1),n.setIsolated(!1)),this._numIntersections++,this.isTrivialIntersection(t,e,n,i)||(this._hasIntersection=!0,!this._includeProper&&this._li.isProper()||(t.addIntersections(this._li,e,0),n.addIntersections(this._li,i,1)),this._li.isProper()&&(this._properIntersectionPoint=this._li.getIntersection(0).copy(),this._hasProper=!0,this._isDoneWhenProperInt&&(this._isDone=!0),this.isBoundaryPoint(this._li,this._bdyNodes)||(this._hasProperInterior=!0))))},cr.prototype.interfaces_=function(){return[]},cr.prototype.getClass=function(){return cr},cr.isAdjacentSegments=function(t,e){return 1===Math.abs(t-e)};var pr=function(t){function e(){t.call(this),this.events=new Nt,this.nOverlaps=null}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.prepareEvents=function(){$e.sort(this.events);for(var t=0;te||this._maxo?1:0},gr.prototype.interfaces_=function(){return[N]},gr.prototype.getClass=function(){return gr};var dr=function(t){function e(){t.call(this),this._item=null;var e=arguments[0],n=arguments[1],i=arguments[2];this._min=e,this._max=n,this._item=i}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.query=function(t,e,n){if(!this.intersects(t,e))return null;n.visitItem(this._item)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(hr),yr=function(t){function e(){t.call(this),this._node1=null,this._node2=null;var e=arguments[0],n=arguments[1];this._node1=e,this._node2=n,this.buildExtent(this._node1,this._node2)}return t&&(e.__proto__=t),e.prototype=Object.create(t&&t.prototype),e.prototype.constructor=e,e.prototype.buildExtent=function(t,e){this._min=Math.min(t._min,e._min),this._max=Math.max(t._max,e._max)},e.prototype.query=function(t,e,n){if(!this.intersects(t,e))return null;null!==this._node1&&this._node1.query(t,e,n),null!==this._node2&&this._node2.query(t,e,n)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e}(hr),_r=function(){this._leaves=new Nt,this._root=null,this._level=0};_r.prototype.buildTree=function(){$e.sort(this._leaves,new hr.NodeComparator);for(var t=this._leaves,e=null,n=new Nt;;){if(this.buildLevel(t,n),1===n.size())return n.get(0);e=t,t=n,n=e}},_r.prototype.insert=function(t,e,n){if(null!==this._root)throw new Error("Index cannot be added to once it has been queried");this._leaves.add(new dr(t,e,n))},_r.prototype.query=function(t,e,n){this.init(),this._root.query(t,e,n)},_r.prototype.buildRoot=function(){if(null!==this._root)return null;this._root=this.buildTree()},_r.prototype.printNode=function(t){Y.out.println(Z.toLineString(new C(t._min,this._level),new C(t._max,this._level)))},_r.prototype.init=function(){if(null!==this._root)return null;this.buildRoot()},_r.prototype.buildLevel=function(t,e){this._level++,e.clear();for(var n=0;n=2,"found LineString with single point"),this.insertBoundaryPoint(this._argIndex,e[0]),this.insertBoundaryPoint(this._argIndex,e[e.length-1])},e.prototype.getInvalidPoint=function(){return this._invalidPoint},e.prototype.getBoundaryPoints=function(){for(var t=this.getBoundaryNodes(),e=new Array(t.size()).fill(null),n=0,i=t.iterator();i.hasNext();){var r=i.next();e[n++]=r.getCoordinate().copy()}return e},e.prototype.getBoundaryNodes=function(){return null===this._boundaryNodes&&(this._boundaryNodes=this._nodes.getBoundaryNodes(this._argIndex)),this._boundaryNodes},e.prototype.addSelfIntersectionNode=function(t,e,n){if(this.isBoundaryNode(t,e))return null;n===w.BOUNDARY&&this._useBoundaryDeterminationRule?this.insertBoundaryPoint(t,e):this.insertPoint(t,e,n)},e.prototype.addPolygonRing=function(t,e,n){if(t.isEmpty())return null;var i=Lt.removeRepeatedPoints(t.getCoordinates());if(i.length<4)return this._hasTooFewPoints=!0,this._invalidPoint=i[0],null;var r=e,o=n;at.isCCW(i)&&(r=n,o=e);var s=new ni(i,new Pe(this._argIndex,w.BOUNDARY,r,o));this._lineEdgeMap.put(t,s),this.insertEdge(s),this.insertPoint(this._argIndex,i[0],w.BOUNDARY)},e.prototype.insertPoint=function(t,e,n){var i=this._nodes.addNode(e),r=i.getLabel();null===r?i._label=new Pe(t,n):r.setLocation(t,n)},e.prototype.createEdgeSetIntersector=function(){return new pr},e.prototype.addSelfIntersectionNodes=function(t){for(var e=this._edges.iterator();e.hasNext();)for(var n=e.next(),i=n.getLabel().getLocation(t),r=n.eiList.iterator();r.hasNext();){var o=r.next();this.addSelfIntersectionNode(t,o.coord,i)}},e.prototype.add=function(){if(1!==arguments.length)return t.prototype.add.apply(this,arguments);var e=arguments[0];if(e.isEmpty())return null;if(e instanceof ne&&(this._useBoundaryDeterminationRule=!1),e instanceof $t)this.addPolygon(e);else if(e instanceof Kt)this.addLineString(e);else if(e instanceof Qt)this.addPoint(e);else if(e instanceof te)this.addCollection(e);else if(e instanceof Xt)this.addCollection(e);else if(e instanceof ne)this.addCollection(e);else{if(!(e instanceof zt))throw new Error(e.getClass().getName());this.addCollection(e)}},e.prototype.addCollection=function(t){for(var e=0;e50?(null===this._areaPtLocator&&(this._areaPtLocator=new vr(this._parentGeom)),this._areaPtLocator.locate(t)):this._ptLocator.locate(t,this._parentGeom)},e.prototype.findEdge=function(){if(1===arguments.length){var e=arguments[0];return this._lineEdgeMap.get(e)}return t.prototype.findEdge.apply(this,arguments)},e.prototype.interfaces_=function(){return[]},e.prototype.getClass=function(){return e},e.determineBoundary=function(t,e){return t.isInBoundary(e)?w.BOUNDARY:w.INTERIOR},e}(Ye),Cr=function(){if(this._li=new rt,this._resultPrecisionModel=null,this._arg=null,1===arguments.length){var t=arguments[0];this.setComputationPrecision(t.getPrecisionModel()),this._arg=new Array(1).fill(null),this._arg[0]=new Nr(0,t)}else if(2===arguments.length){var e=arguments[0],n=arguments[1],i=gt.OGC_SFS_BOUNDARY_RULE;e.getPrecisionModel().compareTo(n.getPrecisionModel())>=0?this.setComputationPrecision(e.getPrecisionModel()):this.setComputationPrecision(n.getPrecisionModel()),this._arg=new Array(2).fill(null),this._arg[0]=new Nr(0,e,i),this._arg[1]=new Nr(1,n,i)}else if(3===arguments.length){var r=arguments[0],o=arguments[1],s=arguments[2];r.getPrecisionModel().compareTo(o.getPrecisionModel())>=0?this.setComputationPrecision(r.getPrecisionModel()):this.setComputationPrecision(o.getPrecisionModel()),this._arg=new Array(2).fill(null),this._arg[0]=new Nr(0,r,s),this._arg[1]=new Nr(1,o,s)}};Cr.prototype.getArgGeometry=function(t){return this._arg[t].getGeometry()},Cr.prototype.setComputationPrecision=function(t){this._resultPrecisionModel=t,this._li.setPrecisionModel(this._resultPrecisionModel)},Cr.prototype.interfaces_=function(){return[]},Cr.prototype.getClass=function(){return Cr};var Sr=function(){};Sr.prototype.interfaces_=function(){return[]},Sr.prototype.getClass=function(){return Sr},Sr.map=function(){if(arguments[0]instanceof ct&&T(arguments[1],Sr.MapOp)){for(var t=arguments[0],e=arguments[1],n=new Nt,i=0;i=t.size()?null:t.get(e)},Dr.union=function(t){return new Dr(t).union()},Mr.STRTREE_NODE_CAPACITY.get=function(){return 4},Object.defineProperties(Dr,Mr);var Ar=function(){};Ar.prototype.interfaces_=function(){return[]},Ar.prototype.getClass=function(){return Ar},Ar.union=function(t,e){if(t.isEmpty()||e.isEmpty()){if(t.isEmpty()&&e.isEmpty())return Lr.createEmptyResult(Lr.UNION,t,e,t.getFactory());if(t.isEmpty())return e.copy();if(e.isEmpty())return t.copy()}return t.checkNotGeometryCollection(t),t.checkNotGeometryCollection(e),or.overlayOp(t,e,Lr.UNION)},t.GeoJSONReader=Ne,t.GeoJSONWriter=Ce,t.OverlayOp=Lr,t.UnionOp=Ar,t.BufferOp=di,Object.defineProperty(t,"__esModule",{value:!0})});\n\n\n//# sourceURL=webpack:///./node_modules/turf-jsts/jsts.min.js?')},function(module,exports,__webpack_require__){"use strict";eval('\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { "default": mod };\n}\nObject.defineProperty(exports, "__esModule", { value: true });\nvar distance_1 = __importDefault(__webpack_require__(9));\nvar meta_1 = __webpack_require__(19);\n/**\n * Takes a {@link GeoJSON} and measures its length in the specified units, {@link (Multi)Point}\'s distance are ignored.\n *\n * @name length\n * @param {Feature} geojson GeoJSON to measure\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units=kilometers] can be degrees, radians, miles, or kilometers\n * @returns {number} length of GeoJSON\n * @example\n * var line = turf.lineString([[115, -32], [131, -22], [143, -25], [150, -34]]);\n * var length = turf.length(line, {units: \'miles\'});\n *\n * //addToMap\n * var addToMap = [line];\n * line.properties.distance = length;\n */\nfunction length(geojson, options) {\n if (options === void 0) { options = {}; }\n // Calculate distance from 2-vertex line segments\n return meta_1.segmentReduce(geojson, function (previousValue, segment) {\n var coords = segment.geometry.coordinates;\n return previousValue + distance_1.default(coords[0], coords[1], options);\n }, 0);\n}\nexports.default = length;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/length/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar invariant_1 = __webpack_require__(2);\nvar helpers_1 = __webpack_require__(1);\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n/**\n * Calculates the distance between two {@link Point|points} in degrees, radians, miles, or kilometers.\n * This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature.\n *\n * @name distance\n * @param {Coord} from origin point\n * @param {Coord} to destination point\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {number} distance between the two points\n * @example\n * var from = turf.point([-75.343, 39.984]);\n * var to = turf.point([-75.534, 39.123]);\n * var options = {units: 'miles'};\n *\n * var distance = turf.distance(from, to, options);\n *\n * //addToMap\n * var addToMap = [from, to];\n * from.properties.distance = distance;\n * to.properties.distance = distance;\n */\nfunction distance(from, to, options) {\n if (options === void 0) { options = {}; }\n var coordinates1 = invariant_1.getCoord(from);\n var coordinates2 = invariant_1.getCoord(to);\n var dLat = helpers_1.degreesToRadians((coordinates2[1] - coordinates1[1]));\n var dLon = helpers_1.degreesToRadians((coordinates2[0] - coordinates1[0]));\n var lat1 = helpers_1.degreesToRadians(coordinates1[1]);\n var lat2 = helpers_1.degreesToRadians(coordinates2[1]);\n var a = Math.pow(Math.sin(dLat / 2), 2) +\n Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);\n return helpers_1.radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), options.units);\n}\nexports.default = distance;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/distance/index.js?")},function(module,exports,__webpack_require__){eval('/* Here we have utilities to convert OSM geojson data into a distance-weighted graph and find the shortest path between two points. */\nvar path = __webpack_require__(33),\n createGraph = __webpack_require__(38),\n lineSlice = __webpack_require__(14).default,\n length = __webpack_require__(8).default,\n Agentmap = __webpack_require__(4).Agentmap;\n/**\r\n * Convert a layerGroup of streets into a graph. Useful if you modify the street layers during the simulation\r\n * and want routing to work with the new street network.\r\n *\r\n * @param {LayerGroup} streets - A Leaflet layerGroup of streets, forming a street network.\r\n * @returns {Object} - A graph representing the street network, operable by the ngraph pathfinder. \r\n */\n\n\nfunction streetsToGraph(streets) {\n var graph = createGraph(),\n streetToGraphBound = streetToGraph.bind(this, graph); //For each street, get an array of indices for the start, intersections, and end coordinates, in order from\n //start to end. Then, add the coordinates at each index as a node, and an edge between each adjacent node in the array,\n //associating the distance between the nodes (between their coordinates) with each edge.\n\n streets.eachLayer(streetToGraphBound);\n return graph;\n}\n/**\r\n * Process a street layer and add it into a graph.\r\n *\r\n * @param {ngraph.graph} graph - An ngraph.graph representing a street network.\r\n * @param {L.Polyline} street - A Leaflet Polyline layer for a street.\r\n */\n\n\nfunction streetToGraph(graph, street) {\n var street_id = street._leaflet_id,\n intersection_indices = [],\n street_points = street.getLatLngs(); //Populate intersection_indices with the indices of all of the street\'s intersections in its coordinate array.\n\n for (var cross_street in street.intersections) {\n var intersections = street.intersections[cross_street];\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n var _loop = function _loop() {\n var intersection = _step.value;\n var intersection_index = intersection[1][street_id]; //Ignore duplicate intersection points (caused by 3-way intersections).\n\n if (!intersection_indices.some(function (other_intersection_index) {\n return other_intersection_index === intersection_index;\n })) {\n intersection_indices.push(intersection_index);\n }\n };\n\n for (var _iterator = intersections[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n _loop();\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n } //Sort the intersection_indices so that they are in order from the start of the street\'s coordinate array to the end;\n //this is why we\'re not getting the raw coordinates, but their indices first, so they can be sorted.\n\n\n intersection_indices = intersection_indices.sort(function (a, b) {\n return a - b;\n }); //Check if beginning and end points of the street are in the intersection_incides; if not, add them.\n\n if (!intersection_indices.some(function (intersection_index) {\n return intersection_index === 0;\n })) {\n intersection_indices.unshift(0);\n }\n\n if (!intersection_indices.some(function (intersection_index) {\n return intersection_index === street_points.length - 1;\n })) {\n intersection_indices.push(street_points.length - 1);\n } //Make a graph out of segments of the street between the start, intersections, and end of the street,\n //so that the nodes are the coordinates of the start, end, and intersection points, and the edges are\n //the segments between successive nodes. Each edge is associated with the geographic distance between its nodes.\n\n\n for (var i = 0; i <= intersection_indices.length - 2; i++) {\n var node_a = street_points[intersection_indices[i]],\n node_b = street_points[intersection_indices[i + 1]],\n a_string = encodeLatLng(node_a),\n b_string = encodeLatLng(node_b),\n start_coords = L.A.pointToCoordinateArray(node_a),\n end_coords = L.A.pointToCoordinateArray(node_b),\n segment = lineSlice(start_coords, end_coords, street.toGeoJSON()),\n distance = length(segment);\n graph.addLink(a_string, b_string, {\n distance: distance,\n place: {\n type: "street",\n id: street_id\n }\n });\n }\n}\n/**\r\n * Given a street network (graph), return a pathfinder that can operate on it.\r\n * Useful if you modify the street graph during the simulation.\r\n * \r\n * @param {object} graph - An ngraph graph representing an OSM street network.\r\n * @returns {object} - An A* pathfinder for the graph.\r\n */\n\n\nfunction getPathFinder(graph) {\n return path.aStar(graph, {\n distance: function distance(fromNode, toNode, link) {\n return link.data.distance;\n }\n });\n}\n/**\r\n * Get a path between two points on a graph.\r\n * @memberof Agentmap\r\n * @instance\r\n * @private\r\n *\r\n * @param start_int_lat_lng {LatLng} - The coordinates of the nearest intersection on the same street at the start_lat_lng.\r\n * @param goal_int_lat_lng {LatLng} - The coordinates of the nearest intersection on the same street as the goal_lat_lng.\r\n * @param start_lat_lng {LatLng} - The coordinates of the point on the street from which the agent will be traveling.\r\n * @param goal_lat_lng {LatLng} - The coordinates of the point on the street to which the agent should travel.\r\n * @param {Boolean} [sparse=false] - Whether to exclude intersections between the first and last along a street-specific path (which are superfluous for extracting the necessary sub-street).\r\n * @return {Array>} - An array of points along the graph, leading from the start to the end.\r\n */\n\n\nfunction getPath(start_int_lat_lng, goal_int_lat_lng, start_lat_lng, goal_lat_lng) {\n var sparse = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n var start_coord = encodeLatLng(start_int_lat_lng),\n end_coord = encodeLatLng(goal_int_lat_lng),\n encoded_path = this.pathfinder.find(start_coord, end_coord),\n path = [];\n\n if (encoded_path.length > 0 && decodeCoordString(encoded_path[0].id).distanceTo(start_int_lat_lng) > decodeCoordString(encoded_path[0].id).distanceTo(goal_int_lat_lng)) {\n encoded_path = encoded_path.reverse();\n }\n\n if (sparse === true && encoded_path.length >= 2) {\n var sparse_path = [],\n recent_street = null,\n current_street = null;\n\n for (var i = 0; i <= encoded_path.length - 2; i++) {\n current_street = this.streets.graph.getLink(encoded_path[i].id, encoded_path[i + 1].id) || this.streets.graph.getLink(encoded_path[i + 1].id, encoded_path[i].id);\n\n if (recent_street === null || current_street.data.place.id !== recent_street.data.place.id) {\n var decoded_coords = decodeCoordString(encoded_path[i].id, current_street.data.place);\n sparse_path.push(decoded_coords);\n } //If the last place on the path to the goal is labeled with a different street id than the goal,\n //add it to the sparse path.\t\n\n\n if (i === encoded_path.length - 2) {\n var _decoded_coords = decodeCoordString(encoded_path[i + 1].id, current_street.data.place);\n\n sparse_path.push(_decoded_coords);\n }\n }\n\n path = sparse_path;\n } else {\n path = encoded_path.map(function (point) {\n return decodeCoordString(point.id, 0);\n });\n }\n\n path.unshift(start_lat_lng);\n path.push(goal_lat_lng); //If the goal point lies before the first intersection of the goal street, then the 2nd to last point in the\n //path will have the previous street\'s id attached to it. If the goal lies on a different street, make\n //sure the 2nd to last point (the street path intersection point before the goal) has the same street id as the goal.\n\n if (path[path.length - 2].new_place.id !== goal_lat_lng.new_place.id) {\n path[path.length - 2].new_place = goal_lat_lng.new_place;\n } //If the second [to last] point--namely the intersection closest to the start [goal]--is further from the third\n //[to last] point than the goal, and all three points are on the same street, remove the second [to last] point.\n\n\n if (path.length >= 3) {\n checkStartExcess.call(this, path);\n checkEndExcess.call(this, path);\n }\n\n return path;\n} //checkStartExcess and checkEndExcess are _much_ easier to follow given distinct variable names,\n//and so they are not abstracted into one more general function.\n\n/** \r\n * If the first two points after the start point share the same street as the start point, and the\r\n * third point is closer to the first (start) point than it is to the second point, remove the \r\n * second point, as it\'s a superfluous detour.

\r\n *\r\n * Typically happens when the start point\'s nearest intersection is beyond it on the street,\r\n * and so the path would have an agent travel from the start, then to the intersection,\r\n * then backwards to the third point.\r\n * @private\r\n *\r\n * @param {Array} path - An array of LatLngs representing a path for an agent to travel along.\r\n */\n\n\nfunction checkStartExcess(path) {\n var start_street = this.streets.getLayer(path[0].new_place.id),\n second_street_id = path[1].new_place.id,\n start_second_intersections = start_street.intersections[second_street_id],\n second_is_intersection = typeof start_second_intersections === "undefined" ? false : start_second_intersections.some(function (intersection) {\n return intersection[0].lat === path[1].lat && intersection[0].lng === path[1].lng;\n }),\n third_street_id = path[2].new_place.id,\n start_third_intersections = start_street.intersections[third_street_id],\n third_is_intersection = typeof start_third_intersections === "undefined" ? false : start_third_intersections.some(function (intersection) {\n return intersection[0].lat === path[2].lat && intersection[0].lng === path[2].lng;\n });\n\n if ((second_is_intersection || second_street_id === path[0].new_place.id) && (third_is_intersection || third_street_id === path[0].new_place.id)) {\n if (path[2].distanceTo(path[0]) < path[2].distanceTo(path[1])) {\n path.splice(1, 1);\n }\n }\n}\n/** \r\n * If the last two points before the goal point share the same street as the goal point, and the\r\n * first point is closer to the third (goal) point than it is to the second point, remove the \r\n * second point, as it\'s a superfluous detour.

\r\n *\r\n * Typically happens when the goal point\'s nearest intersection is beyond it on the street,\r\n * and so the path would have an agent travel from the first point, then to the intersection (second point),\r\n * then backwards to the (third) goal point.

\r\n *\r\n * @private\r\n *\r\n * @param {Array} path - An array of LatLngs representing a path for an agent to travel along.\r\n */\n\n\nfunction checkEndExcess(path) {\n var goal_street = this.streets.getLayer(path[path.length - 1].new_place.id),\n second_to_last_street_id = path[path.length - 2].new_place.id,\n goal_second_to_last_intersections = goal_street.intersections[second_to_last_street_id],\n second_to_last_is_intersection = typeof goal_second_to_last_intersections === "undefined" ? false : goal_second_to_last_intersections.some(function (intersection) {\n return intersection[0].lat === path[path.length - 1].lat && intersection[0].lng === path[path.length - 1].lng;\n }),\n third_last_street_id = path[path.length - 3].new_place.id,\n goal_third_last_intersections = goal_street.intersections[third_last_street_id],\n third_last_is_intersection = typeof goal_third_last_intersections === "undefined" ? false : goal_third_last_intersections.some(function (intersection) {\n return intersection[0].lat === path[path.length - 3].lat && intersection[0].lng === path[path.length - 3].lng;\n });\n\n if ((second_to_last_is_intersection || second_to_last_street_id === path[path.length - 1].new_place.id) && (third_last_is_intersection || third_last_street_id === path[path.length - 1].new_place.id) && path.length >= 3) {\n if (path[path.length - 3].distanceTo(path[path.length - 1]) < path[path.length - 3].distanceTo(path[path.length - 2])) {\n path.splice(path.length - 2, 1);\n }\n }\n}\n/**\r\n * Turn a LatLng object into a string representing its coordinates (to act as a graph node\'s ID).\r\n * @private\r\n *\r\n * @param {LatLng} lat_lng - The coordinates to encode into a string.\r\n * @returns {string} - A string containing coordinates in the format of "Latitude,Longitude".\r\n */\n\n\nfunction encodeLatLng(lat_lng) {\n return lat_lng.lat.toString() + "," + lat_lng.lng.toString();\n}\n/**\r\n * Turn a string containing coordinates (a graph node\'s ID) into a LatLng object.\r\n * @private\r\n *\r\n * @param {string} coord_string - A string containing coordinates in the format of "Latitude,Longitude".\r\n * @param {object} place - An object specifying the place of the coordinate string.\r\n * @returns {LatLng} - The coordinates encoded by the coord_string.\r\n */\n\n\nfunction decodeCoordString(coord_string, place) {\n var coord_strings = coord_string.split(","),\n lat_lng = L.latLng(coord_strings);\n lat_lng.new_place = place;\n return lat_lng;\n}\n\nAgentmap.prototype.getPath = getPath;\nexports.streetsToGraph = streetsToGraph;\nexports.getPathFinder = getPathFinder;\nexports.encodeLatLng = encodeLatLng;\n\n//# sourceURL=webpack:///./src/routing.js?')},function(module,exports){eval("/**\n * Based on https://github.com/mourner/tinyqueue\n * Copyright (c) 2017, Vladimir Agafonkin https://github.com/mourner/tinyqueue/blob/master/LICENSE\n * \n * Adapted for PathFinding needs by @anvaka\n * Copyright (c) 2017, Andrei Kashcha\n */\nmodule.exports = NodeHeap;\n\nfunction NodeHeap(data, options) {\n if (!(this instanceof NodeHeap)) return new NodeHeap(data, options);\n\n if (!Array.isArray(data)) {\n // assume first argument is our config object;\n options = data;\n data = [];\n }\n\n options = options || {};\n\n this.data = data || [];\n this.length = this.data.length;\n this.compare = options.compare || defaultCompare;\n this.setNodeId = options.setNodeId || noop;\n\n if (this.length > 0) {\n for (var i = (this.length >> 1); i >= 0; i--) this._down(i);\n }\n\n if (options.setNodeId) {\n for (var i = 0; i < this.length; ++i) {\n this.setNodeId(this.data[i], i);\n }\n }\n}\n\nfunction noop() {}\n\nfunction defaultCompare(a, b) {\n return a - b;\n}\n\nNodeHeap.prototype = {\n\n push: function (item) {\n this.data.push(item);\n this.setNodeId(item, this.length);\n this.length++;\n this._up(this.length - 1);\n },\n\n pop: function () {\n if (this.length === 0) return undefined;\n\n var top = this.data[0];\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = this.data[this.length];\n this.setNodeId(this.data[0], 0);\n this._down(0);\n }\n this.data.pop();\n\n return top;\n },\n\n peek: function () {\n return this.data[0];\n },\n\n updateItem: function (pos) {\n this._down(pos);\n this._up(pos);\n },\n\n _up: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var setNodeId = this.setNodeId;\n var item = data[pos];\n\n while (pos > 0) {\n var parent = (pos - 1) >> 1;\n var current = data[parent];\n if (compare(item, current) >= 0) break;\n data[pos] = current;\n\n setNodeId(current, pos);\n pos = parent;\n }\n\n data[pos] = item;\n setNodeId(item, pos);\n },\n\n _down: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var halfLength = this.length >> 1;\n var item = data[pos];\n var setNodeId = this.setNodeId;\n\n while (pos < halfLength) {\n var left = (pos << 1) + 1;\n var right = left + 1;\n var best = data[left];\n\n if (right < this.length && compare(data[right], best) < 0) {\n left = right;\n best = data[right];\n }\n if (compare(best, item) >= 0) break;\n\n data[pos] = best;\n setNodeId(best, pos);\n pos = left;\n }\n\n data[pos] = item;\n setNodeId(item, pos);\n }\n};\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/NodeHeap.js?")},function(module,exports){eval("module.exports = {\n l2: l2,\n l1: l1\n};\n\n/**\n * Euclid distance (l2 norm);\n * \n * @param {*} a \n * @param {*} b \n */\nfunction l2(a, b) {\n var dx = a.x - b.x;\n var dy = a.y - b.y;\n return Math.sqrt(dx * dx + dy * dy);\n}\n\n/**\n * Manhattan distance (l1 norm);\n * @param {*} a \n * @param {*} b \n */\nfunction l1(a, b) {\n var dx = a.x - b.x;\n var dy = a.y - b.y;\n return Math.abs(dx) + Math.abs(dy);\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/heuristics.js?")},function(module,exports){eval("// We reuse instance of array, but we trie to freeze it as well,\n// so that consumers don't modify it. Maybe it's a bad idea.\nvar NO_PATH = [];\nif (typeof Object.freeze === 'function') Object.freeze(NO_PATH);\n\nmodule.exports = {\n // Path search settings\n heuristic: blindHeuristic,\n distance: constantDistance,\n compareFScore: compareFScore,\n NO_PATH: NO_PATH,\n\n // heap settings\n setHeapIndex: setHeapIndex,\n\n // nba:\n setH1: setH1,\n setH2: setH2,\n compareF1Score: compareF1Score,\n compareF2Score: compareF2Score,\n}\n\nfunction blindHeuristic(/* a, b */) {\n // blind heuristic makes this search equal to plain Dijkstra path search.\n return 0;\n}\n\nfunction constantDistance(/* a, b */) {\n return 1;\n}\n\nfunction compareFScore(a, b) {\n var result = a.fScore - b.fScore;\n // TODO: Can I improve speed with smarter ties-breaking?\n // I tried distanceToSource, but it didn't seem to have much effect\n return result;\n}\n\nfunction setHeapIndex(nodeSearchState, heapIndex) {\n nodeSearchState.heapIndex = heapIndex;\n}\n\nfunction compareF1Score(a, b) {\n return a.f1 - b.f1;\n}\n\nfunction compareF2Score(a, b) {\n return a.f2 - b.f2;\n}\n\nfunction setH1(node, heapIndex) {\n node.h1 = heapIndex;\n}\n\nfunction setH2(node, heapIndex) {\n node.h2 = heapIndex;\n}\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/defaultSettings.js?")},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar factors = {\n meters: earthRadius,\n metres: earthRadius,\n millimeters: earthRadius * 1000,\n millimetres: earthRadius * 1000,\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n kilometers: earthRadius / 1000,\n kilometres: earthRadius / 1000,\n miles: earthRadius / 1609.344,\n nauticalmiles: earthRadius / 1852,\n inches: earthRadius * 39.370,\n yards: earthRadius / 1.0936,\n feet: earthRadius * 3.28084,\n radians: 1,\n degrees: earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = point(coordinates).geometry; break;\n case 'LineString': geom = lineString(coordinates).geometry; break;\n case 'Polygon': geom = polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/invariant/main.es.js\n\n\n/**\n * Unwrap a coordinate from a Point Feature, Geometry or a single coordinate.\n *\n * @name getCoord\n * @param {Array|Geometry|Feature} coord GeoJSON Point or an Array of numbers\n * @returns {Array} coordinates\n * @example\n * var pt = turf.point([10, 10]);\n *\n * var coord = turf.getCoord(pt);\n * //= [10, 10]\n */\nfunction getCoord(coord) {\n if (!coord) throw new Error('coord is required');\n if (coord.type === 'Feature' && coord.geometry !== null && coord.geometry.type === 'Point') return coord.geometry.coordinates;\n if (coord.type === 'Point') return coord.coordinates;\n if (Array.isArray(coord) && coord.length >= 2 && coord[0].length === undefined && coord[1].length === undefined) return coord;\n\n throw new Error('coord must be GeoJSON Point or an Array of numbers');\n}\n\n/**\n * Unwrap coordinates from a Feature, Geometry Object or an Array\n *\n * @name getCoords\n * @param {Array|Geometry|Feature} coords Feature, Geometry Object or an Array\n * @returns {Array} coordinates\n * @example\n * var poly = turf.polygon([[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]);\n *\n * var coords = turf.getCoords(poly);\n * //= [[[119.32, -8.7], [119.55, -8.69], [119.51, -8.54], [119.32, -8.7]]]\n */\nfunction getCoords(coords) {\n if (!coords) throw new Error('coords is required');\n\n // Feature\n if (coords.type === 'Feature' && coords.geometry !== null) return coords.geometry.coordinates;\n\n // Geometry\n if (coords.coordinates) return coords.coordinates;\n\n // Array of numbers\n if (Array.isArray(coords)) return coords;\n\n throw new Error('coords must be GeoJSON Feature, Geometry Object or an Array');\n}\n\n/**\n * Checks if coordinates contains a number\n *\n * @name containsNumber\n * @param {Array} coordinates GeoJSON Coordinates\n * @returns {boolean} true if Array contains a number\n */\nfunction containsNumber(coordinates) {\n if (coordinates.length > 1 && isNumber(coordinates[0]) && isNumber(coordinates[1])) {\n return true;\n }\n\n if (Array.isArray(coordinates[0]) && coordinates[0].length) {\n return containsNumber(coordinates[0]);\n }\n throw new Error('coordinates must only contain numbers');\n}\n\n/**\n * Enforce expectations about types of GeoJSON objects for Turf.\n *\n * @name geojsonType\n * @param {GeoJSON} value any GeoJSON object\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction geojsonType(value, type, name) {\n if (!type || !name) throw new Error('type and name required');\n\n if (!value || value.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + value.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link Feature} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name featureOf\n * @param {Feature} feature a feature with an expected geometry type\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} error if value is not the expected type.\n */\nfunction featureOf(feature, type, name) {\n if (!feature) throw new Error('No feature passed');\n if (!name) throw new Error('.featureOf() requires a name');\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n}\n\n/**\n * Enforce expectations about types of {@link FeatureCollection} inputs for Turf.\n * Internally this uses {@link geojsonType} to judge geometry types.\n *\n * @name collectionOf\n * @param {FeatureCollection} featureCollection a FeatureCollection for which features will be judged\n * @param {string} type expected GeoJSON type\n * @param {string} name name of calling function\n * @throws {Error} if value is not the expected type.\n */\nfunction collectionOf(featureCollection, type, name) {\n if (!featureCollection) throw new Error('No featureCollection passed');\n if (!name) throw new Error('.collectionOf() requires a name');\n if (!featureCollection || featureCollection.type !== 'FeatureCollection') {\n throw new Error('Invalid input to ' + name + ', FeatureCollection required');\n }\n for (var i = 0; i < featureCollection.features.length; i++) {\n var feature = featureCollection.features[i];\n if (!feature || feature.type !== 'Feature' || !feature.geometry) {\n throw new Error('Invalid input to ' + name + ', Feature with geometry required');\n }\n if (!feature.geometry || feature.geometry.type !== type) {\n throw new Error('Invalid input to ' + name + ': must be a ' + type + ', given ' + feature.geometry.type);\n }\n }\n}\n\n/**\n * Get Geometry from Feature or Geometry Object\n *\n * @param {Feature|Geometry} geojson GeoJSON Feature or Geometry Object\n * @returns {Geometry|null} GeoJSON Geometry Object\n * @throws {Error} if geojson is not a Feature or Geometry Object\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getGeom(point)\n * //={\"type\": \"Point\", \"coordinates\": [110, 40]}\n */\nfunction getGeom(geojson) {\n if (!geojson) throw new Error('geojson is required');\n if (geojson.geometry !== undefined) return geojson.geometry;\n if (geojson.coordinates || geojson.geometries) return geojson;\n throw new Error('geojson must be a valid Feature or Geometry Object');\n}\n\n/**\n * Get Geometry Type from Feature or Geometry Object\n *\n * @throws {Error} **DEPRECATED** in v5.0.0 in favor of getType\n */\nfunction getGeomType() {\n throw new Error('invariant.getGeomType has been deprecated in v5.0 in favor of invariant.getType');\n}\n\n/**\n * Get GeoJSON object's type, Geometry type is prioritize.\n *\n * @param {GeoJSON} geojson GeoJSON object\n * @param {string} [name=\"geojson\"] name of the variable to display in error message\n * @returns {string} GeoJSON type\n * @example\n * var point = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 40]\n * }\n * }\n * var geom = turf.getType(point)\n * //=\"Point\"\n */\nfunction getType(geojson, name) {\n if (!geojson) throw new Error((name || 'geojson') + ' is required');\n // GeoJSON Feature & GeometryCollection\n if (geojson.geometry && geojson.geometry.type) return geojson.geometry.type;\n // GeoJSON Geometry & FeatureCollection\n if (geojson.type) return geojson.type;\n throw new Error((name || 'geojson') + ' is invalid');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/bearing/main.es.js\n\n\n\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n\n/**\n * Takes two {@link Point|points} and finds the geographic bearing between them,\n * i.e. the angle measured in degrees from the north line (0 degrees)\n *\n * @name bearing\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.final=false] calculates the final bearing if true\n * @returns {number} bearing in decimal degrees, between -180 and 180 degrees (positive clockwise)\n * @example\n * var point1 = turf.point([-75.343, 39.984]);\n * var point2 = turf.point([-75.534, 39.123]);\n *\n * var bearing = turf.bearing(point1, point2);\n *\n * //addToMap\n * var addToMap = [point1, point2]\n * point1.properties['marker-color'] = '#f00'\n * point2.properties['marker-color'] = '#0f0'\n * point1.properties.bearing = bearing\n */\nfunction main_es_bearing(start, end, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var final = options.final;\n\n // Reverse calculation\n if (final === true) return calculateFinalBearing(start, end);\n\n var coordinates1 = getCoord(start);\n var coordinates2 = getCoord(end);\n\n var lon1 = degreesToRadians(coordinates1[0]);\n var lon2 = degreesToRadians(coordinates2[0]);\n var lat1 = degreesToRadians(coordinates1[1]);\n var lat2 = degreesToRadians(coordinates2[1]);\n var a = Math.sin(lon2 - lon1) * Math.cos(lat2);\n var b = Math.cos(lat1) * Math.sin(lat2) -\n Math.sin(lat1) * Math.cos(lat2) * Math.cos(lon2 - lon1);\n\n return radiansToDegrees(Math.atan2(a, b));\n}\n\n/**\n * Calculates Final Bearing\n *\n * @private\n * @param {Coord} start starting Point\n * @param {Coord} end ending Point\n * @returns {number} bearing\n */\nfunction calculateFinalBearing(start, end) {\n // Swap start & end\n var bear = main_es_bearing(end, start);\n bear = (bear + 180) % 360;\n return bear;\n}\n\n/* harmony default export */ var main_es = (main_es_bearing);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/distance/main.es.js\n\n\n\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n\n/**\n * Calculates the distance between two {@link Point|points} in degrees, radians,\n * miles, or kilometers. This uses the\n * [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula)\n * to account for global curvature.\n *\n * @name distance\n * @param {Coord} from origin point\n * @param {Coord} to destination point\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {number} distance between the two points\n * @example\n * var from = turf.point([-75.343, 39.984]);\n * var to = turf.point([-75.534, 39.123]);\n * var options = {units: 'miles'};\n *\n * var distance = turf.distance(from, to, options);\n *\n * //addToMap\n * var addToMap = [from, to];\n * from.properties.distance = distance;\n * to.properties.distance = distance;\n */\nfunction main_es_distance(from, to, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var units = options.units;\n\n var coordinates1 = getCoord(from);\n var coordinates2 = getCoord(to);\n var dLat = degreesToRadians((coordinates2[1] - coordinates1[1]));\n var dLon = degreesToRadians((coordinates2[0] - coordinates1[0]));\n var lat1 = degreesToRadians(coordinates1[1]);\n var lat2 = degreesToRadians(coordinates2[1]);\n\n var a = Math.pow(Math.sin(dLat / 2), 2) +\n Math.pow(Math.sin(dLon / 2), 2) * Math.cos(lat1) * Math.cos(lat2);\n\n return radiansToLength(2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)), units);\n}\n\n/* harmony default export */ var distance_main_es = (main_es_distance);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/destination/main.es.js\n\n\n\n//http://en.wikipedia.org/wiki/Haversine_formula\n//http://www.movable-type.co.uk/scripts/latlong.html\n/**\n * Takes a {@link Point} and calculates the location of a destination point given a distance in degrees, radians, miles, or kilometers; and bearing in degrees. This uses the [Haversine formula](http://en.wikipedia.org/wiki/Haversine_formula) to account for global curvature.\n *\n * @name destination\n * @param {Coord} origin starting point\n * @param {number} distance distance from the origin point\n * @param {number} bearing ranging from -180 to 180\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] miles, kilometers, degrees, or radians\n * @param {Object} [options.properties={}] Translate properties to Point\n * @returns {Feature} destination point\n * @example\n * var point = turf.point([-75.343, 39.984]);\n * var distance = 50;\n * var bearing = 90;\n * var options = {units: 'miles'};\n *\n * var destination = turf.destination(point, distance, bearing, options);\n *\n * //addToMap\n * var addToMap = [point, destination]\n * destination.properties['marker-color'] = '#f00';\n * point.properties['marker-color'] = '#0f0';\n */\nfunction destination(origin, distance, bearing, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var units = options.units;\n var properties = options.properties;\n\n // Handle input\n var coordinates1 = getCoord(origin);\n var longitude1 = degreesToRadians(coordinates1[0]);\n var latitude1 = degreesToRadians(coordinates1[1]);\n var bearing_rad = degreesToRadians(bearing);\n var radians = lengthToRadians(distance, units);\n\n // Main\n var latitude2 = Math.asin(Math.sin(latitude1) * Math.cos(radians) +\n Math.cos(latitude1) * Math.sin(radians) * Math.cos(bearing_rad));\n var longitude2 = longitude1 + Math.atan2(Math.sin(bearing_rad) * Math.sin(radians) * Math.cos(latitude1),\n Math.cos(radians) - Math.sin(latitude1) * Math.sin(latitude2));\n var lng = radiansToDegrees(longitude2);\n var lat = radiansToDegrees(latitude2);\n\n return point([lng, lat], properties);\n}\n\n/* harmony default export */ var destination_main_es = (destination);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/geojson-rbush/quickselect.js\nfunction quickselect(arr, k, left, right, compare) {\n quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);\n}\n\nfunction quickselectStep(arr, k, left, right, compare) {\n\n while (right > left) {\n if (right - left > 600) {\n var n = right - left + 1;\n var m = k - left + 1;\n var z = Math.log(n);\n var s = 0.5 * Math.exp(2 * z / 3);\n var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselectStep(arr, k, newLeft, newRight, compare);\n }\n\n var t = arr[k];\n var i = left;\n var j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap(arr, i, j) {\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\n/* harmony default export */ var geojson_rbush_quickselect = (quickselect);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/geojson-rbush/rbush.js\n\n\nfunction rbush(maxEntries, format) {\n if (!(this instanceof rbush)) return new rbush(maxEntries, format);\n\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries || 9);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\n if (format) {\n this._initFormat(format);\n }\n\n this.clear();\n}\n\nrbush.prototype = {\n\n all: function () {\n return this._all(this.data, []);\n },\n\n search: function (bbox) {\n\n var node = this.data,\n result = [],\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return result;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return result;\n },\n\n collides: function (bbox) {\n\n var node = this.data,\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return false;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) return true;\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return false;\n },\n\n load: function (data) {\n if (!(data && data.length)) return this;\n\n if (data.length < this._minEntries) {\n for (var i = 0, len = data.length; i < len; i++) {\n this.insert(data[i]);\n }\n return this;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n var node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n var tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n\n return this;\n },\n\n insert: function (item) {\n if (item) this._insert(item, this.data.height - 1);\n return this;\n },\n\n clear: function () {\n this.data = createNode([]);\n return this;\n },\n\n remove: function (item, equalsFn) {\n if (!item) return this;\n\n var node = this.data,\n bbox = this.toBBox(item),\n path = [],\n indexes = [],\n i, parent, index, goingUp;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n\n if (!node) { // go up\n node = path.pop();\n parent = path[path.length - 1];\n i = indexes.pop();\n goingUp = true;\n }\n\n if (node.leaf) { // check current node\n index = findItem(item, node.children, equalsFn);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n return this;\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n path.push(node);\n indexes.push(i);\n i = 0;\n parent = node;\n node = node.children[0];\n\n } else if (parent) { // go right\n i++;\n node = parent.children[i];\n goingUp = false;\n\n } else node = null; // nothing found\n }\n\n return this;\n },\n\n toBBox: function (item) { return item; },\n\n compareMinX: compareNodeMinX,\n compareMinY: compareNodeMinY,\n\n toJSON: function () { return this.data; },\n\n fromJSON: function (data) {\n this.data = data;\n return this;\n },\n\n _all: function (node, result) {\n var nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push.apply(result, node.children);\n else nodesToSearch.push.apply(nodesToSearch, node.children);\n\n node = nodesToSearch.pop();\n }\n return result;\n },\n\n _build: function (items, left, right, height) {\n\n var N = right - left + 1,\n M = this._maxEntries,\n node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n var N2 = Math.ceil(N / M),\n N1 = N2 * Math.ceil(Math.sqrt(M)),\n i, j, right2, right3;\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (i = left; i <= right; i += N1) {\n\n right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (j = i; j <= right2; j += N2) {\n\n right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n },\n\n _chooseSubtree: function (bbox, node, level, path) {\n\n var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;\n\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) break;\n\n minArea = minEnlargement = Infinity;\n\n for (i = 0, len = node.children.length; i < len; i++) {\n child = node.children[i];\n area = bboxArea(child);\n enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n },\n\n _insert: function (item, level, isNode) {\n\n var toBBox = this.toBBox,\n bbox = isNode ? item : toBBox(item),\n insertPath = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n var node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n },\n\n // split overflowed node into two\n _split: function (insertPath, level) {\n\n var node = insertPath[level],\n M = node.children.length,\n m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n var splitIndex = this._chooseSplitIndex(node, m, M);\n\n var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n },\n\n _splitRoot: function (node, newNode) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n },\n\n _chooseSplitIndex: function (node, m, M) {\n\n var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;\n\n minOverlap = minArea = Infinity;\n\n for (i = m; i <= M - m; i++) {\n bbox1 = distBBox(node, 0, i, this.toBBox);\n bbox2 = distBBox(node, i, M, this.toBBox);\n\n overlap = intersectionArea(bbox1, bbox2);\n area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index;\n },\n\n // sorts node children by the best axis for split\n _chooseSplitAxis: function (node, m, M) {\n\n var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,\n compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,\n xMargin = this._allDistMargin(node, m, M, compareMinX),\n yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) node.children.sort(compareMinX);\n },\n\n // total margin of all possible split distributions where each node is at least m full\n _allDistMargin: function (node, m, M, compare) {\n\n node.children.sort(compare);\n\n var toBBox = this.toBBox,\n leftBBox = distBBox(node, 0, m, toBBox),\n rightBBox = distBBox(node, M - m, M, toBBox),\n margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),\n i, child;\n\n for (i = m; i < M - m; i++) {\n child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (i = M - m - 1; i >= m; i--) {\n child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n },\n\n _adjustParentBBoxes: function (bbox, path, level) {\n // adjust bboxes along the given tree path\n for (var i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n },\n\n _condense: function (path) {\n // go through the path, removing empty nodes and updating bboxes\n for (var i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n\n } else this.clear();\n\n } else calcBBox(path[i], this.toBBox);\n }\n },\n\n _initFormat: function (format) {\n // data format (minX, minY, maxX, maxY accessors)\n\n // uses eval-type function compilation instead of just accepting a toBBox function\n // because the algorithms are very sensitive to sorting functions performance,\n // so they should be dead simple and without inner calls\n\n var compareArr = ['return a', ' - b', ';'];\n\n this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));\n this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));\n\n this.toBBox = new Function('a',\n 'return {minX: a' + format[0] +\n ', minY: a' + format[1] +\n ', maxX: a' + format[2] +\n ', maxY: a' + format[3] + '};');\n }\n};\n\nfunction findItem(item, items, equalsFn) {\n if (!equalsFn) return items.indexOf(item);\n\n for (var i = 0; i < items.length; i++) {\n if (equalsFn(item, items[i])) return i;\n }\n return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n if (!destNode) destNode = createNode(null);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (var i = k, child; i < p; i++) {\n child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a, b) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n var minX = Math.max(a.minX, b.minX),\n minY = Math.max(a.minY, b.minY),\n maxX = Math.min(a.maxX, b.maxX),\n maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) *\n Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n return a.minX <= b.minX &&\n a.minY <= b.minY &&\n b.maxX <= a.maxX &&\n b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n return b.minX <= a.maxX &&\n b.minY <= a.maxY &&\n b.maxX >= a.minX &&\n b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n return {\n children: children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n var stack = [left, right],\n mid;\n\n while (stack.length) {\n right = stack.pop();\n left = stack.pop();\n\n if (right - left <= n) continue;\n\n mid = left + Math.ceil((right - left) / n / 2) * n;\n geojson_rbush_quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n\n/* harmony default export */ var geojson_rbush_rbush = (rbush);\n\n// EXTERNAL MODULE: ./node_modules/@turf/meta/main.es.js + 1 modules\nvar meta_main_es = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/geojson-rbush/index.js\n\n\n\n/**\n * GeoJSON implementation of [RBush](https://github.com/mourner/rbush#rbush) spatial index.\n *\n * @name rbush\n * @param {number} [maxEntries=9] defines the maximum number of entries in a tree node. 9 (used by default) is a\n * reasonable choice for most applications. Higher value means faster insertion and slower search, and vice versa.\n * @returns {RBush} GeoJSON RBush\n * @example\n * import geojsonRbush from 'geojson-rbush';\n * var tree = geojsonRbush();\n */\nfunction geojsonRbush(maxEntries) {\n var tree = geojson_rbush_rbush(maxEntries);\n /**\n * [insert](https://github.com/mourner/rbush#data-format)\n *\n * @param {Feature} feature insert single GeoJSON Feature\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.insert(polygon)\n */\n tree.insert = function (feature) {\n if (Array.isArray(feature)) {\n var bbox = feature;\n feature = bboxPolygon(bbox);\n feature.bbox = bbox;\n } else {\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n }\n return geojson_rbush_rbush.prototype.insert.call(this, feature);\n };\n\n /**\n * [load](https://github.com/mourner/rbush#bulk-inserting-data)\n *\n * @param {BBox[]|FeatureCollection} features load entire GeoJSON FeatureCollection\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polygons = {\n * \"type\": \"FeatureCollection\",\n * \"features\": [\n * {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * },\n * {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]]\n * }\n * }\n * ]\n * }\n * tree.load(polygons)\n */\n tree.load = function (features) {\n var load = [];\n // Load an Array of BBox\n if (Array.isArray(features)) {\n features.forEach(function (bbox) {\n var feature = bboxPolygon(bbox);\n feature.bbox = bbox;\n load.push(feature);\n });\n } else {\n // Load FeatureCollection\n Object(meta_main_es[\"b\" /* featureEach */])(features, function (feature) {\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n load.push(feature);\n });\n }\n return geojson_rbush_rbush.prototype.load.call(this, load);\n };\n\n /**\n * [remove](https://github.com/mourner/rbush#removing-data)\n *\n * @param {BBox|Feature} feature remove single GeoJSON Feature\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.remove(polygon)\n */\n tree.remove = function (feature) {\n if (Array.isArray(feature)) {\n var bbox = feature;\n feature = bboxPolygon(bbox);\n feature.bbox = bbox;\n }\n return geojson_rbush_rbush.prototype.remove.call(this, feature);\n };\n\n /**\n * [clear](https://github.com/mourner/rbush#removing-data)\n *\n * @returns {RBush} GeoJSON Rbush\n * @example\n * tree.clear()\n */\n tree.clear = function () {\n return geojson_rbush_rbush.prototype.clear.call(this);\n };\n\n /**\n * [search](https://github.com/mourner/rbush#search)\n *\n * @param {BBox|FeatureCollection|Feature} geojson search with GeoJSON\n * @returns {FeatureCollection} all features that intersects with the given GeoJSON.\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.search(polygon)\n */\n tree.search = function (geojson) {\n var features = geojson_rbush_rbush.prototype.search.call(this, this.toBBox(geojson));\n return {\n type: 'FeatureCollection',\n features: features\n };\n };\n\n /**\n * [collides](https://github.com/mourner/rbush#collisions)\n *\n * @param {BBox|FeatureCollection|Feature} geojson collides with GeoJSON\n * @returns {boolean} true if there are any items intersecting the given GeoJSON, otherwise false.\n * @example\n * var polygon = {\n * \"type\": \"Feature\",\n * \"properties\": {},\n * \"geometry\": {\n * \"type\": \"Polygon\",\n * \"coordinates\": [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]\n * }\n * }\n * tree.collides(polygon)\n */\n tree.collides = function (geojson) {\n return geojson_rbush_rbush.prototype.collides.call(this, this.toBBox(geojson));\n };\n\n /**\n * [all](https://github.com/mourner/rbush#search)\n *\n * @returns {FeatureCollection} all the features in RBush\n * @example\n * tree.all()\n * //=FeatureCollection\n */\n tree.all = function () {\n var features = geojson_rbush_rbush.prototype.all.call(this);\n return {\n type: 'FeatureCollection',\n features: features\n };\n };\n\n /**\n * [toJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @returns {any} export data as JSON object\n * @example\n * var exported = tree.toJSON()\n * //=JSON object\n */\n tree.toJSON = function () {\n return geojson_rbush_rbush.prototype.toJSON.call(this);\n };\n\n /**\n * [fromJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @param {any} json import previously exported data\n * @returns {RBush} GeoJSON RBush\n * @example\n * var exported = {\n * \"children\": [\n * {\n * \"type\": \"Feature\",\n * \"geometry\": {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * },\n * \"properties\": {},\n * \"bbox\": [110, 50, 110, 50]\n * }\n * ],\n * \"height\": 1,\n * \"leaf\": true,\n * \"minX\": 110,\n * \"minY\": 50,\n * \"maxX\": 110,\n * \"maxY\": 50\n * }\n * tree.fromJSON(exported)\n */\n tree.fromJSON = function (json) {\n return geojson_rbush_rbush.prototype.fromJSON.call(this, json);\n };\n\n /**\n * Converts GeoJSON to {minX, minY, maxX, maxY} schema\n *\n * @private\n * @param {BBox|FeatureCollectio|Feature} geojson feature(s) to retrieve BBox from\n * @returns {Object} converted to {minX, minY, maxX, maxY}\n */\n tree.toBBox = function (geojson) {\n var bbox;\n if (geojson.bbox) bbox = geojson.bbox;\n else if (Array.isArray(geojson) && geojson.length === 4) bbox = geojson;\n else bbox = turfBBox(geojson);\n\n return {\n minX: bbox[0],\n minY: bbox[1],\n maxX: bbox[2],\n maxY: bbox[3]\n };\n };\n return tree;\n}\n\n/**\n * Takes a bbox and returns an equivalent {@link Polygon|polygon}.\n *\n * @private\n * @name bboxPolygon\n * @param {Array} bbox extent in [minX, minY, maxX, maxY] order\n * @returns {Feature} a Polygon representation of the bounding box\n * @example\n * var bbox = [0, 0, 10, 10];\n *\n * var poly = turf.bboxPolygon(bbox);\n *\n * //addToMap\n * var addToMap = [poly]\n */\nfunction bboxPolygon(bbox) {\n var lowLeft = [bbox[0], bbox[1]];\n var topLeft = [bbox[0], bbox[3]];\n var topRight = [bbox[2], bbox[3]];\n var lowRight = [bbox[2], bbox[1]];\n var coordinates = [[lowLeft, lowRight, topRight, topLeft, lowLeft]];\n\n return {\n type: 'Feature',\n bbox: bbox,\n properties: {},\n geometry: {\n type: 'Polygon',\n coordinates: coordinates\n }\n };\n}\n\n/**\n * Takes a set of features, calculates the bbox of all input features, and returns a bounding box.\n *\n * @private\n * @name bbox\n * @param {FeatureCollection|Feature} geojson input features\n * @returns {Array} bbox extent in [minX, minY, maxX, maxY] order\n * @example\n * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]]);\n * var bbox = turf.bbox(line);\n * var bboxPolygon = turf.bboxPolygon(bbox);\n *\n * //addToMap\n * var addToMap = [line, bboxPolygon]\n */\nfunction turfBBox(geojson) {\n var bbox = [Infinity, Infinity, -Infinity, -Infinity];\n Object(meta_main_es[\"a\" /* coordEach */])(geojson, function (coord) {\n if (bbox[0] > coord[0]) bbox[0] = coord[0];\n if (bbox[1] > coord[1]) bbox[1] = coord[1];\n if (bbox[2] < coord[0]) bbox[2] = coord[0];\n if (bbox[3] < coord[1]) bbox[3] = coord[1];\n });\n return bbox;\n}\n\n/* harmony default export */ var geojson_rbush = (geojsonRbush);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/line-segment/main.es.js\n\n\n\n\n/**\n * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}.\n *\n * @name lineSegment\n * @param {Geometry|FeatureCollection|Feature} geojson GeoJSON Polygon or LineString\n * @returns {FeatureCollection} 2-vertex line segments\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n * var segments = turf.lineSegment(polygon);\n *\n * //addToMap\n * var addToMap = [polygon, segments]\n */\nfunction lineSegment(geojson) {\n if (!geojson) throw new Error('geojson is required');\n\n var results = [];\n Object(meta_main_es[\"c\" /* flattenEach */])(geojson, function (feature) {\n lineSegmentFeature(feature, results);\n });\n return featureCollection(results);\n}\n\n/**\n * Line Segment\n *\n * @private\n * @param {Feature} geojson Line or polygon feature\n * @param {Array} results push to results\n * @returns {void}\n */\nfunction lineSegmentFeature(geojson, results) {\n var coords = [];\n var geometry = geojson.geometry;\n switch (geometry.type) {\n case 'Polygon':\n coords = getCoords(geometry);\n break;\n case 'LineString':\n coords = [getCoords(geometry)];\n }\n coords.forEach(function (coord) {\n var segments = createSegments(coord, geojson.properties);\n segments.forEach(function (segment) {\n segment.id = results.length;\n results.push(segment);\n });\n });\n}\n\n/**\n * Create Segments from LineString coordinates\n *\n * @private\n * @param {LineString} coords LineString coordinates\n * @param {*} properties GeoJSON properties\n * @returns {Array>} line segments\n */\nfunction createSegments(coords, properties) {\n var segments = [];\n coords.reduce(function (previousCoords, currentCoords) {\n var segment = lineString([previousCoords, currentCoords], properties);\n segment.bbox = main_es_bbox(previousCoords, currentCoords);\n segments.push(segment);\n return currentCoords;\n });\n return segments;\n}\n\n/**\n * Create BBox between two coordinates (faster than @turf/bbox)\n *\n * @private\n * @param {Array} coords1 Point coordinate\n * @param {Array} coords2 Point coordinate\n * @returns {BBox} [west, south, east, north]\n */\nfunction main_es_bbox(coords1, coords2) {\n var x1 = coords1[0];\n var y1 = coords1[1];\n var x2 = coords2[0];\n var y2 = coords2[1];\n var west = (x1 < x2) ? x1 : x2;\n var south = (y1 < y2) ? y1 : y2;\n var east = (x1 > x2) ? x1 : x2;\n var north = (y1 > y2) ? y1 : y2;\n return [west, south, east, north];\n}\n\n/* harmony default export */ var line_segment_main_es = (lineSegment);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/line-intersect/main.es.js\n\n\n\n\n\n\n/**\n * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s).\n *\n * @name lineIntersect\n * @param {Geometry|FeatureCollection|Feature} line1 any LineString or Polygon\n * @param {Geometry|FeatureCollection|Feature} line2 any LineString or Polygon\n * @returns {FeatureCollection} point(s) that intersect both\n * @example\n * var line1 = turf.lineString([[126, -11], [129, -21]]);\n * var line2 = turf.lineString([[123, -18], [131, -14]]);\n * var intersects = turf.lineIntersect(line1, line2);\n *\n * //addToMap\n * var addToMap = [line1, line2, intersects]\n */\nfunction lineIntersect(line1, line2) {\n var unique = {};\n var results = [];\n\n // First, normalize geometries to features\n // Then, handle simple 2-vertex segments\n if (line1.type === 'LineString') line1 = main_es_feature(line1);\n if (line2.type === 'LineString') line2 = main_es_feature(line2);\n if (line1.type === 'Feature' &&\n line2.type === 'Feature' &&\n line1.geometry.type === 'LineString' &&\n line2.geometry.type === 'LineString' &&\n line1.geometry.coordinates.length === 2 &&\n line2.geometry.coordinates.length === 2) {\n var intersect = main_es_intersects(line1, line2);\n if (intersect) results.push(intersect);\n return featureCollection(results);\n }\n\n // Handles complex GeoJSON Geometries\n var tree = geojson_rbush();\n tree.load(line_segment_main_es(line2));\n Object(meta_main_es[\"b\" /* featureEach */])(line_segment_main_es(line1), function (segment) {\n Object(meta_main_es[\"b\" /* featureEach */])(tree.search(segment), function (match) {\n var intersect = main_es_intersects(segment, match);\n if (intersect) {\n // prevent duplicate points https://github.com/Turfjs/turf/issues/688\n var key = getCoords(intersect).join(',');\n if (!unique[key]) {\n unique[key] = true;\n results.push(intersect);\n }\n }\n });\n });\n return featureCollection(results);\n}\n\n/**\n * Find a point that intersects LineStrings with two coordinates each\n *\n * @private\n * @param {Feature} line1 GeoJSON LineString (Must only contain 2 coordinates)\n * @param {Feature} line2 GeoJSON LineString (Must only contain 2 coordinates)\n * @returns {Feature} intersecting GeoJSON Point\n */\nfunction main_es_intersects(line1, line2) {\n var coords1 = getCoords(line1);\n var coords2 = getCoords(line2);\n if (coords1.length !== 2) {\n throw new Error(' line1 must only contain 2 coordinates');\n }\n if (coords2.length !== 2) {\n throw new Error(' line2 must only contain 2 coordinates');\n }\n var x1 = coords1[0][0];\n var y1 = coords1[0][1];\n var x2 = coords1[1][0];\n var y2 = coords1[1][1];\n var x3 = coords2[0][0];\n var y3 = coords2[0][1];\n var x4 = coords2[1][0];\n var y4 = coords2[1][1];\n var denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));\n var numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));\n var numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));\n\n if (denom === 0) {\n if (numeA === 0 && numeB === 0) {\n return null;\n }\n return null;\n }\n\n var uA = numeA / denom;\n var uB = numeB / denom;\n\n if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {\n var x = x1 + (uA * (x2 - x1));\n var y = y1 + (uA * (y2 - y1));\n return point([x, y]);\n }\n return null;\n}\n\n/* harmony default export */ var line_intersect_main_es = (lineIntersect);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/node_modules/@turf/nearest-point-on-line/main.es.js\n\n\n\n\n\n\n\n\n/**\n * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.\n *\n * @name nearestPointOnLine\n * @param {Geometry|Feature} lines lines to snap to\n * @param {Geometry|Feature|number[]} pt point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {Feature} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var pt = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, pt, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine(lines, pt, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n\n // validation\n var type = (lines.geometry) ? lines.geometry.type : lines.type;\n if (type !== 'LineString' && type !== 'MultiLineString') {\n throw new Error('lines must be LineString or MultiLineString');\n }\n\n var closestPt = point([Infinity, Infinity], {\n dist: Infinity\n });\n\n var length = 0.0;\n Object(meta_main_es[\"c\" /* flattenEach */])(lines, function (line) {\n var coords = getCoords(line);\n\n for (var i = 0; i < coords.length - 1; i++) {\n //start\n var start = point(coords[i]);\n start.properties.dist = distance_main_es(pt, start, options);\n //stop\n var stop = point(coords[i + 1]);\n stop.properties.dist = distance_main_es(pt, stop, options);\n // sectionLength\n var sectionLength = distance_main_es(start, stop, options);\n //perpendicular\n var heightDistance = Math.max(start.properties.dist, stop.properties.dist);\n var direction = main_es(start, stop);\n var perpendicularPt1 = destination_main_es(pt, heightDistance, direction + 90, options);\n var perpendicularPt2 = destination_main_es(pt, heightDistance, direction - 90, options);\n var intersect = line_intersect_main_es(\n lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]),\n lineString([start.geometry.coordinates, stop.geometry.coordinates])\n );\n var intersectPt = null;\n if (intersect.features.length > 0) {\n intersectPt = intersect.features[0];\n intersectPt.properties.dist = distance_main_es(pt, intersectPt, options);\n intersectPt.properties.location = length + distance_main_es(start, intersectPt, options);\n }\n\n if (start.properties.dist < closestPt.properties.dist) {\n closestPt = start;\n closestPt.properties.index = i;\n closestPt.properties.location = length;\n }\n if (stop.properties.dist < closestPt.properties.dist) {\n closestPt = stop;\n closestPt.properties.index = i + 1;\n closestPt.properties.location = length + sectionLength;\n }\n if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {\n closestPt = intersectPt;\n closestPt.properties.index = i;\n }\n // update length\n length += sectionLength;\n }\n\n });\n\n return closestPt;\n}\n\n/* harmony default export */ var nearest_point_on_line_main_es = (nearestPointOnLine);\n\n// CONCATENATED MODULE: ./node_modules/@turf/line-slice/main.es.js\n\n\n\n\n/**\n * Takes a {@link LineString|line}, a start {@link Point}, and a stop point\n * and returns a subsection of the line in-between those points.\n * The start & stop points don't need to fall exactly on the line.\n *\n * This can be useful for extracting only the part of a route between waypoints.\n *\n * @name lineSlice\n * @param {Coord} startPt starting point\n * @param {Coord} stopPt stopping point\n * @param {Feature|LineString} line line to slice\n * @returns {Feature} sliced line\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var start = turf.point([-77.029609, 38.881946]);\n * var stop = turf.point([-77.021884, 38.889563]);\n *\n * var sliced = turf.lineSlice(start, stop, line);\n *\n * //addToMap\n * var addToMap = [start, stop, line]\n */\nfunction lineSlice(startPt, stopPt, line) {\n // Validation\n var coords = getCoords(line);\n if (getType(line) !== 'LineString') throw new Error('line must be a LineString');\n\n var startVertex = nearest_point_on_line_main_es(line, startPt);\n var stopVertex = nearest_point_on_line_main_es(line, stopPt);\n var ends;\n if (startVertex.properties.index <= stopVertex.properties.index) {\n ends = [startVertex, stopVertex];\n } else {\n ends = [stopVertex, startVertex];\n }\n var clipCoords = [ends[0].geometry.coordinates];\n for (var i = ends[0].properties.index + 1; i < ends[1].properties.index + 1; i++) {\n clipCoords.push(coords[i]);\n }\n clipCoords.push(ends[1].geometry.coordinates);\n return lineString(clipCoords, line.properties);\n}\n\n/* harmony default export */ var line_slice_main_es = __webpack_exports__[\"default\"] = (lineSlice);\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-slice/main.es.js_+_11_modules?")},function(module,exports,__webpack_require__){"use strict";eval('\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { "default": mod };\n}\nObject.defineProperty(exports, "__esModule", { value: true });\nvar bearing_1 = __importDefault(__webpack_require__(5));\nvar destination_1 = __importDefault(__webpack_require__(6));\nvar distance_1 = __importDefault(__webpack_require__(9));\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n/**\n * Takes a {@link LineString} and returns a {@link Point} at a specified distance along the line.\n *\n * @name along\n * @param {Feature} line input line\n * @param {number} distance distance along the line\n * @param {Object} [options] Optional parameters\n * @param {string} [options.units="kilometers"] can be degrees, radians, miles, or kilometers\n * @returns {Feature} Point `distance` `units` along the line\n * @example\n * var line = turf.lineString([[-83, 30], [-84, 36], [-78, 41]]);\n * var options = {units: \'miles\'};\n *\n * var along = turf.along(line, 200, options);\n *\n * //addToMap\n * var addToMap = [along, line]\n */\nfunction along(line, distance, options) {\n if (options === void 0) { options = {}; }\n // Get Coords\n var geom = invariant_1.getGeom(line);\n var coords = geom.coordinates;\n var travelled = 0;\n for (var i = 0; i < coords.length; i++) {\n if (distance >= travelled && i === coords.length - 1) {\n break;\n }\n else if (travelled >= distance) {\n var overshot = distance - travelled;\n if (!overshot) {\n return helpers_1.point(coords[i]);\n }\n else {\n var direction = bearing_1.default(coords[i], coords[i - 1]) - 180;\n var interpolated = destination_1.default(coords[i], overshot, direction, options);\n return interpolated;\n }\n }\n else {\n travelled += distance_1.default(coords[i], coords[i + 1], options);\n }\n }\n return helpers_1.point(coords[coords.length - 1]);\n}\nexports.default = along;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/along/index.js?')},function(module,exports,__webpack_require__){"use strict";eval('\nvar __importDefault = (this && this.__importDefault) || function (mod) {\n return (mod && mod.__esModule) ? mod : { "default": mod };\n}\nObject.defineProperty(exports, "__esModule", { value: true });\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\nvar line_segment_1 = __importDefault(__webpack_require__(25));\nvar meta_1 = __webpack_require__(27);\nvar geojson_rbush_1 = __importDefault(__webpack_require__(28));\n/**\n * Takes any LineString or Polygon GeoJSON and returns the intersecting point(s).\n *\n * @name lineIntersect\n * @param {GeoJSON} line1 any LineString or Polygon\n * @param {GeoJSON} line2 any LineString or Polygon\n * @returns {FeatureCollection} point(s) that intersect both\n * @example\n * var line1 = turf.lineString([[126, -11], [129, -21]]);\n * var line2 = turf.lineString([[123, -18], [131, -14]]);\n * var intersects = turf.lineIntersect(line1, line2);\n *\n * //addToMap\n * var addToMap = [line1, line2, intersects]\n */\nfunction lineIntersect(line1, line2) {\n var unique = {};\n var results = [];\n // First, normalize geometries to features\n // Then, handle simple 2-vertex segments\n if (line1.type === "LineString") {\n line1 = helpers_1.feature(line1);\n }\n if (line2.type === "LineString") {\n line2 = helpers_1.feature(line2);\n }\n if (line1.type === "Feature" &&\n line2.type === "Feature" &&\n line1.geometry !== null &&\n line2.geometry !== null &&\n line1.geometry.type === "LineString" &&\n line2.geometry.type === "LineString" &&\n line1.geometry.coordinates.length === 2 &&\n line2.geometry.coordinates.length === 2) {\n var intersect = intersects(line1, line2);\n if (intersect) {\n results.push(intersect);\n }\n return helpers_1.featureCollection(results);\n }\n // Handles complex GeoJSON Geometries\n var tree = geojson_rbush_1.default();\n tree.load(line_segment_1.default(line2));\n meta_1.featureEach(line_segment_1.default(line1), function (segment) {\n meta_1.featureEach(tree.search(segment), function (match) {\n var intersect = intersects(segment, match);\n if (intersect) {\n // prevent duplicate points https://github.com/Turfjs/turf/issues/688\n var key = invariant_1.getCoords(intersect).join(",");\n if (!unique[key]) {\n unique[key] = true;\n results.push(intersect);\n }\n }\n });\n });\n return helpers_1.featureCollection(results);\n}\n/**\n * Find a point that intersects LineStrings with two coordinates each\n *\n * @private\n * @param {Feature} line1 GeoJSON LineString (Must only contain 2 coordinates)\n * @param {Feature} line2 GeoJSON LineString (Must only contain 2 coordinates)\n * @returns {Feature} intersecting GeoJSON Point\n */\nfunction intersects(line1, line2) {\n var coords1 = invariant_1.getCoords(line1);\n var coords2 = invariant_1.getCoords(line2);\n if (coords1.length !== 2) {\n throw new Error(" line1 must only contain 2 coordinates");\n }\n if (coords2.length !== 2) {\n throw new Error(" line2 must only contain 2 coordinates");\n }\n var x1 = coords1[0][0];\n var y1 = coords1[0][1];\n var x2 = coords1[1][0];\n var y2 = coords1[1][1];\n var x3 = coords2[0][0];\n var y3 = coords2[0][1];\n var x4 = coords2[1][0];\n var y4 = coords2[1][1];\n var denom = ((y4 - y3) * (x2 - x1)) - ((x4 - x3) * (y2 - y1));\n var numeA = ((x4 - x3) * (y1 - y3)) - ((y4 - y3) * (x1 - x3));\n var numeB = ((x2 - x1) * (y1 - y3)) - ((y2 - y1) * (x1 - x3));\n if (denom === 0) {\n if (numeA === 0 && numeB === 0) {\n return null;\n }\n return null;\n }\n var uA = numeA / denom;\n var uB = numeB / denom;\n if (uA >= 0 && uA <= 1 && uB >= 0 && uB <= 1) {\n var x = x1 + (uA * (x2 - x1));\n var y = y1 + (uA * (y2 - y1));\n return helpers_1.point([x, y]);\n }\n return null;\n}\nexports.default = lineIntersect;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-intersect/index.js?')},function(module,exports){eval("/**\n * This class represents a single search node in the exploration tree for\n * A* algorithm.\n * \n * @param {Object} node original node in the graph\n */\nfunction NodeSearchState(node) {\n this.node = node;\n\n // How we came to this node?\n this.parent = null;\n\n this.closed = false;\n this.open = 0;\n\n this.distanceToSource = Number.POSITIVE_INFINITY;\n // the f(n) = g(n) + h(n) value\n this.fScore = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated.\n this.heapIndex = -1;\n};\n\nfunction makeSearchStatePool() {\n var currentInCache = 0;\n var nodeCache = [];\n\n return {\n createNewState: createNewState,\n reset: reset\n };\n\n function reset() {\n currentInCache = 0;\n }\n\n function createNewState(node) {\n var cached = nodeCache[currentInCache];\n if (cached) {\n // TODO: This almost duplicates constructor code. Not sure if\n // it would impact performance if I move this code into a function\n cached.node = node;\n // How we came to this node?\n cached.parent = null;\n\n cached.closed = false;\n cached.open = 0;\n\n cached.distanceToSource = Number.POSITIVE_INFINITY;\n // the f(n) = g(n) + h(n) value\n cached.fScore = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated.\n cached.heapIndex = -1;\n\n } else {\n cached = new NodeSearchState(node);\n nodeCache[currentInCache] = cached;\n }\n currentInCache++;\n return cached;\n }\n}\nmodule.exports = makeSearchStatePool;\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/makeSearchStatePool.js?")},function(module,exports,__webpack_require__){eval("var agentmap = __webpack_require__(4),\n agents = __webpack_require__(20),\n buildings = __webpack_require__(40),\n utils = __webpack_require__(43);\n\nL.A = Object.assign({}, agentmap, agents, utils);\n\n//# sourceURL=webpack:///./src/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/length/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){eval('function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n/* Here we define agentify, the agent base class, and everything they uniquely rely on. */\nvar centroid = __webpack_require__(21).default,\n buffer = __webpack_require__(44).default,\n booleanPointInPolygon = __webpack_require__(23).default,\n along = __webpack_require__(15).default,\n nearestPointOnLine = __webpack_require__(24).default,\n lineSlice = __webpack_require__(14).default,\n length = __webpack_require__(8).default,\n lineString = __webpack_require__(1).lineString,\n bearing = __webpack_require__(5).default,\n destination = __webpack_require__(6).default,\n Agentmap = __webpack_require__(4).Agentmap,\n encodeLatLng = __webpack_require__(10).encodeLatLng;\n/**\r\n * The main class representing individual agents, using Leaflet class system.\r\n * @private\r\n *\r\n * @class Agent\r\n */\n\n\nvar Agent = {};\n/**\r\n * Constructor for the Agent class, using Leaflet class system.\r\n * \r\n * @name Agent\r\n * @constructor \r\n * @param {LatLng} lat_lng - A pair of coordinates to place the agent at.\r\n * @param {Object} options - An array of options for the agent, namely its layer.\r\n * @param {Agentmap} agentmap - The agentmap instance in which the agent exists.\r\n * @property {Agentmap} agentmap - The agentmap instance in which the agent exists.\r\n * @property {Place} place - A place object specifying where the agent is currently at.\r\n * @property {number} [steps_made=0] - The number of steps the agent has moved since the beginning.\r\n * @property {Object} this.trip - Properties detailing information about the agent\'s trip that change sometimes, but needs to be accessed by future updates.\r\n * @property {boolean} this.trip.moving - Whether the agent currently moving.\r\n * @property {boolean} this.trip.paused - Whether the agent should be allowed to move along its trip.\r\n * @property {?Point} this.trip.current_point - The point where the agent is currently located.\r\n * @property {?Point} this.trip.goal_point - The point where the agent is traveling to.\r\n * @property {?number} this.trip.lat_dir - The latitudinal direction. -1 if traveling to lower latitude (down), 1 if traveling to higher latitude (up).\r\n * @property {?number} this.trip.lng_dir - The longitudinal direction. -1 if traveling to lesser longitude (left), 1 if traveling to greater longitude (right).\r\n * @property {?number} this.trip.speed - The speed that the agent should travel, in meters per tick.\r\n * @property {?number} this.trip.angle - The angle between the current point and the goal.\r\n * @property {?number} this.trip.slope - The slope of the line segment formed by the two points between which the agent is traveling at this time during its trip.\r\n * @property {Array} this.trip.path - A sequence of LatLngs; the agent will move from one to the next, popping each one off after it arrives until the end of the street; or, until the trip is changed/reset.\r\n * @property {?function} controller - User-defined function to be called on each update (each tick).\r\n * @property {?function} fine_controller - User-defined function to be called before & after each movemnt (on each step an agent performs during a tick).\r\n */\n\nAgent.initialize = function (lat_lng, options, agentmap) {\n this.agentmap = agentmap, this.place = null, this.steps_made = 0, this.trip = {\n paused: false,\n moving: false,\n current_point: null,\n goal_point: null,\n lat_dir: null,\n lng_dir: null,\n slope: null,\n angle: null,\n speed: null,\n path: []\n }, this.controller = function () {}, this.fine_controller = function () {};\n L.CircleMarker.prototype.initialize.call(this, lat_lng, options);\n};\n/**\r\n * Reset all the properties of its trip, but don\'t change whether it\'s allowed to be traveling or not.\r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.resetTrip = function () {\n for (var key in this.trip) {\n this.trip[key] = key === "paused" ? false : key === "moving" ? false : key === "path" ? [] : null;\n }\n};\n/**\r\n * Set the agent up to start traveling along the path specified in the agent\'s trip..\r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.startTrip = function () {\n if (this.trip.path.length > 0) {\n this.travelTo(this.trip.path[0]);\n }\n};\n/**\r\n * Stop the agent where it is along its trip. \r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.pauseTrip = function () {\n this.trip.paused = true;\n};\n/**\r\n * Have the agent continue from where it was left off along its trip. \r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.resumeTrip = function () {\n this.trip.paused = false;\n};\n/**\r\n * Set the agent to travel to some point on the map.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} goal_point - The point to which the agent should travel.\r\n */\n\n\nAgent.travelTo = function (goal_point) {\n this.trip.current_point = this.getLatLng(), this.trip.goal_point = goal_point, //Negating so that neg result corresponds to the goal being rightward/above, pos result to it being leftward/below.\n this.trip.lat_dir = Math.sign(-(this.trip.current_point.lat - this.trip.goal_point.lat)), this.trip.lng_dir = Math.sign(-(this.trip.current_point.lng - this.trip.goal_point.lng)), this.trip.angle = bearing(L.A.pointToCoordinateArray(this.trip.current_point), L.A.pointToCoordinateArray(this.trip.goal_point));\n this.trip.slope = Math.abs((this.trip.current_point.lat - this.trip.goal_point.lat) / (this.trip.current_point.lng - this.trip.goal_point.lng));\n this.trip.speed = this.trip.goal_point.speed; //If the agent won\'t be at any particular place at least until it reaches its next goal, mark its place as unanchored.\n\n if (this.trip.path[0].new_place.type === "unanchored" || this.trip.path[0].move_directly === true) {\n this.place = {\n type: "unanchored"\n };\n }\n};\n/**\r\n * Given the agent\'s currently scheduledthis.trips (its path), get the place from which a newthis.trip should start (namely, the end of the current path).\r\n * That is: If there\'s already a path in queue, start the new path from the end of the existing one.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @returns {Place} - The place where a newthis.trip should start.\r\n */\n\n\nAgent.newTripStartPlace = function () {\n if (this.trip.path.length === 0) {\n start_place = this.place;\n } else {\n start_place = this.trip.path[this.trip.path.length - 1].new_place;\n }\n\n return start_place;\n};\n/**\r\n * Schedule the agent to travel to a point within the unit he is in.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} goal_lat_lng - LatLng coordinate object for a point in the same unit the agent is in.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\n\nAgent.setTravelInUnit = function (goal_lat_lng, goal_place, speed) {\n goal_lat_lng.new_place = goal_place, goal_lat_lng.speed = speed;\n this.trip.path.push(goal_lat_lng);\n};\n/**\r\n * Schedule the agent to travel directly from any point (e.g. of a street or unit) to a point (e.g. of another street or unit).\r\n * @name scheduleTrip\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {LatLng} goal_lat_lng - The point within the place to which the agent is to travel.\r\n * @param {Place} goal_place - The place to which the agent will travel.\r\n * @param {number} [speed=1] - The speed in meters per tick that the agent should try to travel. Must be >= .1.\r\n * @param {Boolean} [move_directly=false] - Whether to ignore the streets & roads and move directly to the goal.\r\n * @param {Boolean} [replace_trip=false] - Whether to empty the currently scheduled path and replace it with this new trip; false by default (the new trip is\r\n * simply appended to the current scheduled path).\r\n */\n\n\nAgent.setTravelToPlace = function (goal_lat_lng, goal_place) {\n var speed = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : 1;\n var move_directly = arguments.length > 3 && arguments[3] !== undefined ? arguments[3] : false;\n var replace_trip = arguments.length > 4 && arguments[4] !== undefined ? arguments[4] : false;\n this.checkSpeed(speed);\n var start_place = this.newTripStartPlace();\n goal_lat_lng = L.latLng(goal_lat_lng);\n\n if (replace_trip === true) {\n start_place = this.place;\n this.resetTrip();\n } //If either the agent is already unanchored or its goal is unanchored, just schedule it to move directly to its goal.\n\n\n if (start_place.type === "unanchored" || goal_place.type === "unanchored" || move_directly === true) {\n var goal = goal_lat_lng;\n goal.new_place = goal_place, goal.move_directly = true, goal.speed = speed;\n this.trip.path.push(goal);\n return;\n }\n\n var goal_layer = this.agentmap.units.getLayer(goal_place.id) || this.agentmap.streets.getLayer(goal_place.id); //If the goal isn\'t unanchored, see if it\'s a street or a unit and schedule the agent appropriately.\n\n if (goal_layer) {\n var goal_coords = L.A.pointToCoordinateArray(goal_lat_lng); //Buffering so that points on the perimeter, like the door, are captured. \n //Also expands street lines into thin polygons (booleanPointInPolygon requires polys).\n //Might be more efficient to generate the door so that it\'s slightly inside the area.\n\n var goal_polygon = buffer(goal_layer.toGeoJSON(), .001);\n\n if (booleanPointInPolygon(goal_coords, goal_polygon)) {\n if (start_place.type === "unit" && goal_place.type === "unit" && start_place.id === goal_place.id) {\n this.setTravelInUnit(goal_lat_lng, goal_place, speed);\n return;\n } //Move to the street if it\'s starting at a unit and its goal is elsewhere.\n else if (start_place.type === "unit") {\n var start_unit_door = this.agentmap.getUnitDoor(start_place.id);\n start_unit_door.new_place = start_place, start_unit_door.speed = speed;\n this.trip.path.push(start_unit_door);\n var start_unit_street_id = this.agentmap.units.getLayer(start_place.id).street_id,\n start_unit_street_point = this.agentmap.getStreetNearDoor(start_place.id);\n start_unit_street_point.new_place = {\n type: "street",\n id: start_unit_street_id\n }, start_unit_street_point.speed = speed;\n this.trip.path.push(start_unit_street_point);\n }\n\n if (goal_place.type === "unit") {\n var goal_street_point = this.agentmap.getStreetNearDoor(goal_place.id),\n goal_street_point_place = {\n type: "street",\n id: this.agentmap.units.getLayer(goal_place.id).street_id\n }; //Move to the point on the street closest to the goal unit...\n\n this.setTravelAlongStreet(goal_street_point, goal_street_point_place, speed); //Move from that point into the unit.\n\n var goal_door = this.agentmap.getUnitDoor(goal_place.id);\n goal_door.new_place = goal_place, goal_door.speed = speed;\n this.trip.path.push(goal_door);\n this.setTravelInUnit(goal_lat_lng, goal_place, speed);\n } else if (goal_place.street === "number") {\n this.setTravelAlongStreet(goal_lat_lng, goal_place, speed);\n }\n } else {\n throw new Error("The goal_lat_lng is not inside of the polygon of the goal_place!");\n }\n } else {\n throw new Error("No place exists matching the specified goal_place!");\n }\n};\n\nAgent.scheduleTrip = Agent.setTravelToPlace;\n/**\r\n * Schedule the agent to travel to a point along the streets, via streets.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} goal_lat_lng - The coordinates of a point on a street to which the agent should travel.\r\n * @param {Place} goal_place - The place to which the agent will travel. Must be a street.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\nAgent.setTravelAlongStreet = function (goal_lat_lng, goal_place, speed) {\n var goal_coords,\n goal_street_id,\n goal_street_point,\n goal_street_feature,\n start_place = this.newTripStartPlace(),\n start_street_id,\n start_street_point,\n start_street_feature;\n\n if (start_place.type === "street" && goal_place.type === "street") {\n start_street_id = start_place.id, start_street_point = this.trip.path.length !== 0 ? this.trip.path[this.trip.path.length - 1] : this.getLatLng();\n start_street_point.new_place = {\n type: "street",\n id: start_street_id\n };\n goal_street_id = goal_place.id, goal_street_feature = this.agentmap.streets.getLayer(goal_street_id).feature, goal_coords = L.A.pointToCoordinateArray(goal_lat_lng), goal_street_point = L.latLng(nearestPointOnLine(goal_street_feature, goal_coords).geometry.coordinates.reverse());\n goal_street_point.new_place = goal_place;\n } else {\n throw new Error("Both the start and end places must be streets!");\n }\n\n if (start_street_id === goal_street_id) {\n this.setTravelOnSameStreet(start_street_point, goal_street_point, goal_street_feature, goal_street_id, speed);\n } //If the start and end points are on different streets, move from the start to its nearest intersection, then from there\n //to the intersection nearest to the end, and finally to the end.\n else {\n var start_nearest_intersection = this.agentmap.getNearestIntersection(start_street_point, start_place),\n goal_nearest_intersection = this.agentmap.getNearestIntersection(goal_street_point, goal_place);\n start_street_feature = this.agentmap.streets.getLayer(start_street_id).feature;\n this.setTravelOnStreetNetwork(start_street_point, goal_street_point, start_nearest_intersection, goal_nearest_intersection, speed);\n }\n};\n/**\r\n * Schedule the agent to travel between two points on the same street.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param start_lat_lng {LatLng} - The coordinates of the point on the street from which the agent will be traveling.\r\n * @param goal_lat_lng {LatLng} - The coordinates of the point on the street to which the agent should travel.\r\n * @param street_feature {Feature} - A GeoJSON object representing an OpenStreetMap street.\r\n * @param street_id {number} - The ID of the street in the streets layerGroup.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\n\nAgent.setTravelOnSameStreet = function (start_lat_lng, goal_lat_lng, street_feature, street_id, speed) {\n var _this$trip$path;\n\n //lineSlice, regardless of the specified starting point, will give a segment with the same coordinate order \n //as the original lineString array. So, if the goal point comes earlier in the array (e.g. it\'s on the far left),\n //it\'ll end up being the first point in the path, instead of the last, and the agent will move to it directly,\n //ignoring the street points that should come before it. It would then travel along the street from the goal point \n //to its original point (backwards).\n //To fix this, I\'m reversing the order of the coordinates in the segment if the last point in the line is closer\n //to the agent\'s starting point than the first point on the line (implying the last point in the array is the starting \n //point, not the goal). \n var start_coords = L.A.pointToCoordinateArray(start_lat_lng),\n goal_coords = L.A.pointToCoordinateArray(goal_lat_lng),\n street_path_unordered = L.A.reversedCoordinates(lineSlice(start_coords, goal_coords, street_feature).geometry.coordinates);\n var start_to_path_beginning = start_lat_lng.distanceTo(L.latLng(street_path_unordered[0])),\n start_to_path_end = start_lat_lng.distanceTo(L.latLng(street_path_unordered[street_path_unordered.length - 1]));\n var street_path = start_to_path_beginning < start_to_path_end ? street_path_unordered : street_path_unordered.reverse();\n var street_path_lat_lngs = street_path.map(function (coords) {\n var lat_lng = L.latLng(coords);\n lat_lng.new_place = {\n type: "street",\n id: street_id\n }, lat_lng.speed = speed;\n return lat_lng;\n });\n var first_lat = street_path_lat_lngs[0].lat,\n first_lng = street_path_lat_lngs[0].lng; //Exclude the last point if it\'s the same as the second to last point of this proposed segment,\n //and the second of it\'s the same as the first.\n //(since lineSlice adds a point for each other street in an intersection).\n\n if (street_path_lat_lngs.length > 1) {\n var second_lat = street_path_lat_lngs[1].lat,\n second_lng = street_path_lat_lngs[1].lng,\n final_lat = street_path_lat_lngs[street_path_lat_lngs.length - 1].lat,\n final_lng = street_path_lat_lngs[street_path_lat_lngs.length - 1].lng,\n penultimate_lat = street_path_lat_lngs[street_path_lat_lngs.length - 2].lat,\n penultimate_lng = street_path_lat_lngs[street_path_lat_lngs.length - 2].lng;\n\n if (first_lat === second_lat && first_lng === second_lng) {\n street_path_lat_lngs.shift();\n }\n\n if (final_lat === penultimate_lat && final_lng === penultimate_lng) {\n street_path_lat_lngs.pop();\n }\n } //Exclude the first point if it\'s already the last point of the already scheduled path.\n\n\n if (this.trip.path.length > 0) {\n var prev_lat = this.trip.path[this.trip.path.length - 1].lat,\n prev_lng = this.trip.path[this.trip.path.length - 1].lng;\n\n if (prev_lat === first_lat && prev_lng === first_lng) {\n street_path_lat_lngs.shift();\n }\n }\n\n (_this$trip$path = this.trip.path).push.apply(_this$trip$path, _toConsumableArray(street_path_lat_lngs));\n};\n/**\r\n * Schedule the agent up to travel between two points on a street network.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} start_lat_lng - The coordinates of the point on the street from which the agent will be traveling.\r\n * @param {LatLng} goal_lat_lng - The coordinates of the point on the street to which the agent should travel.\r\n * @param {LatLng} start_int_lat_lng - The coordinates of the nearest intersection on the same street at the start_lat_lng.\r\n * @param {LatLng} goal_int_lat_lng - The coordinates of the nearest intersection on the same street as the goal_lat_lng.\r\n * @param {number} speed - The speed that the agent should travel, in meters per tick.\r\n */\n\n\nAgent.setTravelOnStreetNetwork = function (start_lat_lng, goal_lat_lng, start_int_lat_lng, goal_int_lat_lng, speed) {\n var path = this.agentmap.getPath(start_int_lat_lng, goal_int_lat_lng, start_lat_lng, goal_lat_lng, true);\n\n for (var i = 0; i <= path.length - 2; i++) {\n var current_street_id = path[i].new_place.id,\n current_street_feature = this.agentmap.streets.getLayer(current_street_id).feature;\n this.setTravelOnSameStreet(path[i], path[i + 1], current_street_feature, current_street_id, speed);\n }\n};\n/**\r\n * Set a new, constant speed for the agent to move along its currently scheduled path.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} speed - The speed (in meters per tick) that the agent should move. Must be >= .1.\r\n */\n\n\nAgent.setSpeed = function (speed) {\n this.checkSpeed(speed);\n\n if (this.trip.goal_point !== null) {\n this.trip.speed = speed;\n }\n\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = this.trip.path[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var spot = _step.value;\n this.trip.speed = speed;\n spot.speed = speed;\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n};\n/**\r\n * Multiply the speed the agent moves along its currently scheduled path by a constant.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} multiplier - The number to multiply the agent\'s scheduled speed by. \r\n * All scheduled speeds must be >= .1.\r\n */\n\n\nAgent.multiplySpeed = function (multiplier) {\n if (this.trip.goal_point !== null) {\n this.trip.speed *= multiplier;\n this.checkSpeed(this.trip.speed);\n }\n\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = this.trip.path[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var spot = _step2.value;\n spot.speed *= multiplier;\n this.checkSpeed(spot.speed);\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n};\n/**\r\n * Increase the speed the agent moves along its currently scheduled path by a constant.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} magnitude - The number to add to the agent\'s scheduled speed.\r\n * All scheduled speeds must be >= .1\r\n */\n\n\nAgent.increaseSpeed = function (magnitude) {\n if (this.trip.goal_point !== null) {\n this.trip.speed += magnitude;\n this.checkSpeed(this.trip.speed);\n }\n\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = this.trip.path[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n var spot = _step3.value;\n spot.speed += magnitude;\n this.checkSpeed(spot.speed);\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return != null) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n};\n/**\r\n * Check whether a given speed is greater than the minimum.\r\n * @memberof Agent\r\n * @instance\r\n *\r\n * @param {number} speed - A number representing the speed of an agent in meters per second.\r\n */\n\n\nAgent.checkSpeed = function (speed) {\n if (speed < .1) {\n throw new Error("Cannot assign speed below .1 to agent!");\n }\n};\n/**\r\n * Continue to move the agent directly along the points in its path, at approximately the speed associated with each point in the path.\r\n * Since two points along the path may be far apart, the agent will make multiple intermediary movements too, splitting up its transfer\r\n * from its current point to its goal point into a sub-path with multiple sub-goals.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {number} override_speed - Have the agent step this distance, instead of the distance suggested by the current state\'s speed property.\r\n */\n\n\nAgent.travel = function (override_speed) {\n var current_coords = L.A.pointToCoordinateArray(this.trip.current_point),\n sub_goal_distance = override_speed || this.trip.speed,\n sub_goal_coords = destination(current_coords, sub_goal_distance * .001, this.trip.angle).geometry.coordinates,\n sub_goal_lat_lng = L.latLng(L.A.reversedCoordinates(sub_goal_coords));\n var segment_to_goal = lineString([this.trip.current_point, this.trip.goal_point].map(function (point) {\n return L.A.pointToCoordinateArray(point);\n })),\n segment_to_sub_goal = lineString([this.trip.current_point, sub_goal_lat_lng].map(function (point) {\n return L.A.pointToCoordinateArray(point);\n }));\n var goal_lat_dist = Math.abs(this.trip.current_point.lat - this.trip.goal_point.lat),\n goal_lng_dist = Math.abs(this.trip.current_point.lng - this.trip.goal_point.lng);\n var dist_to_goal = length(segment_to_goal) * 1000,\n dist_to_sub_goal = length(segment_to_sub_goal) * 1000,\n leftover_after_goal; //Check if the distance to the sub_goal is greater than the distance to the goal, and if so, make the sub_goal equal the goal\n //and change the number of meters to the sub_goal to the number of meters to the goal.\n\n if (dist_to_goal < dist_to_sub_goal) {\n sub_goal_lat_lng = this.trip.goal_point, sub_goal_distance = dist_to_goal, leftover_after_goal = dist_to_sub_goal - dist_to_goal;\n }\n\n if (this.checkArrival(sub_goal_lat_lng, leftover_after_goal)) {\n return;\n } //Lat/Lng distance between current point and sub_goal point.\n\n\n var sub_goal_lat_dist = Math.abs(sub_goal_lat_lng.lat - this.trip.current_point.lat),\n sub_goal_lng_dist = Math.abs(sub_goal_lat_lng.lng - this.trip.current_point.lng);\n var half_meters = sub_goal_distance * 2,\n int_half_meters = Math.floor(half_meters),\n int_lat_step_value = this.trip.lat_dir * (sub_goal_lat_dist / half_meters),\n int_lng_step_value = this.trip.lng_dir * (sub_goal_lng_dist / half_meters),\n final_lat_step_value = this.trip.lat_dir * (sub_goal_lat_dist - Math.abs(int_lat_step_value * int_half_meters)),\n final_lng_step_value = this.trip.lng_dir * (sub_goal_lng_dist - Math.abs(int_lng_step_value * int_half_meters)); //Intermediary movements.\n\n for (var i = 0; i < int_half_meters; ++i) {\n this.step(int_lat_step_value, int_lng_step_value); //If the agent is moving directly from a large distance, redirect it back towards the goal if it appears off course.\n\n if (this.trip.goal_point.move_directly === true) {\n var new_goal_lat_dist = Math.abs(this.trip.current_point.lat - this.trip.goal_point.lat),\n new_goal_lng_dist = Math.abs(this.trip.current_point.lng - this.trip.goal_point.lng);\n\n if (new_goal_lat_dist > goal_lat_dist || new_goal_lng_dist > goal_lng_dist) {\n this.travelTo(this.trip.goal_point);\n }\n }\n\n if (this.checkArrival(sub_goal_lat_lng, leftover_after_goal)) {\n return;\n }\n } //Last movement after intermediary movements.\n\n\n this.step(final_lat_step_value, final_lng_step_value, true);\n\n if (this.checkArrival(sub_goal_lat_lng, leftover_after_goal)) {\n return;\n }\n};\n/** \r\n * Move the agent a given latitude and longitude.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {number} lat_step_value - The number to add to the agent\'s latitude.\r\n * @param {number} lng_step_value - The number to add to the agent\'s longitude.\r\n */\n\n\nAgent.step = function (lat_step_value, lng_step_value) {\n var new_lat_lng = L.latLng([this.trip.current_point.lat + lat_step_value, this.trip.current_point.lng + lng_step_value]);\n this.trip.current_point = new_lat_lng, this.steps_made++; //Only redraw the Agent\'s position if the number of steps the agent has moved is a multiple of the agentmap.animation_interval.\n\n if (this.agentmap.animation_interval > 0 && this.steps_made % this.agentmap.animation_interval === 0) {\n this.setLatLng(new_lat_lng);\n } else {\n this._latlng = new_lat_lng;\n }\n};\n/**\r\n * Check if the agent has arrived at the next goal in its path or to a sub_goal along the way and perform appropriate arrival operations.\r\n * @memberof Agent\r\n * @instance\r\n * @private\r\n *\r\n * @param {LatLng} sub_goal_lat_lng - A sub_goal on the way to the goal (possibly the goal itself).\r\n * @param {number} leftover_after_goal - If the agent arrives at its goal during the tick, the number of meters, according to its speed,\r\n * leftover beyond the goal that it should still move during the tick.\r\n */\n\n\nAgent.checkArrival = function (sub_goal_lat_lng, leftover_after_goal) {\n if (this.trip.goal_point.distanceTo(this.trip.current_point) < .1) {\n this.place = this.trip.path[0].new_place;\n arrived = true;\n this.trip.path.shift();\n\n if (this.trip.path.length === 0) {\n this.resetTrip();\n } else {\n this.travelTo(this.trip.path[0]); //If it still needs to move a certain distance during this tick, move it that distance towards the next goal before returning.\n\n if (leftover_after_goal > 0) {\n this.travel(leftover_after_goal);\n }\n }\n\n this.trip.moving = false;\n return true;\n } else if (sub_goal_lat_lng.distanceTo(this.trip.current_point) < .1) {\n this.trip.moving = false;\n return true;\n }\n};\n/**\r\n * Make the agent proceed along its trip.\r\n * @memberof Agent\r\n * @instance\r\n */\n\n\nAgent.moveIt = function () {\n //Make sure the agent isn\'t paused or already moving.\n if (!this.trip.paused && !this.trip.moving) {\n //Call the agent\'s fine_controller before it begins moving.\n this.fine_controller(); //Check if the agent has a goal point, and if so travel towards it.\n\n if (this.trip.goal_point !== null) {\n this.trip.moving = true;\n this.travel();\n } //Otherwise, if there\'s a scheduled path that the agent hasn\'t started traveling on yet,\n //start traveling on it.\n else if (this.trip.path.length !== 0) {\n this.trip.moving = true;\n this.startTrip();\n this.travel();\n }\n }\n};\n\nAgent = L.CircleMarker.extend(Agent);\n/**\r\n * Returns an agent object.\r\n *\r\n * @param {LatLng} lat_lng - A pair of coordinates to locate the agent at.\r\n * @param {Object} options - An array of options for the agent, namely its layer.\r\n * @param {Agentmap} agentmap - The agentmap instance in which the agent exists.\r\n */\n\nfunction agent(lat_lng, options, agentmap) {\n return new Agent(lat_lng, options, agentmap);\n}\n/**\r\n * A user-defined callback function that returns a feature with appropriate geometry and properties to represent an agent.\r\n *\r\n * @callback agentFeatureMaker\r\n * @param {number} id - The agent\'s Leaflet layer ID.\r\n * @returns {Point} - A GeoJSON Point object with geometry and other properties for the agent, including\r\n * a "place" property that will set the agent\'s initial {@link Place} and a "layer_options" property\r\n * that will specify the feature\'s Leaflet options (like its color, size, etc.). All other provided properties \r\n * will be transferred to the Agent object once it is created.\r\n * See {@link https://leafletjs.com/reference-1.3.2.html#circlemarker} for all possible layer options.\r\n *\r\n * @example\r\n * let point = {\t\t\t\t\t\r\n * \t"type": "Feature",\t\t\t\t \r\n * \t"properties": {\t\t\t\t\t\r\n * \t\t"layer_options": {\t\t\t\r\n * \t\t\t"color": "red",\t\t\t\r\n * \t\t\t"radius": .5,\t\t\t\r\n * \t\t},\t\t\t\t\t\r\n * \t\t"place": {\t\t\t\t\r\n * \t\t\t"type": "unit",\t\t\t\r\n * \t\t\t"id": 89\t\t\t\r\n * \t\t},\t\t\t\t\t\r\n * \t\t\t\t\t\t\t\r\n * \t\tage: 72,\t\t\t\t\r\n * \t\thome_city: "LA"\t\t\t\t\r\n * \t},\t\t\t\t\t\t\r\n * \t"geometry" {\t\t\t\t\t\r\n * \t\t"type": "Point",\t\t\t\r\n * \t\t"coordinates": [\t\t\t\r\n * \t\t\t14.54589,\t\t\t\r\n * \t\t\t57.136239\t\t\t\r\n * \t\t]\t\t\t\t\t\r\n * \t}\t\t\t\t\t\t\r\n * }\t\t\t\t\t\t\t\r\n */\n\n/**\r\n * A standard {@link agentFeatureMaker}, which sets an agent\'s location to be the point near the center of the iᵗʰ unit of the map,\r\n * its place property to be that unit\'s, and its layer_options to be red and of radius .5 meters.\r\n * @memberof Agentmap\r\n * @instance\r\n * @type {agentFeatureMaker}\r\n */\n\n\nfunction seqUnitAgentMaker(id) {\n var index = this.agents.count();\n\n if (index > this.units.getLayers().length - 1) {\n throw new Error("seqUnitAgentMaker cannot accommodate more agents than there are units.");\n }\n\n var unit = this.units.getLayers()[index],\n unit_id = this.units.getLayerId(unit),\n center_point = centroid(unit.feature);\n center_point.properties.place = {\n "type": "unit",\n "id": unit_id\n }, center_point.properties.layer_options = {\n radius: .5,\n color: "red",\n fillColor: "red"\n };\n return center_point;\n}\n/**\r\n * Generate some number of agents and place them on the map.\r\n * @memberof Agentmap\r\n * @instance\r\n *\r\n * @param {number} count - The desired number of agents.\r\n * @param {agentFeatureMaker} agentFeatureMaker - A callback that determines an agent i\'s feature properties and geometry (always a Point).\r\n */\n\n\nfunction agentify(count, agentFeatureMaker) {\n var agentmap = this;\n\n if (!(this.agents instanceof L.LayerGroup)) {\n this.agents = L.featureGroup().addTo(this.map);\n }\n\n var agents_existing = agentmap.agents.getLayers().length;\n\n for (var i = agents_existing; i < agents_existing + count; i++) {\n var new_agent = agent(null, null, agentmap); //Callback function aren\'t automatically bound to the agentmap.\n\n var boundFeatureMaker = agentFeatureMaker.bind(agentmap),\n agent_feature = boundFeatureMaker(new_agent._leaflet_id);\n var coordinates = L.A.reversedCoordinates(agent_feature.geometry.coordinates),\n place = agent_feature.properties.place,\n layer_options = agent_feature.properties.layer_options; //Make sure the agent feature is valid and has everything we need.\n\n if (!L.A.isPointCoordinates(coordinates)) {\n throw new Error("Invalid feature returned from agentFeatureMaker: geometry.coordinates must be a 2-element array of numbers.");\n } else if (typeof place.id !== "number") {\n throw new Error("Invalid feature returned from agentFeatureMaker: properties.place must be a {unit: unit_id} or {street: street_id} with an existing layer\'s ID.");\n }\n\n new_agent.setLatLng(coordinates);\n new_agent.setStyle(layer_options);\n delete agent_feature.properties.layer_options;\n Object.assign(new_agent, agent_feature.properties);\n this.agents.addLayer(new_agent);\n }\n}\n\nAgentmap.prototype.agent = agent, Agentmap.prototype.agentify = agentify, Agentmap.prototype.seqUnitAgentMaker = seqUnitAgentMaker;\nexports.Agent = Agent, exports.agent = agent;\n\n//# sourceURL=webpack:///./src/agents.js?')},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nvar meta_1 = __webpack_require__(22);\nvar helpers_1 = __webpack_require__(1);\n/**\n * Takes one or more features and calculates the centroid using the mean of all vertices.\n * This lessens the effect of small islands and artifacts when calculating the centroid of a set of polygons.\n *\n * @name centroid\n * @param {GeoJSON} geojson GeoJSON to be centered\n * @param {Object} [options={}] Optional Parameters\n * @param {Object} [options.properties={}] an Object that is used as the {@link Feature}\'s properties\n * @returns {Feature} the centroid of the input features\n * @example\n * var polygon = turf.polygon([[[-81, 41], [-88, 36], [-84, 31], [-80, 33], [-77, 39], [-81, 41]]]);\n *\n * var centroid = turf.centroid(polygon);\n *\n * //addToMap\n * var addToMap = [polygon, centroid]\n */\nfunction centroid(geojson, options) {\n if (options === void 0) { options = {}; }\n var xSum = 0;\n var ySum = 0;\n var len = 0;\n meta_1.coordEach(geojson, function (coord) {\n xSum += coord[0];\n ySum += coord[1];\n len++;\n });\n return helpers_1.point([xSum / len, ySum / len], options.properties);\n}\nexports.default = centroid;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/centroid/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/centroid/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nvar invariant_1 = __webpack_require__(2);\n// http://en.wikipedia.org/wiki/Even%E2%80%93odd_rule\n// modified from: https://github.com/substack/point-in-polygon/blob/master/index.js\n// which was modified from http://www.ecse.rpi.edu/Homepages/wrf/Research/Short_Notes/pnpoly.html\n/**\n * Takes a {@link Point} and a {@link Polygon} or {@link MultiPolygon} and determines if the point\n * resides inside the polygon. The polygon can be convex or concave. The function accounts for holes.\n *\n * @name booleanPointInPolygon\n * @param {Coord} point input point\n * @param {Feature} polygon input polygon or multipolygon\n * @param {Object} [options={}] Optional parameters\n * @param {boolean} [options.ignoreBoundary=false] True if polygon boundary should be ignored when determining if\n * the point is inside the polygon otherwise false.\n * @returns {boolean} `true` if the Point is inside the Polygon; `false` if the Point is not inside the Polygon\n * @example\n * var pt = turf.point([-77, 44]);\n * var poly = turf.polygon([[\n * [-81, 41],\n * [-81, 47],\n * [-72, 47],\n * [-72, 41],\n * [-81, 41]\n * ]]);\n *\n * turf.booleanPointInPolygon(pt, poly);\n * //= true\n */\nfunction booleanPointInPolygon(point, polygon, options) {\n if (options === void 0) { options = {}; }\n // validation\n if (!point) {\n throw new Error("point is required");\n }\n if (!polygon) {\n throw new Error("polygon is required");\n }\n var pt = invariant_1.getCoord(point);\n var geom = invariant_1.getGeom(polygon);\n var type = geom.type;\n var bbox = polygon.bbox;\n var polys = geom.coordinates;\n // Quick elimination if point is not inside bbox\n if (bbox && inBBox(pt, bbox) === false) {\n return false;\n }\n // normalize to multipolygon\n if (type === "Polygon") {\n polys = [polys];\n }\n var insidePoly = false;\n for (var i = 0; i < polys.length && !insidePoly; i++) {\n // check if it is in the outer ring first\n if (inRing(pt, polys[i][0], options.ignoreBoundary)) {\n var inHole = false;\n var k = 1;\n // check for the point in any of the holes\n while (k < polys[i].length && !inHole) {\n if (inRing(pt, polys[i][k], !options.ignoreBoundary)) {\n inHole = true;\n }\n k++;\n }\n if (!inHole) {\n insidePoly = true;\n }\n }\n }\n return insidePoly;\n}\nexports.default = booleanPointInPolygon;\n/**\n * inRing\n *\n * @private\n * @param {Array} pt [x,y]\n * @param {Array>} ring [[x,y], [x,y],..]\n * @param {boolean} ignoreBoundary ignoreBoundary\n * @returns {boolean} inRing\n */\nfunction inRing(pt, ring, ignoreBoundary) {\n var isInside = false;\n if (ring[0][0] === ring[ring.length - 1][0] && ring[0][1] === ring[ring.length - 1][1]) {\n ring = ring.slice(0, ring.length - 1);\n }\n for (var i = 0, j = ring.length - 1; i < ring.length; j = i++) {\n var xi = ring[i][0];\n var yi = ring[i][1];\n var xj = ring[j][0];\n var yj = ring[j][1];\n var onBoundary = (pt[1] * (xi - xj) + yi * (xj - pt[0]) + yj * (pt[0] - xi) === 0) &&\n ((xi - pt[0]) * (xj - pt[0]) <= 0) && ((yi - pt[1]) * (yj - pt[1]) <= 0);\n if (onBoundary) {\n return !ignoreBoundary;\n }\n var intersect = ((yi > pt[1]) !== (yj > pt[1])) &&\n (pt[0] < (xj - xi) * (pt[1] - yi) / (yj - yi) + xi);\n if (intersect) {\n isInside = !isInside;\n }\n }\n return isInside;\n}\n/**\n * inBBox\n *\n * @private\n * @param {Position} pt point [x,y]\n * @param {BBox} bbox BBox [west, south, east, north]\n * @returns {boolean} true/false if point is inside BBox\n */\nfunction inBBox(pt, bbox) {\n return bbox[0] <= pt[0] &&\n bbox[1] <= pt[1] &&\n bbox[2] >= pt[0] &&\n bbox[3] >= pt[1];\n}\n\n\n//# sourceURL=webpack:///./node_modules/@turf/boolean-point-in-polygon/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\nObject.defineProperty(exports, \"__esModule\", { value: true });\nvar bearing_1 = __webpack_require__(5);\nvar distance_1 = __webpack_require__(9);\nvar destination_1 = __webpack_require__(6);\nvar line_intersect_1 = __webpack_require__(16);\nvar meta_1 = __webpack_require__(32);\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\n/**\n * Takes a {@link Point} and a {@link LineString} and calculates the closest Point on the (Multi)LineString.\n *\n * @name nearestPointOnLine\n * @param {Geometry|Feature} lines lines to snap to\n * @param {Geometry|Feature|number[]} pt point to snap from\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units='kilometers'] can be degrees, radians, miles, or kilometers\n * @returns {Feature} closest point on the `line` to `point`. The properties object will contain three values: `index`: closest point was found on nth line part, `dist`: distance between pt and the closest point, `location`: distance along the line between start and the closest point.\n * @example\n * var line = turf.lineString([\n * [-77.031669, 38.878605],\n * [-77.029609, 38.881946],\n * [-77.020339, 38.884084],\n * [-77.025661, 38.885821],\n * [-77.021884, 38.889563],\n * [-77.019824, 38.892368]\n * ]);\n * var pt = turf.point([-77.037076, 38.884017]);\n *\n * var snapped = turf.nearestPointOnLine(line, pt, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [line, pt, snapped];\n * snapped.properties['marker-color'] = '#00f';\n */\nfunction nearestPointOnLine(lines, pt, options) {\n if (options === void 0) { options = {}; }\n var closestPt = helpers_1.point([Infinity, Infinity], {\n dist: Infinity\n });\n var length = 0.0;\n meta_1.flattenEach(lines, function (line) {\n var coords = invariant_1.getCoords(line);\n for (var i = 0; i < coords.length - 1; i++) {\n //start\n var start = helpers_1.point(coords[i]);\n start.properties.dist = distance_1.default(pt, start, options);\n //stop\n var stop_1 = helpers_1.point(coords[i + 1]);\n stop_1.properties.dist = distance_1.default(pt, stop_1, options);\n // sectionLength\n var sectionLength = distance_1.default(start, stop_1, options);\n //perpendicular\n var heightDistance = Math.max(start.properties.dist, stop_1.properties.dist);\n var direction = bearing_1.default(start, stop_1);\n var perpendicularPt1 = destination_1.default(pt, heightDistance, direction + 90, options);\n var perpendicularPt2 = destination_1.default(pt, heightDistance, direction - 90, options);\n var intersect = line_intersect_1.default(helpers_1.lineString([perpendicularPt1.geometry.coordinates, perpendicularPt2.geometry.coordinates]), helpers_1.lineString([start.geometry.coordinates, stop_1.geometry.coordinates]));\n var intersectPt = null;\n if (intersect.features.length > 0) {\n intersectPt = intersect.features[0];\n intersectPt.properties.dist = distance_1.default(pt, intersectPt, options);\n intersectPt.properties.location = length + distance_1.default(start, intersectPt, options);\n }\n if (start.properties.dist < closestPt.properties.dist) {\n closestPt = start;\n closestPt.properties.index = i;\n closestPt.properties.location = length;\n }\n if (stop_1.properties.dist < closestPt.properties.dist) {\n closestPt = stop_1;\n closestPt.properties.index = i + 1;\n closestPt.properties.location = length + sectionLength;\n }\n if (intersectPt && intersectPt.properties.dist < closestPt.properties.dist) {\n closestPt = intersectPt;\n closestPt.properties.index = i;\n }\n // update length\n length += sectionLength;\n }\n });\n return closestPt;\n}\nexports.default = nearestPointOnLine;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/nearest-point-on-line/index.js?")},function(module,exports,__webpack_require__){"use strict";eval('\nObject.defineProperty(exports, "__esModule", { value: true });\nvar helpers_1 = __webpack_require__(1);\nvar invariant_1 = __webpack_require__(2);\nvar meta_1 = __webpack_require__(26);\n/**\n * Creates a {@link FeatureCollection} of 2-vertex {@link LineString} segments from a\n * {@link LineString|(Multi)LineString} or {@link Polygon|(Multi)Polygon}.\n *\n * @name lineSegment\n * @param {GeoJSON} geojson GeoJSON Polygon or LineString\n * @returns {FeatureCollection} 2-vertex line segments\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n * var segments = turf.lineSegment(polygon);\n *\n * //addToMap\n * var addToMap = [polygon, segments]\n */\nfunction lineSegment(geojson) {\n if (!geojson) {\n throw new Error("geojson is required");\n }\n var results = [];\n meta_1.flattenEach(geojson, function (feature) {\n lineSegmentFeature(feature, results);\n });\n return helpers_1.featureCollection(results);\n}\n/**\n * Line Segment\n *\n * @private\n * @param {Feature} geojson Line or polygon feature\n * @param {Array} results push to results\n * @returns {void}\n */\nfunction lineSegmentFeature(geojson, results) {\n var coords = [];\n var geometry = geojson.geometry;\n if (geometry !== null) {\n switch (geometry.type) {\n case "Polygon":\n coords = invariant_1.getCoords(geometry);\n break;\n case "LineString":\n coords = [invariant_1.getCoords(geometry)];\n }\n coords.forEach(function (coord) {\n var segments = createSegments(coord, geojson.properties);\n segments.forEach(function (segment) {\n segment.id = results.length;\n results.push(segment);\n });\n });\n }\n}\n/**\n * Create Segments from LineString coordinates\n *\n * @private\n * @param {Array>} coords LineString coordinates\n * @param {*} properties GeoJSON properties\n * @returns {Array>} line segments\n */\nfunction createSegments(coords, properties) {\n var segments = [];\n coords.reduce(function (previousCoords, currentCoords) {\n var segment = helpers_1.lineString([previousCoords, currentCoords], properties);\n segment.bbox = bbox(previousCoords, currentCoords);\n segments.push(segment);\n return currentCoords;\n });\n return segments;\n}\n/**\n * Create BBox between two coordinates (faster than @turf/bbox)\n *\n * @private\n * @param {Array} coords1 Point coordinate\n * @param {Array} coords2 Point coordinate\n * @returns {BBox} [west, south, east, north]\n */\nfunction bbox(coords1, coords2) {\n var x1 = coords1[0];\n var y1 = coords1[1];\n var x2 = coords2[0];\n var y2 = coords2[1];\n var west = (x1 < x2) ? x1 : x2;\n var south = (y1 < y2) ? y1 : y2;\n var east = (x1 > x2) ? x1 : x2;\n var north = (y1 > y2) ? y1 : y2;\n return [west, south, east, north];\n}\nexports.default = lineSegment;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-segment/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-segment/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/line-intersect/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){eval('var rbush = __webpack_require__(29);\nvar helpers = __webpack_require__(1);\nvar meta = __webpack_require__(31);\nvar turfBBox = __webpack_require__(3).default;\nvar featureEach = meta.featureEach;\nvar coordEach = meta.coordEach;\nvar polygon = helpers.polygon;\nvar featureCollection = helpers.featureCollection;\n\n/**\n * GeoJSON implementation of [RBush](https://github.com/mourner/rbush#rbush) spatial index.\n *\n * @name rbush\n * @param {number} [maxEntries=9] defines the maximum number of entries in a tree node. 9 (used by default) is a\n * reasonable choice for most applications. Higher value means faster insertion and slower search, and vice versa.\n * @returns {RBush} GeoJSON RBush\n * @example\n * var geojsonRbush = require(\'geojson-rbush\').default;\n * var tree = geojsonRbush();\n */\nfunction geojsonRbush(maxEntries) {\n var tree = rbush(maxEntries);\n /**\n * [insert](https://github.com/mourner/rbush#data-format)\n *\n * @param {Feature} feature insert single GeoJSON Feature\n * @returns {RBush} GeoJSON RBush\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n * tree.insert(poly)\n */\n tree.insert = function (feature) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid feature\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n return rbush.prototype.insert.call(this, feature);\n };\n\n /**\n * [load](https://github.com/mourner/rbush#bulk-inserting-data)\n *\n * @param {FeatureCollection|Array} features load entire GeoJSON FeatureCollection\n * @returns {RBush} GeoJSON RBush\n * @example\n * var polys = turf.polygons([\n * [[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]],\n * [[[-93, 32], [-83, 32], [-83, 39], [-93, 39], [-93, 32]]]\n * ]);\n * tree.load(polys);\n */\n tree.load = function (features) {\n var load = [];\n // Load an Array of Features\n if (Array.isArray(features)) {\n features.forEach(function (feature) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid features\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n load.push(feature);\n });\n } else {\n // Load a FeatureCollection\n featureEach(features, function (feature) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid features\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n load.push(feature);\n });\n }\n return rbush.prototype.load.call(this, load);\n };\n\n /**\n * [remove](https://github.com/mourner/rbush#removing-data)\n *\n * @param {Feature} feature remove single GeoJSON Feature\n * @param {Function} equals Pass a custom equals function to compare by value for removal.\n * @returns {RBush} GeoJSON RBush\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n *\n * tree.remove(poly);\n */\n tree.remove = function (feature, equals) {\n if (feature.type !== \'Feature\') throw new Error(\'invalid feature\');\n feature.bbox = feature.bbox ? feature.bbox : turfBBox(feature);\n return rbush.prototype.remove.call(this, feature, equals);\n };\n\n /**\n * [clear](https://github.com/mourner/rbush#removing-data)\n *\n * @returns {RBush} GeoJSON Rbush\n * @example\n * tree.clear()\n */\n tree.clear = function () {\n return rbush.prototype.clear.call(this);\n };\n\n /**\n * [search](https://github.com/mourner/rbush#search)\n *\n * @param {BBox|FeatureCollection|Feature} geojson search with GeoJSON\n * @returns {FeatureCollection} all features that intersects with the given GeoJSON.\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n *\n * tree.search(poly);\n */\n tree.search = function (geojson) {\n var features = rbush.prototype.search.call(this, this.toBBox(geojson));\n return featureCollection(features);\n };\n\n /**\n * [collides](https://github.com/mourner/rbush#collisions)\n *\n * @param {BBox|FeatureCollection|Feature} geojson collides with GeoJSON\n * @returns {boolean} true if there are any items intersecting the given GeoJSON, otherwise false.\n * @example\n * var poly = turf.polygon([[[-78, 41], [-67, 41], [-67, 48], [-78, 48], [-78, 41]]]);\n *\n * tree.collides(poly);\n */\n tree.collides = function (geojson) {\n return rbush.prototype.collides.call(this, this.toBBox(geojson));\n };\n\n /**\n * [all](https://github.com/mourner/rbush#search)\n *\n * @returns {FeatureCollection} all the features in RBush\n * @example\n * tree.all()\n */\n tree.all = function () {\n var features = rbush.prototype.all.call(this);\n return featureCollection(features);\n };\n\n /**\n * [toJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @returns {any} export data as JSON object\n * @example\n * var exported = tree.toJSON()\n */\n tree.toJSON = function () {\n return rbush.prototype.toJSON.call(this);\n };\n\n /**\n * [fromJSON](https://github.com/mourner/rbush#export-and-import)\n *\n * @param {any} json import previously exported data\n * @returns {RBush} GeoJSON RBush\n * @example\n * var exported = {\n * "children": [\n * {\n * "type": "Feature",\n * "geometry": {\n * "type": "Point",\n * "coordinates": [110, 50]\n * },\n * "properties": {},\n * "bbox": [110, 50, 110, 50]\n * }\n * ],\n * "height": 1,\n * "leaf": true,\n * "minX": 110,\n * "minY": 50,\n * "maxX": 110,\n * "maxY": 50\n * }\n * tree.fromJSON(exported)\n */\n tree.fromJSON = function (json) {\n return rbush.prototype.fromJSON.call(this, json);\n };\n\n /**\n * Converts GeoJSON to {minX, minY, maxX, maxY} schema\n *\n * @private\n * @param {BBox|FeatureCollection|Feature} geojson feature(s) to retrieve BBox from\n * @returns {Object} converted to {minX, minY, maxX, maxY}\n */\n tree.toBBox = function (geojson) {\n var bbox;\n if (geojson.bbox) bbox = geojson.bbox;\n else if (Array.isArray(geojson) && geojson.length === 4) bbox = geojson;\n else if (Array.isArray(geojson) && geojson.length === 6) bbox = [geojson[0], geojson[1], geojson[3], geojson[4]];\n else if (geojson.type === \'Feature\') bbox = turfBBox(geojson);\n else if (geojson.type === \'FeatureCollection\') bbox = turfBBox(geojson);\n else throw new Error(\'invalid geojson\')\n\n return {\n minX: bbox[0],\n minY: bbox[1],\n maxX: bbox[2],\n maxY: bbox[3]\n };\n };\n return tree;\n}\n\nmodule.exports = geojsonRbush;\nmodule.exports.default = geojsonRbush;\n\n\n//# sourceURL=webpack:///./node_modules/geojson-rbush/index.js?')},function(module,exports,__webpack_require__){"use strict";eval("\n\nmodule.exports = rbush;\nmodule.exports.default = rbush;\n\nvar quickselect = __webpack_require__(30);\n\nfunction rbush(maxEntries, format) {\n if (!(this instanceof rbush)) return new rbush(maxEntries, format);\n\n // max entries in a node is 9 by default; min node fill is 40% for best performance\n this._maxEntries = Math.max(4, maxEntries || 9);\n this._minEntries = Math.max(2, Math.ceil(this._maxEntries * 0.4));\n\n if (format) {\n this._initFormat(format);\n }\n\n this.clear();\n}\n\nrbush.prototype = {\n\n all: function () {\n return this._all(this.data, []);\n },\n\n search: function (bbox) {\n\n var node = this.data,\n result = [],\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return result;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf) result.push(child);\n else if (contains(bbox, childBBox)) this._all(child, result);\n else nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return result;\n },\n\n collides: function (bbox) {\n\n var node = this.data,\n toBBox = this.toBBox;\n\n if (!intersects(bbox, node)) return false;\n\n var nodesToSearch = [],\n i, len, child, childBBox;\n\n while (node) {\n for (i = 0, len = node.children.length; i < len; i++) {\n\n child = node.children[i];\n childBBox = node.leaf ? toBBox(child) : child;\n\n if (intersects(bbox, childBBox)) {\n if (node.leaf || contains(bbox, childBBox)) return true;\n nodesToSearch.push(child);\n }\n }\n node = nodesToSearch.pop();\n }\n\n return false;\n },\n\n load: function (data) {\n if (!(data && data.length)) return this;\n\n if (data.length < this._minEntries) {\n for (var i = 0, len = data.length; i < len; i++) {\n this.insert(data[i]);\n }\n return this;\n }\n\n // recursively build the tree with the given data from scratch using OMT algorithm\n var node = this._build(data.slice(), 0, data.length - 1, 0);\n\n if (!this.data.children.length) {\n // save as is if tree is empty\n this.data = node;\n\n } else if (this.data.height === node.height) {\n // split root if trees have the same height\n this._splitRoot(this.data, node);\n\n } else {\n if (this.data.height < node.height) {\n // swap trees if inserted one is bigger\n var tmpNode = this.data;\n this.data = node;\n node = tmpNode;\n }\n\n // insert the small tree into the large tree at appropriate level\n this._insert(node, this.data.height - node.height - 1, true);\n }\n\n return this;\n },\n\n insert: function (item) {\n if (item) this._insert(item, this.data.height - 1);\n return this;\n },\n\n clear: function () {\n this.data = createNode([]);\n return this;\n },\n\n remove: function (item, equalsFn) {\n if (!item) return this;\n\n var node = this.data,\n bbox = this.toBBox(item),\n path = [],\n indexes = [],\n i, parent, index, goingUp;\n\n // depth-first iterative tree traversal\n while (node || path.length) {\n\n if (!node) { // go up\n node = path.pop();\n parent = path[path.length - 1];\n i = indexes.pop();\n goingUp = true;\n }\n\n if (node.leaf) { // check current node\n index = findItem(item, node.children, equalsFn);\n\n if (index !== -1) {\n // item found, remove the item and condense tree upwards\n node.children.splice(index, 1);\n path.push(node);\n this._condense(path);\n return this;\n }\n }\n\n if (!goingUp && !node.leaf && contains(node, bbox)) { // go down\n path.push(node);\n indexes.push(i);\n i = 0;\n parent = node;\n node = node.children[0];\n\n } else if (parent) { // go right\n i++;\n node = parent.children[i];\n goingUp = false;\n\n } else node = null; // nothing found\n }\n\n return this;\n },\n\n toBBox: function (item) { return item; },\n\n compareMinX: compareNodeMinX,\n compareMinY: compareNodeMinY,\n\n toJSON: function () { return this.data; },\n\n fromJSON: function (data) {\n this.data = data;\n return this;\n },\n\n _all: function (node, result) {\n var nodesToSearch = [];\n while (node) {\n if (node.leaf) result.push.apply(result, node.children);\n else nodesToSearch.push.apply(nodesToSearch, node.children);\n\n node = nodesToSearch.pop();\n }\n return result;\n },\n\n _build: function (items, left, right, height) {\n\n var N = right - left + 1,\n M = this._maxEntries,\n node;\n\n if (N <= M) {\n // reached leaf level; return leaf\n node = createNode(items.slice(left, right + 1));\n calcBBox(node, this.toBBox);\n return node;\n }\n\n if (!height) {\n // target height of the bulk-loaded tree\n height = Math.ceil(Math.log(N) / Math.log(M));\n\n // target number of root entries to maximize storage utilization\n M = Math.ceil(N / Math.pow(M, height - 1));\n }\n\n node = createNode([]);\n node.leaf = false;\n node.height = height;\n\n // split the items into M mostly square tiles\n\n var N2 = Math.ceil(N / M),\n N1 = N2 * Math.ceil(Math.sqrt(M)),\n i, j, right2, right3;\n\n multiSelect(items, left, right, N1, this.compareMinX);\n\n for (i = left; i <= right; i += N1) {\n\n right2 = Math.min(i + N1 - 1, right);\n\n multiSelect(items, i, right2, N2, this.compareMinY);\n\n for (j = i; j <= right2; j += N2) {\n\n right3 = Math.min(j + N2 - 1, right2);\n\n // pack each entry recursively\n node.children.push(this._build(items, j, right3, height - 1));\n }\n }\n\n calcBBox(node, this.toBBox);\n\n return node;\n },\n\n _chooseSubtree: function (bbox, node, level, path) {\n\n var i, len, child, targetNode, area, enlargement, minArea, minEnlargement;\n\n while (true) {\n path.push(node);\n\n if (node.leaf || path.length - 1 === level) break;\n\n minArea = minEnlargement = Infinity;\n\n for (i = 0, len = node.children.length; i < len; i++) {\n child = node.children[i];\n area = bboxArea(child);\n enlargement = enlargedArea(bbox, child) - area;\n\n // choose entry with the least area enlargement\n if (enlargement < minEnlargement) {\n minEnlargement = enlargement;\n minArea = area < minArea ? area : minArea;\n targetNode = child;\n\n } else if (enlargement === minEnlargement) {\n // otherwise choose one with the smallest area\n if (area < minArea) {\n minArea = area;\n targetNode = child;\n }\n }\n }\n\n node = targetNode || node.children[0];\n }\n\n return node;\n },\n\n _insert: function (item, level, isNode) {\n\n var toBBox = this.toBBox,\n bbox = isNode ? item : toBBox(item),\n insertPath = [];\n\n // find the best node for accommodating the item, saving all nodes along the path too\n var node = this._chooseSubtree(bbox, this.data, level, insertPath);\n\n // put the item into the node\n node.children.push(item);\n extend(node, bbox);\n\n // split on node overflow; propagate upwards if necessary\n while (level >= 0) {\n if (insertPath[level].children.length > this._maxEntries) {\n this._split(insertPath, level);\n level--;\n } else break;\n }\n\n // adjust bboxes along the insertion path\n this._adjustParentBBoxes(bbox, insertPath, level);\n },\n\n // split overflowed node into two\n _split: function (insertPath, level) {\n\n var node = insertPath[level],\n M = node.children.length,\n m = this._minEntries;\n\n this._chooseSplitAxis(node, m, M);\n\n var splitIndex = this._chooseSplitIndex(node, m, M);\n\n var newNode = createNode(node.children.splice(splitIndex, node.children.length - splitIndex));\n newNode.height = node.height;\n newNode.leaf = node.leaf;\n\n calcBBox(node, this.toBBox);\n calcBBox(newNode, this.toBBox);\n\n if (level) insertPath[level - 1].children.push(newNode);\n else this._splitRoot(node, newNode);\n },\n\n _splitRoot: function (node, newNode) {\n // split root node\n this.data = createNode([node, newNode]);\n this.data.height = node.height + 1;\n this.data.leaf = false;\n calcBBox(this.data, this.toBBox);\n },\n\n _chooseSplitIndex: function (node, m, M) {\n\n var i, bbox1, bbox2, overlap, area, minOverlap, minArea, index;\n\n minOverlap = minArea = Infinity;\n\n for (i = m; i <= M - m; i++) {\n bbox1 = distBBox(node, 0, i, this.toBBox);\n bbox2 = distBBox(node, i, M, this.toBBox);\n\n overlap = intersectionArea(bbox1, bbox2);\n area = bboxArea(bbox1) + bboxArea(bbox2);\n\n // choose distribution with minimum overlap\n if (overlap < minOverlap) {\n minOverlap = overlap;\n index = i;\n\n minArea = area < minArea ? area : minArea;\n\n } else if (overlap === minOverlap) {\n // otherwise choose distribution with minimum area\n if (area < minArea) {\n minArea = area;\n index = i;\n }\n }\n }\n\n return index;\n },\n\n // sorts node children by the best axis for split\n _chooseSplitAxis: function (node, m, M) {\n\n var compareMinX = node.leaf ? this.compareMinX : compareNodeMinX,\n compareMinY = node.leaf ? this.compareMinY : compareNodeMinY,\n xMargin = this._allDistMargin(node, m, M, compareMinX),\n yMargin = this._allDistMargin(node, m, M, compareMinY);\n\n // if total distributions margin value is minimal for x, sort by minX,\n // otherwise it's already sorted by minY\n if (xMargin < yMargin) node.children.sort(compareMinX);\n },\n\n // total margin of all possible split distributions where each node is at least m full\n _allDistMargin: function (node, m, M, compare) {\n\n node.children.sort(compare);\n\n var toBBox = this.toBBox,\n leftBBox = distBBox(node, 0, m, toBBox),\n rightBBox = distBBox(node, M - m, M, toBBox),\n margin = bboxMargin(leftBBox) + bboxMargin(rightBBox),\n i, child;\n\n for (i = m; i < M - m; i++) {\n child = node.children[i];\n extend(leftBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(leftBBox);\n }\n\n for (i = M - m - 1; i >= m; i--) {\n child = node.children[i];\n extend(rightBBox, node.leaf ? toBBox(child) : child);\n margin += bboxMargin(rightBBox);\n }\n\n return margin;\n },\n\n _adjustParentBBoxes: function (bbox, path, level) {\n // adjust bboxes along the given tree path\n for (var i = level; i >= 0; i--) {\n extend(path[i], bbox);\n }\n },\n\n _condense: function (path) {\n // go through the path, removing empty nodes and updating bboxes\n for (var i = path.length - 1, siblings; i >= 0; i--) {\n if (path[i].children.length === 0) {\n if (i > 0) {\n siblings = path[i - 1].children;\n siblings.splice(siblings.indexOf(path[i]), 1);\n\n } else this.clear();\n\n } else calcBBox(path[i], this.toBBox);\n }\n },\n\n _initFormat: function (format) {\n // data format (minX, minY, maxX, maxY accessors)\n\n // uses eval-type function compilation instead of just accepting a toBBox function\n // because the algorithms are very sensitive to sorting functions performance,\n // so they should be dead simple and without inner calls\n\n var compareArr = ['return a', ' - b', ';'];\n\n this.compareMinX = new Function('a', 'b', compareArr.join(format[0]));\n this.compareMinY = new Function('a', 'b', compareArr.join(format[1]));\n\n this.toBBox = new Function('a',\n 'return {minX: a' + format[0] +\n ', minY: a' + format[1] +\n ', maxX: a' + format[2] +\n ', maxY: a' + format[3] + '};');\n }\n};\n\nfunction findItem(item, items, equalsFn) {\n if (!equalsFn) return items.indexOf(item);\n\n for (var i = 0; i < items.length; i++) {\n if (equalsFn(item, items[i])) return i;\n }\n return -1;\n}\n\n// calculate node's bbox from bboxes of its children\nfunction calcBBox(node, toBBox) {\n distBBox(node, 0, node.children.length, toBBox, node);\n}\n\n// min bounding rectangle of node children from k to p-1\nfunction distBBox(node, k, p, toBBox, destNode) {\n if (!destNode) destNode = createNode(null);\n destNode.minX = Infinity;\n destNode.minY = Infinity;\n destNode.maxX = -Infinity;\n destNode.maxY = -Infinity;\n\n for (var i = k, child; i < p; i++) {\n child = node.children[i];\n extend(destNode, node.leaf ? toBBox(child) : child);\n }\n\n return destNode;\n}\n\nfunction extend(a, b) {\n a.minX = Math.min(a.minX, b.minX);\n a.minY = Math.min(a.minY, b.minY);\n a.maxX = Math.max(a.maxX, b.maxX);\n a.maxY = Math.max(a.maxY, b.maxY);\n return a;\n}\n\nfunction compareNodeMinX(a, b) { return a.minX - b.minX; }\nfunction compareNodeMinY(a, b) { return a.minY - b.minY; }\n\nfunction bboxArea(a) { return (a.maxX - a.minX) * (a.maxY - a.minY); }\nfunction bboxMargin(a) { return (a.maxX - a.minX) + (a.maxY - a.minY); }\n\nfunction enlargedArea(a, b) {\n return (Math.max(b.maxX, a.maxX) - Math.min(b.minX, a.minX)) *\n (Math.max(b.maxY, a.maxY) - Math.min(b.minY, a.minY));\n}\n\nfunction intersectionArea(a, b) {\n var minX = Math.max(a.minX, b.minX),\n minY = Math.max(a.minY, b.minY),\n maxX = Math.min(a.maxX, b.maxX),\n maxY = Math.min(a.maxY, b.maxY);\n\n return Math.max(0, maxX - minX) *\n Math.max(0, maxY - minY);\n}\n\nfunction contains(a, b) {\n return a.minX <= b.minX &&\n a.minY <= b.minY &&\n b.maxX <= a.maxX &&\n b.maxY <= a.maxY;\n}\n\nfunction intersects(a, b) {\n return b.minX <= a.maxX &&\n b.minY <= a.maxY &&\n b.maxX >= a.minX &&\n b.maxY >= a.minY;\n}\n\nfunction createNode(children) {\n return {\n children: children,\n height: 1,\n leaf: true,\n minX: Infinity,\n minY: Infinity,\n maxX: -Infinity,\n maxY: -Infinity\n };\n}\n\n// sort an array so that items come in groups of n unsorted items, with groups sorted between each other;\n// combines selection algorithm with binary divide & conquer approach\n\nfunction multiSelect(arr, left, right, n, compare) {\n var stack = [left, right],\n mid;\n\n while (stack.length) {\n right = stack.pop();\n left = stack.pop();\n\n if (right - left <= n) continue;\n\n mid = left + Math.ceil((right - left) / n / 2) * n;\n quickselect(arr, mid, left, right, compare);\n\n stack.push(left, mid, mid, right);\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/rbush/index.js?")},function(module,exports,__webpack_require__){eval("(function (global, factory) {\n\t true ? module.exports = factory() :\n\tundefined;\n}(this, (function () { 'use strict';\n\nfunction quickselect(arr, k, left, right, compare) {\n quickselectStep(arr, k, left || 0, right || (arr.length - 1), compare || defaultCompare);\n}\n\nfunction quickselectStep(arr, k, left, right, compare) {\n\n while (right > left) {\n if (right - left > 600) {\n var n = right - left + 1;\n var m = k - left + 1;\n var z = Math.log(n);\n var s = 0.5 * Math.exp(2 * z / 3);\n var sd = 0.5 * Math.sqrt(z * s * (n - s) / n) * (m - n / 2 < 0 ? -1 : 1);\n var newLeft = Math.max(left, Math.floor(k - m * s / n + sd));\n var newRight = Math.min(right, Math.floor(k + (n - m) * s / n + sd));\n quickselectStep(arr, k, newLeft, newRight, compare);\n }\n\n var t = arr[k];\n var i = left;\n var j = right;\n\n swap(arr, left, k);\n if (compare(arr[right], t) > 0) swap(arr, left, right);\n\n while (i < j) {\n swap(arr, i, j);\n i++;\n j--;\n while (compare(arr[i], t) < 0) i++;\n while (compare(arr[j], t) > 0) j--;\n }\n\n if (compare(arr[left], t) === 0) swap(arr, left, j);\n else {\n j++;\n swap(arr, j, right);\n }\n\n if (j <= k) left = j + 1;\n if (k <= j) right = j - 1;\n }\n}\n\nfunction swap(arr, i, j) {\n var tmp = arr[i];\n arr[i] = arr[j];\n arr[j] = tmp;\n}\n\nfunction defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n}\n\nreturn quickselect;\n\n})));\n\n\n//# sourceURL=webpack:///./node_modules/quickselect/quickselect.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/geojson-rbush/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){"use strict";eval("\n\nObject.defineProperty(exports, '__esModule', { value: true });\n\nvar helpers = __webpack_require__(1);\n\n/**\n * Callback for coordEach\n *\n * @callback coordEachCallback\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Iterate over coordinates in any GeoJSON object, similar to Array.forEach()\n *\n * @name coordEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentCoord, coordIndex, featureIndex, multiFeatureIndex)\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordEach(features, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction coordEach(geojson, callback, excludeWrapCoord) {\n // Handles null Geometry -- Skips this GeoJSON\n if (geojson === null) return;\n var j, k, l, geometry, stopG, coords,\n geometryMaybeCollection,\n wrapShrink = 0,\n coordIndex = 0,\n isGeometryCollection,\n type = geojson.type,\n isFeatureCollection = type === 'FeatureCollection',\n isFeature = type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (var featureIndex = 0; featureIndex < stop; featureIndex++) {\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[featureIndex].geometry :\n (isFeature ? geojson.geometry : geojson));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (var geomIndex = 0; geomIndex < stopG; geomIndex++) {\n var multiFeatureIndex = 0;\n var geometryIndex = 0;\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[geomIndex] : geometryMaybeCollection;\n\n // Handles null Geometry -- Skips this geometry\n if (geometry === null) continue;\n coords = geometry.coordinates;\n var geomType = geometry.type;\n\n wrapShrink = (excludeWrapCoord && (geomType === 'Polygon' || geomType === 'MultiPolygon')) ? 1 : 0;\n\n switch (geomType) {\n case null:\n break;\n case 'Point':\n if (callback(coords, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n multiFeatureIndex++;\n break;\n case 'LineString':\n case 'MultiPoint':\n for (j = 0; j < coords.length; j++) {\n if (callback(coords[j], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n if (geomType === 'MultiPoint') multiFeatureIndex++;\n }\n if (geomType === 'LineString') multiFeatureIndex++;\n break;\n case 'Polygon':\n case 'MultiLineString':\n for (j = 0; j < coords.length; j++) {\n for (k = 0; k < coords[j].length - wrapShrink; k++) {\n if (callback(coords[j][k], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n if (geomType === 'MultiLineString') multiFeatureIndex++;\n if (geomType === 'Polygon') geometryIndex++;\n }\n if (geomType === 'Polygon') multiFeatureIndex++;\n break;\n case 'MultiPolygon':\n for (j = 0; j < coords.length; j++) {\n geometryIndex = 0;\n for (k = 0; k < coords[j].length; k++) {\n for (l = 0; l < coords[j][k].length - wrapShrink; l++) {\n if (callback(coords[j][k][l], coordIndex, featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n coordIndex++;\n }\n geometryIndex++;\n }\n multiFeatureIndex++;\n }\n break;\n case 'GeometryCollection':\n for (j = 0; j < geometry.geometries.length; j++)\n if (coordEach(geometry.geometries[j], callback, excludeWrapCoord) === false) return false;\n break;\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n }\n}\n\n/**\n * Callback for coordReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback coordReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Array} currentCoord The current coordinate being processed.\n * @param {number} coordIndex The current index of the coordinate being processed.\n * Starts at index 0, if an initialValue is provided, and at index 1 otherwise.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n */\n\n/**\n * Reduce coordinates in any GeoJSON object, similar to Array.reduce()\n *\n * @name coordReduce\n * @param {FeatureCollection|Geometry|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentCoord, coordIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @param {boolean} [excludeWrapCoord=false] whether or not to include the final coordinate of LinearRings that wraps the ring in its iteration.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.coordReduce(features, function (previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentCoord\n * //=coordIndex\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentCoord;\n * });\n */\nfunction coordReduce(geojson, callback, initialValue, excludeWrapCoord) {\n var previousValue = initialValue;\n coordEach(geojson, function (currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex) {\n if (coordIndex === 0 && initialValue === undefined) previousValue = currentCoord;\n else previousValue = callback(previousValue, currentCoord, coordIndex, featureIndex, multiFeatureIndex, geometryIndex);\n }, excludeWrapCoord);\n return previousValue;\n}\n\n/**\n * Callback for propEach\n *\n * @callback propEachCallback\n * @param {Object} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over properties in any GeoJSON object, similar to Array.forEach()\n *\n * @name propEach\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentProperties, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propEach(features, function (currentProperties, featureIndex) {\n * //=currentProperties\n * //=featureIndex\n * });\n */\nfunction propEach(geojson, callback) {\n var i;\n switch (geojson.type) {\n case 'FeatureCollection':\n for (i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i].properties, i) === false) break;\n }\n break;\n case 'Feature':\n callback(geojson.properties, 0);\n break;\n }\n}\n\n\n/**\n * Callback for propReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback propReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {*} currentProperties The current Properties being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce properties in any GeoJSON object into a single value,\n * similar to how Array.reduce works. However, in this case we lazily run\n * the reduction, so an array of all properties is unnecessary.\n *\n * @name propReduce\n * @param {FeatureCollection|Feature} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentProperties, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.propReduce(features, function (previousValue, currentProperties, featureIndex) {\n * //=previousValue\n * //=currentProperties\n * //=featureIndex\n * return currentProperties\n * });\n */\nfunction propReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n propEach(geojson, function (currentProperties, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentProperties;\n else previousValue = callback(previousValue, currentProperties, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for featureEach\n *\n * @callback featureEachCallback\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Iterate over features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name featureEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.featureEach(features, function (currentFeature, featureIndex) {\n * //=currentFeature\n * //=featureIndex\n * });\n */\nfunction featureEach(geojson, callback) {\n if (geojson.type === 'Feature') {\n callback(geojson, 0);\n } else if (geojson.type === 'FeatureCollection') {\n for (var i = 0; i < geojson.features.length; i++) {\n if (callback(geojson.features[i], i) === false) break;\n }\n }\n}\n\n/**\n * Callback for featureReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback featureReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name featureReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {\"foo\": \"bar\"}),\n * turf.point([36, 53], {\"hello\": \"world\"})\n * ]);\n *\n * turf.featureReduce(features, function (previousValue, currentFeature, featureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * return currentFeature\n * });\n */\nfunction featureReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n featureEach(geojson, function (currentFeature, featureIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex);\n });\n return previousValue;\n}\n\n/**\n * Get all coordinates from any GeoJSON object.\n *\n * @name coordAll\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @returns {Array>} coordinate position array\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * var coords = turf.coordAll(features);\n * //= [[26, 37], [36, 53]]\n */\nfunction coordAll(geojson) {\n var coords = [];\n coordEach(geojson, function (coord) {\n coords.push(coord);\n });\n return coords;\n}\n\n/**\n * Callback for geomEach\n *\n * @callback geomEachCallback\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Iterate over each geometry in any GeoJSON object, similar to Array.forEach()\n *\n * @name geomEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @returns {void}\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomEach(features, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * });\n */\nfunction geomEach(geojson, callback) {\n var i, j, g, geometry, stopG,\n geometryMaybeCollection,\n isGeometryCollection,\n featureProperties,\n featureBBox,\n featureId,\n featureIndex = 0,\n isFeatureCollection = geojson.type === 'FeatureCollection',\n isFeature = geojson.type === 'Feature',\n stop = isFeatureCollection ? geojson.features.length : 1;\n\n // This logic may look a little weird. The reason why it is that way\n // is because it's trying to be fast. GeoJSON supports multiple kinds\n // of objects at its root: FeatureCollection, Features, Geometries.\n // This function has the responsibility of handling all of them, and that\n // means that some of the `for` loops you see below actually just don't apply\n // to certain inputs. For instance, if you give this just a\n // Point geometry, then both loops are short-circuited and all we do\n // is gradually rename the input until it's called 'geometry'.\n //\n // This also aims to allocate as few resources as possible: just a\n // few numbers and booleans, rather than any temporary arrays as would\n // be required with the normalization approach.\n for (i = 0; i < stop; i++) {\n\n geometryMaybeCollection = (isFeatureCollection ? geojson.features[i].geometry :\n (isFeature ? geojson.geometry : geojson));\n featureProperties = (isFeatureCollection ? geojson.features[i].properties :\n (isFeature ? geojson.properties : {}));\n featureBBox = (isFeatureCollection ? geojson.features[i].bbox :\n (isFeature ? geojson.bbox : undefined));\n featureId = (isFeatureCollection ? geojson.features[i].id :\n (isFeature ? geojson.id : undefined));\n isGeometryCollection = (geometryMaybeCollection) ? geometryMaybeCollection.type === 'GeometryCollection' : false;\n stopG = isGeometryCollection ? geometryMaybeCollection.geometries.length : 1;\n\n for (g = 0; g < stopG; g++) {\n geometry = isGeometryCollection ?\n geometryMaybeCollection.geometries[g] : geometryMaybeCollection;\n\n // Handle null Geometry\n if (geometry === null) {\n if (callback(null, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n continue;\n }\n switch (geometry.type) {\n case 'Point':\n case 'LineString':\n case 'MultiPoint':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon': {\n if (callback(geometry, featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n break;\n }\n case 'GeometryCollection': {\n for (j = 0; j < geometry.geometries.length; j++) {\n if (callback(geometry.geometries[j], featureIndex, featureProperties, featureBBox, featureId) === false) return false;\n }\n break;\n }\n default:\n throw new Error('Unknown Geometry Type');\n }\n }\n // Only increase `featureIndex` per each feature\n featureIndex++;\n }\n}\n\n/**\n * Callback for geomReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback geomReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Geometry} currentGeometry The current Geometry being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {Object} featureProperties The current Feature Properties being processed.\n * @param {Array} featureBBox The current Feature BBox being processed.\n * @param {number|string} featureId The current Feature Id being processed.\n */\n\n/**\n * Reduce geometry in any GeoJSON object, similar to Array.reduce().\n *\n * @name geomReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.point([36, 53], {hello: 'world'})\n * ]);\n *\n * turf.geomReduce(features, function (previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n * //=previousValue\n * //=currentGeometry\n * //=featureIndex\n * //=featureProperties\n * //=featureBBox\n * //=featureId\n * return currentGeometry\n * });\n */\nfunction geomReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n geomEach(geojson, function (currentGeometry, featureIndex, featureProperties, featureBBox, featureId) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentGeometry;\n else previousValue = callback(previousValue, currentGeometry, featureIndex, featureProperties, featureBBox, featureId);\n });\n return previousValue;\n}\n\n/**\n * Callback for flattenEach\n *\n * @callback flattenEachCallback\n * @param {Feature} currentFeature The current flattened feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Iterate over flattened features in any GeoJSON object, similar to\n * Array.forEach.\n *\n * @name flattenEach\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (currentFeature, featureIndex, multiFeatureIndex)\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenEach(features, function (currentFeature, featureIndex, multiFeatureIndex) {\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * });\n */\nfunction flattenEach(geojson, callback) {\n geomEach(geojson, function (geometry, featureIndex, properties, bbox, id) {\n // Callback for single geometry\n var type = (geometry === null) ? null : geometry.type;\n switch (type) {\n case null:\n case 'Point':\n case 'LineString':\n case 'Polygon':\n if (callback(helpers.feature(geometry, properties, {bbox: bbox, id: id}), featureIndex, 0) === false) return false;\n return;\n }\n\n var geomType;\n\n // Callback for multi-geometry\n switch (type) {\n case 'MultiPoint':\n geomType = 'Point';\n break;\n case 'MultiLineString':\n geomType = 'LineString';\n break;\n case 'MultiPolygon':\n geomType = 'Polygon';\n break;\n }\n\n for (var multiFeatureIndex = 0; multiFeatureIndex < geometry.coordinates.length; multiFeatureIndex++) {\n var coordinate = geometry.coordinates[multiFeatureIndex];\n var geom = {\n type: geomType,\n coordinates: coordinate\n };\n if (callback(helpers.feature(geom, properties), featureIndex, multiFeatureIndex) === false) return false;\n }\n });\n}\n\n/**\n * Callback for flattenReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback flattenReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentFeature The current Feature being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n */\n\n/**\n * Reduce flattened features in any GeoJSON object, similar to Array.reduce().\n *\n * @name flattenReduce\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON object\n * @param {Function} callback a method that takes (previousValue, currentFeature, featureIndex, multiFeatureIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var features = turf.featureCollection([\n * turf.point([26, 37], {foo: 'bar'}),\n * turf.multiPoint([[40, 30], [36, 53]], {hello: 'world'})\n * ]);\n *\n * turf.flattenReduce(features, function (previousValue, currentFeature, featureIndex, multiFeatureIndex) {\n * //=previousValue\n * //=currentFeature\n * //=featureIndex\n * //=multiFeatureIndex\n * return currentFeature\n * });\n */\nfunction flattenReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n flattenEach(geojson, function (currentFeature, featureIndex, multiFeatureIndex) {\n if (featureIndex === 0 && multiFeatureIndex === 0 && initialValue === undefined) previousValue = currentFeature;\n else previousValue = callback(previousValue, currentFeature, featureIndex, multiFeatureIndex);\n });\n return previousValue;\n}\n\n/**\n * Callback for segmentEach\n *\n * @callback segmentEachCallback\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n * @returns {void}\n */\n\n/**\n * Iterate over 2-vertex line segment in any GeoJSON object, similar to Array.forEach()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex)\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentEach(polygon, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //=currentSegment\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * //=segmentIndex\n * });\n *\n * // Calculate the total number of segments\n * var total = 0;\n * turf.segmentEach(polygon, function () {\n * total++;\n * });\n */\nfunction segmentEach(geojson, callback) {\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n var segmentIndex = 0;\n\n // Exclude null Geometries\n if (!feature.geometry) return;\n // (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n var type = feature.geometry.type;\n if (type === 'Point' || type === 'MultiPoint') return;\n\n // Generate 2-vertex line segments\n var previousCoords;\n var previousFeatureIndex = 0;\n var previousMultiIndex = 0;\n var prevGeomIndex = 0;\n if (coordEach(feature, function (currentCoord, coordIndex, featureIndexCoord, multiPartIndexCoord, geometryIndex) {\n // Simulating a meta.coordReduce() since `reduce` operations cannot be stopped by returning `false`\n if (previousCoords === undefined || featureIndex > previousFeatureIndex || multiPartIndexCoord > previousMultiIndex || geometryIndex > prevGeomIndex) {\n previousCoords = currentCoord;\n previousFeatureIndex = featureIndex;\n previousMultiIndex = multiPartIndexCoord;\n prevGeomIndex = geometryIndex;\n segmentIndex = 0;\n return;\n }\n var currentSegment = helpers.lineString([previousCoords, currentCoord], feature.properties);\n if (callback(currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) === false) return false;\n segmentIndex++;\n previousCoords = currentCoord;\n }) === false) return false;\n });\n}\n\n/**\n * Callback for segmentReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback segmentReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentSegment The current Segment being processed.\n * @param {number} featureIndex The current index of the Feature being processed.\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed.\n * @param {number} geometryIndex The current index of the Geometry being processed.\n * @param {number} segmentIndex The current index of the Segment being processed.\n */\n\n/**\n * Reduce 2-vertex line segment in any GeoJSON object, similar to Array.reduce()\n * (Multi)Point geometries do not contain segments therefore they are ignored during this operation.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson any GeoJSON\n * @param {Function} callback a method that takes (previousValue, currentSegment, currentIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {void}\n * @example\n * var polygon = turf.polygon([[[-50, 5], [-40, -10], [-50, -10], [-40, 5], [-50, 5]]]);\n *\n * // Iterate over GeoJSON by 2-vertex segments\n * turf.segmentReduce(polygon, function (previousSegment, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n * //= previousSegment\n * //= currentSegment\n * //= featureIndex\n * //= multiFeatureIndex\n * //= geometryIndex\n * //= segmentInex\n * return currentSegment\n * });\n *\n * // Calculate the total number of segments\n * var initialValue = 0\n * var total = turf.segmentReduce(polygon, function (previousValue) {\n * previousValue++;\n * return previousValue;\n * }, initialValue);\n */\nfunction segmentReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n var started = false;\n segmentEach(geojson, function (currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex) {\n if (started === false && initialValue === undefined) previousValue = currentSegment;\n else previousValue = callback(previousValue, currentSegment, featureIndex, multiFeatureIndex, geometryIndex, segmentIndex);\n started = true;\n });\n return previousValue;\n}\n\n/**\n * Callback for lineEach\n *\n * @callback lineEachCallback\n * @param {Feature} currentLine The current LineString|LinearRing being processed\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Iterate over line or ring coordinates in LineString, Polygon, MultiLineString, MultiPolygon Features or Geometries,\n * similar to Array.forEach.\n *\n * @name lineEach\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @example\n * var multiLine = turf.multiLineString([\n * [[26, 37], [35, 45]],\n * [[36, 53], [38, 50], [41, 55]]\n * ]);\n *\n * turf.lineEach(multiLine, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * });\n */\nfunction lineEach(geojson, callback) {\n // validation\n if (!geojson) throw new Error('geojson is required');\n\n flattenEach(geojson, function (feature, featureIndex, multiFeatureIndex) {\n if (feature.geometry === null) return;\n var type = feature.geometry.type;\n var coords = feature.geometry.coordinates;\n switch (type) {\n case 'LineString':\n if (callback(feature, featureIndex, multiFeatureIndex, 0, 0) === false) return false;\n break;\n case 'Polygon':\n for (var geometryIndex = 0; geometryIndex < coords.length; geometryIndex++) {\n if (callback(helpers.lineString(coords[geometryIndex], feature.properties), featureIndex, multiFeatureIndex, geometryIndex) === false) return false;\n }\n break;\n }\n });\n}\n\n/**\n * Callback for lineReduce\n *\n * The first time the callback function is called, the values provided as arguments depend\n * on whether the reduce method has an initialValue argument.\n *\n * If an initialValue is provided to the reduce method:\n * - The previousValue argument is initialValue.\n * - The currentValue argument is the value of the first element present in the array.\n *\n * If an initialValue is not provided:\n * - The previousValue argument is the value of the first element present in the array.\n * - The currentValue argument is the value of the second element present in the array.\n *\n * @callback lineReduceCallback\n * @param {*} previousValue The accumulated value previously returned in the last invocation\n * of the callback, or initialValue, if supplied.\n * @param {Feature} currentLine The current LineString|LinearRing being processed.\n * @param {number} featureIndex The current index of the Feature being processed\n * @param {number} multiFeatureIndex The current index of the Multi-Feature being processed\n * @param {number} geometryIndex The current index of the Geometry being processed\n */\n\n/**\n * Reduce features in any GeoJSON object, similar to Array.reduce().\n *\n * @name lineReduce\n * @param {Geometry|Feature} geojson object\n * @param {Function} callback a method that takes (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex)\n * @param {*} [initialValue] Value to use as the first argument to the first call of the callback.\n * @returns {*} The value that results from the reduction.\n * @example\n * var multiPoly = turf.multiPolygon([\n * turf.polygon([[[12,48],[2,41],[24,38],[12,48]], [[9,44],[13,41],[13,45],[9,44]]]),\n * turf.polygon([[[5, 5], [0, 0], [2, 2], [4, 4], [5, 5]]])\n * ]);\n *\n * turf.lineReduce(multiPoly, function (previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n * //=previousValue\n * //=currentLine\n * //=featureIndex\n * //=multiFeatureIndex\n * //=geometryIndex\n * return currentLine\n * });\n */\nfunction lineReduce(geojson, callback, initialValue) {\n var previousValue = initialValue;\n lineEach(geojson, function (currentLine, featureIndex, multiFeatureIndex, geometryIndex) {\n if (featureIndex === 0 && initialValue === undefined) previousValue = currentLine;\n else previousValue = callback(previousValue, currentLine, featureIndex, multiFeatureIndex, geometryIndex);\n });\n return previousValue;\n}\n\n/**\n * Finds a particular 2-vertex LineString Segment from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n * Point & MultiPoint will always return null.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.segmentIndex=0] Segment Index\n * @param {Object} [options.properties={}] Translate Properties to output LineString\n * @param {BBox} [options.bbox={}] Translate BBox to output LineString\n * @param {number|string} [options.id={}] Translate Id to output LineString\n * @returns {Feature} 2-vertex GeoJSON Feature LineString\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findSegment(multiLine);\n * // => Feature>\n *\n * // First Segment of 2nd Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of Last Multi Feature\n * turf.findSegment(multiLine, {multiFeatureIndex: -1, segmentIndex: -1});\n * // => Feature>\n */\nfunction findSegment(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var segmentIndex = options.segmentIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find SegmentIndex\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n if (segmentIndex < 0) segmentIndex = coords.length + segmentIndex - 1;\n return helpers.lineString([coords[segmentIndex], coords[segmentIndex + 1]], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[geometryIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[geometryIndex][segmentIndex], coords[geometryIndex][segmentIndex + 1]], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex].length + segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][segmentIndex], coords[multiFeatureIndex][segmentIndex + 1]], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (segmentIndex < 0) segmentIndex = coords[multiFeatureIndex][geometryIndex].length - segmentIndex - 1;\n return helpers.lineString([coords[multiFeatureIndex][geometryIndex][segmentIndex], coords[multiFeatureIndex][geometryIndex][segmentIndex + 1]], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\n/**\n * Finds a particular Point from a GeoJSON using `@turf/meta` indexes.\n *\n * Negative indexes are permitted.\n *\n * @param {FeatureCollection|Feature|Geometry} geojson Any GeoJSON Feature or Geometry\n * @param {Object} [options={}] Optional parameters\n * @param {number} [options.featureIndex=0] Feature Index\n * @param {number} [options.multiFeatureIndex=0] Multi-Feature Index\n * @param {number} [options.geometryIndex=0] Geometry Index\n * @param {number} [options.coordIndex=0] Coord Index\n * @param {Object} [options.properties={}] Translate Properties to output Point\n * @param {BBox} [options.bbox={}] Translate BBox to output Point\n * @param {number|string} [options.id={}] Translate Id to output Point\n * @returns {Feature} 2-vertex GeoJSON Feature Point\n * @example\n * var multiLine = turf.multiLineString([\n * [[10, 10], [50, 30], [30, 40]],\n * [[-10, -10], [-50, -30], [-30, -40]]\n * ]);\n *\n * // First Segment (defaults are 0)\n * turf.findPoint(multiLine);\n * // => Feature>\n *\n * // First Segment of the 2nd Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: 1});\n * // => Feature>\n *\n * // Last Segment of last Multi-Feature\n * turf.findPoint(multiLine, {multiFeatureIndex: -1, coordIndex: -1});\n * // => Feature>\n */\nfunction findPoint(geojson, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers.isObject(options)) throw new Error('options is invalid');\n var featureIndex = options.featureIndex || 0;\n var multiFeatureIndex = options.multiFeatureIndex || 0;\n var geometryIndex = options.geometryIndex || 0;\n var coordIndex = options.coordIndex || 0;\n\n // Find FeatureIndex\n var properties = options.properties;\n var geometry;\n\n switch (geojson.type) {\n case 'FeatureCollection':\n if (featureIndex < 0) featureIndex = geojson.features.length + featureIndex;\n properties = properties || geojson.features[featureIndex].properties;\n geometry = geojson.features[featureIndex].geometry;\n break;\n case 'Feature':\n properties = properties || geojson.properties;\n geometry = geojson.geometry;\n break;\n case 'Point':\n case 'MultiPoint':\n return null;\n case 'LineString':\n case 'Polygon':\n case 'MultiLineString':\n case 'MultiPolygon':\n geometry = geojson;\n break;\n default:\n throw new Error('geojson is invalid');\n }\n\n // Find Coord Index\n if (geometry === null) return null;\n var coords = geometry.coordinates;\n switch (geometry.type) {\n case 'Point':\n return helpers.point(coords, properties, options);\n case 'MultiPoint':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n return helpers.point(coords[multiFeatureIndex], properties, options);\n case 'LineString':\n if (coordIndex < 0) coordIndex = coords.length + coordIndex;\n return helpers.point(coords[coordIndex], properties, options);\n case 'Polygon':\n if (geometryIndex < 0) geometryIndex = coords.length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[geometryIndex].length + coordIndex;\n return helpers.point(coords[geometryIndex][coordIndex], properties, options);\n case 'MultiLineString':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex].length + coordIndex;\n return helpers.point(coords[multiFeatureIndex][coordIndex], properties, options);\n case 'MultiPolygon':\n if (multiFeatureIndex < 0) multiFeatureIndex = coords.length + multiFeatureIndex;\n if (geometryIndex < 0) geometryIndex = coords[multiFeatureIndex].length + geometryIndex;\n if (coordIndex < 0) coordIndex = coords[multiFeatureIndex][geometryIndex].length - coordIndex;\n return helpers.point(coords[multiFeatureIndex][geometryIndex][coordIndex], properties, options);\n }\n throw new Error('geojson is invalid');\n}\n\nexports.coordEach = coordEach;\nexports.coordReduce = coordReduce;\nexports.propEach = propEach;\nexports.propReduce = propReduce;\nexports.featureEach = featureEach;\nexports.featureReduce = featureReduce;\nexports.coordAll = coordAll;\nexports.geomEach = geomEach;\nexports.geomReduce = geomReduce;\nexports.flattenEach = flattenEach;\nexports.flattenReduce = flattenReduce;\nexports.segmentEach = segmentEach;\nexports.segmentReduce = segmentReduce;\nexports.lineEach = lineEach;\nexports.lineReduce = lineReduce;\nexports.findSegment = findSegment;\nexports.findPoint = findPoint;\n\n\n//# sourceURL=webpack:///./node_modules/@turf/nearest-point-on-line/node_modules/@turf/meta/index.js?")},function(module,exports,__webpack_require__){eval("module.exports = {\n aStar: __webpack_require__(34),\n aGreedy: __webpack_require__(35),\n nba: __webpack_require__(36),\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/index.js?")},function(module,exports,__webpack_require__){eval("/**\n * Performs a uni-directional A Star search on graph.\n * \n * We will try to minimize f(n) = g(n) + h(n), where\n * g(n) is actual distance from source node to `n`, and\n * h(n) is heuristic distance from `n` to target node.\n */\nmodule.exports = aStarPathSearch;\n\nvar NodeHeap = __webpack_require__(11);\nvar makeSearchStatePool = __webpack_require__(17);\nvar heuristics = __webpack_require__(12);\nvar defaultSettings = __webpack_require__(13);\n\nvar NO_PATH = defaultSettings.NO_PATH;\n\nmodule.exports.l2 = heuristics.l2;\nmodule.exports.l1 = heuristics.l1;\n\n/**\n * Creates a new instance of pathfinder. A pathfinder has just one method:\n * `find(fromId, toId)`, it may be extended in future.\n * \n * @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph\n * @param {Object} options that configures search\n * @param {Function(a, b)} options.heuristic - a function that returns estimated distance between\n * nodes `a` and `b`. This function should never overestimate actual distance between two\n * nodes (otherwise the found path will not be the shortest). Defaults function returns 0,\n * which makes this search equivalent to Dijkstra search.\n * @param {Function(a, b)} options.distance - a function that returns actual distance between two\n * nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);\n * \n * @returns {Object} A pathfinder with single method `find()`.\n */\nfunction aStarPathSearch(graph, options) {\n options = options || {};\n // whether traversal should be considered over oriented graph.\n var oriented = options.oriented;\n\n var heuristic = options.heuristic;\n if (!heuristic) heuristic = defaultSettings.heuristic;\n\n var distance = options.distance;\n if (!distance) distance = defaultSettings.distance;\n var pool = makeSearchStatePool();\n\n return {\n /**\n * Finds a path between node `fromId` and `toId`.\n * @returns {Array} of nodes between `toId` and `fromId`. Empty array is returned\n * if no path is found.\n */\n find: find\n };\n\n function find(fromId, toId) {\n var from = graph.getNode(fromId);\n if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);\n var to = graph.getNode(toId);\n if (!to) throw new Error('toId is not defined in this graph: ' + toId);\n pool.reset();\n\n // Maps nodeId to NodeSearchState.\n var nodeState = new Map();\n\n // the nodes that we still need to evaluate\n var openSet = new NodeHeap({\n compare: defaultSettings.compareFScore,\n setNodeId: defaultSettings.setHeapIndex\n });\n\n var startNode = pool.createNewState(from);\n nodeState.set(fromId, startNode);\n\n // For the first node, fScore is completely heuristic.\n startNode.fScore = heuristic(from, to);\n\n // The cost of going from start to start is zero.\n startNode.distanceToSource = 0;\n openSet.push(startNode);\n startNode.open = 1;\n\n var cameFrom;\n\n while (openSet.length > 0) {\n cameFrom = openSet.pop();\n if (goalReached(cameFrom, to)) return reconstructPath(cameFrom);\n\n // no need to visit this node anymore\n cameFrom.closed = true;\n graph.forEachLinkedNode(cameFrom.node.id, visitNeighbour, oriented);\n }\n\n // If we got here, then there is no path.\n return NO_PATH;\n\n function visitNeighbour(otherNode, link) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) {\n // Already processed this node.\n return;\n }\n if (otherSearchState.open === 0) {\n // Remember this node.\n openSet.push(otherSearchState);\n otherSearchState.open = 1;\n }\n\n var tentativeDistance = cameFrom.distanceToSource + distance(otherNode, cameFrom.node, link);\n if (tentativeDistance >= otherSearchState.distanceToSource) {\n // This would only make our path longer. Ignore this route.\n return;\n }\n\n // bingo! we found shorter path:\n otherSearchState.parent = cameFrom;\n otherSearchState.distanceToSource = tentativeDistance;\n otherSearchState.fScore = tentativeDistance + heuristic(otherSearchState.node, to);\n\n openSet.updateItem(otherSearchState.heapIndex);\n }\n }\n}\n\nfunction goalReached(searchState, targetNode) {\n return searchState.node === targetNode;\n}\n\nfunction reconstructPath(searchState) {\n var path = [searchState.node];\n var parent = searchState.parent;\n\n while (parent) {\n path.push(parent.node);\n parent = parent.parent;\n }\n\n return path;\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/a-star.js?")},function(module,exports,__webpack_require__){eval("/**\n * Performs suboptimal, greed A Star path finding.\n * This finder does not necessary finds the shortest path. The path\n * that it finds is very close to the shortest one. It is very fast though.\n */\nmodule.exports = aStarBi;\n\nvar NodeHeap = __webpack_require__(11);\nvar makeSearchStatePool = __webpack_require__(17);\nvar heuristics = __webpack_require__(12);\nvar defaultSettings = __webpack_require__(13);\n\nvar BY_FROM = 1;\nvar BY_TO = 2;\nvar NO_PATH = defaultSettings.NO_PATH;\n\nmodule.exports.l2 = heuristics.l2;\nmodule.exports.l1 = heuristics.l1;\n\n/**\n * Creates a new instance of pathfinder. A pathfinder has just one method:\n * `find(fromId, toId)`, it may be extended in future.\n * \n * NOTE: Algorithm implemented in this code DOES NOT find optimal path.\n * Yet the path that it finds is always near optimal, and it finds it very fast.\n * \n * @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph\n * \n * @param {Object} options that configures search\n * @param {Function(a, b)} options.heuristic - a function that returns estimated distance between\n * nodes `a` and `b`. Defaults function returns 0, which makes this search equivalent to Dijkstra search.\n * @param {Function(a, b)} options.distance - a function that returns actual distance between two\n * nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);\n * \n * @returns {Object} A pathfinder with single method `find()`.\n */\nfunction aStarBi(graph, options) {\n options = options || {};\n // whether traversal should be considered over oriented graph.\n var oriented = options.oriented;\n\n var heuristic = options.heuristic;\n if (!heuristic) heuristic = defaultSettings.heuristic;\n\n var distance = options.distance;\n if (!distance) distance = defaultSettings.distance;\n var pool = makeSearchStatePool();\n\n return {\n find: find\n };\n\n function find(fromId, toId) {\n // Not sure if we should return NO_PATH or throw. Throw seem to be more\n // helpful to debug errors. So, throwing.\n var from = graph.getNode(fromId);\n if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);\n var to = graph.getNode(toId);\n if (!to) throw new Error('toId is not defined in this graph: ' + toId);\n\n if (from === to) return [from]; // trivial case.\n\n pool.reset();\n\n var callVisitor = oriented ? orientedVisitor : nonOrientedVisitor;\n\n // Maps nodeId to NodeSearchState.\n var nodeState = new Map();\n\n var openSetFrom = new NodeHeap({\n compare: defaultSettings.compareFScore,\n setNodeId: defaultSettings.setHeapIndex\n });\n\n var openSetTo = new NodeHeap({\n compare: defaultSettings.compareFScore,\n setNodeId: defaultSettings.setHeapIndex\n });\n\n\n var startNode = pool.createNewState(from);\n nodeState.set(fromId, startNode);\n\n // For the first node, fScore is completely heuristic.\n startNode.fScore = heuristic(from, to);\n // The cost of going from start to start is zero.\n startNode.distanceToSource = 0;\n openSetFrom.push(startNode);\n startNode.open = BY_FROM;\n\n var endNode = pool.createNewState(to);\n endNode.fScore = heuristic(to, from);\n endNode.distanceToSource = 0;\n openSetTo.push(endNode);\n endNode.open = BY_TO;\n\n // Cost of the best solution found so far. Used for accurate termination\n var lMin = Number.POSITIVE_INFINITY;\n var minFrom;\n var minTo;\n\n var currentSet = openSetFrom;\n var currentOpener = BY_FROM;\n\n while (openSetFrom.length > 0 && openSetTo.length > 0) {\n if (openSetFrom.length < openSetTo.length) {\n // we pick a set with less elements\n currentOpener = BY_FROM;\n currentSet = openSetFrom;\n } else {\n currentOpener = BY_TO;\n currentSet = openSetTo;\n }\n\n var current = currentSet.pop();\n\n // no need to visit this node anymore\n current.closed = true;\n\n if (current.distanceToSource > lMin) continue;\n\n graph.forEachLinkedNode(current.node.id, callVisitor);\n\n if (minFrom && minTo) {\n // This is not necessary the best path, but we are so greedy that we\n // can't resist:\n return reconstructBiDirectionalPath(minFrom, minTo);\n }\n }\n\n return NO_PATH; // No path.\n\n function nonOrientedVisitor(otherNode, link) {\n return visitNode(otherNode, link, current);\n }\n\n function orientedVisitor(otherNode, link) {\n // For oritned graphs we need to reverse graph, when traveling\n // backwards. So, we use non-oriented ngraph's traversal, and \n // filter link orientation here.\n if (currentOpener === BY_FROM) {\n if (link.fromId === current.node.id) return visitNode(otherNode, link, current)\n } else if (currentOpener === BY_TO) {\n if (link.toId === current.node.id) return visitNode(otherNode, link, current);\n }\n }\n\n function canExit(currentNode) {\n var opener = currentNode.open\n if (opener && opener !== currentOpener) {\n return true;\n }\n\n return false;\n }\n\n function reconstructBiDirectionalPath(a, b) {\n var pathOfNodes = [];\n var aParent = a;\n while(aParent) {\n pathOfNodes.push(aParent.node);\n aParent = aParent.parent;\n }\n var bParent = b;\n while (bParent) {\n pathOfNodes.unshift(bParent.node);\n bParent = bParent.parent\n }\n return pathOfNodes;\n }\n\n function visitNode(otherNode, link, cameFrom) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) {\n // Already processed this node.\n return;\n }\n\n if (canExit(otherSearchState, cameFrom)) {\n // this node was opened by alternative opener. The sets intersect now,\n // we found an optimal path, that goes through *this* node. However, there\n // is no guarantee that this is the global optimal solution path.\n\n var potentialLMin = otherSearchState.distanceToSource + cameFrom.distanceToSource;\n if (potentialLMin < lMin) {\n minFrom = otherSearchState;\n minTo = cameFrom\n lMin = potentialLMin;\n }\n // we are done with this node.\n return;\n }\n\n var tentativeDistance = cameFrom.distanceToSource + distance(otherSearchState.node, cameFrom.node, link);\n\n if (tentativeDistance >= otherSearchState.distanceToSource) {\n // This would only make our path longer. Ignore this route.\n return;\n }\n\n // Choose target based on current working set:\n var target = (currentOpener === BY_FROM) ? to : from;\n var newFScore = tentativeDistance + heuristic(otherSearchState.node, target);\n if (newFScore >= lMin) {\n // this can't be optimal path, as we have already found a shorter path.\n return;\n }\n otherSearchState.fScore = newFScore;\n\n if (otherSearchState.open === 0) {\n // Remember this node in the current set\n currentSet.push(otherSearchState);\n currentSet.updateItem(otherSearchState.heapIndex);\n\n otherSearchState.open = currentOpener;\n }\n\n // bingo! we found shorter path:\n otherSearchState.parent = cameFrom;\n otherSearchState.distanceToSource = tentativeDistance;\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/a-greedy-star.js?")},function(module,exports,__webpack_require__){eval("module.exports = nba;\n\nvar NodeHeap = __webpack_require__(11);\nvar heuristics = __webpack_require__(12);\nvar defaultSettings = __webpack_require__(13);\nvar makeNBASearchStatePool = __webpack_require__(37);\n\nvar NO_PATH = defaultSettings.NO_PATH;\n\nmodule.exports.l2 = heuristics.l2;\nmodule.exports.l1 = heuristics.l1;\n\n/**\n * Creates a new instance of pathfinder. A pathfinder has just one method:\n * `find(fromId, toId)`.\n * \n * This is implementation of the NBA* algorithm described in \n * \n * \"Yet another bidirectional algorithm for shortest paths\" paper by Wim Pijls and Henk Post\n * \n * The paper is available here: https://repub.eur.nl/pub/16100/ei2009-10.pdf\n * \n * @param {ngraph.graph} graph instance. See https://github.com/anvaka/ngraph.graph\n * @param {Object} options that configures search\n * @param {Function(a, b)} options.heuristic - a function that returns estimated distance between\n * nodes `a` and `b`. This function should never overestimate actual distance between two\n * nodes (otherwise the found path will not be the shortest). Defaults function returns 0,\n * which makes this search equivalent to Dijkstra search.\n * @param {Function(a, b)} options.distance - a function that returns actual distance between two\n * nodes `a` and `b`. By default this is set to return graph-theoretical distance (always 1);\n * \n * @returns {Object} A pathfinder with single method `find()`.\n */\nfunction nba(graph, options) {\n options = options || {};\n // whether traversal should be considered over oriented graph.\n var oriented = options.oriented;\n var quitFast = options.quitFast;\n\n var heuristic = options.heuristic;\n if (!heuristic) heuristic = defaultSettings.heuristic;\n\n var distance = options.distance;\n if (!distance) distance = defaultSettings.distance;\n\n // During stress tests I noticed that garbage collection was one of the heaviest\n // contributors to the algorithm's speed. So I'm using an object pool to recycle nodes.\n var pool = makeNBASearchStatePool();\n\n return {\n /**\n * Finds a path between node `fromId` and `toId`.\n * @returns {Array} of nodes between `toId` and `fromId`. Empty array is returned\n * if no path is found.\n */\n find: find\n };\n\n function find(fromId, toId) {\n // I must apologize for the code duplication. This was the easiest way for me to\n // implement the algorithm fast.\n var from = graph.getNode(fromId);\n if (!from) throw new Error('fromId is not defined in this graph: ' + fromId);\n var to = graph.getNode(toId);\n if (!to) throw new Error('toId is not defined in this graph: ' + toId);\n\n pool.reset();\n\n // I must also apologize for somewhat cryptic names. The NBA* is bi-directional\n // search algorithm, which means it runs two searches in parallel. One runs\n // from source node to target, while the other one runs from target to source.\n // Everywhere where you see `1` it means it's for the forward search. `2` is for \n // backward search.\n\n // For oriented graph path finding, we need to reverse the graph, so that\n // backward search visits correct link. Obviously we don't want to duplicate\n // the graph, instead we always traverse the graph as non-oriented, and filter\n // edges in `visitN1Oriented/visitN2Oritented`\n var forwardVisitor = oriented ? visitN1Oriented : visitN1;\n var reverseVisitor = oriented ? visitN2Oriented : visitN2;\n\n // Maps nodeId to NBASearchState.\n var nodeState = new Map();\n\n // These two heaps store nodes by their underestimated values.\n var open1Set = new NodeHeap({\n compare: defaultSettings.compareF1Score,\n setNodeId: defaultSettings.setH1\n });\n var open2Set = new NodeHeap({\n compare: defaultSettings.compareF2Score,\n setNodeId: defaultSettings.setH2\n });\n\n // This is where both searches will meet.\n var minNode;\n\n // The smallest path length seen so far is stored here:\n var lMin = Number.POSITIVE_INFINITY;\n\n // We start by putting start/end nodes to the corresponding heaps\n var startNode = pool.createNewState(from);\n nodeState.set(fromId, startNode); \n startNode.g1 = 0;\n var f1 = heuristic(from, to);\n startNode.f1 = f1;\n open1Set.push(startNode);\n\n var endNode = pool.createNewState(to);\n nodeState.set(toId, endNode);\n endNode.g2 = 0;\n var f2 = f1; // they should agree originally\n endNode.f2 = f2;\n open2Set.push(endNode)\n\n // the `cameFrom` variable is accessed by both searches, so that we can store parents.\n var cameFrom;\n\n // this is the main algorithm loop:\n while (open2Set.length && open1Set.length) {\n if (open1Set.length < open2Set.length) {\n forwardSearch();\n } else {\n reverseSearch();\n }\n\n if (quitFast && minNode) break;\n }\n\n // If we got here, then there is no path.\n var path = reconstructPath(minNode);\n return path; // the public API is over\n\n function forwardSearch() {\n cameFrom = open1Set.pop();\n if (cameFrom.closed) {\n return;\n }\n\n cameFrom.closed = true;\n\n if (cameFrom.f1 < lMin && (cameFrom.g1 + f2 - heuristic(from, cameFrom.node)) < lMin) {\n graph.forEachLinkedNode(cameFrom.node.id, forwardVisitor);\n }\n\n if (open1Set.length > 0) {\n f1 = open1Set.peek().f1;\n } \n }\n\n function reverseSearch() {\n cameFrom = open2Set.pop();\n if (cameFrom.closed) {\n return;\n }\n cameFrom.closed = true;\n\n if (cameFrom.f2 < lMin && (cameFrom.g2 + f1 - heuristic(cameFrom.node, to)) < lMin) {\n graph.forEachLinkedNode(cameFrom.node.id, reverseVisitor);\n }\n\n if (open2Set.length > 0) {\n f2 = open2Set.peek().f2;\n }\n }\n\n function visitN1(otherNode, link) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) return;\n\n var tentativeDistance = cameFrom.g1 + distance(cameFrom.node, otherNode, link);\n\n if (tentativeDistance < otherSearchState.g1) {\n otherSearchState.g1 = tentativeDistance;\n otherSearchState.f1 = tentativeDistance + heuristic(otherSearchState.node, to);\n otherSearchState.p1 = cameFrom;\n if (otherSearchState.h1 < 0) {\n open1Set.push(otherSearchState);\n } else {\n open1Set.updateItem(otherSearchState.h1);\n }\n }\n var potentialMin = otherSearchState.g1 + otherSearchState.g2;\n if (potentialMin < lMin) { \n lMin = potentialMin;\n minNode = otherSearchState;\n }\n }\n\n function visitN2(otherNode, link) {\n var otherSearchState = nodeState.get(otherNode.id);\n if (!otherSearchState) {\n otherSearchState = pool.createNewState(otherNode);\n nodeState.set(otherNode.id, otherSearchState);\n }\n\n if (otherSearchState.closed) return;\n\n var tentativeDistance = cameFrom.g2 + distance(cameFrom.node, otherNode, link);\n\n if (tentativeDistance < otherSearchState.g2) {\n otherSearchState.g2 = tentativeDistance;\n otherSearchState.f2 = tentativeDistance + heuristic(from, otherSearchState.node);\n otherSearchState.p2 = cameFrom;\n if (otherSearchState.h2 < 0) {\n open2Set.push(otherSearchState);\n } else {\n open2Set.updateItem(otherSearchState.h2);\n }\n }\n var potentialMin = otherSearchState.g1 + otherSearchState.g2;\n if (potentialMin < lMin) {\n lMin = potentialMin;\n minNode = otherSearchState;\n }\n }\n\n function visitN2Oriented(otherNode, link) {\n // we are going backwards, graph needs to be reversed. \n if (link.toId === cameFrom.node.id) return visitN2(otherNode, link);\n }\n function visitN1Oriented(otherNode, link) {\n // this is forward direction, so we should be coming FROM:\n if (link.fromId === cameFrom.node.id) return visitN1(otherNode, link);\n }\n }\n}\n\nfunction reconstructPath(searchState) {\n if (!searchState) return NO_PATH;\n\n var path = [searchState.node];\n var parent = searchState.p1;\n\n while (parent) {\n path.push(parent.node);\n parent = parent.p1;\n }\n\n var child = searchState.p2;\n\n while (child) {\n path.unshift(child.node);\n child = child.p2;\n }\n return path;\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/nba/index.js?")},function(module,exports){eval("module.exports = makeNBASearchStatePool;\n\n/**\n * Creates new instance of NBASearchState. The instance stores information\n * about search state, and is used by NBA* algorithm.\n *\n * @param {Object} node - original graph node\n */\nfunction NBASearchState(node) {\n /**\n * Original graph node.\n */\n this.node = node;\n\n /**\n * Parent of this node in forward search\n */\n this.p1 = null;\n\n /**\n * Parent of this node in reverse search\n */\n this.p2 = null;\n\n /**\n * If this is set to true, then the node was already processed\n * and we should not touch it anymore.\n */\n this.closed = false;\n\n /**\n * Actual distance from this node to its parent in forward search\n */\n this.g1 = Number.POSITIVE_INFINITY;\n\n /**\n * Actual distance from this node to its parent in reverse search\n */\n this.g2 = Number.POSITIVE_INFINITY;\n\n\n /**\n * Underestimated distance from this node to the path-finding source.\n */\n this.f1 = Number.POSITIVE_INFINITY;\n\n /**\n * Underestimated distance from this node to the path-finding target.\n */\n this.f2 = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated. TODO: do I need them both?\n\n /**\n * Index of this node in the forward heap.\n */\n this.h1 = -1;\n\n /**\n * Index of this node in the reverse heap.\n */\n this.h2 = -1;\n}\n\n/**\n * As path-finding is memory-intensive process, we want to reduce pressure on\n * garbage collector. This class helps us to recycle path-finding nodes and significantly\n * reduces the search time (~20% faster than without it).\n */\nfunction makeNBASearchStatePool() {\n var currentInCache = 0;\n var nodeCache = [];\n\n return {\n /**\n * Creates a new NBASearchState instance\n */\n createNewState: createNewState,\n\n /**\n * Marks all created instances available for recycling.\n */\n reset: reset\n };\n\n function reset() {\n currentInCache = 0;\n }\n\n function createNewState(node) {\n var cached = nodeCache[currentInCache];\n if (cached) {\n // TODO: This almost duplicates constructor code. Not sure if\n // it would impact performance if I move this code into a function\n cached.node = node;\n\n // How we came to this node?\n cached.p1 = null;\n cached.p2 = null;\n\n cached.closed = false;\n\n cached.g1 = Number.POSITIVE_INFINITY;\n cached.g2 = Number.POSITIVE_INFINITY;\n cached.f1 = Number.POSITIVE_INFINITY;\n cached.f2 = Number.POSITIVE_INFINITY;\n\n // used to reconstruct heap when fScore is updated.\n cached.h1 = -1;\n cached.h2 = -1;\n } else {\n cached = new NBASearchState(node);\n nodeCache[currentInCache] = cached;\n }\n currentInCache++;\n return cached;\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.path/a-star/nba/makeNBASearchStatePool.js?")},function(module,exports,__webpack_require__){eval("/**\n * @fileOverview Contains definition of the core graph object.\n */\n\n// TODO: need to change storage layer:\n// 1. Be able to get all nodes O(1)\n// 2. Be able to get number of links O(1)\n\n/**\n * @example\n * var graph = require('ngraph.graph')();\n * graph.addNode(1); // graph has one node.\n * graph.addLink(2, 3); // now graph contains three nodes and one link.\n *\n */\nmodule.exports = createGraph;\n\nvar eventify = __webpack_require__(39);\n\n/**\n * Creates a new graph\n */\nfunction createGraph(options) {\n // Graph structure is maintained as dictionary of nodes\n // and array of links. Each node has 'links' property which\n // hold all links related to that node. And general links\n // array is used to speed up all links enumeration. This is inefficient\n // in terms of memory, but simplifies coding.\n options = options || {};\n if ('uniqueLinkId' in options) {\n console.warn(\n 'ngraph.graph: Starting from version 0.14 `uniqueLinkId` is deprecated.\\n' +\n 'Use `multigraph` option instead\\n',\n '\\n',\n 'Note: there is also change in default behavior: From now own each graph\\n'+\n 'is considered to be not a multigraph by default (each edge is unique).'\n );\n\n options.multigraph = options.uniqueLinkId;\n }\n\n // Dear reader, the non-multigraphs do not guarantee that there is only\n // one link for a given pair of node. When this option is set to false\n // we can save some memory and CPU (18% faster for non-multigraph);\n if (options.multigraph === undefined) options.multigraph = false;\n\n var nodes = typeof Object.create === 'function' ? Object.create(null) : {},\n links = [],\n // Hash of multi-edges. Used to track ids of edges between same nodes\n multiEdges = {},\n nodesCount = 0,\n suspendEvents = 0,\n\n forEachNode = createNodeIterator(),\n createLink = options.multigraph ? createUniqueLink : createSingleLink,\n\n // Our graph API provides means to listen to graph changes. Users can subscribe\n // to be notified about changes in the graph by using `on` method. However\n // in some cases they don't use it. To avoid unnecessary memory consumption\n // we will not record graph changes until we have at least one subscriber.\n // Code below supports this optimization.\n //\n // Accumulates all changes made during graph updates.\n // Each change element contains:\n // changeType - one of the strings: 'add', 'remove' or 'update';\n // node - if change is related to node this property is set to changed graph's node;\n // link - if change is related to link this property is set to changed graph's link;\n changes = [],\n recordLinkChange = noop,\n recordNodeChange = noop,\n enterModification = noop,\n exitModification = noop;\n\n // this is our public API:\n var graphPart = {\n /**\n * Adds node to the graph. If node with given id already exists in the graph\n * its data is extended with whatever comes in 'data' argument.\n *\n * @param nodeId the node's identifier. A string or number is preferred.\n * @param [data] additional data for the node being added. If node already\n * exists its data object is augmented with the new one.\n *\n * @return {node} The newly added node or node with given id if it already exists.\n */\n addNode: addNode,\n\n /**\n * Adds a link to the graph. The function always create a new\n * link between two nodes. If one of the nodes does not exists\n * a new node is created.\n *\n * @param fromId link start node id;\n * @param toId link end node id;\n * @param [data] additional data to be set on the new link;\n *\n * @return {link} The newly created link\n */\n addLink: addLink,\n\n /**\n * Removes link from the graph. If link does not exist does nothing.\n *\n * @param link - object returned by addLink() or getLinks() methods.\n *\n * @returns true if link was removed; false otherwise.\n */\n removeLink: removeLink,\n\n /**\n * Removes node with given id from the graph. If node does not exist in the graph\n * does nothing.\n *\n * @param nodeId node's identifier passed to addNode() function.\n *\n * @returns true if node was removed; false otherwise.\n */\n removeNode: removeNode,\n\n /**\n * Gets node with given identifier. If node does not exist undefined value is returned.\n *\n * @param nodeId requested node identifier;\n *\n * @return {node} in with requested identifier or undefined if no such node exists.\n */\n getNode: getNode,\n\n /**\n * Gets number of nodes in this graph.\n *\n * @return number of nodes in the graph.\n */\n getNodesCount: function () {\n return nodesCount;\n },\n\n /**\n * Gets total number of links in the graph.\n */\n getLinksCount: function () {\n return links.length;\n },\n\n /**\n * Gets all links (inbound and outbound) from the node with given id.\n * If node with given id is not found null is returned.\n *\n * @param nodeId requested node identifier.\n *\n * @return Array of links from and to requested node if such node exists;\n * otherwise null is returned.\n */\n getLinks: getLinks,\n\n /**\n * Invokes callback on each node of the graph.\n *\n * @param {Function(node)} callback Function to be invoked. The function\n * is passed one argument: visited node.\n */\n forEachNode: forEachNode,\n\n /**\n * Invokes callback on every linked (adjacent) node to the given one.\n *\n * @param nodeId Identifier of the requested node.\n * @param {Function(node, link)} callback Function to be called on all linked nodes.\n * The function is passed two parameters: adjacent node and link object itself.\n * @param oriented if true graph treated as oriented.\n */\n forEachLinkedNode: forEachLinkedNode,\n\n /**\n * Enumerates all links in the graph\n *\n * @param {Function(link)} callback Function to be called on all links in the graph.\n * The function is passed one parameter: graph's link object.\n *\n * Link object contains at least the following fields:\n * fromId - node id where link starts;\n * toId - node id where link ends,\n * data - additional data passed to graph.addLink() method.\n */\n forEachLink: forEachLink,\n\n /**\n * Suspend all notifications about graph changes until\n * endUpdate is called.\n */\n beginUpdate: enterModification,\n\n /**\n * Resumes all notifications about graph changes and fires\n * graph 'changed' event in case there are any pending changes.\n */\n endUpdate: exitModification,\n\n /**\n * Removes all nodes and links from the graph.\n */\n clear: clear,\n\n /**\n * Detects whether there is a link between two nodes.\n * Operation complexity is O(n) where n - number of links of a node.\n * NOTE: this function is synonim for getLink()\n *\n * @returns link if there is one. null otherwise.\n */\n hasLink: getLink,\n\n /**\n * Detects whether there is a node with given id\n * \n * Operation complexity is O(1)\n * NOTE: this function is synonim for getNode()\n *\n * @returns node if there is one; Falsy value otherwise.\n */\n hasNode: getNode,\n\n /**\n * Gets an edge between two nodes.\n * Operation complexity is O(n) where n - number of links of a node.\n *\n * @param {string} fromId link start identifier\n * @param {string} toId link end identifier\n *\n * @returns link if there is one. null otherwise.\n */\n getLink: getLink\n };\n\n // this will add `on()` and `fire()` methods.\n eventify(graphPart);\n\n monitorSubscribers();\n\n return graphPart;\n\n function monitorSubscribers() {\n var realOn = graphPart.on;\n\n // replace real `on` with our temporary on, which will trigger change\n // modification monitoring:\n graphPart.on = on;\n\n function on() {\n // now it's time to start tracking stuff:\n graphPart.beginUpdate = enterModification = enterModificationReal;\n graphPart.endUpdate = exitModification = exitModificationReal;\n recordLinkChange = recordLinkChangeReal;\n recordNodeChange = recordNodeChangeReal;\n\n // this will replace current `on` method with real pub/sub from `eventify`.\n graphPart.on = realOn;\n // delegate to real `on` handler:\n return realOn.apply(graphPart, arguments);\n }\n }\n\n function recordLinkChangeReal(link, changeType) {\n changes.push({\n link: link,\n changeType: changeType\n });\n }\n\n function recordNodeChangeReal(node, changeType) {\n changes.push({\n node: node,\n changeType: changeType\n });\n }\n\n function addNode(nodeId, data) {\n if (nodeId === undefined) {\n throw new Error('Invalid node identifier');\n }\n\n enterModification();\n\n var node = getNode(nodeId);\n if (!node) {\n node = new Node(nodeId, data);\n nodesCount++;\n recordNodeChange(node, 'add');\n } else {\n node.data = data;\n recordNodeChange(node, 'update');\n }\n\n nodes[nodeId] = node;\n\n exitModification();\n return node;\n }\n\n function getNode(nodeId) {\n return nodes[nodeId];\n }\n\n function removeNode(nodeId) {\n var node = getNode(nodeId);\n if (!node) {\n return false;\n }\n\n enterModification();\n\n var prevLinks = node.links;\n if (prevLinks) {\n node.links = null;\n for(var i = 0; i < prevLinks.length; ++i) {\n removeLink(prevLinks[i]);\n }\n }\n\n delete nodes[nodeId];\n nodesCount--;\n\n recordNodeChange(node, 'remove');\n\n exitModification();\n\n return true;\n }\n\n\n function addLink(fromId, toId, data) {\n enterModification();\n\n var fromNode = getNode(fromId) || addNode(fromId);\n var toNode = getNode(toId) || addNode(toId);\n\n var link = createLink(fromId, toId, data);\n\n links.push(link);\n\n // TODO: this is not cool. On large graphs potentially would consume more memory.\n addLinkToNode(fromNode, link);\n if (fromId !== toId) {\n // make sure we are not duplicating links for self-loops\n addLinkToNode(toNode, link);\n }\n\n recordLinkChange(link, 'add');\n\n exitModification();\n\n return link;\n }\n\n function createSingleLink(fromId, toId, data) {\n var linkId = makeLinkId(fromId, toId);\n return new Link(fromId, toId, data, linkId);\n }\n\n function createUniqueLink(fromId, toId, data) {\n // TODO: Get rid of this method.\n var linkId = makeLinkId(fromId, toId);\n var isMultiEdge = multiEdges.hasOwnProperty(linkId);\n if (isMultiEdge || getLink(fromId, toId)) {\n if (!isMultiEdge) {\n multiEdges[linkId] = 0;\n }\n var suffix = '@' + (++multiEdges[linkId]);\n linkId = makeLinkId(fromId + suffix, toId + suffix);\n }\n\n return new Link(fromId, toId, data, linkId);\n }\n\n function getLinks(nodeId) {\n var node = getNode(nodeId);\n return node ? node.links : null;\n }\n\n function removeLink(link) {\n if (!link) {\n return false;\n }\n var idx = indexOfElementInArray(link, links);\n if (idx < 0) {\n return false;\n }\n\n enterModification();\n\n links.splice(idx, 1);\n\n var fromNode = getNode(link.fromId);\n var toNode = getNode(link.toId);\n\n if (fromNode) {\n idx = indexOfElementInArray(link, fromNode.links);\n if (idx >= 0) {\n fromNode.links.splice(idx, 1);\n }\n }\n\n if (toNode) {\n idx = indexOfElementInArray(link, toNode.links);\n if (idx >= 0) {\n toNode.links.splice(idx, 1);\n }\n }\n\n recordLinkChange(link, 'remove');\n\n exitModification();\n\n return true;\n }\n\n function getLink(fromNodeId, toNodeId) {\n // TODO: Use sorted links to speed this up\n var node = getNode(fromNodeId),\n i;\n if (!node || !node.links) {\n return null;\n }\n\n for (i = 0; i < node.links.length; ++i) {\n var link = node.links[i];\n if (link.fromId === fromNodeId && link.toId === toNodeId) {\n return link;\n }\n }\n\n return null; // no link.\n }\n\n function clear() {\n enterModification();\n forEachNode(function(node) {\n removeNode(node.id);\n });\n exitModification();\n }\n\n function forEachLink(callback) {\n var i, length;\n if (typeof callback === 'function') {\n for (i = 0, length = links.length; i < length; ++i) {\n callback(links[i]);\n }\n }\n }\n\n function forEachLinkedNode(nodeId, callback, oriented) {\n var node = getNode(nodeId);\n\n if (node && node.links && typeof callback === 'function') {\n if (oriented) {\n return forEachOrientedLink(node.links, nodeId, callback);\n } else {\n return forEachNonOrientedLink(node.links, nodeId, callback);\n }\n }\n }\n\n function forEachNonOrientedLink(links, nodeId, callback) {\n var quitFast;\n for (var i = 0; i < links.length; ++i) {\n var link = links[i];\n var linkedNodeId = link.fromId === nodeId ? link.toId : link.fromId;\n\n quitFast = callback(nodes[linkedNodeId], link);\n if (quitFast) {\n return true; // Client does not need more iterations. Break now.\n }\n }\n }\n\n function forEachOrientedLink(links, nodeId, callback) {\n var quitFast;\n for (var i = 0; i < links.length; ++i) {\n var link = links[i];\n if (link.fromId === nodeId) {\n quitFast = callback(nodes[link.toId], link);\n if (quitFast) {\n return true; // Client does not need more iterations. Break now.\n }\n }\n }\n }\n\n // we will not fire anything until users of this library explicitly call `on()`\n // method.\n function noop() {}\n\n // Enter, Exit modification allows bulk graph updates without firing events.\n function enterModificationReal() {\n suspendEvents += 1;\n }\n\n function exitModificationReal() {\n suspendEvents -= 1;\n if (suspendEvents === 0 && changes.length > 0) {\n graphPart.fire('changed', changes);\n changes.length = 0;\n }\n }\n\n function createNodeIterator() {\n // Object.keys iterator is 1.3x faster than `for in` loop.\n // See `https://github.com/anvaka/ngraph.graph/tree/bench-for-in-vs-obj-keys`\n // branch for perf test\n return Object.keys ? objectKeysIterator : forInIterator;\n }\n\n function objectKeysIterator(callback) {\n if (typeof callback !== 'function') {\n return;\n }\n\n var keys = Object.keys(nodes);\n for (var i = 0; i < keys.length; ++i) {\n if (callback(nodes[keys[i]])) {\n return true; // client doesn't want to proceed. Return.\n }\n }\n }\n\n function forInIterator(callback) {\n if (typeof callback !== 'function') {\n return;\n }\n var node;\n\n for (node in nodes) {\n if (callback(nodes[node])) {\n return true; // client doesn't want to proceed. Return.\n }\n }\n }\n}\n\n// need this for old browsers. Should this be a separate module?\nfunction indexOfElementInArray(element, array) {\n if (!array) return -1;\n\n if (array.indexOf) {\n return array.indexOf(element);\n }\n\n var len = array.length,\n i;\n\n for (i = 0; i < len; i += 1) {\n if (array[i] === element) {\n return i;\n }\n }\n\n return -1;\n}\n\n/**\n * Internal structure to represent node;\n */\nfunction Node(id, data) {\n this.id = id;\n this.links = null;\n this.data = data;\n}\n\nfunction addLinkToNode(node, link) {\n if (node.links) {\n node.links.push(link);\n } else {\n node.links = [link];\n }\n}\n\n/**\n * Internal structure to represent links;\n */\nfunction Link(fromId, toId, data, id) {\n this.fromId = fromId;\n this.toId = toId;\n this.data = data;\n this.id = id;\n}\n\nfunction hashCode(str) {\n var hash = 0, i, chr, len;\n if (str.length == 0) return hash;\n for (i = 0, len = str.length; i < len; i++) {\n chr = str.charCodeAt(i);\n hash = ((hash << 5) - hash) + chr;\n hash |= 0; // Convert to 32bit integer\n }\n return hash;\n}\n\nfunction makeLinkId(fromId, toId) {\n return fromId.toString() + '👉 ' + toId.toString();\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.graph/index.js?")},function(module,exports){eval("module.exports = function(subject) {\n validateSubject(subject);\n\n var eventsStorage = createEventsStorage(subject);\n subject.on = eventsStorage.on;\n subject.off = eventsStorage.off;\n subject.fire = eventsStorage.fire;\n return subject;\n};\n\nfunction createEventsStorage(subject) {\n // Store all event listeners to this hash. Key is event name, value is array\n // of callback records.\n //\n // A callback record consists of callback function and its optional context:\n // { 'eventName' => [{callback: function, ctx: object}] }\n var registeredEvents = Object.create(null);\n\n return {\n on: function (eventName, callback, ctx) {\n if (typeof callback !== 'function') {\n throw new Error('callback is expected to be a function');\n }\n var handlers = registeredEvents[eventName];\n if (!handlers) {\n handlers = registeredEvents[eventName] = [];\n }\n handlers.push({callback: callback, ctx: ctx});\n\n return subject;\n },\n\n off: function (eventName, callback) {\n var wantToRemoveAll = (typeof eventName === 'undefined');\n if (wantToRemoveAll) {\n // Killing old events storage should be enough in this case:\n registeredEvents = Object.create(null);\n return subject;\n }\n\n if (registeredEvents[eventName]) {\n var deleteAllCallbacksForEvent = (typeof callback !== 'function');\n if (deleteAllCallbacksForEvent) {\n delete registeredEvents[eventName];\n } else {\n var callbacks = registeredEvents[eventName];\n for (var i = 0; i < callbacks.length; ++i) {\n if (callbacks[i].callback === callback) {\n callbacks.splice(i, 1);\n }\n }\n }\n }\n\n return subject;\n },\n\n fire: function (eventName) {\n var callbacks = registeredEvents[eventName];\n if (!callbacks) {\n return subject;\n }\n\n var fireArguments;\n if (arguments.length > 1) {\n fireArguments = Array.prototype.splice.call(arguments, 1);\n }\n for(var i = 0; i < callbacks.length; ++i) {\n var callbackInfo = callbacks[i];\n callbackInfo.callback.apply(callbackInfo.ctx, fireArguments);\n }\n\n return subject;\n }\n };\n}\n\nfunction validateSubject(subject) {\n if (!subject) {\n throw new Error('Eventify cannot use falsy object as events subject');\n }\n var reservedWords = ['on', 'fire', 'off'];\n for (var i = 0; i < reservedWords.length; ++i) {\n if (subject.hasOwnProperty(reservedWords[i])) {\n throw new Error(\"Subject cannot be eventified, since it already has property '\" + reservedWords[i] + \"'\");\n }\n }\n}\n\n\n//# sourceURL=webpack:///./node_modules/ngraph.events/index.js?")},function(module,exports,__webpack_require__){eval('function _toConsumableArray(arr) { return _arrayWithoutHoles(arr) || _iterableToArray(arr) || _nonIterableSpread(); }\n\nfunction _nonIterableSpread() { throw new TypeError("Invalid attempt to spread non-iterable instance"); }\n\nfunction _iterableToArray(iter) { if (Symbol.iterator in Object(iter) || Object.prototype.toString.call(iter) === "[object Arguments]") return Array.from(iter); }\n\nfunction _arrayWithoutHoles(arr) { if (Array.isArray(arr)) { for (var i = 0, arr2 = new Array(arr.length); i < arr.length; i++) { arr2[i] = arr[i]; } return arr2; } }\n\n/* Functions that help design and generate building units onto the map. */\nvar bearing = __webpack_require__(5).default,\n destination = __webpack_require__(6).default,\n along = __webpack_require__(15).default,\n lineIntersect = __webpack_require__(16).default,\n intersect = __webpack_require__(41).default,\n Agentmap = __webpack_require__(4).Agentmap,\n streetsToGraph = __webpack_require__(10).streetsToGraph,\n getPathFinder = __webpack_require__(10).getPathFinder;\n/**\r\n * Generate and setup the desired map features (e.g. streets, houses).\r\n * @memberof Agentmap\r\n * @instance\r\n *\r\n * @param {Array.>} bounding_box - The map\'s top-left and bottom-right coordinates.\r\n * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} [street_options] - An object containing the Leaflet styling options for streets. See available options here: {@link https://leafletjs.com/reference-1.3.2.html#polyline-l-polyline}.\r\n * @param {object} [unit_options] - An object containing the Leaflet & AgentMaps styling options for units.
See available Leaflet options here: {@link https://leafletjs.com/reference-1.3.2.html#polygon-l-polygon}
Additional AgentMaps-specific options are described below.\r\n * @param {number} [unit_options.front_buffer = 6] - The number of meters beetween the front of unit and its street.\r\n * @param {number} [unit_options.side_buffer = 3] - The number of meters between two units on the same street.\r\n * @param {number} [unit_options.length = 14] - The length of the unit in meters along the street.\r\n * @param {number} [unit_options.depth = 18] - The depth of the unit in meters out from its front.\r\n * @param {object} [unit_layers]- If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup.\r\n * @param {object} [street_layers]- If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup.\r\n */\n\n\nfunction buildingify(bounding_box, OSM_data, street_options, unit_options, unit_layers, street_layers) {\n setupStreetFeatures.call(this, OSM_data, street_options);\n setupUnitFeatures.call(this, bounding_box, OSM_data, unit_options, unit_layers);\n}\n/**\r\n * Generate and setup streets based on the provided GeoJSON data.\r\n *\r\n * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} street_options - An object containing the Leaflet styling options for streets.\r\n * @param {object} [street_layers] - If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup.\r\n */\n\n\nfunction setupStreetFeatures(OSM_data, street_options, street_layers) {\n var default_options = {\n "color": "yellow",\n "weight": 4,\n "opacity": .5\n };\n street_options = Object.assign(default_options, street_options);\n var street_feature_collection;\n\n if (typeof street_layers === "undefined") {\n var street_features = getStreetFeatures(OSM_data);\n street_feature_collection = {\n type: "FeatureCollection",\n features: street_features\n };\n } else {\n street_feature_collection = street_layers;\n }\n\n this.streets = L.geoJSON(street_feature_collection, street_options).addTo(this.map); //Map streets\' OSM IDs to their Leaflet IDs.\n\n this.streets.id_map = {}; //Having added the streets as layers to the map, do any processing that requires access to those layers.\n\n this.streets.eachLayer(function (street) {\n this.streets.id_map[street.feature.id] = street._leaflet_id;\n addStreetLayerIntersections.call(this, street);\n }, this); //Add general graph-making and path-finder-making methods to Agentmap, in case streets are added, removed, or modified mid-simulation.\n\n this.streetsToGraph = streetsToGraph, this.getPathFinder = getPathFinder;\n this.streets.graph = streetsToGraph(this.streets), this.pathfinder = getPathFinder(this.streets.graph);\n}\n/**\r\n * Get all streets from the GeoJSON data.\r\n * @private\r\n *\r\n * @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box.\r\n * @returns {Array} - array of street features.\r\n */\n\n\nfunction getStreetFeatures(OSM_data) {\n var street_features = [];\n\n for (var i = 0; i < OSM_data.features.length; ++i) {\n var feature = OSM_data.features[i];\n\n if (feature.geometry.type === "LineString" && feature.properties.highway) {\n var street_feature = feature;\n street_features.push(street_feature);\n }\n }\n\n return street_features;\n}\n/**\r\n * Gets the intersections of all the streets on the map and adds them as properties to the street layers.\r\n * @private\r\n * \r\n * @param {object} street - A Leaflet polyline representing a street.\r\n */\n\n\nfunction addStreetLayerIntersections(street) {\n var street_id = street._leaflet_id;\n street.intersections = typeof street.intersections === "undefined" ? {} : street.intersections;\n this.streets.eachLayer(function (other_street) {\n var other_street_id = other_street._leaflet_id; //Skip if both streets are the same, or if the street already has its intersections with the other street.\n\n if (typeof street.intersections[other_street_id] === "undefined" && street_id !== other_street_id) {\n var street_coords = street.getLatLngs().map(L.A.pointToCoordinateArray),\n other_street_coords = other_street.getLatLngs().map(L.A.pointToCoordinateArray),\n identified_intersections = L.A.getIntersections(street_coords, other_street_coords, [street_id, other_street_id]).map(function (identified_intersection) {\n return [L.latLng(L.A.reversedCoordinates(identified_intersection[0])), identified_intersection[1]];\n });\n\n if (identified_intersections.length > 0) {\n street.intersections[other_street_id] = identified_intersections, other_street.intersections = typeof other_street.intersections === "undefined" ? {} : other_street.intersections, other_street.intersections[street_id] = identified_intersections;\n }\n }\n });\n}\n/**\r\n * Generate and setup building units based on the provided GeoJSON data.\r\n *\r\n * @param {Array.>} bounding_box - The map\'s top-left and bottom-right coordinates.\r\n * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} unit_options - An object containing the Leaflet & AgentMaps styling options for units.\r\n * @param {object} [unit_layers] - If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup.\r\n */\n\n\nfunction setupUnitFeatures(bounding_box, OSM_data) {\n var unit_options = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : {};\n var unit_layers = arguments.length > 3 ? arguments[3] : undefined;\n var default_options = {\n "color": "green",\n "weight": 1,\n "opacity": .87,\n "front_buffer": 6,\n "side_buffer": 3,\n "length": 14,\n "depth": 18\n };\n unit_options = Object.assign(default_options, unit_options);\n var unit_feature_collection; //If no unit_layers is supplied, generate the units from scratch.\n\n if (typeof unit_layers === "undefined") {\n //Bind getUnitFeatures to "this" so it can access the agentmap as "this.agentmap".\n var _unit_features = getUnitFeatures.bind(this)(bounding_box, OSM_data, unit_options);\n\n unit_feature_collection = {\n type: "FeatureCollection",\n features: _unit_features\n };\n } else {\n unit_feature_collection = unit_layers;\n }\n\n this.units = L.geoJSON(unit_feature_collection, unit_options).addTo(this.map); //Having added the units as layers to the map, do any processing that requires access to those layers.\n\n this.units.eachLayer(function (unit) {\n if (typeof unit_layers === "undefined") {\n unit.street_id = unit.feature.properties.street_id;\n } else {\n unit.street_id = this.streets.id_map[unit.feature.properties.OSM_street_id];\n }\n\n unit.street_anchors = unit.feature.properties.street_anchors, //Change the IDs of each unit in this unit\'s neighbours array into the appropriate Leaflet IDs.\n unit.neighbors = getUnitNeighborLayerIDs.call(this, unit.feature.properties.neighbors);\n }, this);\n}\n/**\r\n * Given an array of pre-layer IDs, check if any of them correspond to the pre-layer IDs of unit layers, and if so\r\n * return an array of the corresponding layer IDs.\r\n * @private\r\n *\r\n * @param {Array} - An array of pre-layer feature IDs for a unit\'s neighbors.\r\n * @returns {Array} - An array of Leaflet layer IDs corresponding to the unit\'s neighbors.\r\n */\n\n\nfunction getUnitNeighborLayerIDs(neighbors) {\n var neighbor_layer_ids = neighbors.map(function (neighbor) {\n if (neighbor !== null) {\n var neighbor_layer_id = null;\n this.units.eachLayer(function (possible_neighbor_layer) {\n if (possible_neighbor_layer.feature.properties.id === neighbor) {\n neighbor_layer_id = this.units.getLayerId(possible_neighbor_layer);\n }\n }, this);\n return neighbor_layer_id;\n } else {\n return null;\n }\n }, this);\n return neighbor_layer_ids;\n}\n/**\r\n * Get all appropriate units within the desired bounding box.\r\n * @private\r\n *\r\n * @param {Array.>} bounding_box - The map\'s top-left and bottom-right coordinates.\r\n * @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box.\r\n * @param {object} unit_options - An object containing the AgentMaps styling options for units.\r\n * @returns {Array} - Array of features representing real estate units.\r\n */\n\n\nfunction getUnitFeatures(bounding_box, OSM_data, unit_options) {\n var proposed_unit_features = [];\n this.streets.eachLayer(function (layer) {\n var street_feature = layer.feature,\n street_id = layer._leaflet_id,\n street_OSM_id = layer.feature.id,\n proposed_anchors = getUnitAnchors(street_feature, bounding_box, unit_options),\n new_proposed_unit_features = generateUnitFeatures(proposed_anchors, proposed_unit_features, street_id, street_OSM_id, unit_options);\n proposed_unit_features.push.apply(proposed_unit_features, _toConsumableArray(new_proposed_unit_features));\n });\n unit_features = unitsOutOfStreets(proposed_unit_features, this.streets);\n return unit_features;\n}\n/**\r\n * Given an array of anchor pairs, for each anchor pair find four \r\n * nearby points on either side of the street appropriate to build a unit(s) on.\r\n * @private\r\n *\r\n * @param {Array>} unit_anchors - Array of pairs of points around which to anchor units along a street.\r\n * @param {Array} proposed_unit_features - Array of features representing building units already proposed for construction.\r\n * @param {string} street_leaflet_id - The Leaflet layer ID of the street feature along which the unit is being constructed.\r\n * @param {string} street_OSM_id - The OSM feature ID of the street feature along which the unit is being constructed.\r\n * @param {object} unit_options - An object containing the AgentMaps styling options for units.\r\n * @returns {Array} unit_features - Array of features representing units.\r\n */\n\n\nfunction generateUnitFeatures(unit_anchors, proposed_unit_features, street_leaflet_id, street_OSM_id, unit_options) {\n var _ref;\n\n //One sub-array of unit features for each side of the road.\n var unit_features = [[], []],\n starting_id = proposed_unit_features.length,\n increment = 1;\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = unit_anchors[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var anchor_pair = _step.value;\n //Pair of unit_features opposite each other on a street.\n var unit_pair = [null, null];\n var _arr = [1, -1];\n\n for (var _i = 0; _i < _arr.length; _i++) {\n var i = _arr[_i];\n var anchor_a = anchor_pair[0].geometry.coordinates,\n anchor_b = anchor_pair[1].geometry.coordinates,\n anchor_latLng_pair = [anchor_a, anchor_b],\n street_buffer = unit_options.front_buffer / 1000,\n //Distance between center of street and start of unit.\n house_depth = unit_options.depth / 1000,\n angle = bearing(anchor_a, anchor_b),\n new_angle = angle + i * 90,\n //Angle of line perpendicular to the anchor segment.\n unit_feature = {\n type: "Feature",\n properties: {\n street: "none"\n },\n geometry: {\n type: "Polygon",\n coordinates: [[]]\n }\n };\n unit_feature.geometry.coordinates[0][0] = destination(anchor_a, street_buffer, new_angle).geometry.coordinates, unit_feature.geometry.coordinates[0][1] = destination(anchor_b, street_buffer, new_angle).geometry.coordinates, unit_feature.geometry.coordinates[0][2] = destination(anchor_b, street_buffer + house_depth, new_angle).geometry.coordinates, unit_feature.geometry.coordinates[0][3] = destination(anchor_a, street_buffer + house_depth, new_angle).geometry.coordinates;\n unit_feature.geometry.coordinates[0][4] = unit_feature.geometry.coordinates[0][0]; //Exclude the unit if it overlaps with any of the other proposed units.\n\n var all_proposed_unit_features = unit_features[0].concat(unit_features[1]).concat(proposed_unit_features);\n\n if (noOverlaps(unit_feature, all_proposed_unit_features)) {\n //Recode index so that it\'s useful here.\n i = i === 1 ? 0 : 1;\n unit_feature.properties.street_id = street_leaflet_id, unit_feature.properties.OSM_street_id = street_OSM_id, unit_feature.properties.street_anchors = anchor_latLng_pair, unit_feature.properties.neighbors = [null, null, null], unit_feature.properties.id = starting_id + increment, increment += 1;\n\n if (unit_features[i].length !== 0) {\n //Make previous unit_feature this unit_feature\'s first neighbor.\n unit_feature.properties.neighbors[0] = unit_features[i][unit_features[i].length - 1].properties.id, //Make this unit_feature the previous unit_feature\'s second neighbor.\n unit_features[i][unit_features[i].length - 1].properties.neighbors[1] = unit_feature.properties.id;\n }\n\n if (i === 0) {\n unit_pair[0] = unit_feature;\n } else {\n if (unit_pair[0] !== null) {\n //Make unit_feature opposite to this unit_feature on the street its third neighbor.\n unit_feature.properties.neighbors[2] = unit_pair[0].properties.id, //Make unit_feature opposite to this unit_feature on the street\'s third neighbor this unit_feature.\n unit_pair[0].properties.neighbors[2] = unit_feature.properties.id;\n }\n\n unit_pair[1] = unit_feature;\n }\n }\n }\n\n if (unit_pair[0] !== null) {\n unit_features[0].push(unit_pair[0]);\n }\n\n if (unit_pair[1] !== null) {\n unit_features[1].push(unit_pair[1]);\n }\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n\n var unit_features_merged = (_ref = []).concat.apply(_ref, unit_features);\n\n return unit_features_merged;\n}\n/**\r\n * Find anchors for potential units. chors are the pairs of start \r\n * and end points along the street from which units may be constructed.\r\n * @private\r\n * \r\n * @param {Feature} street_feature - A GeoJSON feature object representing a street.\r\n * @param {object} unit_options - An object containing the AgentMaps styling options for units.\r\n * @returns {Array>} - Array of pairs of points around which to anchor units along a street. \r\n */\n\n\nfunction getUnitAnchors(street_feature, bounding_box, unit_options) {\n var unit_anchors = [],\n unit_length = unit_options.length / 1000,\n //Kilometers.\n unit_buffer = unit_options.side_buffer / 1000,\n //Distance between units, kilometers.\n endpoint = street_feature.geometry.coordinates[street_feature.geometry.coordinates.length - 1],\n start_anchor = along(street_feature, 0),\n end_anchor = along(street_feature, unit_length),\n distance_along = unit_length;\n\n while (end_anchor.geometry.coordinates != endpoint) {\n //Exclude proposed anchors if they\'re outside of the bounding box.\n start_coord = L.A.reversedCoordinates(start_anchor.geometry.coordinates), end_coord = L.A.reversedCoordinates(end_anchor.geometry.coordinates);\n\n if (L.latLngBounds(bounding_box).contains(start_coord) && L.latLngBounds(bounding_box).contains(end_coord)) {\n unit_anchors.push([start_anchor, end_anchor]);\n } //Find next pair of anchors.\n\n\n start_anchor = along(street_feature, distance_along + unit_buffer);\n end_anchor = along(street_feature, distance_along + unit_buffer + unit_length);\n distance_along += unit_buffer + unit_length;\n }\n\n return unit_anchors;\n}\n/**\r\n * Get an array of units excluding units that overlap with streets.\r\n * @private\r\n *\r\n * @param {Array} unit_features - Array of features representing units.\r\n * @param {Array} street_layers - Array of Leaflet layers representing streets.\r\n * @returns {Array} - unit_features, but with all units that intersect any streets removed.\r\n */\n\n\nfunction unitsOutOfStreets(unit_features, street_layers) {\n var processed_unit_features = unit_features.slice();\n street_layers.eachLayer(function (street_layer) {\n var street_feature = street_layer.feature;\n var _iteratorNormalCompletion2 = true;\n var _didIteratorError2 = false;\n var _iteratorError2 = undefined;\n\n try {\n for (var _iterator2 = processed_unit_features[Symbol.iterator](), _step2; !(_iteratorNormalCompletion2 = (_step2 = _iterator2.next()).done); _iteratorNormalCompletion2 = true) {\n var unit_feature = _step2.value;\n var intersection_exists = lineIntersect(street_feature, unit_feature).features.length > 0;\n\n if (intersection_exists) {\n processed_unit_features.splice(processed_unit_features.indexOf(unit_feature), 1, null);\n }\n }\n } catch (err) {\n _didIteratorError2 = true;\n _iteratorError2 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion2 && _iterator2.return != null) {\n _iterator2.return();\n }\n } finally {\n if (_didIteratorError2) {\n throw _iteratorError2;\n }\n }\n }\n\n processed_unit_features = processed_unit_features.filter(function (feature) {\n return feature === null ? false : true;\n });\n });\n return processed_unit_features;\n}\n/**\r\n * Check whether a polygon overlaps with any member of an array of polygons.\r\n * @private\r\n *\r\n * @param {Feature} reference_polygon_feature - A geoJSON polygon feature.\r\n * @param {Array} polygon_feature_array - Array of geoJSON polygon features.\r\n * @returns {boolean} - Whether the polygon_feature overlaps with any one in the array.\r\n */\n\n\nfunction noOverlaps(reference_polygon_feature, polygon_feature_array) {\n var _iteratorNormalCompletion3 = true;\n var _didIteratorError3 = false;\n var _iteratorError3 = undefined;\n\n try {\n for (var _iterator3 = polygon_feature_array[Symbol.iterator](), _step3; !(_iteratorNormalCompletion3 = (_step3 = _iterator3.next()).done); _iteratorNormalCompletion3 = true) {\n feature_array_element = _step3.value;\n var overlap_exists = intersect(reference_polygon_feature, feature_array_element);\n\n if (overlap_exists) {\n return false;\n }\n }\n } catch (err) {\n _didIteratorError3 = true;\n _iteratorError3 = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion3 && _iterator3.return != null) {\n _iterator3.return();\n }\n } finally {\n if (_didIteratorError3) {\n throw _iteratorError3;\n }\n }\n }\n\n return true;\n}\n\nAgentmap.prototype.buildingify = buildingify;\nexports.buildingify = buildingify;\n\n//# sourceURL=webpack:///./src/buildings.js?')},function(module,exports,__webpack_require__){"use strict";eval('\r\nvar __importStar = (this && this.__importStar) || function (mod) {\r\n if (mod && mod.__esModule) return mod;\r\n var result = {};\r\n if (mod != null) for (var k in mod) if (Object.hasOwnProperty.call(mod, k)) result[k] = mod[k];\r\n result["default"] = mod;\r\n return result;\r\n};\r\nObject.defineProperty(exports, "__esModule", { value: true });\r\nvar helpers_1 = __webpack_require__(1);\r\nvar invariant_1 = __webpack_require__(2);\r\nvar martinez = __importStar(__webpack_require__(42));\r\n/**\r\n * Takes two {@link Polygon|polygon} or {@link MultiPolygon|multi-polygon} geometries and\r\n * finds their polygonal intersection. If they don\'t intersect, returns null.\r\n *\r\n * @name intersect\r\n * @param {Feature} poly1 the first polygon or multipolygon\r\n * @param {Feature} poly2 the second polygon or multipolygon\r\n * @param {Object} [options={}] Optional Parameters\r\n * @param {Object} [options.properties={}] Translate GeoJSON Properties to Feature\r\n * @returns {Feature|null} returns a feature representing the area they share (either a {@link Polygon} or\r\n * {@link MultiPolygon}). If they do not share any area, returns `null`.\r\n * @example\r\n * var poly1 = turf.polygon([[\r\n * [-122.801742, 45.48565],\r\n * [-122.801742, 45.60491],\r\n * [-122.584762, 45.60491],\r\n * [-122.584762, 45.48565],\r\n * [-122.801742, 45.48565]\r\n * ]]);\r\n *\r\n * var poly2 = turf.polygon([[\r\n * [-122.520217, 45.535693],\r\n * [-122.64038, 45.553967],\r\n * [-122.720031, 45.526554],\r\n * [-122.669906, 45.507309],\r\n * [-122.723464, 45.446643],\r\n * [-122.532577, 45.408574],\r\n * [-122.487258, 45.477466],\r\n * [-122.520217, 45.535693]\r\n * ]]);\r\n *\r\n * var intersection = turf.intersect(poly1, poly2);\r\n *\r\n * //addToMap\r\n * var addToMap = [poly1, poly2, intersection];\r\n */\r\nfunction intersect(poly1, poly2, options) {\r\n if (options === void 0) { options = {}; }\r\n var geom1 = invariant_1.getGeom(poly1);\r\n var geom2 = invariant_1.getGeom(poly2);\r\n if (geom1.type === "Polygon" && geom2.type === "Polygon") {\r\n var intersection = martinez.intersection(geom1.coordinates, geom2.coordinates);\r\n if (intersection === null || intersection.length === 0) {\r\n return null;\r\n }\r\n if (intersection.length === 1) {\r\n var start = intersection[0][0][0];\r\n var end = intersection[0][0][intersection[0][0].length - 1];\r\n if (start[0] === end[0] && start[1] === end[1]) {\r\n return helpers_1.polygon(intersection[0], options.properties);\r\n }\r\n return null;\r\n }\r\n return helpers_1.multiPolygon(intersection, options.properties);\r\n }\r\n else if (geom1.type === "MultiPolygon") {\r\n var resultCoords = [];\r\n // iterate through the polygon and run intersect with each part, adding to the resultCoords.\r\n for (var _i = 0, _a = geom1.coordinates; _i < _a.length; _i++) {\r\n var coords = _a[_i];\r\n var subGeom = invariant_1.getGeom(helpers_1.polygon(coords));\r\n var subIntersection = intersect(subGeom, geom2);\r\n if (subIntersection) {\r\n var subIntGeom = invariant_1.getGeom(subIntersection);\r\n if (subIntGeom.type === "Polygon") {\r\n resultCoords.push(subIntGeom.coordinates);\r\n }\r\n else if (subIntGeom.type === "MultiPolygon") {\r\n resultCoords = resultCoords.concat(subIntGeom.coordinates);\r\n }\r\n else {\r\n throw new Error("intersection is invalid");\r\n }\r\n }\r\n }\r\n // Make a polygon with the result\r\n if (resultCoords.length === 0) {\r\n return null;\r\n }\r\n if (resultCoords.length === 1) {\r\n return helpers_1.polygon(resultCoords[0], options.properties);\r\n }\r\n else {\r\n return helpers_1.multiPolygon(resultCoords, options.properties);\r\n }\r\n }\r\n else if (geom2.type === "MultiPolygon") {\r\n // geom1 is a polygon and geom2 a multiPolygon,\r\n // put the multiPolygon first and fallback to the previous case.\r\n return intersect(geom2, geom1);\r\n }\r\n else {\r\n // handle invalid geometry types\r\n throw new Error("poly1 and poly2 must be either polygons or multiPolygons");\r\n }\r\n}\r\nexports.default = intersect;\r\n\n\n//# sourceURL=webpack:///./node_modules/@turf/intersect/index.js?')},function(module,exports,__webpack_require__){eval("/**\n * martinez v0.4.3\n * Martinez polygon clipping algorithm, does boolean operation on polygons (multipolygons, polygons with holes etc): intersection, union, difference, xor\n *\n * @author Alex Milevski \n * @license MIT\n * @preserve\n */\n\n(function (global, factory) {\n true ? factory(exports) :\n undefined;\n}(this, (function (exports) { 'use strict';\n\n function DEFAULT_COMPARE (a, b) { return a > b ? 1 : a < b ? -1 : 0; }\n\n var SplayTree = function SplayTree(compare, noDuplicates) {\n if ( compare === void 0 ) compare = DEFAULT_COMPARE;\n if ( noDuplicates === void 0 ) noDuplicates = false;\n\n this._compare = compare;\n this._root = null;\n this._size = 0;\n this._noDuplicates = !!noDuplicates;\n };\n\n var prototypeAccessors = { size: { configurable: true } };\n\n\n SplayTree.prototype.rotateLeft = function rotateLeft (x) {\n var y = x.right;\n if (y) {\n x.right = y.left;\n if (y.left) { y.left.parent = x; }\n y.parent = x.parent;\n }\n\n if (!x.parent) { this._root = y; }\n else if (x === x.parent.left) { x.parent.left = y; }\n else { x.parent.right = y; }\n if (y) { y.left = x; }\n x.parent = y;\n };\n\n\n SplayTree.prototype.rotateRight = function rotateRight (x) {\n var y = x.left;\n if (y) {\n x.left = y.right;\n if (y.right) { y.right.parent = x; }\n y.parent = x.parent;\n }\n\n if (!x.parent) { this._root = y; }\n else if(x === x.parent.left) { x.parent.left = y; }\n else { x.parent.right = y; }\n if (y) { y.right = x; }\n x.parent = y;\n };\n\n\n SplayTree.prototype._splay = function _splay (x) {\n var this$1 = this;\n\n while (x.parent) {\n var p = x.parent;\n if (!p.parent) {\n if (p.left === x) { this$1.rotateRight(p); }\n else { this$1.rotateLeft(p); }\n } else if (p.left === x && p.parent.left === p) {\n this$1.rotateRight(p.parent);\n this$1.rotateRight(p);\n } else if (p.right === x && p.parent.right === p) {\n this$1.rotateLeft(p.parent);\n this$1.rotateLeft(p);\n } else if (p.left === x && p.parent.right === p) {\n this$1.rotateRight(p);\n this$1.rotateLeft(p);\n } else {\n this$1.rotateLeft(p);\n this$1.rotateRight(p);\n }\n }\n };\n\n\n SplayTree.prototype.splay = function splay (x) {\n var this$1 = this;\n\n var p, gp, ggp, l, r;\n\n while (x.parent) {\n p = x.parent;\n gp = p.parent;\n\n if (gp && gp.parent) {\n ggp = gp.parent;\n if (ggp.left === gp) { ggp.left= x; }\n else { ggp.right = x; }\n x.parent = ggp;\n } else {\n x.parent = null;\n this$1._root = x;\n }\n\n l = x.left; r = x.right;\n\n if (x === p.left) { // left\n if (gp) {\n if (gp.left === p) {\n /* zig-zig */\n if (p.right) {\n gp.left = p.right;\n gp.left.parent = gp;\n } else { gp.left = null; }\n\n p.right = gp;\n gp.parent = p;\n } else {\n /* zig-zag */\n if (l) {\n gp.right = l;\n l.parent = gp;\n } else { gp.right = null; }\n\n x.left = gp;\n gp.parent = x;\n }\n }\n if (r) {\n p.left = r;\n r.parent = p;\n } else { p.left = null; }\n\n x.right= p;\n p.parent = x;\n } else { // right\n if (gp) {\n if (gp.right === p) {\n /* zig-zig */\n if (p.left) {\n gp.right = p.left;\n gp.right.parent = gp;\n } else { gp.right = null; }\n\n p.left = gp;\n gp.parent = p;\n } else {\n /* zig-zag */\n if (r) {\n gp.left = r;\n r.parent = gp;\n } else { gp.left = null; }\n\n x.right = gp;\n gp.parent = x;\n }\n }\n if (l) {\n p.right = l;\n l.parent = p;\n } else { p.right = null; }\n\n x.left = p;\n p.parent = x;\n }\n }\n };\n\n\n SplayTree.prototype.replace = function replace (u, v) {\n if (!u.parent) { this._root = v; }\n else if (u === u.parent.left) { u.parent.left = v; }\n else { u.parent.right = v; }\n if (v) { v.parent = u.parent; }\n };\n\n\n SplayTree.prototype.minNode = function minNode (u) {\n if ( u === void 0 ) u = this._root;\n\n if (u) { while (u.left) { u = u.left; } }\n return u;\n };\n\n\n SplayTree.prototype.maxNode = function maxNode (u) {\n if ( u === void 0 ) u = this._root;\n\n if (u) { while (u.right) { u = u.right; } }\n return u;\n };\n\n\n SplayTree.prototype.insert = function insert (key, data) {\n var z = this._root;\n var p = null;\n var comp = this._compare;\n var cmp;\n\n if (this._noDuplicates) {\n while (z) {\n p = z;\n cmp = comp(z.key, key);\n if (cmp === 0) { return; }\n else if (comp(z.key, key) < 0) { z = z.right; }\n else { z = z.left; }\n }\n } else {\n while (z) {\n p = z;\n if (comp(z.key, key) < 0) { z = z.right; }\n else { z = z.left; }\n }\n }\n\n z = { key: key, data: data, left: null, right: null, parent: p };\n\n if (!p) { this._root = z; }\n else if (comp(p.key, z.key) < 0) { p.right = z; }\n else { p.left= z; }\n\n this.splay(z);\n this._size++;\n return z;\n };\n\n\n SplayTree.prototype.find = function find (key) {\n var z = this._root;\n var comp = this._compare;\n while (z) {\n var cmp = comp(z.key, key);\n if (cmp < 0) { z = z.right; }\n else if (cmp > 0) { z = z.left; }\n else { return z; }\n }\n return null;\n };\n\n /**\n * Whether the tree contains a node with the given key\n * @param{Key} key\n * @return {boolean} true/false\n */\n SplayTree.prototype.contains = function contains (key) {\n var node = this._root;\n var comparator = this._compare;\n while (node){\n var cmp = comparator(key, node.key);\n if (cmp === 0) { return true; }\n else if (cmp < 0) { node = node.left; }\n else { node = node.right; }\n }\n\n return false;\n };\n\n\n SplayTree.prototype.remove = function remove (key) {\n var z = this.find(key);\n\n if (!z) { return false; }\n\n this.splay(z);\n\n if (!z.left) { this.replace(z, z.right); }\n else if (!z.right) { this.replace(z, z.left); }\n else {\n var y = this.minNode(z.right);\n if (y.parent !== z) {\n this.replace(y, y.right);\n y.right = z.right;\n y.right.parent = y;\n }\n this.replace(z, y);\n y.left = z.left;\n y.left.parent = y;\n }\n\n this._size--;\n return true;\n };\n\n\n SplayTree.prototype.removeNode = function removeNode (z) {\n if (!z) { return false; }\n\n this.splay(z);\n\n if (!z.left) { this.replace(z, z.right); }\n else if (!z.right) { this.replace(z, z.left); }\n else {\n var y = this.minNode(z.right);\n if (y.parent !== z) {\n this.replace(y, y.right);\n y.right = z.right;\n y.right.parent = y;\n }\n this.replace(z, y);\n y.left = z.left;\n y.left.parent = y;\n }\n\n this._size--;\n return true;\n };\n\n\n SplayTree.prototype.erase = function erase (key) {\n var z = this.find(key);\n if (!z) { return; }\n\n this.splay(z);\n\n var s = z.left;\n var t = z.right;\n\n var sMax = null;\n if (s) {\n s.parent = null;\n sMax = this.maxNode(s);\n this.splay(sMax);\n this._root = sMax;\n }\n if (t) {\n if (s) { sMax.right = t; }\n else { this._root = t; }\n t.parent = sMax;\n }\n\n this._size--;\n };\n\n /**\n * Removes and returns the node with smallest key\n * @return {?Node}\n */\n SplayTree.prototype.pop = function pop () {\n var node = this._root, returnValue = null;\n if (node) {\n while (node.left) { node = node.left; }\n returnValue = { key: node.key, data: node.data };\n this.remove(node.key);\n }\n return returnValue;\n };\n\n\n /* eslint-disable class-methods-use-this */\n\n /**\n * Successor node\n * @param{Node} node\n * @return {?Node}\n */\n SplayTree.prototype.next = function next (node) {\n var successor = node;\n if (successor) {\n if (successor.right) {\n successor = successor.right;\n while (successor && successor.left) { successor = successor.left; }\n } else {\n successor = node.parent;\n while (successor && successor.right === node) {\n node = successor; successor = successor.parent;\n }\n }\n }\n return successor;\n };\n\n\n /**\n * Predecessor node\n * @param{Node} node\n * @return {?Node}\n */\n SplayTree.prototype.prev = function prev (node) {\n var predecessor = node;\n if (predecessor) {\n if (predecessor.left) {\n predecessor = predecessor.left;\n while (predecessor && predecessor.right) { predecessor = predecessor.right; }\n } else {\n predecessor = node.parent;\n while (predecessor && predecessor.left === node) {\n node = predecessor;\n predecessor = predecessor.parent;\n }\n }\n }\n return predecessor;\n };\n /* eslint-enable class-methods-use-this */\n\n\n /**\n * @param{forEachCallback} callback\n * @return {SplayTree}\n */\n SplayTree.prototype.forEach = function forEach (callback) {\n var current = this._root;\n var s = [], done = false, i = 0;\n\n while (!done) {\n // Reach the left most Node of the current Node\n if (current) {\n // Place pointer to a tree node on the stack\n // before traversing the node's left subtree\n s.push(current);\n current = current.left;\n } else {\n // BackTrack from the empty subtree and visit the Node\n // at the top of the stack; however, if the stack is\n // empty you are done\n if (s.length > 0) {\n current = s.pop();\n callback(current, i++);\n\n // We have visited the node and its left\n // subtree. Now, it's right subtree's turn\n current = current.right;\n } else { done = true; }\n }\n }\n return this;\n };\n\n\n /**\n * Walk key range from `low` to `high`. Stops if `fn` returns a value.\n * @param{Key} low\n * @param{Key} high\n * @param{Function} fn\n * @param{*?} ctx\n * @return {SplayTree}\n */\n SplayTree.prototype.range = function range (low, high, fn, ctx) {\n var this$1 = this;\n\n var Q = [];\n var compare = this._compare;\n var node = this._root, cmp;\n\n while (Q.length !== 0 || node) {\n if (node) {\n Q.push(node);\n node = node.left;\n } else {\n node = Q.pop();\n cmp = compare(node.key, high);\n if (cmp > 0) {\n break;\n } else if (compare(node.key, low) >= 0) {\n if (fn.call(ctx, node)) { return this$1; } // stop if smth is returned\n }\n node = node.right;\n }\n }\n return this;\n };\n\n /**\n * Returns all keys in order\n * @return {Array}\n */\n SplayTree.prototype.keys = function keys () {\n var current = this._root;\n var s = [], r = [], done = false;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n r.push(current.key);\n current = current.right;\n } else { done = true; }\n }\n }\n return r;\n };\n\n\n /**\n * Returns `data` fields of all nodes in order.\n * @return {Array}\n */\n SplayTree.prototype.values = function values () {\n var current = this._root;\n var s = [], r = [], done = false;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n r.push(current.data);\n current = current.right;\n } else { done = true; }\n }\n }\n return r;\n };\n\n\n /**\n * Returns node at given index\n * @param{number} index\n * @return {?Node}\n */\n SplayTree.prototype.at = function at (index) {\n // removed after a consideration, more misleading than useful\n // index = index % this.size;\n // if (index < 0) index = this.size - index;\n\n var current = this._root;\n var s = [], done = false, i = 0;\n\n while (!done) {\n if (current) {\n s.push(current);\n current = current.left;\n } else {\n if (s.length > 0) {\n current = s.pop();\n if (i === index) { return current; }\n i++;\n current = current.right;\n } else { done = true; }\n }\n }\n return null;\n };\n\n /**\n * Bulk-load items. Both array have to be same size\n * @param{Array} keys\n * @param{Array}[values]\n * @param{Boolean} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @return {AVLTree}\n */\n SplayTree.prototype.load = function load (keys, values, presort) {\n if ( keys === void 0 ) keys = [];\n if ( values === void 0 ) values = [];\n if ( presort === void 0 ) presort = false;\n\n if (this._size !== 0) { throw new Error('bulk-load: tree is not empty'); }\n var size = keys.length;\n if (presort) { sort(keys, values, 0, size - 1, this._compare); }\n this._root = loadRecursive(null, keys, values, 0, size);\n this._size = size;\n return this;\n };\n\n\n SplayTree.prototype.min = function min () {\n var node = this.minNode(this._root);\n if (node) { return node.key; }\n else { return null; }\n };\n\n\n SplayTree.prototype.max = function max () {\n var node = this.maxNode(this._root);\n if (node) { return node.key; }\n else { return null; }\n };\n\n SplayTree.prototype.isEmpty = function isEmpty () { return this._root === null; };\n prototypeAccessors.size.get = function () { return this._size; };\n\n\n /**\n * Create a tree and load it with items\n * @param{Array} keys\n * @param{Array?} [values]\n\n * @param{Function?} [comparator]\n * @param{Boolean?} [presort=false] Pre-sort keys and values, using\n * tree's comparator. Sorting is done\n * in-place\n * @param{Boolean?} [noDuplicates=false] Allow duplicates\n * @return {SplayTree}\n */\n SplayTree.createTree = function createTree (keys, values, comparator, presort, noDuplicates) {\n return new SplayTree(comparator, noDuplicates).load(keys, values, presort);\n };\n\n Object.defineProperties( SplayTree.prototype, prototypeAccessors );\n\n\n function loadRecursive (parent, keys, values, start, end) {\n var size = end - start;\n if (size > 0) {\n var middle = start + Math.floor(size / 2);\n var key = keys[middle];\n var data = values[middle];\n var node = { key: key, data: data, parent: parent };\n node.left = loadRecursive(node, keys, values, start, middle);\n node.right = loadRecursive(node, keys, values, middle + 1, end);\n return node;\n }\n return null;\n }\n\n\n function sort(keys, values, left, right, compare) {\n if (left >= right) { return; }\n\n var pivot = keys[(left + right) >> 1];\n var i = left - 1;\n var j = right + 1;\n\n while (true) {\n do { i++; } while (compare(keys[i], pivot) < 0);\n do { j--; } while (compare(keys[j], pivot) > 0);\n if (i >= j) { break; }\n\n var tmp = keys[i];\n keys[i] = keys[j];\n keys[j] = tmp;\n\n tmp = values[i];\n values[i] = values[j];\n values[j] = tmp;\n }\n\n sort(keys, values, left, j, compare);\n sort(keys, values, j + 1, right, compare);\n }\n\n var NORMAL = 0;\n var NON_CONTRIBUTING = 1;\n var SAME_TRANSITION = 2;\n var DIFFERENT_TRANSITION = 3;\n\n var INTERSECTION = 0;\n var UNION = 1;\n var DIFFERENCE = 2;\n var XOR = 3;\n\n /**\n * @param {SweepEvent} event\n * @param {SweepEvent} prev\n * @param {Operation} operation\n */\n function computeFields (event, prev, operation) {\n // compute inOut and otherInOut fields\n if (prev === null) {\n event.inOut = false;\n event.otherInOut = true;\n\n // previous line segment in sweepline belongs to the same polygon\n } else {\n if (event.isSubject === prev.isSubject) {\n event.inOut = !prev.inOut;\n event.otherInOut = prev.otherInOut;\n\n // previous line segment in sweepline belongs to the clipping polygon\n } else {\n event.inOut = !prev.otherInOut;\n event.otherInOut = prev.isVertical() ? !prev.inOut : prev.inOut;\n }\n\n // compute prevInResult field\n if (prev) {\n event.prevInResult = (!inResult(prev, operation) || prev.isVertical())\n ? prev.prevInResult : prev;\n }\n }\n\n // check if the line segment belongs to the Boolean operation\n event.inResult = inResult(event, operation);\n }\n\n\n /* eslint-disable indent */\n function inResult(event, operation) {\n switch (event.type) {\n case NORMAL:\n switch (operation) {\n case INTERSECTION:\n return !event.otherInOut;\n case UNION:\n return event.otherInOut;\n case DIFFERENCE:\n // return (event.isSubject && !event.otherInOut) ||\n // (!event.isSubject && event.otherInOut);\n return (event.isSubject && event.otherInOut) ||\n (!event.isSubject && !event.otherInOut);\n case XOR:\n return true;\n }\n break;\n case SAME_TRANSITION:\n return operation === INTERSECTION || operation === UNION;\n case DIFFERENT_TRANSITION:\n return operation === DIFFERENCE;\n case NON_CONTRIBUTING:\n return false;\n }\n return false;\n }\n /* eslint-enable indent */\n\n var SweepEvent = function SweepEvent (point, left, otherEvent, isSubject, edgeType) {\n\n /**\n * Is left endpoint?\n * @type {Boolean}\n */\n this.left = left;\n\n /**\n * @type {Array.}\n */\n this.point = point;\n\n /**\n * Other edge reference\n * @type {SweepEvent}\n */\n this.otherEvent = otherEvent;\n\n /**\n * Belongs to source or clipping polygon\n * @type {Boolean}\n */\n this.isSubject = isSubject;\n\n /**\n * Edge contribution type\n * @type {Number}\n */\n this.type = edgeType || NORMAL;\n\n\n /**\n * In-out transition for the sweepline crossing polygon\n * @type {Boolean}\n */\n this.inOut = false;\n\n\n /**\n * @type {Boolean}\n */\n this.otherInOut = false;\n\n /**\n * Previous event in result?\n * @type {SweepEvent}\n */\n this.prevInResult = null;\n\n /**\n * Does event belong to result?\n * @type {Boolean}\n */\n this.inResult = false;\n\n\n // connection step\n\n /**\n * @type {Boolean}\n */\n this.resultInOut = false;\n\n this.isExteriorRing = true;\n };\n\n\n /**\n * @param{Array.}p\n * @return {Boolean}\n */\n SweepEvent.prototype.isBelow = function isBelow (p) {\n var p0 = this.point, p1 = this.otherEvent.point;\n return this.left\n ? (p0[0] - p[0]) * (p1[1] - p[1]) - (p1[0] - p[0]) * (p0[1] - p[1]) > 0\n // signedArea(this.point, this.otherEvent.point, p) > 0 :\n : (p1[0] - p[0]) * (p0[1] - p[1]) - (p0[0] - p[0]) * (p1[1] - p[1]) > 0;\n //signedArea(this.otherEvent.point, this.point, p) > 0;\n };\n\n\n /**\n * @param{Array.}p\n * @return {Boolean}\n */\n SweepEvent.prototype.isAbove = function isAbove (p) {\n return !this.isBelow(p);\n };\n\n\n /**\n * @return {Boolean}\n */\n SweepEvent.prototype.isVertical = function isVertical () {\n return this.point[0] === this.otherEvent.point[0];\n };\n\n\n SweepEvent.prototype.clone = function clone () {\n var copy = new SweepEvent(\n this.point, this.left, this.otherEvent, this.isSubject, this.type);\n\n copy.inResult = this.inResult;\n copy.prevInResult = this.prevInResult;\n copy.isExteriorRing = this.isExteriorRing;\n copy.inOut = this.inOut;\n copy.otherInOut = this.otherInOut;\n\n return copy;\n };\n\n function equals(p1, p2) {\n if (p1[0] === p2[0]) {\n if (p1[1] === p2[1]) {\n return true;\n } else {\n return false;\n }\n }\n return false;\n }\n\n // const EPSILON = 1e-9;\n // const abs = Math.abs;\n // TODO https://github.com/w8r/martinez/issues/6#issuecomment-262847164\n // Precision problem.\n //\n // module.exports = function equals(p1, p2) {\n // return abs(p1[0] - p2[0]) <= EPSILON && abs(p1[1] - p2[1]) <= EPSILON;\n // };\n\n /**\n * Signed area of the triangle (p0, p1, p2)\n * @param {Array.} p0\n * @param {Array.} p1\n * @param {Array.} p2\n * @return {Number}\n */\n function signedArea(p0, p1, p2) {\n return (p0[0] - p2[0]) * (p1[1] - p2[1]) - (p1[0] - p2[0]) * (p0[1] - p2[1]);\n }\n\n /**\n * @param {SweepEvent} e1\n * @param {SweepEvent} e2\n * @return {Number}\n */\n function compareEvents(e1, e2) {\n var p1 = e1.point;\n var p2 = e2.point;\n\n // Different x-coordinate\n if (p1[0] > p2[0]) { return 1; }\n if (p1[0] < p2[0]) { return -1; }\n\n // Different points, but same x-coordinate\n // Event with lower y-coordinate is processed first\n if (p1[1] !== p2[1]) { return p1[1] > p2[1] ? 1 : -1; }\n\n return specialCases(e1, e2, p1, p2);\n }\n\n\n /* eslint-disable no-unused-vars */\n function specialCases(e1, e2, p1, p2) {\n // Same coordinates, but one is a left endpoint and the other is\n // a right endpoint. The right endpoint is processed first\n if (e1.left !== e2.left)\n { return e1.left ? 1 : -1; }\n\n // const p2 = e1.otherEvent.point, p3 = e2.otherEvent.point;\n // const sa = (p1[0] - p3[0]) * (p2[1] - p3[1]) - (p2[0] - p3[0]) * (p1[1] - p3[1])\n // Same coordinates, both events\n // are left endpoints or right endpoints.\n // not collinear\n if (signedArea(p1, e1.otherEvent.point, e2.otherEvent.point) !== 0) {\n // the event associate to the bottom segment is processed first\n return (!e1.isBelow(e2.otherEvent.point)) ? 1 : -1;\n }\n\n return (!e1.isSubject && e2.isSubject) ? 1 : -1;\n }\n /* eslint-enable no-unused-vars */\n\n /**\n * @param {SweepEvent} se\n * @param {Array.} p\n * @param {Queue} queue\n * @return {Queue}\n */\n function divideSegment(se, p, queue) {\n var r = new SweepEvent(p, false, se, se.isSubject);\n var l = new SweepEvent(p, true, se.otherEvent, se.isSubject);\n\n /* eslint-disable no-console */\n if (equals(se.point, se.otherEvent.point)) {\n\n console.warn('what is that, a collapsed segment?', se);\n }\n /* eslint-enable no-console */\n\n r.contourId = l.contourId = se.contourId;\n\n // avoid a rounding error. The left event would be processed after the right event\n if (compareEvents(l, se.otherEvent) > 0) {\n se.otherEvent.left = true;\n l.left = false;\n }\n\n // avoid a rounding error. The left event would be processed after the right event\n // if (compareEvents(se, r) > 0) {}\n\n se.otherEvent.otherEvent = l;\n se.otherEvent = r;\n\n queue.push(l);\n queue.push(r);\n\n return queue;\n }\n\n //const EPS = 1e-9;\n\n /**\n * Finds the magnitude of the cross product of two vectors (if we pretend\n * they're in three dimensions)\n *\n * @param {Object} a First vector\n * @param {Object} b Second vector\n * @private\n * @returns {Number} The magnitude of the cross product\n */\n function crossProduct(a, b) {\n return (a[0] * b[1]) - (a[1] * b[0]);\n }\n\n /**\n * Finds the dot product of two vectors.\n *\n * @param {Object} a First vector\n * @param {Object} b Second vector\n * @private\n * @returns {Number} The dot product\n */\n function dotProduct(a, b) {\n return (a[0] * b[0]) + (a[1] * b[1]);\n }\n\n /**\n * Finds the intersection (if any) between two line segments a and b, given the\n * line segments' end points a1, a2 and b1, b2.\n *\n * This algorithm is based on Schneider and Eberly.\n * http://www.cimec.org.ar/~ncalvo/Schneider_Eberly.pdf\n * Page 244.\n *\n * @param {Array.} a1 point of first line\n * @param {Array.} a2 point of first line\n * @param {Array.} b1 point of second line\n * @param {Array.} b2 point of second line\n * @param {Boolean=} noEndpointTouch whether to skip single touchpoints\n * (meaning connected segments) as\n * intersections\n * @returns {Array.>|Null} If the lines intersect, the point of\n * intersection. If they overlap, the two end points of the overlapping segment.\n * Otherwise, null.\n */\n function intersection (a1, a2, b1, b2, noEndpointTouch) {\n // The algorithm expects our lines in the form P + sd, where P is a point,\n // s is on the interval [0, 1], and d is a vector.\n // We are passed two points. P can be the first point of each pair. The\n // vector, then, could be thought of as the distance (in x and y components)\n // from the first point to the second point.\n // So first, let's make our vectors:\n var va = [a2[0] - a1[0], a2[1] - a1[1]];\n var vb = [b2[0] - b1[0], b2[1] - b1[1]];\n // We also define a function to convert back to regular point form:\n\n /* eslint-disable arrow-body-style */\n\n function toPoint(p, s, d) {\n return [\n p[0] + s * d[0],\n p[1] + s * d[1]\n ];\n }\n\n /* eslint-enable arrow-body-style */\n\n // The rest is pretty much a straight port of the algorithm.\n var e = [b1[0] - a1[0], b1[1] - a1[1]];\n var kross = crossProduct(va, vb);\n var sqrKross = kross * kross;\n var sqrLenA = dotProduct(va, va);\n //const sqrLenB = dotProduct(vb, vb);\n\n // Check for line intersection. This works because of the properties of the\n // cross product -- specifically, two vectors are parallel if and only if the\n // cross product is the 0 vector. The full calculation involves relative error\n // to account for possible very small line segments. See Schneider & Eberly\n // for details.\n if (sqrKross > 0/* EPS * sqrLenB * sqLenA */) {\n // If they're not parallel, then (because these are line segments) they\n // still might not actually intersect. This code checks that the\n // intersection point of the lines is actually on both line segments.\n var s = crossProduct(e, vb) / kross;\n if (s < 0 || s > 1) {\n // not on line segment a\n return null;\n }\n var t = crossProduct(e, va) / kross;\n if (t < 0 || t > 1) {\n // not on line segment b\n return null;\n }\n if (s === 0 || s === 1) {\n // on an endpoint of line segment a\n return noEndpointTouch ? null : [toPoint(a1, s, va)];\n }\n if (t === 0 || t === 1) {\n // on an endpoint of line segment b\n return noEndpointTouch ? null : [toPoint(b1, t, vb)];\n }\n return [toPoint(a1, s, va)];\n }\n\n // If we've reached this point, then the lines are either parallel or the\n // same, but the segments could overlap partially or fully, or not at all.\n // So we need to find the overlap, if any. To do that, we can use e, which is\n // the (vector) difference between the two initial points. If this is parallel\n // with the line itself, then the two lines are the same line, and there will\n // be overlap.\n //const sqrLenE = dotProduct(e, e);\n kross = crossProduct(e, va);\n sqrKross = kross * kross;\n\n if (sqrKross > 0 /* EPS * sqLenB * sqLenE */) {\n // Lines are just parallel, not the same. No overlap.\n return null;\n }\n\n var sa = dotProduct(va, e) / sqrLenA;\n var sb = sa + dotProduct(va, vb) / sqrLenA;\n var smin = Math.min(sa, sb);\n var smax = Math.max(sa, sb);\n\n // this is, essentially, the FindIntersection acting on floats from\n // Schneider & Eberly, just inlined into this function.\n if (smin <= 1 && smax >= 0) {\n\n // overlap on an end point\n if (smin === 1) {\n return noEndpointTouch ? null : [toPoint(a1, smin > 0 ? smin : 0, va)];\n }\n\n if (smax === 0) {\n return noEndpointTouch ? null : [toPoint(a1, smax < 1 ? smax : 1, va)];\n }\n\n if (noEndpointTouch && smin === 0 && smax === 1) { return null; }\n\n // There's overlap on a segment -- two points of intersection. Return both.\n return [\n toPoint(a1, smin > 0 ? smin : 0, va),\n toPoint(a1, smax < 1 ? smax : 1, va)\n ];\n }\n\n return null;\n }\n\n /**\n * @param {SweepEvent} se1\n * @param {SweepEvent} se2\n * @param {Queue} queue\n * @return {Number}\n */\n function possibleIntersection (se1, se2, queue) {\n // that disallows self-intersecting polygons,\n // did cost us half a day, so I'll leave it\n // out of respect\n // if (se1.isSubject === se2.isSubject) return;\n var inter = intersection(\n se1.point, se1.otherEvent.point,\n se2.point, se2.otherEvent.point\n );\n\n var nintersections = inter ? inter.length : 0;\n if (nintersections === 0) { return 0; } // no intersection\n\n // the line segments intersect at an endpoint of both line segments\n if ((nintersections === 1) &&\n (equals(se1.point, se2.point) ||\n equals(se1.otherEvent.point, se2.otherEvent.point))) {\n return 0;\n }\n\n if (nintersections === 2 && se1.isSubject === se2.isSubject) {\n // if(se1.contourId === se2.contourId){\n // console.warn('Edges of the same polygon overlap',\n // se1.point, se1.otherEvent.point, se2.point, se2.otherEvent.point);\n // }\n //throw new Error('Edges of the same polygon overlap');\n return 0;\n }\n\n // The line segments associated to se1 and se2 intersect\n if (nintersections === 1) {\n\n // if the intersection point is not an endpoint of se1\n if (!equals(se1.point, inter[0]) && !equals(se1.otherEvent.point, inter[0])) {\n divideSegment(se1, inter[0], queue);\n }\n\n // if the intersection point is not an endpoint of se2\n if (!equals(se2.point, inter[0]) && !equals(se2.otherEvent.point, inter[0])) {\n divideSegment(se2, inter[0], queue);\n }\n return 1;\n }\n\n // The line segments associated to se1 and se2 overlap\n var events = [];\n var leftCoincide = false;\n var rightCoincide = false;\n\n if (equals(se1.point, se2.point)) {\n leftCoincide = true; // linked\n } else if (compareEvents(se1, se2) === 1) {\n events.push(se2, se1);\n } else {\n events.push(se1, se2);\n }\n\n if (equals(se1.otherEvent.point, se2.otherEvent.point)) {\n rightCoincide = true;\n } else if (compareEvents(se1.otherEvent, se2.otherEvent) === 1) {\n events.push(se2.otherEvent, se1.otherEvent);\n } else {\n events.push(se1.otherEvent, se2.otherEvent);\n }\n\n if ((leftCoincide && rightCoincide) || leftCoincide) {\n // both line segments are equal or share the left endpoint\n se2.type = NON_CONTRIBUTING;\n se1.type = (se2.inOut === se1.inOut)\n ? SAME_TRANSITION : DIFFERENT_TRANSITION;\n\n if (leftCoincide && !rightCoincide) {\n // honestly no idea, but changing events selection from [2, 1]\n // to [0, 1] fixes the overlapping self-intersecting polygons issue\n divideSegment(events[1].otherEvent, events[0].point, queue);\n }\n return 2;\n }\n\n // the line segments share the right endpoint\n if (rightCoincide) {\n divideSegment(events[0], events[1].point, queue);\n return 3;\n }\n\n // no line segment includes totally the other one\n if (events[0] !== events[3].otherEvent) {\n divideSegment(events[0], events[1].point, queue);\n divideSegment(events[1], events[2].point, queue);\n return 3;\n }\n\n // one line segment includes the other one\n divideSegment(events[0], events[1].point, queue);\n divideSegment(events[3].otherEvent, events[2].point, queue);\n\n return 3;\n }\n\n /**\n * @param {SweepEvent} le1\n * @param {SweepEvent} le2\n * @return {Number}\n */\n function compareSegments(le1, le2) {\n if (le1 === le2) { return 0; }\n\n // Segments are not collinear\n if (signedArea(le1.point, le1.otherEvent.point, le2.point) !== 0 ||\n signedArea(le1.point, le1.otherEvent.point, le2.otherEvent.point) !== 0) {\n\n // If they share their left endpoint use the right endpoint to sort\n if (equals(le1.point, le2.point)) { return le1.isBelow(le2.otherEvent.point) ? -1 : 1; }\n\n // Different left endpoint: use the left endpoint to sort\n if (le1.point[0] === le2.point[0]) { return le1.point[1] < le2.point[1] ? -1 : 1; }\n\n // has the line segment associated to e1 been inserted\n // into S after the line segment associated to e2 ?\n if (compareEvents(le1, le2) === 1) { return le2.isAbove(le1.point) ? -1 : 1; }\n\n // The line segment associated to e2 has been inserted\n // into S after the line segment associated to e1\n return le1.isBelow(le2.point) ? -1 : 1;\n }\n\n if (le1.isSubject === le2.isSubject) { // same polygon\n var p1 = le1.point, p2 = le2.point;\n if (p1[0] === p2[0] && p1[1] === p2[1]/*equals(le1.point, le2.point)*/) {\n p1 = le1.otherEvent.point; p2 = le2.otherEvent.point;\n if (p1[0] === p2[0] && p1[1] === p2[1]) { return 0; }\n else { return le1.contourId > le2.contourId ? 1 : -1; }\n }\n } else { // Segments are collinear, but belong to separate polygons\n return le1.isSubject ? -1 : 1;\n }\n\n return compareEvents(le1, le2) === 1 ? 1 : -1;\n }\n\n function subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation) {\n var sweepLine = new SplayTree(compareSegments);\n var sortedEvents = [];\n\n var rightbound = Math.min(sbbox[2], cbbox[2]);\n\n var prev, next, begin;\n\n while (eventQueue.length !== 0) {\n var event = eventQueue.pop();\n sortedEvents.push(event);\n\n // optimization by bboxes for intersection and difference goes here\n if ((operation === INTERSECTION && event.point[0] > rightbound) ||\n (operation === DIFFERENCE && event.point[0] > sbbox[2])) {\n break;\n }\n\n if (event.left) {\n next = prev = sweepLine.insert(event);\n begin = sweepLine.minNode();\n\n if (prev !== begin) { prev = sweepLine.prev(prev); }\n else { prev = null; }\n\n next = sweepLine.next(next);\n\n var prevEvent = prev ? prev.key : null;\n var prevprevEvent = (void 0);\n computeFields(event, prevEvent, operation);\n if (next) {\n if (possibleIntersection(event, next.key, eventQueue) === 2) {\n computeFields(event, prevEvent, operation);\n computeFields(event, next.key, operation);\n }\n }\n\n if (prev) {\n if (possibleIntersection(prev.key, event, eventQueue) === 2) {\n var prevprev = prev;\n if (prevprev !== begin) { prevprev = sweepLine.prev(prevprev); }\n else { prevprev = null; }\n\n prevprevEvent = prevprev ? prevprev.key : null;\n computeFields(prevEvent, prevprevEvent, operation);\n computeFields(event, prevEvent, operation);\n }\n }\n } else {\n event = event.otherEvent;\n next = prev = sweepLine.find(event);\n\n if (prev && next) {\n\n if (prev !== begin) { prev = sweepLine.prev(prev); }\n else { prev = null; }\n\n next = sweepLine.next(next);\n sweepLine.remove(event);\n\n if (next && prev) {\n possibleIntersection(prev.key, next.key, eventQueue);\n }\n }\n }\n }\n return sortedEvents;\n }\n\n /**\n * @param {Array.} sortedEvents\n * @return {Array.}\n */\n function orderEvents(sortedEvents) {\n var event, i, len, tmp;\n var resultEvents = [];\n for (i = 0, len = sortedEvents.length; i < len; i++) {\n event = sortedEvents[i];\n if ((event.left && event.inResult) ||\n (!event.left && event.otherEvent.inResult)) {\n resultEvents.push(event);\n }\n }\n // Due to overlapping edges the resultEvents array can be not wholly sorted\n var sorted = false;\n while (!sorted) {\n sorted = true;\n for (i = 0, len = resultEvents.length; i < len; i++) {\n if ((i + 1) < len &&\n compareEvents(resultEvents[i], resultEvents[i + 1]) === 1) {\n tmp = resultEvents[i];\n resultEvents[i] = resultEvents[i + 1];\n resultEvents[i + 1] = tmp;\n sorted = false;\n }\n }\n }\n\n\n for (i = 0, len = resultEvents.length; i < len; i++) {\n event = resultEvents[i];\n event.pos = i;\n }\n\n // imagine, the right event is found in the beginning of the queue,\n // when his left counterpart is not marked yet\n for (i = 0, len = resultEvents.length; i < len; i++) {\n event = resultEvents[i];\n if (!event.left) {\n tmp = event.pos;\n event.pos = event.otherEvent.pos;\n event.otherEvent.pos = tmp;\n }\n }\n\n return resultEvents;\n }\n\n\n /**\n * @param {Number} pos\n * @param {Array.} resultEvents\n * @param {Object>} processed\n * @return {Number}\n */\n function nextPos(pos, resultEvents, processed, origIndex) {\n var newPos = pos + 1;\n var length = resultEvents.length;\n if (newPos > length - 1) { return pos - 1; }\n var p = resultEvents[pos].point;\n var p1 = resultEvents[newPos].point;\n\n\n // while in range and not the current one by value\n while (newPos < length && p1[0] === p[0] && p1[1] === p[1]) {\n if (!processed[newPos]) {\n return newPos;\n } else {\n newPos++;\n }\n p1 = resultEvents[newPos].point;\n }\n\n newPos = pos - 1;\n\n while (processed[newPos] && newPos >= origIndex) {\n newPos--;\n }\n return newPos;\n }\n\n\n /**\n * @param {Array.} sortedEvents\n * @return {Array.<*>} polygons\n */\n function connectEdges(sortedEvents, operation) {\n var i, len;\n var resultEvents = orderEvents(sortedEvents);\n\n // \"false\"-filled array\n var processed = {};\n var result = [];\n var event;\n\n for (i = 0, len = resultEvents.length; i < len; i++) {\n if (processed[i]) { continue; }\n var contour = [[]];\n\n if (!resultEvents[i].isExteriorRing) {\n if (operation === DIFFERENCE && !resultEvents[i].isSubject && result.length === 0) {\n result.push(contour);\n } else if (result.length === 0) {\n result.push([[contour]]);\n } else {\n result[result.length - 1].push(contour[0]);\n }\n } else if (operation === DIFFERENCE && !resultEvents[i].isSubject && result.length > 1) {\n result[result.length - 1].push(contour[0]);\n } else {\n result.push(contour);\n }\n\n var ringId = result.length - 1;\n var pos = i;\n\n var initial = resultEvents[i].point;\n contour[0].push(initial);\n\n while (pos >= i) {\n event = resultEvents[pos];\n processed[pos] = true;\n\n if (event.left) {\n event.resultInOut = false;\n event.contourId = ringId;\n } else {\n event.otherEvent.resultInOut = true;\n event.otherEvent.contourId = ringId;\n }\n\n pos = event.pos;\n processed[pos] = true;\n contour[0].push(resultEvents[pos].point);\n pos = nextPos(pos, resultEvents, processed, i);\n }\n\n pos = pos === -1 ? i : pos;\n\n event = resultEvents[pos];\n processed[pos] = processed[event.pos] = true;\n event.otherEvent.resultInOut = true;\n event.otherEvent.contourId = ringId;\n }\n\n // Handle if the result is a polygon (eg not multipoly)\n // Commented it again, let's see what do we mean by that\n // if (result.length === 1) result = result[0];\n return result;\n }\n\n var tinyqueue = TinyQueue;\n var default_1 = TinyQueue;\n\n function TinyQueue(data, compare) {\n var this$1 = this;\n\n if (!(this instanceof TinyQueue)) { return new TinyQueue(data, compare); }\n\n this.data = data || [];\n this.length = this.data.length;\n this.compare = compare || defaultCompare;\n\n if (this.length > 0) {\n for (var i = (this.length >> 1) - 1; i >= 0; i--) { this$1._down(i); }\n }\n }\n\n function defaultCompare(a, b) {\n return a < b ? -1 : a > b ? 1 : 0;\n }\n\n TinyQueue.prototype = {\n\n push: function (item) {\n this.data.push(item);\n this.length++;\n this._up(this.length - 1);\n },\n\n pop: function () {\n if (this.length === 0) { return undefined; }\n\n var top = this.data[0];\n this.length--;\n\n if (this.length > 0) {\n this.data[0] = this.data[this.length];\n this._down(0);\n }\n this.data.pop();\n\n return top;\n },\n\n peek: function () {\n return this.data[0];\n },\n\n _up: function (pos) {\n var data = this.data;\n var compare = this.compare;\n var item = data[pos];\n\n while (pos > 0) {\n var parent = (pos - 1) >> 1;\n var current = data[parent];\n if (compare(item, current) >= 0) { break; }\n data[pos] = current;\n pos = parent;\n }\n\n data[pos] = item;\n },\n\n _down: function (pos) {\n var this$1 = this;\n\n var data = this.data;\n var compare = this.compare;\n var halfLength = this.length >> 1;\n var item = data[pos];\n\n while (pos < halfLength) {\n var left = (pos << 1) + 1;\n var right = left + 1;\n var best = data[left];\n\n if (right < this$1.length && compare(data[right], best) < 0) {\n left = right;\n best = data[right];\n }\n if (compare(best, item) >= 0) { break; }\n\n data[pos] = best;\n pos = left;\n }\n\n data[pos] = item;\n }\n };\n tinyqueue.default = default_1;\n\n var max = Math.max;\n var min = Math.min;\n\n var contourId = 0;\n\n\n function processPolygon(contourOrHole, isSubject, depth, Q, bbox, isExteriorRing) {\n var i, len, s1, s2, e1, e2;\n for (i = 0, len = contourOrHole.length - 1; i < len; i++) {\n s1 = contourOrHole[i];\n s2 = contourOrHole[i + 1];\n e1 = new SweepEvent(s1, false, undefined, isSubject);\n e2 = new SweepEvent(s2, false, e1, isSubject);\n e1.otherEvent = e2;\n\n if (s1[0] === s2[0] && s1[1] === s2[1]) {\n continue; // skip collapsed edges, or it breaks\n }\n\n e1.contourId = e2.contourId = depth;\n if (!isExteriorRing) {\n e1.isExteriorRing = false;\n e2.isExteriorRing = false;\n }\n if (compareEvents(e1, e2) > 0) {\n e2.left = true;\n } else {\n e1.left = true;\n }\n\n var x = s1[0], y = s1[1];\n bbox[0] = min(bbox[0], x);\n bbox[1] = min(bbox[1], y);\n bbox[2] = max(bbox[2], x);\n bbox[3] = max(bbox[3], y);\n\n // Pushing it so the queue is sorted from left to right,\n // with object on the left having the highest priority.\n Q.push(e1);\n Q.push(e2);\n }\n }\n\n\n function fillQueue(subject, clipping, sbbox, cbbox, operation) {\n var eventQueue = new tinyqueue(null, compareEvents);\n var polygonSet, isExteriorRing, i, ii, j, jj; //, k, kk;\n\n for (i = 0, ii = subject.length; i < ii; i++) {\n polygonSet = subject[i];\n for (j = 0, jj = polygonSet.length; j < jj; j++) {\n isExteriorRing = j === 0;\n if (isExteriorRing) { contourId++; }\n processPolygon(polygonSet[j], true, contourId, eventQueue, sbbox, isExteriorRing);\n }\n }\n\n for (i = 0, ii = clipping.length; i < ii; i++) {\n polygonSet = clipping[i];\n for (j = 0, jj = polygonSet.length; j < jj; j++) {\n isExteriorRing = j === 0;\n if (operation === DIFFERENCE) { isExteriorRing = false; }\n if (isExteriorRing) { contourId++; }\n processPolygon(polygonSet[j], false, contourId, eventQueue, cbbox, isExteriorRing);\n }\n }\n\n return eventQueue;\n }\n\n var EMPTY = [];\n\n\n function trivialOperation(subject, clipping, operation) {\n var result = null;\n if (subject.length * clipping.length === 0) {\n if (operation === INTERSECTION) {\n result = EMPTY;\n } else if (operation === DIFFERENCE) {\n result = subject;\n } else if (operation === UNION ||\n operation === XOR) {\n result = (subject.length === 0) ? clipping : subject;\n }\n }\n return result;\n }\n\n\n function compareBBoxes(subject, clipping, sbbox, cbbox, operation) {\n var result = null;\n if (sbbox[0] > cbbox[2] ||\n cbbox[0] > sbbox[2] ||\n sbbox[1] > cbbox[3] ||\n cbbox[1] > sbbox[3]) {\n if (operation === INTERSECTION) {\n result = EMPTY;\n } else if (operation === DIFFERENCE) {\n result = subject;\n } else if (operation === UNION ||\n operation === XOR) {\n result = subject.concat(clipping);\n }\n }\n return result;\n }\n\n\n function boolean(subject, clipping, operation) {\n if (typeof subject[0][0][0] === 'number') {\n subject = [subject];\n }\n if (typeof clipping[0][0][0] === 'number') {\n clipping = [clipping];\n }\n var trivial = trivialOperation(subject, clipping, operation);\n if (trivial) {\n return trivial === EMPTY ? null : trivial;\n }\n var sbbox = [Infinity, Infinity, -Infinity, -Infinity];\n var cbbox = [Infinity, Infinity, -Infinity, -Infinity];\n\n //console.time('fill queue');\n var eventQueue = fillQueue(subject, clipping, sbbox, cbbox, operation);\n //console.timeEnd('fill queue');\n\n trivial = compareBBoxes(subject, clipping, sbbox, cbbox, operation);\n if (trivial) {\n return trivial === EMPTY ? null : trivial;\n }\n //console.time('subdivide edges');\n var sortedEvents = subdivide(eventQueue, subject, clipping, sbbox, cbbox, operation);\n //console.timeEnd('subdivide edges');\n\n //console.time('connect vertices');\n var result = connectEdges(sortedEvents, operation);\n //console.timeEnd('connect vertices');\n return result;\n }\n\n function union (subject, clipping) {\n return boolean(subject, clipping, UNION);\n }\n\n function diff (subject, clipping) {\n return boolean(subject, clipping, DIFFERENCE);\n }\n\n function xor (subject, clipping){\n return boolean(subject, clipping, XOR);\n }\n\n function intersection$1 (subject, clipping) {\n return boolean(subject, clipping, INTERSECTION);\n }\n\n /**\n * @enum {Number}\n */\n var operations = { UNION: UNION, DIFFERENCE: DIFFERENCE, INTERSECTION: INTERSECTION, XOR: XOR };\n\n exports.union = union;\n exports.diff = diff;\n exports.xor = xor;\n exports.intersection = intersection$1;\n exports.operations = operations;\n\n Object.defineProperty(exports, '__esModule', { value: true });\n\n})));\n//# sourceMappingURL=martinez.umd.js.map\n\n\n//# sourceURL=webpack:///./node_modules/martinez-polygon-clipping/dist/martinez.umd.js?")},function(module,exports){eval('/* A few functions that may be useful in other modules. */\n\n/**\r\n * Given a geoJSON geometry object\'s coordinates, return the object, but with\r\n * all the coordinates reversed.
\r\n * \r\n * Why? GeoJSON coordinates are in lngLat format by default, while Leaflet uses latLng.\r\n * L.geoJSON will auto-reverse the order of a GeoJSON object\'s coordinates, as it\r\n * expects geoJSON coordinates to be lngLat. However, normal, non-GeoJSON-specific Leaflet\r\n * methods expect Leaflet\'s latLng pairs and won\'t auto-reverse, so we have to do that\r\n * manually if we\'re preprocessing the GeoJSON data before passing it to L.geoJSON.\r\n * \r\n * @param {Array>>} coordinates - GeoJSON coordinates for a point, (multi-)line, or (multi-)polygon.\r\n * @returns {Array>>} - Reversed geoJSON coordinates for a point, (multi-)line, or (multi-)polygon.\r\n */\nfunction reversedCoordinates(coordinates) {\n var reversed = coordinates.slice();\n\n if (typeof coordinates[0] != "number") {\n var _iteratorNormalCompletion = true;\n var _didIteratorError = false;\n var _iteratorError = undefined;\n\n try {\n for (var _iterator = coordinates[Symbol.iterator](), _step; !(_iteratorNormalCompletion = (_step = _iterator.next()).done); _iteratorNormalCompletion = true) {\n var inner_coordinates = _step.value;\n reversed.splice(reversed.indexOf(inner_coordinates), 1, reversedCoordinates(inner_coordinates));\n }\n } catch (err) {\n _didIteratorError = true;\n _iteratorError = err;\n } finally {\n try {\n if (!_iteratorNormalCompletion && _iterator.return != null) {\n _iterator.return();\n }\n } finally {\n if (_didIteratorError) {\n throw _iteratorError;\n }\n }\n }\n } else {\n reversed = [coordinates[1], coordinates[0]];\n }\n\n return reversed;\n}\n/**\r\n * Given an array, check whether it can represent the coordinates of a point.\r\n *\r\n * @param {Array} array - Array to check.\r\n * @returns {boolean} - Whether the array can be the coordinates of a point.\r\n */\n\n\nfunction isPointCoordinates(array) {\n if (array.length !== 2 || typeof array[0] !== "number" || typeof array[1] !== "number") {\n return false;\n }\n\n return true;\n}\n/**\r\n * Given either a GeoJSON feature, L.latLng, or coordinate array containing the coordinates of a point,\r\n * return an array of the coordinates.\r\n *\r\n * @param {Point|Array|LatLng} point - The data containing the point\'s coordinates (latitude & longitude).\r\n * @returns {Array} - Array of the point\'s coordinates. I.e.: [lng, lat].\r\n */\n\n\nfunction pointToCoordinateArray(point) {\n var coordinate_array;\n\n if (typeof point.lat === "number" && typeof point.lng === "number") {\n coordinate_array = [point.lng, point.lat];\n } else if (point.geometry && point.geometry.coordinates && isPointCoordinates(point.geometry.coordinates)) {\n coordinate_array = point.geometry.coordinates;\n } else if (isPointCoordinates(point)) {\n coordinate_array = point;\n } else {\n throw new Error("Invalid point: point must either be array of 2 coordinates, or an L.latLng.");\n }\n\n return coordinate_array;\n}\n/**\r\n * Given two coordinate arrays, get their intersections.\r\n * \r\n * @param {array>} arr_a - Array of coordinate pairs.\r\n * @param {array>} arr_b - Array of coordinate pairs.\r\n * @param {array} ids - 2-element array whose elements are IDs for arr_a and arr_b respectively.\r\n *\r\n * @returns {Array>>} - Array whose elements are the intersections\' cooridinate-pairs if\r\n * ids is empty, or otherwise whose elements are arrays each of whose first element is an\r\n * intersection\'s coordinate-pair and whose second element is an object mapping each array\'s ID (supplied by ids) \r\n * to the index of the intersection\'s coordinate-pair in that array.\r\n */\n\n\nfunction getIntersections(arr_a, arr_b) {\n var ids = arguments.length > 2 && arguments[2] !== undefined ? arguments[2] : [];\n var intersections = [];\n\n for (var i = 0; i < arr_a.length; i++) {\n var el_a = arr_a[i];\n\n for (var j = 0; j < arr_b.length; j++) {\n var el_b = arr_b[j];\n\n if (isPointCoordinates(el_a) && isPointCoordinates(el_b)) {\n if (el_a[0] === el_b[0] && el_a[1] === el_b[1]) {\n var new_intersection = void 0;\n\n if (ids.length === 2) {\n var identified_intersections = {};\n identified_intersections[ids[0]] = i, identified_intersections[ids[1]] = j, new_intersection = [el_a, identified_intersections];\n } else {\n new_intersection = el_a;\n }\n\n intersections.push(new_intersection);\n }\n } else {\n throw new Error("Every element of each array must be a coordinate pair array.");\n }\n }\n }\n\n return intersections;\n}\n\nexports.getIntersections = getIntersections;\nexports.reversedCoordinates = reversedCoordinates;\nexports.isPointCoordinates = isPointCoordinates;\nexports.pointToCoordinateArray = pointToCoordinateArray;\n\n//# sourceURL=webpack:///./src/utils.js?')},function(module,__webpack_exports__,__webpack_require__){"use strict";eval("__webpack_require__.r(__webpack_exports__);\n\n// EXTERNAL MODULE: ./node_modules/@turf/bbox/main.es.js\nvar main_es = __webpack_require__(3);\n\n// CONCATENATED MODULE: ./node_modules/@turf/center/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar factors = {\n meters: earthRadius,\n metres: earthRadius,\n millimeters: earthRadius * 1000,\n millimetres: earthRadius * 1000,\n centimeters: earthRadius * 100,\n centimetres: earthRadius * 100,\n kilometers: earthRadius / 1000,\n kilometres: earthRadius / 1000,\n miles: earthRadius / 1609.344,\n nauticalmiles: earthRadius / 1852,\n inches: earthRadius * 39.370,\n yards: earthRadius / 1.0936,\n feet: earthRadius * 3.28084,\n radians: 1,\n degrees: earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = main_es_point(coordinates).geometry; break;\n case 'LineString': geom = lineString(coordinates).geometry; break;\n case 'Polygon': geom = main_es_polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction main_es_point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!isNumber(coordinates[0]) || !isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction main_es_points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return main_es_point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction main_es_polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !isNumber(ring[0][0]) || !isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return main_es_polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!isNumber(coordinates[0][1]) || !isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return featureCollection(coordinates.map(function (coords) {\n return lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) validateBBox(bbox);\n if (id) validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction lengthToDegrees(distance, units) {\n return radiansToDegrees(lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return radiansToLength(lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/center/main.es.js\n\n\n\n/**\n * Takes a {@link Feature} or {@link FeatureCollection} and returns the absolute center point of all features.\n *\n * @name center\n * @param {GeoJSON} geojson GeoJSON to be centered\n * @param {Object} [options={}] Optional parameters\n * @param {Object} [options.properties={}] an Object that is used as the {@link Feature}'s properties\n * @returns {Feature} a Point feature at the absolute center point of all input features\n * @example\n * var features = turf.featureCollection([\n * turf.point( [-97.522259, 35.4691]),\n * turf.point( [-97.502754, 35.463455]),\n * turf.point( [-97.508269, 35.463245])\n * ]);\n *\n * var center = turf.center(features);\n *\n * //addToMap\n * var addToMap = [features, center]\n * center.properties['marker-size'] = 'large';\n * center.properties['marker-color'] = '#000';\n */\nfunction main_es_center(geojson, options) {\n // Optional parameters\n options = options || {};\n if (!isObject(options)) throw new Error('options is invalid');\n var properties = options.properties;\n\n // Input validation\n if (!geojson) throw new Error('geojson is required');\n\n var ext = Object(main_es[\"default\"])(geojson);\n var x = (ext[0] + ext[2]) / 2;\n var y = (ext[1] + ext[3]) / 2;\n return main_es_point([x, y], properties);\n}\n\n/* harmony default export */ var center_main_es = (main_es_center);\n\n// EXTERNAL MODULE: ./node_modules/turf-jsts/jsts.min.js\nvar jsts_min = __webpack_require__(7);\n\n// EXTERNAL MODULE: ./node_modules/@turf/meta/main.es.js + 1 modules\nvar meta_main_es = __webpack_require__(0);\n\n// CONCATENATED MODULE: ./node_modules/@turf/projection/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar main_es_earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar main_es_factors = {\n meters: main_es_earthRadius,\n metres: main_es_earthRadius,\n millimeters: main_es_earthRadius * 1000,\n millimetres: main_es_earthRadius * 1000,\n centimeters: main_es_earthRadius * 100,\n centimetres: main_es_earthRadius * 100,\n kilometers: main_es_earthRadius / 1000,\n kilometres: main_es_earthRadius / 1000,\n miles: main_es_earthRadius / 1609.344,\n nauticalmiles: main_es_earthRadius / 1852,\n inches: main_es_earthRadius * 39.370,\n yards: main_es_earthRadius / 1.0936,\n feet: main_es_earthRadius * 3.28084,\n radians: 1,\n degrees: main_es_earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar main_es_unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / main_es_earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar main_es_areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction helpers_main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) main_es_validateBBox(bbox);\n if (id) main_es_validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction helpers_main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) main_es_validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = helpers_main_es_point(coordinates).geometry; break;\n case 'LineString': geom = main_es_lineString(coordinates).geometry; break;\n case 'Polygon': geom = helpers_main_es_polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = main_es_multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = main_es_multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = main_es_multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction helpers_main_es_point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!main_es_isNumber(coordinates[0]) || !main_es_isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return helpers_main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction helpers_main_es_points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return main_es_featureCollection(coordinates.map(function (coords) {\n return helpers_main_es_point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction helpers_main_es_polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !main_es_isNumber(ring[0][0]) || !main_es_isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return helpers_main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction main_es_polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return main_es_featureCollection(coordinates.map(function (coords) {\n return helpers_main_es_polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction main_es_lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!main_es_isNumber(coordinates[0][1]) || !main_es_isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return helpers_main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction main_es_lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return main_es_featureCollection(coordinates.map(function (coords) {\n return main_es_lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction main_es_featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) main_es_validateBBox(bbox);\n if (id) main_es_validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction main_es_multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return helpers_main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction main_es_multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return helpers_main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction main_es_multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return helpers_main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction main_es_geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return helpers_main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction main_es_round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction main_es_radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction main_es_lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction main_es_lengthToDegrees(distance, units) {\n return main_es_radiansToDegrees(main_es_lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction main_es_bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction main_es_radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction main_es_degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction main_es_convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return main_es_radiansToLength(main_es_lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction main_es_convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = main_es_areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = main_es_areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction main_es_isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction main_es_isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction main_es_validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!main_es_isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction main_es_validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction main_es_radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction main_es_degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction main_es_distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction main_es_distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction main_es_radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction main_es_bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction main_es_convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/clone/main.es.js\n/**\n * Returns a cloned copy of the passed GeoJSON Object, including possible 'Foreign Members'.\n * ~3-5x faster than the common JSON.parse + JSON.stringify combo method.\n *\n * @name clone\n * @param {GeoJSON} geojson GeoJSON Object\n * @returns {GeoJSON} cloned GeoJSON Object\n * @example\n * var line = turf.lineString([[-74, 40], [-78, 42], [-82, 35]], {color: 'red'});\n *\n * var lineCloned = turf.clone(line);\n */\nfunction clone(geojson) {\n if (!geojson) throw new Error('geojson is required');\n\n switch (geojson.type) {\n case 'Feature':\n return cloneFeature(geojson);\n case 'FeatureCollection':\n return cloneFeatureCollection(geojson);\n case 'Point':\n case 'LineString':\n case 'Polygon':\n case 'MultiPoint':\n case 'MultiLineString':\n case 'MultiPolygon':\n case 'GeometryCollection':\n return cloneGeometry(geojson);\n default:\n throw new Error('unknown GeoJSON type');\n }\n}\n\n/**\n * Clone Feature\n *\n * @private\n * @param {Feature} geojson GeoJSON Feature\n * @returns {Feature} cloned Feature\n */\nfunction cloneFeature(geojson) {\n var cloned = {type: 'Feature'};\n // Preserve Foreign Members\n Object.keys(geojson).forEach(function (key) {\n switch (key) {\n case 'type':\n case 'properties':\n case 'geometry':\n return;\n default:\n cloned[key] = geojson[key];\n }\n });\n // Add properties & geometry last\n cloned.properties = cloneProperties(geojson.properties);\n cloned.geometry = cloneGeometry(geojson.geometry);\n return cloned;\n}\n\n/**\n * Clone Properties\n *\n * @private\n * @param {Object} properties GeoJSON Properties\n * @returns {Object} cloned Properties\n */\nfunction cloneProperties(properties) {\n var cloned = {};\n if (!properties) return cloned;\n Object.keys(properties).forEach(function (key) {\n var value = properties[key];\n if (typeof value === 'object') {\n if (value === null) {\n // handle null\n cloned[key] = null;\n } else if (value.length) {\n // handle Array\n cloned[key] = value.map(function (item) {\n return item;\n });\n } else {\n // handle generic Object\n cloned[key] = cloneProperties(value);\n }\n } else cloned[key] = value;\n });\n return cloned;\n}\n\n/**\n * Clone Feature Collection\n *\n * @private\n * @param {FeatureCollection} geojson GeoJSON Feature Collection\n * @returns {FeatureCollection} cloned Feature Collection\n */\nfunction cloneFeatureCollection(geojson) {\n var cloned = {type: 'FeatureCollection'};\n\n // Preserve Foreign Members\n Object.keys(geojson).forEach(function (key) {\n switch (key) {\n case 'type':\n case 'features':\n return;\n default:\n cloned[key] = geojson[key];\n }\n });\n // Add features\n cloned.features = geojson.features.map(function (feature) {\n return cloneFeature(feature);\n });\n return cloned;\n}\n\n/**\n * Clone Geometry\n *\n * @private\n * @param {Geometry} geometry GeoJSON Geometry\n * @returns {Geometry} cloned Geometry\n */\nfunction cloneGeometry(geometry) {\n var geom = {type: geometry.type};\n if (geometry.bbox) geom.bbox = geometry.bbox;\n\n if (geometry.type === 'GeometryCollection') {\n geom.geometries = geometry.geometries.map(function (geom) {\n return cloneGeometry(geom);\n });\n return geom;\n }\n geom.coordinates = deepSlice(geometry.coordinates);\n return geom;\n}\n\n/**\n * Deep Slice coordinates\n *\n * @private\n * @param {Coordinates} coords Coordinates\n * @returns {Coordinates} all coordinates sliced\n */\nfunction deepSlice(coords) {\n if (typeof coords[0] !== 'object') { return coords.slice(); }\n return coords.map(function (coord) {\n return deepSlice(coord);\n });\n}\n\n/* harmony default export */ var clone_main_es = (clone);\n\n// CONCATENATED MODULE: ./node_modules/@turf/projection/main.es.js\n\n\n\n\n/**\n * Converts a WGS84 GeoJSON object into Mercator (EPSG:900913) projection\n *\n * @name toMercator\n * @param {GeoJSON|Position} geojson WGS84 GeoJSON object\n * @param {Object} [options] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)\n * @returns {GeoJSON} true/false\n * @example\n * var pt = turf.point([-71,41]);\n * var converted = turf.toMercator(pt);\n *\n * //addToMap\n * var addToMap = [pt, converted];\n */\nfunction toMercator(geojson, options) {\n return convert(geojson, 'mercator', options);\n}\n\n/**\n * Converts a Mercator (EPSG:900913) GeoJSON object into WGS84 projection\n *\n * @name toWgs84\n * @param {GeoJSON|Position} geojson Mercator GeoJSON object\n * @param {Object} [options] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)\n * @returns {GeoJSON} true/false\n * @example\n * var pt = turf.point([-7903683.846322424, 5012341.663847514]);\n * var converted = turf.toWgs84(pt);\n *\n * //addToMap\n * var addToMap = [pt, converted];\n */\nfunction toWgs84(geojson, options) {\n return convert(geojson, 'wgs84', options);\n}\n\n\n/**\n * Converts a GeoJSON coordinates to the defined `projection`\n *\n * @private\n * @param {GeoJSON} geojson GeoJSON Feature or Geometry\n * @param {string} projection defines the projection system to convert the coordinates to\n * @param {Object} [options] Optional parameters\n * @param {boolean} [options.mutate=false] allows GeoJSON input to be mutated (significant performance increase if true)\n * @returns {GeoJSON} true/false\n */\nfunction convert(geojson, projection, options) {\n // Optional parameters\n options = options || {};\n if (!main_es_isObject(options)) throw new Error('options is invalid');\n var mutate = options.mutate;\n\n // Validation\n if (!geojson) throw new Error('geojson is required');\n\n // Handle Position\n if (Array.isArray(geojson) && main_es_isNumber(geojson[0])) geojson = (projection === 'mercator') ? convertToMercator(geojson) : convertToWgs84(geojson);\n\n // Handle GeoJSON\n else {\n // Handle possible data mutation\n if (mutate !== true) geojson = clone_main_es(geojson);\n\n Object(meta_main_es[\"a\" /* coordEach */])(geojson, function (coord) {\n var newCoord = (projection === 'mercator') ? convertToMercator(coord) : convertToWgs84(coord);\n coord[0] = newCoord[0];\n coord[1] = newCoord[1];\n });\n }\n return geojson;\n}\n\n/**\n * Convert lon/lat values to 900913 x/y.\n * (from https://github.com/mapbox/sphericalmercator)\n *\n * @private\n * @param {Array} lonLat WGS84 point\n * @returns {Array} Mercator [x, y] point\n */\nfunction convertToMercator(lonLat) {\n var D2R = Math.PI / 180,\n // 900913 properties\n A = 6378137.0,\n MAXEXTENT = 20037508.342789244;\n\n // compensate longitudes passing the 180th meridian\n // from https://github.com/proj4js/proj4js/blob/master/lib/common/adjust_lon.js\n var adjusted = (Math.abs(lonLat[0]) <= 180) ? lonLat[0] : (lonLat[0] - (main_es_sign(lonLat[0]) * 360));\n var xy = [\n A * adjusted * D2R,\n A * Math.log(Math.tan((Math.PI * 0.25) + (0.5 * lonLat[1] * D2R)))\n ];\n\n // if xy value is beyond maxextent (e.g. poles), return maxextent\n if (xy[0] > MAXEXTENT) xy[0] = MAXEXTENT;\n if (xy[0] < -MAXEXTENT) xy[0] = -MAXEXTENT;\n if (xy[1] > MAXEXTENT) xy[1] = MAXEXTENT;\n if (xy[1] < -MAXEXTENT) xy[1] = -MAXEXTENT;\n\n return xy;\n}\n\n/**\n * Convert 900913 x/y values to lon/lat.\n * (from https://github.com/mapbox/sphericalmercator)\n *\n * @private\n * @param {Array} xy Mercator [x, y] point\n * @returns {Array} WGS84 [lon, lat] point\n */\nfunction convertToWgs84(xy) {\n // 900913 properties.\n var R2D = 180 / Math.PI;\n var A = 6378137.0;\n\n return [\n (xy[0] * R2D / A),\n ((Math.PI * 0.5) - 2.0 * Math.atan(Math.exp(-xy[1] / A))) * R2D\n ];\n}\n\n/**\n * Returns the sign of the input, or zero\n *\n * @private\n * @param {number} x input\n * @returns {number} -1|0|1 output\n */\nfunction main_es_sign(x) {\n return (x < 0) ? -1 : (x > 0) ? 1 : 0;\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/adder.js\n// Adds floating point numbers with twice the normal precision.\n// Reference: J. R. Shewchuk, Adaptive Precision Floating-Point Arithmetic and\n// Fast Robust Geometric Predicates, Discrete & Computational Geometry 18(3)\n// 305–363 (1997).\n// Code adapted from GeographicLib by Charles F. F. Karney,\n// http://geographiclib.sourceforge.net/\n\n/* harmony default export */ var adder = (function() {\n return new Adder;\n});\n\nfunction Adder() {\n this.reset();\n}\n\nAdder.prototype = {\n constructor: Adder,\n reset: function() {\n this.s = // rounded value\n this.t = 0; // exact error\n },\n add: function(y) {\n add(temp, y, this.t);\n add(this, temp.s, this.s);\n if (this.s) this.t += temp.t;\n else this.s = temp.t;\n },\n valueOf: function() {\n return this.s;\n }\n};\n\nvar temp = new Adder;\n\nfunction add(adder, a, b) {\n var x = adder.s = a + b,\n bv = x - a,\n av = x - bv;\n adder.t = (a - av) + (b - bv);\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/math.js\nvar epsilon = 1e-6;\nvar epsilon2 = 1e-12;\nvar pi = Math.PI;\nvar halfPi = pi / 2;\nvar quarterPi = pi / 4;\nvar tau = pi * 2;\n\nvar degrees = 180 / pi;\nvar radians = pi / 180;\n\nvar abs = Math.abs;\nvar atan = Math.atan;\nvar atan2 = Math.atan2;\nvar cos = Math.cos;\nvar ceil = Math.ceil;\nvar exp = Math.exp;\nvar floor = Math.floor;\nvar log = Math.log;\nvar pow = Math.pow;\nvar sin = Math.sin;\nvar math_sign = Math.sign || function(x) { return x > 0 ? 1 : x < 0 ? -1 : 0; };\nvar sqrt = Math.sqrt;\nvar tan = Math.tan;\n\nfunction acos(x) {\n return x > 1 ? 0 : x < -1 ? pi : Math.acos(x);\n}\n\nfunction asin(x) {\n return x > 1 ? halfPi : x < -1 ? -halfPi : Math.asin(x);\n}\n\nfunction haversin(x) {\n return (x = sin(x / 2)) * x;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/noop.js\nfunction noop() {}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/stream.js\nfunction streamGeometry(geometry, stream) {\n if (geometry && streamGeometryType.hasOwnProperty(geometry.type)) {\n streamGeometryType[geometry.type](geometry, stream);\n }\n}\n\nvar streamObjectType = {\n Feature: function(object, stream) {\n streamGeometry(object.geometry, stream);\n },\n FeatureCollection: function(object, stream) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) streamGeometry(features[i].geometry, stream);\n }\n};\n\nvar streamGeometryType = {\n Sphere: function(object, stream) {\n stream.sphere();\n },\n Point: function(object, stream) {\n object = object.coordinates;\n stream.point(object[0], object[1], object[2]);\n },\n MultiPoint: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) object = coordinates[i], stream.point(object[0], object[1], object[2]);\n },\n LineString: function(object, stream) {\n streamLine(object.coordinates, stream, 0);\n },\n MultiLineString: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamLine(coordinates[i], stream, 0);\n },\n Polygon: function(object, stream) {\n streamPolygon(object.coordinates, stream);\n },\n MultiPolygon: function(object, stream) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) streamPolygon(coordinates[i], stream);\n },\n GeometryCollection: function(object, stream) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) streamGeometry(geometries[i], stream);\n }\n};\n\nfunction streamLine(coordinates, stream, closed) {\n var i = -1, n = coordinates.length - closed, coordinate;\n stream.lineStart();\n while (++i < n) coordinate = coordinates[i], stream.point(coordinate[0], coordinate[1], coordinate[2]);\n stream.lineEnd();\n}\n\nfunction streamPolygon(coordinates, stream) {\n var i = -1, n = coordinates.length;\n stream.polygonStart();\n while (++i < n) streamLine(coordinates[i], stream, 1);\n stream.polygonEnd();\n}\n\n/* harmony default export */ var src_stream = (function(object, stream) {\n if (object && streamObjectType.hasOwnProperty(object.type)) {\n streamObjectType[object.type](object, stream);\n } else {\n streamGeometry(object, stream);\n }\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/area.js\n\n\n\n\n\nvar areaRingSum = adder();\n\nvar areaSum = adder(),\n area_lambda00,\n phi00,\n area_lambda0,\n area_cosPhi0,\n area_sinPhi0;\n\nvar areaStream = {\n point: noop,\n lineStart: noop,\n lineEnd: noop,\n polygonStart: function() {\n areaRingSum.reset();\n areaStream.lineStart = areaRingStart;\n areaStream.lineEnd = areaRingEnd;\n },\n polygonEnd: function() {\n var areaRing = +areaRingSum;\n areaSum.add(areaRing < 0 ? tau + areaRing : areaRing);\n this.lineStart = this.lineEnd = this.point = noop;\n },\n sphere: function() {\n areaSum.add(tau);\n }\n};\n\nfunction areaRingStart() {\n areaStream.point = areaPointFirst;\n}\n\nfunction areaRingEnd() {\n areaPoint(area_lambda00, phi00);\n}\n\nfunction areaPointFirst(lambda, phi) {\n areaStream.point = areaPoint;\n area_lambda00 = lambda, phi00 = phi;\n lambda *= radians, phi *= radians;\n area_lambda0 = lambda, area_cosPhi0 = cos(phi = phi / 2 + quarterPi), area_sinPhi0 = sin(phi);\n}\n\nfunction areaPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n phi = phi / 2 + quarterPi; // half the angular distance from south pole\n\n // Spherical excess E for a spherical triangle with vertices: south pole,\n // previous point, current point. Uses a formula derived from Cagnoli’s\n // theorem. See Todhunter, Spherical Trig. (1871), Sec. 103, Eq. (2).\n var dLambda = lambda - area_lambda0,\n sdLambda = dLambda >= 0 ? 1 : -1,\n adLambda = sdLambda * dLambda,\n cosPhi = cos(phi),\n sinPhi = sin(phi),\n k = area_sinPhi0 * sinPhi,\n u = area_cosPhi0 * cosPhi + k * cos(adLambda),\n v = k * sdLambda * sin(adLambda);\n areaRingSum.add(atan2(v, u));\n\n // Advance the previous points.\n area_lambda0 = lambda, area_cosPhi0 = cosPhi, area_sinPhi0 = sinPhi;\n}\n\n/* harmony default export */ var src_area = (function(object) {\n areaSum.reset();\n src_stream(object, areaStream);\n return areaSum * 2;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/cartesian.js\n\n\nfunction cartesian_spherical(cartesian) {\n return [atan2(cartesian[1], cartesian[0]), asin(cartesian[2])];\n}\n\nfunction cartesian_cartesian(spherical) {\n var lambda = spherical[0], phi = spherical[1], cosPhi = cos(phi);\n return [cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi)];\n}\n\nfunction cartesianDot(a, b) {\n return a[0] * b[0] + a[1] * b[1] + a[2] * b[2];\n}\n\nfunction cartesianCross(a, b) {\n return [a[1] * b[2] - a[2] * b[1], a[2] * b[0] - a[0] * b[2], a[0] * b[1] - a[1] * b[0]];\n}\n\n// TODO return a\nfunction cartesianAddInPlace(a, b) {\n a[0] += b[0], a[1] += b[1], a[2] += b[2];\n}\n\nfunction cartesianScale(vector, k) {\n return [vector[0] * k, vector[1] * k, vector[2] * k];\n}\n\n// TODO return d\nfunction cartesianNormalizeInPlace(d) {\n var l = sqrt(d[0] * d[0] + d[1] * d[1] + d[2] * d[2]);\n d[0] /= l, d[1] /= l, d[2] /= l;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/bounds.js\n\n\n\n\n\n\nvar bounds_lambda0, bounds_phi0, bounds_lambda1, bounds_phi1, // bounds\n bounds_lambda2, // previous lambda-coordinate\n bounds_lambda00, bounds_phi00, // first point\n bounds_p0, // previous 3D point\n deltaSum = adder(),\n ranges,\n range;\n\nvar boundsStream = {\n point: boundsPoint,\n lineStart: boundsLineStart,\n lineEnd: boundsLineEnd,\n polygonStart: function() {\n boundsStream.point = boundsRingPoint;\n boundsStream.lineStart = boundsRingStart;\n boundsStream.lineEnd = boundsRingEnd;\n deltaSum.reset();\n areaStream.polygonStart();\n },\n polygonEnd: function() {\n areaStream.polygonEnd();\n boundsStream.point = boundsPoint;\n boundsStream.lineStart = boundsLineStart;\n boundsStream.lineEnd = boundsLineEnd;\n if (areaRingSum < 0) bounds_lambda0 = -(bounds_lambda1 = 180), bounds_phi0 = -(bounds_phi1 = 90);\n else if (deltaSum > epsilon) bounds_phi1 = 90;\n else if (deltaSum < -epsilon) bounds_phi0 = -90;\n range[0] = bounds_lambda0, range[1] = bounds_lambda1;\n }\n};\n\nfunction boundsPoint(lambda, phi) {\n ranges.push(range = [bounds_lambda0 = lambda, bounds_lambda1 = lambda]);\n if (phi < bounds_phi0) bounds_phi0 = phi;\n if (phi > bounds_phi1) bounds_phi1 = phi;\n}\n\nfunction bounds_linePoint(lambda, phi) {\n var p = cartesian_cartesian([lambda * radians, phi * radians]);\n if (bounds_p0) {\n var normal = cartesianCross(bounds_p0, p),\n equatorial = [normal[1], -normal[0], 0],\n inflection = cartesianCross(equatorial, normal);\n cartesianNormalizeInPlace(inflection);\n inflection = cartesian_spherical(inflection);\n var delta = lambda - bounds_lambda2,\n sign = delta > 0 ? 1 : -1,\n lambdai = inflection[0] * degrees * sign,\n phii,\n antimeridian = abs(delta) > 180;\n if (antimeridian ^ (sign * bounds_lambda2 < lambdai && lambdai < sign * lambda)) {\n phii = inflection[1] * degrees;\n if (phii > bounds_phi1) bounds_phi1 = phii;\n } else if (lambdai = (lambdai + 360) % 360 - 180, antimeridian ^ (sign * bounds_lambda2 < lambdai && lambdai < sign * lambda)) {\n phii = -inflection[1] * degrees;\n if (phii < bounds_phi0) bounds_phi0 = phii;\n } else {\n if (phi < bounds_phi0) bounds_phi0 = phi;\n if (phi > bounds_phi1) bounds_phi1 = phi;\n }\n if (antimeridian) {\n if (lambda < bounds_lambda2) {\n if (bounds_angle(bounds_lambda0, lambda) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda1 = lambda;\n } else {\n if (bounds_angle(lambda, bounds_lambda1) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda0 = lambda;\n }\n } else {\n if (bounds_lambda1 >= bounds_lambda0) {\n if (lambda < bounds_lambda0) bounds_lambda0 = lambda;\n if (lambda > bounds_lambda1) bounds_lambda1 = lambda;\n } else {\n if (lambda > bounds_lambda2) {\n if (bounds_angle(bounds_lambda0, lambda) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda1 = lambda;\n } else {\n if (bounds_angle(lambda, bounds_lambda1) > bounds_angle(bounds_lambda0, bounds_lambda1)) bounds_lambda0 = lambda;\n }\n }\n }\n } else {\n ranges.push(range = [bounds_lambda0 = lambda, bounds_lambda1 = lambda]);\n }\n if (phi < bounds_phi0) bounds_phi0 = phi;\n if (phi > bounds_phi1) bounds_phi1 = phi;\n bounds_p0 = p, bounds_lambda2 = lambda;\n}\n\nfunction boundsLineStart() {\n boundsStream.point = bounds_linePoint;\n}\n\nfunction boundsLineEnd() {\n range[0] = bounds_lambda0, range[1] = bounds_lambda1;\n boundsStream.point = boundsPoint;\n bounds_p0 = null;\n}\n\nfunction boundsRingPoint(lambda, phi) {\n if (bounds_p0) {\n var delta = lambda - bounds_lambda2;\n deltaSum.add(abs(delta) > 180 ? delta + (delta > 0 ? 360 : -360) : delta);\n } else {\n bounds_lambda00 = lambda, bounds_phi00 = phi;\n }\n areaStream.point(lambda, phi);\n bounds_linePoint(lambda, phi);\n}\n\nfunction boundsRingStart() {\n areaStream.lineStart();\n}\n\nfunction boundsRingEnd() {\n boundsRingPoint(bounds_lambda00, bounds_phi00);\n areaStream.lineEnd();\n if (abs(deltaSum) > epsilon) bounds_lambda0 = -(bounds_lambda1 = 180);\n range[0] = bounds_lambda0, range[1] = bounds_lambda1;\n bounds_p0 = null;\n}\n\n// Finds the left-right distance between two longitudes.\n// This is almost the same as (lambda1 - lambda0 + 360°) % 360°, except that we want\n// the distance between ±180° to be 360°.\nfunction bounds_angle(lambda0, lambda1) {\n return (lambda1 -= lambda0) < 0 ? lambda1 + 360 : lambda1;\n}\n\nfunction rangeCompare(a, b) {\n return a[0] - b[0];\n}\n\nfunction rangeContains(range, x) {\n return range[0] <= range[1] ? range[0] <= x && x <= range[1] : x < range[0] || range[1] < x;\n}\n\n/* harmony default export */ var bounds = (function(feature) {\n var i, n, a, b, merged, deltaMax, delta;\n\n bounds_phi1 = bounds_lambda1 = -(bounds_lambda0 = bounds_phi0 = Infinity);\n ranges = [];\n src_stream(feature, boundsStream);\n\n // First, sort ranges by their minimum longitudes.\n if (n = ranges.length) {\n ranges.sort(rangeCompare);\n\n // Then, merge any ranges that overlap.\n for (i = 1, a = ranges[0], merged = [a]; i < n; ++i) {\n b = ranges[i];\n if (rangeContains(a, b[0]) || rangeContains(a, b[1])) {\n if (bounds_angle(a[0], b[1]) > bounds_angle(a[0], a[1])) a[1] = b[1];\n if (bounds_angle(b[0], a[1]) > bounds_angle(a[0], a[1])) a[0] = b[0];\n } else {\n merged.push(a = b);\n }\n }\n\n // Finally, find the largest gap between the merged ranges.\n // The final bounding box will be the inverse of this gap.\n for (deltaMax = -Infinity, n = merged.length - 1, i = 0, a = merged[n]; i <= n; a = b, ++i) {\n b = merged[i];\n if ((delta = bounds_angle(a[1], b[0])) > deltaMax) deltaMax = delta, bounds_lambda0 = b[0], bounds_lambda1 = a[1];\n }\n }\n\n ranges = range = null;\n\n return bounds_lambda0 === Infinity || bounds_phi0 === Infinity\n ? [[NaN, NaN], [NaN, NaN]]\n : [[bounds_lambda0, bounds_phi0], [bounds_lambda1, bounds_phi1]];\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/centroid.js\n\n\n\n\nvar W0, W1,\n centroid_X0, centroid_Y0, Z0,\n centroid_X1, centroid_Y1, Z1,\n X2, Y2, Z2,\n centroid_lambda00, centroid_phi00, // first point\n centroid_x0, centroid_y0, z0; // previous point\n\nvar centroidStream = {\n sphere: noop,\n point: centroidPoint,\n lineStart: centroidLineStart,\n lineEnd: centroidLineEnd,\n polygonStart: function() {\n centroidStream.lineStart = centroidRingStart;\n centroidStream.lineEnd = centroidRingEnd;\n },\n polygonEnd: function() {\n centroidStream.lineStart = centroidLineStart;\n centroidStream.lineEnd = centroidLineEnd;\n }\n};\n\n// Arithmetic mean of Cartesian vectors.\nfunction centroidPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi);\n centroidPointCartesian(cosPhi * cos(lambda), cosPhi * sin(lambda), sin(phi));\n}\n\nfunction centroidPointCartesian(x, y, z) {\n ++W0;\n centroid_X0 += (x - centroid_X0) / W0;\n centroid_Y0 += (y - centroid_Y0) / W0;\n Z0 += (z - Z0) / W0;\n}\n\nfunction centroidLineStart() {\n centroidStream.point = centroidLinePointFirst;\n}\n\nfunction centroidLinePointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi);\n centroid_x0 = cosPhi * cos(lambda);\n centroid_y0 = cosPhi * sin(lambda);\n z0 = sin(phi);\n centroidStream.point = centroidLinePoint;\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\nfunction centroidLinePoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi),\n x = cosPhi * cos(lambda),\n y = cosPhi * sin(lambda),\n z = sin(phi),\n w = atan2(sqrt((w = centroid_y0 * z - z0 * y) * w + (w = z0 * x - centroid_x0 * z) * w + (w = centroid_x0 * y - centroid_y0 * x) * w), centroid_x0 * x + centroid_y0 * y + z0 * z);\n W1 += w;\n centroid_X1 += w * (centroid_x0 + (centroid_x0 = x));\n centroid_Y1 += w * (centroid_y0 + (centroid_y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\nfunction centroidLineEnd() {\n centroidStream.point = centroidPoint;\n}\n\n// See J. E. Brock, The Inertia Tensor for a Spherical Triangle,\n// J. Applied Mechanics 42, 239 (1975).\nfunction centroidRingStart() {\n centroidStream.point = centroidRingPointFirst;\n}\n\nfunction centroidRingEnd() {\n centroidRingPoint(centroid_lambda00, centroid_phi00);\n centroidStream.point = centroidPoint;\n}\n\nfunction centroidRingPointFirst(lambda, phi) {\n centroid_lambda00 = lambda, centroid_phi00 = phi;\n lambda *= radians, phi *= radians;\n centroidStream.point = centroidRingPoint;\n var cosPhi = cos(phi);\n centroid_x0 = cosPhi * cos(lambda);\n centroid_y0 = cosPhi * sin(lambda);\n z0 = sin(phi);\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\nfunction centroidRingPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var cosPhi = cos(phi),\n x = cosPhi * cos(lambda),\n y = cosPhi * sin(lambda),\n z = sin(phi),\n cx = centroid_y0 * z - z0 * y,\n cy = z0 * x - centroid_x0 * z,\n cz = centroid_x0 * y - centroid_y0 * x,\n m = sqrt(cx * cx + cy * cy + cz * cz),\n w = asin(m), // line weight = angle\n v = m && -w / m; // area weight multiplier\n X2 += v * cx;\n Y2 += v * cy;\n Z2 += v * cz;\n W1 += w;\n centroid_X1 += w * (centroid_x0 + (centroid_x0 = x));\n centroid_Y1 += w * (centroid_y0 + (centroid_y0 = y));\n Z1 += w * (z0 + (z0 = z));\n centroidPointCartesian(centroid_x0, centroid_y0, z0);\n}\n\n/* harmony default export */ var centroid = (function(object) {\n W0 = W1 =\n centroid_X0 = centroid_Y0 = Z0 =\n centroid_X1 = centroid_Y1 = Z1 =\n X2 = Y2 = Z2 = 0;\n src_stream(object, centroidStream);\n\n var x = X2,\n y = Y2,\n z = Z2,\n m = x * x + y * y + z * z;\n\n // If the area-weighted ccentroid is undefined, fall back to length-weighted ccentroid.\n if (m < epsilon2) {\n x = centroid_X1, y = centroid_Y1, z = Z1;\n // If the feature has zero length, fall back to arithmetic mean of point vectors.\n if (W1 < epsilon) x = centroid_X0, y = centroid_Y0, z = Z0;\n m = x * x + y * y + z * z;\n // If the feature still has an undefined ccentroid, then return.\n if (m < epsilon2) return [NaN, NaN];\n }\n\n return [atan2(y, x) * degrees, asin(z / sqrt(m)) * degrees];\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/constant.js\n/* harmony default export */ var constant = (function(x) {\n return function() {\n return x;\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/compose.js\n/* harmony default export */ var compose = (function(a, b) {\n\n function compose(x, y) {\n return x = a(x, y), b(x[0], x[1]);\n }\n\n if (a.invert && b.invert) compose.invert = function(x, y) {\n return x = b.invert(x, y), x && a.invert(x[0], x[1]);\n };\n\n return compose;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/rotation.js\n\n\n\nfunction rotationIdentity(lambda, phi) {\n return [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi];\n}\n\nrotationIdentity.invert = rotationIdentity;\n\nfunction rotateRadians(deltaLambda, deltaPhi, deltaGamma) {\n return (deltaLambda %= tau) ? (deltaPhi || deltaGamma ? compose(rotationLambda(deltaLambda), rotationPhiGamma(deltaPhi, deltaGamma))\n : rotationLambda(deltaLambda))\n : (deltaPhi || deltaGamma ? rotationPhiGamma(deltaPhi, deltaGamma)\n : rotationIdentity);\n}\n\nfunction forwardRotationLambda(deltaLambda) {\n return function(lambda, phi) {\n return lambda += deltaLambda, [lambda > pi ? lambda - tau : lambda < -pi ? lambda + tau : lambda, phi];\n };\n}\n\nfunction rotationLambda(deltaLambda) {\n var rotation = forwardRotationLambda(deltaLambda);\n rotation.invert = forwardRotationLambda(-deltaLambda);\n return rotation;\n}\n\nfunction rotationPhiGamma(deltaPhi, deltaGamma) {\n var cosDeltaPhi = cos(deltaPhi),\n sinDeltaPhi = sin(deltaPhi),\n cosDeltaGamma = cos(deltaGamma),\n sinDeltaGamma = sin(deltaGamma);\n\n function rotation(lambda, phi) {\n var cosPhi = cos(phi),\n x = cos(lambda) * cosPhi,\n y = sin(lambda) * cosPhi,\n z = sin(phi),\n k = z * cosDeltaPhi + x * sinDeltaPhi;\n return [\n atan2(y * cosDeltaGamma - k * sinDeltaGamma, x * cosDeltaPhi - z * sinDeltaPhi),\n asin(k * cosDeltaGamma + y * sinDeltaGamma)\n ];\n }\n\n rotation.invert = function(lambda, phi) {\n var cosPhi = cos(phi),\n x = cos(lambda) * cosPhi,\n y = sin(lambda) * cosPhi,\n z = sin(phi),\n k = z * cosDeltaGamma - y * sinDeltaGamma;\n return [\n atan2(y * cosDeltaGamma + z * sinDeltaGamma, x * cosDeltaPhi + k * sinDeltaPhi),\n asin(k * cosDeltaPhi - x * sinDeltaPhi)\n ];\n };\n\n return rotation;\n}\n\n/* harmony default export */ var src_rotation = (function(rotate) {\n rotate = rotateRadians(rotate[0] * radians, rotate[1] * radians, rotate.length > 2 ? rotate[2] * radians : 0);\n\n function forward(coordinates) {\n coordinates = rotate(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;\n }\n\n forward.invert = function(coordinates) {\n coordinates = rotate.invert(coordinates[0] * radians, coordinates[1] * radians);\n return coordinates[0] *= degrees, coordinates[1] *= degrees, coordinates;\n };\n\n return forward;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/circle.js\n\n\n\n\n\n// Generates a circle centered at [0°, 0°], with a given radius and precision.\nfunction circleStream(stream, radius, delta, direction, t0, t1) {\n if (!delta) return;\n var cosRadius = cos(radius),\n sinRadius = sin(radius),\n step = direction * delta;\n if (t0 == null) {\n t0 = radius + direction * tau;\n t1 = radius - step / 2;\n } else {\n t0 = circleRadius(cosRadius, t0);\n t1 = circleRadius(cosRadius, t1);\n if (direction > 0 ? t0 < t1 : t0 > t1) t0 += direction * tau;\n }\n for (var point, t = t0; direction > 0 ? t > t1 : t < t1; t -= step) {\n point = cartesian_spherical([cosRadius, -sinRadius * cos(t), -sinRadius * sin(t)]);\n stream.point(point[0], point[1]);\n }\n}\n\n// Returns the signed angle of a cartesian point relative to [cosRadius, 0, 0].\nfunction circleRadius(cosRadius, point) {\n point = cartesian_cartesian(point), point[0] -= cosRadius;\n cartesianNormalizeInPlace(point);\n var radius = acos(-point[1]);\n return ((-point[2] < 0 ? -radius : radius) + tau - epsilon) % tau;\n}\n\n/* harmony default export */ var src_circle = (function() {\n var center = constant([0, 0]),\n radius = constant(90),\n precision = constant(6),\n ring,\n rotate,\n stream = {point: point};\n\n function point(x, y) {\n ring.push(x = rotate(x, y));\n x[0] *= degrees, x[1] *= degrees;\n }\n\n function circle() {\n var c = center.apply(this, arguments),\n r = radius.apply(this, arguments) * radians,\n p = precision.apply(this, arguments) * radians;\n ring = [];\n rotate = rotateRadians(-c[0] * radians, -c[1] * radians, 0).invert;\n circleStream(stream, r, p, 1);\n c = {type: \"Polygon\", coordinates: [ring]};\n ring = rotate = null;\n return c;\n }\n\n circle.center = function(_) {\n return arguments.length ? (center = typeof _ === \"function\" ? _ : constant([+_[0], +_[1]]), circle) : center;\n };\n\n circle.radius = function(_) {\n return arguments.length ? (radius = typeof _ === \"function\" ? _ : constant(+_), circle) : radius;\n };\n\n circle.precision = function(_) {\n return arguments.length ? (precision = typeof _ === \"function\" ? _ : constant(+_), circle) : precision;\n };\n\n return circle;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/buffer.js\n\n\n/* harmony default export */ var buffer = (function() {\n var lines = [],\n line;\n return {\n point: function(x, y) {\n line.push([x, y]);\n },\n lineStart: function() {\n lines.push(line = []);\n },\n lineEnd: noop,\n rejoin: function() {\n if (lines.length > 1) lines.push(lines.pop().concat(lines.shift()));\n },\n result: function() {\n var result = lines;\n lines = [];\n line = null;\n return result;\n }\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/line.js\n/* harmony default export */ var clip_line = (function(a, b, x0, y0, x1, y1) {\n var ax = a[0],\n ay = a[1],\n bx = b[0],\n by = b[1],\n t0 = 0,\n t1 = 1,\n dx = bx - ax,\n dy = by - ay,\n r;\n\n r = x0 - ax;\n if (!dx && r > 0) return;\n r /= dx;\n if (dx < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dx > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = x1 - ax;\n if (!dx && r < 0) return;\n r /= dx;\n if (dx < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dx > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n r = y0 - ay;\n if (!dy && r > 0) return;\n r /= dy;\n if (dy < 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n } else if (dy > 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n }\n\n r = y1 - ay;\n if (!dy && r < 0) return;\n r /= dy;\n if (dy < 0) {\n if (r > t1) return;\n if (r > t0) t0 = r;\n } else if (dy > 0) {\n if (r < t0) return;\n if (r < t1) t1 = r;\n }\n\n if (t0 > 0) a[0] = ax + t0 * dx, a[1] = ay + t0 * dy;\n if (t1 < 1) b[0] = ax + t1 * dx, b[1] = ay + t1 * dy;\n return true;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/pointEqual.js\n\n\n/* harmony default export */ var pointEqual = (function(a, b) {\n return abs(a[0] - b[0]) < epsilon && abs(a[1] - b[1]) < epsilon;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/polygon.js\n\n\nfunction Intersection(point, points, other, entry) {\n this.x = point;\n this.z = points;\n this.o = other; // another intersection\n this.e = entry; // is an entry?\n this.v = false; // visited\n this.n = this.p = null; // next & previous\n}\n\n// A generalized polygon clipping algorithm: given a polygon that has been cut\n// into its visible line segments, and rejoins the segments by interpolating\n// along the clip edge.\n/* harmony default export */ var clip_polygon = (function(segments, compareIntersection, startInside, interpolate, stream) {\n var subject = [],\n clip = [],\n i,\n n;\n\n segments.forEach(function(segment) {\n if ((n = segment.length - 1) <= 0) return;\n var n, p0 = segment[0], p1 = segment[n], x;\n\n // If the first and last points of a segment are coincident, then treat as a\n // closed ring. TODO if all rings are closed, then the winding order of the\n // exterior ring should be checked.\n if (pointEqual(p0, p1)) {\n stream.lineStart();\n for (i = 0; i < n; ++i) stream.point((p0 = segment[i])[0], p0[1]);\n stream.lineEnd();\n return;\n }\n\n subject.push(x = new Intersection(p0, segment, null, true));\n clip.push(x.o = new Intersection(p0, null, x, false));\n subject.push(x = new Intersection(p1, segment, null, false));\n clip.push(x.o = new Intersection(p1, null, x, true));\n });\n\n if (!subject.length) return;\n\n clip.sort(compareIntersection);\n polygon_link(subject);\n polygon_link(clip);\n\n for (i = 0, n = clip.length; i < n; ++i) {\n clip[i].e = startInside = !startInside;\n }\n\n var start = subject[0],\n points,\n point;\n\n while (1) {\n // Find first unvisited intersection.\n var current = start,\n isSubject = true;\n while (current.v) if ((current = current.n) === start) return;\n points = current.z;\n stream.lineStart();\n do {\n current.v = current.o.v = true;\n if (current.e) {\n if (isSubject) {\n for (i = 0, n = points.length; i < n; ++i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.n.x, 1, stream);\n }\n current = current.n;\n } else {\n if (isSubject) {\n points = current.p.z;\n for (i = points.length - 1; i >= 0; --i) stream.point((point = points[i])[0], point[1]);\n } else {\n interpolate(current.x, current.p.x, -1, stream);\n }\n current = current.p;\n }\n current = current.o;\n points = current.z;\n isSubject = !isSubject;\n } while (!current.v);\n stream.lineEnd();\n }\n});\n\nfunction polygon_link(array) {\n if (!(n = array.length)) return;\n var n,\n i = 0,\n a = array[0],\n b;\n while (++i < n) {\n a.n = b = array[i];\n b.p = a;\n a = b;\n }\n a.n = b = array[0];\n b.p = a;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/ascending.js\n/* harmony default export */ var ascending = (function(a, b) {\n return a < b ? -1 : a > b ? 1 : a >= b ? 0 : NaN;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/bisector.js\n\n\n/* harmony default export */ var bisector = (function(compare) {\n if (compare.length === 1) compare = ascendingComparator(compare);\n return {\n left: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) < 0) lo = mid + 1;\n else hi = mid;\n }\n return lo;\n },\n right: function(a, x, lo, hi) {\n if (lo == null) lo = 0;\n if (hi == null) hi = a.length;\n while (lo < hi) {\n var mid = lo + hi >>> 1;\n if (compare(a[mid], x) > 0) hi = mid;\n else lo = mid + 1;\n }\n return lo;\n }\n };\n});\n\nfunction ascendingComparator(f) {\n return function(d, x) {\n return ascending(f(d), x);\n };\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/bisect.js\n\n\n\nvar ascendingBisect = bisector(ascending);\nvar bisectRight = ascendingBisect.right;\nvar bisectLeft = ascendingBisect.left;\n/* harmony default export */ var bisect = (bisectRight);\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/pairs.js\n/* harmony default export */ var pairs = (function(array, f) {\n if (f == null) f = pair;\n var i = 0, n = array.length - 1, p = array[0], pairs = new Array(n < 0 ? 0 : n);\n while (i < n) pairs[i] = f(p, p = array[++i]);\n return pairs;\n});\n\nfunction pair(a, b) {\n return [a, b];\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/cross.js\n\n\n/* harmony default export */ var cross = (function(values0, values1, reduce) {\n var n0 = values0.length,\n n1 = values1.length,\n values = new Array(n0 * n1),\n i0,\n i1,\n i,\n value0;\n\n if (reduce == null) reduce = pair;\n\n for (i0 = i = 0; i0 < n0; ++i0) {\n for (value0 = values0[i0], i1 = 0; i1 < n1; ++i1, ++i) {\n values[i] = reduce(value0, values1[i1]);\n }\n }\n\n return values;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/descending.js\n/* harmony default export */ var descending = (function(a, b) {\n return b < a ? -1 : b > a ? 1 : b >= a ? 0 : NaN;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/number.js\n/* harmony default export */ var number = (function(x) {\n return x === null ? NaN : +x;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/variance.js\n\n\n/* harmony default export */ var variance = (function(values, valueof) {\n var n = values.length,\n m = 0,\n i = -1,\n mean = 0,\n value,\n delta,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n delta = value - mean;\n mean += delta / ++m;\n sum += delta * (value - mean);\n }\n }\n }\n\n if (m > 1) return sum / (m - 1);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/deviation.js\n\n\n/* harmony default export */ var deviation = (function(array, f) {\n var v = variance(array, f);\n return v ? Math.sqrt(v) : v;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/extent.js\n/* harmony default export */ var src_extent = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null) {\n if (min > value) min = value;\n if (max < value) max = value;\n }\n }\n }\n }\n }\n\n return [min, max];\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/array.js\nvar array_array = Array.prototype;\n\nvar slice = array_array.slice;\nvar map = array_array.map;\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/constant.js\n/* harmony default export */ var src_constant = (function(x) {\n return function() {\n return x;\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/identity.js\n/* harmony default export */ var identity = (function(x) {\n return x;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/range.js\n/* harmony default export */ var src_range = (function(start, stop, step) {\n start = +start, stop = +stop, step = (n = arguments.length) < 2 ? (stop = start, start = 0, 1) : n < 3 ? 1 : +step;\n\n var i = -1,\n n = Math.max(0, Math.ceil((stop - start) / step)) | 0,\n range = new Array(n);\n\n while (++i < n) {\n range[i] = start + i * step;\n }\n\n return range;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/ticks.js\nvar e10 = Math.sqrt(50),\n e5 = Math.sqrt(10),\n e2 = Math.sqrt(2);\n\n/* harmony default export */ var ticks = (function(start, stop, count) {\n var reverse,\n i = -1,\n n,\n ticks,\n step;\n\n stop = +stop, start = +start, count = +count;\n if (start === stop && count > 0) return [start];\n if (reverse = stop < start) n = start, start = stop, stop = n;\n if ((step = tickIncrement(start, stop, count)) === 0 || !isFinite(step)) return [];\n\n if (step > 0) {\n start = Math.ceil(start / step);\n stop = Math.floor(stop / step);\n ticks = new Array(n = Math.ceil(stop - start + 1));\n while (++i < n) ticks[i] = (start + i) * step;\n } else {\n start = Math.floor(start * step);\n stop = Math.ceil(stop * step);\n ticks = new Array(n = Math.ceil(start - stop + 1));\n while (++i < n) ticks[i] = (start - i) / step;\n }\n\n if (reverse) ticks.reverse();\n\n return ticks;\n});\n\nfunction tickIncrement(start, stop, count) {\n var step = (stop - start) / Math.max(0, count),\n power = Math.floor(Math.log(step) / Math.LN10),\n error = step / Math.pow(10, power);\n return power >= 0\n ? (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1) * Math.pow(10, power)\n : -Math.pow(10, -power) / (error >= e10 ? 10 : error >= e5 ? 5 : error >= e2 ? 2 : 1);\n}\n\nfunction tickStep(start, stop, count) {\n var step0 = Math.abs(stop - start) / Math.max(0, count),\n step1 = Math.pow(10, Math.floor(Math.log(step0) / Math.LN10)),\n error = step0 / step1;\n if (error >= e10) step1 *= 10;\n else if (error >= e5) step1 *= 5;\n else if (error >= e2) step1 *= 2;\n return stop < start ? -step1 : step1;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/threshold/sturges.js\n/* harmony default export */ var sturges = (function(values) {\n return Math.ceil(Math.log(values.length) / Math.LN2) + 1;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/histogram.js\n\n\n\n\n\n\n\n\n\n/* harmony default export */ var src_histogram = (function() {\n var value = identity,\n domain = src_extent,\n threshold = sturges;\n\n function histogram(data) {\n var i,\n n = data.length,\n x,\n values = new Array(n);\n\n for (i = 0; i < n; ++i) {\n values[i] = value(data[i], i, data);\n }\n\n var xz = domain(values),\n x0 = xz[0],\n x1 = xz[1],\n tz = threshold(values, x0, x1);\n\n // Convert number of thresholds into uniform thresholds.\n if (!Array.isArray(tz)) {\n tz = tickStep(x0, x1, tz);\n tz = src_range(Math.ceil(x0 / tz) * tz, Math.floor(x1 / tz) * tz, tz); // exclusive\n }\n\n // Remove any thresholds outside the domain.\n var m = tz.length;\n while (tz[0] <= x0) tz.shift(), --m;\n while (tz[m - 1] > x1) tz.pop(), --m;\n\n var bins = new Array(m + 1),\n bin;\n\n // Initialize bins.\n for (i = 0; i <= m; ++i) {\n bin = bins[i] = [];\n bin.x0 = i > 0 ? tz[i - 1] : x0;\n bin.x1 = i < m ? tz[i] : x1;\n }\n\n // Assign data to bins by value, ignoring any outside the domain.\n for (i = 0; i < n; ++i) {\n x = values[i];\n if (x0 <= x && x <= x1) {\n bins[bisect(tz, x, 0, m)].push(data[i]);\n }\n }\n\n return bins;\n }\n\n histogram.value = function(_) {\n return arguments.length ? (value = typeof _ === \"function\" ? _ : src_constant(_), histogram) : value;\n };\n\n histogram.domain = function(_) {\n return arguments.length ? (domain = typeof _ === \"function\" ? _ : src_constant([_[0], _[1]]), histogram) : domain;\n };\n\n histogram.thresholds = function(_) {\n return arguments.length ? (threshold = typeof _ === \"function\" ? _ : Array.isArray(_) ? src_constant(slice.call(_)) : src_constant(_), histogram) : threshold;\n };\n\n return histogram;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/quantile.js\n\n\n/* harmony default export */ var quantile = (function(values, p, valueof) {\n if (valueof == null) valueof = number;\n if (!(n = values.length)) return;\n if ((p = +p) <= 0 || n < 2) return +valueof(values[0], 0, values);\n if (p >= 1) return +valueof(values[n - 1], n - 1, values);\n var n,\n i = (n - 1) * p,\n i0 = Math.floor(i),\n value0 = +valueof(values[i0], i0, values),\n value1 = +valueof(values[i0 + 1], i0 + 1, values);\n return value0 + (value1 - value0) * (i - i0);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/threshold/freedmanDiaconis.js\n\n\n\n\n\n/* harmony default export */ var freedmanDiaconis = (function(values, min, max) {\n values = map.call(values, number).sort(ascending);\n return Math.ceil((max - min) / (2 * (quantile(values, 0.75) - quantile(values, 0.25)) * Math.pow(values.length, -1 / 3)));\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/threshold/scott.js\n\n\n/* harmony default export */ var scott = (function(values, min, max) {\n return Math.ceil((max - min) / (3.5 * deviation(values) * Math.pow(values.length, -1 / 3)));\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/max.js\n/* harmony default export */ var src_max = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n max;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n max = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && value > max) {\n max = value;\n }\n }\n }\n }\n }\n\n return max;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/mean.js\n\n\n/* harmony default export */ var src_mean = (function(values, valueof) {\n var n = values.length,\n m = n,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) sum += value;\n else --m;\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) sum += value;\n else --m;\n }\n }\n\n if (m) return sum / m;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/median.js\n\n\n\n\n/* harmony default export */ var median = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n numbers = [];\n\n if (valueof == null) {\n while (++i < n) {\n if (!isNaN(value = number(values[i]))) {\n numbers.push(value);\n }\n }\n }\n\n else {\n while (++i < n) {\n if (!isNaN(value = number(valueof(values[i], i, values)))) {\n numbers.push(value);\n }\n }\n }\n\n return quantile(numbers.sort(ascending), 0.5);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/merge.js\n/* harmony default export */ var merge = (function(arrays) {\n var n = arrays.length,\n m,\n i = -1,\n j = 0,\n merged,\n array;\n\n while (++i < n) j += arrays[i].length;\n merged = new Array(j);\n\n while (--n >= 0) {\n array = arrays[n];\n m = array.length;\n while (--m >= 0) {\n merged[--j] = array[m];\n }\n }\n\n return merged;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/min.js\n/* harmony default export */ var src_min = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n min;\n\n if (valueof == null) {\n while (++i < n) { // Find the first comparable value.\n if ((value = values[i]) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = values[i]) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n else {\n while (++i < n) { // Find the first comparable value.\n if ((value = valueof(values[i], i, values)) != null && value >= value) {\n min = value;\n while (++i < n) { // Compare the remaining values.\n if ((value = valueof(values[i], i, values)) != null && min > value) {\n min = value;\n }\n }\n }\n }\n }\n\n return min;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/permute.js\n/* harmony default export */ var permute = (function(array, indexes) {\n var i = indexes.length, permutes = new Array(i);\n while (i--) permutes[i] = array[indexes[i]];\n return permutes;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/scan.js\n\n\n/* harmony default export */ var scan = (function(values, compare) {\n if (!(n = values.length)) return;\n var n,\n i = 0,\n j = 0,\n xi,\n xj = values[j];\n\n if (compare == null) compare = ascending;\n\n while (++i < n) {\n if (compare(xi = values[i], xj) < 0 || compare(xj, xj) !== 0) {\n xj = xi, j = i;\n }\n }\n\n if (compare(xj, xj) === 0) return j;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/shuffle.js\n/* harmony default export */ var shuffle = (function(array, i0, i1) {\n var m = (i1 == null ? array.length : i1) - (i0 = i0 == null ? 0 : +i0),\n t,\n i;\n\n while (m) {\n i = Math.random() * m-- | 0;\n t = array[m + i0];\n array[m + i0] = array[i + i0];\n array[i + i0] = t;\n }\n\n return array;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/sum.js\n/* harmony default export */ var src_sum = (function(values, valueof) {\n var n = values.length,\n i = -1,\n value,\n sum = 0;\n\n if (valueof == null) {\n while (++i < n) {\n if (value = +values[i]) sum += value; // Note: zero and null are equivalent.\n }\n }\n\n else {\n while (++i < n) {\n if (value = +valueof(values[i], i, values)) sum += value;\n }\n }\n\n return sum;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/transpose.js\n\n\n/* harmony default export */ var src_transpose = (function(matrix) {\n if (!(n = matrix.length)) return [];\n for (var i = -1, m = src_min(matrix, transpose_length), transpose = new Array(m); ++i < m;) {\n for (var j = -1, n, row = transpose[i] = new Array(n); ++j < n;) {\n row[j] = matrix[j][i];\n }\n }\n return transpose;\n});\n\nfunction transpose_length(d) {\n return d.length;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-array/src/zip.js\n\n\n/* harmony default export */ var zip = (function() {\n return src_transpose(arguments);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-array/index.js\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/extent.js\n\n\n\n\n\n\nvar clipMax = 1e9, clipMin = -clipMax;\n\n// TODO Use d3-polygon’s polygonContains here for the ring check?\n// TODO Eliminate duplicate buffering in clipBuffer and polygon.push?\n\nfunction extent_clipExtent(x0, y0, x1, y1) {\n\n function visible(x, y) {\n return x0 <= x && x <= x1 && y0 <= y && y <= y1;\n }\n\n function interpolate(from, to, direction, stream) {\n var a = 0, a1 = 0;\n if (from == null\n || (a = corner(from, direction)) !== (a1 = corner(to, direction))\n || comparePoint(from, to) < 0 ^ direction > 0) {\n do stream.point(a === 0 || a === 3 ? x0 : x1, a > 1 ? y1 : y0);\n while ((a = (a + direction + 4) % 4) !== a1);\n } else {\n stream.point(to[0], to[1]);\n }\n }\n\n function corner(p, direction) {\n return abs(p[0] - x0) < epsilon ? direction > 0 ? 0 : 3\n : abs(p[0] - x1) < epsilon ? direction > 0 ? 2 : 1\n : abs(p[1] - y0) < epsilon ? direction > 0 ? 1 : 0\n : direction > 0 ? 3 : 2; // abs(p[1] - y1) < epsilon\n }\n\n function compareIntersection(a, b) {\n return comparePoint(a.x, b.x);\n }\n\n function comparePoint(a, b) {\n var ca = corner(a, 1),\n cb = corner(b, 1);\n return ca !== cb ? ca - cb\n : ca === 0 ? b[1] - a[1]\n : ca === 1 ? a[0] - b[0]\n : ca === 2 ? a[1] - b[1]\n : b[0] - a[0];\n }\n\n return function(stream) {\n var activeStream = stream,\n bufferStream = buffer(),\n segments,\n polygon,\n ring,\n x__, y__, v__, // first point\n x_, y_, v_, // previous point\n first,\n clean;\n\n var clipStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: polygonStart,\n polygonEnd: polygonEnd\n };\n\n function point(x, y) {\n if (visible(x, y)) activeStream.point(x, y);\n }\n\n function polygonInside() {\n var winding = 0;\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n for (var ring = polygon[i], j = 1, m = ring.length, point = ring[0], a0, a1, b0 = point[0], b1 = point[1]; j < m; ++j) {\n a0 = b0, a1 = b1, point = ring[j], b0 = point[0], b1 = point[1];\n if (a1 <= y1) { if (b1 > y1 && (b0 - a0) * (y1 - a1) > (b1 - a1) * (x0 - a0)) ++winding; }\n else { if (b1 <= y1 && (b0 - a0) * (y1 - a1) < (b1 - a1) * (x0 - a0)) --winding; }\n }\n }\n\n return winding;\n }\n\n // Buffer geometry within a polygon and then clip it en masse.\n function polygonStart() {\n activeStream = bufferStream, segments = [], polygon = [], clean = true;\n }\n\n function polygonEnd() {\n var startInside = polygonInside(),\n cleanInside = clean && startInside,\n visible = (segments = merge(segments)).length;\n if (cleanInside || visible) {\n stream.polygonStart();\n if (cleanInside) {\n stream.lineStart();\n interpolate(null, null, 1, stream);\n stream.lineEnd();\n }\n if (visible) {\n clip_polygon(segments, compareIntersection, startInside, interpolate, stream);\n }\n stream.polygonEnd();\n }\n activeStream = stream, segments = polygon = ring = null;\n }\n\n function lineStart() {\n clipStream.point = linePoint;\n if (polygon) polygon.push(ring = []);\n first = true;\n v_ = false;\n x_ = y_ = NaN;\n }\n\n // TODO rather than special-case polygons, simply handle them separately.\n // Ideally, coincident intersection points should be jittered to avoid\n // clipping issues.\n function lineEnd() {\n if (segments) {\n linePoint(x__, y__);\n if (v__ && v_) bufferStream.rejoin();\n segments.push(bufferStream.result());\n }\n clipStream.point = point;\n if (v_) activeStream.lineEnd();\n }\n\n function linePoint(x, y) {\n var v = visible(x, y);\n if (polygon) ring.push([x, y]);\n if (first) {\n x__ = x, y__ = y, v__ = v;\n first = false;\n if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n }\n } else {\n if (v && v_) activeStream.point(x, y);\n else {\n var a = [x_ = Math.max(clipMin, Math.min(clipMax, x_)), y_ = Math.max(clipMin, Math.min(clipMax, y_))],\n b = [x = Math.max(clipMin, Math.min(clipMax, x)), y = Math.max(clipMin, Math.min(clipMax, y))];\n if (clip_line(a, b, x0, y0, x1, y1)) {\n if (!v_) {\n activeStream.lineStart();\n activeStream.point(a[0], a[1]);\n }\n activeStream.point(b[0], b[1]);\n if (!v) activeStream.lineEnd();\n clean = false;\n } else if (v) {\n activeStream.lineStart();\n activeStream.point(x, y);\n clean = false;\n }\n }\n }\n x_ = x, y_ = y, v_ = v;\n }\n\n return clipStream;\n };\n}\n\n/* harmony default export */ var clip_extent = (function() {\n var x0 = 0,\n y0 = 0,\n x1 = 960,\n y1 = 500,\n cache,\n cacheStream,\n clip;\n\n return clip = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = extent_clipExtent(x0, y0, x1, y1)(cacheStream = stream);\n },\n extent: function(_) {\n return arguments.length ? (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1], cache = cacheStream = null, clip) : [[x0, y0], [x1, y1]];\n }\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/polygonContains.js\n\n\n\n\nvar polygonContains_sum = adder();\n\n/* harmony default export */ var polygonContains = (function(polygon, point) {\n var lambda = point[0],\n phi = point[1],\n normal = [sin(lambda), -cos(lambda), 0],\n angle = 0,\n winding = 0;\n\n polygonContains_sum.reset();\n\n for (var i = 0, n = polygon.length; i < n; ++i) {\n if (!(m = (ring = polygon[i]).length)) continue;\n var ring,\n m,\n point0 = ring[m - 1],\n lambda0 = point0[0],\n phi0 = point0[1] / 2 + quarterPi,\n sinPhi0 = sin(phi0),\n cosPhi0 = cos(phi0);\n\n for (var j = 0; j < m; ++j, lambda0 = lambda1, sinPhi0 = sinPhi1, cosPhi0 = cosPhi1, point0 = point1) {\n var point1 = ring[j],\n lambda1 = point1[0],\n phi1 = point1[1] / 2 + quarterPi,\n sinPhi1 = sin(phi1),\n cosPhi1 = cos(phi1),\n delta = lambda1 - lambda0,\n sign = delta >= 0 ? 1 : -1,\n absDelta = sign * delta,\n antimeridian = absDelta > pi,\n k = sinPhi0 * sinPhi1;\n\n polygonContains_sum.add(atan2(k * sign * sin(absDelta), cosPhi0 * cosPhi1 + k * cos(absDelta)));\n angle += antimeridian ? delta + sign * tau : delta;\n\n // Are the longitudes either side of the point’s meridian (lambda),\n // and are the latitudes smaller than the parallel (phi)?\n if (antimeridian ^ lambda0 >= lambda ^ lambda1 >= lambda) {\n var arc = cartesianCross(cartesian_cartesian(point0), cartesian_cartesian(point1));\n cartesianNormalizeInPlace(arc);\n var intersection = cartesianCross(normal, arc);\n cartesianNormalizeInPlace(intersection);\n var phiArc = (antimeridian ^ delta >= 0 ? -1 : 1) * asin(intersection[2]);\n if (phi > phiArc || phi === phiArc && (arc[0] || arc[1])) {\n winding += antimeridian ^ delta >= 0 ? 1 : -1;\n }\n }\n }\n }\n\n // First, determine whether the South pole is inside or outside:\n //\n // It is inside if:\n // * the polygon winds around it in a clockwise direction.\n // * the polygon does not (cumulatively) wind around it, but has a negative\n // (counter-clockwise) area.\n //\n // Second, count the (signed) number of times a segment crosses a lambda\n // from the point to the South pole. If it is zero, then the point is the\n // same side as the South pole.\n\n return (angle < -epsilon || angle < epsilon && polygonContains_sum < -epsilon) ^ (winding & 1);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/length.js\n\n\n\n\n\nvar lengthSum = adder(),\n length_lambda0,\n length_sinPhi0,\n length_cosPhi0;\n\nvar lengthStream = {\n sphere: noop,\n point: noop,\n lineStart: lengthLineStart,\n lineEnd: noop,\n polygonStart: noop,\n polygonEnd: noop\n};\n\nfunction lengthLineStart() {\n lengthStream.point = lengthPointFirst;\n lengthStream.lineEnd = lengthLineEnd;\n}\n\nfunction lengthLineEnd() {\n lengthStream.point = lengthStream.lineEnd = noop;\n}\n\nfunction lengthPointFirst(lambda, phi) {\n lambda *= radians, phi *= radians;\n length_lambda0 = lambda, length_sinPhi0 = sin(phi), length_cosPhi0 = cos(phi);\n lengthStream.point = lengthPoint;\n}\n\nfunction lengthPoint(lambda, phi) {\n lambda *= radians, phi *= radians;\n var sinPhi = sin(phi),\n cosPhi = cos(phi),\n delta = abs(lambda - length_lambda0),\n cosDelta = cos(delta),\n sinDelta = sin(delta),\n x = cosPhi * sinDelta,\n y = length_cosPhi0 * sinPhi - length_sinPhi0 * cosPhi * cosDelta,\n z = length_sinPhi0 * sinPhi + length_cosPhi0 * cosPhi * cosDelta;\n lengthSum.add(atan2(sqrt(x * x + y * y), z));\n length_lambda0 = lambda, length_sinPhi0 = sinPhi, length_cosPhi0 = cosPhi;\n}\n\n/* harmony default export */ var src_length = (function(object) {\n lengthSum.reset();\n src_stream(object, lengthStream);\n return +lengthSum;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/distance.js\n\n\nvar distance_coordinates = [null, null],\n distance_object = {type: \"LineString\", coordinates: distance_coordinates};\n\n/* harmony default export */ var src_distance = (function(a, b) {\n distance_coordinates[0] = a;\n distance_coordinates[1] = b;\n return src_length(distance_object);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/contains.js\n\n\n\n\nvar containsObjectType = {\n Feature: function(object, point) {\n return containsGeometry(object.geometry, point);\n },\n FeatureCollection: function(object, point) {\n var features = object.features, i = -1, n = features.length;\n while (++i < n) if (containsGeometry(features[i].geometry, point)) return true;\n return false;\n }\n};\n\nvar containsGeometryType = {\n Sphere: function() {\n return true;\n },\n Point: function(object, point) {\n return containsPoint(object.coordinates, point);\n },\n MultiPoint: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPoint(coordinates[i], point)) return true;\n return false;\n },\n LineString: function(object, point) {\n return containsLine(object.coordinates, point);\n },\n MultiLineString: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsLine(coordinates[i], point)) return true;\n return false;\n },\n Polygon: function(object, point) {\n return containsPolygon(object.coordinates, point);\n },\n MultiPolygon: function(object, point) {\n var coordinates = object.coordinates, i = -1, n = coordinates.length;\n while (++i < n) if (containsPolygon(coordinates[i], point)) return true;\n return false;\n },\n GeometryCollection: function(object, point) {\n var geometries = object.geometries, i = -1, n = geometries.length;\n while (++i < n) if (containsGeometry(geometries[i], point)) return true;\n return false;\n }\n};\n\nfunction containsGeometry(geometry, point) {\n return geometry && containsGeometryType.hasOwnProperty(geometry.type)\n ? containsGeometryType[geometry.type](geometry, point)\n : false;\n}\n\nfunction containsPoint(coordinates, point) {\n return src_distance(coordinates, point) === 0;\n}\n\nfunction containsLine(coordinates, point) {\n var ab = src_distance(coordinates[0], coordinates[1]),\n ao = src_distance(coordinates[0], point),\n ob = src_distance(point, coordinates[1]);\n return ao + ob <= ab + epsilon;\n}\n\nfunction containsPolygon(coordinates, point) {\n return !!polygonContains(coordinates.map(ringRadians), pointRadians(point));\n}\n\nfunction ringRadians(ring) {\n return ring = ring.map(pointRadians), ring.pop(), ring;\n}\n\nfunction pointRadians(point) {\n return [point[0] * radians, point[1] * radians];\n}\n\n/* harmony default export */ var contains = (function(object, point) {\n return (object && containsObjectType.hasOwnProperty(object.type)\n ? containsObjectType[object.type]\n : containsGeometry)(object, point);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/graticule.js\n\n\n\nfunction graticuleX(y0, y1, dy) {\n var y = src_range(y0, y1 - epsilon, dy).concat(y1);\n return function(x) { return y.map(function(y) { return [x, y]; }); };\n}\n\nfunction graticuleY(x0, x1, dx) {\n var x = src_range(x0, x1 - epsilon, dx).concat(x1);\n return function(y) { return x.map(function(x) { return [x, y]; }); };\n}\n\nfunction graticule_graticule() {\n var x1, x0, X1, X0,\n y1, y0, Y1, Y0,\n dx = 10, dy = dx, DX = 90, DY = 360,\n x, y, X, Y,\n precision = 2.5;\n\n function graticule() {\n return {type: \"MultiLineString\", coordinates: lines()};\n }\n\n function lines() {\n return src_range(ceil(X0 / DX) * DX, X1, DX).map(X)\n .concat(src_range(ceil(Y0 / DY) * DY, Y1, DY).map(Y))\n .concat(src_range(ceil(x0 / dx) * dx, x1, dx).filter(function(x) { return abs(x % DX) > epsilon; }).map(x))\n .concat(src_range(ceil(y0 / dy) * dy, y1, dy).filter(function(y) { return abs(y % DY) > epsilon; }).map(y));\n }\n\n graticule.lines = function() {\n return lines().map(function(coordinates) { return {type: \"LineString\", coordinates: coordinates}; });\n };\n\n graticule.outline = function() {\n return {\n type: \"Polygon\",\n coordinates: [\n X(X0).concat(\n Y(Y1).slice(1),\n X(X1).reverse().slice(1),\n Y(Y0).reverse().slice(1))\n ]\n };\n };\n\n graticule.extent = function(_) {\n if (!arguments.length) return graticule.extentMinor();\n return graticule.extentMajor(_).extentMinor(_);\n };\n\n graticule.extentMajor = function(_) {\n if (!arguments.length) return [[X0, Y0], [X1, Y1]];\n X0 = +_[0][0], X1 = +_[1][0];\n Y0 = +_[0][1], Y1 = +_[1][1];\n if (X0 > X1) _ = X0, X0 = X1, X1 = _;\n if (Y0 > Y1) _ = Y0, Y0 = Y1, Y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.extentMinor = function(_) {\n if (!arguments.length) return [[x0, y0], [x1, y1]];\n x0 = +_[0][0], x1 = +_[1][0];\n y0 = +_[0][1], y1 = +_[1][1];\n if (x0 > x1) _ = x0, x0 = x1, x1 = _;\n if (y0 > y1) _ = y0, y0 = y1, y1 = _;\n return graticule.precision(precision);\n };\n\n graticule.step = function(_) {\n if (!arguments.length) return graticule.stepMinor();\n return graticule.stepMajor(_).stepMinor(_);\n };\n\n graticule.stepMajor = function(_) {\n if (!arguments.length) return [DX, DY];\n DX = +_[0], DY = +_[1];\n return graticule;\n };\n\n graticule.stepMinor = function(_) {\n if (!arguments.length) return [dx, dy];\n dx = +_[0], dy = +_[1];\n return graticule;\n };\n\n graticule.precision = function(_) {\n if (!arguments.length) return precision;\n precision = +_;\n x = graticuleX(y0, y1, 90);\n y = graticuleY(x0, x1, precision);\n X = graticuleX(Y0, Y1, 90);\n Y = graticuleY(X0, X1, precision);\n return graticule;\n };\n\n return graticule\n .extentMajor([[-180, -90 + epsilon], [180, 90 - epsilon]])\n .extentMinor([[-180, -80 - epsilon], [180, 80 + epsilon]]);\n}\n\nfunction graticule10() {\n return graticule_graticule()();\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/interpolate.js\n\n\n/* harmony default export */ var src_interpolate = (function(a, b) {\n var x0 = a[0] * radians,\n y0 = a[1] * radians,\n x1 = b[0] * radians,\n y1 = b[1] * radians,\n cy0 = cos(y0),\n sy0 = sin(y0),\n cy1 = cos(y1),\n sy1 = sin(y1),\n kx0 = cy0 * cos(x0),\n ky0 = cy0 * sin(x0),\n kx1 = cy1 * cos(x1),\n ky1 = cy1 * sin(x1),\n d = 2 * asin(sqrt(haversin(y1 - y0) + cy0 * cy1 * haversin(x1 - x0))),\n k = sin(d);\n\n var interpolate = d ? function(t) {\n var B = sin(t *= d) / k,\n A = sin(d - t) / k,\n x = A * kx0 + B * kx1,\n y = A * ky0 + B * ky1,\n z = A * sy0 + B * sy1;\n return [\n atan2(y, x) * degrees,\n atan2(z, sqrt(x * x + y * y)) * degrees\n ];\n } : function() {\n return [x0 * degrees, y0 * degrees];\n };\n\n interpolate.distance = d;\n\n return interpolate;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/identity.js\n/* harmony default export */ var src_identity = (function(x) {\n return x;\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/area.js\n\n\n\n\nvar area_areaSum = adder(),\n area_areaRingSum = adder(),\n area_x00,\n area_y00,\n area_x0,\n area_y0;\n\nvar area_areaStream = {\n point: noop,\n lineStart: noop,\n lineEnd: noop,\n polygonStart: function() {\n area_areaStream.lineStart = area_areaRingStart;\n area_areaStream.lineEnd = area_areaRingEnd;\n },\n polygonEnd: function() {\n area_areaStream.lineStart = area_areaStream.lineEnd = area_areaStream.point = noop;\n area_areaSum.add(abs(area_areaRingSum));\n area_areaRingSum.reset();\n },\n result: function() {\n var area = area_areaSum / 2;\n area_areaSum.reset();\n return area;\n }\n};\n\nfunction area_areaRingStart() {\n area_areaStream.point = area_areaPointFirst;\n}\n\nfunction area_areaPointFirst(x, y) {\n area_areaStream.point = area_areaPoint;\n area_x00 = area_x0 = x, area_y00 = area_y0 = y;\n}\n\nfunction area_areaPoint(x, y) {\n area_areaRingSum.add(area_y0 * x - area_x0 * y);\n area_x0 = x, area_y0 = y;\n}\n\nfunction area_areaRingEnd() {\n area_areaPoint(area_x00, area_y00);\n}\n\n/* harmony default export */ var path_area = (area_areaStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/bounds.js\n\n\nvar bounds_x0 = Infinity,\n bounds_y0 = bounds_x0,\n bounds_x1 = -bounds_x0,\n bounds_y1 = bounds_x1;\n\nvar bounds_boundsStream = {\n point: bounds_boundsPoint,\n lineStart: noop,\n lineEnd: noop,\n polygonStart: noop,\n polygonEnd: noop,\n result: function() {\n var bounds = [[bounds_x0, bounds_y0], [bounds_x1, bounds_y1]];\n bounds_x1 = bounds_y1 = -(bounds_y0 = bounds_x0 = Infinity);\n return bounds;\n }\n};\n\nfunction bounds_boundsPoint(x, y) {\n if (x < bounds_x0) bounds_x0 = x;\n if (x > bounds_x1) bounds_x1 = x;\n if (y < bounds_y0) bounds_y0 = y;\n if (y > bounds_y1) bounds_y1 = y;\n}\n\n/* harmony default export */ var path_bounds = (bounds_boundsStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/centroid.js\n\n\n// TODO Enforce positive area for exterior, negative area for interior?\n\nvar path_centroid_X0 = 0,\n path_centroid_Y0 = 0,\n centroid_Z0 = 0,\n path_centroid_X1 = 0,\n path_centroid_Y1 = 0,\n centroid_Z1 = 0,\n centroid_X2 = 0,\n centroid_Y2 = 0,\n centroid_Z2 = 0,\n centroid_x00,\n centroid_y00,\n path_centroid_x0,\n path_centroid_y0;\n\nvar centroid_centroidStream = {\n point: centroid_centroidPoint,\n lineStart: centroid_centroidLineStart,\n lineEnd: centroid_centroidLineEnd,\n polygonStart: function() {\n centroid_centroidStream.lineStart = centroid_centroidRingStart;\n centroid_centroidStream.lineEnd = centroid_centroidRingEnd;\n },\n polygonEnd: function() {\n centroid_centroidStream.point = centroid_centroidPoint;\n centroid_centroidStream.lineStart = centroid_centroidLineStart;\n centroid_centroidStream.lineEnd = centroid_centroidLineEnd;\n },\n result: function() {\n var centroid = centroid_Z2 ? [centroid_X2 / centroid_Z2, centroid_Y2 / centroid_Z2]\n : centroid_Z1 ? [path_centroid_X1 / centroid_Z1, path_centroid_Y1 / centroid_Z1]\n : centroid_Z0 ? [path_centroid_X0 / centroid_Z0, path_centroid_Y0 / centroid_Z0]\n : [NaN, NaN];\n path_centroid_X0 = path_centroid_Y0 = centroid_Z0 =\n path_centroid_X1 = path_centroid_Y1 = centroid_Z1 =\n centroid_X2 = centroid_Y2 = centroid_Z2 = 0;\n return centroid;\n }\n};\n\nfunction centroid_centroidPoint(x, y) {\n path_centroid_X0 += x;\n path_centroid_Y0 += y;\n ++centroid_Z0;\n}\n\nfunction centroid_centroidLineStart() {\n centroid_centroidStream.point = centroidPointFirstLine;\n}\n\nfunction centroidPointFirstLine(x, y) {\n centroid_centroidStream.point = centroidPointLine;\n centroid_centroidPoint(path_centroid_x0 = x, path_centroid_y0 = y);\n}\n\nfunction centroidPointLine(x, y) {\n var dx = x - path_centroid_x0, dy = y - path_centroid_y0, z = sqrt(dx * dx + dy * dy);\n path_centroid_X1 += z * (path_centroid_x0 + x) / 2;\n path_centroid_Y1 += z * (path_centroid_y0 + y) / 2;\n centroid_Z1 += z;\n centroid_centroidPoint(path_centroid_x0 = x, path_centroid_y0 = y);\n}\n\nfunction centroid_centroidLineEnd() {\n centroid_centroidStream.point = centroid_centroidPoint;\n}\n\nfunction centroid_centroidRingStart() {\n centroid_centroidStream.point = centroidPointFirstRing;\n}\n\nfunction centroid_centroidRingEnd() {\n centroidPointRing(centroid_x00, centroid_y00);\n}\n\nfunction centroidPointFirstRing(x, y) {\n centroid_centroidStream.point = centroidPointRing;\n centroid_centroidPoint(centroid_x00 = path_centroid_x0 = x, centroid_y00 = path_centroid_y0 = y);\n}\n\nfunction centroidPointRing(x, y) {\n var dx = x - path_centroid_x0,\n dy = y - path_centroid_y0,\n z = sqrt(dx * dx + dy * dy);\n\n path_centroid_X1 += z * (path_centroid_x0 + x) / 2;\n path_centroid_Y1 += z * (path_centroid_y0 + y) / 2;\n centroid_Z1 += z;\n\n z = path_centroid_y0 * x - path_centroid_x0 * y;\n centroid_X2 += z * (path_centroid_x0 + x);\n centroid_Y2 += z * (path_centroid_y0 + y);\n centroid_Z2 += z * 3;\n centroid_centroidPoint(path_centroid_x0 = x, path_centroid_y0 = y);\n}\n\n/* harmony default export */ var path_centroid = (centroid_centroidStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/context.js\n\n\n\nfunction PathContext(context) {\n this._context = context;\n}\n\nPathContext.prototype = {\n _radius: 4.5,\n pointRadius: function(_) {\n return this._radius = _, this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._context.closePath();\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._context.moveTo(x, y);\n this._point = 1;\n break;\n }\n case 1: {\n this._context.lineTo(x, y);\n break;\n }\n default: {\n this._context.moveTo(x + this._radius, y);\n this._context.arc(x, y, this._radius, 0, tau);\n break;\n }\n }\n },\n result: noop\n};\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/measure.js\n\n\n\n\nvar measure_lengthSum = adder(),\n lengthRing,\n measure_x00,\n measure_y00,\n measure_x0,\n measure_y0;\n\nvar measure_lengthStream = {\n point: noop,\n lineStart: function() {\n measure_lengthStream.point = measure_lengthPointFirst;\n },\n lineEnd: function() {\n if (lengthRing) measure_lengthPoint(measure_x00, measure_y00);\n measure_lengthStream.point = noop;\n },\n polygonStart: function() {\n lengthRing = true;\n },\n polygonEnd: function() {\n lengthRing = null;\n },\n result: function() {\n var length = +measure_lengthSum;\n measure_lengthSum.reset();\n return length;\n }\n};\n\nfunction measure_lengthPointFirst(x, y) {\n measure_lengthStream.point = measure_lengthPoint;\n measure_x00 = measure_x0 = x, measure_y00 = measure_y0 = y;\n}\n\nfunction measure_lengthPoint(x, y) {\n measure_x0 -= x, measure_y0 -= y;\n measure_lengthSum.add(sqrt(measure_x0 * measure_x0 + measure_y0 * measure_y0));\n measure_x0 = x, measure_y0 = y;\n}\n\n/* harmony default export */ var measure = (measure_lengthStream);\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/string.js\nfunction PathString() {\n this._string = [];\n}\n\nPathString.prototype = {\n _radius: 4.5,\n _circle: string_circle(4.5),\n pointRadius: function(_) {\n if ((_ = +_) !== this._radius) this._radius = _, this._circle = null;\n return this;\n },\n polygonStart: function() {\n this._line = 0;\n },\n polygonEnd: function() {\n this._line = NaN;\n },\n lineStart: function() {\n this._point = 0;\n },\n lineEnd: function() {\n if (this._line === 0) this._string.push(\"Z\");\n this._point = NaN;\n },\n point: function(x, y) {\n switch (this._point) {\n case 0: {\n this._string.push(\"M\", x, \",\", y);\n this._point = 1;\n break;\n }\n case 1: {\n this._string.push(\"L\", x, \",\", y);\n break;\n }\n default: {\n if (this._circle == null) this._circle = string_circle(this._radius);\n this._string.push(\"M\", x, \",\", y, this._circle);\n break;\n }\n }\n },\n result: function() {\n if (this._string.length) {\n var result = this._string.join(\"\");\n this._string = [];\n return result;\n } else {\n return null;\n }\n }\n};\n\nfunction string_circle(radius) {\n return \"m0,\" + radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + -2 * radius\n + \"a\" + radius + \",\" + radius + \" 0 1,1 0,\" + 2 * radius\n + \"z\";\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/path/index.js\n\n\n\n\n\n\n\n\n\n/* harmony default export */ var src_path = (function(projection, context) {\n var pointRadius = 4.5,\n projectionStream,\n contextStream;\n\n function path(object) {\n if (object) {\n if (typeof pointRadius === \"function\") contextStream.pointRadius(+pointRadius.apply(this, arguments));\n src_stream(object, projectionStream(contextStream));\n }\n return contextStream.result();\n }\n\n path.area = function(object) {\n src_stream(object, projectionStream(path_area));\n return path_area.result();\n };\n\n path.measure = function(object) {\n src_stream(object, projectionStream(measure));\n return measure.result();\n };\n\n path.bounds = function(object) {\n src_stream(object, projectionStream(path_bounds));\n return path_bounds.result();\n };\n\n path.centroid = function(object) {\n src_stream(object, projectionStream(path_centroid));\n return path_centroid.result();\n };\n\n path.projection = function(_) {\n return arguments.length ? (projectionStream = _ == null ? (projection = null, src_identity) : (projection = _).stream, path) : projection;\n };\n\n path.context = function(_) {\n if (!arguments.length) return context;\n contextStream = _ == null ? (context = null, new PathString) : new PathContext(context = _);\n if (typeof pointRadius !== \"function\") contextStream.pointRadius(pointRadius);\n return path;\n };\n\n path.pointRadius = function(_) {\n if (!arguments.length) return pointRadius;\n pointRadius = typeof _ === \"function\" ? _ : (contextStream.pointRadius(+_), +_);\n return path;\n };\n\n return path.projection(projection).context(context);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/index.js\n\n\n\n\n\n\n/* harmony default export */ var src_clip = (function(pointVisible, clipLine, interpolate, start) {\n return function(rotate, sink) {\n var line = clipLine(sink),\n rotatedStart = rotate.invert(start[0], start[1]),\n ringBuffer = buffer(),\n ringSink = clipLine(ringBuffer),\n polygonStarted = false,\n polygon,\n segments,\n ring;\n\n var clip = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() {\n clip.point = pointRing;\n clip.lineStart = ringStart;\n clip.lineEnd = ringEnd;\n segments = [];\n polygon = [];\n },\n polygonEnd: function() {\n clip.point = point;\n clip.lineStart = lineStart;\n clip.lineEnd = lineEnd;\n segments = merge(segments);\n var startInside = polygonContains(polygon, rotatedStart);\n if (segments.length) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n clip_polygon(segments, clip_compareIntersection, startInside, interpolate, sink);\n } else if (startInside) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n }\n if (polygonStarted) sink.polygonEnd(), polygonStarted = false;\n segments = polygon = null;\n },\n sphere: function() {\n sink.polygonStart();\n sink.lineStart();\n interpolate(null, null, 1, sink);\n sink.lineEnd();\n sink.polygonEnd();\n }\n };\n\n function point(lambda, phi) {\n var point = rotate(lambda, phi);\n if (pointVisible(lambda = point[0], phi = point[1])) sink.point(lambda, phi);\n }\n\n function pointLine(lambda, phi) {\n var point = rotate(lambda, phi);\n line.point(point[0], point[1]);\n }\n\n function lineStart() {\n clip.point = pointLine;\n line.lineStart();\n }\n\n function lineEnd() {\n clip.point = point;\n line.lineEnd();\n }\n\n function pointRing(lambda, phi) {\n ring.push([lambda, phi]);\n var point = rotate(lambda, phi);\n ringSink.point(point[0], point[1]);\n }\n\n function ringStart() {\n ringSink.lineStart();\n ring = [];\n }\n\n function ringEnd() {\n pointRing(ring[0][0], ring[0][1]);\n ringSink.lineEnd();\n\n var clean = ringSink.clean(),\n ringSegments = ringBuffer.result(),\n i, n = ringSegments.length, m,\n segment,\n point;\n\n ring.pop();\n polygon.push(ring);\n ring = null;\n\n if (!n) return;\n\n // No intersections.\n if (clean & 1) {\n segment = ringSegments[0];\n if ((m = segment.length - 1) > 0) {\n if (!polygonStarted) sink.polygonStart(), polygonStarted = true;\n sink.lineStart();\n for (i = 0; i < m; ++i) sink.point((point = segment[i])[0], point[1]);\n sink.lineEnd();\n }\n return;\n }\n\n // Rejoin connected segments.\n // TODO reuse ringBuffer.rejoin()?\n if (n > 1 && clean & 2) ringSegments.push(ringSegments.pop().concat(ringSegments.shift()));\n\n segments.push(ringSegments.filter(validSegment));\n }\n\n return clip;\n };\n});\n\nfunction validSegment(segment) {\n return segment.length > 1;\n}\n\n// Intersections are sorted along the clip edge. For both antimeridian cutting\n// and circle clipping, the same comparison is used.\nfunction clip_compareIntersection(a, b) {\n return ((a = a.x)[0] < 0 ? a[1] - halfPi - epsilon : halfPi - a[1])\n - ((b = b.x)[0] < 0 ? b[1] - halfPi - epsilon : halfPi - b[1]);\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/antimeridian.js\n\n\n\n/* harmony default export */ var clip_antimeridian = (src_clip(\n function() { return true; },\n clipAntimeridianLine,\n clipAntimeridianInterpolate,\n [-pi, -halfPi]\n));\n\n// Takes a line and cuts into visible segments. Return values: 0 - there were\n// intersections or the line was empty; 1 - no intersections; 2 - there were\n// intersections, and the first and last segments should be rejoined.\nfunction clipAntimeridianLine(stream) {\n var lambda0 = NaN,\n phi0 = NaN,\n sign0 = NaN,\n clean; // no intersections\n\n return {\n lineStart: function() {\n stream.lineStart();\n clean = 1;\n },\n point: function(lambda1, phi1) {\n var sign1 = lambda1 > 0 ? pi : -pi,\n delta = abs(lambda1 - lambda0);\n if (abs(delta - pi) < epsilon) { // line crosses a pole\n stream.point(lambda0, phi0 = (phi0 + phi1) / 2 > 0 ? halfPi : -halfPi);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n stream.point(lambda1, phi0);\n clean = 0;\n } else if (sign0 !== sign1 && delta >= pi) { // line crosses antimeridian\n if (abs(lambda0 - sign0) < epsilon) lambda0 -= sign0 * epsilon; // handle degeneracies\n if (abs(lambda1 - sign1) < epsilon) lambda1 -= sign1 * epsilon;\n phi0 = clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1);\n stream.point(sign0, phi0);\n stream.lineEnd();\n stream.lineStart();\n stream.point(sign1, phi0);\n clean = 0;\n }\n stream.point(lambda0 = lambda1, phi0 = phi1);\n sign0 = sign1;\n },\n lineEnd: function() {\n stream.lineEnd();\n lambda0 = phi0 = NaN;\n },\n clean: function() {\n return 2 - clean; // if intersections, rejoin first and last segments\n }\n };\n}\n\nfunction clipAntimeridianIntersect(lambda0, phi0, lambda1, phi1) {\n var cosPhi0,\n cosPhi1,\n sinLambda0Lambda1 = sin(lambda0 - lambda1);\n return abs(sinLambda0Lambda1) > epsilon\n ? atan((sin(phi0) * (cosPhi1 = cos(phi1)) * sin(lambda1)\n - sin(phi1) * (cosPhi0 = cos(phi0)) * sin(lambda0))\n / (cosPhi0 * cosPhi1 * sinLambda0Lambda1))\n : (phi0 + phi1) / 2;\n}\n\nfunction clipAntimeridianInterpolate(from, to, direction, stream) {\n var phi;\n if (from == null) {\n phi = direction * halfPi;\n stream.point(-pi, phi);\n stream.point(0, phi);\n stream.point(pi, phi);\n stream.point(pi, 0);\n stream.point(pi, -phi);\n stream.point(0, -phi);\n stream.point(-pi, -phi);\n stream.point(-pi, 0);\n stream.point(-pi, phi);\n } else if (abs(from[0] - to[0]) > epsilon) {\n var lambda = from[0] < to[0] ? pi : -pi;\n phi = direction * lambda / 2;\n stream.point(-lambda, phi);\n stream.point(0, phi);\n stream.point(lambda, phi);\n } else {\n stream.point(to[0], to[1]);\n }\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/clip/circle.js\n\n\n\n\n\n\n/* harmony default export */ var clip_circle = (function(radius, delta) {\n var cr = cos(radius),\n smallRadius = cr > 0,\n notHemisphere = abs(cr) > epsilon; // TODO optimise for this common case\n\n function interpolate(from, to, direction, stream) {\n circleStream(stream, radius, delta, direction, from, to);\n }\n\n function visible(lambda, phi) {\n return cos(lambda) * cos(phi) > cr;\n }\n\n // Takes a line and cuts into visible segments. Return values used for polygon\n // clipping: 0 - there were intersections or the line was empty; 1 - no\n // intersections 2 - there were intersections, and the first and last segments\n // should be rejoined.\n function clipLine(stream) {\n var point0, // previous point\n c0, // code for previous point\n v0, // visibility of previous point\n v00, // visibility of first point\n clean; // no intersections\n return {\n lineStart: function() {\n v00 = v0 = false;\n clean = 1;\n },\n point: function(lambda, phi) {\n var point1 = [lambda, phi],\n point2,\n v = visible(lambda, phi),\n c = smallRadius\n ? v ? 0 : code(lambda, phi)\n : v ? code(lambda + (lambda < 0 ? pi : -pi), phi) : 0;\n if (!point0 && (v00 = v0 = v)) stream.lineStart();\n // Handle degeneracies.\n // TODO ignore if not clipping polygons.\n if (v !== v0) {\n point2 = intersect(point0, point1);\n if (!point2 || pointEqual(point0, point2) || pointEqual(point1, point2)) {\n point1[0] += epsilon;\n point1[1] += epsilon;\n v = visible(point1[0], point1[1]);\n }\n }\n if (v !== v0) {\n clean = 0;\n if (v) {\n // outside going in\n stream.lineStart();\n point2 = intersect(point1, point0);\n stream.point(point2[0], point2[1]);\n } else {\n // inside going out\n point2 = intersect(point0, point1);\n stream.point(point2[0], point2[1]);\n stream.lineEnd();\n }\n point0 = point2;\n } else if (notHemisphere && point0 && smallRadius ^ v) {\n var t;\n // If the codes for two points are different, or are both zero,\n // and there this segment intersects with the small circle.\n if (!(c & c0) && (t = intersect(point1, point0, true))) {\n clean = 0;\n if (smallRadius) {\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n } else {\n stream.point(t[1][0], t[1][1]);\n stream.lineEnd();\n stream.lineStart();\n stream.point(t[0][0], t[0][1]);\n }\n }\n }\n if (v && (!point0 || !pointEqual(point0, point1))) {\n stream.point(point1[0], point1[1]);\n }\n point0 = point1, v0 = v, c0 = c;\n },\n lineEnd: function() {\n if (v0) stream.lineEnd();\n point0 = null;\n },\n // Rejoin first and last segments if there were intersections and the first\n // and last points were visible.\n clean: function() {\n return clean | ((v00 && v0) << 1);\n }\n };\n }\n\n // Intersects the great circle between a and b with the clip circle.\n function intersect(a, b, two) {\n var pa = cartesian_cartesian(a),\n pb = cartesian_cartesian(b);\n\n // We have two planes, n1.p = d1 and n2.p = d2.\n // Find intersection line p(t) = c1 n1 + c2 n2 + t (n1 ⨯ n2).\n var n1 = [1, 0, 0], // normal\n n2 = cartesianCross(pa, pb),\n n2n2 = cartesianDot(n2, n2),\n n1n2 = n2[0], // cartesianDot(n1, n2),\n determinant = n2n2 - n1n2 * n1n2;\n\n // Two polar points.\n if (!determinant) return !two && a;\n\n var c1 = cr * n2n2 / determinant,\n c2 = -cr * n1n2 / determinant,\n n1xn2 = cartesianCross(n1, n2),\n A = cartesianScale(n1, c1),\n B = cartesianScale(n2, c2);\n cartesianAddInPlace(A, B);\n\n // Solve |p(t)|^2 = 1.\n var u = n1xn2,\n w = cartesianDot(A, u),\n uu = cartesianDot(u, u),\n t2 = w * w - uu * (cartesianDot(A, A) - 1);\n\n if (t2 < 0) return;\n\n var t = sqrt(t2),\n q = cartesianScale(u, (-w - t) / uu);\n cartesianAddInPlace(q, A);\n q = cartesian_spherical(q);\n\n if (!two) return q;\n\n // Two intersection points.\n var lambda0 = a[0],\n lambda1 = b[0],\n phi0 = a[1],\n phi1 = b[1],\n z;\n\n if (lambda1 < lambda0) z = lambda0, lambda0 = lambda1, lambda1 = z;\n\n var delta = lambda1 - lambda0,\n polar = abs(delta - pi) < epsilon,\n meridian = polar || delta < epsilon;\n\n if (!polar && phi1 < phi0) z = phi0, phi0 = phi1, phi1 = z;\n\n // Check that the first point is between a and b.\n if (meridian\n ? polar\n ? phi0 + phi1 > 0 ^ q[1] < (abs(q[0] - lambda0) < epsilon ? phi0 : phi1)\n : phi0 <= q[1] && q[1] <= phi1\n : delta > pi ^ (lambda0 <= q[0] && q[0] <= lambda1)) {\n var q1 = cartesianScale(u, (-w + t) / uu);\n cartesianAddInPlace(q1, A);\n return [q, cartesian_spherical(q1)];\n }\n }\n\n // Generates a 4-bit vector representing the location of a point relative to\n // the small circle's bounding box.\n function code(lambda, phi) {\n var r = smallRadius ? radius : pi - radius,\n code = 0;\n if (lambda < -r) code |= 1; // left\n else if (lambda > r) code |= 2; // right\n if (phi < -r) code |= 4; // below\n else if (phi > r) code |= 8; // above\n return code;\n }\n\n return src_clip(visible, clipLine, interpolate, smallRadius ? [0, -radius] : [-pi, radius - pi]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/transform.js\n/* harmony default export */ var src_transform = (function(methods) {\n return {\n stream: transformer(methods)\n };\n});\n\nfunction transformer(methods) {\n return function(stream) {\n var s = new TransformStream;\n for (var key in methods) s[key] = methods[key];\n s.stream = stream;\n return s;\n };\n}\n\nfunction TransformStream() {}\n\nTransformStream.prototype = {\n constructor: TransformStream,\n point: function(x, y) { this.stream.point(x, y); },\n sphere: function() { this.stream.sphere(); },\n lineStart: function() { this.stream.lineStart(); },\n lineEnd: function() { this.stream.lineEnd(); },\n polygonStart: function() { this.stream.polygonStart(); },\n polygonEnd: function() { this.stream.polygonEnd(); }\n};\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/fit.js\n\n\n\nfunction fitExtent(projection, extent, object) {\n var w = extent[1][0] - extent[0][0],\n h = extent[1][1] - extent[0][1],\n clip = projection.clipExtent && projection.clipExtent();\n\n projection\n .scale(150)\n .translate([0, 0]);\n\n if (clip != null) projection.clipExtent(null);\n\n src_stream(object, projection.stream(path_bounds));\n\n var b = path_bounds.result(),\n k = Math.min(w / (b[1][0] - b[0][0]), h / (b[1][1] - b[0][1])),\n x = +extent[0][0] + (w - k * (b[1][0] + b[0][0])) / 2,\n y = +extent[0][1] + (h - k * (b[1][1] + b[0][1])) / 2;\n\n if (clip != null) projection.clipExtent(clip);\n\n return projection\n .scale(k * 150)\n .translate([x, y]);\n}\n\nfunction fitSize(projection, size, object) {\n return fitExtent(projection, [[0, 0], size], object);\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/resample.js\n\n\n\n\nvar maxDepth = 16, // maximum depth of subdivision\n cosMinDistance = cos(30 * radians); // cos(minimum angular distance)\n\n/* harmony default export */ var resample = (function(project, delta2) {\n return +delta2 ? resample_resample(project, delta2) : resampleNone(project);\n});\n\nfunction resampleNone(project) {\n return transformer({\n point: function(x, y) {\n x = project(x, y);\n this.stream.point(x[0], x[1]);\n }\n });\n}\n\nfunction resample_resample(project, delta2) {\n\n function resampleLineTo(x0, y0, lambda0, a0, b0, c0, x1, y1, lambda1, a1, b1, c1, depth, stream) {\n var dx = x1 - x0,\n dy = y1 - y0,\n d2 = dx * dx + dy * dy;\n if (d2 > 4 * delta2 && depth--) {\n var a = a0 + a1,\n b = b0 + b1,\n c = c0 + c1,\n m = sqrt(a * a + b * b + c * c),\n phi2 = asin(c /= m),\n lambda2 = abs(abs(c) - 1) < epsilon || abs(lambda0 - lambda1) < epsilon ? (lambda0 + lambda1) / 2 : atan2(b, a),\n p = project(lambda2, phi2),\n x2 = p[0],\n y2 = p[1],\n dx2 = x2 - x0,\n dy2 = y2 - y0,\n dz = dy * dx2 - dx * dy2;\n if (dz * dz / d2 > delta2 // perpendicular projected distance\n || abs((dx * dx2 + dy * dy2) / d2 - 0.5) > 0.3 // midpoint close to an end\n || a0 * a1 + b0 * b1 + c0 * c1 < cosMinDistance) { // angular distance\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x2, y2, lambda2, a /= m, b /= m, c, depth, stream);\n stream.point(x2, y2);\n resampleLineTo(x2, y2, lambda2, a, b, c, x1, y1, lambda1, a1, b1, c1, depth, stream);\n }\n }\n }\n return function(stream) {\n var lambda00, x00, y00, a00, b00, c00, // first point\n lambda0, x0, y0, a0, b0, c0; // previous point\n\n var resampleStream = {\n point: point,\n lineStart: lineStart,\n lineEnd: lineEnd,\n polygonStart: function() { stream.polygonStart(); resampleStream.lineStart = ringStart; },\n polygonEnd: function() { stream.polygonEnd(); resampleStream.lineStart = lineStart; }\n };\n\n function point(x, y) {\n x = project(x, y);\n stream.point(x[0], x[1]);\n }\n\n function lineStart() {\n x0 = NaN;\n resampleStream.point = linePoint;\n stream.lineStart();\n }\n\n function linePoint(lambda, phi) {\n var c = cartesian_cartesian([lambda, phi]), p = project(lambda, phi);\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x0 = p[0], y0 = p[1], lambda0 = lambda, a0 = c[0], b0 = c[1], c0 = c[2], maxDepth, stream);\n stream.point(x0, y0);\n }\n\n function lineEnd() {\n resampleStream.point = point;\n stream.lineEnd();\n }\n\n function ringStart() {\n lineStart();\n resampleStream.point = ringPoint;\n resampleStream.lineEnd = ringEnd;\n }\n\n function ringPoint(lambda, phi) {\n linePoint(lambda00 = lambda, phi), x00 = x0, y00 = y0, a00 = a0, b00 = b0, c00 = c0;\n resampleStream.point = linePoint;\n }\n\n function ringEnd() {\n resampleLineTo(x0, y0, lambda0, a0, b0, c0, x00, y00, lambda00, a00, b00, c00, maxDepth, stream);\n resampleStream.lineEnd = lineEnd;\n lineEnd();\n }\n\n return resampleStream;\n };\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/index.js\n\n\n\n\n\n\n\n\n\n\n\nvar transformRadians = transformer({\n point: function(x, y) {\n this.stream.point(x * radians, y * radians);\n }\n});\n\nfunction projection_projection(project) {\n return projectionMutator(function() { return project; })();\n}\n\nfunction projectionMutator(projectAt) {\n var project,\n k = 150, // scale\n x = 480, y = 250, // translate\n dx, dy, lambda = 0, phi = 0, // center\n deltaLambda = 0, deltaPhi = 0, deltaGamma = 0, rotate, projectRotate, // rotate\n theta = null, preclip = clip_antimeridian, // clip angle\n x0 = null, y0, x1, y1, postclip = src_identity, // clip extent\n delta2 = 0.5, projectResample = resample(projectTransform, delta2), // precision\n cache,\n cacheStream;\n\n function projection(point) {\n point = projectRotate(point[0] * radians, point[1] * radians);\n return [point[0] * k + dx, dy - point[1] * k];\n }\n\n function invert(point) {\n point = projectRotate.invert((point[0] - dx) / k, (dy - point[1]) / k);\n return point && [point[0] * degrees, point[1] * degrees];\n }\n\n function projectTransform(x, y) {\n return x = project(x, y), [x[0] * k + dx, dy - x[1] * k];\n }\n\n projection.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = transformRadians(preclip(rotate, projectResample(postclip(cacheStream = stream))));\n };\n\n projection.clipAngle = function(_) {\n return arguments.length ? (preclip = +_ ? clip_circle(theta = _ * radians, 6 * radians) : (theta = null, clip_antimeridian), reset()) : theta * degrees;\n };\n\n projection.clipExtent = function(_) {\n return arguments.length ? (postclip = _ == null ? (x0 = y0 = x1 = y1 = null, src_identity) : extent_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n projection.scale = function(_) {\n return arguments.length ? (k = +_, recenter()) : k;\n };\n\n projection.translate = function(_) {\n return arguments.length ? (x = +_[0], y = +_[1], recenter()) : [x, y];\n };\n\n projection.center = function(_) {\n return arguments.length ? (lambda = _[0] % 360 * radians, phi = _[1] % 360 * radians, recenter()) : [lambda * degrees, phi * degrees];\n };\n\n projection.rotate = function(_) {\n return arguments.length ? (deltaLambda = _[0] % 360 * radians, deltaPhi = _[1] % 360 * radians, deltaGamma = _.length > 2 ? _[2] % 360 * radians : 0, recenter()) : [deltaLambda * degrees, deltaPhi * degrees, deltaGamma * degrees];\n };\n\n projection.precision = function(_) {\n return arguments.length ? (projectResample = resample(projectTransform, delta2 = _ * _), reset()) : sqrt(delta2);\n };\n\n projection.fitExtent = function(extent, object) {\n return fitExtent(projection, extent, object);\n };\n\n projection.fitSize = function(size, object) {\n return fitSize(projection, size, object);\n };\n\n function recenter() {\n projectRotate = compose(rotate = rotateRadians(deltaLambda, deltaPhi, deltaGamma), project);\n var center = project(lambda, phi);\n dx = x - center[0] * k;\n dy = y + center[1] * k;\n return reset();\n }\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return function() {\n project = projectAt.apply(this, arguments);\n projection.invert = project.invert && invert;\n return recenter();\n };\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conic.js\n\n\n\nfunction conicProjection(projectAt) {\n var phi0 = 0,\n phi1 = pi / 3,\n m = projectionMutator(projectAt),\n p = m(phi0, phi1);\n\n p.parallels = function(_) {\n return arguments.length ? m(phi0 = _[0] * radians, phi1 = _[1] * radians) : [phi0 * degrees, phi1 * degrees];\n };\n\n return p;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/cylindricalEqualArea.js\n\n\nfunction cylindricalEqualAreaRaw(phi0) {\n var cosPhi0 = cos(phi0);\n\n function forward(lambda, phi) {\n return [lambda * cosPhi0, sin(phi) / cosPhi0];\n }\n\n forward.invert = function(x, y) {\n return [x / cosPhi0, asin(y * cosPhi0)];\n };\n\n return forward;\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conicEqualArea.js\n\n\n\n\nfunction conicEqualAreaRaw(y0, y1) {\n var sy0 = sin(y0), n = (sy0 + sin(y1)) / 2;\n\n // Are the parallels symmetrical around the Equator?\n if (abs(n) < epsilon) return cylindricalEqualAreaRaw(y0);\n\n var c = 1 + sy0 * (2 * n - sy0), r0 = sqrt(c) / n;\n\n function project(x, y) {\n var r = sqrt(c - 2 * n * sin(y)) / n;\n return [r * sin(x *= n), r0 - r * cos(x)];\n }\n\n project.invert = function(x, y) {\n var r0y = r0 - y;\n return [atan2(x, abs(r0y)) / n * math_sign(r0y), asin((c - (x * x + r0y * r0y) * n * n) / (2 * n))];\n };\n\n return project;\n}\n\n/* harmony default export */ var conicEqualArea = (function() {\n return conicProjection(conicEqualAreaRaw)\n .scale(155.424)\n .center([0, 33.6442]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/albers.js\n\n\n/* harmony default export */ var albers = (function() {\n return conicEqualArea()\n .parallels([29.5, 45.5])\n .scale(1070)\n .translate([480, 250])\n .rotate([96, 0])\n .center([-0.6, 38.7]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/albersUsa.js\n\n\n\n\n\n// The projections must have mutually exclusive clip regions on the sphere,\n// as this will avoid emitting interleaving lines and polygons.\nfunction multiplex(streams) {\n var n = streams.length;\n return {\n point: function(x, y) { var i = -1; while (++i < n) streams[i].point(x, y); },\n sphere: function() { var i = -1; while (++i < n) streams[i].sphere(); },\n lineStart: function() { var i = -1; while (++i < n) streams[i].lineStart(); },\n lineEnd: function() { var i = -1; while (++i < n) streams[i].lineEnd(); },\n polygonStart: function() { var i = -1; while (++i < n) streams[i].polygonStart(); },\n polygonEnd: function() { var i = -1; while (++i < n) streams[i].polygonEnd(); }\n };\n}\n\n// A composite projection for the United States, configured by default for\n// 960×500. The projection also works quite well at 960×600 if you change the\n// scale to 1285 and adjust the translate accordingly. The set of standard\n// parallels for each region comes from USGS, which is published here:\n// http://egsc.usgs.gov/isb/pubs/MapProjections/projections.html#albers\n/* harmony default export */ var projection_albersUsa = (function() {\n var cache,\n cacheStream,\n lower48 = albers(), lower48Point,\n alaska = conicEqualArea().rotate([154, 0]).center([-2, 58.5]).parallels([55, 65]), alaskaPoint, // EPSG:3338\n hawaii = conicEqualArea().rotate([157, 0]).center([-3, 19.9]).parallels([8, 18]), hawaiiPoint, // ESRI:102007\n point, pointStream = {point: function(x, y) { point = [x, y]; }};\n\n function albersUsa(coordinates) {\n var x = coordinates[0], y = coordinates[1];\n return point = null,\n (lower48Point.point(x, y), point)\n || (alaskaPoint.point(x, y), point)\n || (hawaiiPoint.point(x, y), point);\n }\n\n albersUsa.invert = function(coordinates) {\n var k = lower48.scale(),\n t = lower48.translate(),\n x = (coordinates[0] - t[0]) / k,\n y = (coordinates[1] - t[1]) / k;\n return (y >= 0.120 && y < 0.234 && x >= -0.425 && x < -0.214 ? alaska\n : y >= 0.166 && y < 0.234 && x >= -0.214 && x < -0.115 ? hawaii\n : lower48).invert(coordinates);\n };\n\n albersUsa.stream = function(stream) {\n return cache && cacheStream === stream ? cache : cache = multiplex([lower48.stream(cacheStream = stream), alaska.stream(stream), hawaii.stream(stream)]);\n };\n\n albersUsa.precision = function(_) {\n if (!arguments.length) return lower48.precision();\n lower48.precision(_), alaska.precision(_), hawaii.precision(_);\n return reset();\n };\n\n albersUsa.scale = function(_) {\n if (!arguments.length) return lower48.scale();\n lower48.scale(_), alaska.scale(_ * 0.35), hawaii.scale(_);\n return albersUsa.translate(lower48.translate());\n };\n\n albersUsa.translate = function(_) {\n if (!arguments.length) return lower48.translate();\n var k = lower48.scale(), x = +_[0], y = +_[1];\n\n lower48Point = lower48\n .translate(_)\n .clipExtent([[x - 0.455 * k, y - 0.238 * k], [x + 0.455 * k, y + 0.238 * k]])\n .stream(pointStream);\n\n alaskaPoint = alaska\n .translate([x - 0.307 * k, y + 0.201 * k])\n .clipExtent([[x - 0.425 * k + epsilon, y + 0.120 * k + epsilon], [x - 0.214 * k - epsilon, y + 0.234 * k - epsilon]])\n .stream(pointStream);\n\n hawaiiPoint = hawaii\n .translate([x - 0.205 * k, y + 0.212 * k])\n .clipExtent([[x - 0.214 * k + epsilon, y + 0.166 * k + epsilon], [x - 0.115 * k - epsilon, y + 0.234 * k - epsilon]])\n .stream(pointStream);\n\n return reset();\n };\n\n albersUsa.fitExtent = function(extent, object) {\n return fitExtent(albersUsa, extent, object);\n };\n\n albersUsa.fitSize = function(size, object) {\n return fitSize(albersUsa, size, object);\n };\n\n function reset() {\n cache = cacheStream = null;\n return albersUsa;\n }\n\n return albersUsa.scale(1070);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/azimuthal.js\n\n\nfunction azimuthalRaw(scale) {\n return function(x, y) {\n var cx = cos(x),\n cy = cos(y),\n k = scale(cx * cy);\n return [\n k * cy * sin(x),\n k * sin(y)\n ];\n }\n}\n\nfunction azimuthalInvert(angle) {\n return function(x, y) {\n var z = sqrt(x * x + y * y),\n c = angle(z),\n sc = sin(c),\n cc = cos(c);\n return [\n atan2(x * sc, z * cc),\n asin(z && y * sc / z)\n ];\n }\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/azimuthalEqualArea.js\n\n\n\n\nvar azimuthalEqualAreaRaw = azimuthalRaw(function(cxcy) {\n return sqrt(2 / (1 + cxcy));\n});\n\nazimuthalEqualAreaRaw.invert = azimuthalInvert(function(z) {\n return 2 * asin(z / 2);\n});\n\n/* harmony default export */ var azimuthalEqualArea = (function() {\n return projection_projection(azimuthalEqualAreaRaw)\n .scale(124.75)\n .clipAngle(180 - 1e-3);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/azimuthalEquidistant.js\n\n\n\n\nvar azimuthalEquidistantRaw = azimuthalRaw(function(c) {\n return (c = acos(c)) && c / sin(c);\n});\n\nazimuthalEquidistantRaw.invert = azimuthalInvert(function(z) {\n return z;\n});\n\n/* harmony default export */ var azimuthalEquidistant = (function() {\n return projection_projection(azimuthalEquidistantRaw)\n .scale(79.4188)\n .clipAngle(180 - 1e-3);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/mercator.js\n\n\n\n\nfunction mercatorRaw(lambda, phi) {\n return [lambda, log(tan((halfPi + phi) / 2))];\n}\n\nmercatorRaw.invert = function(x, y) {\n return [x, 2 * atan(exp(y)) - halfPi];\n};\n\n/* harmony default export */ var mercator = (function() {\n return mercatorProjection(mercatorRaw)\n .scale(961 / tau);\n});\n\nfunction mercatorProjection(project) {\n var m = projection_projection(project),\n center = m.center,\n scale = m.scale,\n translate = m.translate,\n clipExtent = m.clipExtent,\n x0 = null, y0, x1, y1; // clip extent\n\n m.scale = function(_) {\n return arguments.length ? (scale(_), reclip()) : scale();\n };\n\n m.translate = function(_) {\n return arguments.length ? (translate(_), reclip()) : translate();\n };\n\n m.center = function(_) {\n return arguments.length ? (center(_), reclip()) : center();\n };\n\n m.clipExtent = function(_) {\n return arguments.length ? ((_ == null ? x0 = y0 = x1 = y1 = null : (x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1])), reclip()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n };\n\n function reclip() {\n var k = pi * scale(),\n t = m(src_rotation(m.rotate()).invert([0, 0]));\n return clipExtent(x0 == null\n ? [[t[0] - k, t[1] - k], [t[0] + k, t[1] + k]] : project === mercatorRaw\n ? [[Math.max(t[0] - k, x0), y0], [Math.min(t[0] + k, x1), y1]]\n : [[x0, Math.max(t[1] - k, y0)], [x1, Math.min(t[1] + k, y1)]]);\n }\n\n return reclip();\n}\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conicConformal.js\n\n\n\n\nfunction tany(y) {\n return tan((halfPi + y) / 2);\n}\n\nfunction conicConformalRaw(y0, y1) {\n var cy0 = cos(y0),\n n = y0 === y1 ? sin(y0) : log(cy0 / cos(y1)) / log(tany(y1) / tany(y0)),\n f = cy0 * pow(tany(y0), n) / n;\n\n if (!n) return mercatorRaw;\n\n function project(x, y) {\n if (f > 0) { if (y < -halfPi + epsilon) y = -halfPi + epsilon; }\n else { if (y > halfPi - epsilon) y = halfPi - epsilon; }\n var r = f / pow(tany(y), n);\n return [r * sin(n * x), f - r * cos(n * x)];\n }\n\n project.invert = function(x, y) {\n var fy = f - y, r = math_sign(n) * sqrt(x * x + fy * fy);\n return [atan2(x, abs(fy)) / n * math_sign(fy), 2 * atan(pow(f / r, 1 / n)) - halfPi];\n };\n\n return project;\n}\n\n/* harmony default export */ var conicConformal = (function() {\n return conicProjection(conicConformalRaw)\n .scale(109.5)\n .parallels([30, 30]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/equirectangular.js\n\n\nfunction equirectangularRaw(lambda, phi) {\n return [lambda, phi];\n}\n\nequirectangularRaw.invert = equirectangularRaw;\n\n/* harmony default export */ var equirectangular = (function() {\n return projection_projection(equirectangularRaw)\n .scale(152.63);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/conicEquidistant.js\n\n\n\n\nfunction conicEquidistantRaw(y0, y1) {\n var cy0 = cos(y0),\n n = y0 === y1 ? sin(y0) : (cy0 - cos(y1)) / (y1 - y0),\n g = cy0 / n + y0;\n\n if (abs(n) < epsilon) return equirectangularRaw;\n\n function project(x, y) {\n var gy = g - y, nx = n * x;\n return [gy * sin(nx), g - gy * cos(nx)];\n }\n\n project.invert = function(x, y) {\n var gy = g - y;\n return [atan2(x, abs(gy)) / n * math_sign(gy), g - math_sign(n) * sqrt(x * x + gy * gy)];\n };\n\n return project;\n}\n\n/* harmony default export */ var conicEquidistant = (function() {\n return conicProjection(conicEquidistantRaw)\n .scale(131.154)\n .center([0, 13.9389]);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/gnomonic.js\n\n\n\n\nfunction gnomonicRaw(x, y) {\n var cy = cos(y), k = cos(x) * cy;\n return [cy * sin(x) / k, sin(y) / k];\n}\n\ngnomonicRaw.invert = azimuthalInvert(atan);\n\n/* harmony default export */ var gnomonic = (function() {\n return projection_projection(gnomonicRaw)\n .scale(144.049)\n .clipAngle(60);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/identity.js\n\n\n\n\n\nfunction scaleTranslate(kx, ky, tx, ty) {\n return kx === 1 && ky === 1 && tx === 0 && ty === 0 ? src_identity : transformer({\n point: function(x, y) {\n this.stream.point(x * kx + tx, y * ky + ty);\n }\n });\n}\n\n/* harmony default export */ var projection_identity = (function() {\n var k = 1, tx = 0, ty = 0, sx = 1, sy = 1, transform = src_identity, // scale, translate and reflect\n x0 = null, y0, x1, y1, clip = src_identity, // clip extent\n cache,\n cacheStream,\n projection;\n\n function reset() {\n cache = cacheStream = null;\n return projection;\n }\n\n return projection = {\n stream: function(stream) {\n return cache && cacheStream === stream ? cache : cache = transform(clip(cacheStream = stream));\n },\n clipExtent: function(_) {\n return arguments.length ? (clip = _ == null ? (x0 = y0 = x1 = y1 = null, src_identity) : extent_clipExtent(x0 = +_[0][0], y0 = +_[0][1], x1 = +_[1][0], y1 = +_[1][1]), reset()) : x0 == null ? null : [[x0, y0], [x1, y1]];\n },\n scale: function(_) {\n return arguments.length ? (transform = scaleTranslate((k = +_) * sx, k * sy, tx, ty), reset()) : k;\n },\n translate: function(_) {\n return arguments.length ? (transform = scaleTranslate(k * sx, k * sy, tx = +_[0], ty = +_[1]), reset()) : [tx, ty];\n },\n reflectX: function(_) {\n return arguments.length ? (transform = scaleTranslate(k * (sx = _ ? -1 : 1), k * sy, tx, ty), reset()) : sx < 0;\n },\n reflectY: function(_) {\n return arguments.length ? (transform = scaleTranslate(k * sx, k * (sy = _ ? -1 : 1), tx, ty), reset()) : sy < 0;\n },\n fitExtent: function(extent, object) {\n return fitExtent(projection, extent, object);\n },\n fitSize: function(size, object) {\n return fitSize(projection, size, object);\n }\n };\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/naturalEarth1.js\n\n\n\nfunction naturalEarth1Raw(lambda, phi) {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n return [\n lambda * (0.8707 - 0.131979 * phi2 + phi4 * (-0.013791 + phi4 * (0.003971 * phi2 - 0.001529 * phi4))),\n phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4)))\n ];\n}\n\nnaturalEarth1Raw.invert = function(x, y) {\n var phi = y, i = 25, delta;\n do {\n var phi2 = phi * phi, phi4 = phi2 * phi2;\n phi -= delta = (phi * (1.007226 + phi2 * (0.015085 + phi4 * (-0.044475 + 0.028874 * phi2 - 0.005916 * phi4))) - y) /\n (1.007226 + phi2 * (0.015085 * 3 + phi4 * (-0.044475 * 7 + 0.028874 * 9 * phi2 - 0.005916 * 11 * phi4)));\n } while (abs(delta) > epsilon && --i > 0);\n return [\n x / (0.8707 + (phi2 = phi * phi) * (-0.131979 + phi2 * (-0.013791 + phi2 * phi2 * phi2 * (0.003971 - 0.001529 * phi2)))),\n phi\n ];\n};\n\n/* harmony default export */ var naturalEarth1 = (function() {\n return projection_projection(naturalEarth1Raw)\n .scale(175.295);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/orthographic.js\n\n\n\n\nfunction orthographicRaw(x, y) {\n return [cos(y) * sin(x), sin(y)];\n}\n\northographicRaw.invert = azimuthalInvert(asin);\n\n/* harmony default export */ var orthographic = (function() {\n return projection_projection(orthographicRaw)\n .scale(249.5)\n .clipAngle(90 + epsilon);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/stereographic.js\n\n\n\n\nfunction stereographicRaw(x, y) {\n var cy = cos(y), k = 1 + cos(x) * cy;\n return [cy * sin(x) / k, sin(y) / k];\n}\n\nstereographicRaw.invert = azimuthalInvert(function(z) {\n return 2 * atan(z);\n});\n\n/* harmony default export */ var stereographic = (function() {\n return projection_projection(stereographicRaw)\n .scale(250)\n .clipAngle(142);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/src/projection/transverseMercator.js\n\n\n\nfunction transverseMercatorRaw(lambda, phi) {\n return [log(tan((halfPi + phi) / 2)), -lambda];\n}\n\ntransverseMercatorRaw.invert = function(x, y) {\n return [-y, 2 * atan(exp(x)) - halfPi];\n};\n\n/* harmony default export */ var transverseMercator = (function() {\n var m = mercatorProjection(transverseMercatorRaw),\n center = m.center,\n rotate = m.rotate;\n\n m.center = function(_) {\n return arguments.length ? center([-_[1], _[0]]) : (_ = center(), [_[1], -_[0]]);\n };\n\n m.rotate = function(_) {\n return arguments.length ? rotate([_[0], _[1], _.length > 2 ? _[2] + 90 : 90]) : (_ = rotate(), [_[0], _[1], _[2] - 90]);\n };\n\n return rotate([0, 0, 90])\n .scale(159.155);\n});\n\n// CONCATENATED MODULE: ./node_modules/d3-geo/index.js\n\n\n\n\n // DEPRECATED! Use d3.geoIdentity().clipExtent(…).\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/buffer/node_modules/@turf/helpers/main.es.js\n/**\n * Earth Radius used with the Harvesine formula and approximates using a spherical (non-ellipsoid) Earth.\n */\nvar helpers_main_es_earthRadius = 6371008.8;\n\n/**\n * Unit of measurement factors using a spherical (non-ellipsoid) earth radius.\n */\nvar helpers_main_es_factors = {\n meters: helpers_main_es_earthRadius,\n metres: helpers_main_es_earthRadius,\n millimeters: helpers_main_es_earthRadius * 1000,\n millimetres: helpers_main_es_earthRadius * 1000,\n centimeters: helpers_main_es_earthRadius * 100,\n centimetres: helpers_main_es_earthRadius * 100,\n kilometers: helpers_main_es_earthRadius / 1000,\n kilometres: helpers_main_es_earthRadius / 1000,\n miles: helpers_main_es_earthRadius / 1609.344,\n nauticalmiles: helpers_main_es_earthRadius / 1852,\n inches: helpers_main_es_earthRadius * 39.370,\n yards: helpers_main_es_earthRadius / 1.0936,\n feet: helpers_main_es_earthRadius * 3.28084,\n radians: 1,\n degrees: helpers_main_es_earthRadius / 111325,\n};\n\n/**\n * Units of measurement factors based on 1 meter.\n */\nvar helpers_main_es_unitsFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000,\n millimetres: 1000,\n centimeters: 100,\n centimetres: 100,\n kilometers: 1 / 1000,\n kilometres: 1 / 1000,\n miles: 1 / 1609.344,\n nauticalmiles: 1 / 1852,\n inches: 39.370,\n yards: 1 / 1.0936,\n feet: 3.28084,\n radians: 1 / helpers_main_es_earthRadius,\n degrees: 1 / 111325,\n};\n\n/**\n * Area of measurement factors based on 1 square meter.\n */\nvar helpers_main_es_areaFactors = {\n meters: 1,\n metres: 1,\n millimeters: 1000000,\n millimetres: 1000000,\n centimeters: 10000,\n centimetres: 10000,\n kilometers: 0.000001,\n kilometres: 0.000001,\n acres: 0.000247105,\n miles: 3.86e-7,\n yards: 1.195990046,\n feet: 10.763910417,\n inches: 1550.003100006\n};\n\n/**\n * Wraps a GeoJSON {@link Geometry} in a GeoJSON {@link Feature}.\n *\n * @name feature\n * @param {Geometry} geometry input geometry\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON Feature\n * @example\n * var geometry = {\n * \"type\": \"Point\",\n * \"coordinates\": [110, 50]\n * };\n *\n * var feature = turf.feature(geometry);\n *\n * //=feature\n */\nfunction _turf_helpers_main_es_feature(geometry, properties, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers_main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (geometry === undefined) throw new Error('geometry is required');\n if (properties && properties.constructor !== Object) throw new Error('properties must be an Object');\n if (bbox) helpers_main_es_validateBBox(bbox);\n if (id) helpers_main_es_validateId(id);\n\n // Main\n var feat = {type: 'Feature'};\n if (id) feat.id = id;\n if (bbox) feat.bbox = bbox;\n feat.properties = properties || {};\n feat.geometry = geometry;\n return feat;\n}\n\n/**\n * Creates a GeoJSON {@link Geometry} from a Geometry string type & coordinates.\n * For GeometryCollection type use `helpers.geometryCollection`\n *\n * @name geometry\n * @param {string} type Geometry Type\n * @param {Array} coordinates Coordinates\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Geometry\n * @returns {Geometry} a GeoJSON Geometry\n * @example\n * var type = 'Point';\n * var coordinates = [110, 50];\n *\n * var geometry = turf.geometry(type, coordinates);\n *\n * //=geometry\n */\nfunction _turf_helpers_main_es_geometry(type, coordinates, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers_main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n\n // Validation\n if (!type) throw new Error('type is required');\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (bbox) helpers_main_es_validateBBox(bbox);\n\n // Main\n var geom;\n switch (type) {\n case 'Point': geom = _turf_helpers_main_es_point(coordinates).geometry; break;\n case 'LineString': geom = helpers_main_es_lineString(coordinates).geometry; break;\n case 'Polygon': geom = _turf_helpers_main_es_polygon(coordinates).geometry; break;\n case 'MultiPoint': geom = helpers_main_es_multiPoint(coordinates).geometry; break;\n case 'MultiLineString': geom = helpers_main_es_multiLineString(coordinates).geometry; break;\n case 'MultiPolygon': geom = helpers_main_es_multiPolygon(coordinates).geometry; break;\n default: throw new Error(type + ' is invalid');\n }\n if (bbox) geom.bbox = bbox;\n return geom;\n}\n\n/**\n * Creates a {@link Point} {@link Feature} from a Position.\n *\n * @name point\n * @param {Array} coordinates longitude, latitude position (each in decimal degrees)\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a Point feature\n * @example\n * var point = turf.point([-75.343, 39.984]);\n *\n * //=point\n */\nfunction _turf_helpers_main_es_point(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n if (coordinates.length < 2) throw new Error('coordinates must be at least 2 numbers long');\n if (!helpers_main_es_isNumber(coordinates[0]) || !helpers_main_es_isNumber(coordinates[1])) throw new Error('coordinates must contain numbers');\n\n return _turf_helpers_main_es_feature({\n type: 'Point',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Point} {@link FeatureCollection} from an Array of Point coordinates.\n *\n * @name points\n * @param {Array>} coordinates an array of Points\n * @param {Object} [properties={}] Translate these properties to each Feature\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Point Feature\n * @example\n * var points = turf.points([\n * [-75, 39],\n * [-80, 45],\n * [-78, 50]\n * ]);\n *\n * //=points\n */\nfunction _turf_helpers_main_es_points(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return helpers_main_es_featureCollection(coordinates.map(function (coords) {\n return _turf_helpers_main_es_point(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link Polygon} {@link Feature} from an Array of LinearRings.\n *\n * @name polygon\n * @param {Array>>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} Polygon Feature\n * @example\n * var polygon = turf.polygon([[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]], { name: 'poly1' });\n *\n * //=polygon\n */\nfunction _turf_helpers_main_es_polygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n for (var i = 0; i < coordinates.length; i++) {\n var ring = coordinates[i];\n if (ring.length < 4) {\n throw new Error('Each LinearRing of a Polygon must have 4 or more Positions.');\n }\n for (var j = 0; j < ring[ring.length - 1].length; j++) {\n // Check if first point of Polygon contains two numbers\n if (i === 0 && j === 0 && !helpers_main_es_isNumber(ring[0][0]) || !helpers_main_es_isNumber(ring[0][1])) throw new Error('coordinates must contain numbers');\n if (ring[ring.length - 1][j] !== ring[0][j]) {\n throw new Error('First and last Position are not equivalent.');\n }\n }\n }\n\n return _turf_helpers_main_es_feature({\n type: 'Polygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Polygon} {@link FeatureCollection} from an Array of Polygon coordinates.\n *\n * @name polygons\n * @param {Array>>>} coordinates an array of Polygon coordinates\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} Polygon FeatureCollection\n * @example\n * var polygons = turf.polygons([\n * [[[-5, 52], [-4, 56], [-2, 51], [-7, 54], [-5, 52]]],\n * [[[-15, 42], [-14, 46], [-12, 41], [-17, 44], [-15, 42]]],\n * ]);\n *\n * //=polygons\n */\nfunction helpers_main_es_polygons(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return helpers_main_es_featureCollection(coordinates.map(function (coords) {\n return _turf_helpers_main_es_polygon(coords, properties);\n }), options);\n}\n\n/**\n * Creates a {@link LineString} {@link Feature} from an Array of Positions.\n *\n * @name lineString\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} LineString Feature\n * @example\n * var linestring1 = turf.lineString([[-24, 63], [-23, 60], [-25, 65], [-20, 69]], {name: 'line 1'});\n * var linestring2 = turf.lineString([[-14, 43], [-13, 40], [-15, 45], [-10, 49]], {name: 'line 2'});\n *\n * //=linestring1\n * //=linestring2\n */\nfunction helpers_main_es_lineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (coordinates.length < 2) throw new Error('coordinates must be an array of two or more positions');\n // Check if first point of LineString contains two numbers\n if (!helpers_main_es_isNumber(coordinates[0][1]) || !helpers_main_es_isNumber(coordinates[0][1])) throw new Error('coordinates must contain numbers');\n\n return _turf_helpers_main_es_feature({\n type: 'LineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link LineString} {@link FeatureCollection} from an Array of LineString coordinates.\n *\n * @name lineStrings\n * @param {Array>} coordinates an array of LinearRings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the FeatureCollection\n * @param {string|number} [options.id] Identifier associated with the FeatureCollection\n * @returns {FeatureCollection} LineString FeatureCollection\n * @example\n * var linestrings = turf.lineStrings([\n * [[-24, 63], [-23, 60], [-25, 65], [-20, 69]],\n * [[-14, 43], [-13, 40], [-15, 45], [-10, 49]]\n * ]);\n *\n * //=linestrings\n */\nfunction helpers_main_es_lineStrings(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n if (!Array.isArray(coordinates)) throw new Error('coordinates must be an Array');\n\n return helpers_main_es_featureCollection(coordinates.map(function (coords) {\n return helpers_main_es_lineString(coords, properties);\n }), options);\n}\n\n/**\n * Takes one or more {@link Feature|Features} and creates a {@link FeatureCollection}.\n *\n * @name featureCollection\n * @param {Feature[]} features input features\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {FeatureCollection} FeatureCollection of Features\n * @example\n * var locationA = turf.point([-75.343, 39.984], {name: 'Location A'});\n * var locationB = turf.point([-75.833, 39.284], {name: 'Location B'});\n * var locationC = turf.point([-75.534, 39.123], {name: 'Location C'});\n *\n * var collection = turf.featureCollection([\n * locationA,\n * locationB,\n * locationC\n * ]);\n *\n * //=collection\n */\nfunction helpers_main_es_featureCollection(features, options) {\n // Optional Parameters\n options = options || {};\n if (!helpers_main_es_isObject(options)) throw new Error('options is invalid');\n var bbox = options.bbox;\n var id = options.id;\n\n // Validation\n if (!features) throw new Error('No features passed');\n if (!Array.isArray(features)) throw new Error('features must be an Array');\n if (bbox) helpers_main_es_validateBBox(bbox);\n if (id) helpers_main_es_validateId(id);\n\n // Main\n var fc = {type: 'FeatureCollection'};\n if (id) fc.id = id;\n if (bbox) fc.bbox = bbox;\n fc.features = features;\n return fc;\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiLineString\n * @param {Array>>} coordinates an array of LineStrings\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiLineString feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiLine = turf.multiLineString([[[0,0],[10,10]]]);\n *\n * //=multiLine\n */\nfunction helpers_main_es_multiLineString(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return _turf_helpers_main_es_feature({\n type: 'MultiLineString',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPoint\n * @param {Array>} coordinates an array of Positions\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a MultiPoint feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPt = turf.multiPoint([[0,0],[10,10]]);\n *\n * //=multiPt\n */\nfunction helpers_main_es_multiPoint(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return _turf_helpers_main_es_feature({\n type: 'MultiPoint',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name multiPolygon\n * @param {Array>>>} coordinates an array of Polygons\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a multipolygon feature\n * @throws {Error} if no coordinates are passed\n * @example\n * var multiPoly = turf.multiPolygon([[[[0,0],[0,10],[10,10],[10,0],[0,0]]]]);\n *\n * //=multiPoly\n *\n */\nfunction helpers_main_es_multiPolygon(coordinates, properties, options) {\n if (!coordinates) throw new Error('coordinates is required');\n\n return _turf_helpers_main_es_feature({\n type: 'MultiPolygon',\n coordinates: coordinates\n }, properties, options);\n}\n\n/**\n * Creates a {@link Feature} based on a\n * coordinate array. Properties can be added optionally.\n *\n * @name geometryCollection\n * @param {Array} geometries an array of GeoJSON Geometries\n * @param {Object} [properties={}] an Object of key-value pairs to add as properties\n * @param {Object} [options={}] Optional Parameters\n * @param {Array} [options.bbox] Bounding Box Array [west, south, east, north] associated with the Feature\n * @param {string|number} [options.id] Identifier associated with the Feature\n * @returns {Feature} a GeoJSON GeometryCollection Feature\n * @example\n * var pt = {\n * \"type\": \"Point\",\n * \"coordinates\": [100, 0]\n * };\n * var line = {\n * \"type\": \"LineString\",\n * \"coordinates\": [ [101, 0], [102, 1] ]\n * };\n * var collection = turf.geometryCollection([pt, line]);\n *\n * //=collection\n */\nfunction helpers_main_es_geometryCollection(geometries, properties, options) {\n if (!geometries) throw new Error('geometries is required');\n if (!Array.isArray(geometries)) throw new Error('geometries must be an Array');\n\n return _turf_helpers_main_es_feature({\n type: 'GeometryCollection',\n geometries: geometries\n }, properties, options);\n}\n\n/**\n * Round number to precision\n *\n * @param {number} num Number\n * @param {number} [precision=0] Precision\n * @returns {number} rounded number\n * @example\n * turf.round(120.4321)\n * //=120\n *\n * turf.round(120.4321, 2)\n * //=120.43\n */\nfunction helpers_main_es_round(num, precision) {\n if (num === undefined || num === null || isNaN(num)) throw new Error('num is required');\n if (precision && !(precision >= 0)) throw new Error('precision must be a positive number');\n var multiplier = Math.pow(10, precision || 0);\n return Math.round(num * multiplier) / multiplier;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from radians to a more friendly unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name radiansToLength\n * @param {number} radians in radians across the sphere\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} distance\n */\nfunction helpers_main_es_radiansToLength(radians, units) {\n if (radians === undefined || radians === null) throw new Error('radians is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = helpers_main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return radians * factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into radians\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @name lengthToRadians\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} radians\n */\nfunction helpers_main_es_lengthToRadians(distance, units) {\n if (distance === undefined || distance === null) throw new Error('distance is required');\n\n if (units && typeof units !== 'string') throw new Error('units must be a string');\n var factor = helpers_main_es_factors[units || 'kilometers'];\n if (!factor) throw new Error(units + ' units is invalid');\n return distance / factor;\n}\n\n/**\n * Convert a distance measurement (assuming a spherical Earth) from a real-world unit into degrees\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, centimeters, kilometres, feet\n *\n * @name lengthToDegrees\n * @param {number} distance in real units\n * @param {string} [units='kilometers'] can be degrees, radians, miles, or kilometers inches, yards, metres, meters, kilometres, kilometers.\n * @returns {number} degrees\n */\nfunction helpers_main_es_lengthToDegrees(distance, units) {\n return helpers_main_es_radiansToDegrees(helpers_main_es_lengthToRadians(distance, units));\n}\n\n/**\n * Converts any bearing angle from the north line direction (positive clockwise)\n * and returns an angle between 0-360 degrees (positive clockwise), 0 being the north line\n *\n * @name bearingToAzimuth\n * @param {number} bearing angle, between -180 and +180 degrees\n * @returns {number} angle between 0 and 360 degrees\n */\nfunction helpers_main_es_bearingToAzimuth(bearing) {\n if (bearing === null || bearing === undefined) throw new Error('bearing is required');\n\n var angle = bearing % 360;\n if (angle < 0) angle += 360;\n return angle;\n}\n\n/**\n * Converts an angle in radians to degrees\n *\n * @name radiansToDegrees\n * @param {number} radians angle in radians\n * @returns {number} degrees between 0 and 360 degrees\n */\nfunction helpers_main_es_radiansToDegrees(radians) {\n if (radians === null || radians === undefined) throw new Error('radians is required');\n\n var degrees = radians % (2 * Math.PI);\n return degrees * 180 / Math.PI;\n}\n\n/**\n * Converts an angle in degrees to radians\n *\n * @name degreesToRadians\n * @param {number} degrees angle between 0 and 360 degrees\n * @returns {number} angle in radians\n */\nfunction helpers_main_es_degreesToRadians(degrees) {\n if (degrees === null || degrees === undefined) throw new Error('degrees is required');\n\n var radians = degrees % 360;\n return radians * Math.PI / 180;\n}\n\n/**\n * Converts a length to the requested unit.\n * Valid units: miles, nauticalmiles, inches, yards, meters, metres, kilometers, centimeters, feet\n *\n * @param {number} length to be converted\n * @param {string} originalUnit of the length\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted length\n */\nfunction helpers_main_es_convertLength(length, originalUnit, finalUnit) {\n if (length === null || length === undefined) throw new Error('length is required');\n if (!(length >= 0)) throw new Error('length must be a positive number');\n\n return helpers_main_es_radiansToLength(helpers_main_es_lengthToRadians(length, originalUnit), finalUnit || 'kilometers');\n}\n\n/**\n * Converts a area to the requested unit.\n * Valid units: kilometers, kilometres, meters, metres, centimetres, millimeters, acres, miles, yards, feet, inches\n * @param {number} area to be converted\n * @param {string} [originalUnit='meters'] of the distance\n * @param {string} [finalUnit='kilometers'] returned unit\n * @returns {number} the converted distance\n */\nfunction helpers_main_es_convertArea(area, originalUnit, finalUnit) {\n if (area === null || area === undefined) throw new Error('area is required');\n if (!(area >= 0)) throw new Error('area must be a positive number');\n\n var startFactor = helpers_main_es_areaFactors[originalUnit || 'meters'];\n if (!startFactor) throw new Error('invalid original units');\n\n var finalFactor = helpers_main_es_areaFactors[finalUnit || 'kilometers'];\n if (!finalFactor) throw new Error('invalid final units');\n\n return (area / startFactor) * finalFactor;\n}\n\n/**\n * isNumber\n *\n * @param {*} num Number to validate\n * @returns {boolean} true/false\n * @example\n * turf.isNumber(123)\n * //=true\n * turf.isNumber('foo')\n * //=false\n */\nfunction helpers_main_es_isNumber(num) {\n return !isNaN(num) && num !== null && !Array.isArray(num);\n}\n\n/**\n * isObject\n *\n * @param {*} input variable to validate\n * @returns {boolean} true/false\n * @example\n * turf.isObject({elevation: 10})\n * //=true\n * turf.isObject('foo')\n * //=false\n */\nfunction helpers_main_es_isObject(input) {\n return (!!input) && (input.constructor === Object);\n}\n\n/**\n * Validate BBox\n *\n * @private\n * @param {Array} bbox BBox to validate\n * @returns {void}\n * @throws Error if BBox is not valid\n * @example\n * validateBBox([-180, -40, 110, 50])\n * //=OK\n * validateBBox([-180, -40])\n * //=Error\n * validateBBox('Foo')\n * //=Error\n * validateBBox(5)\n * //=Error\n * validateBBox(null)\n * //=Error\n * validateBBox(undefined)\n * //=Error\n */\nfunction helpers_main_es_validateBBox(bbox) {\n if (!bbox) throw new Error('bbox is required');\n if (!Array.isArray(bbox)) throw new Error('bbox must be an Array');\n if (bbox.length !== 4 && bbox.length !== 6) throw new Error('bbox must be an Array of 4 or 6 numbers');\n bbox.forEach(function (num) {\n if (!helpers_main_es_isNumber(num)) throw new Error('bbox must only contain numbers');\n });\n}\n\n/**\n * Validate Id\n *\n * @private\n * @param {string|number} id Id to validate\n * @returns {void}\n * @throws Error if Id is not valid\n * @example\n * validateId([-180, -40, 110, 50])\n * //=Error\n * validateId([-180, -40])\n * //=Error\n * validateId('Foo')\n * //=OK\n * validateId(5)\n * //=OK\n * validateId(null)\n * //=Error\n * validateId(undefined)\n * //=Error\n */\nfunction helpers_main_es_validateId(id) {\n if (!id) throw new Error('id is required');\n if (['string', 'number'].indexOf(typeof id) === -1) throw new Error('id must be a number or a string');\n}\n\n// Deprecated methods\nfunction helpers_main_es_radians2degrees() {\n throw new Error('method has been renamed to `radiansToDegrees`');\n}\n\nfunction helpers_main_es_degrees2radians() {\n throw new Error('method has been renamed to `degreesToRadians`');\n}\n\nfunction helpers_main_es_distanceToDegrees() {\n throw new Error('method has been renamed to `lengthToDegrees`');\n}\n\nfunction helpers_main_es_distanceToRadians() {\n throw new Error('method has been renamed to `lengthToRadians`');\n}\n\nfunction helpers_main_es_radiansToDistance() {\n throw new Error('method has been renamed to `radiansToLength`');\n}\n\nfunction helpers_main_es_bearingToAngle() {\n throw new Error('method has been renamed to `bearingToAzimuth`');\n}\n\nfunction helpers_main_es_convertDistance() {\n throw new Error('method has been renamed to `convertLength`');\n}\n\n\n\n// CONCATENATED MODULE: ./node_modules/@turf/buffer/main.es.js\n\n\n\n\n\n\n\n\n/**\n * Calculates a buffer for input features for a given radius. Units supported are miles, kilometers, and degrees.\n *\n * When using a negative radius, the resulting geometry may be invalid if\n * it's too small compared to the radius magnitude. If the input is a\n * FeatureCollection, only valid members will be returned in the output\n * FeatureCollection - i.e., the output collection may have fewer members than\n * the input, or even be empty.\n *\n * @name buffer\n * @param {FeatureCollection|Geometry|Feature} geojson input to be buffered\n * @param {number} radius distance to draw the buffer (negative values are allowed)\n * @param {Object} [options={}] Optional parameters\n * @param {string} [options.units=\"kilometers\"] any of the options supported by turf units\n * @param {number} [options.steps=64] number of steps\n * @returns {FeatureCollection|Feature|undefined} buffered features\n * @example\n * var point = turf.point([-90.548630, 14.616599]);\n * var buffered = turf.buffer(point, 500, {units: 'miles'});\n *\n * //addToMap\n * var addToMap = [point, buffered]\n */\nfunction main_es_buffer(geojson, radius, options) {\n // Optional params\n options = options || {};\n var units = options.units;\n var steps = options.steps || 64;\n\n // validation\n if (!geojson) throw new Error('geojson is required');\n if (typeof options !== 'object') throw new Error('options must be an object');\n if (typeof steps !== 'number') throw new Error('steps must be an number');\n\n // Allow negative buffers (\"erosion\") or zero-sized buffers (\"repair geometry\")\n if (radius === undefined) throw new Error('radius is required');\n if (steps <= 0) throw new Error('steps must be greater than 0');\n\n // default params\n steps = steps || 64;\n units = units || 'kilometers';\n\n var results = [];\n switch (geojson.type) {\n case 'GeometryCollection':\n Object(meta_main_es[\"d\" /* geomEach */])(geojson, function (geometry) {\n var buffered = bufferFeature(geometry, radius, units, steps);\n if (buffered) results.push(buffered);\n });\n return helpers_main_es_featureCollection(results);\n case 'FeatureCollection':\n Object(meta_main_es[\"b\" /* featureEach */])(geojson, function (feature$$1) {\n var multiBuffered = bufferFeature(feature$$1, radius, units, steps);\n if (multiBuffered) {\n Object(meta_main_es[\"b\" /* featureEach */])(multiBuffered, function (buffered) {\n if (buffered) results.push(buffered);\n });\n }\n });\n return helpers_main_es_featureCollection(results);\n }\n return bufferFeature(geojson, radius, units, steps);\n}\n\n/**\n * Buffer single Feature/Geometry\n *\n * @private\n * @param {Feature} geojson input to be buffered\n * @param {number} radius distance to draw the buffer\n * @param {string} [units='kilometers'] any of the options supported by turf units\n * @param {number} [steps=64] number of steps\n * @returns {Feature} buffered feature\n */\nfunction bufferFeature(geojson, radius, units, steps) {\n var properties = geojson.properties || {};\n var geometry = (geojson.type === 'Feature') ? geojson.geometry : geojson;\n\n // Geometry Types faster than jsts\n if (geometry.type === 'GeometryCollection') {\n var results = [];\n Object(meta_main_es[\"d\" /* geomEach */])(geojson, function (geometry) {\n var buffered = bufferFeature(geometry, radius, units, steps);\n if (buffered) results.push(buffered);\n });\n return helpers_main_es_featureCollection(results);\n }\n\n // Project GeoJSON to Transverse Mercator projection (convert to Meters)\n var projected;\n var bbox = Object(main_es[\"default\"])(geojson);\n var needsTransverseMercator = bbox[1] > 50 && bbox[3] > 50;\n\n if (needsTransverseMercator) {\n projected = {\n type: geometry.type,\n coordinates: projectCoords(geometry.coordinates, defineProjection(geometry))\n };\n } else {\n projected = toMercator(geometry);\n }\n\n // JSTS buffer operation\n var reader = new jsts_min[\"GeoJSONReader\"]();\n var geom = reader.read(projected);\n var distance = helpers_main_es_radiansToLength(helpers_main_es_lengthToRadians(radius, units), 'meters');\n var buffered = jsts_min[\"BufferOp\"].bufferOp(geom, distance);\n var writer = new jsts_min[\"GeoJSONWriter\"]();\n buffered = writer.write(buffered);\n\n // Detect if empty geometries\n if (coordsIsNaN(buffered.coordinates)) return undefined;\n\n // Unproject coordinates (convert to Degrees)\n var result;\n if (needsTransverseMercator) {\n result = {\n type: buffered.type,\n coordinates: unprojectCoords(buffered.coordinates, defineProjection(geometry))\n };\n } else {\n result = toWgs84(buffered);\n }\n\n return (result.geometry) ? result : _turf_helpers_main_es_feature(result, properties);\n}\n\n/**\n * Coordinates isNaN\n *\n * @private\n * @param {Array} coords GeoJSON Coordinates\n * @returns {boolean} if NaN exists\n */\nfunction coordsIsNaN(coords) {\n if (Array.isArray(coords[0])) return coordsIsNaN(coords[0]);\n return isNaN(coords[0]);\n}\n\n/**\n * Project coordinates to projection\n *\n * @private\n * @param {Array} coords to project\n * @param {GeoProjection} proj D3 Geo Projection\n * @returns {Array} projected coordinates\n */\nfunction projectCoords(coords, proj) {\n if (typeof coords[0] !== 'object') return proj(coords);\n return coords.map(function (coord) {\n return projectCoords(coord, proj);\n });\n}\n\n/**\n * Un-Project coordinates to projection\n *\n * @private\n * @param {Array} coords to un-project\n * @param {GeoProjection} proj D3 Geo Projection\n * @returns {Array} un-projected coordinates\n */\nfunction unprojectCoords(coords, proj) {\n if (typeof coords[0] !== 'object') return proj.invert(coords);\n return coords.map(function (coord) {\n return unprojectCoords(coord, proj);\n });\n}\n\n/**\n * Define Transverse Mercator projection\n *\n * @private\n * @param {Geometry|Feature} geojson Base projection on center of GeoJSON\n * @returns {GeoProjection} D3 Geo Transverse Mercator Projection\n */\nfunction defineProjection(geojson) {\n var coords = center_main_es(geojson).geometry.coordinates.reverse();\n var rotate = coords.map(function (coord) { return -coord; });\n return transverseMercator()\n .center(coords)\n .rotate(rotate)\n .scale(helpers_main_es_earthRadius);\n}\n\n/* harmony default export */ var buffer_main_es = __webpack_exports__[\"default\"] = (main_es_buffer);\n\n\n//# sourceURL=webpack:///./node_modules/@turf/buffer/main.es.js_+_95_modules?")}]); \ No newline at end of file diff --git a/docs/Agent.html b/docs/Agent.html index 5024e93..d8acacd 100644 --- a/docs/Agent.html +++ b/docs/Agent.html @@ -1858,13 +1858,13 @@
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/Agentmap.html b/docs/Agentmap.html index 6b1122f..f3e245f 100644 --- a/docs/Agentmap.html +++ b/docs/Agentmap.html @@ -792,7 +792,7 @@ -

buildingify(bounding_box, streets_data, street_optionsopt, unit_optionsopt, units_dataopt)

+

buildingify(bounding_box, OSM_data, street_optionsopt, unit_optionsopt, unit_layersopt, street_layersopt)

@@ -869,7 +869,7 @@ - streets_data + OSM_data @@ -1152,7 +1152,7 @@ - units_data + unit_layers @@ -1178,7 +1178,40 @@ - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + + + + + + + street_layers + + + + + +object + + + + + + + + + <optional>
+ + + + + + + + + + + If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. @@ -1219,7 +1252,7 @@
Source:
@@ -2525,13 +2558,13 @@
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/agentmap.js.html b/docs/agentmap.js.html index 664e913..f8ea207 100644 --- a/docs/agentmap.js.html +++ b/docs/agentmap.js.html @@ -337,13 +337,13 @@ exports.agentmap = agentmapFactory;
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/agents.js.html b/docs/agents.js.html index 46a7ca3..70fdfa2 100644 --- a/docs/agents.js.html +++ b/docs/agents.js.html @@ -816,13 +816,13 @@ exports.agent = agent;
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/buildings.js.html b/docs/buildings.js.html index 59657f7..10af537 100644 --- a/docs/buildings.js.html +++ b/docs/buildings.js.html @@ -43,30 +43,30 @@ getPathFinder = require('./routing').getPathFinder; * @instance * * @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates. - * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} [street_options] - An object containing the Leaflet styling options for streets. See available options here: {@link https://leafletjs.com/reference-1.3.2.html#polyline-l-polyline}. * @param {object} [unit_options] - An object containing the Leaflet & AgentMaps styling options for units.<br/>See available Leaflet options here: {@link https://leafletjs.com/reference-1.3.2.html#polygon-l-polygon}<br/>Additional AgentMaps-specific options are described below. * @param {number} [unit_options.front_buffer = 6] - The number of meters beetween the front of unit and its street. * @param {number} [unit_options.side_buffer = 3] - The number of meters between two units on the same street. * @param {number} [unit_options.length = 14] - The length of the unit in meters along the street. * @param {number} [unit_options.depth = 18] - The depth of the unit in meters out from its front. - * @param {object} [units_data]- If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + * @param {object} [unit_layers]- If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + * @param {object} [street_layers]- If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. */ -function buildingify(bounding_box, streets_data, street_options, unit_options, units_data) { - setupStreetFeatures.call(this, streets_data, street_options); - setupUnitFeatures.call(this, bounding_box, streets_data, unit_options, units_data); +function buildingify(bounding_box, OSM_data, street_options, unit_options, unit_layers, street_layers) { + setupStreetFeatures.call(this, OSM_data, street_options); + setupUnitFeatures.call(this, bounding_box, OSM_data, unit_options, unit_layers); } /** * Generate and setup streets based on the provided GeoJSON data. * - * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} street_options - An object containing the Leaflet styling options for streets. + * @param {object} [street_layers] - If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. */ -function setupStreetFeatures(streets_data, street_options) { - let street_features = getStreetFeatures(streets_data); - - default_options = { +function setupStreetFeatures(OSM_data, street_options, street_layers) { + let default_options = { "color": "yellow", "weight": 4, "opacity": .5 @@ -74,10 +74,19 @@ function setupStreetFeatures(streets_data, street_options) { street_options = Object.assign(default_options, street_options); - let street_feature_collection = { - type: "FeatureCollection", - features: street_features - }; + let street_feature_collection; + + if (typeof(street_layers) === "undefined") { + let street_features = getStreetFeatures(OSM_data); + + street_feature_collection = { + type: "FeatureCollection", + features: street_features + }; + } + else { + street_feature_collection = street_layers; + } this.streets = L.geoJSON( street_feature_collection, @@ -86,18 +95,18 @@ function setupStreetFeatures(streets_data, street_options) { //Map streets' OSM IDs to their Leaflet IDs. this.streets.id_map = {}; - + //Having added the streets as layers to the map, do any processing that requires access to those layers. this.streets.eachLayer(function(street) { this.streets.id_map[street.feature.id] = street._leaflet_id; - + addStreetLayerIntersections.call(this, street); }, this); //Add general graph-making and path-finder-making methods to Agentmap, in case streets are added, removed, or modified mid-simulation. this.streetsToGraph = streetsToGraph, - this.getPathFinder = getPathFinder; - + this.getPathFinder = getPathFinder; + this.streets.graph = streetsToGraph(this.streets), this.pathfinder = getPathFinder(this.streets.graph); } @@ -106,15 +115,15 @@ function setupStreetFeatures(streets_data, street_options) { * Get all streets from the GeoJSON data. * @private * - * @param {Object} streets_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box. + * @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM streets inside the bounding box. * @returns {Array<Feature>} - array of street features. */ -function getStreetFeatures(streets_data) { +function getStreetFeatures(OSM_data) { let street_features = []; - for (let i = 0; i < streets_data.features.length; ++i) { - let feature = streets_data.features[i]; - + for (let i = 0; i < OSM_data.features.length; ++i) { + let feature = OSM_data.features[i]; + if (feature.geometry.type === "LineString" && feature.properties.highway) { let street_feature = feature; @@ -161,11 +170,11 @@ function addStreetLayerIntersections(street) { * Generate and setup building units based on the provided GeoJSON data. * * @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates. - * @param {object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} unit_options - An object containing the Leaflet & AgentMaps styling options for units. - * @param {object} [units_data] - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + * @param {object} [unit_layers] - If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. */ -function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_data) { +function setupUnitFeatures(bounding_box, OSM_data, unit_options = {}, unit_layers) { let default_options = { "color": "green", "weight": 1, @@ -180,10 +189,10 @@ function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_ let unit_feature_collection; - //If no units_data is supplied, generate the units from scratch. - if (typeof(units_data) === "undefined") { + //If no unit_layers is supplied, generate the units from scratch. + if (typeof(unit_layers) === "undefined") { //Bind getUnitFeatures to "this" so it can access the agentmap as "this.agentmap". - let unit_features = getUnitFeatures.bind(this)(bounding_box, streets_data, unit_options); + let unit_features = getUnitFeatures.bind(this)(bounding_box, OSM_data, unit_options); unit_feature_collection = { type: "FeatureCollection", @@ -191,7 +200,7 @@ function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_ }; } else { - unit_feature_collection = units_data; + unit_feature_collection = unit_layers; } this.units = L.geoJSON( @@ -201,7 +210,7 @@ function setupUnitFeatures(bounding_box, streets_data, unit_options = {}, units_ //Having added the units as layers to the map, do any processing that requires access to those layers. this.units.eachLayer(function(unit) { - if (typeof(units_data) === "undefined") { + if (typeof(unit_layers) === "undefined") { unit.street_id = unit.feature.properties.street_id; } else { @@ -248,11 +257,11 @@ function getUnitNeighborLayerIDs(neighbors) { * @private * * @param {Array.<Array.<number>>} bounding_box - The map's top-left and bottom-right coordinates. - * @param {Object} streets_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. + * @param {Object} OSM_data - A GeoJSON Feature Collection object containing the OSM street features inside the bounding box. * @param {object} unit_options - An object containing the AgentMaps styling options for units. - * @returns {Array<Feature>} - array of features representing real estate units. + * @returns {Array<Feature>} - Array of features representing real estate units. */ -function getUnitFeatures(bounding_box, streets_data, unit_options) { +function getUnitFeatures(bounding_box, OSM_data, unit_options) { let proposed_unit_features = []; this.streets.eachLayer(function(layer) { @@ -438,7 +447,6 @@ function unitsOutOfStreets(unit_features, street_layers) { * @returns {boolean} - Whether the polygon_feature overlaps with any one in the array. */ function noOverlaps(reference_polygon_feature, polygon_feature_array) { - //return true; for (feature_array_element of polygon_feature_array) { let overlap_exists = intersect(reference_polygon_feature, feature_array_element); if (overlap_exists) { @@ -450,6 +458,7 @@ function noOverlaps(reference_polygon_feature, polygon_feature_array) { } Agentmap.prototype.buildingify = buildingify; +exports.buildingify = buildingify; @@ -460,13 +469,13 @@ Agentmap.prototype.buildingify = buildingify;
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/docs.md b/docs/docs.md index 0c25373..dd79f81 100644 --- a/docs/docs.md +++ b/docs/docs.md @@ -89,10 +89,18 @@ agentmap.buildingify(my_data, [[43.3071, -88.0158], [43.2884, -87.9759]]); `Agentmap.buildingify` accepts more arguments specifying the dimension and appearance of the units and streets it will build. For more on that, see the section on [Feature Styling](#feature-styling). `Agentmap.buildingify` does a lot of work checking for and removing overlapping units, and so the bigger your neighborhood, the noticeably longer it will take. -To compensate for this and help make your simulation more responsive, `Agentmap.buildingify`'s last parameter, after the styling options, accepts a `units_data` object: a GeoJSON FeatureGroup of units. -If one is passed as an argument, instead of generating the units from scratch, `Agentmap.buildingify` will more quickly just use the blueprints in `units_data`. +To compensate for this and help make your simulation more responsive, `Agentmap.buildingify`'s last two parameters, after the styling options, accept a `unit_layers` object and `street_layers` object respectively: a GeoJSON FeatureGroup of units or streets exported from a previous AgentMaps simulation. +If either of these is passed as an argument, instead of generating the unit or street layers from scratch, `Agentmap.buildingify` will more quickly just use the blueprints in `unit_layers` and `street_layers`. -How do you get a `units_data` object? Agentmaps have an [Agentmap.downloadUnits](./Agentmap.html#downloadUnits) method which, when called, will generate a *js* file containing a single variable named `units_data` defined as the vale of `Agentmap.units.toGeoJSON()`. +How do you get a `unit_layers` or `street_layers` object? Agentmaps have an +[Agentmap.downloadUnits](./Agentmap.html#downloadUnits) method and a [Agentmap.downloadStreets](./Agentmap.html#downloadStreets) +method which, when called, will generate a *js* file containing a single variable named `unit_data` or `street_data` defined as the vale of `Agentmap.units.toGeoJSON(20)` or `Agentmap.streets.toGeoJSON(20)` respectively. + +What if your OSM street data is too big for a browser to feasibly generate all the appropriate building layers? +The npm package comes with a command line tool named "featuretool" which, given the bounding coordinates and path to a file containing OSM-style GeoJSON, generates all the appropriate layers and exports them to files similar to those that `Agentmap.downloadUnits` and `Agentmap.downloadStreets` generate. +To use it, you need to have installed AgentMaps globally with `npm install -g AgentMaps`. + +To use featuretool, you'd do something like this: `featuretool --bbox [[39.9058,-86.0910],[39.8992,-86.1017]] --streets data/townmap.js`. ## Navigating Streets diff --git a/docs/global.html b/docs/global.html index 25cb887..e7ee812 100644 --- a/docs/global.html +++ b/docs/global.html @@ -1188,7 +1188,7 @@ -

setupStreetFeatures(streets_data, street_options)

+

setupStreetFeatures(OSM_data, street_options, street_layersopt)

@@ -1220,6 +1220,8 @@ Type + Attributes + @@ -1232,7 +1234,7 @@ - streets_data + OSM_data @@ -1245,6 +1247,14 @@ + + + + + + + + @@ -1268,6 +1278,14 @@ + + + + + + + + @@ -1275,6 +1293,39 @@ + + + + street_layers + + + + + +object + + + + + + + + + <optional>
+ + + + + + + + + + + If you want to load a previously generated AgentMaps.streets object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.streets featureGroup. + + + @@ -1312,7 +1363,7 @@
Source:
@@ -1346,7 +1397,7 @@ -

setupUnitFeatures(bounding_box, streets_data, unit_options, units_dataopt)

+

setupUnitFeatures(bounding_box, OSM_data, unit_options, unit_layersopt)

@@ -1423,7 +1474,7 @@ - streets_data + OSM_data @@ -1485,7 +1536,7 @@ - units_data + unit_layers @@ -1511,7 +1562,7 @@ - If you want to load a previously generated AgentMaps.units object instead of generating one from scarch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. + If you want to load a previously generated AgentMaps.units object instead of generating one from scratch: A GeoJSON Feature Collection of an AgentMaps.units featureGroup. @@ -1552,7 +1603,7 @@
Source:
@@ -2788,13 +2839,13 @@
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/help/extra.md b/docs/help/extra.md deleted file mode 100644 index a43b472..0000000 --- a/docs/help/extra.md +++ /dev/null @@ -1,14 +0,0 @@ -# Extra - -This file will keep track of extensions to and applications of AgentMaps. - -## Applications - -Here are some applications people have made using AgentMaps: - -* [Simple](https://noncomputable.github.io/AgentMaps/demos/simple/simple.html) by Andrew: Shows all the different ways agents can travel around a map. -* [Epidemic](https://noncomputable.github.io/AgentMaps/demos/epidemic/epidemic.html) by Andrew: Agents commute between different parts of a neighborhood while an infection spreads between them. - -## Extensions - -Here are some extensions people have made, which improve or broaden the AgentMaps library: diff --git a/docs/index.html b/docs/index.html index 9f84ed7..3f8760e 100644 --- a/docs/index.html +++ b/docs/index.html @@ -96,9 +96,15 @@ These FeatureGroups can be looped through like any other Leaflet FeatureGroup (u stored in a variable my_data and the coordinates of the top left and bottom right corners of the bounding rectangle are [43.3071, -88.0158] and [43.2884, -87.9759] respectively, the corresponding call to Agentmap.buildingify would look something like:

agentmap.buildingify(my_data, [[43.3071, -88.0158], [43.2884, -87.9759]]);

Agentmap.buildingify accepts more arguments specifying the dimension and appearance of the units and streets it will build. For more on that, see the section on Feature Styling.

Agentmap.buildingify does a lot of work checking for and removing overlapping units, and so the bigger your neighborhood, the noticeably longer it will take. -To compensate for this and help make your simulation more responsive, Agentmap.buildingify's last parameter, after the styling options, accepts a units_data object: a GeoJSON FeatureGroup of units. -If one is passed as an argument, instead of generating the units from scratch, Agentmap.buildingify will more quickly just use the blueprints in units_data.

-

How do you get a units_data object? Agentmaps have an Agentmap.downloadUnits method which, when called, will generate a js file containing a single variable named units_data defined as the vale of Agentmap.units.toGeoJSON().

+To compensate for this and help make your simulation more responsive, Agentmap.buildingify's last two parameters, after the styling options, accept a unit_layers object and street_layers object respectively: a GeoJSON FeatureGroup of units or streets exported from a previous AgentMaps simulation. +If either of these is passed as an argument, instead of generating the unit or street layers from scratch, Agentmap.buildingify will more quickly just use the blueprints in unit_layers and street_layers.

+

How do you get a unit_layers or street_layers object? Agentmaps have an +Agentmap.downloadUnits method and a Agentmap.downloadStreets +method which, when called, will generate a js file containing a single variable named unit_data or street_data defined as the vale of Agentmap.units.toGeoJSON(20) or Agentmap.streets.toGeoJSON(20) respectively.

+

What if your OSM street data is too big for a browser to feasibly generate all the appropriate building layers? +The npm package comes with a command line tool named "featuretool" which, given the bounding coordinates and path to a file containing OSM-style GeoJSON, generates all the appropriate layers and exports them to files similar to those that Agentmap.downloadUnits and Agentmap.downloadStreets generate. +To use it, you need to have installed AgentMaps globally with npm install -g AgentMaps.

+

To use featuretool, you'd do something like this: featuretool --bbox [[39.9058,-86.0910],[39.8992,-86.1017]] --streets data/townmap.js.

Navigating Streets

Given a neighborhood's streets in GeoJSON, AgentMaps extracts a street network and converts it to a graph with the help of the ngraph.graph library. Then, it uses ngraph.path to find an (approximately) shortest path. The graph itself is made out of the start point, end point, and intersections of each street.

The graph is stored in the Agentmap.streets.graph property. It is a symmetric graph; for each edge between two points, an inversely directed edge between them also exists. That is, by default, there are no one-way streets. However, if you'd like to remove some of the directed edges of certain streets from the graph (i.e. for making one-way streets), a very accessible guide to manipulating the graphs is available in the ngraph.graph README.

Navigating Within Units

Every Agentmap has an Agentmap.getUnitPoint method which makes it easy to specify a position inside of a unit, relative to one of its corners, and get back the global coordinates of that spot.

@@ -235,13 +241,13 @@ and a new animation frame will be requested to do the same thing over again.


- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/jsdocs.js.html b/docs/jsdocs.js.html index 7749032..c4a916e 100644 --- a/docs/jsdocs.js.html +++ b/docs/jsdocs.js.html @@ -74,13 +74,13 @@
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/routing.js.html b/docs/routing.js.html index 9d70223..3369458 100644 --- a/docs/routing.js.html +++ b/docs/routing.js.html @@ -314,13 +314,13 @@ exports.encodeLatLng = encodeLatLng;
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/tutorial-extra.html b/docs/tutorial-extra.html index a74f03c..6d2c529 100644 --- a/docs/tutorial-extra.html +++ b/docs/tutorial-extra.html @@ -48,7 +48,7 @@
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:51:17 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/tutorial-quickstart.html b/docs/tutorial-quickstart.html index 2515835..9466688 100644 --- a/docs/tutorial-quickstart.html +++ b/docs/tutorial-quickstart.html @@ -123,13 +123,13 @@ controller function, outside of the 300 tick condition:


- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/docs/utils.js.html b/docs/utils.js.html index 1f4f767..544ed92 100644 --- a/docs/utils.js.html +++ b/docs/utils.js.html @@ -158,13 +158,13 @@ exports.pointToCoordinateArray = pointToCoordinateArray;
- Documentation generated by JSDoc 3.5.5 on Wed Sep 12 2018 22:42:32 GMT-0400 (Eastern Daylight Time) + Documentation generated by JSDoc 3.5.5 on Thu Sep 27 2018 12:52:08 GMT-0400 (Eastern Daylight Time)
diff --git a/index.md b/index.md index f7b70e4..8384ae8 100644 --- a/index.md +++ b/index.md @@ -40,7 +40,9 @@ You can find the corresponding code under _/demos_ in the gh-pages branch [here] ### Plugins -[Spritegents](https://github.com/noncomputable/AgentMaps-Spritegents): Lets you depict agents with custom icons instead of circles. +[IconAgents](https://github.com/noncomputable/AgentMaps-IconAgents): Lets you depict agents with custom icons instead of circles. + +--- Thank you to anyone who somehow benefits from this. diff --git a/resources/street_features.js b/resources/street_features.js new file mode 100644 index 0000000..10315c1 --- /dev/null +++ b/resources/street_features.js @@ -0,0 +1 @@ +var streets_data = {"type":"FeatureCollection","features":[{"type":"Feature","id":"way/17432980","properties":{"timestamp":"2007-12-20T17:42:32Z","version":"1","changeset":"371122","user":"DaveHansenTiger","uid":"7168","highway":"residential","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108058012","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","id":"way/17432980"},"geometry":{"type":"LineString","coordinates":[[-86.098513,39.900295],[-86.098301,39.900298]]}},{"type":"Feature","id":"way/17441358","properties":{"timestamp":"2012-06-04T13:32:19Z","version":"2","changeset":"11796681","user":"WernerP","uid":"315015","highway":"residential","name":"Hooper Place","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Hooper","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108057887:108057888:108057890:108057898","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","id":"way/17441358"},"geometry":{"type":"LineString","coordinates":[[-86.097632,39.904437],[-86.096694,39.904434],[-86.09623,39.904431],[-86.095751,39.904432],[-86.094809,39.904429],[-86.09384,39.904426]]}},{"type":"Feature","id":"way/17441359","properties":{"timestamp":"2018-07-09T06:07:51Z","version":"3","changeset":"60524850","user":"addatla","uid":"8407155","highway":"residential","name":"Hooper Place","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Hooper","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17441359"},"geometry":{"type":"LineString","coordinates":[[-86.0977215,39.9057825],[-86.094322,39.905767],[-86.0941577,39.9057519],[-86.0941146,39.9057046],[-86.094122,39.905423]]}},{"type":"Feature","id":"way/17444242","properties":{"timestamp":"2012-06-06T18:46:08Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Hewes Place","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Hewes","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108055646:108055647","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17444242"},"geometry":{"type":"LineString","coordinates":[[-86.096686,39.905448],[-86.096694,39.904434],[-86.096696,39.903371]]}},{"type":"Feature","id":"way/17444338","properties":{"timestamp":"2012-06-04T13:32:23Z","version":"2","changeset":"11796681","user":"WernerP","uid":"315015","highway":"residential","name":"McKean Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"McKean","tiger:name_type":"Ln","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108039423:108039424","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17444338"},"geometry":{"type":"LineString","coordinates":[[-86.097338,39.903038],[-86.097327,39.903047],[-86.097309,39.903056],[-86.097269,39.903069],[-86.096274,39.903066],[-86.095947,39.903064],[-86.095047,39.903061],[-86.095,39.903052],[-86.094988,39.903043],[-86.094978,39.903038],[-86.09496,39.903024],[-86.094939,39.903002],[-86.094929,39.902984],[-86.094925,39.902966],[-86.094925,39.902952]]}},{"type":"Feature","id":"way/17452141","properties":{"timestamp":"2018-07-02T08:51:58Z","version":"2","changeset":"60340784","user":"ygudeti","uid":"7511407","highway":"residential","name":"5987","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"5987","tiger:reviewed":"no","id":"way/17452141"},"geometry":{"type":"LineString","coordinates":[[-86.0933636,39.903361],[-86.0932352,39.903361]]}},{"type":"Feature","id":"way/17453372","properties":{"timestamp":"2018-07-12T13:07:07Z","version":"4","changeset":"60652363","user":"vssms","uid":"8240204","highway":"residential","name":"Heyward Place","name_1":"546","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_base_1":"546","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17453372"},"geometry":{"type":"LineString","coordinates":[[-86.098273,39.905451],[-86.098121,39.90545],[-86.0978755,39.9054505]]}},{"type":"Feature","id":"way/17454701","properties":{"timestamp":"2012-06-06T18:46:20Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Lynch Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Lynch","tiger:name_type":"Ln","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108057979","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","id":"way/17454701"},"geometry":{"type":"LineString","coordinates":[[-86.095446,39.901614],[-86.095474,39.901605],[-86.095494,39.901596],[-86.095535,39.901587],[-86.095567,39.901588],[-86.095588,39.901583],[-86.09562,39.901588],[-86.095642,39.901588],[-86.095704,39.901602],[-86.095723,39.901607],[-86.095794,39.901643],[-86.095818,39.901662],[-86.095831,39.901675],[-86.095844,39.901684],[-86.09585,39.901693],[-86.095865,39.901712],[-86.095874,39.90173],[-86.095882,39.901743],[-86.095891,39.901766],[-86.095896,39.901784],[-86.0959,39.901815],[-86.095899,39.901842],[-86.095892,39.901874],[-86.095884,39.901896],[-86.095876,39.901914],[-86.095855,39.901946]]}},{"type":"Feature","id":"way/17454713","properties":{"timestamp":"2012-06-06T18:46:20Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Lynch Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Lynch","tiger:name_type":"Ln","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108038636:108055345:108039421","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17454713"},"geometry":{"type":"LineString","coordinates":[[-86.09568,39.900791],[-86.095457,39.901136],[-86.095439,39.901168],[-86.09541,39.90123],[-86.095402,39.901253],[-86.095393,39.901284],[-86.095386,39.901316],[-86.095382,39.901352],[-86.095381,39.901374],[-86.095381,39.90141],[-86.095383,39.901433],[-86.095389,39.901465],[-86.095396,39.901496],[-86.095406,39.901528],[-86.09543,39.901587],[-86.095446,39.901614],[-86.095456,39.901627],[-86.09547,39.90165],[-86.095487,39.901673],[-86.095516,39.901709],[-86.095536,39.901727],[-86.09555,39.901741],[-86.095571,39.901759],[-86.095601,39.901782],[-86.095633,39.901804],[-86.095645,39.901809],[-86.095697,39.901836],[-86.09578,39.901891],[-86.095804,39.901905],[-86.095855,39.901946],[-86.095873,39.901959],[-86.095909,39.901987],[-86.095944,39.902018],[-86.095965,39.902041],[-86.095984,39.902059],[-86.096015,39.902091],[-86.096033,39.902114],[-86.096051,39.902132],[-86.096095,39.902191],[-86.096139,39.902254],[-86.096184,39.90234],[-86.096206,39.902385],[-86.096218,39.902417],[-86.09624,39.90248],[-86.096249,39.902512],[-86.096256,39.902543],[-86.096262,39.90258],[-86.096268,39.902611],[-86.096272,39.902643],[-86.096275,39.902683],[-86.096276,39.902728],[-86.096274,39.903066],[-86.096273,39.903368]]}},{"type":"Feature","id":"way/17461175","properties":{"timestamp":"2012-06-06T18:45:46Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Clymer Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Clymer","tiger:name_type":"Ln","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108039529:108039420","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17461175"},"geometry":{"type":"LineString","coordinates":[[-86.097338,39.903038],[-86.09735,39.90303],[-86.097362,39.903016],[-86.097375,39.902994],[-86.097378,39.902985],[-86.097382,39.902962],[-86.097383,39.902692],[-86.097382,39.902651],[-86.097374,39.902575],[-86.097365,39.902534],[-86.097346,39.902471],[-86.097337,39.902448],[-86.097316,39.902403],[-86.097292,39.902358],[-86.097264,39.902313],[-86.097232,39.902267],[-86.097216,39.902249],[-86.097198,39.902226],[-86.097179,39.902208],[-86.09716,39.902186],[-86.097105,39.902136],[-86.097082,39.902113],[-86.097057,39.902086],[-86.097017,39.902036],[-86.096958,39.901959],[-86.096938,39.901927],[-86.096904,39.901877],[-86.096869,39.901818],[-86.096841,39.901764],[-86.096826,39.901733],[-86.096786,39.901638],[-86.096766,39.901583],[-86.096753,39.901538],[-86.09674,39.901493],[-86.096732,39.901462],[-86.09672,39.901403],[-86.09671,39.90134],[-86.096706,39.901308],[-86.096703,39.901272],[-86.0967,39.901218],[-86.096697,39.90093]]}},{"type":"Feature","id":"way/17462071","properties":{"timestamp":"2012-06-06T18:46:05Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Gwinnett Place","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Gwinnett","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108055644:108055645","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17462071"},"geometry":{"type":"LineString","coordinates":[[-86.09763,39.905451],[-86.097632,39.904437],[-86.097635,39.90337]]}},{"type":"Feature","id":"way/17463192","properties":{"timestamp":"2012-06-06T18:46:48Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Penn Place","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Penn","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108055648:108055649","tiger:upload_uuid":"bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17463192"},"geometry":{"type":"LineString","coordinates":[[-86.09575,39.905445],[-86.095751,39.904432],[-86.095756,39.903368]]}},{"type":"Feature","id":"way/17472157","properties":{"timestamp":"2018-07-09T05:00:19Z","version":"3","changeset":"60523693","user":"ygudeti","uid":"7511407","highway":"residential","name":"Heyward Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_type":"Ln","tiger:reviewed":"no","id":"way/17472157"},"geometry":{"type":"LineString","coordinates":[[-86.09192,39.901838],[-86.091876,39.901811],[-86.091822,39.901775],[-86.09176,39.901729],[-86.091716,39.901684],[-86.091706,39.901675],[-86.091685,39.901652],[-86.091667,39.901629],[-86.091642,39.901588],[-86.091635,39.901579],[-86.091621,39.901551],[-86.091597,39.901502],[-86.091583,39.901462],[-86.091567,39.901394],[-86.091562,39.90134],[-86.091562,39.901299],[-86.091564,39.901272],[-86.091568,39.901241],[-86.091573,39.901214],[-86.091583,39.901174],[-86.091593,39.901151],[-86.091603,39.901124],[-86.091615,39.901097],[-86.091635,39.901057],[-86.091651,39.901034],[-86.091668,39.901012],[-86.091687,39.900985],[-86.091727,39.90094],[-86.091738,39.900931],[-86.091761,39.900909],[-86.091785,39.900891],[-86.09181,39.900869],[-86.091836,39.900851],[-86.091892,39.900816],[-86.091906,39.900811],[-86.091951,39.900784],[-86.091967,39.90078],[-86.09203,39.900754],[-86.092062,39.900745],[-86.092096,39.900732],[-86.09213,39.900723],[-86.092163,39.900719],[-86.092216,39.900705],[-86.092251,39.900701],[-86.092269,39.900701],[-86.092286,39.900702],[-86.092322,39.900697],[-86.092357,39.900698],[-86.092439,39.900698],[-86.09252,39.900708],[-86.092754,39.900746],[-86.09286,39.900756],[-86.092931,39.900756],[-86.092978,39.900752],[-86.09302,39.900752],[-86.093091,39.900744],[-86.093144,39.900735],[-86.093178,39.900731],[-86.093212,39.900722],[-86.093247,39.900718],[-86.093301,39.9007],[-86.093818,39.900542],[-86.094005,39.900494],[-86.094092,39.900481],[-86.094127,39.900473],[-86.094179,39.900469],[-86.094232,39.90046],[-86.094268,39.90046],[-86.094303,39.900456],[-86.094357,39.900452],[-86.094553,39.900453],[-86.094606,39.900458],[-86.094642,39.900459],[-86.094887,39.900492],[-86.094921,39.900501],[-86.094955,39.900506],[-86.09499,39.900515],[-86.095023,39.900525],[-86.09509,39.900543],[-86.095124,39.900553],[-86.095172,39.900571],[-86.095205,39.90058],[-86.095237,39.900594],[-86.095332,39.900631],[-86.095378,39.900654],[-86.095631,39.900773],[-86.09568,39.900791],[-86.095726,39.900809],[-86.095758,39.900819],[-86.09579,39.900833],[-86.095975,39.900883],[-86.096009,39.900893],[-86.096061,39.900902],[-86.09613,39.900912],[-86.096183,39.900921],[-86.096253,39.900931],[-86.096307,39.900936],[-86.096395,39.900936],[-86.096431,39.900941],[-86.096503,39.900942],[-86.096556,39.900938],[-86.096591,39.900938],[-86.096627,39.900934],[-86.096662,39.900929],[-86.096697,39.90093],[-86.096768,39.900921],[-86.096821,39.900913],[-86.096855,39.900904],[-86.09689,39.9009],[-86.096919,39.900891],[-86.096959,39.900887],[-86.097044,39.900865],[-86.097089,39.900852],[-86.097339,39.900772],[-86.097424,39.900751],[-86.097528,39.900733],[-86.097581,39.900725],[-86.097617,39.900725],[-86.097648,39.900721]]}},{"type":"Feature","id":"way/17483936","properties":{"timestamp":"2012-06-04T13:38:17Z","version":"2","changeset":"11796728","user":"WernerP","uid":"315015","highway":"residential","name":"Wythe Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Wythe","tiger:name_type":"Ln","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108039378:108039379","tiger:upload_uuid":"bulk_upload.pl-ed0550aa-ad5a-428d-acd8-2d7fb7833f78","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17483936"},"geometry":{"type":"LineString","coordinates":[[-86.097648,39.900721],[-86.097645,39.900167],[-86.097643,39.900135],[-86.097641,39.900122],[-86.097628,39.900067],[-86.097609,39.900013],[-86.097596,39.899991],[-86.097583,39.899964],[-86.097567,39.899941],[-86.09755,39.899914],[-86.097532,39.899891],[-86.097522,39.899882],[-86.097501,39.899859],[-86.097455,39.899814],[-86.097405,39.899777],[-86.097349,39.899741],[-86.09732,39.899727],[-86.097305,39.899718],[-86.097274,39.899704],[-86.097242,39.899695],[-86.09721,39.899681],[-86.097126,39.899658],[-86.097091,39.899653],[-86.097057,39.899644],[-86.097039,39.899644],[-86.097004,39.899639],[-86.096879,39.899638],[-86.096739,39.899655],[-86.096521,39.899712],[-86.096487,39.899716],[-86.096469,39.899721],[-86.096434,39.899725],[-86.096416,39.899725],[-86.09638,39.899729],[-86.096345,39.899729],[-86.096291,39.899728],[-86.096221,39.899719],[-86.096204,39.899719],[-86.096151,39.899705],[-86.096134,39.899704],[-86.096101,39.899695],[-86.096067,39.899681],[-86.096051,39.899677],[-86.095866,39.899608],[-86.095715,39.899566],[-86.095681,39.899561],[-86.095612,39.899543],[-86.095507,39.899528],[-86.095313,39.899509],[-86.093974,39.899503]]}},{"type":"Feature","id":"way/17486873","properties":{"timestamp":"2012-06-06T18:46:11Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Hopkins Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Hopkins","tiger:name_type":"Ln","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108039430:108045983","tiger:upload_uuid":"bulk_upload.pl-ed0550aa-ad5a-428d-acd8-2d7fb7833f78","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17486873"},"geometry":{"type":"LineString","coordinates":[[-86.094925,39.902952],[-86.094926,39.9027],[-86.094925,39.902668],[-86.094917,39.902587],[-86.094913,39.902556],[-86.094902,39.902497],[-86.094895,39.90247],[-86.094888,39.902438],[-86.094861,39.902352],[-86.094827,39.902267],[-86.0948,39.902212],[-86.094768,39.902153],[-86.094753,39.902131],[-86.094718,39.902076],[-86.094681,39.902027],[-86.094662,39.901999],[-86.094642,39.901977],[-86.094621,39.90195],[-86.0946,39.901927],[-86.094531,39.901859],[-86.094505,39.901832],[-86.094466,39.9018],[-86.094424,39.901763],[-86.094292,39.901668],[-86.094197,39.901613],[-86.094146,39.901585],[-86.094053,39.90154],[-86.09323,39.901164],[-86.093186,39.901141],[-86.093171,39.901132],[-86.093155,39.901118],[-86.093131,39.9011],[-86.093111,39.901082],[-86.093097,39.901068],[-86.093084,39.901059],[-86.093072,39.901041],[-86.09305,39.901014],[-86.093027,39.900978],[-86.093019,39.900964],[-86.093006,39.900932],[-86.092993,39.900892],[-86.092988,39.900869],[-86.092978,39.900752]]}},{"type":"Feature","id":"way/17493499","properties":{"timestamp":"2012-06-06T18:45:53Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Dean Road","tiger:cfcc":"A45","tiger:county":"Marion, IN","tiger:name_base":"Dean","tiger:name_type":"Rd","tiger:reviewed":"no","tiger:separated":"yes","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108058013:108058062:108058066:108058067","tiger:upload_uuid":"bulk_upload.pl-ed0550aa-ad5a-428d-acd8-2d7fb7833f78","tiger:zip_left":"46240","id":"way/17493499"},"geometry":{"type":"LineString","coordinates":[[-86.09865,39.898008],[-86.098624,39.898025],[-86.09861,39.898039],[-86.09859,39.898061],[-86.098579,39.898075],[-86.098567,39.898088],[-86.09855,39.898111],[-86.098536,39.898128],[-86.098507,39.898187],[-86.098495,39.898223],[-86.098486,39.898263],[-86.098484,39.898286],[-86.098475,39.898633],[-86.098474,39.899173],[-86.098482,39.89984],[-86.098496,39.90011],[-86.098503,39.900169],[-86.098512,39.900264],[-86.098513,39.900295],[-86.098514,39.900345],[-86.098513,39.900417],[-86.098508,39.900471],[-86.098489,39.900583],[-86.098471,39.900732],[-86.098466,39.900822],[-86.098465,39.900907],[-86.098467,39.901056],[-86.098468,39.902556],[-86.098457,39.905588],[-86.098458,39.905615],[-86.098461,39.905628],[-86.098463,39.905647],[-86.098488,39.905732],[-86.09849,39.905741],[-86.09849,39.90575],[-86.098488,39.905773],[-86.098483,39.905791],[-86.098474,39.905804],[-86.098462,39.905818],[-86.098449,39.905831],[-86.098433,39.905844],[-86.098406,39.905853],[-86.098395,39.905858],[-86.098375,39.905862],[-86.098362,39.905866],[-86.098272,39.905866]]}},{"type":"Feature","id":"way/17501810","properties":{"timestamp":"2018-07-12T13:07:07Z","version":"4","changeset":"60652363","user":"vssms","uid":"8240204","highway":"residential","name":"Statesmen Drive","name_1":"894","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Statesmen","tiger:name_base_1":"894","tiger:name_type":"Dr","tiger:reviewed":"no","id":"way/17501810"},"geometry":{"type":"LineString","coordinates":[[-86.098288,39.903375],[-86.098108,39.903373],[-86.0978715,39.9033715]]}},{"type":"Feature","id":"way/17509867","properties":{"timestamp":"2012-06-06T18:46:08Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Heyward Drive","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_type":"Dr","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108055682:108055683","tiger:upload_uuid":"bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17509867"},"geometry":{"type":"LineString","coordinates":[[-86.093837,39.905124],[-86.09384,39.904426],[-86.0938425,39.903737]]}},{"type":"Feature","id":"way/17509887","properties":{"timestamp":"2012-06-06T18:46:10Z","version":"3","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","junction":"roundabout","name":"Heyward Drive","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_type":"Dr","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108038606:108038608:108038610:108038611","tiger:upload_uuid":"bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7","id":"way/17509887"},"geometry":{"type":"LineString","coordinates":[[-86.093858,39.9029816],[-86.0938227,39.9029825],[-86.0937875,39.9029853],[-86.0937527,39.90299],[-86.0937185,39.9029967],[-86.0936849,39.9030052],[-86.0936522,39.9030155],[-86.0936206,39.9030276],[-86.0935902,39.9030414],[-86.0935612,39.9030568],[-86.0935337,39.9030738],[-86.0935078,39.9030923],[-86.0934837,39.9031122],[-86.0934616,39.9031333],[-86.0934415,39.9031556],[-86.0934235,39.9031789],[-86.0934077,39.9032032],[-86.0933943,39.9032282],[-86.0933832,39.903254],[-86.0933746,39.9032803],[-86.0933684,39.9033069],[-86.0933648,39.9033339],[-86.0933636,39.903361],[-86.0933654,39.9033916],[-86.0933704,39.9034219],[-86.0933786,39.9034518],[-86.0933899,39.9034812],[-86.0934043,39.9035097],[-86.0934217,39.9035372],[-86.0934418,39.9035636],[-86.0934647,39.9035887],[-86.0934902,39.9036122],[-86.0935181,39.9036341],[-86.0935481,39.9036541],[-86.0935802,39.9036723],[-86.0936142,39.9036884],[-86.0936496,39.9037023],[-86.0936865,39.903714],[-86.0937245,39.9037234],[-86.0937633,39.9037303],[-86.0938027,39.9037349],[-86.0938425,39.903737],[-86.0938817,39.9037366],[-86.0939207,39.9037338],[-86.0939593,39.9037287],[-86.0939972,39.9037213],[-86.0940343,39.9037115],[-86.0940702,39.9036995],[-86.0941047,39.9036854],[-86.0941377,39.9036692],[-86.094169,39.903651],[-86.0941982,39.903631],[-86.0942253,39.9036093],[-86.09425,39.903586],[-86.0942722,39.9035613],[-86.0942918,39.9035353],[-86.0943087,39.9035081],[-86.0943227,39.9034801],[-86.0943337,39.9034512],[-86.0943417,39.9034218],[-86.0943466,39.903392],[-86.0943485,39.903362],[-86.0943477,39.9033382],[-86.094345,39.9033146],[-86.0943404,39.903291],[-86.0943338,39.9032678],[-86.0943253,39.9032449],[-86.094315,39.9032225],[-86.0943029,39.9032006],[-86.094289,39.9031794],[-86.0942734,39.9031588],[-86.0942561,39.9031391],[-86.0942372,39.9031202],[-86.0942169,39.9031023],[-86.0941951,39.9030854],[-86.0941719,39.9030696],[-86.0941476,39.9030549],[-86.094122,39.9030414],[-86.0940954,39.9030292],[-86.0940679,39.9030183],[-86.0940395,39.9030088],[-86.0940104,39.9030006],[-86.0939806,39.9029939],[-86.0939504,39.9029886],[-86.0939198,39.9029848],[-86.093889,39.9029825],[-86.093858,39.9029816]]}},{"type":"Feature","id":"way/17509896","properties":{"timestamp":"2012-06-06T18:46:10Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Heyward Drive","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_type":"Dr","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108038615","tiger:upload_uuid":"bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17509896"},"geometry":{"type":"LineString","coordinates":[[-86.093858,39.9029816],[-86.093851,39.902741],[-86.093846,39.9027],[-86.093832,39.902633],[-86.093816,39.902578],[-86.093788,39.902511],[-86.093755,39.902447],[-86.093723,39.902402],[-86.093705,39.902375],[-86.093687,39.902352],[-86.093625,39.902284],[-86.093602,39.902266],[-86.093579,39.902243],[-86.093555,39.902225],[-86.093529,39.902202],[-86.093449,39.902148],[-86.093332,39.902088],[-86.093285,39.902065],[-86.093253,39.902056],[-86.093221,39.902042],[-86.093054,39.901996],[-86.092914,39.901977],[-86.092879,39.901977],[-86.092266,39.901936],[-86.092249,39.901936],[-86.092231,39.901931],[-86.092196,39.901926],[-86.092179,39.901926],[-86.092061,39.901894],[-86.092028,39.901884],[-86.091996,39.901871],[-86.09198,39.901866],[-86.09192,39.901838]]}},{"type":"Feature","id":"way/17519894","properties":{"timestamp":"2012-06-06T18:47:06Z","version":"2","changeset":"11818393","user":"WernerP","uid":"315015","highway":"residential","name":"Rush Place","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Rush","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:separated":"no","tiger:source":"tiger_import_dch_v0.6_20070810","tiger:tlid":"108055650:108055651","tiger:upload_uuid":"bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/17519894"},"geometry":{"type":"LineString","coordinates":[[-86.094806,39.905442],[-86.094809,39.904429],[-86.094815,39.903361]]}},{"type":"Feature","id":"way/162451324","properties":{"timestamp":"2018-07-09T06:07:51Z","version":"4","changeset":"60524850","user":"addatla","uid":"8407155","highway":"tertiary","name":"Dean Road","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Dean","tiger:name_type":"Rd","tiger:reviewed":"no","tiger:zip_left":"46240","tiger:zip_right":"46240","id":"way/162451324"},"geometry":{"type":"LineString","coordinates":[[-86.0983285,39.8924155],[-86.0983206,39.8926748],[-86.098312,39.894171],[-86.098312,39.894482],[-86.098272,39.896712],[-86.098271,39.89764],[-86.098273,39.897662],[-86.098276,39.897676],[-86.098279,39.897685],[-86.098289,39.897703],[-86.098308,39.89773],[-86.098318,39.897748],[-86.098322,39.897762],[-86.098327,39.897771],[-86.098331,39.897798],[-86.098332,39.898185],[-86.098301,39.900298],[-86.0983,39.900721],[-86.098288,39.903375],[-86.098273,39.905451],[-86.098272,39.905866],[-86.0982717,39.9060187],[-86.0982707,39.9065208],[-86.0982705,39.9066668],[-86.0982692,39.9073088],[-86.098269,39.907429],[-86.098268,39.9076954],[-86.098271,39.907776],[-86.0982731,39.9078264],[-86.098276,39.907897]]}},{"type":"Feature","id":"way/311989171","properties":{"timestamp":"2014-11-09T21:03:16Z","version":"1","changeset":"26674801","user":"erjiang","uid":"701297","highway":"service","id":"way/311989171"},"geometry":{"type":"LineString","coordinates":[[-86.0938112,39.9035743],[-86.0937198,39.9035425],[-86.0936353,39.9034841],[-86.0935813,39.9034087],[-86.0935398,39.9033577],[-86.093465,39.9033407],[-86.0933636,39.903361]]}},{"type":"Feature","id":"way/604182871","properties":{"timestamp":"2018-07-02T08:51:58Z","version":"1","changeset":"60340784","user":"ygudeti","uid":"7511407","access":"private","highway":"residential","name":"5987","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"5987","tiger:reviewed":"no","id":"way/604182871"},"geometry":{"type":"LineString","coordinates":[[-86.0932352,39.903361],[-86.093069,39.903361]]}},{"type":"Feature","id":"way/606231314","properties":{"timestamp":"2018-07-09T05:00:19Z","version":"1","changeset":"60523693","user":"ygudeti","uid":"7511407","access":"private","highway":"residential","name":"Heyward Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_type":"Ln","tiger:reviewed":"no","id":"way/606231314"},"geometry":{"type":"LineString","coordinates":[[-86.097648,39.900721],[-86.0978979,39.9007205]]}},{"type":"Feature","id":"way/606231315","properties":{"timestamp":"2018-07-09T05:00:19Z","version":"1","changeset":"60523693","user":"ygudeti","uid":"7511407","highway":"residential","name":"Heyward Lane","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_type":"Ln","tiger:reviewed":"no","id":"way/606231315"},"geometry":{"type":"LineString","coordinates":[[-86.0978979,39.9007205],[-86.098109,39.90072],[-86.0983,39.900721]]}},{"type":"Feature","id":"way/607399318","properties":{"timestamp":"2018-07-12T13:07:06Z","version":"1","changeset":"60652363","user":"vssms","uid":"8240204","access":"private","highway":"residential","name":"Heyward Place","name_1":"546","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Heyward","tiger:name_base_1":"546","tiger:name_type":"Pl","tiger:reviewed":"no","tiger:zip_left":"46250","tiger:zip_right":"46250","id":"way/607399318"},"geometry":{"type":"LineString","coordinates":[[-86.0978755,39.9054505],[-86.09763,39.905451],[-86.096686,39.905448],[-86.09575,39.905445],[-86.094806,39.905442],[-86.094194,39.905438],[-86.094176,39.905437],[-86.094138,39.905428],[-86.094122,39.905423],[-86.094088,39.905414],[-86.094035,39.905396],[-86.093964,39.905355],[-86.093922,39.905318],[-86.093906,39.9053],[-86.093889,39.905277],[-86.093877,39.905259],[-86.093864,39.905237],[-86.093847,39.905192],[-86.093842,39.905169],[-86.093837,39.905124]]}},{"type":"Feature","id":"way/607399319","properties":{"timestamp":"2018-07-12T13:07:06Z","version":"1","changeset":"60652363","user":"vssms","uid":"8240204","access":"private","highway":"residential","name":"Statesmen Drive","name_1":"894","tiger:cfcc":"A41","tiger:county":"Marion, IN","tiger:name_base":"Statesmen","tiger:name_base_1":"894","tiger:name_type":"Dr","tiger:reviewed":"no","id":"way/607399319"},"geometry":{"type":"LineString","coordinates":[[-86.0978715,39.9033715],[-86.097635,39.90337],[-86.096696,39.903371],[-86.096273,39.903368],[-86.095756,39.903368],[-86.094815,39.903361],[-86.0943485,39.903362]]}}]}; \ No newline at end of file diff --git a/resources/tool_map_data.js b/resources/tool_map_data.js new file mode 100644 index 0000000..02c6f30 --- /dev/null +++ b/resources/tool_map_data.js @@ -0,0 +1,4208 @@ +{ +"type": "FeatureCollection", +"features": [ +{ + "type": "Feature", + "id": "way/81090476", + "properties": { + "timestamp": "2014-01-15T22:29:38Z", + "version": "5", + "changeset": "20024183", + "user": "debutterfly", + "uid": "308181", + "natural": "water", + "water": "pond", + "id": "way/81090476" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -86.1036563, + 39.9084437 + ], + [ + -86.1038542, + 39.9083267 + ], + [ + -86.1039528, + 39.9083089 + ], + [ + -86.1040005, + 39.9083364 + ], + [ + -86.1040661, + 39.9082952 + ], + [ + -86.1040731, + 39.908219 + ], + [ + -86.1041979, + 39.9080691 + ], + [ + -86.1043321, + 39.9080426 + ], + [ + -86.1042682, + 39.9078749 + ], + [ + -86.1041643, + 39.9077135 + ], + [ + -86.1040551, + 39.9076277 + ], + [ + -86.1040392, + 39.9075406 + ], + [ + -86.1040701, + 39.9074471 + ], + [ + -86.1040664, + 39.9072394 + ], + [ + -86.1041377, + 39.9071268 + ], + [ + -86.1045213, + 39.906926 + ], + [ + -86.105019, + 39.9066445 + ], + [ + -86.1053336, + 39.9064993 + ], + [ + -86.1055682, + 39.9063661 + ], + [ + -86.1058548, + 39.9061828 + ], + [ + -86.1060394, + 39.9060866 + ], + [ + -86.1061763, + 39.9060067 + ], + [ + -86.1065502, + 39.9059045 + ], + [ + -86.1068177, + 39.9057501 + ], + [ + -86.1070204, + 39.9056017 + ], + [ + -86.1071276, + 39.905375 + ], + [ + -86.1071372, + 39.905027 + ], + [ + -86.107168, + 39.9047411 + ], + [ + -86.1072181, + 39.9046074 + ], + [ + -86.1072034, + 39.9044549 + ], + [ + -86.10715, + 39.904363 + ], + [ + -86.1070009, + 39.9043353 + ], + [ + -86.1067594, + 39.9043922 + ], + [ + -86.1064943, + 39.9044854 + ], + [ + -86.1062341, + 39.9046235 + ], + [ + -86.1060361, + 39.9046657 + ], + [ + -86.1058322, + 39.904696 + ], + [ + -86.1056994, + 39.9046497 + ], + [ + -86.105465, + 39.9043216 + ], + [ + -86.1054367, + 39.9041697 + ], + [ + -86.105518, + 39.9040346 + ], + [ + -86.1056127, + 39.9039641 + ], + [ + -86.1057202, + 39.9038941 + ], + [ + -86.1057261, + 39.9035612 + ], + [ + -86.1057365, + 39.9034146 + ], + [ + -86.1056753, + 39.9032976 + ], + [ + -86.1056256, + 39.9030665 + ], + [ + -86.1056545, + 39.9027942 + ], + [ + -86.1057067, + 39.9025112 + ], + [ + -86.1056917, + 39.9022848 + ], + [ + -86.1055295, + 39.901974 + ], + [ + -86.1053242, + 39.9017164 + ], + [ + -86.1050289, + 39.901477 + ], + [ + -86.1045751, + 39.9014219 + ], + [ + -86.1040554, + 39.9014013 + ], + [ + -86.1033268, + 39.9013684 + ], + [ + -86.1031802, + 39.9012721 + ], + [ + -86.1031542, + 39.9011227 + ], + [ + -86.1031784, + 39.9009322 + ], + [ + -86.1030864, + 39.9007947 + ], + [ + -86.1030831, + 39.9003344 + ], + [ + -86.1030555, + 39.8997142 + ], + [ + -86.1030795, + 39.8992276 + ], + [ + -86.1030926, + 39.8985275 + ], + [ + -86.1030179, + 39.8983225 + ], + [ + -86.102616, + 39.8982888 + ], + [ + -86.1018477, + 39.8982738 + ], + [ + -86.1009431, + 39.8982738 + ], + [ + -86.1003888, + 39.8982962 + ], + [ + -86.0994453, + 39.8982589 + ], + [ + -86.0992216, + 39.8982813 + ], + [ + -86.0991341, + 39.8983634 + ], + [ + -86.0990757, + 39.8985872 + ], + [ + -86.0991049, + 39.8990573 + ], + [ + -86.0990174, + 39.8994379 + ], + [ + -86.0989298, + 39.9001169 + ], + [ + -86.0988423, + 39.9007362 + ], + [ + -86.0988618, + 39.9013928 + ], + [ + -86.0988715, + 39.902415 + ], + [ + -86.0989315, + 39.9036779 + ], + [ + -86.0989883, + 39.9042827 + ], + [ + -86.0989461, + 39.9045001 + ], + [ + -86.098919, + 39.904957 + ], + [ + -86.0988893, + 39.9053066 + ], + [ + -86.0988908, + 39.9054558 + ], + [ + -86.0989465, + 39.9058084 + ], + [ + -86.0989301, + 39.9059815 + ], + [ + -86.0990016, + 39.906158 + ], + [ + -86.0990087, + 39.9063565 + ], + [ + -86.0989623, + 39.9064898 + ], + [ + -86.0989559, + 39.9071693 + ], + [ + -86.0991341, + 39.9073243 + ], + [ + -86.0997371, + 39.9074661 + ], + [ + -86.1004082, + 39.9076451 + ], + [ + -86.1008459, + 39.9077421 + ], + [ + -86.101021, + 39.9076824 + ], + [ + -86.1008848, + 39.9075854 + ], + [ + -86.1009723, + 39.9074362 + ], + [ + -86.101196, + 39.9072945 + ], + [ + -86.1014091, + 39.9070985 + ], + [ + -86.1017704, + 39.9067284 + ], + [ + -86.1019965, + 39.9063708 + ], + [ + -86.102232, + 39.9062226 + ], + [ + -86.102566, + 39.9059998 + ], + [ + -86.1031249, + 39.9055165 + ], + [ + -86.1032741, + 39.9053603 + ], + [ + -86.1033642, + 39.9051801 + ], + [ + -86.1039874, + 39.9045041 + ], + [ + -86.104348, + 39.9042879 + ], + [ + -86.1045551, + 39.9041959 + ], + [ + -86.1046779, + 39.9041848 + ], + [ + -86.1048141, + 39.9043623 + ], + [ + -86.1049795, + 39.9046608 + ], + [ + -86.1049795, + 39.9048025 + ], + [ + -86.1047266, + 39.9049965 + ], + [ + -86.1044154, + 39.9053024 + ], + [ + -86.1040652, + 39.9054964 + ], + [ + -86.1038513, + 39.9057501 + ], + [ + -86.1036276, + 39.906056 + ], + [ + -86.1032969, + 39.9063544 + ], + [ + -86.1028786, + 39.90672 + ], + [ + -86.1026258, + 39.9070259 + ], + [ + -86.1024604, + 39.9072348 + ], + [ + -86.1021395, + 39.907287 + ], + [ + -86.1019449, + 39.9073467 + ], + [ + -86.1017601, + 39.9075481 + ], + [ + -86.1016055, + 39.9078083 + ], + [ + -86.1018996, + 39.9079106 + ], + [ + -86.1023983, + 39.9080623 + ], + [ + -86.1025382, + 39.9080629 + ], + [ + -86.102949, + 39.9082293 + ], + [ + -86.1029881, + 39.9083083 + ], + [ + -86.1036563, + 39.9084437 + ] + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/191727051", + "properties": { + "timestamp": "2012-11-20T14:04:33Z", + "version": "1", + "changeset": "13944785", + "user": "rama_ge", + "uid": "115464", + "natural": "water", + "id": "way/191727051" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -86.0979649, + 39.9029383 + ], + [ + -86.0980186, + 39.9028724 + ], + [ + -86.0979971, + 39.9027243 + ], + [ + -86.0979649, + 39.9024609 + ], + [ + -86.0980079, + 39.9022881 + ], + [ + -86.0979971, + 39.9020576 + ], + [ + -86.0980079, + 39.9017366 + ], + [ + -86.0978925, + 39.9014074 + ], + [ + -86.097922, + 39.9012593 + ], + [ + -86.0979649, + 39.9011193 + ], + [ + -86.0979006, + 39.901037 + ], + [ + -86.0977826, + 39.9010864 + ], + [ + -86.0974956, + 39.901251 + ], + [ + -86.0973239, + 39.9012099 + ], + [ + -86.097289, + 39.9014239 + ], + [ + -86.0973668, + 39.9015556 + ], + [ + -86.0973775, + 39.9017284 + ], + [ + -86.0974821, + 39.9018601 + ], + [ + -86.0975492, + 39.902 + ], + [ + -86.0977182, + 39.9021728 + ], + [ + -86.0978255, + 39.9023868 + ], + [ + -86.0978818, + 39.9025926 + ], + [ + -86.0978711, + 39.9028313 + ], + [ + -86.0979649, + 39.9029383 + ] + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/191727052", + "properties": { + "timestamp": "2012-11-20T14:04:33Z", + "version": "1", + "changeset": "13944785", + "user": "rama_ge", + "uid": "115464", + "natural": "water", + "id": "way/191727052" + }, + "geometry": { + "type": "Polygon", + "coordinates": [ + [ + [ + -86.0893926, + 39.9032757 + ], + [ + -86.0895643, + 39.9032675 + ], + [ + -86.0899076, + 39.9031687 + ], + [ + -86.0905728, + 39.9031029 + ], + [ + -86.0908303, + 39.9029301 + ], + [ + -86.0911226, + 39.9028313 + ], + [ + -86.0914311, + 39.9028642 + ], + [ + -86.0918066, + 39.9029218 + ], + [ + -86.0919675, + 39.9028642 + ], + [ + -86.092343, + 39.9027737 + ], + [ + -86.0927293, + 39.9028231 + ], + [ + -86.0930404, + 39.9029383 + ], + [ + -86.0931692, + 39.9029877 + ], + [ + -86.093255, + 39.9029794 + ], + [ + -86.0933086, + 39.9028477 + ], + [ + -86.0932657, + 39.9026091 + ], + [ + -86.0931933, + 39.9024774 + ], + [ + -86.0929546, + 39.9024115 + ], + [ + -86.0925254, + 39.9023704 + ], + [ + -86.092107, + 39.9023704 + ], + [ + -86.0917208, + 39.9022469 + ], + [ + -86.0914311, + 39.9020823 + ], + [ + -86.0912594, + 39.9018848 + ], + [ + -86.0911548, + 39.9017284 + ], + [ + -86.0909161, + 39.9016872 + ], + [ + -86.09079, + 39.9018025 + ], + [ + -86.0908088, + 39.9019671 + ], + [ + -86.0908222, + 39.9021728 + ], + [ + -86.0907015, + 39.9022634 + ], + [ + -86.090157, + 39.9025597 + ], + [ + -86.0899076, + 39.9027408 + ], + [ + -86.0897788, + 39.9029712 + ], + [ + -86.0896072, + 39.9030535 + ], + [ + -86.0893926, + 39.9031523 + ], + [ + -86.0893926, + 39.9032757 + ] + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17432980", + "properties": { + "timestamp": "2007-12-20T17:42:32Z", + "version": "1", + "changeset": "371122", + "user": "DaveHansenTiger", + "uid": "7168", + "highway": "residential", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108058012", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "id": "way/17432980" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.098513, + 39.900295 + ], + [ + -86.098301, + 39.900298 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17441358", + "properties": { + "timestamp": "2012-06-04T13:32:19Z", + "version": "2", + "changeset": "11796681", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Hooper Place", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Hooper", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108057887:108057888:108057890:108057898", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "id": "way/17441358" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.097632, + 39.904437 + ], + [ + -86.096694, + 39.904434 + ], + [ + -86.09623, + 39.904431 + ], + [ + -86.095751, + 39.904432 + ], + [ + -86.094809, + 39.904429 + ], + [ + -86.09384, + 39.904426 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17441359", + "properties": { + "timestamp": "2018-07-09T06:07:51Z", + "version": "3", + "changeset": "60524850", + "user": "addatla", + "uid": "8407155", + "highway": "residential", + "name": "Hooper Place", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Hooper", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17441359" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0977215, + 39.9057825 + ], + [ + -86.094322, + 39.905767 + ], + [ + -86.0941577, + 39.9057519 + ], + [ + -86.0941146, + 39.9057046 + ], + [ + -86.094122, + 39.905423 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17444242", + "properties": { + "timestamp": "2012-06-06T18:46:08Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Hewes Place", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Hewes", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108055646:108055647", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17444242" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.096686, + 39.905448 + ], + [ + -86.096694, + 39.904434 + ], + [ + -86.096696, + 39.903371 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17444338", + "properties": { + "timestamp": "2012-06-04T13:32:23Z", + "version": "2", + "changeset": "11796681", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "McKean Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "McKean", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108039423:108039424", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17444338" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.097338, + 39.903038 + ], + [ + -86.097327, + 39.903047 + ], + [ + -86.097309, + 39.903056 + ], + [ + -86.097269, + 39.903069 + ], + [ + -86.096274, + 39.903066 + ], + [ + -86.095947, + 39.903064 + ], + [ + -86.095047, + 39.903061 + ], + [ + -86.095, + 39.903052 + ], + [ + -86.094988, + 39.903043 + ], + [ + -86.094978, + 39.903038 + ], + [ + -86.09496, + 39.903024 + ], + [ + -86.094939, + 39.903002 + ], + [ + -86.094929, + 39.902984 + ], + [ + -86.094925, + 39.902966 + ], + [ + -86.094925, + 39.902952 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17452141", + "properties": { + "timestamp": "2018-07-02T08:51:58Z", + "version": "2", + "changeset": "60340784", + "user": "ygudeti", + "uid": "7511407", + "highway": "residential", + "name": "5987", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "5987", + "tiger:reviewed": "no", + "id": "way/17452141" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0933636, + 39.903361 + ], + [ + -86.0932352, + 39.903361 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17453372", + "properties": { + "timestamp": "2018-07-12T13:07:07Z", + "version": "4", + "changeset": "60652363", + "user": "vssms", + "uid": "8240204", + "highway": "residential", + "name": "Heyward Place", + "name_1": "546", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_base_1": "546", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17453372" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.098273, + 39.905451 + ], + [ + -86.098121, + 39.90545 + ], + [ + -86.0978755, + 39.9054505 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17454701", + "properties": { + "timestamp": "2012-06-06T18:46:20Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Lynch Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Lynch", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108057979", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "id": "way/17454701" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.095446, + 39.901614 + ], + [ + -86.095474, + 39.901605 + ], + [ + -86.095494, + 39.901596 + ], + [ + -86.095535, + 39.901587 + ], + [ + -86.095567, + 39.901588 + ], + [ + -86.095588, + 39.901583 + ], + [ + -86.09562, + 39.901588 + ], + [ + -86.095642, + 39.901588 + ], + [ + -86.095704, + 39.901602 + ], + [ + -86.095723, + 39.901607 + ], + [ + -86.095794, + 39.901643 + ], + [ + -86.095818, + 39.901662 + ], + [ + -86.095831, + 39.901675 + ], + [ + -86.095844, + 39.901684 + ], + [ + -86.09585, + 39.901693 + ], + [ + -86.095865, + 39.901712 + ], + [ + -86.095874, + 39.90173 + ], + [ + -86.095882, + 39.901743 + ], + [ + -86.095891, + 39.901766 + ], + [ + -86.095896, + 39.901784 + ], + [ + -86.0959, + 39.901815 + ], + [ + -86.095899, + 39.901842 + ], + [ + -86.095892, + 39.901874 + ], + [ + -86.095884, + 39.901896 + ], + [ + -86.095876, + 39.901914 + ], + [ + -86.095855, + 39.901946 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17454713", + "properties": { + "timestamp": "2012-06-06T18:46:20Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Lynch Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Lynch", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108038636:108055345:108039421", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17454713" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.09568, + 39.900791 + ], + [ + -86.095457, + 39.901136 + ], + [ + -86.095439, + 39.901168 + ], + [ + -86.09541, + 39.90123 + ], + [ + -86.095402, + 39.901253 + ], + [ + -86.095393, + 39.901284 + ], + [ + -86.095386, + 39.901316 + ], + [ + -86.095382, + 39.901352 + ], + [ + -86.095381, + 39.901374 + ], + [ + -86.095381, + 39.90141 + ], + [ + -86.095383, + 39.901433 + ], + [ + -86.095389, + 39.901465 + ], + [ + -86.095396, + 39.901496 + ], + [ + -86.095406, + 39.901528 + ], + [ + -86.09543, + 39.901587 + ], + [ + -86.095446, + 39.901614 + ], + [ + -86.095456, + 39.901627 + ], + [ + -86.09547, + 39.90165 + ], + [ + -86.095487, + 39.901673 + ], + [ + -86.095516, + 39.901709 + ], + [ + -86.095536, + 39.901727 + ], + [ + -86.09555, + 39.901741 + ], + [ + -86.095571, + 39.901759 + ], + [ + -86.095601, + 39.901782 + ], + [ + -86.095633, + 39.901804 + ], + [ + -86.095645, + 39.901809 + ], + [ + -86.095697, + 39.901836 + ], + [ + -86.09578, + 39.901891 + ], + [ + -86.095804, + 39.901905 + ], + [ + -86.095855, + 39.901946 + ], + [ + -86.095873, + 39.901959 + ], + [ + -86.095909, + 39.901987 + ], + [ + -86.095944, + 39.902018 + ], + [ + -86.095965, + 39.902041 + ], + [ + -86.095984, + 39.902059 + ], + [ + -86.096015, + 39.902091 + ], + [ + -86.096033, + 39.902114 + ], + [ + -86.096051, + 39.902132 + ], + [ + -86.096095, + 39.902191 + ], + [ + -86.096139, + 39.902254 + ], + [ + -86.096184, + 39.90234 + ], + [ + -86.096206, + 39.902385 + ], + [ + -86.096218, + 39.902417 + ], + [ + -86.09624, + 39.90248 + ], + [ + -86.096249, + 39.902512 + ], + [ + -86.096256, + 39.902543 + ], + [ + -86.096262, + 39.90258 + ], + [ + -86.096268, + 39.902611 + ], + [ + -86.096272, + 39.902643 + ], + [ + -86.096275, + 39.902683 + ], + [ + -86.096276, + 39.902728 + ], + [ + -86.096274, + 39.903066 + ], + [ + -86.096273, + 39.903368 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17461175", + "properties": { + "timestamp": "2012-06-06T18:45:46Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Clymer Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Clymer", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108039529:108039420", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17461175" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.097338, + 39.903038 + ], + [ + -86.09735, + 39.90303 + ], + [ + -86.097362, + 39.903016 + ], + [ + -86.097375, + 39.902994 + ], + [ + -86.097378, + 39.902985 + ], + [ + -86.097382, + 39.902962 + ], + [ + -86.097383, + 39.902692 + ], + [ + -86.097382, + 39.902651 + ], + [ + -86.097374, + 39.902575 + ], + [ + -86.097365, + 39.902534 + ], + [ + -86.097346, + 39.902471 + ], + [ + -86.097337, + 39.902448 + ], + [ + -86.097316, + 39.902403 + ], + [ + -86.097292, + 39.902358 + ], + [ + -86.097264, + 39.902313 + ], + [ + -86.097232, + 39.902267 + ], + [ + -86.097216, + 39.902249 + ], + [ + -86.097198, + 39.902226 + ], + [ + -86.097179, + 39.902208 + ], + [ + -86.09716, + 39.902186 + ], + [ + -86.097105, + 39.902136 + ], + [ + -86.097082, + 39.902113 + ], + [ + -86.097057, + 39.902086 + ], + [ + -86.097017, + 39.902036 + ], + [ + -86.096958, + 39.901959 + ], + [ + -86.096938, + 39.901927 + ], + [ + -86.096904, + 39.901877 + ], + [ + -86.096869, + 39.901818 + ], + [ + -86.096841, + 39.901764 + ], + [ + -86.096826, + 39.901733 + ], + [ + -86.096786, + 39.901638 + ], + [ + -86.096766, + 39.901583 + ], + [ + -86.096753, + 39.901538 + ], + [ + -86.09674, + 39.901493 + ], + [ + -86.096732, + 39.901462 + ], + [ + -86.09672, + 39.901403 + ], + [ + -86.09671, + 39.90134 + ], + [ + -86.096706, + 39.901308 + ], + [ + -86.096703, + 39.901272 + ], + [ + -86.0967, + 39.901218 + ], + [ + -86.096697, + 39.90093 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17462071", + "properties": { + "timestamp": "2012-06-06T18:46:05Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Gwinnett Place", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Gwinnett", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108055644:108055645", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17462071" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.09763, + 39.905451 + ], + [ + -86.097632, + 39.904437 + ], + [ + -86.097635, + 39.90337 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17463192", + "properties": { + "timestamp": "2012-06-06T18:46:48Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Penn Place", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Penn", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108055648:108055649", + "tiger:upload_uuid": "bulk_upload.pl-6a2575c3-453e-4f55-86ab-3fdfe08e5f9c", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17463192" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.09575, + 39.905445 + ], + [ + -86.095751, + 39.904432 + ], + [ + -86.095756, + 39.903368 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17472157", + "properties": { + "timestamp": "2018-07-09T05:00:19Z", + "version": "3", + "changeset": "60523693", + "user": "ygudeti", + "uid": "7511407", + "highway": "residential", + "name": "Heyward Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "id": "way/17472157" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.09192, + 39.901838 + ], + [ + -86.091876, + 39.901811 + ], + [ + -86.091822, + 39.901775 + ], + [ + -86.09176, + 39.901729 + ], + [ + -86.091716, + 39.901684 + ], + [ + -86.091706, + 39.901675 + ], + [ + -86.091685, + 39.901652 + ], + [ + -86.091667, + 39.901629 + ], + [ + -86.091642, + 39.901588 + ], + [ + -86.091635, + 39.901579 + ], + [ + -86.091621, + 39.901551 + ], + [ + -86.091597, + 39.901502 + ], + [ + -86.091583, + 39.901462 + ], + [ + -86.091567, + 39.901394 + ], + [ + -86.091562, + 39.90134 + ], + [ + -86.091562, + 39.901299 + ], + [ + -86.091564, + 39.901272 + ], + [ + -86.091568, + 39.901241 + ], + [ + -86.091573, + 39.901214 + ], + [ + -86.091583, + 39.901174 + ], + [ + -86.091593, + 39.901151 + ], + [ + -86.091603, + 39.901124 + ], + [ + -86.091615, + 39.901097 + ], + [ + -86.091635, + 39.901057 + ], + [ + -86.091651, + 39.901034 + ], + [ + -86.091668, + 39.901012 + ], + [ + -86.091687, + 39.900985 + ], + [ + -86.091727, + 39.90094 + ], + [ + -86.091738, + 39.900931 + ], + [ + -86.091761, + 39.900909 + ], + [ + -86.091785, + 39.900891 + ], + [ + -86.09181, + 39.900869 + ], + [ + -86.091836, + 39.900851 + ], + [ + -86.091892, + 39.900816 + ], + [ + -86.091906, + 39.900811 + ], + [ + -86.091951, + 39.900784 + ], + [ + -86.091967, + 39.90078 + ], + [ + -86.09203, + 39.900754 + ], + [ + -86.092062, + 39.900745 + ], + [ + -86.092096, + 39.900732 + ], + [ + -86.09213, + 39.900723 + ], + [ + -86.092163, + 39.900719 + ], + [ + -86.092216, + 39.900705 + ], + [ + -86.092251, + 39.900701 + ], + [ + -86.092269, + 39.900701 + ], + [ + -86.092286, + 39.900702 + ], + [ + -86.092322, + 39.900697 + ], + [ + -86.092357, + 39.900698 + ], + [ + -86.092439, + 39.900698 + ], + [ + -86.09252, + 39.900708 + ], + [ + -86.092754, + 39.900746 + ], + [ + -86.09286, + 39.900756 + ], + [ + -86.092931, + 39.900756 + ], + [ + -86.092978, + 39.900752 + ], + [ + -86.09302, + 39.900752 + ], + [ + -86.093091, + 39.900744 + ], + [ + -86.093144, + 39.900735 + ], + [ + -86.093178, + 39.900731 + ], + [ + -86.093212, + 39.900722 + ], + [ + -86.093247, + 39.900718 + ], + [ + -86.093301, + 39.9007 + ], + [ + -86.093818, + 39.900542 + ], + [ + -86.094005, + 39.900494 + ], + [ + -86.094092, + 39.900481 + ], + [ + -86.094127, + 39.900473 + ], + [ + -86.094179, + 39.900469 + ], + [ + -86.094232, + 39.90046 + ], + [ + -86.094268, + 39.90046 + ], + [ + -86.094303, + 39.900456 + ], + [ + -86.094357, + 39.900452 + ], + [ + -86.094553, + 39.900453 + ], + [ + -86.094606, + 39.900458 + ], + [ + -86.094642, + 39.900459 + ], + [ + -86.094887, + 39.900492 + ], + [ + -86.094921, + 39.900501 + ], + [ + -86.094955, + 39.900506 + ], + [ + -86.09499, + 39.900515 + ], + [ + -86.095023, + 39.900525 + ], + [ + -86.09509, + 39.900543 + ], + [ + -86.095124, + 39.900553 + ], + [ + -86.095172, + 39.900571 + ], + [ + -86.095205, + 39.90058 + ], + [ + -86.095237, + 39.900594 + ], + [ + -86.095332, + 39.900631 + ], + [ + -86.095378, + 39.900654 + ], + [ + -86.095631, + 39.900773 + ], + [ + -86.09568, + 39.900791 + ], + [ + -86.095726, + 39.900809 + ], + [ + -86.095758, + 39.900819 + ], + [ + -86.09579, + 39.900833 + ], + [ + -86.095975, + 39.900883 + ], + [ + -86.096009, + 39.900893 + ], + [ + -86.096061, + 39.900902 + ], + [ + -86.09613, + 39.900912 + ], + [ + -86.096183, + 39.900921 + ], + [ + -86.096253, + 39.900931 + ], + [ + -86.096307, + 39.900936 + ], + [ + -86.096395, + 39.900936 + ], + [ + -86.096431, + 39.900941 + ], + [ + -86.096503, + 39.900942 + ], + [ + -86.096556, + 39.900938 + ], + [ + -86.096591, + 39.900938 + ], + [ + -86.096627, + 39.900934 + ], + [ + -86.096662, + 39.900929 + ], + [ + -86.096697, + 39.90093 + ], + [ + -86.096768, + 39.900921 + ], + [ + -86.096821, + 39.900913 + ], + [ + -86.096855, + 39.900904 + ], + [ + -86.09689, + 39.9009 + ], + [ + -86.096919, + 39.900891 + ], + [ + -86.096959, + 39.900887 + ], + [ + -86.097044, + 39.900865 + ], + [ + -86.097089, + 39.900852 + ], + [ + -86.097339, + 39.900772 + ], + [ + -86.097424, + 39.900751 + ], + [ + -86.097528, + 39.900733 + ], + [ + -86.097581, + 39.900725 + ], + [ + -86.097617, + 39.900725 + ], + [ + -86.097648, + 39.900721 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17483936", + "properties": { + "timestamp": "2012-06-04T13:38:17Z", + "version": "2", + "changeset": "11796728", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Wythe Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Wythe", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108039378:108039379", + "tiger:upload_uuid": "bulk_upload.pl-ed0550aa-ad5a-428d-acd8-2d7fb7833f78", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17483936" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.097648, + 39.900721 + ], + [ + -86.097645, + 39.900167 + ], + [ + -86.097643, + 39.900135 + ], + [ + -86.097641, + 39.900122 + ], + [ + -86.097628, + 39.900067 + ], + [ + -86.097609, + 39.900013 + ], + [ + -86.097596, + 39.899991 + ], + [ + -86.097583, + 39.899964 + ], + [ + -86.097567, + 39.899941 + ], + [ + -86.09755, + 39.899914 + ], + [ + -86.097532, + 39.899891 + ], + [ + -86.097522, + 39.899882 + ], + [ + -86.097501, + 39.899859 + ], + [ + -86.097455, + 39.899814 + ], + [ + -86.097405, + 39.899777 + ], + [ + -86.097349, + 39.899741 + ], + [ + -86.09732, + 39.899727 + ], + [ + -86.097305, + 39.899718 + ], + [ + -86.097274, + 39.899704 + ], + [ + -86.097242, + 39.899695 + ], + [ + -86.09721, + 39.899681 + ], + [ + -86.097126, + 39.899658 + ], + [ + -86.097091, + 39.899653 + ], + [ + -86.097057, + 39.899644 + ], + [ + -86.097039, + 39.899644 + ], + [ + -86.097004, + 39.899639 + ], + [ + -86.096879, + 39.899638 + ], + [ + -86.096739, + 39.899655 + ], + [ + -86.096521, + 39.899712 + ], + [ + -86.096487, + 39.899716 + ], + [ + -86.096469, + 39.899721 + ], + [ + -86.096434, + 39.899725 + ], + [ + -86.096416, + 39.899725 + ], + [ + -86.09638, + 39.899729 + ], + [ + -86.096345, + 39.899729 + ], + [ + -86.096291, + 39.899728 + ], + [ + -86.096221, + 39.899719 + ], + [ + -86.096204, + 39.899719 + ], + [ + -86.096151, + 39.899705 + ], + [ + -86.096134, + 39.899704 + ], + [ + -86.096101, + 39.899695 + ], + [ + -86.096067, + 39.899681 + ], + [ + -86.096051, + 39.899677 + ], + [ + -86.095866, + 39.899608 + ], + [ + -86.095715, + 39.899566 + ], + [ + -86.095681, + 39.899561 + ], + [ + -86.095612, + 39.899543 + ], + [ + -86.095507, + 39.899528 + ], + [ + -86.095313, + 39.899509 + ], + [ + -86.093974, + 39.899503 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17486873", + "properties": { + "timestamp": "2012-06-06T18:46:11Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Hopkins Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Hopkins", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108039430:108045983", + "tiger:upload_uuid": "bulk_upload.pl-ed0550aa-ad5a-428d-acd8-2d7fb7833f78", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17486873" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.094925, + 39.902952 + ], + [ + -86.094926, + 39.9027 + ], + [ + -86.094925, + 39.902668 + ], + [ + -86.094917, + 39.902587 + ], + [ + -86.094913, + 39.902556 + ], + [ + -86.094902, + 39.902497 + ], + [ + -86.094895, + 39.90247 + ], + [ + -86.094888, + 39.902438 + ], + [ + -86.094861, + 39.902352 + ], + [ + -86.094827, + 39.902267 + ], + [ + -86.0948, + 39.902212 + ], + [ + -86.094768, + 39.902153 + ], + [ + -86.094753, + 39.902131 + ], + [ + -86.094718, + 39.902076 + ], + [ + -86.094681, + 39.902027 + ], + [ + -86.094662, + 39.901999 + ], + [ + -86.094642, + 39.901977 + ], + [ + -86.094621, + 39.90195 + ], + [ + -86.0946, + 39.901927 + ], + [ + -86.094531, + 39.901859 + ], + [ + -86.094505, + 39.901832 + ], + [ + -86.094466, + 39.9018 + ], + [ + -86.094424, + 39.901763 + ], + [ + -86.094292, + 39.901668 + ], + [ + -86.094197, + 39.901613 + ], + [ + -86.094146, + 39.901585 + ], + [ + -86.094053, + 39.90154 + ], + [ + -86.09323, + 39.901164 + ], + [ + -86.093186, + 39.901141 + ], + [ + -86.093171, + 39.901132 + ], + [ + -86.093155, + 39.901118 + ], + [ + -86.093131, + 39.9011 + ], + [ + -86.093111, + 39.901082 + ], + [ + -86.093097, + 39.901068 + ], + [ + -86.093084, + 39.901059 + ], + [ + -86.093072, + 39.901041 + ], + [ + -86.09305, + 39.901014 + ], + [ + -86.093027, + 39.900978 + ], + [ + -86.093019, + 39.900964 + ], + [ + -86.093006, + 39.900932 + ], + [ + -86.092993, + 39.900892 + ], + [ + -86.092988, + 39.900869 + ], + [ + -86.092978, + 39.900752 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17493499", + "properties": { + "timestamp": "2012-06-06T18:45:53Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Dean Road", + "tiger:cfcc": "A45", + "tiger:county": "Marion, IN", + "tiger:name_base": "Dean", + "tiger:name_type": "Rd", + "tiger:reviewed": "no", + "tiger:separated": "yes", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108058013:108058062:108058066:108058067", + "tiger:upload_uuid": "bulk_upload.pl-ed0550aa-ad5a-428d-acd8-2d7fb7833f78", + "tiger:zip_left": "46240", + "id": "way/17493499" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.09865, + 39.898008 + ], + [ + -86.098624, + 39.898025 + ], + [ + -86.09861, + 39.898039 + ], + [ + -86.09859, + 39.898061 + ], + [ + -86.098579, + 39.898075 + ], + [ + -86.098567, + 39.898088 + ], + [ + -86.09855, + 39.898111 + ], + [ + -86.098536, + 39.898128 + ], + [ + -86.098507, + 39.898187 + ], + [ + -86.098495, + 39.898223 + ], + [ + -86.098486, + 39.898263 + ], + [ + -86.098484, + 39.898286 + ], + [ + -86.098475, + 39.898633 + ], + [ + -86.098474, + 39.899173 + ], + [ + -86.098482, + 39.89984 + ], + [ + -86.098496, + 39.90011 + ], + [ + -86.098503, + 39.900169 + ], + [ + -86.098512, + 39.900264 + ], + [ + -86.098513, + 39.900295 + ], + [ + -86.098514, + 39.900345 + ], + [ + -86.098513, + 39.900417 + ], + [ + -86.098508, + 39.900471 + ], + [ + -86.098489, + 39.900583 + ], + [ + -86.098471, + 39.900732 + ], + [ + -86.098466, + 39.900822 + ], + [ + -86.098465, + 39.900907 + ], + [ + -86.098467, + 39.901056 + ], + [ + -86.098468, + 39.902556 + ], + [ + -86.098457, + 39.905588 + ], + [ + -86.098458, + 39.905615 + ], + [ + -86.098461, + 39.905628 + ], + [ + -86.098463, + 39.905647 + ], + [ + -86.098488, + 39.905732 + ], + [ + -86.09849, + 39.905741 + ], + [ + -86.09849, + 39.90575 + ], + [ + -86.098488, + 39.905773 + ], + [ + -86.098483, + 39.905791 + ], + [ + -86.098474, + 39.905804 + ], + [ + -86.098462, + 39.905818 + ], + [ + -86.098449, + 39.905831 + ], + [ + -86.098433, + 39.905844 + ], + [ + -86.098406, + 39.905853 + ], + [ + -86.098395, + 39.905858 + ], + [ + -86.098375, + 39.905862 + ], + [ + -86.098362, + 39.905866 + ], + [ + -86.098272, + 39.905866 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17501810", + "properties": { + "timestamp": "2018-07-12T13:07:07Z", + "version": "4", + "changeset": "60652363", + "user": "vssms", + "uid": "8240204", + "highway": "residential", + "name": "Statesmen Drive", + "name_1": "894", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Statesmen", + "tiger:name_base_1": "894", + "tiger:name_type": "Dr", + "tiger:reviewed": "no", + "id": "way/17501810" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.098288, + 39.903375 + ], + [ + -86.098108, + 39.903373 + ], + [ + -86.0978715, + 39.9033715 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17509867", + "properties": { + "timestamp": "2012-06-06T18:46:08Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Heyward Drive", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_type": "Dr", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108055682:108055683", + "tiger:upload_uuid": "bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17509867" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.093837, + 39.905124 + ], + [ + -86.09384, + 39.904426 + ], + [ + -86.0938425, + 39.903737 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17509887", + "properties": { + "timestamp": "2012-06-06T18:46:10Z", + "version": "3", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "junction": "roundabout", + "name": "Heyward Drive", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_type": "Dr", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108038606:108038608:108038610:108038611", + "tiger:upload_uuid": "bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7", + "id": "way/17509887" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.093858, + 39.9029816 + ], + [ + -86.0938227, + 39.9029825 + ], + [ + -86.0937875, + 39.9029853 + ], + [ + -86.0937527, + 39.90299 + ], + [ + -86.0937185, + 39.9029967 + ], + [ + -86.0936849, + 39.9030052 + ], + [ + -86.0936522, + 39.9030155 + ], + [ + -86.0936206, + 39.9030276 + ], + [ + -86.0935902, + 39.9030414 + ], + [ + -86.0935612, + 39.9030568 + ], + [ + -86.0935337, + 39.9030738 + ], + [ + -86.0935078, + 39.9030923 + ], + [ + -86.0934837, + 39.9031122 + ], + [ + -86.0934616, + 39.9031333 + ], + [ + -86.0934415, + 39.9031556 + ], + [ + -86.0934235, + 39.9031789 + ], + [ + -86.0934077, + 39.9032032 + ], + [ + -86.0933943, + 39.9032282 + ], + [ + -86.0933832, + 39.903254 + ], + [ + -86.0933746, + 39.9032803 + ], + [ + -86.0933684, + 39.9033069 + ], + [ + -86.0933648, + 39.9033339 + ], + [ + -86.0933636, + 39.903361 + ], + [ + -86.0933654, + 39.9033916 + ], + [ + -86.0933704, + 39.9034219 + ], + [ + -86.0933786, + 39.9034518 + ], + [ + -86.0933899, + 39.9034812 + ], + [ + -86.0934043, + 39.9035097 + ], + [ + -86.0934217, + 39.9035372 + ], + [ + -86.0934418, + 39.9035636 + ], + [ + -86.0934647, + 39.9035887 + ], + [ + -86.0934902, + 39.9036122 + ], + [ + -86.0935181, + 39.9036341 + ], + [ + -86.0935481, + 39.9036541 + ], + [ + -86.0935802, + 39.9036723 + ], + [ + -86.0936142, + 39.9036884 + ], + [ + -86.0936496, + 39.9037023 + ], + [ + -86.0936865, + 39.903714 + ], + [ + -86.0937245, + 39.9037234 + ], + [ + -86.0937633, + 39.9037303 + ], + [ + -86.0938027, + 39.9037349 + ], + [ + -86.0938425, + 39.903737 + ], + [ + -86.0938817, + 39.9037366 + ], + [ + -86.0939207, + 39.9037338 + ], + [ + -86.0939593, + 39.9037287 + ], + [ + -86.0939972, + 39.9037213 + ], + [ + -86.0940343, + 39.9037115 + ], + [ + -86.0940702, + 39.9036995 + ], + [ + -86.0941047, + 39.9036854 + ], + [ + -86.0941377, + 39.9036692 + ], + [ + -86.094169, + 39.903651 + ], + [ + -86.0941982, + 39.903631 + ], + [ + -86.0942253, + 39.9036093 + ], + [ + -86.09425, + 39.903586 + ], + [ + -86.0942722, + 39.9035613 + ], + [ + -86.0942918, + 39.9035353 + ], + [ + -86.0943087, + 39.9035081 + ], + [ + -86.0943227, + 39.9034801 + ], + [ + -86.0943337, + 39.9034512 + ], + [ + -86.0943417, + 39.9034218 + ], + [ + -86.0943466, + 39.903392 + ], + [ + -86.0943485, + 39.903362 + ], + [ + -86.0943477, + 39.9033382 + ], + [ + -86.094345, + 39.9033146 + ], + [ + -86.0943404, + 39.903291 + ], + [ + -86.0943338, + 39.9032678 + ], + [ + -86.0943253, + 39.9032449 + ], + [ + -86.094315, + 39.9032225 + ], + [ + -86.0943029, + 39.9032006 + ], + [ + -86.094289, + 39.9031794 + ], + [ + -86.0942734, + 39.9031588 + ], + [ + -86.0942561, + 39.9031391 + ], + [ + -86.0942372, + 39.9031202 + ], + [ + -86.0942169, + 39.9031023 + ], + [ + -86.0941951, + 39.9030854 + ], + [ + -86.0941719, + 39.9030696 + ], + [ + -86.0941476, + 39.9030549 + ], + [ + -86.094122, + 39.9030414 + ], + [ + -86.0940954, + 39.9030292 + ], + [ + -86.0940679, + 39.9030183 + ], + [ + -86.0940395, + 39.9030088 + ], + [ + -86.0940104, + 39.9030006 + ], + [ + -86.0939806, + 39.9029939 + ], + [ + -86.0939504, + 39.9029886 + ], + [ + -86.0939198, + 39.9029848 + ], + [ + -86.093889, + 39.9029825 + ], + [ + -86.093858, + 39.9029816 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17509896", + "properties": { + "timestamp": "2012-06-06T18:46:10Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Heyward Drive", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_type": "Dr", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108038615", + "tiger:upload_uuid": "bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17509896" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.093858, + 39.9029816 + ], + [ + -86.093851, + 39.902741 + ], + [ + -86.093846, + 39.9027 + ], + [ + -86.093832, + 39.902633 + ], + [ + -86.093816, + 39.902578 + ], + [ + -86.093788, + 39.902511 + ], + [ + -86.093755, + 39.902447 + ], + [ + -86.093723, + 39.902402 + ], + [ + -86.093705, + 39.902375 + ], + [ + -86.093687, + 39.902352 + ], + [ + -86.093625, + 39.902284 + ], + [ + -86.093602, + 39.902266 + ], + [ + -86.093579, + 39.902243 + ], + [ + -86.093555, + 39.902225 + ], + [ + -86.093529, + 39.902202 + ], + [ + -86.093449, + 39.902148 + ], + [ + -86.093332, + 39.902088 + ], + [ + -86.093285, + 39.902065 + ], + [ + -86.093253, + 39.902056 + ], + [ + -86.093221, + 39.902042 + ], + [ + -86.093054, + 39.901996 + ], + [ + -86.092914, + 39.901977 + ], + [ + -86.092879, + 39.901977 + ], + [ + -86.092266, + 39.901936 + ], + [ + -86.092249, + 39.901936 + ], + [ + -86.092231, + 39.901931 + ], + [ + -86.092196, + 39.901926 + ], + [ + -86.092179, + 39.901926 + ], + [ + -86.092061, + 39.901894 + ], + [ + -86.092028, + 39.901884 + ], + [ + -86.091996, + 39.901871 + ], + [ + -86.09198, + 39.901866 + ], + [ + -86.09192, + 39.901838 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/17519894", + "properties": { + "timestamp": "2012-06-06T18:47:06Z", + "version": "2", + "changeset": "11818393", + "user": "WernerP", + "uid": "315015", + "highway": "residential", + "name": "Rush Place", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Rush", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:separated": "no", + "tiger:source": "tiger_import_dch_v0.6_20070810", + "tiger:tlid": "108055650:108055651", + "tiger:upload_uuid": "bulk_upload.pl-7a0a2fce-411d-43c7-8f86-3d27a78c06e7", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/17519894" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.094806, + 39.905442 + ], + [ + -86.094809, + 39.904429 + ], + [ + -86.094815, + 39.903361 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/162451324", + "properties": { + "timestamp": "2018-07-09T06:07:51Z", + "version": "4", + "changeset": "60524850", + "user": "addatla", + "uid": "8407155", + "highway": "tertiary", + "name": "Dean Road", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Dean", + "tiger:name_type": "Rd", + "tiger:reviewed": "no", + "tiger:zip_left": "46240", + "tiger:zip_right": "46240", + "id": "way/162451324" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0983285, + 39.8924155 + ], + [ + -86.0983206, + 39.8926748 + ], + [ + -86.098312, + 39.894171 + ], + [ + -86.098312, + 39.894482 + ], + [ + -86.098272, + 39.896712 + ], + [ + -86.098271, + 39.89764 + ], + [ + -86.098273, + 39.897662 + ], + [ + -86.098276, + 39.897676 + ], + [ + -86.098279, + 39.897685 + ], + [ + -86.098289, + 39.897703 + ], + [ + -86.098308, + 39.89773 + ], + [ + -86.098318, + 39.897748 + ], + [ + -86.098322, + 39.897762 + ], + [ + -86.098327, + 39.897771 + ], + [ + -86.098331, + 39.897798 + ], + [ + -86.098332, + 39.898185 + ], + [ + -86.098301, + 39.900298 + ], + [ + -86.0983, + 39.900721 + ], + [ + -86.098288, + 39.903375 + ], + [ + -86.098273, + 39.905451 + ], + [ + -86.098272, + 39.905866 + ], + [ + -86.0982717, + 39.9060187 + ], + [ + -86.0982707, + 39.9065208 + ], + [ + -86.0982705, + 39.9066668 + ], + [ + -86.0982692, + 39.9073088 + ], + [ + -86.098269, + 39.907429 + ], + [ + -86.098268, + 39.9076954 + ], + [ + -86.098271, + 39.907776 + ], + [ + -86.0982731, + 39.9078264 + ], + [ + -86.098276, + 39.907897 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/311989171", + "properties": { + "timestamp": "2014-11-09T21:03:16Z", + "version": "1", + "changeset": "26674801", + "user": "erjiang", + "uid": "701297", + "highway": "service", + "id": "way/311989171" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0938112, + 39.9035743 + ], + [ + -86.0937198, + 39.9035425 + ], + [ + -86.0936353, + 39.9034841 + ], + [ + -86.0935813, + 39.9034087 + ], + [ + -86.0935398, + 39.9033577 + ], + [ + -86.093465, + 39.9033407 + ], + [ + -86.0933636, + 39.903361 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/604182871", + "properties": { + "timestamp": "2018-07-02T08:51:58Z", + "version": "1", + "changeset": "60340784", + "user": "ygudeti", + "uid": "7511407", + "access": "private", + "highway": "residential", + "name": "5987", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "5987", + "tiger:reviewed": "no", + "id": "way/604182871" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0932352, + 39.903361 + ], + [ + -86.093069, + 39.903361 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/606231314", + "properties": { + "timestamp": "2018-07-09T05:00:19Z", + "version": "1", + "changeset": "60523693", + "user": "ygudeti", + "uid": "7511407", + "access": "private", + "highway": "residential", + "name": "Heyward Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "id": "way/606231314" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.097648, + 39.900721 + ], + [ + -86.0978979, + 39.9007205 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/606231315", + "properties": { + "timestamp": "2018-07-09T05:00:19Z", + "version": "1", + "changeset": "60523693", + "user": "ygudeti", + "uid": "7511407", + "highway": "residential", + "name": "Heyward Lane", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_type": "Ln", + "tiger:reviewed": "no", + "id": "way/606231315" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0978979, + 39.9007205 + ], + [ + -86.098109, + 39.90072 + ], + [ + -86.0983, + 39.900721 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/607399318", + "properties": { + "timestamp": "2018-07-12T13:07:06Z", + "version": "1", + "changeset": "60652363", + "user": "vssms", + "uid": "8240204", + "access": "private", + "highway": "residential", + "name": "Heyward Place", + "name_1": "546", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Heyward", + "tiger:name_base_1": "546", + "tiger:name_type": "Pl", + "tiger:reviewed": "no", + "tiger:zip_left": "46250", + "tiger:zip_right": "46250", + "id": "way/607399318" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0978755, + 39.9054505 + ], + [ + -86.09763, + 39.905451 + ], + [ + -86.096686, + 39.905448 + ], + [ + -86.09575, + 39.905445 + ], + [ + -86.094806, + 39.905442 + ], + [ + -86.094194, + 39.905438 + ], + [ + -86.094176, + 39.905437 + ], + [ + -86.094138, + 39.905428 + ], + [ + -86.094122, + 39.905423 + ], + [ + -86.094088, + 39.905414 + ], + [ + -86.094035, + 39.905396 + ], + [ + -86.093964, + 39.905355 + ], + [ + -86.093922, + 39.905318 + ], + [ + -86.093906, + 39.9053 + ], + [ + -86.093889, + 39.905277 + ], + [ + -86.093877, + 39.905259 + ], + [ + -86.093864, + 39.905237 + ], + [ + -86.093847, + 39.905192 + ], + [ + -86.093842, + 39.905169 + ], + [ + -86.093837, + 39.905124 + ] + ] + } +}, +{ + "type": "Feature", + "id": "way/607399319", + "properties": { + "timestamp": "2018-07-12T13:07:06Z", + "version": "1", + "changeset": "60652363", + "user": "vssms", + "uid": "8240204", + "access": "private", + "highway": "residential", + "name": "Statesmen Drive", + "name_1": "894", + "tiger:cfcc": "A41", + "tiger:county": "Marion, IN", + "tiger:name_base": "Statesmen", + "tiger:name_base_1": "894", + "tiger:name_type": "Dr", + "tiger:reviewed": "no", + "id": "way/607399319" + }, + "geometry": { + "type": "LineString", + "coordinates": [ + [ + -86.0978715, + 39.9033715 + ], + [ + -86.097635, + 39.90337 + ], + [ + -86.096696, + 39.903371 + ], + [ + -86.096273, + 39.903368 + ], + [ + -86.095756, + 39.903368 + ], + [ + -86.094815, + 39.903361 + ], + [ + -86.0943485, + 39.903362 + ] + ] + } +}, +{ + "type": "Feature", + "id": "node/181005411", + "properties": { + "timestamp": "2012-04-16T12:18:58Z", + "version": "3", + "changeset": "11321053", + "user": "debutterfly", + "uid": "308181", + "highway": "turning_circle", + "id": "node/181005411" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -86.093974, + 39.899503 + ] + } +}, +{ + "type": "Feature", + "id": "node/181134239", + "properties": { + "timestamp": "2014-08-03T18:22:55Z", + "version": "3", + "changeset": "24521651", + "user": "svance92", + "uid": "401490", + "highway": "traffic_signals", + "traffic_signals:direction": "forward", + "id": "node/181134239" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -86.098268, + 39.9076954 + ] + } +}, +{ + "type": "Feature", + "id": "node/5733573172", + "properties": { + "timestamp": "2018-07-02T08:51:57Z", + "version": "1", + "changeset": "60340784", + "user": "ygudeti", + "uid": "7511407", + "access": "private", + "barrier": "gate", + "id": "node/5733573172" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -86.0932352, + 39.903361 + ] + } +}, +{ + "type": "Feature", + "id": "node/5748379661", + "properties": { + "timestamp": "2018-07-09T05:00:19Z", + "version": "1", + "changeset": "60523693", + "user": "ygudeti", + "uid": "7511407", + "access": "private", + "barrier": "gate", + "id": "node/5748379661" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -86.0978979, + 39.9007205 + ] + } +}, +{ + "type": "Feature", + "id": "node/5748482000", + "properties": { + "timestamp": "2018-07-09T06:07:51Z", + "version": "1", + "changeset": "60524850", + "user": "addatla", + "uid": "8407155", + "access": "private", + "barrier": "gate", + "id": "node/5748482000" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -86.0978755, + 39.9054505 + ] + } +}, +{ + "type": "Feature", + "id": "node/5748482001", + "properties": { + "timestamp": "2018-07-09T06:07:51Z", + "version": "1", + "changeset": "60524850", + "user": "addatla", + "uid": "8407155", + "access": "private", + "barrier": "gate", + "id": "node/5748482001" + }, + "geometry": { + "type": "Point", + "coordinates": [ + -86.0978715, + 39.9033715 + ] + } +} +] +} diff --git a/resources/unit_features.js b/resources/unit_features.js new file mode 100644 index 0000000..f18db29 --- /dev/null +++ b/resources/unit_features.js @@ -0,0 +1 @@ +var units_data = {"type":"FeatureCollection","features":[{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09743270388371,39.90443636322463],[-86.09726857767308,39.90443583856525]],"neighbors":[3,7,6],"id":5},"geometry":{"type":"Polygon","coordinates":[[[-86.09743299693511,39.9043824044711],[-86.09726887072448,39.90438187981172],[-86.09726974987589,39.90422000355112],[-86.09743387608654,39.904220528210494],[-86.09743299693511,39.9043824044711]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09723340777113,39.90443572610813],[-86.09706928156355,39.9044352011678]],"neighbors":[5,9,8],"id":7},"geometry":{"type":"Polygon","coordinates":[[[-86.09723370097947,39.904381767355105],[-86.09706957477191,39.90438124241478],[-86.0970704543942,39.90421936615568],[-86.09723458060178,39.904219891096],[-86.09723370097947,39.904381767355105]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09703411166225,39.90443508865048],[-86.09686998545774,39.9044345634292]],"neighbors":[7,11,10],"id":9},"geometry":{"type":"Polygon","coordinates":[[[-86.09703440502757,39.904381129897956],[-86.09687027882305,39.90438060467668],[-86.0968711589162,39.90421872841908],[-86.09703528512074,39.904219253640356],[-86.09703440502757,39.904381129897956]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09663552102202,39.90443362200502],[-86.09647139922141,39.90443256100163]],"neighbors":[11,15,14],"id":13},"geometry":{"type":"Polygon","coordinates":[[[-86.09663611371738,39.904379664698766],[-86.09647199191674,39.90437860369537],[-86.09647376999722,39.904216731776565],[-86.09663789179787,39.90421779277996],[-86.09663611371738,39.904379664698766]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.0964362302648,39.904432333613656],[-86.09627210847037,39.90443127232934]],"neighbors":[13,17,16],"id":15},"geometry":{"type":"Polygon","coordinates":[[[-86.09643682311707,39.90437837630841],[-86.09627270132268,39.9043773150241],[-86.0962744798739,39.904215443108335],[-86.09643860166837,39.90421650439266],[-86.09643682311707,39.90437837630841]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09623693951508,39.90443104488118],[-86.09607281272078,39.90443132837439]],"neighbors":[15,19,18],"id":17},"geometry":{"type":"Polygon","coordinates":[[[-86.09623678106844,39.90437708579625],[-86.09607265427412,39.90437736928946],[-86.09607217893571,39.90421549203468],[-86.09623630573002,39.904215208541466],[-86.09623678106844,39.90437708579625]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09603764264587,39.904431401817895],[-86.09587351562868,39.9044317444138]],"neighbors":[17,21,20],"id":19},"geometry":{"type":"Polygon","coordinates":[[[-86.09603745118022,39.904377442795976],[-86.09587332416302,39.90437778539188],[-86.09587274976786,39.9042159083261],[-86.09603687678506,39.90421556573019],[-86.09603745118022,39.904377442795976]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09563904900793,39.904431643867255],[-86.09547492279582,39.90443112156279]],"neighbors":[21,25,24],"id":23},"geometry":{"type":"Polygon","coordinates":[[[-86.09563934074366,39.90437768510954],[-86.09547521453156,39.90437716280506],[-86.09547608973602,39.90421528653186],[-86.09564021594814,39.90421580883634],[-86.09563934074366,39.90437768510954]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09543975289355,39.9044310096103],[-86.09527562668451,39.90443048702489]],"neighbors":[23,27,26],"id":25},"geometry":{"type":"Polygon","coordinates":[[[-86.09544004478624,39.90437705085307],[-86.09527591857719,39.90437652826767],[-86.09527679425251,39.904214651995964],[-86.09544092046153,39.90421517458138],[-86.09544004478624,39.90437705085307]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09524045678289,39.9044303750122],[-86.09507633057689,39.904429852145846]],"neighbors":[25,29,28],"id":27},"geometry":{"type":"Polygon","coordinates":[[[-86.09524074883254,39.904376416255474],[-86.09507662262652,39.904375893389116],[-86.09507749877268,39.90421401711892],[-86.09524162497871,39.904214539985276],[-86.09524074883254,39.904376416255474]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09504116067592,39.904429740072956],[-86.09487703447294,39.90442921692566]],"neighbors":[27,31,30],"id":29},"geometry":{"type":"Polygon","coordinates":[[[-86.09504145288253,39.90437578131673],[-86.09487732667955,39.90437525816943],[-86.09487820329659,39.90421338190074],[-86.09504232949958,39.90421390504803],[-86.09504145288253,39.90437578131673]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09464256838692,39.904428485305495],[-86.09447844210501,39.9044279775073]],"neighbors":[31,35,34],"id":33},"geometry":{"type":"Polygon","coordinates":[[[-86.0946428520183,39.904374526522346],[-86.0944787257364,39.90437401872415],[-86.09447957662786,39.90421214237467],[-86.09464370290975,39.904212650172866],[-86.0946428520183,39.904374526522346]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09444327218779,39.904427868663284],[-86.09427914590883,39.90442736058414]],"neighbors":[33,37,36],"id":35},"geometry":{"type":"Polygon","coordinates":[[[-86.09444355597613,39.90437390988062],[-86.09427942969717,39.90437340180147],[-86.09428028105951,39.90421152545345],[-86.09444440733847,39.9042120335326],[-86.09444355597613,39.90437390988062]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09424397599223,39.90442725167995],[-86.09407984971624,39.90442674331985]],"neighbors":[35,39,38],"id":37},"geometry":{"type":"Polygon","coordinates":[[[-86.09424425993754,39.904373292897766],[-86.09408013366152,39.90437278453768],[-86.09408098549474,39.90421090819111],[-86.09424511177075,39.9042114165512],[-86.09424425993754,39.904373292897766]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09404467980028,39.904426634355445],[-86.09388055352724,39.90442612571442]],"neighbors":[37,null,40],"id":39},"geometry":{"type":"Polygon","coordinates":[[[-86.09404496390252,39.90437267557375],[-86.0938808376295,39.904372166932724],[-86.09388168993353,39.90421029058762],[-86.09404581620655,39.90421079922864],[-86.09404496390252,39.90437267557375]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.097632,39.904437],[-86.09746787378633,39.904436475621544]],"neighbors":[null,6,3],"id":4},"geometry":{"type":"Polygon","coordinates":[[[-86.09763170710508,39.90449095875404],[-86.09746758089142,39.904490434375575],[-86.0974667022039,39.90465231063767],[-86.09763082841756,39.90465283501613],[-86.09763170710508,39.90449095875404]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09743270388371,39.90443636322463],[-86.09726857767308,39.90443583856525]],"neighbors":[4,8,5],"id":6},"geometry":{"type":"Polygon","coordinates":[[[-86.09743241083184,39.904490321978166],[-86.09726828462122,39.90448979731878],[-86.09726740546287,39.90465167357937],[-86.09743153167351,39.90465219823876],[-86.09743241083184,39.904490321978166]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09723340777113,39.90443572610813],[-86.09706928156355,39.9044352011678]],"neighbors":[6,10,7],"id":8},"geometry":{"type":"Polygon","coordinates":[[[-86.09723311456231,39.90448968486116],[-86.09706898835474,39.90448915992084],[-86.09706810872552,39.904651036179914],[-86.0972322349331,39.90465156112024],[-86.09723311456231,39.90448968486116]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09703411166225,39.90443508865048],[-86.09686998545774,39.9044345634292]],"neighbors":[8,12,9],"id":10},"geometry":{"type":"Polygon","coordinates":[[[-86.09703381829648,39.90448904740302],[-86.09686969209196,39.90448852218173],[-86.09686881199187,39.9046503984393],[-86.09703293819638,39.90465092366059],[-86.09703381829648,39.90448904740302]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09663552102202,39.90443362200502],[-86.09647139922141,39.90443256100163]],"neighbors":[12,16,13],"id":14},"geometry":{"type":"Polygon","coordinates":[[[-86.09663492832573,39.90448757931128],[-86.09647080652512,39.90448651830789],[-86.09646902843066,39.90464839022663],[-86.09663315023124,39.90464945123002],[-86.09663492832573,39.90448757931128]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.0964362302648,39.904432333613656],[-86.09627210847037,39.90443127232934]],"neighbors":[14,18,15],"id":16},"geometry":{"type":"Polygon","coordinates":[[[-86.09643563741156,39.904486290918896],[-86.09627151561718,39.90448522963458],[-86.0962697370519,39.90464710155028],[-86.09643385884628,39.9046481628346],[-86.09643563741156,39.904486290918896]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09623693951508,39.90443104488118],[-86.09607281272078,39.90443132837439]],"neighbors":[16,20,17],"id":18},"geometry":{"type":"Polygon","coordinates":[[[-86.09623709796197,39.9044850039661],[-86.09607297116764,39.904485287459316],[-86.09607344650982,39.904647164714085],[-86.09623757330412,39.90464688122088],[-86.09623709796197,39.9044850039661]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09603764264587,39.904431401817895],[-86.09587351562868,39.9044317444138]],"neighbors":[18,22,19],"id":20},"geometry":{"type":"Polygon","coordinates":[[[-86.09603783411184,39.90448536083982],[-86.09587370709463,39.90448570343573],[-86.0958742814943,39.90464758050149],[-86.09603840851152,39.9046472379056],[-86.09603783411184,39.90448536083982]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09563904900793,39.904431643867255],[-86.09547492279582,39.90443112156279]],"neighbors":[22,26,23],"id":24},"geometry":{"type":"Polygon","coordinates":[[[-86.09563875727173,39.90448560262498],[-86.09547463105963,39.90448508032051],[-86.09547375584827,39.90464695659369],[-86.09563788206036,39.90464747889815],[-86.09563875727173,39.90448560262498]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09543975289355,39.9044310096103],[-86.09527562668451,39.90443048702489]],"neighbors":[24,28,25],"id":26},"geometry":{"type":"Polygon","coordinates":[[[-86.0954394610004,39.90448496836753],[-86.09527533479135,39.90448444578212],[-86.09527445910916,39.90464632205379],[-86.09543858531819,39.904646844639196],[-86.0954394610004,39.90448496836753]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09524045678289,39.9044303750122],[-86.09507633057689,39.904429852145846]],"neighbors":[26,30,27],"id":28},"geometry":{"type":"Polygon","coordinates":[[[-86.09524016473279,39.90448433376892],[-86.09507603852678,39.90448381090257],[-86.09507516237372,39.904645687172746],[-86.0952392885797,39.9046462100391],[-86.09524016473279,39.90448433376892]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09504116067592,39.904429740072956],[-86.09487703447294,39.90442921692566]],"neighbors":[28,32,29],"id":30},"geometry":{"type":"Polygon","coordinates":[[[-86.09504086846887,39.90448369882918],[-86.09487674226588,39.90448317568188],[-86.09487586564194,39.90464505195056],[-86.0950399918449,39.90464557509785],[-86.09504086846887,39.90448369882918]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09464256838692,39.904428485305495],[-86.09447844210501,39.9044279775073]],"neighbors":[32,36,33],"id":34},"geometry":{"type":"Polygon","coordinates":[[[-86.0946422847551,39.904482444088664],[-86.09447815847318,39.90448193629045],[-86.09447730757502,39.90464381263991],[-86.09464143385692,39.90464432043811],[-86.0946422847551,39.904482444088664]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09444327218779,39.904427868663284],[-86.09427914590883,39.90442736058414]],"neighbors":[34,38,35],"id":36},"geometry":{"type":"Polygon","coordinates":[[[-86.09444298839902,39.90448182744596],[-86.09427886212006,39.904481319366816],[-86.09427801075103,39.904643195714804],[-86.09444213702997,39.90464370379395],[-86.09444298839902,39.90448182744596]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09424397599223,39.90442725167995],[-86.09407984971624,39.90442674331985]],"neighbors":[36,40,37],"id":38},"geometry":{"type":"Polygon","coordinates":[[[-86.09424369204648,39.90448121046214],[-86.09407956577049,39.904480702102035],[-86.09407871393059,39.90464257844857],[-86.09424284020656,39.904643086808676],[-86.09424369204648,39.90448121046214]]]}},{"type":"Feature","properties":{"street":"none","street_id":3,"OSM_street_id":"way/17441358","street_anchors":[[-86.09404467980028,39.904426634355445],[-86.09388055352724,39.90442612571442]],"neighbors":[38,null,39],"id":40},"geometry":{"type":"Polygon","coordinates":[[[-86.09404439569758,39.904480593137144],[-86.09388026942457,39.90448008449612],[-86.09387941711381,39.9046419608412],[-86.09404354338682,39.90464246948222],[-86.09404439569758,39.904480593137144]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.0977215,39.9057825],[-86.09755737202134,39.905781753940076]],"neighbors":[null,43,42],"id":41},"geometry":{"type":"Polygon","coordinates":[[[-86.09772191675137,39.90572854172522],[-86.09755778877269,39.90572779566529],[-86.0975590390228,39.90556592084093],[-86.0977231670015,39.905566666900846],[-86.09772191675137,39.90572854172522]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09752220174067,39.905781594039986],[-86.09735807376636,39.90578084769911]],"neighbors":[41,45,44],"id":43},"geometry":{"type":"Polygon","coordinates":[[[-86.097522618649,39.90572763576592],[-86.09735849067467,39.90572688942505],[-86.09735974139565,39.90556501460282],[-86.09752386936998,39.90556576094368],[-86.097522618649,39.90572763576592]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09732290348661,39.90578068773882],[-86.09715877551665,39.905779941117]],"neighbors":[43,47,46],"id":45},"geometry":{"type":"Polygon","coordinates":[[[-86.09732332055188,39.90572672946547],[-86.09715919258191,39.90572598284364],[-86.0971604437738,39.90556410802354],[-86.09732457174377,39.90556485464538],[-86.09732332055188,39.90572672946547]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09712360523783,39.9057797810965],[-86.0969594772722,39.90577903419373]],"neighbors":[45,49,48],"id":47},"geometry":{"type":"Polygon","coordinates":[[[-86.09712402246005,39.90572582282386],[-86.09695989449442,39.90572507592109],[-86.09696114615716,39.905563201103135],[-86.09712527412279,39.905563948005906],[-86.09712402246005,39.90572582282386]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09692430699432,39.90577887411302],[-86.09676017903303,39.90577812692929]],"neighbors":[47,51,50],"id":49},"geometry":{"type":"Polygon","coordinates":[[[-86.09692472437351,39.905724915841084],[-86.0967605964122,39.905724168657365],[-86.09676184854582,39.905562293841555],[-86.09692597650712,39.90556304102528],[-86.09692472437351,39.905724915841084]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09672500875608,39.9057779667884],[-86.09656088079915,39.90577721932372]],"neighbors":[49,53,52],"id":51},"geometry":{"type":"Polygon","coordinates":[[[-86.09672542629221,39.90572400851719],[-86.0965612983353,39.90572326105251],[-86.09656255093978,39.90556138623884],[-86.09672667889673,39.905562133703526],[-86.09672542629221,39.90572400851719]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09652571052314,39.905777059122606],[-86.09636158257055,39.905776311376975]],"neighbors":[51,55,54],"id":53},"geometry":{"type":"Polygon","coordinates":[[[-86.09652612821625,39.90572310085211],[-86.09636200026365,39.90572235310648],[-86.09636325333902,39.905560478294966],[-86.09652738129162,39.90556122604058],[-86.09652612821625,39.90572310085211]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09632641229545,39.90577615111567],[-86.09616228434723,39.90577540308908]],"neighbors":[53,57,56],"id":55},"geometry":{"type":"Polygon","coordinates":[[[-86.09632683014551,39.90572219284588],[-86.09616270219729,39.90572144481929],[-86.09616395574353,39.90555957000991],[-86.0963280836918,39.90556031803651],[-86.09632683014551,39.90572219284588]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09612711407306,39.90577524276757],[-86.09596298612918,39.90577449446003]],"neighbors":[55,59,58],"id":57},"geometry":{"type":"Polygon","coordinates":[[[-86.0961275320801,39.905721284498505],[-86.09596340413621,39.90572053619097],[-86.09596465815335,39.90555866138374],[-86.09612878609724,39.90555940969127],[-86.0961275320801,39.905721284498505]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09592781585597,39.905774334078316],[-86.09576368791643,39.905773585489825]],"neighbors":[57,61,60],"id":59},"geometry":{"type":"Polygon","coordinates":[[[-86.09592823401996,39.90572037580996],[-86.09576410608042,39.90571962722148],[-86.09576536056844,39.9055577524164],[-86.09592948850796,39.90555850100489],[-86.09592823401996,39.90572037580996]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09572851764416,39.90577342504792],[-86.09556438970898,39.90577267617848]],"neighbors":[59,63,62],"id":61},"geometry":{"type":"Polygon","coordinates":[[[-86.09572893596511,39.90571946678029],[-86.09556480802992,39.905718717910844],[-86.09556606298881,39.905556843107924],[-86.095730190924,39.905557591977356],[-86.09572893596511,39.90571946678029]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09552921943764,39.905772515676354],[-86.09536509150682,39.90577176652596]],"neighbors":[61,65,64],"id":63},"geometry":{"type":"Polygon","coordinates":[[[-86.09552963791553,39.90571855740944],[-86.09536550998472,39.905717808259034],[-86.0953667654145,39.90555593345826],[-86.09553089334533,39.905556682608655],[-86.09552963791553,39.90571855740944]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.0953299212364,39.90577160596365],[-86.09516579330993,39.90577085653231]],"neighbors":[63,67,66],"id":65},"geometry":{"type":"Polygon","coordinates":[[[-86.09533033987125,39.90571764769744],[-86.0951662119448,39.90571689826611],[-86.09516746784541,39.90555502346747],[-86.09533159577188,39.90555577289881],[-86.09533033987125,39.90571764769744]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09513062304046,39.90577069590976],[-86.09496649511836,39.90576994619748]],"neighbors":[65,69,68],"id":67},"geometry":{"type":"Polygon","coordinates":[[[-86.09513104183226,39.905716737644276],[-86.09496691391016,39.905715987932005],[-86.09496817028162,39.90555411313551],[-86.09513229820375,39.90555486284778],[-86.09513104183226,39.905716737644276]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09493132484981,39.90576978551476],[-86.0947671969321,39.90576903552151]],"neighbors":[67,71,70],"id":69},"geometry":{"type":"Polygon","coordinates":[[[-86.09493174379858,39.905715827249985],[-86.09476761588087,39.90571507725674],[-86.09476887272325,39.9055532024624],[-86.094933000641,39.905553952455655],[-86.09493174379858,39.905715827249985]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09473202666447,39.90576887477857],[-86.09456789875111,39.905768124504384]],"neighbors":[69,73,72],"id":71},"geometry":{"type":"Polygon","coordinates":[[[-86.09473244577022,39.90571491651452],[-86.09456831785684,39.90571416624034],[-86.09456957517006,39.90555229144815],[-86.09473370308346,39.905553041722335],[-86.09473244577022,39.90571491651452]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09453272848442,39.90576796370124],[-86.09436860057542,39.90576721314609]],"neighbors":[71,75,74],"id":73},"geometry":{"type":"Polygon","coordinates":[[[-86.09453314774713,39.9057140054379],[-86.09436901983811,39.905713254882755],[-86.09437027762226,39.905551380092724],[-86.09453440553126,39.90555213064787],[-86.09453314774713,39.9057140054379]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09433343030969,39.90576705228275],[-86.09417038397703,39.90575306573005]],"neighbors":[73,null,76],"id":75},"geometry":{"type":"Polygon","coordinates":[[[-86.0943412476338,39.905713427311944],[-86.09417820129954,39.90569944075926],[-86.09420165319366,39.90553856584368],[-86.0943646995327,39.90555255239637],[-86.0943412476338,39.905713427311944]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.0977215,39.9057825],[-86.09755737202134,39.905781753940076]],"neighbors":[null,44,41],"id":42},"geometry":{"type":"Polygon","coordinates":[[[-86.09772108324798,39.90583645827479],[-86.09755695526933,39.905835712214866],[-86.09755570500937,39.9059975870392],[-86.097719832988,39.90599833309913],[-86.09772108324798,39.90583645827479]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09752220174067,39.905781594039986],[-86.09735807376636,39.90578084769911]],"neighbors":[42,46,43],"id":44},"geometry":{"type":"Polygon","coordinates":[[[-86.09752178483171,39.905835552314066],[-86.0973576568574,39.90583480597319],[-86.09735640612656,39.90599668079539],[-86.09752053410087,39.90599742713626],[-86.09752178483171,39.905835552314066]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09732290348661,39.90578068773882],[-86.09715877551665,39.905779941117]],"neighbors":[44,48,45],"id":46},"geometry":{"type":"Polygon","coordinates":[[[-86.0973224864207,39.90583464601219],[-86.09715835845071,39.90583389939036],[-86.09715710724898,39.90599577421042],[-86.09732123521896,39.90599652083225],[-86.0973224864207,39.90583464601219]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09712360523783,39.9057797810965],[-86.0969594772722,39.90577903419373]],"neighbors":[46,50,47],"id":48},"geometry":{"type":"Polygon","coordinates":[[[-86.09712318801493,39.90583373936915],[-86.09695906004931,39.90583299246639],[-86.09695780837674,39.9059948672843],[-86.09712193634235,39.90599561418706],[-86.09712318801493,39.90583373936915]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09692430699432,39.90577887411302],[-86.09676017903303,39.90577812692929]],"neighbors":[48,52,49],"id":50},"geometry":{"type":"Polygon","coordinates":[[[-86.09692388961447,39.90583283238495],[-86.09675976165319,39.905832085201226],[-86.09675850950971,39.90599396001701],[-86.096922637471,39.90599470720072],[-86.09692388961447,39.90583283238495]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09672500875608,39.9057779667884],[-86.09656088079915,39.90577721932372]],"neighbors":[50,54,51],"id":52},"geometry":{"type":"Polygon","coordinates":[[[-86.09672459121927,39.905831925059616],[-86.09656046326235,39.90583117759494],[-86.09655921064798,39.90599305240856],[-86.09672333860489,39.90599379987325],[-86.09672459121927,39.905831925059616]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09652571052314,39.905777059122606],[-86.09636158257055,39.905776311376975]],"neighbors":[52,56,53],"id":54},"geometry":{"type":"Polygon","coordinates":[[[-86.09652529282937,39.90583101739311],[-86.09636116487678,39.90583026964748],[-86.09635991179155,39.90599214445896],[-86.09652403974411,39.905992892204594],[-86.09652529282937,39.90583101739311]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09632641229545,39.90577615111567],[-86.09616228434723,39.90577540308908]],"neighbors":[54,58,55],"id":56},"geometry":{"type":"Polygon","coordinates":[[[-86.09632599444473,39.905830109385455],[-86.0961618664965,39.90582936135886],[-86.0961606129404,39.9059912361682],[-86.0963247408886,39.90599198419479],[-86.09632599444473,39.905830109385455]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09612711407306,39.90577524276757],[-86.09596298612918,39.90577449446003]],"neighbors":[56,60,57],"id":58},"geometry":{"type":"Polygon","coordinates":[[[-86.09612669606537,39.90582920103664],[-86.09596256812151,39.905828452729104],[-86.09596131409451,39.905990327536294],[-86.09612544203836,39.905991075843836],[-86.09612669606537,39.90582920103664]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09592781585597,39.905774334078316],[-86.09576368791643,39.905773585489825]],"neighbors":[58,62,59],"id":60},"geometry":{"type":"Polygon","coordinates":[[[-86.09592739769131,39.905828292346676],[-86.09576326975179,39.905827543758186],[-86.09576201525392,39.90598941856324],[-86.09592614319342,39.90599016715173],[-86.09592739769131,39.905828292346676]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09572851764416,39.90577342504792],[-86.09556438970898,39.90577267617848]],"neighbors":[60,64,61],"id":62},"geometry":{"type":"Polygon","coordinates":[[[-86.09572809932256,39.90582738331556],[-86.09556397138738,39.90582663444612],[-86.09556271641861,39.90598850924902],[-86.09572684435378,39.90598925811847],[-86.09572809932256,39.90582738331556]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09552921943764,39.905772515676354],[-86.09536509150682,39.90577176652596]],"neighbors":[62,66,63],"id":64},"geometry":{"type":"Polygon","coordinates":[[[-86.09552880095907,39.905826473943286],[-86.09536467302824,39.90582572479288],[-86.0953634175886,39.90598759959362],[-86.09552754551939,39.90598834874404],[-86.09552880095907,39.905826473943286]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.0953299212364,39.90577160596365],[-86.09516579330993,39.90577085653231]],"neighbors":[64,68,65],"id":66},"geometry":{"type":"Polygon","coordinates":[[[-86.09532950260088,39.90582556422986],[-86.09516537467441,39.905824814798514],[-86.09516411876389,39.90598668959712],[-86.09532824669033,39.90598743902846],[-86.09532950260088,39.90582556422986]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09513062304046,39.90577069590976],[-86.09496649511836,39.90576994619748]],"neighbors":[66,70,67],"id":68},"geometry":{"type":"Polygon","coordinates":[[[-86.09513020424798,39.90582465417525],[-86.0949660763259,39.90582390446298],[-86.09496481994454,39.90598577925943],[-86.09512894786661,39.905986528971695],[-86.09513020424798,39.90582465417525]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09493132484981,39.90576978551476],[-86.0947671969321,39.90576903552151]],"neighbors":[68,72,69],"id":70},"geometry":{"type":"Polygon","coordinates":[[[-86.09493090590037,39.90582374377953],[-86.09476677798266,39.90582299378628],[-86.09476552113038,39.90598486858058],[-86.09492964904808,39.90598561857383],[-86.09493090590037,39.90582374377953]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09473202666447,39.90576887477857],[-86.09456789875111,39.905768124504384]],"neighbors":[70,74,71],"id":72},"geometry":{"type":"Polygon","coordinates":[[[-86.09473160755809,39.905822833042635],[-86.09456747964471,39.905822082768445],[-86.09456622232159,39.905983957560586],[-86.09473035023494,39.905984707834776],[-86.09473160755809,39.905822833042635]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09453272848442,39.90576796370124],[-86.09436860057542,39.90576721314609]],"neighbors":[72,76,73],"id":74},"geometry":{"type":"Polygon","coordinates":[[[-86.09453230922107,39.905821921964574],[-86.09436818131208,39.90582117140943],[-86.09436692351804,39.90598304619942],[-86.09453105142701,39.90598379675457],[-86.09453230922107,39.905821921964574]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09433343030969,39.90576705228275],[-86.09417038397703,39.90575306573005]],"neighbors":[74,77,75],"id":76},"geometry":{"type":"Polygon","coordinates":[[[-86.09432561297335,39.90582067725303],[-86.0941625666423,39.905806690700345],[-86.09413911456463,39.90596756560802],[-86.09430216089089,39.905981552160725],[-86.09432561297335,39.90582067725303]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09414486911409,39.905737818781056],[-86.09411684308208,39.905619241877446]],"neighbors":[76,78,null],"id":77},"geometry":{"type":"Polygon","coordinates":[[[-86.09407565575391,39.905747445010604],[-86.09404762984168,39.90562886810701],[-86.0938399900038,39.905657746548776],[-86.09386801555665,39.905776323452386],[-86.09407565575391,39.905747445010604]]]}},{"type":"Feature","properties":{"street":"none","street_id":4,"OSM_street_id":"way/17441359","street_anchors":[[-86.09411755192019,39.90559226774652],[-86.09412085982403,39.90546638846879]],"neighbors":[77,null,null],"id":78},"geometry":{"type":"Polygon","coordinates":[[[-86.0940472246065,39.90559118022267],[-86.09405053263956,39.90546530094494],[-86.09383955109948,39.905462038118486],[-86.09383624267879,39.90558791739622],[-86.0940472246065,39.90559118022267]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09668720618212,39.90529511833808],[-86.09668819950451,39.905169215792974]],"neighbors":[79,83,82],"id":81},"geometry":{"type":"Polygon","coordinates":[[[-86.09675754619144,39.905295444881766],[-86.09675853938458,39.905169542336665],[-86.09696955902878,39.90517052171273],[-86.09696856622345,39.90529642425783],[-86.09675754619144,39.905295444881766]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09668841235884,39.90514223667616],[-86.09668940567683,39.90501633413104]],"neighbors":[81,85,84],"id":83},"geometry":{"type":"Polygon","coordinates":[[[-86.09675875221122,39.90514256321912],[-86.09675974539992,39.90501666067401],[-86.09697076457329,39.90501764004791],[-86.09696977177236,39.905143542593024],[-86.09675875221122,39.90514256321912]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.0966896185302,39.90498935501424],[-86.09669061184374,39.904863452469094]],"neighbors":[83,87,86],"id":85},"geometry":{"type":"Polygon","coordinates":[[[-86.09675995822562,39.90498968155647],[-86.0967609514099,39.90486377901132],[-86.09697197011239,39.904864758383034],[-86.09697097731589,39.90499066092817],[-86.09675995822562,39.90498968155647]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669082469615,39.90483647335228],[-86.09669181800527,39.90471057080715]],"neighbors":[85,89,88],"id":87},"geometry":{"type":"Polygon","coordinates":[[[-86.09676116423462,39.904836799893786],[-86.0967621574145,39.90471089734866],[-86.09697317564611,39.9047118767182],[-86.09697218285405,39.90483777926333],[-86.09676116423462,39.904836799893786]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669468098761,39.904072058790966],[-86.09669491787398,39.9039461540712]],"neighbors":[87,91,90],"id":89},"geometry":{"type":"Polygon","coordinates":[[[-86.09676502095597,39.90407213664994],[-86.09676525771307,39.90394623193017],[-86.09697627723135,39.90394646525209],[-86.096976040862,39.90407236997185],[-86.09676502095597,39.90407213664994]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669496863523,39.90391917448838],[-86.09669520552056,39.9037932697686]],"neighbors":[89,93,92],"id":91},"geometry":{"type":"Polygon","coordinates":[[[-86.09676530844665,39.903919252347194],[-86.09676554520271,39.903793347627406],[-86.0969765642501,39.90379358094883],[-86.09697632788179,39.90391948566862],[-86.09676530844665,39.903919252347194]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669525628159,39.903766290185786],[-86.09669549316585,39.90364038546601]],"neighbors":[91,95,94],"id":93},"geometry":{"type":"Polygon","coordinates":[[[-86.09676559593603,39.90376636804441],[-86.09676583269105,39.90364046332465],[-86.09697685126757,39.90364069664554],[-86.09697661490033,39.90376660136531],[-86.09676559593603,39.90376636804441]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669554392666,39.9036134058832],[-86.09669578080988,39.90348750116341]],"neighbors":[93,null,96],"id":95},"geometry":{"type":"Polygon","coordinates":[[[-86.09676588342417,39.903613483741644],[-86.0967661201781,39.90348757902187],[-86.09697713828379,39.90348781234224],[-86.09697690191759,39.90361371706202],[-86.09676588342417,39.903613483741644]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.096686,39.905448],[-86.09668699332686,39.90532209745489]],"neighbors":[null,82,79],"id":80},"geometry":{"type":"Polygon","coordinates":[[[-86.09661565983438,39.90544767341311],[-86.0966166532905,39.90532177086798],[-86.09640563318548,39.905320790852265],[-86.09640463934159,39.905446693397366],[-86.09661565983438,39.90544767341311]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09668720618212,39.90529511833808],[-86.09668819950451,39.905169215792974]],"neighbors":[80,84,81],"id":82},"geometry":{"type":"Polygon","coordinates":[[[-86.09661686617346,39.905294791751906],[-86.09661785962513,39.9051688892068],[-86.09640683999096,39.905167909193295],[-86.09640584615154,39.90529381173838],[-86.09661686617346,39.905294791751906]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09668841235884,39.90514223667616],[-86.09668940567683,39.90501633413104]],"neighbors":[82,86,83],"id":84},"geometry":{"type":"Polygon","coordinates":[[[-86.09661807250714,39.90514191009071],[-86.09661906595439,39.90501600754559],[-86.0964080467911,39.905015027534255],[-86.09640705295608,39.90514093007938],[-86.09661807250714,39.90514191009071]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.0966896185302,39.90498935501424],[-86.09669061184374,39.904863452469094]],"neighbors":[84,88,85],"id":86},"geometry":{"type":"Polygon","coordinates":[[[-86.09661927883545,39.904989028429526],[-86.09662027227824,39.904863125884376],[-86.09640925358582,39.90486214587523],[-86.09640825975524,39.90498804842037],[-86.09661927883545,39.904989028429526]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669082469615,39.90483647335228],[-86.09669181800527,39.90471057080715]],"neighbors":[86,90,87],"id":88},"geometry":{"type":"Polygon","coordinates":[[[-86.09662048515835,39.90483614676828],[-86.09662147859673,39.90471024422316],[-86.09641046037515,39.904709264216166],[-86.09640946654899,39.90483516676131],[-86.09662048515835,39.90483614676828]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669468098761,39.904072058790966],[-86.09669491787398,39.9039461540712]],"neighbors":[88,92,89],"id":90},"geometry":{"type":"Polygon","coordinates":[[[-86.09662434101944,39.904071980889505],[-86.09662457803503,39.90394607616974],[-86.09641355851919,39.903945842210376],[-86.0964133211158,39.904071746930136],[-86.09662434101944,39.904071980889505]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669496863523,39.90391917448838],[-86.09669520552056,39.9037932697686]],"neighbors":[90,94,91],"id":92},"geometry":{"type":"Polygon","coordinates":[[[-86.096624628824,39.90391909658709],[-86.09662486583859,39.9037931918673],[-86.09641384679361,39.90379295790844],[-86.09641360939125,39.90391886262823],[-86.096624628824,39.90391909658709]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669525628159,39.903766290185786],[-86.09669549316585,39.90364038546601]],"neighbors":[92,96,93],"id":94},"geometry":{"type":"Polygon","coordinates":[[[-86.0966249166273,39.90376621228468],[-86.09662515364082,39.90364030756489],[-86.0964141350667,39.903640073606574],[-86.0964138976654,39.90376597832634],[-86.0966249166273,39.90376621228468]]]}},{"type":"Feature","properties":{"street":"none","street_id":5,"OSM_street_id":"way/17444242","street_anchors":[[-86.09669554392666,39.9036134058832],[-86.09669578080988,39.90348750116341]],"neighbors":[94,null,95],"id":96},"geometry":{"type":"Polygon","coordinates":[[[-86.09662520442934,39.90361332798226],[-86.0966254414418,39.90348742326247],[-86.09641442333852,39.90348718930466],[-86.09641418593829,39.90361309402445],[-86.09662520442934,39.90361332798226]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.097338,39.903038],[-86.09718588605072,39.90306874973067]],"neighbors":[null,100,98],"id":97},"geometry":{"type":"Polygon","coordinates":[[[-86.09732007654115,39.90298582198948],[-86.09716796258384,39.90301657172015],[-86.09711419234698,39.90286003767202],[-86.09726630632842,39.90282928794135],[-86.09732007654115,39.90298582198948]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09695142448803,39.903068043409796],[-86.096787301397,39.903067548704264]],"neighbors":[97,102,101],"id":100},"geometry":{"type":"Polygon","coordinates":[[[-86.09695170079932,39.90301408460431],[-86.0967875777083,39.90301358989878],[-86.09678840663958,39.9028517134823],[-86.09695252973061,39.90285220818783],[-86.09695170079932,39.90301408460431]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.0967521321635,39.90306744266584],[-86.09658800907536,39.90306694767938]],"neighbors":[100,104,103],"id":102},"geometry":{"type":"Polygon","coordinates":[[[-86.09675240863176,39.90301348386083],[-86.09658828554359,39.90301298887437],[-86.09658911494573,39.90285111245931],[-86.09675323803387,39.90285160744577],[-86.09675240863176,39.90301348386083]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09655283984249,39.903066841580745],[-86.09638871675722,39.903066346313345]],"neighbors":[102,106,105],"id":104},"geometry":{"type":"Polygon","coordinates":[[[-86.09655311646767,39.90301288277621],[-86.0963889933824,39.90301238750881],[-86.09638982325538,39.902850511095174],[-86.09655394634065,39.90285100636257],[-86.09655311646767,39.90301288277621]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09615425808806,39.90306526774016],[-86.09599013895404,39.90306426389942]],"neighbors":[106,110,109],"id":108},"geometry":{"type":"Polygon","coordinates":[[[-86.09615481883667,39.90301131023304],[-86.09599069970265,39.90301030639228],[-86.09599238194316,39.90284843387088],[-86.09615650107722,39.90284943771163],[-86.09615481883667,39.90301131023304]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09595497056881,39.90306404876058],[-86.09579084794527,39.903063479991985]],"neighbors":[108,112,111],"id":110},"geometry":{"type":"Polygon","coordinates":[[[-86.09595528825683,39.90301009008912],[-86.09579116563329,39.90300952132053],[-86.0957921186943,39.90284764530613],[-86.09595624131785,39.902848214074716],[-86.09595528825683,39.90301009008912]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.0957556787738,39.90306336284487],[-86.09559155597505,39.90306281601785]],"neighbors":[110,114,113],"id":112},"geometry":{"type":"Polygon","coordinates":[[[-86.09575598420366,39.90300940413175],[-86.09559186140493,39.903008857304734],[-86.09559277769164,39.902846981165375],[-86.0957569004904,39.90284752799241],[-86.09575598420366,39.90300940413175]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09555638680425,39.90306269881053],[-86.0953922640087,39.90306215170258]],"neighbors":[112,116,115],"id":114},"geometry":{"type":"Polygon","coordinates":[[[-86.09555669239106,39.90300874009793],[-86.0953925695955,39.90300819298999],[-86.09539348635305,39.9028463168522],[-86.09555760914861,39.90284686396014],[-86.09555669239106,39.90300874009793]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09535709483858,39.90306203443507],[-86.09519297204619,39.90306148704618]],"neighbors":[114,118,117],"id":116},"geometry":{"type":"Polygon","coordinates":[[[-86.09535740058233,39.903008075723],[-86.09519327778996,39.903007528334115],[-86.09519419501834,39.9028456521979],[-86.09535831781072,39.90284619958678],[-86.09535740058233,39.903008075723]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09515780287674,39.903061369718465],[-86.09499651180815,39.90304938385649]],"neighbors":[116,null,119],"id":118},"geometry":{"type":"Polygon","coordinates":[[[-86.09516458480375,39.90300766189516],[-86.09500329373397,39.90299567603318],[-86.09502363944765,39.902834552560854],[-86.09518493052097,39.902846538422835],[-86.09516458480375,39.90300766189516]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.097338,39.903038],[-86.09718588605072,39.90306874973067]],"neighbors":[null,99,97],"id":98},"geometry":{"type":"Polygon","coordinates":[[[-86.09735592348613,39.90309017800778],[-86.09720380954491,39.90312092773845],[-86.09725758019124,39.903277461745176],[-86.09740969410832,39.9032467120145],[-86.09735592348613,39.90309017800778]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.097150716816,39.90306864381264],[-86.09698659372211,39.90306814938804]],"neighbors":[98,101,null],"id":99},"geometry":{"type":"Polygon","coordinates":[[[-86.09715044066122,39.9031226026186],[-86.09698631756731,39.903122108194005],[-86.09698548910032,39.903283984611875],[-86.09714961219423,39.903284479036486],[-86.09715044066122,39.9031226026186]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09695142448803,39.903068043409796],[-86.096787301397,39.903067548704264]],"neighbors":[99,103,100],"id":101},"geometry":{"type":"Polygon","coordinates":[[[-86.09695114817627,39.90312200221528],[-86.09678702508526,39.90312150750976],[-86.09678619614743,39.90328338392621],[-86.09695031923846,39.90328387863173],[-86.09695114817627,39.90312200221528]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.0967521321635,39.90306744266584],[-86.09658800907536,39.90306694767938]],"neighbors":[101,105,102],"id":103},"geometry":{"type":"Polygon","coordinates":[[[-86.09675185569483,39.90312140147085],[-86.09658773260666,39.903120906484396],[-86.096586903198,39.90328278289943],[-86.09675102628617,39.90328327788589],[-86.09675185569483,39.90312140147085]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09655283984249,39.903066841580745],[-86.09638871675722,39.903066346313345]],"neighbors":[103,107,104],"id":105},"geometry":{"type":"Polygon","coordinates":[[[-86.09655256321686,39.90312080038529],[-86.09638844013159,39.90312030511789],[-86.09638761025208,39.90328218153151],[-86.09655173333735,39.9032826767989],[-86.09655256321686,39.90312080038529]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09615425808806,39.90306526774016],[-86.09599013895404,39.90306426389942]],"neighbors":[107,111,108],"id":109},"geometry":{"type":"Polygon","coordinates":[[[-86.09615369733856,39.903119225247295],[-86.09598957820457,39.903118221406544],[-86.09598789595078,39.9032800939279],[-86.09615201508478,39.90328109776864],[-86.09615369733856,39.903119225247295]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09595497056881,39.90306404876058],[-86.09579084794527,39.903063479991985]],"neighbors":[109,113,110],"id":111},"geometry":{"type":"Polygon","coordinates":[[[-86.09595465288031,39.90311800743204],[-86.09579053025676,39.90311743866346],[-86.09578957718824,39.90327931467783],[-86.09595369981176,39.903279883446416],[-86.09595465288031,39.90311800743204]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.0957556787738,39.90306336284487],[-86.09559155597505,39.90306281601785]],"neighbors":[111,115,112],"id":113},"geometry":{"type":"Polygon","coordinates":[[[-86.09575537334344,39.90311732155799],[-86.09559125054471,39.90311677473097],[-86.09559033425076,39.9032786508703],[-86.0957544570495,39.90327919769732],[-86.09575537334344,39.90311732155799]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09555638680425,39.90306269881053],[-86.0953922640087,39.90306215170258]],"neighbors":[113,117,114],"id":115},"geometry":{"type":"Polygon","coordinates":[[[-86.09555608121696,39.90311665752312],[-86.0953919584214,39.903116110415176],[-86.09539104165663,39.903277986552936],[-86.09555516445216,39.90327853366089],[-86.09555608121696,39.90311665752312]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09535709483858,39.90306203443507],[-86.09519297204619,39.90306148704618]],"neighbors":[115,119,116],"id":117},"geometry":{"type":"Polygon","coordinates":[[[-86.09535678909432,39.90311599314714],[-86.09519266630195,39.903115445758246],[-86.09519174906634,39.90327732189444],[-86.09535587185873,39.90327786928333],[-86.09535678909432,39.90311599314714]]]}},{"type":"Feature","properties":{"street":"none","street_id":6,"OSM_street_id":"way/17444338","street_anchors":[[-86.09515780287674,39.903061369718465],[-86.09499651180815,39.90304938385649]],"neighbors":[117,null,118],"id":119},"geometry":{"type":"Polygon","coordinates":[[[-86.0951510209391,39.90311507754139],[-86.0949897298717,39.90310309167941],[-86.09496938399855,39.90326421514579],[-86.09513067506238,39.90327620100778],[-86.0951510209391,39.90311507754139]]]}},{"type":"Feature","properties":{"street":"none","street_id":8,"OSM_street_id":"way/17453372","street_anchors":[[-86.098073704963,39.90545009636416],[-86.09790957547628,39.905450430630786]],"neighbors":[120,null,123],"id":122},"geometry":{"type":"Polygon","coordinates":[[[-86.09807351814796,39.905396137332644],[-86.09790938866124,39.90539647159926],[-86.09790882821787,39.905234594504684],[-86.0980729577046,39.90523426023806],[-86.09807351814796,39.905396137332644]]]}},{"type":"Feature","properties":{"street":"none","street_id":8,"OSM_street_id":"way/17453372","street_anchors":[[-86.098273,39.905451],[-86.0981088755671,39.9054500247055]],"neighbors":[null,123,120],"id":121},"geometry":{"type":"Polygon","coordinates":[[[-86.0982724551771,39.90550495760327],[-86.09810833074421,39.90550398230877],[-86.0981066962703,39.90566585511852],[-86.09827082070316,39.90566683041302],[-86.0982724551771,39.90550495760327]]]}},{"type":"Feature","properties":{"street":"none","street_id":8,"OSM_street_id":"way/17453372","street_anchors":[[-86.098073704963,39.90545009636416],[-86.09790957547628,39.905450430630786]],"neighbors":[121,null,122],"id":123},"geometry":{"type":"Polygon","coordinates":[[[-86.09807389177833,39.905504055395696],[-86.09790976229161,39.90550438966231],[-86.0979103227394,39.905666266756874],[-86.09807445222611,39.90566593249026],[-86.09807389177833,39.905504055395696]]]}},{"type":"Feature","properties":{"street":"none","street_id":9,"OSM_street_id":"way/17454701","street_anchors":[[-86.09563642702201,39.901588000000395],[-86.09578459329465,39.901638230407585]],"neighbors":[125,127,null],"id":126},"geometry":{"type":"Polygon","coordinates":[[[-86.09566485785918,39.901538645231916],[-86.09581302415265,39.90158887563911],[-86.09589831648086,39.90144081129203],[-86.09575015012484,39.90139058088483],[-86.09566485785918,39.901538645231916]]]}},{"type":"Feature","properties":{"street":"none","street_id":9,"OSM_street_id":"way/17454701","street_anchors":[[-86.09581062715161,39.90165616316334],[-86.09589023871531,39.90176405449535]],"neighbors":[126,128,null],"id":127},"geometry":{"type":"Polygon","coordinates":[[[-86.0958718381276,39.90162958192056],[-86.09595144978769,39.90173747325258],[-86.09613508271978,39.90165772933116],[-86.09605547077055,39.90154983799915],[-86.0958718381276,39.90162958192056]]]}},{"type":"Feature","properties":{"street":"none","street_id":9,"OSM_street_id":"way/17454701","street_anchors":[[-86.09589684030432,39.9017905123607],[-86.0958760076863,39.90191398270577]],"neighbors":[127,null,null],"id":128},"geometry":{"type":"Polygon","coordinates":[[[-86.09596659609731,39.90179743886907],[-86.09594576360499,39.90192090921415],[-86.09615503144568,39.901941688488485],[-86.0961758635609,39.901818218143404],[-86.09596659609731,39.90179743886907]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09568,39.900791],[-86.09560708996857,39.90090379845989]],"neighbors":[null,131,130],"id":129},"geometry":{"type":"Polygon","coordinates":[[[-86.09561698521381,39.900767028569696],[-86.09554407507865,39.9008798270296],[-86.09535503067345,39.900807912534056],[-86.0954279411198,39.90069511407415],[-86.09561698521381,39.900767028569696]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09559146635918,39.900927969552505],[-86.09551855603628,39.901040767956985]],"neighbors":[129,133,132],"id":131},"geometry":{"type":"Polygon","coordinates":[[[-86.09552845147799,39.90090399807429],[-86.09545554105136,39.90101679647878],[-86.0952664963612,39.90094488183951],[-86.095339407099,39.90083208343503],[-86.09552845147799,39.90090399807429]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09550293236444,39.90106493903771],[-86.09543383370233,39.9011790451969]],"neighbors":[131,135,134],"id":133},"geometry":{"type":"Polygon","coordinates":[[[-86.09543914282295,39.90104220513781],[-86.0953700440546,39.901156311296994],[-86.09517867536543,39.90108810938757],[-86.09524777445245,39.90097400322839],[-86.09543914282295,39.90104220513781]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09542195575418,39.901204439436576],[-86.09538481133615,39.90132669797859]],"neighbors":[133,136,null],"id":135},"geometry":{"type":"Polygon","coordinates":[[[-86.09535345468083,39.90119219118254],[-86.09531631014057,39.90131444972456],[-86.0951108067008,39.901277704720634],[-86.0951479516077,39.901155446178606],[-86.09535345468083,39.90119219118254]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09538192796026,39.901353584874485],[-86.09539213644857,39.90147888999001]],"neighbors":[135,137,null],"id":136},"geometry":{"type":"Polygon","coordinates":[[[-86.09531172767727,39.90135695067619],[-86.09532193603722,39.90148225579171],[-86.09511133476175,39.90149235294287],[-86.09510112678696,39.901367047827335],[-86.09531172767727,39.90135695067619]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09539892182946,39.90150534985742],[-86.09545338524063,39.90162360081339]],"neighbors":[136,138,null],"id":137},"geometry":{"type":"Polygon","coordinates":[[[-86.09533260238389,39.90152332607646],[-86.09538706568063,39.90164157703242],[-86.09518810679178,39.90169550546286],[-86.09513364383841,39.901577254506904],[-86.09533260238389,39.90152332607646]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09574144809855,39.90186545357762],[-86.09586166523292,39.901950813780225]],"neighbors":[137,139,null],"id":138},"geometry":{"type":"Polygon","coordinates":[[[-86.09569366969994,39.901905053596764],[-86.09581388677479,39.90199041379937],[-86.09567055106902,39.902109213739145],[-86.09555033417274,39.90202385353654],[-86.09569366969994,39.901905053596764]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09601225578562,39.90208816726411],[-86.09609800984363,39.902195309553065]],"neighbors":[138,142,140],"id":139},"geometry":{"type":"Polygon","coordinates":[[[-86.09595231480735,39.9021164009532],[-86.09603806877163,39.90222354324215],[-86.09585824525924,39.90230824412427],[-86.09577249157616,39.902201101835296],[-86.09595231480735,39.9021164009532]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09619343457324,39.902359297998494],[-86.09623997822818,39.902479937653496]],"neighbors":[139,145,143],"id":142},"geometry":{"type":"Polygon","coordinates":[[[-86.09612598830125,39.90237461150775],[-86.09617253183744,39.902495251162755],[-86.09597019248432,39.902541191456095],[-86.09592364930438,39.902420551801086],[-86.09612598830125,39.90237461150775]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09627311038949,39.902657805198764],[-86.09627567064472,39.902783661271236]],"neighbors":[142,null,146],"id":145},"geometry":{"type":"Polygon","coordinates":[[[-86.09620278036232,39.902658647140726],[-86.09620534048837,39.902784503213205],[-86.09599435000898,39.90278702878418],[-86.09599179027049,39.9026611727117],[-86.09620278036232,39.902658647140726]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09559146635918,39.900927969552505],[-86.09551855603628,39.901040767956985]],"neighbors":[130,134,131],"id":132},"geometry":{"type":"Polygon","coordinates":[[[-86.09565448128443,39.90095194099661],[-86.09558157106527,39.901064739401086],[-86.09577061641683,39.90113665352877],[-86.09584352632477,39.90102385512429],[-86.09565448128443,39.90095194099661]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09550293236444,39.90106493903771],[-86.09543383370233,39.9011790451969]],"neighbors":[132,140,133],"id":134},"geometry":{"type":"Polygon","coordinates":[[[-86.09556672194826,39.901087672902676],[-86.09549762339236,39.90120177906185],[-86.09568899271648,39.90126998044703],[-86.0957580909537,39.90115587428785],[-86.09556672194826,39.901087672902676]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09601225578562,39.90208816726411],[-86.09609800984363,39.902195309553065]],"neighbors":[134,141,139],"id":140},"geometry":{"type":"Polygon","coordinates":[[[-86.0960721967145,39.902059933544166],[-86.09615795086623,39.90216707583312],[-86.09633777363767,39.90208237448811],[-86.09625201920473,39.90197523219916],[-86.0960721967145,39.902059933544166]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09611461901981,39.90221909088566],[-86.09618090723092,39.902334089382116]],"neighbors":[140,143,null],"id":141},"geometry":{"type":"Polygon","coordinates":[[[-86.09617894829037,39.90219726850836],[-86.09624523660946,39.90231226700481],[-86.09643822449924,39.90224679965964],[-86.09637193585627,39.90213180116318],[-86.09617894829037,39.90219726850836]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09619343457324,39.902359297998494],[-86.09623997822818,39.902479937653496]],"neighbors":[141,144,142],"id":143},"geometry":{"type":"Polygon","coordinates":[[[-86.0962608808151,39.90234398445016],[-86.09630742458877,39.90246462410517],[-86.09650976348968,39.90241868322576],[-86.09646321935975,39.902298043570774],[-86.0962608808151,39.90234398445016]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09624739959071,39.902506309658094],[-86.09627048819343,39.90263090555101]],"neighbors":[143,146,null],"id":144},"geometry":{"type":"Polygon","coordinates":[[[-86.09631703789663,39.9024987153445],[-86.09634012662598,39.90262331123741],[-86.09654904183095,39.90260052804672],[-86.09652595272172,39.9024759321538],[-86.09631703789663,39.9024987153445]]]}},{"type":"Feature","properties":{"street":"none","street_id":10,"OSM_street_id":"way/17454713","street_anchors":[[-86.09627311038949,39.902657805198764],[-86.09627567064472,39.902783661271236]],"neighbors":[144,null,145],"id":146},"geometry":{"type":"Polygon","coordinates":[[[-86.09634344041493,39.90265696321432],[-86.09634600079933,39.90278281928679],[-86.09655699125281,39.902780293078564],[-86.09655443048084,39.90265443700609],[-86.09634344041493,39.90265696321432]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.097338,39.903038],[-86.0973821492787,39.9029216948834]],"neighbors":[null,148,null],"id":147},"geometry":{"type":"Polygon","coordinates":[[[-86.09740553385463,39.903053086401556],[-86.09744968301868,39.90293678128496],[-86.09765228441714,39.90298204025454],[-86.09760813559699,39.903098345371134],[-86.09740553385463,39.903053086401556]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09738224920302,39.902894715381386],[-86.09738271551547,39.902768811038655]],"neighbors":[147,149,null],"id":148},"geometry":{"type":"Polygon","coordinates":[[[-86.09745258775214,39.90289486867052],[-86.09745305393534,39.90276896432779],[-86.09766406919684,39.902769423940214],[-86.09766360340139,39.90289532828293],[-86.09745258775214,39.90289486867052]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09738281543933,39.90274183153664],[-86.09737832082253,39.902616047835025]],"neighbors":[148,151,150],"id":149},"geometry":{"type":"Polygon","coordinates":[[[-86.09745312770177,39.902740352941095],[-86.09744863295589,39.90261456923948],[-86.0976595693378,39.90261013319808],[-86.09766406447089,39.90273591689969],[-86.09745312770177,39.902740352941095]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09737549007865,39.90258915575984],[-86.0973439530734,39.90246576896678]],"neighbors":[149,152,null],"id":151},"geometry":{"type":"Polygon","coordinates":[[[-86.09744451425243,39.90257877331524],[-86.0974129771229,39.90245538652217],[-86.09762004914583,39.90242423894282],[-86.09765158664827,39.90254762573589],[-86.09744451425243,39.90257877331524]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.0973332973651,39.90244006578689],[-86.0972707097238,39.90232378349071]],"neighbors":[151,154,153],"id":152},"geometry":{"type":"Polygon","coordinates":[[[-86.09739831158124,39.90241947222671],[-86.0973357238296,39.902303189930535],[-86.09753076591255,39.90224140903216],[-86.0975933539952,39.90235769132834],[-86.09739831158124,39.90241947222671]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09725477529737,39.902299739497195],[-86.0971667460997,39.90219381127533]],"neighbors":[152,155,null],"id":154},"geometry":{"type":"Polygon","coordinates":[[[-86.0973140859807,39.902270732832875],[-86.09722605669133,39.90216480461101],[-86.09740398816488,39.902077784436756],[-86.09749201772934,39.902183712658626],[-86.0973140859807,39.902270732832875]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09714519608029,39.90217254190092],[-86.09704610126178,39.902072376585814]],"neighbors":[154,158,156],"id":155},"geometry":{"type":"Polygon","coordinates":[[[-86.09720122508446,39.90213992085455],[-86.09710213018404,39.90203975553946],[-86.09727021663075,39.901941892238604],[-86.09736931177689,39.9020420575537],[-86.09720122508446,39.90213992085455]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09693053746076,39.9019160256847],[-86.09686077755646,39.90180214243984]],"neighbors":[155,160,159],"id":158},"geometry":{"type":"Polygon","coordinates":[[[-86.09699419681104,39.901893076726864],[-86.09692443680093,39.90177919348202],[-86.09711541427853,39.901710346399696],[-86.09718517460605,39.90182422964455],[-86.09699419681104,39.901893076726864]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09684777876758,39.90177707334592],[-86.09679443993339,39.901658044864895]],"neighbors":[158,162,161],"id":160},"geometry":{"type":"Polygon","coordinates":[[[-86.09691429569875,39.901759531252466],[-86.09686095674901,39.901640502771436],[-86.09706050699151,39.90158787626304],[-86.0971138462879,39.90170690474405],[-86.09691429569875,39.901759531252466]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.0967839281941,39.901632302538026],[-86.0967449255916,39.90151005013187]],"neighbors":[160,164,163],"id":162},"geometry":{"type":"Polygon","coordinates":[[[-86.09685224924083,39.901619474823576],[-86.09681324651642,39.901497222417426],[-86.0970182091374,39.90145873903352],[-86.0970572122275,39.90158099143969],[-86.09685224924083,39.901619474823576]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09673759106684,39.90148366538703],[-86.09671305052206,39.90135921830129]],"neighbors":[162,166,165],"id":164},"geometry":{"type":"Polygon","coordinates":[[[-86.09680713714792,39.90147559428152],[-86.09678259647683,39.90135114719577],[-86.09699123424282,39.901326933629974],[-86.09701577529286,39.90145138071572],[-86.09680713714792,39.90147559428152]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.0967090519299,39.90133241544194],[-86.09669988276475,39.9012067454622]],"neighbors":[164,168,167],"id":166},"geometry":{"type":"Polygon","coordinates":[[[-86.09677927923126,39.90132939987522],[-86.09677010993731,39.90120372989548],[-86.09698079141789,39.90119468294117],[-86.09698996109823,39.90132035292091],[-86.09677927923126,39.90132939987522]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09669960173514,39.90117976671269],[-86.0966982902665,39.90105386588165]],"neighbors":[166,null,169],"id":168},"geometry":{"type":"Polygon","coordinates":[[[-86.0967699365614,39.90117933550676],[-86.09676862496354,39.90105343467574],[-86.0969796290493,39.90105214080305],[-86.09698094103486,39.90117804163408],[-86.0967699365614,39.90117933550676]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09738281543933,39.90274183153664],[-86.09737832082253,39.902616047835025]],"neighbors":[null,153,149],"id":150},"geometry":{"type":"Polygon","coordinates":[[[-86.09731250317385,39.902743310089726],[-86.09730800868613,39.90261752638811],[-86.0970970722587,39.90262196179259],[-86.09710156635919,39.902747745494196],[-86.09731250317385,39.902743310089726]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.0973332973651,39.90244006578689],[-86.0972707097238,39.90232378349071]],"neighbors":[150,156,152],"id":153},"geometry":{"type":"Polygon","coordinates":[[[-86.09726828310987,39.902460659310776],[-86.09720569557891,39.902344377014586],[-86.09701065290976,39.9024061573684],[-86.09707324010972,39.90252243966459],[-86.09726828310987,39.902460659310776]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09714519608029,39.90217254190092],[-86.09704610126178,39.902072376585814]],"neighbors":[153,157,155],"id":156},"geometry":{"type":"Polygon","coordinates":[[[-86.09708916702279,39.90220516292031],[-86.09699007228616,39.902104997605214],[-86.09682198503923,39.902202860501625],[-86.09692107953013,39.902303025816714],[-86.09708916702279,39.90220516292031]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09702770562726,39.90204938204259],[-86.09694622914645,39.901940166638354]],"neighbors":[156,159,null],"id":157},"geometry":{"type":"Polygon","coordinates":[[[-86.0969666581222,39.9020761841175],[-86.0968851817387,39.90196696871326],[-86.09670203922887,39.90204737474595],[-86.09678351532045,39.902156590150184],[-86.0969666581222,39.9020761841175]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09693053746076,39.9019160256847],[-86.09686077755646,39.90180214243984]],"neighbors":[157,161,158],"id":159},"geometry":{"type":"Polygon","coordinates":[[[-86.09686687806786,39.90193897460772],[-86.09679711826934,39.90182509136287],[-86.09660614015213,39.901893937923084],[-86.09667589963321,39.90200782116793],[-86.09686687806786,39.90193897460772]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09684777876758,39.90177707334592],[-86.09679443993339,39.901658044864895]],"neighbors":[159,163,160],"id":161},"geometry":{"type":"Polygon","coordinates":[[[-86.09678126180235,39.901794615401386],[-86.09672792308372,39.901675586920355],[-86.09652837233034,39.90172821285874],[-86.09658171070234,39.901847241339766],[-86.09678126180235,39.901794615401386]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.0967839281941,39.901632302538026],[-86.0967449255916,39.90151005013187]],"neighbors":[161,165,162],"id":163},"geometry":{"type":"Polygon","coordinates":[[[-86.09671560712181,39.90164513021239],[-86.09667660464117,39.90152287780623],[-86.09647164163647,39.90156136058877],[-86.0965106437514,39.90168361299492],[-86.09671560712181,39.90164513021239]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09673759106684,39.90148366538703],[-86.09671305052206,39.90135921830129]],"neighbors":[163,167,164],"id":165},"geometry":{"type":"Polygon","coordinates":[[[-86.09666804496938,39.901491736451014],[-86.09664350455088,39.90136728936527],[-86.09643486653914,39.90139150230794],[-86.09645940657869,39.90151594939368],[-86.09666804496938,39.901491736451014]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.0967090519299,39.90133241544194],[-86.09669988276475,39.9012067454622]],"neighbors":[165,169,166],"id":167},"geometry":{"type":"Polygon","coordinates":[[[-86.09663882462237,39.901335430966306],[-86.09662965558603,39.901209760986546],[-86.09641897401272,39.90121880730548],[-86.09642814266267,39.90134447728523],[-86.09663882462237,39.901335430966306]]]}},{"type":"Feature","properties":{"street":"none","street_id":11,"OSM_street_id":"way/17461175","street_anchors":[[-86.09669960173514,39.90117976671269],[-86.0966982902665,39.90105386588165]],"neighbors":[167,null,168],"id":169},"geometry":{"type":"Polygon","coordinates":[[[-86.096629266908,39.90118019787612],[-86.0966279555686,39.901054297045086],[-86.09641695146955,39.901055590280436],[-86.09641826242127,39.90118149111146],[-86.096629266908,39.90118019787612]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763060310006,39.90514523142633],[-86.09763085143382,39.905019326719525]],"neighbors":[null,174,173],"id":172},"geometry":{"type":"Polygon","coordinates":[[[-86.09770094416297,39.90514531304754],[-86.09770119236745,39.905019408340735],[-86.09791221516936,39.90501965294936],[-86.09791196735266,39.905145557656155],[-86.09770094416297,39.90514531304754]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763090464808,39.90499234713949],[-86.09763115298072,39.904866442432684]],"neighbors":[172,176,175],"id":174},"geometry":{"type":"Polygon","coordinates":[[[-86.097701245554,39.904992428760515],[-86.0977014937574,39.9048665240537],[-86.0979125160884,39.90486676866176],[-86.09791226827282,39.90499267336857],[-86.097701245554,39.904992428760515]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763120619476,39.904839462852664],[-86.09763145452631,39.90471355814586]],"neighbors":[174,178,177],"id":176},"geometry":{"type":"Polygon","coordinates":[[[-86.09770154694372,39.904839544473504],[-86.09770179514602,39.904713639766705],[-86.09791281700615,39.90471388437423],[-86.09791256919165,39.90483978908104],[-86.09770154694372,39.904839544473504]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763150774008,39.90468657856582],[-86.09763175607051,39.90456067385902]],"neighbors":[176,179,null],"id":178},"geometry":{"type":"Polygon","coordinates":[[[-86.09770184833208,39.90468666018649],[-86.09770209653325,39.904560755479686],[-86.0979131179225,39.90456100008667],[-86.0979128701091,39.90468690479348],[-86.09770184833208,39.90468666018649]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763180928407,39.90453369427898],[-86.09763208212982,39.904407789606694]],"neighbors":[178,180,null],"id":179},"geometry":{"type":"Polygon","coordinates":[[[-86.09770214970243,39.904533783959586],[-86.09770242241892,39.9044078792873],[-86.09791344328737,39.90440814807409],[-86.09791317095866,39.904534052746385],[-86.09770214970243,39.904533783959586]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763215798716,39.90438081005854],[-86.09763251198738,39.90425490550049]],"neighbors":[179,181,null],"id":180},"geometry":{"type":"Polygon","coordinates":[[[-86.09770249818219,39.904380926420046],[-86.09770285205315,39.90425502186199],[-86.09791387225188,39.904255370691544],[-86.0979135187687,39.904381275249584],[-86.09770249818219,39.904380926420046]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763258784442,39.90422792595232],[-86.09763294184307,39.90410202139425]],"neighbors":[180,182,null],"id":181},"geometry":{"type":"Polygon","coordinates":[[[-86.0977029278825,39.90422804231358],[-86.09770328175186,39.90410213775551],[-86.09791430147973,39.904102486584286],[-86.09791394799811,39.904228391142354],[-86.0977029278825,39.90422804231358]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763301769975,39.9040750418461],[-86.09763337169683,39.90394913728804]],"neighbors":[181,184,183],"id":182},"geometry":{"type":"Polygon","coordinates":[[[-86.09770335758087,39.90407515820709],[-86.09770371144867,39.90394925364904],[-86.09791473070567,39.90394960247704],[-86.09791437722562,39.904075507035095],[-86.09770335758087,39.90407515820709]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763344755316,39.90392215773986],[-86.09763380154865,39.9037962531818]],"neighbors":[182,186,185],"id":184},"geometry":{"type":"Polygon","coordinates":[[[-86.09770378727731,39.903922274100594],[-86.09770414114355,39.90379636954253],[-86.09791515992967,39.90379671836976],[-86.09791480645123,39.903922622927816],[-86.09770378727731,39.903922274100594]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763387740466,39.90376927363365],[-86.09763423139857,39.90364336907559]],"neighbors":[184,188,187],"id":186},"geometry":{"type":"Polygon","coordinates":[[[-86.09770421697186,39.903769389994125],[-86.09770457083653,39.903643485436056],[-86.0979155891518,39.9036438342625],[-86.0979152356749,39.90376973882058],[-86.09770421697186,39.903769389994125]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763430725424,39.90361638952742],[-86.09763466124657,39.90349048496935]],"neighbors":[186,null,189],"id":188},"geometry":{"type":"Polygon","coordinates":[[[-86.09770464666448,39.90361650588764],[-86.09770500052758,39.90349060132958],[-86.09791601837199,39.90349095015525],[-86.09791566489668,39.90361685471332],[-86.09770464666448,39.90361650588764]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763030155072,39.905298115713165],[-86.0976305498856,39.90517221100636]],"neighbors":[170,173,null],"id":171},"geometry":{"type":"Polygon","coordinates":[[[-86.09755996033104,39.905298034049295],[-86.09756020879516,39.90517212934249],[-86.09734918552488,39.905171884095864],[-86.09734893667296,39.90529778880266],[-86.09755996033104,39.905298034049295]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763060310006,39.90514523142633],[-86.09763085143382,39.905019326719525]],"neighbors":[171,175,172],"id":173},"geometry":{"type":"Polygon","coordinates":[[[-86.09756026203733,39.905145149762625],[-86.09756051050037,39.905019245055826],[-86.097349487701,39.905018999809734],[-86.09734923885016,39.90514490451654],[-86.09756026203733,39.905145149762625]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763090464808,39.90499234713949],[-86.09763115298072,39.904866442432684]],"neighbors":[173,177,174],"id":175},"geometry":{"type":"Polygon","coordinates":[[[-86.09756056374232,39.90499226547598],[-86.09756081220422,39.90486636076918],[-86.09734978987574,39.90486611552366],[-86.09734954102603,39.90499202023046],[-86.09756056374232,39.90499226547598]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763120619476,39.904839462852664],[-86.09763145452631,39.90471355814586]],"neighbors":[175,183,176],"id":177},"geometry":{"type":"Polygon","coordinates":[[[-86.09756086544597,39.90483938118934],[-86.09756111390676,39.904713476482534],[-86.09735009204917,39.90471323123755],[-86.09734984320058,39.90483913594436],[-86.09756086544597,39.90483938118934]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763301769975,39.9040750418461],[-86.09763337169683,39.90394913728804]],"neighbors":[177,185,182],"id":183},"geometry":{"type":"Polygon","coordinates":[[[-86.09756267781887,39.90407492544261],[-86.09756303194521,39.903949020884546],[-86.0973520126918,39.90394867141911],[-86.0973516581777,39.904074575977155],[-86.09756267781887,39.90407492544261]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763344755316,39.90392215773986],[-86.09763380154865,39.9037962531818]],"neighbors":[183,187,184],"id":185},"geometry":{"type":"Polygon","coordinates":[[[-86.09756310782926,39.90392204133664],[-86.09756346195398,39.90379613677858],[-86.09735244317145,39.903795787313925],[-86.09735208865895,39.903921691871986],[-86.09756310782926,39.90392204133664]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763387740466,39.90376927363365],[-86.09763423139857,39.90364336907559]],"neighbors":[185,189,186],"id":187},"geometry":{"type":"Polygon","coordinates":[[[-86.0975635378377,39.903769157230684],[-86.09756389196086,39.90364325267262],[-86.09735287364919,39.90364290320875],[-86.09735251913824,39.90376880776681],[-86.0975635378377,39.903769157230684]]]}},{"type":"Feature","properties":{"street":"none","street_id":12,"OSM_street_id":"way/17462071","street_anchors":[[-86.09763430725424,39.90361638952742],[-86.09763466124657,39.90349048496935]],"neighbors":[187,null,188],"id":189},"geometry":{"type":"Polygon","coordinates":[[[-86.09756396784422,39.90361627312471],[-86.09756432196582,39.90349036856665],[-86.09735330412498,39.90349001910354],[-86.09735294961563,39.903615923661604],[-86.09756396784422,39.90361627312471]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575,39.905445],[-86.09575012429067,39.90531909518518]],"neighbors":[null,192,191],"id":190},"geometry":{"type":"Polygon","coordinates":[[[-86.09582034143098,39.9054450408405],[-86.0958204655924,39.90531913602568],[-86.09603148949802,39.90531925829218],[-86.0960313657244,39.90544516310701],[-86.09582034143098,39.9054450408405]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575015092432,39.905292115582],[-86.09575027521444,39.90516621076718]],"neighbors":[190,194,193],"id":192},"geometry":{"type":"Polygon","coordinates":[[[-86.09582049219833,39.905292156422405],[-86.09582061635916,39.90516625160759],[-86.09603163979388,39.90516637387381],[-86.09603151602084,39.90529227868862],[-86.09582049219833,39.905292156422405]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575030184799,39.905139231164],[-86.09575042613753,39.905013326349184]],"neighbors":[192,196,195],"id":194},"geometry":{"type":"Polygon","coordinates":[[[-86.09582064296502,39.90513927200432],[-86.0958207671253,39.9050133671895],[-86.09603179008913,39.90501348945544],[-86.09603166631663,39.905139394270265],[-86.09582064296502,39.90513927200432]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575045277094,39.904986346746],[-86.09575057705993,39.904860441931184]],"neighbors":[194,198,197],"id":196},"geometry":{"type":"Polygon","coordinates":[[[-86.09582079373102,39.90498638758622],[-86.09582091789073,39.9048604827714],[-86.09603194038368,39.90486060503706],[-86.09603181661174,39.90498650985189],[-86.09582079373102,39.90498638758622]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575060369325,39.90483346232801],[-86.09575072798168,39.90470755751319]],"neighbors":[196,200,199],"id":198},"geometry":{"type":"Polygon","coordinates":[[[-86.09582094449637,39.904833503168135],[-86.09582106865554,39.904707598353326],[-86.09603209067758,39.90470772061872],[-86.0960319669062,39.90483362543351],[-86.09582094449637,39.904833503168135]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575270564484,39.90406904249234],[-86.09575329730096,39.90394313845949]],"neighbors":[198,202,201],"id":200},"geometry":{"type":"Polygon","coordinates":[[[-86.09582304522645,39.904069236987596],[-86.09582363675331,39.903943332954746],[-86.09603465511276,39.90394391618553],[-86.09603406397365,39.904069820218375],[-86.09582304522645,39.904069236987596]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575342408414,39.903916159023886],[-86.09575401573761,39.90379025499105]],"neighbors":[200,204,203],"id":202},"geometry":{"type":"Polygon","coordinates":[[[-86.09582376350878,39.90391635351871],[-86.095824355033,39.903790449485875],[-86.09603537292159,39.90379103271536],[-86.09603478178512,39.90391693674818],[-86.09582376350878,39.90391635351871]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.0957541425202,39.903763275555434],[-86.09575473417107,39.90363737152258]],"neighbors":[202,206,205],"id":204},"geometry":{"type":"Polygon","coordinates":[[[-86.09582448178793,39.90376347004982],[-86.0958250733095,39.90363756601697],[-86.09603609072724,39.903638149245154],[-86.09603549959341,39.903764053278],[-86.09582448178793,39.90376347004982]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.0957548609531,39.90361039208697],[-86.0957554526013,39.90348448805411]],"neighbors":[204,null,207],"id":206},"geometry":{"type":"Polygon","coordinates":[[[-86.09582520006384,39.903610586580925],[-86.09582579158277,39.90348468254807],[-86.09603680852967,39.90348526577495],[-86.09603621739848,39.9036111698078],[-86.09582520006384,39.903610586580925]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575015092432,39.905292115582],[-86.09575027521444,39.90516621076718]],"neighbors":[191,195,192],"id":193},"geometry":{"type":"Polygon","coordinates":[[[-86.09567980965039,39.905292074699105],[-86.09567993406978,39.90516616988428],[-86.09546891063631,39.9051660469806],[-86.09546878582914,39.905291951795405],[-86.09567980965039,39.905292074699105]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575030184799,39.905139231164],[-86.09575042613753,39.905013326349184]],"neighbors":[193,197,194],"id":195},"geometry":{"type":"Polygon","coordinates":[[[-86.09567996073102,39.905139190281204],[-86.09568008514982,39.90501328546638],[-86.09546906218725,39.90501316256297],[-86.09546893738064,39.905139067377796],[-86.09567996073102,39.905139190281204]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575045277094,39.904986346746],[-86.09575057705993,39.904860441931184]],"neighbors":[195,199,196],"id":197},"geometry":{"type":"Polygon","coordinates":[[[-86.09568011181095,39.90498630586329],[-86.09568023622921,39.90486040104847],[-86.09546921373753,39.90486027814534],[-86.09546908893148,39.90498618296017],[-86.09568011181095,39.90498630586329]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575060369325,39.90483346232801],[-86.09575072798168,39.90470755751319]],"neighbors":[197,201,198],"id":199},"geometry":{"type":"Polygon","coordinates":[[[-86.09568026289023,39.90483342144539],[-86.09568038730792,39.90470751663058],[-86.09546936528713,39.90470739372773],[-86.09546924048165,39.90483329854254],[-86.09568026289023,39.90483342144539]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575270564484,39.90406904249234],[-86.09575329730096,39.90394313845949]],"neighbors":[199,203,200],"id":201},"geometry":{"type":"Polygon","coordinates":[[[-86.09568236606364,39.90406884795459],[-86.09568295784902,39.903942943921734],[-86.09547193949557,39.903942360053506],[-86.09547134732243,39.90406826408636],[-86.09568236606364,39.90406884795459]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.09575342408414,39.903916159023886],[-86.09575401573761,39.90379025499105]],"neighbors":[201,205,202],"id":203},"geometry":{"type":"Polygon","coordinates":[[[-86.09568308465988,39.90391596448657],[-86.09568367644262,39.903790060453744],[-86.09547265856003,39.90378947658683],[-86.09547206638952,39.903915380619665],[-86.09568308465988,39.90391596448657]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.0957541425202,39.903763275555434],[-86.09575473417107,39.90363737152258]],"neighbors":[203,207,204],"id":205},"geometry":{"type":"Polygon","coordinates":[[[-86.09568380325291,39.90376308101855],[-86.095684395033,39.9036371769857],[-86.09547337762126,39.903636593120076],[-86.09547278545341,39.90376249715294],[-86.09568380325291,39.90376308101855]]]}},{"type":"Feature","properties":{"street":"none","street_id":13,"OSM_street_id":"way/17463192","street_anchors":[[-86.0957548609531,39.90361039208697],[-86.0957554526013,39.90348448805411]],"neighbors":[205,null,206],"id":207},"geometry":{"type":"Polygon","coordinates":[[[-86.09568452184273,39.90361019755052],[-86.09568511362018,39.903484293517664],[-86.09547409667931,39.90348370965336],[-86.09547350451409,39.90360961368622],[-86.09568452184273,39.90361019755052]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09192,39.901838],[-86.09179595336099,39.901755675085816]],"neighbors":[null,211,209],"id":208},"geometry":{"type":"Polygon","coordinates":[[[-86.0919660188159,39.90179719204645],[-86.09184197212157,39.90171486713227],[-86.09198002807447,39.90159244316249],[-86.09210407493468,39.90167476807666],[-86.0919660188159,39.90179719204645]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09165677809531,39.9016122360829],[-86.09159485895975,39.90149588274536]],"neighbors":[208,214,212],"id":211},"geometry":{"type":"Polygon","coordinates":[[[-86.0917218979385,39.901591841351085],[-86.09165997869238,39.901475488013546],[-86.09185533765766,39.90141430359957],[-86.09191725723554,39.90153065693711],[-86.0917218979385,39.901591841351085]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.091562,39.901318453757334],[-86.09157815233057,39.9011933906836]],"neighbors":[211,217,215],"id":214},"geometry":{"type":"Polygon","coordinates":[[[-86.09163199449449,39.901323773982874],[-86.09164814669732,39.90119871090914],[-86.09185812986277,39.90121467133331],[-86.09184197804319,39.90133973440703],[-86.09163199449449,39.901323773982874]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09165789128258,39.9010250818716],[-86.09174877322974,39.90092069517388]],"neighbors":[214,220,218],"id":217},"geometry":{"type":"Polygon","coordinates":[[[-86.09171638166744,39.9010550515505],[-86.0918072635255,39.90095066485278],[-86.09198273471974,39.901040573713175],[-86.09189185312903,39.901144960410896],[-86.09171638166744,39.9010550515505]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09192223330633,39.90080126002066],[-86.09206660956508,39.9007432375201]],"neighbors":[217,223,221],"id":220},"geometry":{"type":"Polygon","coordinates":[[[-86.09195487254514,39.90084905779063],[-86.09209924877626,39.900791035290084],[-86.092197166683,39.90093442854511],[-86.0920527905348,39.90099245104566],[-86.09195487254514,39.90084905779063]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09229165835528,39.90070121411811],[-86.0924550529908,39.900699981855425]],"neighbors":[220,226,224],"id":223},"geometry":{"type":"Polygon","coordinates":[[[-86.09229234971055,39.90075517073326],[-86.09245574434607,39.90075393847058],[-86.0924578184184,39.900915808316014],[-86.09229442378292,39.900917040578705],[-86.09229234971055,39.90075517073326]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09268501608366,39.900734797536934],[-86.09284690642663,39.90075476476262]],"neighbors":[223,228,227],"id":226},"geometry":{"type":"Polygon","coordinates":[[[-86.09267385116911,39.90078807261848],[-86.09283574150882,39.90080803984417],[-86.09280224665125,39.9009678650824],[-86.0926403563213,39.90094789785672],[-86.09267385116911,39.90078807261848]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09308032768209,39.90074520251758],[-86.09324037141145,39.900718757553825]],"neighbors":[228,231,230],"id":229},"geometry":{"type":"Polygon","coordinates":[[[-86.09309513761211,39.900797952049885],[-86.09325518133578,39.90077150708613],[-86.09329961124556,39.90092975567172],[-86.09313956753904,39.90095620063549],[-86.09309513761211,39.900797952049885]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09327310848349,39.900709297176476],[-86.09342521477548,39.900662039087386]],"neighbors":[229,232,null],"id":231},"geometry":{"type":"Polygon","coordinates":[[[-86.09329951101084,39.90075931054849],[-86.09345161728463,39.900712052459404],[-86.09353082504333,39.900862092539526],[-86.09337871882417,39.900909350628616],[-86.09329951101084,39.90075931054849]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09345788609257,39.90065205447315],[-86.09361035211312,39.90060545948551]],"neighbors":[231,234,233],"id":232},"geometry":{"type":"Polygon","coordinates":[[[-86.09348391626641,39.90070218257781],[-86.09363638226925,39.900655587590165],[-86.09371447296618,39.90080597186922],[-86.09356200701643,39.90085256685685],[-86.09348391626641,39.90070218257781]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09364302337625,39.900595474819326],[-86.09379548914502,39.90054887958925]],"neighbors":[232,236,235],"id":234},"geometry":{"type":"Polygon","coordinates":[[[-86.09366905366402,39.90064560288259],[-86.09382151941509,39.90059900765252],[-86.09389961045385,39.90074939180739],[-86.09374714475588,39.90079598703746],[-86.09366905366402,39.90064560288259]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09382837173085,39.900539337747155],[-86.0939840091662,39.90049938803982]],"neighbors":[234,239,237],"id":236},"geometry":{"type":"Polygon","coordinates":[[[-86.09385068948872,39.900590508636405],[-86.09400632691106,39.90055055892906],[-86.09407328034564,39.90070407157113],[-86.09391764296235,39.900744021278456],[-86.09385068948872,39.900590508636405]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.0942130788121,39.900463213034946],[-86.0943761011212,39.90045209746921]],"neighbors":[236,241,240],"id":239},"geometry":{"type":"Polygon","coordinates":[[[-86.09421930562172,39.90051696039116],[-86.09438232792982,39.900505844825425],[-86.09440100841425,39.90066708689207],[-86.09423798610916,39.9006782024578],[-86.09421930562172,39.90051696039116]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09441126850612,39.900452276913164],[-86.09457521611765,39.90045509586319]],"neighbors":[239,243,242],"id":241},"geometry":{"type":"Polygon","coordinates":[[[-86.0944096924015,39.900506222586195],[-86.09457364001298,39.900509041536225],[-86.09456891168404,39.90067087855519],[-86.09440496407278,39.90066805960515],[-86.0944096924015,39.900506222586195]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09461014967653,39.90045811526935],[-86.09477225450954,39.900476544553094]],"neighbors":[241,245,244],"id":243},"geometry":{"type":"Polygon","coordinates":[[[-86.09459983888212,39.90051149156658],[-86.09476194371233,39.90052992085032],[-86.0947310112244,39.90069004973652],[-86.0945689064025,39.900671620452776],[-86.09459983888212,39.90051149156658]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09480689285085,39.90048121011769],[-86.094966567103,39.900508974399344]],"neighbors":[243,248,246],"id":245},"geometry":{"type":"Polygon","coordinates":[[[-86.09479134503462,39.90053383452912],[-86.09495101928046,39.90056159881078],[-86.0949043756696,39.90071947203263],[-86.09474470144266,39.90069170775098],[-86.09479134503462,39.90053383452912]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09518465312658,39.90057445085407],[-86.0953312371726,39.90063070289926]],"neighbors":[245,254,249],"id":248},"geometry":{"type":"Polygon","coordinates":[[[-86.09515318624533,39.90062270905514],[-86.09529977026551,39.900678961100326],[-86.09520536927833,39.90082373565251],[-86.09505878533562,39.900767483607325],[-86.09515318624533,39.90062270905514]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09607727667999,39.90090435894308],[-86.0962382309689,39.900928890142154]],"neighbors":[248,259,255],"id":254},"geometry":{"type":"Polygon","coordinates":[[[-86.09606357063831,39.900957283792216],[-86.0962245249223,39.90098181499128],[-86.09618340665547,39.901140589529014],[-86.09602245238621,39.90111605832994],[-86.09606357063831,39.900957283792216]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09705559383507,39.900861650672006],[-86.0972075248164,39.90081407214897]],"neighbors":[254,260,null],"id":259},"geometry":{"type":"Polygon","coordinates":[[[-86.09708217631737,39.90091160793023],[-86.09723410728023,39.900864029407195],[-86.09731385490431,39.90101390114543],[-86.09716192399681,39.90106147966848],[-86.09708217631737,39.90091160793023]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.0972399826189,39.9008036856485],[-86.0973930964898,39.900758634993544]],"neighbors":[259,null,261],"id":260},"geometry":{"type":"Polygon","coordinates":[[[-86.09726517004228,39.90085406651458],[-86.09741828389662,39.90080901585963],[-86.09749384633928,39.90096015842517],[-86.09734073253463,39.90100520908013],[-86.09726517004228,39.90085406651458]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09192,39.901838],[-86.09179595336099,39.901755675085816]],"neighbors":[null,210,208],"id":209},"geometry":{"type":"Polygon","coordinates":[[[-86.09187398112931,39.901878807935354],[-86.09174993454558,39.90179648302118],[-86.09161187777046,39.90191890671811],[-86.09173592418833,39.90200123163229],[-86.09187398112931,39.901878807935354]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09177067333835,39.90173691893521],[-86.09167268464702,39.901636263717606]],"neighbors":[209,212,null],"id":210},"geometry":{"type":"Polygon","coordinates":[[[-86.09171431740288,39.90176920651358],[-86.09161632879434,39.90166855129598],[-86.09144726091765,39.90176541386741],[-86.09154524927781,39.901866069084996],[-86.09171431740288,39.90176920651358]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09165677809531,39.9016122360829],[-86.09159485895975,39.90149588274536]],"neighbors":[210,213,211],"id":212},"geometry":{"type":"Polygon","coordinates":[[[-86.09159165821335,39.901632630778295],[-86.09152973918836,39.90151627744075],[-86.09133437964161,39.9015774613084],[-86.09139629833484,39.901693814645945],[-86.09159165821335,39.901632630778295]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09158573911509,39.90146982604694],[-86.09156250182491,39.901345419712605]],"neighbors":[212,215,null],"id":213},"geometry":{"type":"Polygon","coordinates":[[[-86.09151611291298,39.90147747979855],[-86.09149287574922,39.90135307346421],[-86.09128399742879,39.9013760344692],[-86.09130723421332,39.901500440803545],[-86.09151611291298,39.90147747979855]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.091562,39.901318453757334],[-86.09157815233057,39.9011933906836]],"neighbors":[213,216,214],"id":215},"geometry":{"type":"Polygon","coordinates":[[[-86.09149200551637,39.90131313348972],[-86.0915081579747,39.90118807041599],[-86.09129817497228,39.90117210936065],[-86.09128202213071,39.90129717243437],[-86.09149200551637,39.90131313348972]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09158598425705,39.90116713621048],[-86.09164080465017,39.901048655817426]],"neighbors":[215,218,null],"id":216},"geometry":{"type":"Polygon","coordinates":[[[-86.09151969918689,39.901149086273676],[-86.09157451969462,39.901030605880614],[-86.09137566503749,39.900976455843775],[-86.09132084418592,39.901094936236824],[-86.09151969918689,39.901149086273676]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09165789128258,39.9010250818716],[-86.09174877322974,39.90092069517388]],"neighbors":[216,219,217],"id":218},"geometry":{"type":"Polygon","coordinates":[[[-86.0915994009489,39.900995112163315],[-86.09169028298514,39.900890725465594],[-86.09151481255833,39.90080081616444],[-86.09142393025479,39.90090520286217],[-86.0915994009489,39.900995112163315]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09177217357531,39.900900619820305],[-86.09189280051115,39.900815714103224]],"neighbors":[218,221,null],"id":219},"geometry":{"type":"Polygon","coordinates":[[[-86.09172462168868,39.900860860161586],[-86.09184524868346,39.90077595444451],[-86.0917025935314,39.900656675351826],[-86.09158196635988,39.900741581068914],[-86.09172462168868,39.900860860161586]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09192223330633,39.90080126002066],[-86.09206660956508,39.9007432375201]],"neighbors":[219,222,220],"id":221},"geometry":{"type":"Polygon","coordinates":[[[-86.09188959411306,39.900753462241525],[-86.09203397039944,39.90069543974098],[-86.09193605317573,39.9005520463487],[-86.09179167680644,39.90061006884924],[-86.09188959411306,39.900753462241525]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09209820235533,39.90073141702396],[-86.09225663194977,39.90070100000029]],"neighbors":[221,224,null],"id":222},"geometry":{"type":"Polygon","coordinates":[[[-86.09208112642675,39.90067907211352],[-86.09223955602876,39.900648655089846],[-86.0921883284223,39.900491620343466],[-86.09202989879753,39.90052203736713],[-86.09208112642675,39.90067907211352]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09229165835528,39.90070121411811],[-86.0924550529908,39.900699981855425]],"neighbors":[222,225,223],"id":224},"geometry":{"type":"Polygon","coordinates":[[[-86.09229096700109,39.90064725750296],[-86.09245436163663,39.90064602524028],[-86.09245228758063,39.90048415539476],[-86.09228889294506,39.900485387657454],[-86.09229096700109,39.90064725750296]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09248977455103,39.900704268470015],[-86.09265061017777,39.900729210262995]],"neighbors":[224,227,null],"id":225},"geometry":{"type":"Polygon","coordinates":[[[-86.0925037108462,39.90065137902881],[-86.09266454647803,39.90067632082178],[-86.09270635524973,39.90051765248814],[-86.0925455196027,39.900492710695154],[-86.0925037108462,39.90065137902881]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09268501608366,39.900734797536934],[-86.09284690642663,39.90075476476262]],"neighbors":[225,230,226],"id":227},"geometry":{"type":"Polygon","coordinates":[[[-86.09269618098085,39.900681522454306],[-86.09285807132707,39.90070148967998],[-86.09289156592423,39.90054166442569],[-86.09272967556825,39.900521697200006],[-86.09269618098085,39.900681522454306]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09308032768209,39.90074520251758],[-86.09324037141145,39.900718757553825]],"neighbors":[227,233,229],"id":230},"geometry":{"type":"Polygon","coordinates":[[[-86.09306551777485,39.90069245298339],[-86.09322556150993,39.90066600801963],[-86.09318113194219,39.90050775940576],[-86.09302108818996,39.90053420436952],[-86.09306551777485,39.90069245298339]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09345788609257,39.90065205447315],[-86.09361035211312,39.90060545948551]],"neighbors":[230,235,232],"id":233},"geometry":{"type":"Polygon","coordinates":[[[-86.09343185595681,39.90060192636267],[-86.09358432199505,39.90055533137504],[-86.0935062318694,39.90040494700869],[-86.09335376577806,39.900451541996325],[-86.09343185595681,39.90060192636267]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09364302337625,39.900595474819326],[-86.09379548914502,39.90054887958925]],"neighbors":[233,237,234],"id":235},"geometry":{"type":"Polygon","coordinates":[[[-86.09361699312655,39.900545346750235],[-86.09376945891302,39.90049875152017],[-86.09369136844556,39.900348367277985],[-86.09353890260596,39.90039496250807],[-86.09361699312655,39.900545346750235]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09382837173085,39.900539337747155],[-86.0939840091662,39.90049938803982]],"neighbors":[235,238,236],"id":237},"geometry":{"type":"Polygon","coordinates":[[[-86.09380605400631,39.90048816685364],[-86.09396169145465,39.9004482171463],[-86.09389473852008,39.90029470444006],[-86.09373910103267,39.9003346541474],[-86.09380605400631,39.90048816685364]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09401779312121,39.900492088388575],[-86.09417873684208,39.90046902024298]],"neighbors":[237,240,null],"id":238},"geometry":{"type":"Polygon","coordinates":[[[-86.09400487558231,39.90043904696025],[-86.09416581930753,39.90041597881465],[-86.09412706682387,39.90025685452105],[-86.09396612308561,39.90027992266665],[-86.09400487558231,39.90043904696025]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.0942130788121,39.900463213034946],[-86.0943761011212,39.90045209746921]],"neighbors":[238,242,239],"id":240},"geometry":{"type":"Polygon","coordinates":[[[-86.09420685201226,39.90040946567839],[-86.09436987432237,39.90039835011267],[-86.09435119398447,39.90023710804103],[-86.09418817167132,39.900248223606766],[-86.09420685201226,39.90040946567839]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09441126850612,39.900452276913164],[-86.09457521611765,39.90045509586319]],"neighbors":[240,244,241],"id":242},"geometry":{"type":"Polygon","coordinates":[[[-86.09441284460826,39.900398331240105],[-86.09457679221984,39.900401150190135],[-86.09458152051154,39.90023931317085],[-86.09441757289976,39.90023649422082],[-86.09441284460826,39.900398331240105]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09461014967653,39.90045811526935],[-86.09477225450954,39.900476544553094]],"neighbors":[242,246,243],"id":244},"geometry":{"type":"Polygon","coordinates":[[[-86.09462046045488,39.90040473897121],[-86.09478256529064,39.90042316825497],[-86.09481349753764,39.900263039355075],[-86.09465139269358,39.900244610071326],[-86.09462046045488,39.90040473897121]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09480689285085,39.90048121011769],[-86.094966567103,39.900508974399344]],"neighbors":[244,247,245],"id":246},"geometry":{"type":"Polygon","coordinates":[[[-86.0948224406432,39.90042858570418],[-86.09498211490164,39.90045634998583],[-86.09502875815429,39.900298476732836],[-86.09486908387696,39.90027071245118],[-86.0948224406432,39.90042858570418]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09499972293236,39.900517946344415],[-86.0951524691839,39.9005636759475]],"neighbors":[246,249,null],"id":247},"geometry":{"type":"Polygon","coordinates":[[[-86.09502529350789,39.90046767923613],[-86.09517803977648,39.90051340883921],[-86.09525475132916,39.90036260748062],[-86.09510200500938,39.90031687787755],[-86.09502529350789,39.90046767923613]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09518465312658,39.90057445085407],[-86.0953312371726,39.90063070289926]],"neighbors":[247,250,248],"id":249},"geometry":{"type":"Polygon","coordinates":[[[-86.09521611996352,39.90052619264449],[-86.09536270403535,39.900582444689675],[-86.09545710435773,39.90043767000991],[-86.09531052020839,39.90038141796473],[-86.09521611996352,39.90052619264449]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09536074621688,39.90064537311239],[-86.09550035692564,39.90071155140149]],"neighbors":[249,251,null],"id":250},"geometry":{"type":"Polygon","coordinates":[[[-86.09539771816917,39.90059946974861],[-86.09553732891362,39.90066564803772],[-86.09564824458035,39.90052793787598],[-86.09550863372877,39.900461759586875],[-86.09539771816917,39.90059946974861]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09553033863196,39.900725653464],[-86.09567252837978,39.90078825532514]],"neighbors":[250,252,null],"id":251},"geometry":{"type":"Polygon","coordinates":[[[-86.09556534890004,39.900678853625166],[-86.09570753867985,39.9007414554863],[-86.09581256929314,39.9006010559066],[-86.09567037941737,39.90053845404546],[-86.09556534890004,39.900678853625166]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09570394879846,39.90080037127241],[-86.09585411153081,39.9008503274823]],"neighbors":[251,253,null],"id":252},"geometry":{"type":"Polygon","coordinates":[[[-86.09573193265885,39.90075086649874],[-86.09588209541161,39.90080082270863],[-86.09596604681137,39.90065230834723],[-86.09581588399742,39.90060235213734],[-86.09573193265885,39.90075086649874]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09588728161258,39.900859292373454],[-86.09604285231089,39.90089885905672]],"neighbors":[252,255,null],"id":253},"geometry":{"type":"Polygon","coordinates":[[[-86.09590941550252,39.90080807448223],[-86.09606498621362,39.900847641165484],[-86.09613138772326,39.900693987466546],[-86.0959758169738,39.900654420783276],[-86.09590941550252,39.90080807448223]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09607727667999,39.90090435894308],[-86.0962382309689,39.900928890142154]],"neighbors":[253,256,254],"id":255},"geometry":{"type":"Polygon","coordinates":[[[-86.0960909827005,39.90085143409234],[-86.0962519369943,39.90087596529141],[-86.09629305494354,39.90071719072948],[-86.09613210063503,39.90069265953041],[-86.0960909827005,39.90085143409234]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.0964714493969,39.90094156180266],[-86.09663479794337,39.900932886009066]],"neighbors":[255,257,null],"id":256},"geometry":{"type":"Polygon","coordinates":[[[-86.0964665914879,39.900887731431915],[-86.09662994003499,39.90087905563832],[-86.0966153663556,39.90071756452487],[-86.09645201780668,39.900726240318455],[-86.0964665914879,39.900887731431915]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09666949353647,39.900929214101915],[-86.0968310342696,39.9009103438711]],"neighbors":[256,258,null],"id":257},"geometry":{"type":"Polygon","coordinates":[[[-86.09665890551942,39.900875869747345],[-86.09682044625548,39.90085699951652],[-86.09678868231202,39.90069696644701],[-86.09662714156723,39.90071583667783],[-86.09665890551942,39.900875869747345]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.09686470896655,39.90090289040493],[-86.0970224155902,39.90087058656033]],"neighbors":[257,261,null],"id":258},"geometry":{"type":"Polygon","coordinates":[[[-86.09684656434871,39.90085075751274],[-86.09700427098092,39.900818453668144],[-86.09694983731875,39.90066205497461],[-86.09679213066086,39.90069435881921],[-86.09684656434871,39.90085075751274]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.0972399826189,39.9008036856485],[-86.0973930964898,39.900758634993544]],"neighbors":[258,262,260],"id":261},"geometry":{"type":"Polygon","coordinates":[[[-86.09721479523257,39.90075330477696],[-86.09736790912001,39.90070825412202],[-86.09729234723291,39.900557111474726],[-86.09713923329579,39.900602162129665],[-86.09721479523257,39.90075330477696]]]}},{"type":"Feature","properties":{"street":"none","street_id":14,"OSM_street_id":"way/17472157","street_anchors":[[-86.0974266355448,39.900750543849284],[-86.09758719049634,39.9007250000008]],"neighbors":[261,null,null],"id":262},"geometry":{"type":"Polygon","coordinates":[[[-86.0974123527299,39.900697708839886],[-86.09757290768673,39.90067216499139],[-86.09753005939012,39.90051365995266],[-86.0973695044173,39.900539203801145],[-86.0974123527299,39.900697708839886]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.097648,39.900721],[-86.0976473182064,39.90059509623552]],"neighbors":[null,264,null],"id":263},"geometry":{"type":"Polygon","coordinates":[[[-86.09771833599434,39.90072077581715],[-86.09771765407152,39.90059487205268],[-86.09792866166407,39.90059419924918],[-86.09792934397461,39.90072010301365],[-86.09771833599434,39.90072077581715]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0976471721081,39.900568116857414],[-86.09764649031754,39.90044221309292]],"neighbors":[263,265,null],"id":264},"geometry":{"type":"Polygon","coordinates":[[[-86.09771750794553,39.90056789267506],[-86.09771682602573,39.900441988910565],[-86.09792783314752,39.90044131610856],[-86.09792851545502,39.90056721987304],[-86.09771750794553,39.90056789267506]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0976463442199,39.900415233714824],[-86.09764566243238,39.90028932995032]],"neighbors":[264,267,266],"id":265},"geometry":{"type":"Polygon","coordinates":[[[-86.0977166799004,39.90041500953298],[-86.09771599798366,39.90028910576848],[-86.0979270046347,39.90028843296799],[-86.09792768693913,39.900414336732496],[-86.0977166799004,39.90041500953298]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09764551633539,39.90026235057221],[-86.09764309260026,39.90013648160457]],"neighbors":[265,269,268],"id":267},"geometry":{"type":"Polygon","coordinates":[[[-86.09771584479195,39.90026155352442],[-86.09771342092762,39.90013568455679],[-86.09792440589986,39.900133293158554],[-86.09792683015174,39.90025916212619],[-86.09771584479195,39.90026155352442]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09763811470498,39.90010979299034],[-86.09759494928714,39.89998881775108]],"neighbors":[267,270,null],"id":269},"geometry":{"type":"Polygon","coordinates":[[[-86.09770595493093,39.90009554660866],[-86.09766278939331,39.8999745713694],[-86.09786630954254,39.89993183198719],[-86.09790947543944,39.90005280722645],[-86.09770595493093,39.90009554660866]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09758267906793,39.89996353866033],[-86.09749807333023,39.8998561369558]],"neighbors":[269,272,271],"id":270},"geometry":{"type":"Polygon","coordinates":[[[-86.09764287605327,39.89993562975484],[-86.09755827022123,39.8998282280503],[-86.09773886059997,39.89974450114708],[-86.09782346671507,39.899851902851616],[-86.09764287605327,39.89993562975484]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.097476371531,39.89983490694213],[-86.09735900090777,39.89974742915974]],"neighbors":[270,273,null],"id":272},"geometry":{"type":"Polygon","coordinates":[[[-86.09752538253848,39.89979620468345],[-86.0974080118527,39.89970872690105],[-86.09755504435526,39.89959262000121],[-86.09767241522876,39.8996800977836],[-86.09752538253848,39.89979620468345]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09733027845112,39.899731962012375],[-86.097185478643,39.899674285826784]],"neighbors":[272,275,274],"id":273},"geometry":{"type":"Polygon","coordinates":[[[-86.09736268876019,39.899684072860296],[-86.0972178889248,39.89962639667469],[-86.09731511949836,39.8994827291643],[-86.09745991941561,39.89954040534989],[-86.09736268876019,39.899684072860296]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09715235723628,39.8996652168705],[-86.09699304042572,39.89963891232877]],"neighbors":[273,276,null],"id":275},"geometry":{"type":"Polygon","coordinates":[[[-86.09716715576813,39.89961246549596],[-86.09700783895187,39.899586160954236],[-86.09705223439366,39.89942790681933],[-86.09721155122692,39.89945421136105],[-86.09716715576813,39.89961246549596]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09695787459219,39.89963863101236],[-86.09679481080698,39.89964822299463]],"neighbors":[275,278,277],"id":276},"geometry":{"type":"Polygon","coordinates":[[[-86.09695249726882,39.899584829717135],[-86.09678943348287,39.89959442169941],[-86.0967733015612,39.89943301781226],[-86.0969363653494,39.89942342582998],[-86.09695249726882,39.899584829717135]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09676007547412,39.899652440846594],[-86.09660385523183,39.89969033607662]],"neighbors":[276,279,null],"id":278},"geometry":{"type":"Polygon","coordinates":[[[-86.09673887041905,39.89960099228886],[-86.09658265016503,39.89963888751887],[-86.0965190351557,39.89948454182248],[-86.0966752554449,39.89944664659245],[-86.09673887041905,39.89960099228886]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09657056768364,39.89969903968653],[-86.09641122823463,39.89972553019682]],"neighbors":[278,282,280],"id":279},"geometry":{"type":"Polygon","coordinates":[[[-86.09655567108612,39.89964630455832],[-86.09639633163135,39.8996727950686],[-86.09635164195912,39.899514589672506],[-86.09651098143114,39.89948809916222],[-86.09655567108612,39.89964630455832]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09617950543429,39.89971252974107],[-86.09602718589232,39.89966811800572]],"neighbors":[279,284,283],"id":282},"geometry":{"type":"Polygon","coordinates":[[[-86.09620449320526,39.89966209051961],[-86.09605217364708,39.89961767878426],[-86.09612713669065,39.899466361087676],[-86.09627945629741,39.89951077282303],[-86.09620449320526,39.89966209051961]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09599555783831,39.89965632161755],[-86.09584714259537,39.89960275490759]],"neighbors":[282,286,285],"id":284},"geometry":{"type":"Polygon","coordinates":[[[-86.09602549987711,39.89960749592147],[-86.09587708461079,39.899553929211514],[-86.095966910401,39.899407452077064],[-86.09611532573757,39.89946101878703],[-86.09602549987711,39.89960749592147]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09581408078809,39.899593558922604],[-86.09565817827736,39.89955504651271]],"neighbors":[284,287,null],"id":286},"geometry":{"type":"Polygon","coordinates":[[[-86.09583563868377,39.89954219674487],[-86.09567973616093,39.899503684334974],[-86.09574440961775,39.89934959777781],[-86.09590031217692,39.899388110187694],[-86.09583563868377,39.89954219674487]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09562488287743,39.89954636075445],[-86.09546364819809,39.89952375423392]],"neighbors":[286,289,288],"id":287},"geometry":{"type":"Polygon","coordinates":[[[-86.09563752792153,39.89949328071999],[-86.095476293238,39.89947067419944],[-86.09551422824016,39.89931143408779],[-86.09567546293621,39.89933404060832],[-86.09563752792153,39.89949328071999]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09542876362691,39.89952033771496],[-86.09526558811052,39.899508787812394]],"neighbors":[287,291,290],"id":289},"geometry":{"type":"Polygon","coordinates":[[[-86.09543522552114,39.89946660669937],[-86.09527205000367,39.8994550567968],[-86.09529143562234,39.89929386374789],[-86.09545461114308,39.89930541365046],[-86.09543522552114,39.89946660669937]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09523042103044,39.89950863041286],[-86.09506630799208,39.89950789574123]],"neighbors":[289,293,292],"id":291},"geometry":{"type":"Polygon","coordinates":[[[-86.0952308313817,39.89945467210937],[-86.09506671834335,39.89945393743775],[-86.09506794939327,39.89929206252729],[-86.09523206243162,39.8992927971989],[-86.0952308313817,39.89945467210937]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0950311409129,39.899507738281514],[-86.09486702787882,39.899507003328985]],"neighbors":[291,295,294],"id":293},"geometry":{"type":"Polygon","coordinates":[[[-86.09503155142107,39.899453779978735],[-86.09486743838701,39.899453045026206],[-86.09486866990768,39.89929117011785],[-86.09503278294174,39.89929190507037],[-86.09503155142107,39.899453779978735]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09483186080055,39.899506845809064],[-86.09466774777076,39.89950611057566]],"neighbors":[293,297,296],"id":295},"geometry":{"type":"Polygon","coordinates":[[[-86.09483227146565,39.89945288750699],[-86.09466815843585,39.899452152273575],[-86.09466939042723,39.899290277367335],[-86.09483350345704,39.89929101260074],[-86.09483227146565,39.89945288750699]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0946325806934,39.89950595299555],[-86.09446846766785,39.89950521748125]],"neighbors":[295,299,298],"id":297},"geometry":{"type":"Polygon","coordinates":[[[-86.09463299151541,39.899451994694175],[-86.09446887848986,39.89945125917988],[-86.09447011095197,39.89928938427573],[-86.09463422397755,39.89929011979004],[-86.09463299151541,39.899451994694175]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09443330059143,39.89950505984095],[-86.09426918757019,39.89950432404576]],"neighbors":[297,301,300],"id":299},"geometry":{"type":"Polygon","coordinates":[[[-86.09443371157033,39.89945110154028],[-86.0942695985491,39.89945036574509],[-86.09427083148196,39.89928849084307],[-86.0944349445032,39.899289226638246],[-86.09443371157033,39.89945110154028]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09423402049467,39.899504166345274],[-86.0940699074777,39.8995034302692]],"neighbors":[299,null,302],"id":301},"geometry":{"type":"Polygon","coordinates":[[[-86.0942344316305,39.89945020804531],[-86.09407031861352,39.899449471969234],[-86.0940715520171,39.89928759706932],[-86.09423566503408,39.899288333145385],[-86.0942344316305,39.89945020804531]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0976463442199,39.900415233714824],[-86.09764566243238,39.90028932995032]],"neighbors":[null,268,265],"id":266},"geometry":{"type":"Polygon","coordinates":[[[-86.09757600853894,39.90041545785418],[-86.09757532688067,39.90028955408968],[-86.09736432022274,39.90029022625283],[-86.0973650014933,39.90041613001732],[-86.09757600853894,39.90041545785418]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09764551633539,39.90026235057221],[-86.09764309260026,39.90013648160457]],"neighbors":[266,271,267],"id":268},"geometry":{"type":"Polygon","coordinates":[[[-86.09757518787723,39.90026314757752],[-86.09757276427128,39.900137278609876],[-86.09736177927448,39.900139669370894],[-86.0973642024929,39.90026553833854],[-86.09757518787723,39.90026314757752]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09758267906793,39.89996353866033],[-86.09749807333023,39.8998561369558]],"neighbors":[268,274,270],"id":271},"geometry":{"type":"Polygon","coordinates":[[[-86.09752248203355,39.8999914475347],[-86.09743787639022,39.89988404583018],[-86.09725728527594,39.89996777226655],[-86.09734189063626,39.900075173971075],[-86.09752248203355,39.8999914475347]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09733027845112,39.899731962012375],[-86.097185478643,39.899674285826784]],"neighbors":[271,277,273],"id":274},"geometry":{"type":"Polygon","coordinates":[[[-86.09729786809673,39.89977985115544],[-86.09715306831592,39.89972217496985],[-86.09705583706284,39.89986584234491],[-86.09720063676183,39.89992351853051],[-86.09729786809673,39.89977985115544]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09695787459219,39.89963863101236],[-86.09679481080698,39.89964822299463]],"neighbors":[274,280,276],"id":277},"geometry":{"type":"Polygon","coordinates":[[[-86.096963251924,39.89969243230733],[-86.09680018813955,39.8997020242896],[-86.0968163201879,39.89986342817301],[-86.09697938397007,39.89985383619075],[-86.096963251924,39.89969243230733]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09657056768364,39.89969903968653],[-86.09641122823463,39.89972553019682]],"neighbors":[277,281,279],"id":280},"geometry":{"type":"Polygon","coordinates":[[[-86.09658546430408,39.89975177481285],[-86.09642612486084,39.899778265323135],[-86.09647081487701,39.89993647069063],[-86.09663015430299,39.899909980180354],[-86.09658546430408,39.89975177481285]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09637638627392,39.8997290000005],[-86.09621326189308,39.89971900000032]],"neighbors":[280,283,null],"id":281},"geometry":{"type":"Polygon","coordinates":[[[-86.09637078381289,39.89978278777396],[-86.09620765943286,39.89977278777376],[-86.0961908519994,39.899934151092516],[-86.09635397637697,39.89994415109271],[-86.09637078381289,39.89978278777396]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09617950543429,39.89971252974107],[-86.09602718589232,39.89966811800572]],"neighbors":[281,285,282],"id":283},"geometry":{"type":"Polygon","coordinates":[[[-86.09615451762656,39.89976296895718],[-86.09600219810076,39.899718557221824],[-86.09592723450541,39.89986987483796],[-86.09607955398262,39.899914286573306],[-86.09615451762656,39.89976296895718]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09599555783831,39.89965632161755],[-86.09584714259537,39.89960275490759]],"neighbors":[283,288,284],"id":285},"geometry":{"type":"Polygon","coordinates":[[[-86.09596561575682,39.89970514730592],[-86.0958172005373,39.899651580595965],[-86.09572737410706,39.8997980576149],[-86.09587578925637,39.89985162432485],[-86.09596561575682,39.89970514730592]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09562488287743,39.89954636075445],[-86.09546364819809,39.89952375423392]],"neighbors":[285,290,287],"id":288},"geometry":{"type":"Polygon","coordinates":[[[-86.09561223781377,39.899599440787554],[-86.0954510031386,39.899576834267016],[-86.09541306784257,39.89973607435806],[-86.09557430250524,39.8997586808786],[-86.09561223781377,39.899599440787554]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09542876362691,39.89952033771496],[-86.09526558811052,39.899508787812394]],"neighbors":[288,292,289],"id":290},"geometry":{"type":"Polygon","coordinates":[[[-86.09542230172252,39.89957406873018],[-86.09525912620725,39.89956251882762],[-86.09523974043658,39.89972371187113],[-86.0954029159486,39.8997352617737],[-86.09542230172252,39.89957406873018]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09523042103044,39.89950863041286],[-86.09506630799208,39.89950789574123]],"neighbors":[290,294,291],"id":292},"geometry":{"type":"Polygon","coordinates":[[[-86.09523001067852,39.89956258871634],[-86.09506589764018,39.89956185404472],[-86.09506466658056,39.89972372895514],[-86.09522877961889,39.89972446362677],[-86.09523001067852,39.89956258871634]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0950311409129,39.899507738281514],[-86.09486702787882,39.899507003328985]],"neighbors":[292,296,293],"id":294},"geometry":{"type":"Polygon","coordinates":[[[-86.09503073040405,39.89956169658429],[-86.09486661737,39.89956096163177],[-86.09486538583964,39.899722836540086],[-86.09502949887369,39.899723571492615],[-86.09503073040405,39.89956169658429]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09483186080055,39.899506845809064],[-86.09466774777076,39.89950611057566]],"neighbors":[294,298,295],"id":296},"geometry":{"type":"Polygon","coordinates":[[[-86.09483145013482,39.89956080411115],[-86.09466733710501,39.89956006887774],[-86.09466610510394,39.89972194378395],[-86.09483021813372,39.899722679017366],[-86.09483145013482,39.89956080411115]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.0946325806934,39.89950595299555],[-86.09446846766785,39.89950521748125]],"neighbors":[296,300,297],"id":298},"geometry":{"type":"Polygon","coordinates":[[[-86.09463216987075,39.899559911296926],[-86.09446805684522,39.89955917578263],[-86.09446682437337,39.89972105068673],[-86.09463093739892,39.899721786201034],[-86.09463216987075,39.899559911296926]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09443330059143,39.89950505984095],[-86.09426918757019,39.89950432404576]],"neighbors":[298,302,299],"id":300},"geometry":{"type":"Polygon","coordinates":[[[-86.09443288961187,39.89955901814162],[-86.09426877659064,39.89955828234643],[-86.09426754364809,39.89972015724843],[-86.09443165666929,39.899720893043614],[-86.09443288961187,39.89955901814162]]]}},{"type":"Feature","properties":{"street":"none","street_id":15,"OSM_street_id":"way/17483936","street_anchors":[[-86.09423402049467,39.899504166345274],[-86.0940699074777,39.8995034302692]],"neighbors":[300,null,301],"id":302},"geometry":{"type":"Polygon","coordinates":[[[-86.09423360935818,39.899558124645246],[-86.09406949634123,39.89955738856917],[-86.09406826292796,39.89971926346905],[-86.0942323759449,39.89971999954513],[-86.09423360935818,39.899558124645246]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09492560668244,39.90279911624656],[-86.09492516311083,39.902673219549186]],"neighbors":[null,306,305],"id":304},"geometry":{"type":"Polygon","coordinates":[[[-86.09499594516011,39.90279897038237],[-86.09499550145925,39.902673073684994],[-86.09520651650273,39.90267263583747],[-86.09520696059128,39.902798532534845],[-86.09499594516011,39.90279897038237]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09492285714614,39.90264630362355],[-86.0949064886783,39.902521075650554]],"neighbors":[304,308,307],"id":306},"geometry":{"type":"Polygon","coordinates":[[[-86.09499284475434,39.90264092000169],[-86.09497647615859,39.9025156920287],[-86.09518643853345,39.90249954091068],[-86.09520280751293,39.90262476888367],[-86.09499284475434,39.90264092000169]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09490132388298,39.90249439212096],[-86.09486706531483,39.90237131917032]],"neighbors":[306,310,309],"id":308},"geometry":{"type":"Polygon","coordinates":[[[-86.09497011143397,39.90248312367025],[-86.09493585274228,39.90236005071961],[-86.0951422148888,39.902326245123625],[-86.09517647395116,39.902449318074275],[-86.09497011143397,39.90248312367025]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09485828188045,39.90234520470925],[-86.09480673948221,39.9022257285837]],"neighbors":[308,312,311],"id":310},"geometry":{"type":"Polygon","coordinates":[[[-86.09492505825817,39.90232825135053],[-86.09487351574352,39.90220877522499],[-86.09507384432915,39.90215791491905],[-86.0951253871931,39.9022773910446],[-86.09492505825817,39.90232825135053]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09479383579504,39.90220063475565],[-86.09472470233003,39.902086532240546]],"neighbors":[310,314,313],"id":312},"geometry":{"type":"Polygon","coordinates":[[[-86.09485762047406,39.902177891082836],[-86.09478848690281,39.90206378856773],[-86.09497984036709,39.901995557339596],[-86.09504897425697,39.902109659854695],[-86.09485762047406,39.902177891082836]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09470802963433,39.9020627960103],[-86.0946245349464,39.90195454493284]],"neighbors":[312,316,315],"id":314},"geometry":{"type":"Polygon","coordinates":[[[-86.09476856440268,39.90203531806099],[-86.09468506961912,39.901927066983525],[-86.09486667334596,39.90184463294674],[-86.09495016841643,39.90195288402421],[-86.09476856440268,39.90203531806099]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09460478146373,39.901932236842896],[-86.0945051787709,39.9018321856468]],"neighbors":[314,318,317],"id":316},"geometry":{"type":"Polygon","coordinates":[[[-86.09466068181295,39.901899486355944],[-86.09456107903851,39.90179943515985],[-86.0947287795207,39.90170118353795],[-86.09482838254,39.90180123473405],[-86.09466068181295,39.901899486355944]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09448118682376,39.90181246098869],[-86.09436716591495,39.90172209673185]],"neighbors":[316,320,319],"id":318},"geometry":{"type":"Polygon","coordinates":[[[-86.09453172564027,39.901774931828186],[-86.09441770466482,39.901684567571344],[-86.09456932058228,39.90157197995816],[-86.09468334175769,39.901662344215],[-86.09453172564027,39.901774931828186]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09434151726407,39.90170363747331],[-86.09421519346115,39.90162353306929]],"neighbors":[318,322,321],"id":320},"geometry":{"type":"Polygon","coordinates":[[[-86.094386330293,39.901662047325054],[-86.09426000643771,39.90158194292103],[-86.09439444504096,39.901457172372744],[-86.09452076905342,39.90153727677677],[-86.094386330293,39.901662047325054]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.0941869359769,39.90160747465757],[-86.09404971131617,39.901538497534844]],"neighbors":[320,324,323],"id":322},"geometry":{"type":"Polygon","coordinates":[[[-86.09422548509465,39.901562341035714],[-86.09408826039514,39.901493363912984],[-86.0942039073273,39.90135796297085],[-86.09434113214323,39.90142694009357],[-86.09422548509465,39.901562341035714]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09401949496035,39.90152469290995],[-86.09387848546073,39.90146027122348]],"neighbors":[322,326,325],"id":324},"geometry":{"type":"Polygon","coordinates":[[[-86.09405548441217,39.90147833207487],[-86.0939144748787,39.9014139103884],[-86.09402244284043,39.90127482781639],[-86.09416345247539,39.90133924950286],[-86.09405548441217,39.90147833207487]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09384826917386,39.90144646655415],[-86.0937072599962,39.9013820446603]],"neighbors":[324,328,327],"id":326},"geometry":{"type":"Polygon","coordinates":[[[-86.09388425870044,39.90140010577199],[-86.09374324948894,39.901335683878145],[-86.09385121767497,39.901196601464925],[-86.09399222698796,39.90126102335878],[-86.09388425870044,39.90140010577199]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09367704377836,39.901368239946535],[-86.09353603492265,39.90130381784531]],"neighbors":[326,330,329],"id":328},"geometry":{"type":"Polygon","coordinates":[[[-86.0937130333797,39.90132187921731],[-86.09357202449016,39.90125745711608],[-86.09367999290048,39.901118374861646],[-86.09382100189151,39.90118279696287],[-86.0937130333797,39.90132187921731]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09350581877376,39.90129001308712],[-86.09336481024002,39.90122559077853]],"neighbors":[328,332,331],"id":330},"geometry":{"type":"Polygon","coordinates":[[[-86.09354180844987,39.90124365241083],[-86.09340079988229,39.90117923010222],[-86.0935087685169,39.90104014800657],[-86.09364977718596,39.90110457031517],[-86.09354180844987,39.90124365241083]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09333459416015,39.901211785975896],[-86.09319497544533,39.90114569171266]],"neighbors":[330,null,333],"id":332},"geometry":{"type":"Polygon","coordinates":[[[-86.09337153099516,39.90116586583219],[-86.09323191224469,39.901099771568944],[-86.09334272234578,39.90096201106749],[-86.09348234120313,39.90102810533073],[-86.09337153099516,39.90116586583219]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.094925,39.902952],[-86.09492549962103,39.90282609573245]],"neighbors":[null,305,null],"id":303},"geometry":{"type":"Polygon","coordinates":[[[-86.0948546614344,39.902951835717595],[-86.09485516118467,39.902825931450046],[-86.09464414587767,39.90282543834788],[-86.09464364573962,39.902951342615424],[-86.0948546614344,39.902951835717595]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09492560668244,39.90279911624656],[-86.09492516311083,39.902673219549186]],"neighbors":[303,307,304],"id":305},"geometry":{"type":"Polygon","coordinates":[[[-86.09485526820448,39.902799262068264],[-86.09485482476212,39.90267336537089],[-86.09464380971417,39.902673802581],[-86.09464425276882,39.902799699278376],[-86.09485526820448,39.902799262068264]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09492285714614,39.90264630362355],[-86.0949064886783,39.902521075650554]],"neighbors":[305,309,306],"id":307},"geometry":{"type":"Polygon","coordinates":[[[-86.09485286952695,39.90265168720334],[-86.09483650118702,39.90252645923035],[-86.09462653864719,39.9025426097173],[-86.09464290660337,39.902667837690295],[-86.09485286952695,39.90265168720334]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09490132388298,39.90249439212096],[-86.09486706531483,39.90237131917032]],"neighbors":[307,311,308],"id":309},"geometry":{"type":"Polygon","coordinates":[[[-86.09483253630937,39.902505660531034],[-86.0947982778648,39.90238258758039],[-86.09459191537889,39.90241639256677],[-86.0946261734528,39.90253946551741],[-86.09483253630937,39.902505660531034]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09485828188045,39.90234520470925],[-86.09480673948221,39.9022257285837]],"neighbors":[309,313,310],"id":311},"geometry":{"type":"Polygon","coordinates":[[[-86.09479150546966,39.90236215802967],[-86.09473996318789,39.90224268190413],[-86.0945396341066,39.90229354163558],[-86.09459117603907,39.90241301776113],[-86.09479150546966,39.90236215802967]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09479383579504,39.90220063475565],[-86.09472470233003,39.902086532240546]],"neighbors":[311,315,312],"id":313},"geometry":{"type":"Polygon","coordinates":[[[-86.09473005107371,39.90222337839352],[-86.0946609177149,39.90210927587843],[-86.09446956361546,39.90217750658239],[-86.0945386966556,39.90229160909749],[-86.09473005107371,39.90222337839352]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09470802963433,39.9020627960103],[-86.0946245349464,39.90195454493284]],"neighbors":[313,317,314],"id":315},"geometry":{"type":"Polygon","coordinates":[[[-86.09464749481744,39.90209027392814],[-86.09456400022512,39.901982022850675],[-86.09438239577003,39.902064456415346],[-86.09446589007541,39.90217270749281],[-86.09464749481744,39.90209027392814]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09460478146373,39.901932236842896],[-86.0945051787709,39.9018321856468]],"neighbors":[315,319,316],"id":317},"geometry":{"type":"Polygon","coordinates":[[[-86.09454888106104,39.90196498730302],[-86.09444927844986,39.90186493610692],[-86.09428157716613,39.90196318732622],[-86.09438117953245,39.90206323852232],[-86.09454888106104,39.90196498730302]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09448118682376,39.90181246098869],[-86.09436716591495,39.90172209673185]],"neighbors":[317,321,318],"id":319},"geometry":{"type":"Polygon","coordinates":[[[-86.09443064795187,39.90184999012726],[-86.09431662710972,39.90175962587043],[-86.09416501036186,39.90187221315453],[-86.09427903100405,39.901962577411375],[-86.09443064795187,39.90184999012726]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09434151726407,39.90170363747331],[-86.09421519346115,39.90162353306929]],"neighbors":[319,323,320],"id":321},"geometry":{"type":"Polygon","coordinates":[[[-86.09429670418072,39.90174522760433],[-86.0941703804302,39.90166512320031],[-86.09403594101096,39.90178989348986],[-86.09416226460431,39.901869997893876],[-86.09429670418072,39.90174522760433]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.0941869359769,39.90160747465757],[-86.09404971131617,39.901538497534844]],"neighbors":[321,325,322],"id":323},"geometry":{"type":"Polygon","coordinates":[[[-86.09414838680836,39.901652608266666],[-86.09401116218643,39.901583631143936],[-86.09389551449253,39.90171903189463],[-86.09403273899802,39.90178800901736],[-86.09414838680836,39.901652608266666]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09401949496035,39.90152469290995],[-86.09387848546073,39.90146027122348]],"neighbors":[323,327,324],"id":325},"geometry":{"type":"Polygon","coordinates":[[[-86.09398350545985,39.90157105373392],[-86.09384249599404,39.90150663204745],[-86.09373452730182,39.90164571445259],[-86.0938755366661,39.90171013613905],[-86.09398350545985,39.90157105373392]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09384826917386,39.90144646655415],[-86.0937072599962,39.9013820446603]],"neighbors":[325,329,326],"id":327},"geometry":{"type":"Polygon","coordinates":[[[-86.09381227959858,39.90149282732518],[-86.09367127045476,39.901428405431346],[-86.09356330153824,39.901567487677696],[-86.09370431058053,39.90163190957153],[-86.09381227959858,39.90149282732518]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09367704377836,39.901368239946535],[-86.09353603492265,39.90130381784531]],"neighbors":[327,331,328],"id":329},"geometry":{"type":"Polygon","coordinates":[[[-86.0936410541283,39.901414600664644],[-86.09350004530646,39.90135017856342],[-86.09339207616564,39.90148926065098],[-86.09353308488598,39.90155368275221],[-86.0936410541283,39.901414600664644]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09350581877376,39.90129001308712],[-86.09336481024002,39.90122559077853]],"neighbors":[329,333,330],"id":331},"geometry":{"type":"Polygon","coordinates":[[[-86.09346982904896,39.9013363737523],[-86.09332882054906,39.90127195144372],[-86.09322085118396,39.90141103337249],[-86.09336185958236,39.90147545568109],[-86.09346982904896,39.9013363737523]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09333459416015,39.901211785975896],[-86.09319497544533,39.90114569171266]],"neighbors":[331,334,332],"id":333},"geometry":{"type":"Polygon","coordinates":[[[-86.09329765727564,39.901257706107884],[-86.09315803859644,39.90119161184465],[-86.09304722775279,39.901329372170316],[-86.09318684632508,39.90139546643356],[-86.09329765727564,39.901257706107884]]]}},{"type":"Feature","properties":{"street":"none","street_id":16,"OSM_street_id":"way/17486873","street_anchors":[[-86.09316752931716,39.90112896315319],[-86.0930646566572,39.901031987718504]],"neighbors":[333,null,null],"id":334},"geometry":{"type":"Polygon","coordinates":[[[-86.09311297462438,39.901163022335055],[-86.09301010204163,39.901066046900375],[-86.09284643786954,39.90116822429259],[-86.09294931022065,39.90126519972727],[-86.09311297462438,39.901163022335055]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09847610523487,39.89934852521608],[-86.09847761526991,39.89947442473738]],"neighbors":[null,338,335],"id":336},"geometry":{"type":"Polygon","coordinates":[[[-86.0985464374498,39.89934802871406],[-86.09854794761407,39.89947392823536],[-86.09875894464041,39.89947243847437],[-86.0987574340885,39.899346538953075],[-86.0985464374498,39.89934802871406]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09847793884957,39.89950140320623],[-86.09847944889137,39.89962730272751]],"neighbors":[336,340,337],"id":338},"geometry":{"type":"Polygon","coordinates":[[[-86.0985482712214,39.89950090670311],[-86.0985497813924,39.89962680622439],[-86.09876077888943,39.89962531646008],[-86.09875926833078,39.89949941693881],[-86.0985482712214,39.89950090670311]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09847977247246,39.899654281196355],[-86.09848128252098,39.89978018071762]],"neighbors":[338,342,339],"id":340},"geometry":{"type":"Polygon","coordinates":[[[-86.0985501050012,39.89965378469213],[-86.09855161517893,39.89977968421339],[-86.09876261314665,39.89977819444576],[-86.09876110258124,39.89965229492449],[-86.0985501050012,39.89965378469213]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09848160610356,39.899807159186444],[-86.09848682164483,39.89993298910506]],"neighbors":[340,343,341],"id":342},"geometry":{"type":"Polygon","coordinates":[[[-86.09855190623279,39.89980544421711],[-86.09855712190317,39.899931274135724],[-86.09876802265703,39.89992612897302],[-86.09876280659938,39.8998002990544],[-86.09855190623279,39.89980544421711]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09848821948096,39.899959947395494],[-86.0984947427307,39.90008575275064]],"neighbors":[342,344,null],"id":343},"geometry":{"type":"Polygon","coordinates":[[[-86.0985584997166,39.89995780262988],[-86.09856502309539,39.90008360798502],[-86.09877586416303,39.900077173433615],[-86.09876934039717,39.89995136807848],[-86.0985584997166,39.89995780262988]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09849632057785,39.900112702015704],[-86.09850955499556,39.900238191645926]],"neighbors":[343,345,null],"id":344},"geometry":{"type":"Polygon","coordinates":[[[-86.0985664274688,39.90010835055218],[-86.09857966201488,39.9002338401824],[-86.0987899830194,39.90022078553856],[-86.09877674808818,39.90009529590834],[-86.0985664274688,39.90010835055218]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09851203557568,39.90026510284677],[-86.09851336124956,39.9003909900487]],"neighbors":[344,346,null],"id":345},"geometry":{"type":"Polygon","coordinates":[[[-86.09858236941363,39.90026466691935],[-86.09858369521673,39.90039055412128],[-86.0987946971129,39.90038924608412],[-86.09879337092214,39.90026335888218],[-86.09858236941363,39.90026466691935]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09851291057879,39.9004179657498],[-86.09849576388746,39.90054312870576]],"neighbors":[345,348,null],"id":346},"geometry":{"type":"Polygon","coordinates":[[[-86.09858286161872,39.900423605614414],[-86.09856571505514,39.90054876857038],[-86.09877556862739,39.90056568791204],[-86.09879271480762,39.90044052495608],[-86.09858286161872,39.900423605614414]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.0984912252597,39.90056988269863],[-86.09847544611175,39.900695196135445]],"neighbors":[346,350,347],"id":348},"geometry":{"type":"Polygon","coordinates":[[[-86.09856123582617,39.90057507090708],[-86.09854545680624,39.900700384343885],[-86.09875548895333,39.90071594871664],[-86.09877126758914,39.900590635279826],[-86.09856123582617,39.90057507090708]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09847220073249,39.900722060623494],[-86.0984656959988,39.90084784012555]],"neighbors":[348,352,349],"id":350},"geometry":{"type":"Polygon","coordinates":[[[-86.09854248204745,39.900724199683616],[-86.09853597744275,39.90084997918567],[-86.09874682180097,39.900856396111486],[-86.09875332601862,39.900730616609444],[-86.09854248204745,39.900724199683616]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846537860457,39.90087481863768],[-86.0984662579481,39.90100071720938]],"neighbors":[350,354,351],"id":352},"geometry":{"type":"Polygon","coordinates":[[[-86.098535714354,39.90087452949537],[-86.09853659382676,39.90100042806707],[-86.09874760145915,39.90099956038519],[-86.09874672159872,39.9008736618135],[-86.098535714354,39.90087452949537]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846662007169,39.90102769539],[-86.0984670650645,39.90115359872754]],"neighbors":[352,356,353],"id":354},"geometry":{"type":"Polygon","coordinates":[[[-86.09853695672932,39.901027549063016],[-86.09853740185135,39.90115345240055],[-86.09874841221013,39.901153013164624],[-86.09874796670037,39.90102710982709],[-86.09853695672932,39.901027549063016]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846708305055,39.90118057833492],[-86.09846716698573,39.90130648316938]],"neighbors":[354,358,355],"id":356},"geometry":{"type":"Polygon","coordinates":[[[-86.09853742011458,39.90118055071757],[-86.098537504179,39.90130645555203],[-86.09874851575847,39.90130637244501],[-86.09874843130632,39.90118046761055],[-86.09853742011458,39.90118055071757]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.0984671849719,39.90133346277676],[-86.09846726890743,39.90145936761121]],"neighbors":[356,360,357],"id":358},"geometry":{"type":"Polygon","coordinates":[[[-86.09853752219287,39.901333435159344],[-86.09853760625765,39.90145933999381],[-86.09874861830791,39.901459256886625],[-86.09874853385541,39.90133335205217],[-86.09853752219287,39.901333435159344]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846728689367,39.9014863472186],[-86.09846737082958,39.901612252053056]],"neighbors":[358,362,359],"id":360},"geometry":{"type":"Polygon","coordinates":[[[-86.09853762427157,39.901486319601126],[-86.09853770833674,39.901612224435574],[-86.09874872085781,39.901612141328194],[-86.09874863640492,39.901486236493746],[-86.09853762427157,39.901486319601126]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846738881589,39.90163923166043],[-86.09846747275219,39.90176513649489]],"neighbors":[360,364,361],"id":362},"geometry":{"type":"Polygon","coordinates":[[[-86.09853772635073,39.9016392040429],[-86.09853781041627,39.90176510887735],[-86.09874882340817,39.90176502576978],[-86.09874873895491,39.901639120935336],[-86.09853772635073,39.9016392040429]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.0984674907386,39.90179211610228],[-86.09846757467527,39.90191802093673]],"neighbors":[362,366,363],"id":364},"geometry":{"type":"Polygon","coordinates":[[[-86.09853782843037,39.901792088484676],[-86.0985379124963,39.90191799331914],[-86.09874892595901,39.90191791021137],[-86.09874884150535,39.90179200537691],[-86.09853782843037,39.901792088484676]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846759266175,39.901945000544124],[-86.09846767659879,39.90207090537858]],"neighbors":[364,368,365],"id":366},"geometry":{"type":"Polygon","coordinates":[[[-86.09853793051047,39.901944972926465],[-86.09853801457676,39.90207087776092],[-86.0987490285103,39.90207079465297],[-86.09874894405625,39.901944889818516],[-86.09853793051047,39.901944972926465]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846769458534,39.90209788498595],[-86.09846777852277,39.90222378982041]],"neighbors":[366,370,367],"id":368},"geometry":{"type":"Polygon","coordinates":[[[-86.09853803259098,39.90209785736822],[-86.09853811665769,39.90222376220269],[-86.09874913106205,39.902223679094526],[-86.09874904660761,39.90209777426007],[-86.09853803259098,39.90209785736822]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846779650941,39.9022507694278],[-86.09846788044719,39.90237667426225]],"neighbors":[368,372,369],"id":370},"geometry":{"type":"Polygon","coordinates":[[[-86.098538134672,39.90225074181003],[-86.09853821873904,39.90237664664448],[-86.09874923361423,39.90237656353618],[-86.09874914915945,39.90225065870174],[-86.098538134672,39.90225074181003]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846789843391,39.902403653869634],[-86.0984679823721,39.90252955870409]],"neighbors":[370,374,371],"id":372},"geometry":{"type":"Polygon","coordinates":[[[-86.09853823675346,39.90240362625179],[-86.09853832082088,39.902529531086245],[-86.0987493361669,39.902529447977756],[-86.09874925171174,39.902403543143286],[-86.09853823675346,39.90240362625179]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846799804713,39.902556538309454],[-86.09846754128944,39.9026824426728]],"neighbors":[372,376,373],"id":374},"geometry":{"type":"Polygon","coordinates":[[[-86.0985383362606,39.90255668845744],[-86.09853787963216,39.90268259282078],[-86.09874889466217,39.90268304300975],[-86.09874935090286,39.902557138646415],[-86.0985383362606,39.90255668845744]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846744341257,39.90270942217923],[-86.09846698665287,39.90283532654257]],"neighbors":[374,378,375],"id":376},"geometry":{"type":"Polygon","coordinates":[[[-86.098537781783,39.902709572327545],[-86.09853732515253,39.902835476690875],[-86.09874834065337,39.90283592688084],[-86.09874879689609,39.9027100225175],[-86.098537781783,39.902709572327545]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846688877556,39.902862306049],[-86.0984664320138,39.902988210412346]],"neighbors":[376,380,377],"id":378},"geometry":{"type":"Polygon","coordinates":[[[-86.09853722730291,39.90286245619766],[-86.0985367706704,39.90298836056099],[-86.0987477866421,39.90298881075197],[-86.09874824288687,39.902862906388656],[-86.09853722730291,39.90286245619766]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846633413606,39.90301518991877],[-86.09846587737229,39.903141094282105]],"neighbors":[378,382,379],"id":380},"geometry":{"type":"Polygon","coordinates":[[[-86.09853667282036,39.90301534006775],[-86.09853621618585,39.903141244431076],[-86.09874723262837,39.903141694623045],[-86.09874768887514,39.9030157902597],[-86.09853667282036,39.90301534006775]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.0984657794941,39.903168073788535],[-86.09846532272827,39.90329397815187]],"neighbors":[380,384,381],"id":382},"geometry":{"type":"Polygon","coordinates":[[[-86.09853611833536,39.903168223937854],[-86.09853566169879,39.903294128301184],[-86.09874667861214,39.903294578494176],[-86.09874713486097,39.90316867413083],[-86.09853611833536,39.903168223937854]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846522484968,39.903320957658295],[-86.0984647680818,39.903446862021624]],"neighbors":[382,386,383],"id":384},"geometry":{"type":"Polygon","coordinates":[[[-86.09853556384788,39.903321107807955],[-86.09853510720924,39.90344701217129],[-86.09874612459346,39.9034474623653],[-86.09874658084435,39.90332155800196],[-86.09853556384788,39.903321107807955]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846467020276,39.903473841528054],[-86.09846421343282,39.903599745891384]],"neighbors":[384,388,385],"id":386},"geometry":{"type":"Polygon","coordinates":[[[-86.0985350093579,39.90347399167805],[-86.09853455271723,39.90359989604138],[-86.09874557057229,39.903600346236395],[-86.09874602682521,39.903474441873065],[-86.0985350093579,39.90347399167805]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846411555336,39.90362672539781],[-86.09846365878141,39.90375262976114]],"neighbors":[386,390,387],"id":388},"geometry":{"type":"Polygon","coordinates":[[[-86.09853445486546,39.90362687554813],[-86.09853399822276,39.90375277991146],[-86.09874501654868,39.90375323010745],[-86.0987454728036,39.90362732574412],[-86.09853445486546,39.90362687554813]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846356090148,39.90377960926756],[-86.09846310412752,39.903905513630896]],"neighbors":[388,392,389],"id":390},"geometry":{"type":"Polygon","coordinates":[[[-86.09853390037051,39.90377975941821],[-86.09853344372581,39.90390566378154],[-86.09874446252257,39.90390611397852],[-86.09874491877953,39.903780209615185],[-86.09853390037051,39.90377975941821]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846300624716,39.90393249313732],[-86.09846254947112,39.90405839750065]],"neighbors":[390,394,391],"id":392},"geometry":{"type":"Polygon","coordinates":[[[-86.09853334587314,39.903932643288314],[-86.09853288922638,39.904058547651644],[-86.09874390849401,39.90405899784964],[-86.09874436475303,39.903933093486316],[-86.09853334587314,39.903932643288314]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846245159034,39.90408537700707],[-86.09846199481228,39.90421128137039]],"neighbors":[392,396,393],"id":394},"geometry":{"type":"Polygon","coordinates":[[[-86.09853279137329,39.904085527158394],[-86.0985323347245,39.90421143152171],[-86.09874335446298,39.90421188172069],[-86.098743810724,39.904085977357376],[-86.09853279137329,39.904085527158394]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846189693104,39.90423826087682],[-86.09846144015094,39.90436416524013]],"neighbors":[394,398,395],"id":396},"geometry":{"type":"Polygon","coordinates":[[[-86.09853223687094,39.90423841102848],[-86.0985317802201,39.904364315391796],[-86.09874280042948,39.904364765591794],[-86.09874325669253,39.90423886122848],[-86.09853223687094,39.90423841102848]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846134226927,39.904391144746555],[-86.09846088548714,39.904517049109884]],"neighbors":[396,400,397],"id":398},"geometry":{"type":"Polygon","coordinates":[[[-86.09853168236616,39.90439129489856],[-86.09853122571327,39.90451719926189],[-86.0987422463935,39.9045176494629],[-86.09874270265858,39.90439174509957],[-86.09853168236616,39.90439129489856]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846078760502,39.90454402861631],[-86.09846033082086,39.90466993297962]],"neighbors":[398,402,399],"id":400},"geometry":{"type":"Polygon","coordinates":[[[-86.09853112785885,39.90454417876864],[-86.09853067120395,39.904670083131954],[-86.09874169235505,39.90467053333395],[-86.09874214862218,39.904544628970626],[-86.09853112785885,39.90454417876864]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09846023293831,39.90469691248604],[-86.0984597761521,39.90482281684936]],"neighbors":[400,404,401],"id":402},"geometry":{"type":"Polygon","coordinates":[[[-86.0985305733491,39.90469706263871],[-86.09853011669215,39.90482296700203],[-86.09874113831413,39.904823417205044],[-86.09874159458329,39.90469751284173],[-86.0985305733491,39.90469706263871]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09845967826911,39.90484979635578],[-86.09845922148087,39.904975700719085]],"neighbors":[402,406,403],"id":404},"geometry":{"type":"Polygon","coordinates":[[[-86.09853001883687,39.90484994650878],[-86.09852956217787,39.90497585087209],[-86.09874058427074,39.904976301076104],[-86.09874104054194,39.9048503967128],[-86.09853001883687,39.90484994650878]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09845912359745,39.90500268022551],[-86.09845866680715,39.905128584588816]],"neighbors":[404,407,405],"id":406},"geometry":{"type":"Polygon","coordinates":[[[-86.09852946432216,39.90500283037885],[-86.09852900766113,39.905128734742156],[-86.09874003022489,39.905129184947185],[-86.09874048649812,39.90500328058388],[-86.09852946432216,39.90500283037885]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.0984585689233,39.90515556409524],[-86.09845811213097,39.90528146845855]],"neighbors":[406,408,null],"id":407},"geometry":{"type":"Polygon","coordinates":[[[-86.09852890980498,39.90515571424892],[-86.0985284531419,39.90528161861222],[-86.09873947617656,39.90528206881824],[-86.09873993245182,39.90515616445496],[-86.09852890980498,39.90515571424892]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.09845801424669,39.90530844796498],[-86.09845755745232,39.90543435232827]],"neighbors":[407,409,null],"id":408},"geometry":{"type":"Polygon","coordinates":[[[-86.09852835528531,39.90530859811899],[-86.0985278986202,39.90543450248228],[-86.09873892212576,39.905434952689326],[-86.09873937840307,39.905309048326025],[-86.09852835528531,39.90530859811899]]]}},{"type":"Feature","properties":{"street":"none","street_id":17,"OSM_street_id":"way/17493499","street_anchors":[[-86.0984574595676,39.9054613318347],[-86.09845700277118,39.905587236197995]],"neighbors":[408,null,null],"id":409},"geometry":{"type":"Polygon","coordinates":[[[-86.0985278007632,39.90546148198905],[-86.09852734409603,39.905587386352344],[-86.09873836807247,39.90558783656039],[-86.09873882435183,39.905461932197106],[-86.0985278007632,39.90546148198905]]]}},{"type":"Feature","properties":{"street":"none","street_id":18,"OSM_street_id":"way/17501810","street_anchors":[[-86.0980887247849,39.90337287776503],[-86.09792460530643,39.90337183686195]],"neighbors":[null,null,411],"id":410},"geometry":{"type":"Polygon","coordinates":[[[-86.09808930624163,39.90331892038688],[-86.09792518676315,39.903317879483794],[-86.09792693112787,39.9031560073493],[-86.09809105060639,39.903157048252375],[-86.09808930624163,39.90331892038688]]]}},{"type":"Feature","properties":{"street":"none","street_id":18,"OSM_street_id":"way/17501810","street_anchors":[[-86.0980887247849,39.90337287776503],[-86.09792460530643,39.90337183686195]],"neighbors":[null,null,410],"id":411},"geometry":{"type":"Polygon","coordinates":[[[-86.09808814332723,39.903426835143186],[-86.09792402384876,39.903425794240114],[-86.09792227947032,39.903587666374555],[-86.09808639894878,39.903588707277635],[-86.09808814332723,39.903426835143186]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.093837,39.905124],[-86.09383754113989,39.9049980958334]],"neighbors":[null,414,413],"id":412},"geometry":{"type":"Polygon","coordinates":[[[-86.09390734073936,39.90512417788451],[-86.09390788175001,39.904998273717894],[-86.09411890358258,39.904998807116385],[-86.09411836295973,39.90512471128299],[-86.09390734073936,39.90512417788451]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09383765709818,39.904971116369126],[-86.09383819823567,39.90484521220253]],"neighbors":[412,416,415],"id":414},"geometry":{"type":"Polygon","coordinates":[[[-86.09390799768062,39.90497129425323],[-86.09390853868885,39.90484539008663],[-86.09411956005053,39.90484592348396],[-86.09411901943008,39.90497182765054],[-86.09390799768062,39.90497129425323]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09383831419345,39.90481823273826],[-86.09383885532854,39.90469232857165]],"neighbors":[414,421,417],"id":416},"geometry":{"type":"Polygon","coordinates":[[[-86.09390865461891,39.904818410621964],[-86.09390919562476,39.90469250645536],[-86.09412021651556,39.90469303985149],[-86.09411967589752,39.9048189440181],[-86.09390865461891,39.904818410621964]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384079573161,39.90420669787234],[-86.09384125256976,39.90408079350913]],"neighbors":[416,423,422],"id":421},"geometry":{"type":"Polygon","coordinates":[[[-86.09391113563905,39.9042068480437],[-86.09391159234794,39.9040809436805],[-86.09412261168433,39.90408139393962],[-86.09412215536321,39.904207298302815],[-86.09391113563905,39.9042068480437]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384135046344,39.90405381400273],[-86.09384180729951,39.90392790963954]],"neighbors":[421,425,424],"id":423},"geometry":{"type":"Polygon","coordinates":[[[-86.09391169021393,39.90405396417376],[-86.09391214692074,39.90392805981057],[-86.09412316578626,39.903928510068646],[-86.09412270946721,39.90405441443183],[-86.09391169021393,39.90405396417376]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384190519275,39.90390093013315],[-86.09384236202682,39.90377502576994]],"neighbors":[423,null,426],"id":425},"geometry":{"type":"Polygon","coordinates":[[[-86.09391224478628,39.90390108030385],[-86.0939127014911,39.90377517594064],[-86.09412371988577,39.90377562619776],[-86.09412326356872,39.90390153056097],[-86.09391224478628,39.90390108030385]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.093837,39.905124],[-86.09383754113989,39.9049980958334]],"neighbors":[null,415,412],"id":413},"geometry":{"type":"Polygon","coordinates":[[[-86.09376665926096,39.905123822073016],[-86.09376720053012,39.904997917906414],[-86.09355617870303,39.904997383870466],[-86.09355563704608,39.90512328803707],[-86.09376665926096,39.905123822073016]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09383765709818,39.904971116369126],[-86.09383819823567,39.90484521220253]],"neighbors":[413,417,414],"id":415},"geometry":{"type":"Polygon","coordinates":[[[-86.09376731651612,39.90497093844253],[-86.09376785778288,39.904845034275944],[-86.09355683642667,39.90484450024117],[-86.09355629477213,39.90497040440776],[-86.09376731651612,39.90497093844253]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09383831419345,39.90481823273826],[-86.09383885532854,39.90469232857165]],"neighbors":[415,418,416],"id":417},"geometry":{"type":"Polygon","coordinates":[[[-86.09376797376835,39.90481805481206],[-86.09376851503269,39.904692150645445],[-86.09355749414736,39.90469161661187],[-86.0935569524952,39.904817520778465],[-86.09376797376835,39.90481805481206]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09383897128578,39.90466534910738],[-86.09383951241844,39.90453944494078]],"neighbors":[417,419,null],"id":418},"geometry":{"type":"Polygon","coordinates":[[[-86.09376863101764,39.904665171181584],[-86.09376917227955,39.90453926701499],[-86.0935581518651,39.9045387329826],[-86.09355761021538,39.90466463714921],[-86.09376863101764,39.904665171181584]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09383962837518,39.9045124654765],[-86.09384014310277,39.904386561248316]],"neighbors":[418,420,null],"id":419},"geometry":{"type":"Polygon","coordinates":[[[-86.09376928822759,39.90451229623134],[-86.09376980308443,39.904386392003154],[-86.09355878303151,39.90438588401268],[-86.09355826778689,39.904511788240875],[-86.09376928822759,39.90451229623134]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384024099732,39.90435958174192],[-86.09384069783749,39.90423367737873]],"neighbors":[419,422,null],"id":420},"geometry":{"type":"Polygon","coordinates":[[[-86.09376990093322,39.90435943152773],[-86.09377035790266,39.904233527164536],[-86.09355933810002,39.90423307626698],[-86.09355888074282,39.90435898063018],[-86.09376990093322,39.90435943152773]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384079573161,39.90420669787234],[-86.09384125256976,39.90408079350913]],"neighbors":[420,424,421],"id":422},"geometry":{"type":"Polygon","coordinates":[[[-86.09377045582448,39.90420654765847],[-86.09377091279188,39.90408064329527],[-86.09355989346012,39.9040801923987],[-86.09355943610495,39.904206096761904],[-86.09377045582448,39.90420654765847]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384135046344,39.90405381400273],[-86.09384180729951,39.90392790963954]],"neighbors":[422,426,423],"id":424},"geometry":{"type":"Polygon","coordinates":[[[-86.09377101071327,39.90405366378922],[-86.0937714676786,39.903927759426026],[-86.0935604488177,39.90392730853051],[-86.09355999146459,39.90405321289369],[-86.09377101071327,39.90405366378922]]]}},{"type":"Feature","properties":{"street":"none","street_id":19,"OSM_street_id":"way/17509867","street_anchors":[[-86.09384190519275,39.90390093013315],[-86.09384236202682,39.90377502576994]],"neighbors":[424,null,425],"id":426},"geometry":{"type":"Polygon","coordinates":[[[-86.09377156559955,39.90390077991996],[-86.09377202256286,39.903774875556756],[-86.09356100417281,39.903774424662195],[-86.09356054682173,39.9039003290254],[-86.09377156559955,39.90390077991996]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.093858,39.9029816],[-86.0936968629783,39.90300217365267]],"neighbors":[null,429,428],"id":427},"geometry":{"type":"Polygon","coordinates":[[[-86.09384645189976,39.902928372965604],[-86.0936853148746,39.90294894661828],[-86.09365067067115,39.90278926550818],[-86.09381180770673,39.90276869185551],[-86.09384645189976,39.902928372965604]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09366401887313,39.9030117772371],[-86.09352629475508,39.903079089462246]],"neighbors":[427,430,null],"id":429},"geometry":{"type":"Polygon","coordinates":[[[-86.09362622408615,39.90296626932555],[-86.09348849993097,39.9030335815507],[-86.09337511575988,39.90289705774244],[-86.09351284002646,39.902829745517295],[-86.09362622408615,39.90296626932555]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09350106253615,39.90309786330169],[-86.09340891168269,39.90320133646339]],"neighbors":[429,432,431],"id":430},"geometry":{"type":"Polygon","coordinates":[[[-86.09344298357071,39.903067424428635],[-86.09335083262955,39.90317089759035],[-86.09317659577978,39.903079580797375],[-86.09326874698407,39.90297610763566],[-86.09344298357071,39.903067424428635]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.0933953577704,39.90322622654843],[-86.09336412180943,39.90334921580652]],"neighbors":[430,433,null],"id":432},"geometry":{"type":"Polygon","coordinates":[[[-86.09332631675505,39.90321590768584],[-86.09329508067012,39.90333889694392],[-86.09308795737702,39.90330794011046],[-86.09311919383372,39.90318495085238],[-86.09332631675505,39.90321590768584]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.0933644925398,39.9033761731801],[-86.09339871671051,39.90349864974255]],"neighbors":[432,435,434],"id":433},"geometry":{"type":"Polygon","coordinates":[[[-86.09329571563148,39.90338748300511],[-86.09332993967924,39.90350995956755],[-86.09312360844918,39.90354388879877],[-86.09308938477027,39.90342141223633],[-86.09329571563148,39.90338748300511]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09341291130922,39.90352330983087],[-86.09350721852965,39.90362555863325]],"neighbors":[433,438,null],"id":435},"geometry":{"type":"Polygon","coordinates":[[[-86.09335549113214,39.90355447597743],[-86.09344979826687,39.903656724779815],[-86.09327753716511,39.90375022304958],[-86.09318323028745,39.90364797424719],[-86.09335549113214,39.90355447597743]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.0940910491046,39.903690979063505],[-86.09421968623032,39.90361379516041]],"neighbors":[435,439,null],"id":438},"geometry":{"type":"Polygon","coordinates":[[[-86.09413438452388,39.90373348152447],[-86.0942630216008,39.903656297621374],[-86.0943930280348,39.903783804907455],[-86.09426439110436,39.90386098881055],[-86.09413438452388,39.90373348152447]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09424236970756,39.903593197808476],[-86.09432105220081,39.903483395599686]],"neighbors":[438,441,440],"id":439},"geometry":{"type":"Polygon","coordinates":[[[-86.09430400990068,39.9036191912376],[-86.09438269229517,39.90350938902881],[-86.09456761285878,39.90358736912039],[-86.09448893076066,39.90369717132916],[-86.09430400990068,39.9036191912376]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09434333757746,39.90330607105144],[-86.09429377924721,39.90318668921323]],"neighbors":[441,444,443],"id":442},"geometry":{"type":"Polygon","coordinates":[[[-86.09441036037248,39.903289697677735],[-86.09436080192546,39.9031703158395],[-86.09456186976797,39.90312119548687],[-86.09461142856533,39.903240577325086],[-86.09441036037248,39.903289697677735]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09427667634024,39.90316312645048],[-86.09416982536928,39.90306834497692]],"neighbors":[442,445,null],"id":444},"geometry":{"type":"Polygon","coordinates":[[[-86.09432987946077,39.903127830006106],[-86.09422302841622,39.90303304853254],[-86.09438263722816,39.90292715905352],[-86.0944894884935,39.90302194052707],[-86.09432987946077,39.903127830006106]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09414194266105,39.90305191663862],[-86.0939950506329,39.90299714896892]],"neighbors":[444,null,null],"id":445},"geometry":{"type":"Polygon","coordinates":[[[-86.09417268974603,39.90300338573406],[-86.0940257976933,39.902948618064364],[-86.09411803861322,39.90280302530198],[-86.09426493073967,39.902857792971666],[-86.09417268974603,39.90300338573406]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.093858,39.9029816],[-86.0936968629783,39.90300217365267]],"neighbors":[null,431,427],"id":428},"geometry":{"type":"Polygon","coordinates":[[[-86.09386954811816,39.90303482703327],[-86.09370841109994,39.90305540068593],[-86.0937430555725,39.90321508177883],[-86.09390419258035,39.90319450812615],[-86.09386954811816,39.90303482703327]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09350106253615,39.90309786330169],[-86.09340891168269,39.90320133646339]],"neighbors":[428,434,430],"id":431},"geometry":{"type":"Polygon","coordinates":[[[-86.09355914155316,39.90312830214576],[-86.09346699078745,39.90323177530747],[-86.09364122841127,39.90332309166585],[-86.0937333789139,39.90321961850414],[-86.09355914155316,39.90312830214576]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09390178490678,39.90373515800835],[-86.09405961479976,39.903703038230084]],"neighbors":[436,440,null],"id":437},"geometry":{"type":"Polygon","coordinates":[[[-86.09388374857838,39.90368300285393],[-86.09404157847983,39.90365088307567],[-86.09398746968476,39.90349441759563],[-86.09382963975796,39.90352653737389],[-86.09388374857838,39.90368300285393]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09424236970756,39.903593197808476],[-86.09432105220081,39.903483395599686]],"neighbors":[437,443,439],"id":440},"geometry":{"type":"Polygon","coordinates":[[[-86.0941807295612,39.90356720434673],[-86.09425941215325,39.90345740213794],[-86.09407449229116,39.90337942155685],[-86.09399580940277,39.903489223765646],[-86.0941807295612,39.90356720434673]]]}},{"type":"Feature","properties":{"street":"none","street_id":20,"OSM_street_id":"way/17509887","street_anchors":[[-86.09434333757746,39.90330607105144],[-86.09429377924721,39.90318668921323]],"neighbors":[440,null,442],"id":443},"geometry":{"type":"Polygon","coordinates":[[[-86.0942763147504,39.903322444386575],[-86.09422675653694,39.903203062548364],[-86.09402568821393,39.90325218232225],[-86.09407524607705,39.90337156416048],[-86.0942763147504,39.903322444386575]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09384106273261,39.902676371664036],[-86.09380580167121,39.902553596872046]],"neighbors":[null,448,447],"id":446},"geometry":{"type":"Polygon","coordinates":[[[-86.09390975388192,39.9026647616594],[-86.09387449269742,39.902541986867405],[-86.0940805656364,39.902507156610326],[-86.09411582719014,39.90262993140232],[-86.09390975388192,39.9026647616594]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09379506488592,39.902527905275754],[-86.09373044951288,39.902412475883565]],"neighbors":[446,449,null],"id":448},"geometry":{"type":"Polygon","coordinates":[[[-86.09385969598357,39.90250661369192],[-86.09379508050164,39.90239118429974],[-86.09398897322691,39.902327309332975],[-86.09405358903548,39.90244273872516],[-86.09385969598357,39.90250661369192]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09371406928608,39.902388603932124],[-86.09362425618241,39.90228341788213]],"neighbors":[448,451,450],"id":449},"geometry":{"type":"Polygon","coordinates":[[[-86.09377290857384,39.902359037587374],[-86.09368309537984,39.90225385153739],[-86.0938596126675,39.90216515232474],[-86.0939494261325,39.90227033837473],[-86.09377290857384,39.902359037587374]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09359994563592,39.90226394563673],[-86.09348661157887,39.90217338783317]],"neighbors":[449,452,null],"id":451},"geometry":{"type":"Polygon","coordinates":[[[-86.09365068451595,39.90222657541524],[-86.09353735039184,39.90213601761168],[-86.09368956649867,39.902023906814534],[-86.09380290082396,39.9021144646181],[-86.09365068451595,39.90222657541524]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09346020827584,39.90215556559463],[-86.09332486904948,39.90208451038812]],"neighbors":[451,454,453],"id":452},"geometry":{"type":"Polygon","coordinates":[[[-86.09349993365275,39.90211103612735],[-86.0933645943852,39.90203998092084],[-86.09348377008257,39.90190639243768],[-86.09361910947372,39.901977447644185],[-86.09349993365275,39.90211103612735]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09329521900459,39.902070000792406],[-86.09314469008154,39.90202098053887]],"neighbors":[452,455,null],"id":454},"geometry":{"type":"Polygon","coordinates":[[[-86.09332270365978,39.902020331530686],[-86.09317217471707,39.901971311277144],[-86.09325462838457,39.90182230345302],[-86.09340515738626,39.90187132370656],[-86.09332270365978,39.902020331530686]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09311159012617,39.90201186318256],[-86.09295264205191,39.901982244296356]],"neighbors":[454,457,456],"id":455},"geometry":{"type":"Polygon","coordinates":[[[-86.09312819273269,39.90195942867721],[-86.09296924465126,39.90192980979101],[-86.09301905229687,39.901772506260734],[-86.09317800039985,39.901802125146936],[-86.09312819273269,39.90195942867721]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09291801085455,39.901977544332766],[-86.09275442394754,39.90196866809863]],"neighbors":[455,458,null],"id":457},"geometry":{"type":"Polygon","coordinates":[[[-86.0929229733898,39.90192371957494],[-86.09275938648216,39.9019148433408],[-86.0927742740392,39.901753369066036],[-86.0929378609488,39.90176224530017],[-86.0929229733898,39.90192371957494]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09271938791082,39.90196632479241],[-86.09255588643784,39.90195538922394]],"neighbors":[457,460,459],"id":458},"geometry":{"type":"Polygon","coordinates":[[[-86.0927254970958,39.90191256948382],[-86.09256199562182,39.90190163391535],[-86.09258032311631,39.90174036798764],[-86.09274382459319,39.90175130355611],[-86.0927254970958,39.90191256948382]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09252085041469,39.90195304585797],[-86.09235734900506,39.9019421100107]],"neighbors":[458,462,461],"id":460},"geometry":{"type":"Polygon","coordinates":[[[-86.09252695975424,39.90189929055979],[-86.09236345834363,39.901888354712526],[-86.09238178630181,39.90172708881607],[-86.09254528771532,39.90173802466333],[-86.09252695975424,39.90189929055979]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.0923223129955,39.90193976658499],[-86.09216122809363,39.90192118050953]],"neighbors":[460,null,463],"id":462},"geometry":{"type":"Polygon","coordinates":[[[-86.09233277428041,39.901886407499234],[-86.0921716893757,39.901867821423785],[-86.09220307312415,39.90170774416086],[-86.09236415803736,39.901726330236315],[-86.09233277428041,39.901886407499234]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09384106273261,39.902676371664036],[-86.09380580167121,39.902553596872046]],"neighbors":[null,450,446],"id":447},"geometry":{"type":"Polygon","coordinates":[[[-86.09377237156004,39.902687981628155],[-86.0937371106217,39.902565206836165],[-86.09353103733356,39.902600036485346],[-86.09356629790263,39.902722811277336],[-86.09377237156004,39.902687981628155]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09371406928608,39.902388603932124],[-86.09362425618241,39.90228341788213]],"neighbors":[447,453,449],"id":450},"geometry":{"type":"Polygon","coordinates":[[[-86.09365522994753,39.90241817024714],[-86.09356541693418,39.902312984197145],[-86.09338889888484,39.90240168296377],[-86.0934787116272,39.902506869013756],[-86.09365522994753,39.90241817024714]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09346020827584,39.90215556559463],[-86.09332486904948,39.90208451038812]],"neighbors":[450,456,452],"id":453},"geometry":{"type":"Polygon","coordinates":[[[-86.0934204828473,39.90220009504836],[-86.09328514366213,39.90212903984185],[-86.09316596719026,39.90226262812169],[-86.09330130625186,39.9023336833282],[-86.0934204828473,39.90220009504836]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09311159012617,39.90201186318256],[-86.09295264205191,39.901982244296356]],"neighbors":[453,459,455],"id":456},"geometry":{"type":"Polygon","coordinates":[[[-86.09309498749423,39.90206429768555],[-86.09293603942714,39.90203467879934],[-86.09288623140039,39.90219198229409],[-86.09304517944594,39.902221601180294],[-86.09309498749423,39.90206429768555]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09271938791082,39.90196632479241],[-86.09255588643784,39.90195538922394]],"neighbors":[456,461,458],"id":459},"geometry":{"type":"Polygon","coordinates":[[[-86.09271327871626,39.90202008010069],[-86.09254977724426,39.90200914453221],[-86.09253144960599,39.9021704104551],[-86.09269495107509,39.90218134602357],[-86.09271327871626,39.90202008010069]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09252085041469,39.90195304585797],[-86.09235734900506,39.9019421100107]],"neighbors":[459,463,460],"id":461},"geometry":{"type":"Polygon","coordinates":[[[-86.09251474106557,39.90200680115583],[-86.0923512396569,39.90199586530855],[-86.09233291155495,39.902157131200184],[-86.09249641296067,39.902168067047455],[-86.09251474106557,39.90200680115583]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.0923223129955,39.90193976658499],[-86.09216122809363,39.90192118050953]],"neighbors":[461,464,462],"id":463},"geometry":{"type":"Polygon","coordinates":[[[-86.0923118516943,39.901993125669804],[-86.09215076679529,39.90197453959434],[-86.09211938280244,39.902134616843156],[-86.09228046769297,39.902153202918605],[-86.0923118516943,39.901993125669804]]]}},{"type":"Feature","properties":{"street":"none","street_id":21,"OSM_street_id":"way/17509896","street_anchors":[[-86.09212806997877,39.90191218848715],[-86.09197656865194,39.901864398705676]],"neighbors":[463,null,null],"id":464},"geometry":{"type":"Polygon","coordinates":[[[-86.09210132091523,39.901962093517604],[-86.09194981960704,39.901914303736135],[-86.0918695722386,39.90206401879062],[-86.0920210734908,39.90211180857209],[-86.09210132091523,39.901962093517604]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.094806,39.905442],[-86.09480637287113,39.90531609547398]],"neighbors":[null,467,466],"id":465},"geometry":{"type":"Polygon","coordinates":[[[-86.09487634126661,39.905442122563706],[-86.0948767140085,39.905316218037676],[-86.09508773742209,39.9053165854738],[-86.09508736506801,39.905442489999835],[-86.09487634126661,39.905442122563706]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480645277192,39.905289115932696],[-86.0948068256414,39.90516321140668]],"neighbors":[465,469,468],"id":467},"geometry":{"type":"Polygon","coordinates":[[[-86.09487679388158,39.90528923849613],[-86.0948771666218,39.90516333397011],[-86.09508818956448,39.905163701405414],[-86.09508781721206,39.90528960593142],[-86.09487679388158,39.90528923849613]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480690554183,39.905136231865384],[-86.09480727840963,39.90501032733936]],"neighbors":[467,471,470],"id":469},"geometry":{"type":"Polygon","coordinates":[[[-86.09487724649453,39.90513635442854],[-86.09487761923307,39.90501044990252],[-86.09508864170488,39.90501081733699],[-86.09508826935411,39.90513672186302],[-86.09487724649453,39.90513635442854]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480735830971,39.90498334779807],[-86.09480773117586,39.90485744327206]],"neighbors":[469,473,472],"id":471},"geometry":{"type":"Polygon","coordinates":[[[-86.09487769910545,39.90498347036095],[-86.09487807184233,39.904857565834945],[-86.09508909384323,39.9048579332686],[-86.09508872149416,39.9049838377946],[-86.09487769910545,39.90498347036095]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480781107557,39.90483046373076],[-86.09480818394006,39.90470455920474]],"neighbors":[471,475,474],"id":473},"geometry":{"type":"Polygon","coordinates":[[[-86.09487815171434,39.904830586293386],[-86.09487852444957,39.90470468176736],[-86.0950895459796,39.90470504920023],[-86.09508917363216,39.90483095372625],[-86.09487815171434,39.904830586293386]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09481103908936,39.904066045828216],[-86.09481174641566,39.903940142146524]],"neighbors":[473,477,476],"id":475},"geometry":{"type":"Polygon","coordinates":[[[-86.09488137847175,39.90406627835193],[-86.0948820856688,39.90394037467023],[-86.09509310343104,39.90394107198637],[-86.09509239662178,39.904066975668044],[-86.09488137847175,39.90406627835193]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09481189798524,39.90391316278615],[-86.09481260530836,39.90378725910444]],"neighbors":[475,479,478],"id":477},"geometry":{"type":"Polygon","coordinates":[[[-86.09488223721068,39.90391339530933],[-86.09488294440455,39.903787491627625],[-86.09509396169598,39.9037881889422],[-86.09509325488986,39.903914092623914],[-86.09488223721068,39.90391339530933]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09481275687727,39.90376027974408],[-86.09481346419723,39.90363437606237]],"neighbors":[477,480,null],"id":479},"geometry":{"type":"Polygon","coordinates":[[[-86.09488309594578,39.903760512266736],[-86.09488380313647,39.90363460858502],[-86.09509481995704,39.90363530589801],[-86.0950941131541,39.90376120957973],[-86.09488309594578,39.903760512266736]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09481361576546,39.90360739670199],[-86.09481432308229,39.90348149302028]],"neighbors":[479,null,null],"id":480},"geometry":{"type":"Polygon","coordinates":[[[-86.094883954677,39.90360762922414],[-86.09488466186458,39.90348172554243],[-86.09509567821432,39.90348242285389],[-86.09509497141448,39.903608326535604],[-86.094883954677,39.90360762922414]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480645277192,39.905289115932696],[-86.0948068256414,39.90516321140668]],"neighbors":[466,470,467],"id":468},"geometry":{"type":"Polygon","coordinates":[[[-86.09473611166251,39.90528899332677],[-86.09473648466127,39.90516308880076],[-86.09452546172234,39.90516272072799],[-86.0945250883358,39.905288625254],[-86.09473611166251,39.90528899332677]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480690554183,39.905136231865384],[-86.09480727840963,39.90501032733936]],"neighbors":[468,472,469],"id":470},"geometry":{"type":"Polygon","coordinates":[[[-86.09473656458938,39.90513610925973],[-86.09473693758645,39.90501020473372],[-86.09452591511844,39.905009836661776],[-86.09452554173356,39.90513574118779],[-86.09473656458938,39.90513610925973]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480735830971,39.90498334779807],[-86.09480773117586,39.90485744327206]],"neighbors":[470,474,471],"id":472},"geometry":{"type":"Polygon","coordinates":[[[-86.09473701751423,39.904983225192694],[-86.09473739050964,39.90485732066668],[-86.09452636851249,39.904856952595566],[-86.0945259951293,39.904982857121574],[-86.09473701751423,39.904983225192694]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09480781107557,39.90483046373076],[-86.09480818394006,39.90470455920474]],"neighbors":[472,476,473],"id":474},"geometry":{"type":"Polygon","coordinates":[[[-86.09473747043705,39.90483034112566],[-86.09473784343082,39.90470443659964],[-86.09452682190454,39.90470406852931],[-86.094526448523,39.90482997305534],[-86.09473747043705,39.90483034112566]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09481103908936,39.904066045828216],[-86.09481174641566,39.903940142146524]],"neighbors":[474,478,475],"id":476},"geometry":{"type":"Polygon","coordinates":[[[-86.09474069970744,39.90406581326204],[-86.094741407163,39.90393990958033],[-86.0945303894079,39.90393921162678],[-86.09452968156458,39.90406511530846],[-86.09474069970744,39.90406581326204]]]}},{"type":"Feature","properties":{"street":"none","street_id":22,"OSM_street_id":"way/17519894","street_anchors":[[-86.09481189798524,39.90391316278615],[-86.09481260530836,39.90378725910444]],"neighbors":[476,null,477],"id":478},"geometry":{"type":"Polygon","coordinates":[[[-86.09474155876028,39.90391293022048],[-86.09474226621265,39.903787026538765],[-86.0945312489284,39.90378632858677],[-86.09453054108825,39.90391223226847],[-86.09474155876028,39.90391293022048]]]}},{"type":"Feature","properties":{"street":"none","street_id":23,"OSM_street_id":"way/162451324","street_anchors":[[-86.09830462870273,39.90005066967461],[-86.09830278161208,39.90017656655121]],"neighbors":[null,482,null],"id":481},"geometry":{"type":"Polygon","coordinates":[[[-86.09823429724469,39.90005006235912],[-86.09823245002484,39.90017595923572],[-86.09802145527057,39.90017413703433],[-86.09802330287808,39.90004824015773],[-86.09823429724469,39.90005006235912]]]}},{"type":"Feature","properties":{"street":"none","street_id":23,"OSM_street_id":"way/162451324","street_anchors":[[-86.09830238580606,39.90020354445333],[-86.09830092566646,39.9003294432697]],"neighbors":[481,483,null],"id":482},"geometry":{"type":"Polygon","coordinates":[[[-86.09823205252,39.90020306435829],[-86.09823059225117,39.90032896317466],[-86.09801959201125,39.90032752263461],[-86.09802105266776,39.90020162381824],[-86.09823205252,39.90020306435829]]]}},{"type":"Feature","properties":{"street":"none","street_id":23,"OSM_street_id":"way/162451324","street_anchors":[[-86.09830086188528,39.900356422836246],[-86.09830056423915,39.9004823274801]],"neighbors":[482,null,null],"id":483},"geometry":{"type":"Polygon","coordinates":[[[-86.09823052577377,39.900356324954096],[-86.09823022799841,39.90048222959794],[-86.09801921927736,39.90048193569655],[-86.09801951744043,39.900356031052695],[-86.09823052577377,39.900356324954096]]]}},{"type":"Feature","properties":{"street":"none","street_id":26,"OSM_street_id":"way/606231314","street_anchors":[[-86.097648,39.900721],[-86.09781211817851,39.90072067169275]],"neighbors":[null,null,null],"id":484},"geometry":{"type":"Polygon","coordinates":[[[-86.09764818334399,39.9007749590385],[-86.0978123015225,39.900774630731256],[-86.09781285155621,39.900936507846765],[-86.0976487333777,39.90093683615401],[-86.09764818334399,39.9007749590385]]]}},{"type":"Feature","properties":{"street":"none","street_id":27,"OSM_street_id":"way/606231315","street_anchors":[[-86.0978979,39.9007205],[-86.09806201795314,39.90072011131224]],"neighbors":[null,null,null],"id":485},"geometry":{"type":"Polygon","coordinates":[[[-86.09789811707553,39.90077445896485],[-86.09806223502868,39.90077407027708],[-86.09806288625731,39.90093594717161],[-86.09789876830416,39.90093633585938],[-86.09789811707553,39.90077445896485]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.0978755,39.9054505],[-86.09771137051254,39.9054508343333]],"neighbors":[null,487,null],"id":486},"geometry":{"type":"Polygon","coordinates":[[[-86.0978753131477,39.90539654096855],[-86.09771118366025,39.90539687530187],[-86.0977106231051,39.905234998207504],[-86.09787475259256,39.9052346638742],[-86.0978753131477,39.90539654096855]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.09727760150156,39.90544988098486],[-86.0971134728461,39.905449359442486]],"neighbors":[486,488,null],"id":487},"geometry":{"type":"Polygon","coordinates":[[[-86.09727789281585,39.90539592222578],[-86.09711376416041,39.90539540068341],[-86.09711463810056,39.90523352440616],[-86.097278766756,39.905234045948525],[-86.09727789281585,39.90539592222578]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.09628110617388,39.90544670318691],[-86.09611697755062,39.90544617710691]],"neighbors":[487,489,null],"id":488},"geometry":{"type":"Polygon","coordinates":[[[-86.09628140002327,39.905392744435915],[-86.0961172714,39.90539221835592],[-86.09611815294541,39.90523034210293],[-86.09628228156868,39.90523086818293],[-86.09628140002327,39.905392744435915]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.09528461091111,39.90544352196584],[-86.09512048227175,39.90544300026422]],"neighbors":[488,490,null],"id":489},"geometry":{"type":"Polygon","coordinates":[[[-86.09528490231436,39.905389563207045],[-86.095120773675,39.90538904150542],[-86.09512164788198,39.90522716522901],[-86.09528577652137,39.90522768693064],[-86.09528490231436,39.905389563207045]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.09448742350432,39.905439918202184],[-86.0943232994239,39.90543884536235]],"neighbors":[489,491,null],"id":490},"geometry":{"type":"Polygon","coordinates":[[[-86.09448802282125,39.90538596093892],[-86.09432389874084,39.90538488809907],[-86.09432569668594,39.90522301630922],[-86.09448982076638,39.905224089149065],[-86.09448802282125,39.90538596093892]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.09428812997878,39.905438615438],[-86.09412672051009,39.90542447515972]],"neighbors":[490,null,null],"id":491},"geometry":{"type":"Polygon","coordinates":[[[-86.09429611117997,39.905385004677484],[-86.09413470170965,39.90537086439919],[-86.09415864523334,39.90521003211433],[-86.0943200547086,39.90522417239261],[-86.09429611117997,39.905385004677484]]]}},{"type":"Feature","properties":{"street":"none","street_id":28,"OSM_street_id":"way/607399318","street_anchors":[[-86.09393341379202,39.905328055012696],[-86.09385675245083,39.905217815318565]],"neighbors":[null,null,null],"id":492},"geometry":{"type":"Polygon","coordinates":[[[-86.09387135091407,39.90535345192213],[-86.09379468967275,39.90524321222799],[-86.0936085010624,39.905319402757755],[-86.09368516200415,39.90542964245189],[-86.09387135091407,39.90535345192213]]]}},{"type":"Feature","properties":{"street":"none","street_id":29,"OSM_street_id":"way/607399319","street_anchors":[[-86.0978715,39.9033715],[-86.09770738052454,39.90337045912412]],"neighbors":[null,494,null],"id":493},"geometry":{"type":"Polygon","coordinates":[[[-86.09787208144152,39.90331754262175],[-86.09770796196608,39.90331650174586],[-86.09770970628517,39.90315462961107],[-86.09787382576066,39.90315567048696],[-86.09787208144152,39.90331754262175]]]}},{"type":"Feature","properties":{"street":"none","street_id":29,"OSM_street_id":"way/607399319","street_anchors":[[-86.09767221206616,39.9033702360492],[-86.09750808837941,39.903370135598756]],"neighbors":[493,498,null],"id":494},"geometry":{"type":"Polygon","coordinates":[[[-86.09767226812063,39.903316276844514],[-86.09750814443387,39.903316176394064],[-86.09750831259679,39.90315429877999],[-86.09767243628356,39.90315439923043],[-86.09767226812063,39.903316276844514]]]}},{"type":"Feature","properties":{"street":"none","street_id":29,"OSM_street_id":"way/607399319","street_anchors":[[-86.09488214708846,39.90336149975216],[-86.09471802556705,39.90336120803049]],"neighbors":[494,null,499],"id":498},"geometry":{"type":"Polygon","coordinates":[[[-86.09488231000303,39.90330754067507],[-86.09471818848164,39.9033072489534],[-86.09471867722384,39.90314537172211],[-86.09488279874523,39.90314566344378],[-86.09488231000303,39.90330754067507]]]}},{"type":"Feature","properties":{"street":"none","street_id":29,"OSM_street_id":"way/607399319","street_anchors":[[-86.09727362420261,39.90337038574818],[-86.09710949927783,39.90337056057185]],"neighbors":[null,496,null],"id":495},"geometry":{"type":"Polygon","coordinates":[[[-86.09727372193613,39.90342434491793],[-86.09710959701134,39.903424519741584],[-86.09710989021285,39.90358639725079],[-86.09727401513763,39.90358622242712],[-86.09727372193613,39.90342434491793]]]}},{"type":"Feature","properties":{"street":"none","street_id":29,"OSM_street_id":"way/607399319","street_anchors":[[-86.09627716894228,39.90336802957447],[-86.09611304404346,39.903368000245266]],"neighbors":[495,497,null],"id":496},"geometry":{"type":"Polygon","coordinates":[[[-86.09627715262151,39.903421988794854],[-86.09611302772268,39.90342195946564],[-86.09611297876026,39.90358383712676],[-86.09627710365908,39.90358386645595],[-86.09627715262151,39.903421988794854]]]}},{"type":"Feature","properties":{"street":"none","street_id":29,"OSM_street_id":"way/607399319","street_anchors":[[-86.09528071778428,39.90336446537635],[-86.09511660043476,39.90336324440221]],"neighbors":[496,499,null],"id":497},"geometry":{"type":"Polygon","coordinates":[[[-86.09528003572623,39.903418422061335],[-86.09511591837673,39.9034172010872],[-86.0951138721962,39.90357907114214],[-86.09527798954566,39.903580292116274],[-86.09528003572623,39.903418422061335]]]}}]}; \ No newline at end of file