diff --git a/CHANGELOG.md b/CHANGELOG.md index af62feb..12d3277 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -1,5 +1,6 @@ ### Change Log for Node-RED Worldmap + - v4.3.0 - Add support for PMtiles files. - v4.2.1 - Revert use of optional chaining to extend life slightly. Issue #252 - v4.2.0 - Let icons also be inline images data:image... - v4.1.0 - Add optional SOG, COG, altft, altm input properties. diff --git a/README.md b/README.md index 803c0ab..d9f5956 100644 --- a/README.md +++ b/README.md @@ -13,6 +13,7 @@ Feel free to [![](https://img.shields.io/static/v1?label=Sponsor&message=%E2%9D% ### Updates +- v4.3.0 - Add support for PMtiles files. - v4.2.1 - Revert use of optional chaining to extend life slightly. Issue #252 - v4.2.0 - Let icons also be inline images data:image... - v4.1.0 - Add optional SOG, COG, altft, altm input properties. @@ -93,7 +94,7 @@ If you use the name without the fa- prefix (eg `male`) you will get the icon ins You can also specify an emoji as the icon by using the :emoji name: syntax - for example `:smile:`. Here is a **[list of emojis](https://github.com/dceejay/RedMap/blob/master/emojilist.md)**. -Or you can specify an image to load as an icon by setting the icon to http(s)://... By default it will be scaled to 32x32 pixels. You can change the size by setting **iconSize** to a number - eg 64. Example icon - `"https://img.icons8.com/windows/32/000000/bird.png"` or you can use an inline image of the form data:image/... which uses a base64 encoded image. +Or you can specify an image to load as an icon by setting the icon to `http(s)://...` By default it will be scaled to 32x32 pixels. You can change the size by setting **iconSize** to a number - eg 64. Example icon - `"https://img.icons8.com/windows/32/000000/bird.png"` or you can use an inline image of the form `data:image/...` which uses a base64 encoded image. There are also several special icons... @@ -220,7 +221,7 @@ Defaults are shown above. There are several ways to send GeoJSON to the map. -1) If the msg.payload contains a **geojson** property, and no **lat** and **lon**, then +1) If the msg.payload contains a **geojson** property, and no **lat** and **lon**, then rather than draw a point it will render the geojson. msg.payload = { @@ -359,65 +360,6 @@ in addition existing male, female, fa-male and fa-female icons are all represent - This view is a side project to the Node-RED Worldmap project so I'm happy to take PRs but it probably won't be actively developed. -## Events from the map - -The **worldmap in** node can be used to receive various events from the map. Examples of messages coming FROM the map include: - - { "action": "connected" } // useful to trigger delivery or redraw of points - { "action": "disconnect", "clients": 1 } // when a client disconnects - reports number remaining - {"action":"bounds", "south":50.55, "west":-1.48, "north":50.72, "east":-0.98} // reports the outer bounds of the hmap area when zoomed or moved - - { "action": "click", "name":"Jason", "layer":"gps", "icon":"male", "iconColor":"blue", "lat":51.024985, "lon":-1.39698 } // when a marker is clicked - { "action": "move", "name":"Jason", "layer":"gps", "icon":"male", "iconColor":"blue", "lat":51.044632, "lon":-1.359901 } // when a marker is moved - { "action": "delete", "name": "Jason" } // when a point or shape is deleted - - { "action": "point", "lat": "50.60634", "lon": "-1.66580", "point": "Jason,male,gps" } - { "action": "draw", "type": "rectangle", "points": [ { "lat": 50.61243889044519, "lng": -1.5913009643554688 }, { "lat": 50.66665471366635, "lng": -1.5913009643554688 }, { "lat": 50.66665471366635, "lng": -1.4742279052734375 }, { "lat": 50.61243889044519, "lng": -1.4742279052734375 } ] } - - { "action": "layer", "name": "myLayer" } // when a map layer is changed - { "action": "addlayer", "name": "myLayer" } // when a new map layer is added - { "action": "dellayer", "name": "myLayer" } // when a new map layer is deleted - - { "action": "file", "name": "myfilename", "type":"image/jpeg", "lat":51, "lon":-1, "content":"....."} // when a file is dropped on the map - see below. - - { "action": "button", "name": "My Fancy Button" } // when a user defined button is clicked - - { "action": "feedback", "name": "some name", "value": "some value", "lat":51, "lon":0, "layer":"unknown" } // when a user calls the feedback function - see below - -If File Drop is enabled - then the map can accept files of type gpx, kml, nvg, jpeg, png and geojson. The file content property will always be a binary buffer. The lat, lon of the cursor drop point will be included. Tracks will be locally rendered on the map. The `node-red-node-exif` node can be used to extract location information from a jpeg image and then geolocate it back on the map. Png images will be located where they are dropped but can then be dragged if required. - -All actions also include a: -`msg._sessionid` property that indicates which client session they came from. Any msg sent out that includes this property will ONLY be sent to that session - so you can target map updates to specific sessions if required. -`msg._sessionip` property that shows the ip of the client that is connected to the session. - -The "connected" action additionally includes a: -`msg.payload.parameters` property object that lists the parameters sent in the url. -`msg.payload.clientTimezone` property string showing the clients local Timezone. Returns bool of `false` if unable to retrive clients local Timezone. -`msg._clientheaders` property that shows the headers sent by the client to make a connection to the session. - - -### Utility functions - -There are some internal functions available to make interacting with Node-RED easier (e.g. from inside a user defined popup., these include: - - - **feedback()** : it takes 2, 3, or 4 parameters, name, value, and optionally an action name (defaults to "feedback"), and optional boolean to close the popup on calling this function, and can be used inside something like an input tag - `onchange='feedback(this.name,this.value,null,true)'`. Value can be a more complex object if required as long as it is serialisable. If used with a marker the name should be that of the marker - you can use `${name}` to let it be substituted automatically. - - - **addToForm()** : takes a property name value pair to add to a variable called `form`. When used with contextmenu feedback (above) you can set the feedback value to `"_form"` to substitute this accumulated value. This allows you to do things like `onBlur='addToForm(this.name,this.value)'` over several different fields in the menu and then use `feedback(this.name,"_form")` to submit them all at once. For example a simple multiple line form could be as per the example below: - - Also if you wish to retain the values between separate openings of this form you can assign property names to the value field in the form `value="${foo}`, etc. These will then appear as part of an **value** property on the worldmap-in node message. - -``` -var menu = 'Add some data
' -menu += 'Add more data
' -menu += '' -msg.payload = { command: { "contextmenu":menu } } -``` - - - **delMarker()** : takes the name of the marker as a parameter. In a popup this can be specified as `${name}` for dynamic substitution. - - - **editPoly()** : takes the name of the shape or line as a parameter. In a popup this can be specified as `${name}` for dynamic substitution. - - ## Controlling the map You can also control the map via the node, by sending in a msg.payload containing a **command** object. Multiple parameters can be specified in one command. @@ -468,62 +410,11 @@ You can also use the name "none" to completely remove the base layer, msg.payload = { "command": { "layer":"none" }}; -#### To add and remove a user defined button +#### To clear all markers from a layer, or an overlay from the map -to add a button bottom right + msg.payload = { "command": { "clear: "name of the layer/overlay you wish to clear" }}; - msg.payload.command = { "button": { "name":"My Fancy Button", "icon": "fa-star", "position":"bottomright" } }; - -When clicked the button will send an event to the `worldmap in` node containing `{"action":"button", "name","My Fancy Button"}` - this can then be used to trigger other map commands or flows. - -to remove - - msg.payload.command = { "button": { "name":"My Fancy Button" } }; - -Multiple buttons can declared by using an array of button objects. - -#### To add a custom popup or contextmenu - -You can customise a marker's popup, or context menu (right click), by setting the -appropriate property to an html string. Often you will need some embedded javascript -in order to make it do something when you click a button for example. You need to be -careful escaping quotes, and that they remain matched. - -For example a marker popup with a slider (note the \ escaping the internal ' ) - - popup: '' - -Or a marker contextmenu with an input box - - contextmenu: '' - -Or you can add a contextmenu to the map. Simple contextmenu with a button - - msg.payload.command = { - contextmenu: '' - } - -Or with an input box - - msg.payload.command : { - contextmenu: '' - } - -Example simple form - -``` -[{"id":"7351100bacb1f5fe","type":"function","z":"4aa2ed2fd1b11362","name":"","func":"msg.payload = { command: {\ncontextmenu: String.raw`\nText
\nNumber
\n\n`\n}}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":360,"wires":[["a6a82f2e8efc44fc"]]},{"id":"7b595f0c8f6ac710","type":"worldmap in","z":"4aa2ed2fd1b11362","name":"","path":"/worldmap","events":"connect","x":195,"y":360,"wires":[["7351100bacb1f5fe"]]}] -``` - -See the section on **Utility Functions** for details of the feedback function. - -#### To add and remove a legend - -If you want to add a small legend overlay - - msg.payload.command = { "legend": "Title
Water
Forest
" }; - -To remove set the legend to an empty string `""`. +Feeding this into the tracks node will also remove the tracks stored for that layer. #### To add a new base layer @@ -537,23 +428,6 @@ may let your markers be more visible. (see overlay example below). "opt":{ "maxZoom":19, "attribution":"© OpenStreetMap" } }; -#### To add a minimap - -A minimap overview can be added by sending a suitable command. The "minimap" property -must specify the name of an existing base layer to use. The "opt" property can contain -valid options from the [minimap library options](https://github.com/Norkart/Leaflet-MiniMap#available-options). - - msg.payload.command.map = { - minimap: "OSM", - opt: { - centerFixed: [51.05, -1.35], - toggleDisplay: true - } - } - }; - -Set `msg.payload.command.map.minimap = false;` to remove the minimap. - #### To remove base or overlay layers To remove several layers, either base layers or overlays, you can pass an array of names as follows. @@ -637,7 +511,7 @@ As per the geojson overlay you can also inject an ESRI ArcGIS FeatureLayer layer NOTE: you can set various options as [specified here](https://developers.arcgis.com/esri-leaflet/api-reference/layers/feature-layer/#options). -In order to pass over **style**, **pointToLayer**, or **onEachFeature** functions they need to be serialised as follows... for example +In order to pass over **style**, **pointToLayer**, or **onEachFeature** functions they need to be serialised as follows. For example const style = function () { return { color: "#910000", weight: 2 }; @@ -646,6 +520,18 @@ In order to pass over **style**, **pointToLayer**, or **onEachFeature** function This may cause the function node setting them to be in error, for example if it references L.marker, which is unknown on the server side. The flow should still deploy and run ok. +#### To add an Image Overlay + +You can overlay an image as long as you can specify the lower-left and upper-right corners. For example in a function node: + + var imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]]; + msg.payload = { command : { lat:40.74, lon:-74.175, zoom:13 } }; + msg.payload.command.map = { + overlay: "New York Historical", + url: 'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg', + bounds: imageBounds, + opt: { opacity:0.8, attribution:"© University of Texas" } + }; #### To add a Velocity Grid Overlay @@ -673,19 +559,6 @@ Or you can use try this docker image which uses the Canadian Meterological Servi docker run -d -p 7000:7000 --name windserver theceejay/windserver:latest -#### To add an Image Overlay - -in a function node: - - var imageBounds = [[40.712216, -74.22655], [40.773941, -74.12544]]; - msg.payload = { command : { lat:40.74, lon:-74.175, zoom:13 } }; - msg.payload.command.map = { - overlay: "New York Historical", - url: 'https://www.lib.utexas.edu/maps/historical/newark_nj_1922.jpg', - bounds: imageBounds, - opt: { opacity:0.8, attribution:"© University of Texas" } - }; - #### To add a Lat/Lon Graticule overlay A graticule can be enabled via the node configuration, and can also be set dynamically, @@ -698,11 +571,178 @@ for example in a function node: see https://github.com/cloudybay/leaflet.latlng-graticule for more details about options and demo. -#### To clear all markers from a layer, or an overlay from the map +#### To add and remove a user defined button - msg.payload.command.clear = "name of the layer/overlay you wish to clear"; +to add a button bottom right -Feeding this into the tracks node will also remove the tracks stored for that layer. + msg.payload.command = { "button": { "name":"My Fancy Button", "icon": "fa-star", "position":"bottomright" } }; + +When clicked the button will send an event to the `worldmap in` node containing `{"action":"button", "name","My Fancy Button"}` - this can then be used to trigger other map commands or flows. + +to remove + + msg.payload.command = { "button": { "name":"My Fancy Button" } }; + +Multiple buttons can declared by using an array of button objects. + +#### To add a custom popup or contextmenu + +You can customise a marker's popup, or context menu (right click), by setting the +appropriate property to an html string. Often you will need some embedded javascript +in order to make it do something when you click a button for example. You need to be +careful escaping quotes, and that they remain matched. + +For example a marker popup with a slider (note the \ escaping the internal ' ) + + popup: '' + +Or a marker contextmenu with an input box + + contextmenu: '' + +Or you can add a contextmenu to the map. Simple contextmenu with a button + + msg.payload.command = { + contextmenu: '' + } + +Or with an input box + + msg.payload.command : { + contextmenu: '' + } + +Example simple form + +``` +[{"id":"7351100bacb1f5fe","type":"function","z":"4aa2ed2fd1b11362","name":"","func":"msg.payload = { command: {\ncontextmenu: String.raw`\nText
\nNumber
\n\n`\n}}\nreturn msg;","outputs":1,"noerr":0,"initialize":"","finalize":"","libs":[],"x":350,"y":360,"wires":[["a6a82f2e8efc44fc"]]},{"id":"7b595f0c8f6ac710","type":"worldmap in","z":"4aa2ed2fd1b11362","name":"","path":"/worldmap","events":"connect","x":195,"y":360,"wires":[["7351100bacb1f5fe"]]}] +``` + +See the section on **Utility Functions** for details of the feedback function. + +#### To add and remove a legend + +If you want to add a small legend overlay + + msg.payload.command = { "legend": "Title
Water
Forest
" }; + +To remove set the legend to an empty string `""`. + +#### To add a minimap + +A minimap overview can be added by sending a suitable command. The "minimap" property +must specify the name of an existing base layer to use. The "opt" property can contain +valid options from the [minimap library options](https://github.com/Norkart/Leaflet-MiniMap#available-options). + + msg.payload.command.map = { + minimap: "OSM", + opt: { + centerFixed: [51.05, -1.35], + toggleDisplay: true + } + } + }; + +Set `msg.payload.command.map.minimap = false;` to remove the minimap. + + +## Events from the map + +The **worldmap in** node can be used to receive various events from the map. Examples of messages coming FROM the map include: + + { "action": "connected" } // useful to trigger delivery or redraw of points + { "action": "disconnect", "clients": 1 } // when a client disconnects - reports number remaining + {"action":"bounds", "south":50.55, "west":-1.48, "north":50.72, "east":-0.98} // reports the outer bounds of the hmap area when zoomed or moved + + { "action": "click", "name":"Jason", "layer":"gps", "icon":"male", "iconColor":"blue", "lat":51.024985, "lon":-1.39698 } // when a marker is clicked + { "action": "move", "name":"Jason", "layer":"gps", "icon":"male", "iconColor":"blue", "lat":51.044632, "lon":-1.359901 } // when a marker is moved + { "action": "delete", "name": "Jason" } // when a point or shape is deleted + + { "action": "point", "lat": "50.60634", "lon": "-1.66580", "point": "Jason,male,gps" } + { "action": "draw", "type": "rectangle", "points": [ { "lat": 50.61243889044519, "lng": -1.5913009643554688 }, { "lat": 50.66665471366635, "lng": -1.5913009643554688 }, { "lat": 50.66665471366635, "lng": -1.4742279052734375 }, { "lat": 50.61243889044519, "lng": -1.4742279052734375 } ] } + + { "action": "layer", "name": "myLayer" } // when a map layer is changed + { "action": "addlayer", "name": "myLayer" } // when a new map layer is added + { "action": "dellayer", "name": "myLayer" } // when a new map layer is deleted + + { "action": "file", "name": "myfilename", "type":"image/jpeg", "lat":51, "lon":-1, "content":"....."} // when a file is dropped on the map - see below. + + { "action": "button", "name": "My Fancy Button" } // when a user defined button is clicked + + { "action": "feedback", "name": "some name", "value": "some value", "lat":51, "lon":0, "layer":"unknown" } // when a user calls the feedback function - see below + +If File Drop is enabled - then the map can accept files of type gpx, kml, nvg, jpeg, png and geojson. The file content property will always be a binary buffer. The lat, lon of the cursor drop point will be included. Tracks will be locally rendered on the map. The `node-red-node-exif` node can be used to extract location information from a jpeg image and then geolocate it back on the map. Png images will be located where they are dropped but can then be dragged if required. + +All actions also include a: +`msg._sessionid` property that indicates which client session they came from. Any msg sent out that includes this property will ONLY be sent to that session - so you can target map updates to specific sessions if required. +`msg._sessionip` property that shows the ip of the client that is connected to the session. + +The "connected" action additionally includes a: +`msg.payload.parameters` property object that lists the parameters sent in the url. +`msg.payload.clientTimezone` property string showing the clients local Timezone. Returns bool of `false` if unable to retrive clients local Timezone. +`msg._clientheaders` property that shows the headers sent by the client to make a connection to the session. + + +### Utility functions + +There are some internal functions available to make interacting with Node-RED easier (e.g. from inside a user defined popup., these include: + + - **feedback()** : it takes 2, 3, or 4 parameters, name, value, and optionally an action name (defaults to "feedback"), and optional boolean to close the popup on calling this function, and can be used inside something like an input tag - `onchange='feedback(this.name,this.value,null,true)'`. Value can be a more complex object if required as long as it is serialisable. If used with a marker the name should be that of the marker - you can use `${name}` to let it be substituted automatically. + + - **addToForm()** : takes a property name value pair to add to a variable called `form`. When used with contextmenu feedback (above) you can set the feedback value to `"_form"` to substitute this accumulated value. This allows you to do things like `onBlur='addToForm(this.name,this.value)'` over several different fields in the menu and then use `feedback(this.name,"_form")` to submit them all at once. For example a simple multiple line form could be as per the example below: + + Also if you wish to retain the values between separate openings of this form you can assign property names to the value field in the form `value="${foo}`, etc. These will then appear as part of an **value** property on the worldmap-in node message. + +``` +var menu = 'Add some data
' +menu += 'Add more data
' +menu += '' +msg.payload = { command: { "contextmenu":menu } } +``` + + - **delMarker()** : takes the name of the marker as a parameter. In a popup this can be specified as `${name}` for dynamic substitution. + + - **editPoly()** : takes the name of the shape or line as a parameter. In a popup this can be specified as `${name}` for dynamic substitution. + + +## Serving maps + +By default this node expects users to have access to the internet in order to access the map servers that provide all the built in mapping. As per above you are able to add your own sources of mapping and sometimes this includes the requirement for offline access, in which case maps must be served up locally. There are several ways to do this outlined below. My personal favourite is the Tileserver-gl docker option, but of course this does require Docker. + +### Using PMtiles files + +You can use a PMtiles format map archive file from [Protomaps](https://docs.protomaps.com/basemaps/downloads) as a base layer map. + +**Note**: the whole planet file is over 100GB so be warned both for local storage and your download speed. You can download or extract just a portion of it if you use the **pmtiles** command line with the extract option. Use `pmtiles extract --help` to see the options. + +Copy, or create an alias to, your .pmtiles file(s) into your `~/.node-red/node_modules/node-red-contrib-web-worldmap/worldmap/` directory. On re-starting Node-RED the node will detect the file(s) and add them to the base map layer menu, using the file name as the layer name. + +### Using a Docker Map Server + +I have found the easiest to use mapserver for decent generic map to be Tileserver-gl. It uses mbtiles format maps - for example from [MapTiler Data](https://data.maptiler.com/downloads/planet/). You can download your mbtiles file into a directory and then from that directory run +``` +docker run --name maptiler -d -v $(pwd):/data -p 1884:8080 maptiler/tileserver-gl -p 8080 --mbtiles yourMapFile.mbtiles +``` +and use a url like `"url": "http://localhost:1884/styles/basic-preview/{z}/{x}/{y}.png"` + +Other more traditional map servers include containers like https://hub.docker.com/r/camptocamp/mapserver, then assuming you have the mapfile 'my-app.map' in the current working directory, you could mount it as: +``` +docker run -d --name camptocamp -v $(pwd):/etc/mapserver/:ro -p 1881:80 camptocamp/mapserver +``` + +then the url should be of the form `"url": "http://localhost:1881/?map=/etc/mapserver/my-app.map"` where *my-app.map* is the name of your map file. A quick test of the server would be to browse to http://localhost:1881/?map=/etc/mapserver/my-app.map&mode=map + +Or you can use a docker container like https://hub.docker.com/r/geodata/mapserver/ then assuming you have the mapfile 'my-app.map' in the current working directory, you could mount it as: +``` +docker run -d --name mapserver -v $(pwd):/maps:ro -p 1882:80 geodata/mapserver +``` +and use a url like `"url": "http://localhost:1882/?map=/maps/my-app.map",` + + +Other useful map servers include Geoserver, a somewhat larger image but fully featured. +``` +docker run --name geoserver -d -v ${PWD}:/var/local/geoserver -p 1885:8080 oscarfonts/geoserver +``` ### Using a local Map Server (WMS server) @@ -736,32 +776,6 @@ You can then add a new WMS Base layer by injecting a message like "wms": true // set to true for WMS type mapserver }}} -#### Using a Docker Map Server - -You can use a docker container like https://hub.docker.com/r/camptocamp/mapserver, then assuming you have the mapfile 'my-app.map' in the current working directory, you could mount it as: -``` -docker run -d --name camptocamp -v $(pwd):/etc/mapserver/:ro -p 1881:80 camptocamp/mapserver -``` - -then the url should be of the form `"url": "http://localhost:1881/?map=/etc/mapserver/my-app.map"` where *my-app.map* is the name of your map file. A quick test of the server would be to browse to http://localhost:1881/?map=/etc/mapserver/my-app.map&mode=map - -Or you can use a docker container like https://hub.docker.com/r/geodata/mapserver/ then assuming you have the mapfile 'my-app.map' in the current working directory, you could mount it as: -``` -docker run -d --name mapserver -v $(pwd):/maps:ro -p 1882:80 geodata/mapserver -``` -and use a url like `"url": "http://localhost:1882/?map=/maps/my-app.map",` - - -To use a vector mbtiles server like **MapTiler** then you can download your mbtiles file into a directory and then from that directory run -``` -docker run --name maptiler -d -v $(pwd):/data -p 1884:8080 maptiler/tileserver-gl -p 8080 --mbtiles yourMapFile.mbtiles -``` -and use a url like `"url": "http://localhost:1884/styles/basic-preview/{z}/{x}/{y}.png"` - -Other useful map servers include Geoserver, a somewhat larger image but fully featured. -``` -docker run --name geoserver -d -v ${PWD}:/var/local/geoserver -p 1885:8080 oscarfonts/geoserver -``` --- diff --git a/package.json b/package.json index 9384916..e875125 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "node-red-contrib-web-worldmap", - "version": "4.2.1", + "version": "4.3.0", "description": "A Node-RED node to provide a web page of a world map for plotting things on.", "dependencies": { "@turf/bezier-spline": "~6.5.0", diff --git a/worldmap.js b/worldmap.js index 7a9d21b..d13d9be 100644 --- a/worldmap.js +++ b/worldmap.js @@ -13,6 +13,7 @@ module.exports = function(RED) { if (fs.existsSync((__dirname + '/mapserv'))) { RED.httpNode.use("/cgi-bin/mapserv", require('cgi')(__dirname + '/mapserv')); } + var pmtiles = fs.readdirSync(__dirname + '/worldmap').filter(fn => fn.endsWith('.pmtiles')); function worldMap(node, n) { var allPoints = {}; @@ -119,6 +120,9 @@ module.exports = function(RED) { if (node.name) { c.toptitle = node.name; } //console.log("INIT",c) client.write(JSON.stringify({command:c})); + for (var p=0; p delete v.tout); setTimeout(function() { client.write(JSON.stringify(o)) }, 250); diff --git a/worldmap/index.html b/worldmap/index.html index 615ebf8..75b3d6e 100644 --- a/worldmap/index.html +++ b/worldmap/index.html @@ -76,6 +76,7 @@ + diff --git a/worldmap/leaflet/protomaps-leaflet.min.js b/worldmap/leaflet/protomaps-leaflet.min.js new file mode 100644 index 0000000..d19d342 --- /dev/null +++ b/worldmap/leaflet/protomaps-leaflet.min.js @@ -0,0 +1,9 @@ +var protomapsL=(()=>{var bi=Object.create;var De=Object.defineProperty;var wi=Object.getOwnPropertyDescriptor;var vi=Object.getOwnPropertyNames,Jt=Object.getOwnPropertySymbols,_i=Object.getPrototypeOf,Gt=Object.prototype.hasOwnProperty,zi=Object.prototype.propertyIsEnumerable;var Qt=(t,e,r)=>e in t?De(t,e,{enumerable:!0,configurable:!0,writable:!0,value:r}):t[e]=r,er=(t,e)=>{for(var r in e||(e={}))Gt.call(e,r)&&Qt(t,r,e[r]);if(Jt)for(var r of Jt(e))zi.call(e,r)&&Qt(t,r,e[r]);return t};var tr=t=>De(t,"__esModule",{value:!0});var K=(t,e)=>()=>(e||t((e={exports:{}}).exports,e),e.exports),ki=(t,e)=>{tr(t);for(var r in e)De(t,r,{get:e[r],enumerable:!0})},Li=(t,e,r)=>{if(e&&typeof e=="object"||typeof e=="function")for(let i of vi(e))!Gt.call(t,i)&&i!=="default"&&De(t,i,{get:()=>e[i],enumerable:!(r=wi(e,i))||r.enumerable});return t},N=t=>Li(tr(De(t!=null?bi(_i(t)):{},"default",t&&t.__esModule&&"default"in t?{get:()=>t.default,enumerable:!0}:{value:t,enumerable:!0})),t);var O=(t,e,r)=>new Promise((i,n)=>{var a=l=>{try{o(r.next(l))}catch(u){n(u)}},s=l=>{try{o(r.throw(l))}catch(u){n(u)}},o=l=>l.done?i(l.value):Promise.resolve(l.value).then(a,s);o((r=r.apply(t,e)).next())});var re=K((ca,rr)=>{"use strict";rr.exports=ge;function ge(t,e){this.x=t,this.y=e}ge.prototype={clone:function(){return new ge(this.x,this.y)},add:function(t){return this.clone()._add(t)},sub:function(t){return this.clone()._sub(t)},multByPoint:function(t){return this.clone()._multByPoint(t)},divByPoint:function(t){return this.clone()._divByPoint(t)},mult:function(t){return this.clone()._mult(t)},div:function(t){return this.clone()._div(t)},rotate:function(t){return this.clone()._rotate(t)},rotateAround:function(t,e){return this.clone()._rotateAround(t,e)},matMult:function(t){return this.clone()._matMult(t)},unit:function(){return this.clone()._unit()},perp:function(){return this.clone()._perp()},round:function(){return this.clone()._round()},mag:function(){return Math.sqrt(this.x*this.x+this.y*this.y)},equals:function(t){return this.x===t.x&&this.y===t.y},dist:function(t){return Math.sqrt(this.distSqr(t))},distSqr:function(t){var e=t.x-this.x,r=t.y-this.y;return e*e+r*r},angle:function(){return Math.atan2(this.y,this.x)},angleTo:function(t){return Math.atan2(this.y-t.y,this.x-t.x)},angleWith:function(t){return this.angleWithSep(t.x,t.y)},angleWithSep:function(t,e){return Math.atan2(this.x*e-this.y*t,this.x*t+this.y*e)},_matMult:function(t){var e=t[0]*this.x+t[1]*this.y,r=t[2]*this.x+t[3]*this.y;return this.x=e,this.y=r,this},_add:function(t){return this.x+=t.x,this.y+=t.y,this},_sub:function(t){return this.x-=t.x,this.y-=t.y,this},_mult:function(t){return this.x*=t,this.y*=t,this},_div:function(t){return this.x/=t,this.y/=t,this},_multByPoint:function(t){return this.x*=t.x,this.y*=t.y,this},_divByPoint:function(t){return this.x/=t.x,this.y/=t.y,this},_unit:function(){return this._div(this.mag()),this},_perp:function(){var t=this.y;return this.y=this.x,this.x=-t,this},_rotate:function(t){var e=Math.cos(t),r=Math.sin(t),i=e*this.x-r*this.y,n=r*this.x+e*this.y;return this.x=i,this.y=n,this},_rotateAround:function(t,e){var r=Math.cos(t),i=Math.sin(t),n=e.x+r*(this.x-e.x)-i*(this.y-e.y),a=e.y+i*(this.x-e.x)+r*(this.y-e.y);return this.x=n,this.y=a,this},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this}};ge.convert=function(t){return t instanceof ge?t:Array.isArray(t)?new ge(t[0],t[1]):t}});var pt=K((ma,ir)=>{"use strict";var Si=re();ir.exports=be;function be(t,e,r,i,n){this.properties={},this.extent=r,this.type=0,this._pbf=t,this._geometry=-1,this._keys=i,this._values=n,t.readFields(Fi,this,e)}function Fi(t,e,r){t==1?e.id=r.readVarint():t==2?Mi(r,e):t==3?e.type=r.readVarint():t==4&&(e._geometry=r.pos)}function Mi(t,e){for(var r=t.readVarint()+t.pos;t.pos>3}if(i--,r===1||r===2)n+=t.readSVarint(),a+=t.readSVarint(),r===1&&(o&&s.push(o),o=[]),o.push(new Si(n,a));else if(r===7)o&&o.push(o[0].clone());else throw new Error("unknown command "+r)}return o&&s.push(o),s};be.prototype.bbox=function(){var t=this._pbf;t.pos=this._geometry;for(var e=t.readVarint()+t.pos,r=1,i=0,n=0,a=0,s=1/0,o=-1/0,l=1/0,u=-1/0;t.pos>3}if(i--,r===1||r===2)n+=t.readSVarint(),a+=t.readSVarint(),no&&(o=n),au&&(u=a);else if(r!==7)throw new Error("unknown command "+r)}return[s,l,o,u]};be.prototype.toGeoJSON=function(t,e,r){var i=this.extent*Math.pow(2,r),n=this.extent*t,a=this.extent*e,s=this.loadGeometry(),o=be.types[this.type],l,u;function f(x){for(var w=0;w{"use strict";var Pi=pt();ar.exports=nr;function nr(t,e){this.version=1,this.name=null,this.extent=4096,this.length=0,this._pbf=t,this._keys=[],this._values=[],this._features=[],t.readFields(Di,this,e),this.length=this._features.length}function Di(t,e,r){t===15?e.version=r.readVarint():t===1?e.name=r.readString():t===5?e.extent=r.readVarint():t===2?e._features.push(r.pos):t===3?e._keys.push(r.readString()):t===4&&e._values.push(Ai(r))}function Ai(t){for(var e=null,r=t.readVarint()+t.pos;t.pos>3;e=i===1?t.readString():i===2?t.readFloat():i===3?t.readDouble():i===4?t.readVarint64():i===5?t.readVarint():i===6?t.readSVarint():i===7?t.readBoolean():null}return e}nr.prototype.feature=function(t){if(t<0||t>=this._features.length)throw new Error("feature index out of bounds");this._pbf.pos=this._features[t];var e=this._pbf.readVarint()+this._pbf.pos;return new Pi(this._pbf,e,this.extent,this._keys,this._values)}});var or=K((ya,sr)=>{"use strict";var Bi=yt();sr.exports=Ei;function Ei(t,e){this.layers=t.readFields(Ri,{},e)}function Ri(t,e,r){if(t===3){var i=new Bi(r,r.readVarint()+r.pos);i.length&&(e[i.name]=i)}}});var lr=K((xa,Ge)=>{Ge.exports.VectorTile=or();Ge.exports.VectorTileFeature=pt();Ge.exports.VectorTileLayer=yt()});var ur=K(xt=>{xt.read=function(t,e,r,i,n){var a,s,o=n*8-i-1,l=(1<>1,f=-7,d=r?n-1:0,c=r?-1:1,x=t[e+d];for(d+=c,a=x&(1<<-f)-1,x>>=-f,f+=o;f>0;a=a*256+t[e+d],d+=c,f-=8);for(s=a&(1<<-f)-1,a>>=-f,f+=i;f>0;s=s*256+t[e+d],d+=c,f-=8);if(a===0)a=1-u;else{if(a===l)return s?NaN:(x?-1:1)*(1/0);s=s+Math.pow(2,i),a=a-u}return(x?-1:1)*s*Math.pow(2,a-i)};xt.write=function(t,e,r,i,n,a){var s,o,l,u=a*8-n-1,f=(1<>1,c=n===23?Math.pow(2,-24)-Math.pow(2,-77):0,x=i?0:a-1,w=i?1:-1,z=e<0||e===0&&1/e<0?1:0;for(e=Math.abs(e),isNaN(e)||e===1/0?(o=isNaN(e)?1:0,s=f):(s=Math.floor(Math.log(e)/Math.LN2),e*(l=Math.pow(2,-s))<1&&(s--,l*=2),s+d>=1?e+=c/l:e+=c*Math.pow(2,1-d),e*l>=2&&(s++,l/=2),s+d>=f?(o=0,s=f):s+d>=1?(o=(e*l-1)*Math.pow(2,n),s=s+d):(o=e*Math.pow(2,d-1)*Math.pow(2,n),s=0));n>=8;t[r+x]=o&255,x+=w,o/=256,n-=8);for(s=s<0;t[r+x]=s&255,x+=w,s/=256,u-=8);t[r+x-w]|=z*128}});var pr=K((ba,mr)=>{"use strict";mr.exports=F;var Qe=ur();function F(t){this.buf=ArrayBuffer.isView&&ArrayBuffer.isView(t)?t:new Uint8Array(t||0),this.pos=0,this.type=0,this.length=this.buf.length}F.Varint=0;F.Fixed64=1;F.Bytes=2;F.Fixed32=5;var gt=(1<<16)*(1<<16),hr=1/gt,Oi=12,fr=typeof TextDecoder=="undefined"?null:new TextDecoder("utf8");F.prototype={destroy:function(){this.buf=null},readFields:function(t,e,r){for(r=r||this.length;this.pos>3,a=this.pos;this.type=i&7,t(n,e,this),this.pos===a&&this.skip(i)}return e},readMessage:function(t,e){return this.readFields(t,e,this.readVarint()+this.pos)},readFixed32:function(){var t=et(this.buf,this.pos);return this.pos+=4,t},readSFixed32:function(){var t=cr(this.buf,this.pos);return this.pos+=4,t},readFixed64:function(){var t=et(this.buf,this.pos)+et(this.buf,this.pos+4)*gt;return this.pos+=8,t},readSFixed64:function(){var t=et(this.buf,this.pos)+cr(this.buf,this.pos+4)*gt;return this.pos+=8,t},readFloat:function(){var t=Qe.read(this.buf,this.pos,!0,23,4);return this.pos+=4,t},readDouble:function(){var t=Qe.read(this.buf,this.pos,!0,52,8);return this.pos+=8,t},readVarint:function(t){var e=this.buf,r,i;return i=e[this.pos++],r=i&127,i<128||(i=e[this.pos++],r|=(i&127)<<7,i<128)||(i=e[this.pos++],r|=(i&127)<<14,i<128)||(i=e[this.pos++],r|=(i&127)<<21,i<128)?r:(i=e[this.pos],r|=(i&15)<<28,Ii(r,t,this))},readVarint64:function(){return this.readVarint(!0)},readSVarint:function(){var t=this.readVarint();return t%2==1?(t+1)/-2:t/2},readBoolean:function(){return Boolean(this.readVarint())},readString:function(){var t=this.readVarint()+this.pos,e=this.pos;return this.pos=t,t-e>=Oi&&fr?Gi(this.buf,e,t):Ji(this.buf,e,t)},readBytes:function(){var t=this.readVarint()+this.pos,e=this.buf.subarray(this.pos,t);return this.pos=t,e},readPackedVarint:function(t,e){if(this.type!==F.Bytes)return t.push(this.readVarint(e));var r=ae(this);for(t=t||[];this.pos127;);else if(e===F.Bytes)this.pos=this.readVarint()+this.pos;else if(e===F.Fixed32)this.pos+=4;else if(e===F.Fixed64)this.pos+=8;else throw new Error("Unimplemented type: "+e)},writeTag:function(t,e){this.writeVarint(t<<3|e)},realloc:function(t){for(var e=this.length||16;e268435455||t<0){Xi(t,this);return}this.realloc(4),this.buf[this.pos++]=t&127|(t>127?128:0),!(t<=127)&&(this.buf[this.pos++]=(t>>>=7)&127|(t>127?128:0),!(t<=127)&&(this.buf[this.pos++]=(t>>>=7)&127|(t>127?128:0),!(t<=127)&&(this.buf[this.pos++]=t>>>7&127)))},writeSVarint:function(t){this.writeVarint(t<0?-t*2-1:t*2)},writeBoolean:function(t){this.writeVarint(Boolean(t))},writeString:function(t){t=String(t),this.realloc(t.length*4),this.pos++;var e=this.pos;this.pos=Qi(this.buf,t,this.pos);var r=this.pos-e;r>=128&&dr(e,r,this),this.pos=e-1,this.writeVarint(r),this.pos+=r},writeFloat:function(t){this.realloc(4),Qe.write(this.buf,t,this.pos,!0,23,4),this.pos+=4},writeDouble:function(t){this.realloc(8),Qe.write(this.buf,t,this.pos,!0,52,8),this.pos+=8},writeBytes:function(t){var e=t.length;this.writeVarint(e),this.realloc(e);for(var r=0;r=128&&dr(r,i,this),this.pos=r-1,this.writeVarint(i),this.pos+=i},writeMessage:function(t,e,r){this.writeTag(t,F.Bytes),this.writeRawMessage(e,r)},writePackedVarint:function(t,e){e.length&&this.writeMessage(t,Ui,e)},writePackedSVarint:function(t,e){e.length&&this.writeMessage(t,ji,e)},writePackedBoolean:function(t,e){e.length&&this.writeMessage(t,Zi,e)},writePackedFloat:function(t,e){e.length&&this.writeMessage(t,Ni,e)},writePackedDouble:function(t,e){e.length&&this.writeMessage(t,qi,e)},writePackedFixed32:function(t,e){e.length&&this.writeMessage(t,Wi,e)},writePackedSFixed32:function(t,e){e.length&&this.writeMessage(t,$i,e)},writePackedFixed64:function(t,e){e.length&&this.writeMessage(t,Hi,e)},writePackedSFixed64:function(t,e){e.length&&this.writeMessage(t,Ki,e)},writeBytesField:function(t,e){this.writeTag(t,F.Bytes),this.writeBytes(e)},writeFixed32Field:function(t,e){this.writeTag(t,F.Fixed32),this.writeFixed32(e)},writeSFixed32Field:function(t,e){this.writeTag(t,F.Fixed32),this.writeSFixed32(e)},writeFixed64Field:function(t,e){this.writeTag(t,F.Fixed64),this.writeFixed64(e)},writeSFixed64Field:function(t,e){this.writeTag(t,F.Fixed64),this.writeSFixed64(e)},writeVarintField:function(t,e){this.writeTag(t,F.Varint),this.writeVarint(e)},writeSVarintField:function(t,e){this.writeTag(t,F.Varint),this.writeSVarint(e)},writeStringField:function(t,e){this.writeTag(t,F.Bytes),this.writeString(e)},writeFloatField:function(t,e){this.writeTag(t,F.Fixed32),this.writeFloat(e)},writeDoubleField:function(t,e){this.writeTag(t,F.Fixed64),this.writeDouble(e)},writeBooleanField:function(t,e){this.writeVarintField(t,Boolean(e))}};function Ii(t,e,r){var i=r.buf,n,a;if(a=i[r.pos++],n=(a&112)>>4,a<128||(a=i[r.pos++],n|=(a&127)<<3,a<128)||(a=i[r.pos++],n|=(a&127)<<10,a<128)||(a=i[r.pos++],n|=(a&127)<<17,a<128)||(a=i[r.pos++],n|=(a&127)<<24,a<128)||(a=i[r.pos++],n|=(a&1)<<31,a<128))return we(t,n,e);throw new Error("Expected varint not more than 10 bytes")}function ae(t){return t.type===F.Bytes?t.readVarint()+t.pos:t.pos+1}function we(t,e,r){return r?e*4294967296+(t>>>0):(e>>>0)*4294967296+(t>>>0)}function Xi(t,e){var r,i;if(t>=0?(r=t%4294967296|0,i=t/4294967296|0):(r=~(-t%4294967296),i=~(-t/4294967296),r^4294967295?r=r+1|0:(r=0,i=i+1|0)),t>=18446744073709552e3||t<-18446744073709552e3)throw new Error("Given varint doesn't fit into 10 bytes");e.realloc(10),Vi(r,i,e),Yi(i,e)}function Vi(t,e,r){r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos++]=t&127|128,t>>>=7,r.buf[r.pos]=t&127}function Yi(t,e){var r=(t&7)<<4;e.buf[e.pos++]|=r|((t>>>=3)?128:0),!!t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),!!t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),!!t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),!!t&&(e.buf[e.pos++]=t&127|((t>>>=7)?128:0),!!t&&(e.buf[e.pos++]=t&127)))))}function dr(t,e,r){var i=e<=16383?1:e<=2097151?2:e<=268435455?3:Math.floor(Math.log(e)/(Math.LN2*7));r.realloc(i);for(var n=r.pos-1;n>=t;n--)r.buf[n+i]=r.buf[n]}function Ui(t,e){for(var r=0;r>>8,t[r+2]=e>>>16,t[r+3]=e>>>24}function cr(t,e){return(t[e]|t[e+1]<<8|t[e+2]<<16)+(t[e+3]<<24)}function Ji(t,e,r){for(var i="",n=e;n239?4:a>223?3:a>191?2:1;if(n+o>r)break;var l,u,f;o===1?a<128&&(s=a):o===2?(l=t[n+1],(l&192)==128&&(s=(a&31)<<6|l&63,s<=127&&(s=null))):o===3?(l=t[n+1],u=t[n+2],(l&192)==128&&(u&192)==128&&(s=(a&15)<<12|(l&63)<<6|u&63,(s<=2047||s>=55296&&s<=57343)&&(s=null))):o===4&&(l=t[n+1],u=t[n+2],f=t[n+3],(l&192)==128&&(u&192)==128&&(f&192)==128&&(s=(a&15)<<18|(l&63)<<12|(u&63)<<6|f&63,(s<=65535||s>=1114112)&&(s=null))),s===null?(s=65533,o=1):s>65535&&(s-=65536,i+=String.fromCharCode(s>>>10&1023|55296),s=56320|s&1023),i+=String.fromCharCode(s),n+=o}return i}function Gi(t,e,r){return fr.decode(t.subarray(e,r))}function Qi(t,e,r){for(var i=0,n,a;i55295&&n<57344)if(a)if(n<56320){t[r++]=239,t[r++]=191,t[r++]=189,a=n;continue}else n=a-55296<<10|n-56320|65536,a=null;else{n>56319||i+1===e.length?(t[r++]=239,t[r++]=191,t[r++]=189):a=n;continue}else a&&(t[r++]=239,t[r++]=191,t[r++]=189,a=null);n<128?t[r++]=n:(n<2048?t[r++]=n>>6|192:(n<65536?t[r++]=n>>12|224:(t[r++]=n>>18|240,t[r++]=n>>12&63|128),t[r++]=n>>6&63|128),t[r++]=n&63|128)}return r}});var jr=K((Ft,Mt)=>{(function(t,e){typeof Ft=="object"&&typeof Mt!="undefined"?Mt.exports=e():typeof define=="function"&&define.amd?define(e):(t=t||self).RBush=e()})(Ft,function(){"use strict";function t(h,m,p,b,y){(function g(v,_,k,S,D){for(;S>k;){if(S-k>600){var T=S-k+1,E=_-k+1,W=Math.log(T),$=.5*Math.exp(2*W/3),ie=.5*Math.sqrt(W*$*(T-$)/T)*(E-T/2<0?-1:1),V=Math.max(k,Math.floor(_-E*$/T+ie)),dt=Math.min(S,Math.floor(_+(T-E)*$/T+ie));g(v,_,V,dt,D)}var xe=v[_],ne=k,R=S;for(e(v,k,_),D(v[S],xe)>0&&e(v,k,S);ne0;)R--}D(v[k],xe)===0?e(v,k,R):e(v,++R,S),R<=_&&(k=R+1),_<=R&&(S=R-1)}})(h,m,p||0,b||h.length-1,y||r)}function e(h,m,p){var b=h[m];h[m]=h[p],h[p]=b}function r(h,m){return hm?1:0}var i=function(h){h===void 0&&(h=9),this._maxEntries=Math.max(4,h),this._minEntries=Math.max(2,Math.ceil(.4*this._maxEntries)),this.clear()};function n(h,m,p){if(!p)return m.indexOf(h);for(var b=0;b=h.minX&&m.maxY>=h.minY}function w(h){return{children:h,height:1,leaf:!0,minX:1/0,minY:1/0,maxX:-1/0,maxY:-1/0}}function z(h,m,p,b,y){for(var g=[m,p];g.length;)if(!((p=g.pop())-(m=g.pop())<=b)){var v=m+Math.ceil((p-m)/b/2)*b;t(h,v,m,p,y),g.push(m,v,v,p)}}return i.prototype.all=function(){return this._all(this.data,[])},i.prototype.search=function(h){var m=this.data,p=[];if(!x(h,m))return p;for(var b=this.toBBox,y=[];m;){for(var g=0;g=0&&y[m].children.length>this._maxEntries;)this._split(y,m),m--;this._adjustParentBBoxes(b,y,m)},i.prototype._split=function(h,m){var p=h[m],b=p.children.length,y=this._minEntries;this._chooseSplitAxis(p,y,b);var g=this._chooseSplitIndex(p,y,b),v=w(p.children.splice(g,p.children.length-g));v.height=p.height,v.leaf=p.leaf,a(p,this.toBBox),a(v,this.toBBox),m?h[m-1].children.push(v):this._splitRoot(p,v)},i.prototype._splitRoot=function(h,m){this.data=w([h,m]),this.data.height=h.height+1,this.data.leaf=!1,a(this.data,this.toBBox)},i.prototype._chooseSplitIndex=function(h,m,p){for(var b,y,g,v,_,k,S,D=1/0,T=1/0,E=m;E<=p-m;E++){var W=s(h,0,E,this.toBBox),$=s(h,E,p,this.toBBox),ie=(y=W,g=$,v=void 0,_=void 0,k=void 0,S=void 0,v=Math.max(y.minX,g.minX),_=Math.max(y.minY,g.minY),k=Math.min(y.maxX,g.maxX),S=Math.min(y.maxY,g.maxY),Math.max(0,k-v)*Math.max(0,S-_)),V=f(W)+f($);ie=m;D--){var T=h.children[D];o(v,h.leaf?y(T):T),_+=d(v)}return _},i.prototype._adjustParentBBoxes=function(h,m,p){for(var b=p;b>=0;b--)o(m[b],h)},i.prototype._condense=function(h){for(var m=h.length-1,p=void 0;m>=0;m--)h[m].children.length===0?m>0?(p=h[m-1].children).splice(p.indexOf(h[m]),1):this.clear():a(h[m],this.toBBox)},i})});var Kr=K(()=>{});var Jr=K((Pt,Dt)=>{(function(t,e){typeof Pt=="object"&&typeof Dt!="undefined"?Dt.exports=e():typeof define=="function"&&define.amd?define(e):(t=t||self,t.TinyQueue=e())})(Pt,function(){"use strict";var t=function(i,n){if(i===void 0&&(i=[]),n===void 0&&(n=e),this.data=i,this.length=this.data.length,this.compare=n,this.length>0)for(var a=(this.length>>1)-1;a>=0;a--)this._down(a)};t.prototype.push=function(i){this.data.push(i),this.length++,this._up(this.length-1)},t.prototype.pop=function(){if(this.length!==0){var i=this.data[0],n=this.data.pop();return this.length--,this.length>0&&(this.data[0]=n,this._down(0)),i}},t.prototype.peek=function(){return this.data[0]},t.prototype._up=function(i){for(var n=this,a=n.data,s=n.compare,o=a[i];i>0;){var l=i-1>>1,u=a[l];if(s(o,u)>=0)break;a[i]=u,i=l}a[i]=o},t.prototype._down=function(i){for(var n=this,a=n.data,s=n.compare,o=this.length>>1,l=a[i];i=0)break;a[i]=f,i=u}a[i]=l};function e(r,i){return ri?1:0}return t})});var Qr=K((Ua,At)=>{"use strict";var ot=Jr();ot.default&&(ot=ot.default);At.exports=Gr;At.exports.default=Gr;function Gr(t,e,r){e=e||1;for(var i,n,a,s,o=0;oa)&&(a=l[0]),(!o||l[1]>s)&&(s=l[1])}var u=a-i,f=s-n,d=Math.min(u,f),c=d/2;if(d===0){var x=[i,n];return x.distance=0,x}for(var w=new ot(void 0,Wn),z=i;zm.d&&(m=p);for(var b=w.length;w.length;){var y=w.pop();y.d>m.d&&(m=y,r&&console.log("found best %d after %d probes",Math.round(1e4*y.d)/1e4,b)),!(y.max-m.d<=e)&&(c=y.h/2,w.push(new fe(y.x-c,y.y-c,c,t)),w.push(new fe(y.x+c,y.y-c,c,t)),w.push(new fe(y.x-c,y.y+c,c,t)),w.push(new fe(y.x+c,y.y+c,c,t)),b+=4)}r&&(console.log("num probes: "+b),console.log("best distance: "+m.d));var g=[m.x,m.y];return g.distance=m.d,g}function Wn(t,e){return e.max-t.max}function fe(t,e,r,i){this.x=t,this.y=e,this.h=r,this.d=$n(t,e,i),this.max=this.d+this.h*Math.SQRT2}function $n(t,e,r){for(var i=!1,n=1/0,a=0;ae!=d[1]>e&&t<(d[0]-f[0])*(e-f[1])/(d[1]-f[1])+f[0]&&(i=!i),n=Math.min(n,Kn(t,e,f,d))}return n===0?0:(i?1:-1)*Math.sqrt(n)}function Hn(t){for(var e=0,r=0,i=0,n=t[0],a=0,s=n.length,o=s-1;a1?(n=i[0],a=i[1]):l>0&&(n+=s*l,a+=o*l)}return s=t-n,o=e-a,s*s+o*o}});var fa={};ki(fa,{CenteredSymbolizer:()=>It,CenteredTextSymbolizer:()=>U,CircleSymbolizer:()=>te,FlexSymbolizer:()=>$e,Font:()=>Ut,GeomType:()=>ee,GroupSymbolizer:()=>ye,IconSymbolizer:()=>li,Index:()=>Ct,Justify:()=>X,Labeler:()=>Ue,Labelers:()=>je,LineLabelPlacement:()=>Me,LineLabelSymbolizer:()=>ce,LineSymbolizer:()=>C,OffsetSymbolizer:()=>Xt,OffsetTextSymbolizer:()=>le,PMTiles:()=>rt,Padding:()=>hi,PmtilesSource:()=>Oe,PolygonLabelSymbolizer:()=>ue,PolygonSymbolizer:()=>A,Sheet:()=>gi,ShieldSymbolizer:()=>lt,Static:()=>pi,TextPlacements:()=>P,TextSymbolizer:()=>He,TileCache:()=>st,Toner:()=>ha,View:()=>St,ZxySource:()=>it,arr:()=>de,covering:()=>Zr,createPattern:()=>Ot,cubicBezier:()=>ta,dark:()=>Se,exp:()=>j,filterFn:()=>Je,getFont:()=>qt,getZoom:()=>Vt,isCCW:()=>Ir,isInRing:()=>Lt,json_style:()=>ua,labelRules:()=>Te,leafletLayer:()=>oa,light:()=>Le,linear:()=>ea,numberFn:()=>ft,numberOrFn:()=>jt,paintRules:()=>Ce,painter:()=>Ye,pointInPolygon:()=>Xr,pointMinDistToLines:()=>Yr,pointMinDistToPoints:()=>Vr,sourcesToViews:()=>Ve,step:()=>Qn,toIndex:()=>oe,transformGeom:()=>Ie,widthFn:()=>Nt,wrap:()=>Xe});var he=N(re());var pe=N(re());var ke=N(re()),Ar=N(lr()),Br=N(pr());var Y=(t,e,r)=>new Promise((i,n)=>{var a=l=>{try{o(r.next(l))}catch(u){n(u)}},s=l=>{try{o(r.throw(l))}catch(u){n(u)}},o=l=>l.done?i(l.value):Promise.resolve(l.value).then(a,s);o((r=r.apply(t,e)).next())}),q=Uint8Array,me=Uint16Array,yr=Uint32Array,xr=new q([0,0,0,0,0,0,0,0,1,1,1,1,2,2,2,2,3,3,3,3,4,4,4,4,5,5,5,5,0,0,0,0]),gr=new q([0,0,0,0,1,1,2,2,3,3,4,4,5,5,6,6,7,7,8,8,9,9,10,10,11,11,12,12,13,13,0,0]),en=new q([16,17,18,0,8,7,9,6,10,5,11,4,12,3,13,2,14,1,15]),br=function(t,e){for(var r=new me(31),i=0;i<31;++i)r[i]=e+=1<>>1|(M&21845)<<1,se=(se&52428)>>>2|(se&13107)<<2,se=(se&61680)>>>4|(se&3855)<<4,bt[M]=((se&65280)>>>8|(se&255)<<8)>>>1;var se,M,Ae=function(t,e,r){for(var i=t.length,n=0,a=new me(e);n>>l]=u}else for(o=new me(i),n=0;n>>15-t[n]);return o},Be=new q(288);for(M=0;M<144;++M)Be[M]=8;var M;for(M=144;M<256;++M)Be[M]=9;var M;for(M=256;M<280;++M)Be[M]=7;var M;for(M=280;M<288;++M)Be[M]=8;var M,zr=new q(32);for(M=0;M<32;++M)zr[M]=5;var M,nn=Ae(Be,9,1),an=Ae(zr,5,1),wt=function(t){for(var e=t[0],r=1;re&&(e=t[r]);return e},J=function(t,e,r){var i=e/8|0;return(t[i]|t[i+1]<<8)>>(e&7)&r},vt=function(t,e){var r=e/8|0;return(t[r]|t[r+1]<<8|t[r+2]<<16)>>(e&7)},sn=function(t){return(t+7)/8|0},on=function(t,e,r){(e==null||e<0)&&(e=0),(r==null||r>t.length)&&(r=t.length);var i=new(t.BYTES_PER_ELEMENT==2?me:t.BYTES_PER_ELEMENT==4?yr:q)(r-e);return i.set(t.subarray(e,r)),i},ln=["unexpected EOF","invalid block type","invalid length/literal","invalid distance","stream finished","no stream handler",,"no callback","invalid UTF-8 data","extra field too long","date not in range 1980-2099","filename too long","stream finishing","invalid zip data"],G=function(t,e,r){var i=new Error(e||ln[t]);if(i.code=t,Error.captureStackTrace&&Error.captureStackTrace(i,G),!r)throw i;return i},_t=function(t,e,r){var i=t.length;if(!i||r&&r.f&&!r.l)return e||new q(0);var n=!e||r,a=!r||r.i;r||(r={}),e||(e=new q(i*3));var s=function($t){var Ht=e.length;if($t>Ht){var Kt=new q(Math.max(Ht*2,$t));Kt.set(e),e=Kt}},o=r.f||0,l=r.p||0,u=r.b||0,f=r.l,d=r.d,c=r.m,x=r.n,w=i*8;do{if(!f){o=J(t,l,1);var z=J(t,l+1,3);if(l+=3,z)if(z==1)f=nn,d=an,c=9,x=5;else if(z==2){var b=J(t,l,31)+257,y=J(t,l+10,15)+4,g=b+J(t,l+5,31)+1;l+=14;for(var v=new q(g),_=new q(19),k=0;k>>4;if(h<16)v[k++]=h;else{var W=0,$=0;for(h==16?($=3+J(t,l,3),l+=2,W=v[k-1]):h==17?($=3+J(t,l,7),l+=3):h==18&&($=11+J(t,l,127),l+=7);$--;)v[k++]=W}}var ie=v.subarray(0,b),V=v.subarray(b);c=wt(ie),x=wt(V),f=Ae(ie,c,1),d=Ae(V,x,1)}else G(1);else{var h=sn(l)+4,m=t[h-4]|t[h-3]<<8,p=h+m;if(p>i){a&&G(0);break}n&&s(u+m),e.set(t.subarray(h,p),u),r.b=u+=m,r.p=l=p*8,r.f=o;continue}if(l>w){a&&G(0);break}}n&&s(u+131072);for(var dt=(1<>>4;if(l+=W&15,l>w){a&&G(0);break}if(W||G(2),R<256)e[u++]=R;else if(R==256){ne=l,f=null;break}else{var Zt=R-254;if(R>264){var k=R-257,Pe=xr[k];Zt=J(t,l,(1<>>4;ct||G(3),l+=ct&15;var V=rn[mt];if(mt>3){var Pe=gr[mt];V+=vt(t,l)&(1<w){a&&G(0);break}n&&s(u+131072);for(var Wt=u+Zt;u>3&1)+(e>>4&1);i>0;i-=!t[r++]);return r+(e&2)},fn=function(t){var e=t.length;return(t[e-4]|t[e-3]<<8|t[e-2]<<16|t[e-1]<<24)>>>0},dn=function(t){((t[0]&15)!=8||t[0]>>>4>7||(t[0]<<8|t[1])%31)&&G(6,"invalid zlib data"),t[1]&32&&G(6,"invalid zlib data: preset dictionaries not supported")};function cn(t,e){return _t(t,e)}function mn(t,e){return _t(t.subarray(hn(t),-8),e||new q(fn(t)))}function pn(t,e){return _t((dn(t),t.subarray(2,-4)),e)}function zt(t,e){return t[0]==31&&t[1]==139&&t[2]==8?mn(t,e):(t[0]&15)!=8||t[0]>>4>7||(t[0]<<8|t[1])%31?cn(t,e):pn(t,e)}var yn=typeof TextDecoder!="undefined"&&new TextDecoder,xn=0;try{yn.decode(un,{stream:!0}),xn=1}catch(t){}var kr=(t,e)=>t*Math.pow(2,e),Ee=(t,e)=>Math.floor(t/Math.pow(2,e)),tt=(t,e)=>kr(t.getUint16(e+1,!0),8)+t.getUint8(e),Lr=(t,e)=>kr(t.getUint32(e+2,!0),16)+t.getUint16(e,!0),gn=(t,e,r,i,n)=>{if(t!=i.getUint8(n))return t-i.getUint8(n);let a=tt(i,n+1);if(e!=a)return e-a;let s=tt(i,n+4);return r!=s?r-s:0},bn=(t,e,r,i)=>{let n=Fr(t,e|128,r,i);return n?{z:e,x:r,y:i,offset:n[0],length:n[1],is_dir:!0}:null},Sr=(t,e,r,i)=>{let n=Fr(t,e,r,i);return n?{z:e,x:r,y:i,offset:n[0],length:n[1],is_dir:!1}:null},Fr=(t,e,r,i)=>{let n=0,a=t.byteLength/17-1;for(;n<=a;){let s=a+n>>1,o=gn(e,r,i,t,s*17);if(o>0)n=s+1;else if(o<0)a=s-1;else return[Lr(t,s*17+7),t.getUint32(s*17+13,!0)]}return null},wn=(t,e)=>t.is_dir&&!e.is_dir?1:!t.is_dir&&e.is_dir?-1:t.z!==e.z?t.z-e.z:t.x!==e.x?t.x-e.x:t.y-e.y,Mr=(t,e)=>{let r=t.getUint8(e*17);return{z:r&127,x:tt(t,e*17+1),y:tt(t,e*17+4),offset:Lr(t,e*17+7),length:t.getUint32(e*17+13,!0),is_dir:r>>7==1}},Cr=t=>{let e=[],r=new DataView(t);for(let i=0;i{t.sort(wn);let e=new ArrayBuffer(17*t.length),r=new Uint8Array(e);for(let i=0;i>8&255,r[i*17+3]=n.x>>16&255,r[i*17+4]=n.y&255,r[i*17+5]=n.y>>8&255,r[i*17+6]=n.y>>16&255,r[i*17+7]=n.offset&255,r[i*17+8]=Ee(n.offset,8)&255,r[i*17+9]=Ee(n.offset,16)&255,r[i*17+10]=Ee(n.offset,24)&255,r[i*17+11]=Ee(n.offset,32)&255,r[i*17+12]=Ee(n.offset,48)&255,r[i*17+13]=n.length&255,r[i*17+14]=n.length>>8&255,r[i*17+15]=n.length>>16&255,r[i*17+16]=n.length>>24&255}return e},_n=(t,e)=>{if(t.byteLength<17)return null;let r=t.byteLength/17,i=Mr(t,r-1);if(i.is_dir){let n=i.z,a=e.z-n,s=Math.trunc(e.x/(1<>>0)*4294967296+(t>>>0)}function Ln(t,e){let r=e.buf,i,n;if(n=r[e.pos++],i=(n&112)>>4,n<128||(n=r[e.pos++],i|=(n&127)<<3,n<128)||(n=r[e.pos++],i|=(n&127)<<10,n<128)||(n=r[e.pos++],i|=(n&127)<<17,n<128)||(n=r[e.pos++],i|=(n&127)<<24,n<128)||(n=r[e.pos++],i|=(n&1)<<31,n<128))return _e(t,i);throw new Error("Expected varint not more than 10 bytes")}function Re(t){let e=t.buf,r,i;return i=e[t.pos++],r=i&127,i<128||(i=e[t.pos++],r|=(i&127)<<7,i<128)||(i=e[t.pos++],r|=(i&127)<<14,i<128)||(i=e[t.pos++],r|=(i&127)<<21,i<128)?r:(i=e[t.pos],r|=(i&15)<<28,Ln(r,t))}function Sn(t,e,r,i){if(i==0){r==1&&(e[0]=t-1-e[0],e[1]=t-1-e[1]);let n=e[0];e[0]=e[1],e[1]=n}}function Fn(t,e,r){if(t>26)throw Error("Tile zoom level exceeds max safe number limit (26)");if(e>Math.pow(2,t)-1||r>Math.pow(2,t)-1)throw Error("tile x/y outside zoom level bounds");let i=0,n=0;for(;n0;)s=(u[0]&f)>0?1:0,o=(u[1]&f)>0?1:0,l+=f*f*(3*s^o),Sn(f,u,s,o),f=f/2;return i+l}function Pr(t,e){return Y(this,null,function*(){if(e===1||e===0)return t;if(e===2)return zt(new Uint8Array(t));throw Error("Compression method not supported")})}var Mn=127;function Cn(t,e){let r=0,i=t.length-1;for(;r<=i;){let n=i+r>>1,a=e-t[n].tileId;if(a>0)r=n+1;else if(a<0)i=n-1;else return t[n]}return i>=0&&(t[i].runLength===0||e-t[i].tileId=300)throw Error("Bad response code: "+n.status);let a=n.headers.get("Content-Length");if(n.status===200&&(!a||+a>e))throw i&&i.abort(),Error("Server returned no content-length header or content-length exceeding request. Check that your storage backend supports HTTP Byte Serving.");return{data:yield n.arrayBuffer(),etag:n.headers.get("ETag")||void 0,cacheControl:n.headers.get("Cache-Control")||void 0,expires:n.headers.get("Expires")||void 0}})}};function Q(t,e){let r=t.getUint32(e+4,!0),i=t.getUint32(e+0,!0);return r*Math.pow(2,32)+i}function Pn(t,e){let r=new DataView(t),i=r.getUint8(7);if(i>3)throw Error(`Archive is spec version ${i} but this library supports up to spec version 3`);return{specVersion:i,rootDirectoryOffset:Q(r,8),rootDirectoryLength:Q(r,16),jsonMetadataOffset:Q(r,24),jsonMetadataLength:Q(r,32),leafDirectoryOffset:Q(r,40),leafDirectoryLength:Q(r,48),tileDataOffset:Q(r,56),tileDataLength:Q(r,64),numAddressedTiles:Q(r,72),numTileEntries:Q(r,80),numTileContents:Q(r,88),clustered:r.getUint8(96)===1,internalCompression:r.getUint8(97),tileCompression:r.getUint8(98),tileType:r.getUint8(99),minZoom:r.getUint8(100),maxZoom:r.getUint8(101),minLon:r.getInt32(102,!0)/1e7,minLat:r.getInt32(106,!0)/1e7,maxLon:r.getInt32(110,!0)/1e7,maxLat:r.getInt32(114,!0)/1e7,centerZoom:r.getUint8(118),centerLon:r.getInt32(119,!0)/1e7,centerLat:r.getInt32(123,!0)/1e7,etag:e}}function Dr(t){let e={buf:new Uint8Array(t),pos:0},r=Re(e),i=[],n=0;for(let a=0;a0?i[a].offset=i[a-1].offset+i[a-1].length:i[a].offset=s-1}return i}function Dn(t){let e=new DataView(t);return e.getUint16(2,!0)===2?(console.warn("PMTiles spec version 2 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"),2):e.getUint16(2,!0)===1?(console.warn("PMTiles spec version 1 has been deprecated; please see github.com/protomaps/PMTiles for tools to upgrade"),1):3}var ze=class extends Error{};function An(t,e,r,i){return Y(this,null,function*(){let n=yield t.getBytes(0,16384);if(new DataView(n.data).getUint16(0,!0)!==19792)throw new Error("Wrong magic number for PMTiles archive");if(Dn(n.data)<3)return[yield Tr.getHeader(t)];let s=n.data.slice(0,Mn),o=n.etag;i&&n.etag!=i&&(console.warn("ETag conflict detected; your HTTP server might not support content-based ETag headers. ETags disabled for "+t.getKey()),o=void 0);let l=Pn(s,o);if(r){let u=n.data.slice(l.rootDirectoryOffset,l.rootDirectoryOffset+l.rootDirectoryLength),f=t.getKey()+"|"+(l.etag||"")+"|"+l.rootDirectoryOffset+"|"+l.rootDirectoryLength,d=Dr(yield e(u,l.internalCompression));return[l,[f,d.length,d]]}return[l,void 0]})}function Bn(t,e,r,i,n){return Y(this,null,function*(){let a=yield t.getBytes(r,i);if(n.etag&&n.etag!==a.etag)throw new ze(a.etag);let s=yield e(a.data,n.internalCompression),o=Dr(s);if(o.length===0)throw new Error("Empty directory is invalid");return o})}var En=class{constructor(t=100,e=!0,r=Pr){this.cache=new Map,this.maxCacheEntries=t,this.counter=1,this.prefetch=e,this.decompress=r}getHeader(t,e){return Y(this,null,function*(){let r=t.getKey();if(this.cache.has(r))return this.cache.get(r).lastUsed=this.counter++,yield this.cache.get(r).data;let i=new Promise((n,a)=>{An(t,this.decompress,this.prefetch,e).then(s=>{s[1]&&this.cache.set(s[1][0],{lastUsed:this.counter++,data:Promise.resolve(s[1][2])}),n(s[0]),this.prune()}).catch(s=>{a(s)})});return this.cache.set(r,{lastUsed:this.counter++,data:i}),i})}getDirectory(t,e,r,i){return Y(this,null,function*(){let n=t.getKey()+"|"+(i.etag||"")+"|"+e+"|"+r;if(this.cache.has(n))return this.cache.get(n).lastUsed=this.counter++,yield this.cache.get(n).data;let a=new Promise((s,o)=>{Bn(t,this.decompress,e,r,i).then(l=>{s(l),this.prune()}).catch(l=>{o(l)})});return this.cache.set(n,{lastUsed:this.counter++,data:a}),a})}getArrayBuffer(t,e,r,i){return Y(this,null,function*(){let n=t.getKey()+"|"+(i.etag||"")+"|"+e+"|"+r;if(this.cache.has(n))return this.cache.get(n).lastUsed=this.counter++,yield this.cache.get(n).data;let a=new Promise((s,o)=>{t.getBytes(e,r).then(l=>{if(i.etag&&i.etag!==l.etag)throw new ze(l.etag);s(l.data),this.cache.has(n),this.prune()}).catch(l=>{o(l)})});return this.cache.set(n,{lastUsed:this.counter++,data:a}),a})}prune(){if(this.cache.size>=this.maxCacheEntries){let t=1/0,e;this.cache.forEach((r,i)=>{r.lastUseda.maxZoom)return;let s=a.rootDirectoryOffset,o=a.rootDirectoryLength;for(let l=0;l<=3;l++){let u=yield this.cache.getDirectory(this.source,s,o,a),f=Cn(u,n);if(f)if(f.runLength>0){let d=yield this.source.getBytes(a.tileDataOffset+f.offset,f.length,i);if(a.etag&&a.etag!==d.etag)throw new ze(d.etag);return{data:yield this.decompress(d.data,a.tileCompression),cacheControl:d.cacheControl,expires:d.expires}}else s=a.leafDirectoryOffset+f.offset,o=f.length;else return}throw Error("Maximum directory depth exceeded")})}getZxy(t,e,r,i){return Y(this,null,function*(){try{return yield this.getZxyAttempt(t,e,r,i)}catch(n){if(n instanceof ze)return this.cache.invalidate(this.source,n.message),yield this.getZxyAttempt(t,e,r,i);throw n}})}getMetadataAttempt(){return Y(this,null,function*(){let t=yield this.cache.getHeader(this.source),e=yield this.source.getBytes(t.jsonMetadataOffset,t.jsonMetadataLength);if(t.etag&&t.etag!==e.etag)throw new ze(e.etag);let r=yield this.decompress(e.data,t.internalCompression),i=new TextDecoder("utf-8");return JSON.parse(i.decode(r))})}getMetadata(){return Y(this,null,function*(){try{return yield this.getMetadataAttempt()}catch(t){if(t instanceof ze)return this.cache.invalidate(this.source,t.message),yield this.getMetadataAttempt();throw t}})}};var ee;(function(i){i[i.Point=1]="Point",i[i.Line=2]="Line",i[i.Polygon=3]="Polygon"})(ee||(ee={}));function oe(t){return t.x+":"+t.y+":"+t.z}var Rn=(t,e,r)=>{t.pos=e;for(var i=t.readVarint()+t.pos,n=1,a=0,s=0,o=0,l=1/0,u=-1/0,f=1/0,d=-1/0,c=[],x=[];t.pos>3}if(a--,n===1||n===2)s+=t.readSVarint()*r,o+=t.readSVarint()*r,su&&(u=s),od&&(d=o),n===1&&(x.length>0&&c.push(x),x=[]),x.push(new ke.default(s,o));else if(n===7)x&&x.push(x[0].clone());else throw new Error("unknown command "+n)}return x&&c.push(x),{geom:c,bbox:{minX:l,minY:f,maxX:u,maxY:d}}};function Er(t,e){let r=new Ar.VectorTile(new Br.default(t)),i=new Map;for(let[n,a]of Object.entries(r.layers)){let s=[],o=a;for(let l=0;ls[0]!=e.z?(s[1].abort(),!1):!0));let i=new AbortController;this.controllers.push([e.z,i]);let n=i.signal,a=yield this.p.getZxy(e.z,e.x,e.y,n);return a?Er(a.data,r):new Map})}},it=class{constructor(e,r){this.url=e,this.controllers=[],this.shouldCancelZooms=r}get(e,r){return O(this,null,function*(){this.shouldCancelZooms&&(this.controllers=this.controllers.filter(s=>s[0]!=e.z?(s[1].abort(),!1):!0));let i=this.url.replace("{z}",e.z.toString()).replace("{x}",e.x.toString()).replace("{y}",e.y.toString()),n=new AbortController;this.controllers.push([e.z,n]);let a=n.signal;return new Promise((s,o)=>{fetch(i,{signal:a}).then(l=>l.arrayBuffer()).then(l=>{let u=Er(l,r);s(u)}).catch(l=>{o(l)})})})}},kt=6378137,Rr=85.0511287798,nt=kt*Math.PI,On=t=>{let e=Math.PI/180,r=Math.max(Math.min(Rr,t[0]),-Rr),i=Math.sin(r*e);return new ke.default(kt*t[1]*e,kt*Math.log((1+i)/(1-i))/2)};function Or(t){return t*t}function at(t,e){return Or(t.x-e.x)+Or(t.y-e.y)}function In(t,e,r){var i=at(e,r);if(i===0)return at(t,e);var n=((t.x-e.x)*(r.x-e.x)+(t.y-e.y)*(r.y-e.y))/i;return n=Math.max(0,Math.min(1,n)),at(t,new ke.default(e.x+n*(r.x-e.x),e.y+n*(r.y-e.y)))}function Lt(t,e){for(var r=!1,i=0,n=e.length-1;it.y!=l>t.y&&t.x<(o-a)*(t.y-s)/(l-s)+a;u&&(r=!r)}return r}function Ir(t){for(var e=0,r=0;r1&&(s.x=s.x-Math.floor(s.x));let o=s.mult(1<{let a=this.cache.get(r);if(a)a.used=performance.now(),i(a.data);else{let s=this.inflight.get(r);s?s.push([i,n]):(this.inflight.set(r,[]),this.source.get(e,this.tileSize).then(o=>{this.cache.set(r,{used:performance.now(),data:o});let l=this.inflight.get(r);if(l&&l.forEach(u=>u[0](o)),this.inflight.delete(r),i(o),this.cache.size>=64){let u=1/0,f;this.cache.forEach((d,c)=>{d.used{let l=this.inflight.get(r);l&&l.forEach(u=>u[1](o)),this.inflight.delete(r),n(o)}))}})})}};var Ie=(t,e,r)=>{let i=[];for(let n of t){let a=[];for(let s of n)a.push(s.clone().mult(e).add(r));i.push(a)}return i},Xe=(t,e)=>{let r=1<=r&&(t=t%r),t},St=class{constructor(e,r,i){this.tileCache=e,this.maxDataLevel=r,this.levelDiff=i}dataTilesForBounds(e,r){let i=Math.pow(2,e)/Math.pow(2,Math.ceil(e)),n=[];var a=1,s=this.tileCache.tileSize;if(ethis.tileCache.get(a.data_tile)))).map((a,s)=>{let o=i[s];return{data:a,z:e,data_tile:o.data_tile,scale:o.scale,dim:o.dim,origin:o.origin}})})}getDisplayTile(e){return O(this,null,function*(){let r=this.dataTileForDisplayTile(e);return{data:yield this.tileCache.get(r.data_tile),z:e.z,data_tile:r.data_tile,scale:r.scale,origin:r.origin,dim:r.dim}})}queryFeatures(e,r,i){let n=Math.round(i),a=Math.min(n-this.levelDiff,this.maxDataLevel),s=16/(1<{let e=i=>{let n=i.levelDiff===void 0?2:i.levelDiff,a=i.maxDataZoom||14,s;typeof i.url=="string"?i.url.endsWith(".pmtiles")?s=new Oe(i.url,!0):s=new it(i.url,!0):s=new Oe(i.url,!0);let o=new st(s,256*1<f.maxzoom)continue;let w=r.get(f.dataSource||"");if(!!w)for(let z of w){var d=z.data.get(f.dataLayer);if(d===void 0)continue;f.symbolizer.before&&f.symbolizer.before(t,z.z);let h=z.origin,m=z.dim,p=z.scale;if(t.save(),o){t.beginPath();let b=Math.max(h.x-s.x,a.minX-s.x),y=Math.max(h.y-s.y,a.minY-s.y),g=Math.min(h.x-s.x+m,a.maxX-s.x),v=Math.min(h.y-s.y+m,a.maxY-s.y);t.rect(b,y,g-b,v-y),t.clip()}t.translate(h.x-s.x,h.y-s.y);for(var c of d){let b=c.geom,y=c.bbox;y.maxX*p+h.xa.maxX||y.minY*p+h.y>a.maxY||y.maxY*p+h.y{let i=256,n=e/i,a=Math.floor(r.minX/i),s=Math.floor(r.minY/i),o=Math.floor(r.maxX/i),l=Math.floor(r.maxY/i),u=Math.log2(n),f=[];for(let d=a;d<=o;d++){let c=d%(1<this.dim&&(o=!0)}if(s||o){var u=s?this.dim:-this.dim,f=[];for(let x of e.bboxes)f.push({minX:x.minX+u,minY:x.minY,maxX:x.maxX+u,maxY:x.maxY});let d={anchor:new Nr.default(e.anchor.x+u,e.anchor.y),bboxes:f,draw:e.draw,order:r,tileKey:i},c=this.current.get(i);c&&c.add(d);for(let x of f){var l=x;l.indexed_label=d,this.tree.insert(l)}}}pruneOrNoop(e){let r=e.split(":"),i,n=0,a=0;for(var s of this.current.keys()){let o=s.split(":");if(o[3]===r[3]){a++;let l=Math.sqrt(Math.pow(+o[0]-+r[0],2)+Math.pow(+o[1]-+r[1],2));l>n&&(n=l,i=s)}i&&a>this.maxLabeledTiles&&this.pruneKey(i)}}pruneKey(e){let r=this.current.get(e);if(!r)return;let i=[];for(let n of this.tree.all())r.has(n.indexed_label)&&i.push(n);i.forEach(n=>{this.tree.remove(n)}),this.current.delete(e)}removeLabel(e){let r=[];for(let n of this.tree.all())e==n.indexed_label&&r.push(n);r.forEach(n=>{this.tree.remove(n)});let i=this.current.get(e.tileKey);i&&i.delete(e)}},Ue=class{constructor(e,r,i,n,a){this.index=new Ct(256*1<l.maxzoom)continue;let u=l.dataSource||"",f=e.get(u);if(!!f)for(let d of f){let c=oe(d.data_tile)+":"+u;if(!i.has(c))continue;let x=d.data.get(l.dataLayer);if(x===void 0)continue;let w=x;l.sort&&w.sort((h,m)=>l.sort?l.sort(h.props,m.props):0);let z={index:this.index,zoom:this.z,scratch:this.scratch,order:o,overzoom:this.z-d.data_tile.z};for(let h of w){if(l.filter&&!l.filter(this.z,h))continue;let m=Ie(h.geom,d.scale,d.origin),p=l.symbolizer.place(z,m,h);if(!!p)for(let b of p){var a=!1;if(!(b.deduplicationKey&&this.index.deduplicationCollides(b))){if(this.index.labelCollides(b,1/0)){if(!this.index.labelCollides(b,o)){let y=this.index.searchLabel(b,1/0);for(let g of y){this.index.removeLabel(g);for(let v of g.bboxes)this.findInvalidatedTiles(n,d.dim,v,c)}this.index.insert(b,o,c),a=!0}}else this.index.insert(b,o,c),a=!0;if(a)for(let y of b.bboxes)(y.maxX>d.origin.x+d.dim||y.minXd.origin.y+d.dim)&&this.findInvalidatedTiles(n,d.dim,y,c)}}}}}for(var s of i)this.index.pruneOrNoop(s);return n.size>0&&this.callback&&this.callback(n),performance.now()-r}findInvalidatedTiles(e,r,i,n){let a=Zr(this.z,r,i);for(let s of a)s.key!=n&&this.index.hasPrefix(s.key)&&e.add(s.display)}add(e){var r=!0;for(let[i,n]of e)for(let a of n)this.index.has(oe(a.data_tile)+":"+i)||(r=!1);return r?0:this.layout(e)}},je=class{constructor(e,r,i,n){this.labelers=new Map,this.scratch=e,this.labelRules=r,this.maxLabeledTiles=i,this.callback=n}add(e,r){var i=this.labelers.get(e);return i||(i=new Ue(e,this.scratch,this.labelRules,this.maxLabeledTiles,this.callback),this.labelers.set(e,i)),i.add(r)}getIndex(e){let r=this.labelers.get(e);if(r)return r.index}};var Le={earth:"#FFFBF6",glacier:"#ffffff",residential:"#F4F4F8",hospital:"#FFF6F6",cemetery:"#EFF2EE",school:"#F7F6FF",industrial:"#FFF9EF",wood:"#F4F9EF",grass:"#EBF9E3",park:"#E5F9D5",water:"#B7DFF2",sand:"#ebebeb",buildings:"#F2EDE8",highwayCasing:"#FFC3C3",majorRoadCasing:"#FFB9B9",mediumRoadCasing:"#FFCE8E",minorRoadCasing:"#cccccc",highway:"#FFCEBB",majorRoad:"#FFE4B3",mediumRoad:"#FFF2C8",minorRoad:"#ffffff",boundaries:"#9e9e9e",mask:"#dddddd",countryLabel:"#aaaaaa",cityLabel:"#6C6C6C",stateLabel:"#999999",neighbourhoodLabel:"#888888",landuseLabel:"#898989",waterLabel:"#41ABDC",naturalLabel:"#4B8F14",roadsLabel:"#888888",poisLabel:"#606060"};var Se={earth:"#151515",glacier:"#1c1c1c",residential:"#252B2F",hospital:"#3E2C2C",cemetery:"#36483D",school:"#2C3440",industrial:"#33312C",wood:"#3A3E38",grass:"#4E604D",park:"#2C4034",water:"#4D5B73",sand:"#777777",buildings:"#464545",highwayCasing:"#000000",majorRoadCasing:"#1C1B1B",mediumRoadCasing:"#3E3E3E",minorRoadCasing:"#000000",highway:"#5B5B5B",majorRoad:"#595959",mediumRoad:"#4F4F4F",minorRoad:"#393939",boundaries:"#666666",mask:"#dddddd",countryLabel:"#ffffff",cityLabel:"#FFFFFF",stateLabel:"#ffffff",neighbourhoodLabel:"#FDFDFD",landuseLabel:"#DDDDDD",waterLabel:"#707E95",naturalLabel:"#4c4c4c",roadsLabel:"#C4C4C4",poisLabel:"#959393"};function Ne(t,e,r){return Math.min(Math.max(t,r),e)}var Fe=class extends Error{constructor(e){super(`Failed to parse color: "${e}"`)}};function Xn(t){if(typeof t!="string")throw new Fe(t);if(t.trim().toLowerCase()==="transparent")return[0,0,0,0];let e=t.trim();e=qn.test(t)?function(s){let o=s.toLowerCase().trim(),l=Vn[function(u){let f=5381,d=u.length;for(;d;)f=33*f^u.charCodeAt(--d);return(f>>>0)%2341}(o)];if(!l)throw new Fe(s);return`#${l}`}(t):t;let r=Yn.exec(e);if(r){let s=Array.from(r).slice(1);return[...s.slice(0,3).map(o=>parseInt(qe(o,2),16)),parseInt(qe(s[3]||"f",2),16)/255]}let i=Un.exec(e);if(i){let s=Array.from(i).slice(1);return[...s.slice(0,3).map(o=>parseInt(o,16)),parseInt(s[3]||"ff",16)/255]}let n=jn.exec(e);if(n){let s=Array.from(n).slice(1);return[...s.slice(0,3).map(o=>parseInt(o,10)),parseFloat(s[3]||"1")]}let a=Nn.exec(e);if(a){let[s,o,l,u]=Array.from(a).slice(1).map(parseFloat);if(Ne(0,100,o)!==o)throw new Fe(t);if(Ne(0,100,l)!==l)throw new Fe(t);return[...Zn(s,o,l),u||1]}throw new Fe(t)}var Wr=t=>parseInt(t.replace(/_/g,""),36),Vn="1q29ehhb 1n09sgk7 1kl1ekf_ _yl4zsno 16z9eiv3 1p29lhp8 _bd9zg04 17u0____ _iw9zhe5 _to73___ _r45e31e _7l6g016 _jh8ouiv _zn3qba8 1jy4zshs 11u87k0u 1ro9yvyo 1aj3xael 1gz9zjz0 _3w8l4xo 1bf1ekf_ _ke3v___ _4rrkb__ 13j776yz _646mbhl _nrjr4__ _le6mbhl 1n37ehkb _m75f91n _qj3bzfz 1939yygw 11i5z6x8 _1k5f8xs 1509441m 15t5lwgf _ae2th1n _tg1ugcv 1lp1ugcv 16e14up_ _h55rw7n _ny9yavn _7a11xb_ 1ih442g9 _pv442g9 1mv16xof 14e6y7tu 1oo9zkds 17d1cisi _4v9y70f _y98m8kc 1019pq0v 12o9zda8 _348j4f4 1et50i2o _8epa8__ _ts6senj 1o350i2o 1mi9eiuo 1259yrp0 1ln80gnw _632xcoy 1cn9zldc _f29edu4 1n490c8q _9f9ziet 1b94vk74 _m49zkct 1kz6s73a 1eu9dtog _q58s1rz 1dy9sjiq __u89jo3 _aj5nkwg _ld89jo3 13h9z6wx _qa9z2ii _l119xgq _bs5arju 1hj4nwk9 1qt4nwk9 1ge6wau6 14j9zlcw 11p1edc_ _ms1zcxe _439shk6 _jt9y70f _754zsow 1la40eju _oq5p___ _x279qkz 1fa5r3rv _yd2d9ip _424tcku _8y1di2_ _zi2uabw _yy7rn9h 12yz980_ __39ljp6 1b59zg0x _n39zfzp 1fy9zest _b33k___ _hp9wq92 1il50hz4 _io472ub _lj9z3eo 19z9ykg0 _8t8iu3a 12b9bl4a 1ak5yw0o _896v4ku _tb8k8lv _s59zi6t _c09ze0p 1lg80oqn 1id9z8wb _238nba5 1kq6wgdi _154zssg _tn3zk49 _da9y6tc 1sg7cv4f _r12jvtt 1gq5fmkz 1cs9rvci _lp9jn1c _xw1tdnb 13f9zje6 16f6973h _vo7ir40 _bt5arjf _rc45e4t _hr4e100 10v4e100 _hc9zke2 _w91egv_ _sj2r1kk 13c87yx8 _vqpds__ _ni8ggk8 _tj9yqfb 1ia2j4r4 _7x9b10u 1fc9ld4j 1eq9zldr _5j9lhpx _ez9zl6o _md61fzm".split(" ").reduce((t,e)=>{let r=Wr(e.substring(0,3)),i=Wr(e.substring(3)).toString(16),n="";for(let a=0;a<6-i.length;a++)n+="0";return t[r]=`${n}${i}`,t},{}),qe=(t,e)=>Array.from(Array(e)).map(()=>t).join(""),Yn=new RegExp(`^#${qe("([a-f0-9])",3)}([a-f0-9])?$`,"i"),Un=new RegExp(`^#${qe("([a-f0-9]{2})",3)}([a-f0-9]{2})?$`,"i"),jn=new RegExp(`^rgba?\\(\\s*(\\d+)\\s*${qe(",\\s*(\\d+)\\s*",2)}(?:,\\s*([\\d.]+))?\\s*\\)$`,"i"),Nn=/^hsla?\(\s*([\d.]+)\s*,\s*([\d.]+)%\s*,\s*([\d.]+)%(?:\s*,\s*([\d.]+))?\s*\)$/i,qn=/^[a-z]+$/i,$r=t=>Math.round(255*t),Zn=(t,e,r)=>{let i=r/100;if(e===0)return[i,i,i].map($r);let n=(t%360+360)%360/60,a=(1-Math.abs(2*i-1))*(e/100),s=a*(1-Math.abs(n%2-1)),o=0,l=0,u=0;n>=0&&n<1?(o=a,l=s):n>=1&&n<2?(o=s,l=a):n>=2&&n<3?(l=a,u=s):n>=3&&n<4?(l=s,u=a):n>=4&&n<5?(o=s,u=a):n>=5&&n<6&&(o=a,u=s);let f=i-a/2;return[o+f,l+f,u+f].map($r)};function Tt(t){let[e,r,i,n]=Xn(t).map((u,f)=>f===3?u:u/255),a=Math.max(e,r,i),s=Math.min(e,r,i),o=(a+s)/2;if(a===s)return[0,0,o,n];let l=a-s;return[60*(e===a?(r-i)/l+(r.5?l/(2-a-s):l/(a+s),o,n]}function Hr(t,e,r,i){return`hsla(${(t%360).toFixed()}, ${Ne(0,100,100*e).toFixed()}%, ${Ne(0,100,100*r).toFixed()}%, ${parseFloat(Ne(0,1,i).toFixed(3))})`}var Z=N(re()),ri=N(Kr()),ii=N(Qr());var I=class{constructor(e,r){this.str=e!=null?e:r,this.per_feature=typeof this.str=="function"&&this.str.length==2}get(e,r){return typeof this.str=="function"?this.str(e,r):this.str}},B=class{constructor(e,r=1){this.value=e!=null?e:r,this.per_feature=typeof this.value=="function"&&this.value.length==2}get(e,r){return typeof this.value=="function"?this.value(e,r):this.value}},Ze=class{constructor(e){var r;this.label_props=(r=e==null?void 0:e.label_props)!=null?r:["name"],this.textTransform=e==null?void 0:e.textTransform}get(e,r){let i,n;typeof this.label_props=="function"?n=this.label_props(e,r):n=this.label_props;for(let s of n)if(r.props.hasOwnProperty(s)&&typeof r.props[s]=="string"){i=r.props[s];break}let a;return typeof this.textTransform=="function"?a=this.textTransform(e,r):a=this.textTransform,i&&a==="uppercase"?i=i.toUpperCase():i&&a==="lowercase"?i=i.toLowerCase():i&&a==="capitalize"&&(i=i.toLowerCase().split(" ").map(l=>l[0].toUpperCase()+l.slice(1)).join(" ")),i}},We=class{constructor(e){var r,i;(e==null?void 0:e.font)?this.font=e.font:(this.family=(r=e==null?void 0:e.fontFamily)!=null?r:"sans-serif",this.size=(i=e==null?void 0:e.fontSize)!=null?i:12,this.weight=e==null?void 0:e.fontWeight,this.style=e==null?void 0:e.fontStyle)}get(e,r){if(this.font)return typeof this.font=="function"?this.font(e,r):this.font;var i="";this.style&&(typeof this.style=="function"?i=this.style(e,r)+" ":i=this.style+" ");var n="";this.weight&&(typeof this.weight=="function"?n=this.weight(e,r)+" ":n=this.weight+" ");var a;typeof this.size=="function"?a=this.size(e,r):a=this.size;var s;return typeof this.family=="function"?s=this.family(e,r):s=this.family,`${i}${n}${a}px ${s}`}},Bt=class{constructor(e,r=[]){this.value=e!=null?e:r,this.per_feature=typeof this.value=="function"&&this.value.length==2}get(e,r){return typeof this.value=="function"?this.value(e,r):this.value}};var Et=N(re()),Jn=(t,e,r)=>{var i=[],n,a,s,o=0,l=0,u=0,f=0,d=0,c=0,x=0,w=0,z=0,h=0,m=0,p=0;if(t.length<2)return[];if(t.length===2)return u=Math.sqrt(Math.pow(t[1].x-t[0].x,2)+Math.pow(t[1].y-t[0].y,2)),[{length:u,beginIndex:0,beginDistance:0,endIndex:2,endDistance:u}];for(f=Math.sqrt(Math.pow(t[1].x-t[0].x,2)+Math.pow(t[1].y-t[0].y,2)),o=1,l=t.length-1;oe||u-p>r)&&(i.push({length:u-p,beginDistance:p,beginIndex:m,endIndex:o+1,endDistance:u}),m=o,p=u),f=d;return o-m>0&&i.push({length:u-p+d,beginIndex:m,beginDistance:p,endIndex:o+1,endDistance:u+d}),i};function ei(t,e,r,i){let n,a,s=0,o=[];var l=-1/0;for(let f of t){let d=Jn(f,Math.PI/45,e);for(let c of d)if(c.length>=e+i){let x=new Et.default(f[c.beginIndex].x,f[c.beginIndex].y),w=f[c.endIndex-1],z=new Et.default((w.x-x.x)/c.length,(w.y-x.y)/c.length);for(var u=i;u=0&&r-i{let i=document.createElement("canvas"),n=i.getContext("2d");return i.width=t,i.height=e,n!==null&&r(i,n),i},A=class{constructor(e){var r;this.pattern=e.pattern,this.fill=new I(e.fill,"black"),this.opacity=new B(e.opacity,1),this.stroke=new I(e.stroke,"black"),this.width=new B(e.width,0),this.per_feature=(r=this.fill.per_feature||this.opacity.per_feature||this.stroke.per_feature||this.width.per_feature||e.per_feature)!=null?r:!1,this.do_stroke=!1}before(e,r){if(!this.per_feature){e.globalAlpha=this.opacity.get(r),e.fillStyle=this.fill.get(r),e.strokeStyle=this.stroke.get(r);let i=this.width.get(r);i>0&&(this.do_stroke=!0),e.lineWidth=i}if(this.pattern){let i=e.createPattern(this.pattern,"repeat");i&&(e.fillStyle=i)}}draw(e,r,i,n){var a=!1;if(this.per_feature){e.globalAlpha=this.opacity.get(i,n),e.fillStyle=this.fill.get(i,n);var s=this.width.get(i,n);s&&(a=!0,e.strokeStyle=this.stroke.get(i,n),e.lineWidth=s)}let o=()=>{e.fill(),(a||this.do_stroke)&&e.stroke()};var l=0;e.beginPath();for(var u of r){l+u.length>ni&&(o(),l=0,e.beginPath());for(var f=0;f0&&o()}};function de(t,e){return r=>{let i=r-t;return i>=0&&i{if(e.length<1)return 0;if(r<=e[0][0])return e[0][1];if(r>=e[e.length-1][0])return e[e.length-1][1];let i=ai(r,e),n=oi(r,i,t,e);return si(n,e[i][1],e[i+1][1])}}function Qn(t,e){return r=>{if(e.length<1)return 0;let i=t;for(let n=0;n=e[n][0]&&(i=e[n][1]);return i}}function ea(t){return j(1,t)}function ta(t,e,r,i,n){return a=>{if(n.length<1)return 0;let s=new ri.default(t,e,r,i),o=ai(a,n),l=s.solve(oi(a,o,1,n));return si(l,n[o][1],n[o+1][1])}}var C=class{constructor(e){var r;this.color=new I(e.color,"black"),this.width=new B(e.width),this.opacity=new B(e.opacity),this.dash=e.dash?new Bt(e.dash):null,this.dashColor=new I(e.dashColor,"black"),this.dashWidth=new B(e.dashWidth,1),this.lineCap=new I(e.lineCap,"butt"),this.lineJoin=new I(e.lineJoin,"miter"),this.skip=!1,this.per_feature=!!(((r=this.dash)==null?void 0:r.per_feature)||this.color.per_feature||this.opacity.per_feature||this.width.per_feature||this.lineCap.per_feature||this.lineJoin.per_feature||e.per_feature)}before(e,r){this.per_feature||(e.strokeStyle=this.color.get(r),e.lineWidth=this.width.get(r),e.globalAlpha=this.opacity.get(r),e.lineCap=this.lineCap.get(r),e.lineJoin=this.lineJoin.get(r))}draw(e,r,i,n){if(this.skip)return;let a=()=>{this.per_feature&&(e.globalAlpha=this.opacity.get(i,n),e.lineCap=this.lineCap.get(i,n),e.lineJoin=this.lineJoin.get(i,n)),this.dash?(e.save(),this.per_feature?(e.lineWidth=this.dashWidth.get(i,n),e.strokeStyle=this.dashColor.get(i,n),e.setLineDash(this.dash.get(i,n))):e.setLineDash(this.dash.get(i)),e.stroke(),e.restore()):(e.save(),this.per_feature&&(e.lineWidth=this.width.get(i,n),e.strokeStyle=this.color.get(i,n)),e.stroke(),e.restore())};var s=0;e.beginPath();for(var o of r){s+o.length>ni&&(a(),s=0,e.beginPath());for(var l=0;l0&&a()}},li=class{constructor(e){this.name=e.name,this.sheet=e.sheet,this.dpr=window.devicePixelRatio}place(e,r,i){let n=r[0],a=new Z.default(r[0][0].x,r[0][0].y),s=this.sheet.get(this.name),o=s.w/this.dpr,l=s.h/this.dpr,u={minX:a.x-o/2,minY:a.y-l/2,maxX:a.x+o/2,maxY:a.y+l/2};return[{anchor:a,bboxes:[u],draw:d=>{d.globalAlpha=1,d.drawImage(this.sheet.canvas,s.x,s.y,s.w,s.h,-s.w/2/this.dpr,-s.h/2/this.dpr,s.w/2,s.h/2)}}]}},te=class{constructor(e){this.radius=new B(e.radius,3),this.fill=new I(e.fill,"black"),this.stroke=new I(e.stroke,"white"),this.width=new B(e.width,0),this.opacity=new B(e.opacity)}draw(e,r,i,n){e.globalAlpha=this.opacity.get(i,n);let a=this.radius.get(i,n),s=this.width.get(i,n);s>0&&(e.strokeStyle=this.stroke.get(i,n),e.lineWidth=s,e.beginPath(),e.arc(r[0][0].x,r[0][0].y,a+s/2,0,2*Math.PI),e.stroke()),e.fillStyle=this.fill.get(i,n),e.beginPath(),e.arc(r[0][0].x,r[0][0].y,a,0,2*Math.PI),e.fill()}place(e,r,i){let n=r[0],a=new Z.default(r[0][0].x,r[0][0].y),s=this.radius.get(e.zoom,i),o={minX:a.x-s,minY:a.y-s,maxX:a.x+s,maxY:a.y+s};return[{anchor:a,bboxes:[o],draw:u=>{this.draw(u,[[new Z.default(0,0)]],e.zoom,i)}}]}},lt=class{constructor(e){this.font=new We(e),this.text=new Ze(e),this.fill=new I(e.fill,"black"),this.background=new I(e.background,"white"),this.padding=new B(e.padding,0)}place(e,r,i){let n=this.text.get(e.zoom,i);if(!n)return;let a=this.font.get(e.zoom,i);e.scratch.font=a;let s=e.scratch.measureText(n),o=s.width,l=s.actualBoundingBoxAscent,u=s.actualBoundingBoxDescent,f=r[0],d=new Z.default(r[0][0].x,r[0][0].y),c=this.padding.get(e.zoom,i),x={minX:d.x-o/2-c,minY:d.y-l-c,maxX:d.x+o/2+c,maxY:d.y+u+c};return[{anchor:d,bboxes:[x],draw:z=>{z.globalAlpha=1,z.fillStyle=this.background.get(e.zoom,i),z.fillRect(-o/2-c,-l-c,o+2*c,l+u+2*c),z.fillStyle=this.fill.get(e.zoom,i),z.font=a,z.fillText(n,-o/2,0)}}]}},$e=class{constructor(e){this.list=e}place(e,r,i){var n=this.list[0].place(e,r,i);if(!n)return;var a=n[0];let s=a.anchor,o=a.bboxes[0],l=o.maxY-o.minY,u=[{draw:a.draw,translate:{x:0,y:0}}],f=[[new Z.default(r[0][0].x,r[0][0].y+l)]];for(let c=1;c{for(let x of u)c.save(),c.translate(x.translate.x,x.translate.y),x.draw(c),c.restore()}}]}},ui=(t,e)=>({minX:Math.min(t.minX,e.minX),minY:Math.min(t.minY,e.minY),maxX:Math.max(t.maxX,e.maxX),maxY:Math.max(t.maxY,e.maxY)}),ye=class{constructor(e){this.list=e}place(e,r,i){let n=this.list[0];if(!n)return;var a=n.place(e,r,i);if(!a)return;var s=a[0];let o=s.anchor,l=s.bboxes[0],u=[s.draw];for(let d=1;d{u.forEach(c=>c(d))}}]}},It=class{constructor(e){this.symbolizer=e}place(e,r,i){let n=r[0][0],a=this.symbolizer.place(e,[[new Z.default(0,0)]],i);if(!a||a.length==0)return;let s=a[0],o=s.bboxes[0],l=o.maxX-o.minX,u=o.maxY-o.minY,f={minX:n.x-l/2,maxX:n.x+l/2,minY:n.y-u/2,maxY:n.y+u/2};return[{anchor:n,bboxes:[f],draw:c=>{c.translate(-l/2,u/2-o.maxY),s.draw(c,{justify:2})}}]}},hi=class{constructor(e,r){this.padding=new B(e,0),this.symbolizer=r}place(e,r,i){let n=this.symbolizer.place(e,r,i);if(!n||n.length==0)return;let a=this.padding.get(e.zoom,i);for(var s of n)for(var o of s.bboxes)o.minX-=a,o.minY-=a,o.maxX+=a,o.maxY+=a;return n}},He=class{constructor(e){this.font=new We(e),this.text=new Ze(e),this.fill=new I(e.fill,"black"),this.stroke=new I(e.stroke,"black"),this.width=new B(e.width,0),this.lineHeight=new B(e.lineHeight,1),this.letterSpacing=new B(e.letterSpacing,0),this.maxLineCodeUnits=new B(e.maxLineChars,15),this.justify=e.justify}place(e,r,i){let n=this.text.get(e.zoom,i);if(!n)return;let a=this.font.get(e.zoom,i);e.scratch.font=a;let s=this.letterSpacing.get(e.zoom,i),o=Rt(n,this.maxLineCodeUnits.get(e.zoom,i));var l="",u=0;for(let p of o)p.length>u&&(u=p.length,l=p);let f=e.scratch.measureText(l),d=f.width+s*(u-1),c=f.actualBoundingBoxAscent,x=f.actualBoundingBoxDescent,w=(c+x)*this.lineHeight.get(e.zoom,i),z=new Z.default(r[0][0].x,r[0][0].y),h={minX:z.x,minY:z.y-c,maxX:z.x+d,maxY:z.y+x+(o.length-1)*w};return[{anchor:z,bboxes:[h],draw:(p,b)=>{p.globalAlpha=1,p.font=a,p.fillStyle=this.fill.get(e.zoom,i);let y=this.width.get(e.zoom,i);var g=0;for(let S of o){var v=0;if(this.justify==2||b&&b.justify==2?v=(d-p.measureText(S).width)/2:(this.justify==3||b&&b.justify==3)&&(v=d-p.measureText(S).width),y)if(p.lineWidth=y*2,p.strokeStyle=this.stroke.get(e.zoom,i),s>0){var _=v;for(var k of S)p.strokeText(k,_,g),_+=p.measureText(k).width+s}else p.strokeText(S,v,g);if(s>0){var _=v;for(var k of S)p.fillText(k,_,g),_+=p.measureText(k).width+s}else p.fillText(S,v,g);g+=w}}}]}},U=class{constructor(e){this.centered=new It(new He(e))}place(e,r,i){return this.centered.place(e,r,i)}},Xt=class{constructor(e,r){var i,n,a;this.symbolizer=e,this.offsetX=new B(r.offsetX,0),this.offsetY=new B(r.offsetY,0),this.justify=(i=r.justify)!=null?i:void 0,this.placements=(n=r.placements)!=null?n:[2,6,8,4,1,3,5,7],this.ddValues=(a=r.ddValues)!=null?a:()=>({})}place(e,r,i){if(i.geomType!==ee.Point)return;let n=r[0][0],a=this.symbolizer.place(e,[[new Z.default(0,0)]],i);if(!a||a.length==0)return;let s=a[0],o=s.bboxes[0],l=this.offsetX,u=this.offsetY,f=this.justify,d=this.placements,{offsetX:c,offsetY:x,justify:w,placements:z}=this.ddValues(e.zoom,i)||{};c&&(l=new B(c,0)),x&&(u=new B(x,0)),w&&(f=w),z&&(d=z);let h=l.get(e.zoom,i),m=u.get(e.zoom,i),p=(_,k)=>({minX:_.x+k.x+o.minX,minY:_.y+k.y+o.minY,maxX:_.x+k.x+o.maxX,maxY:_.y+k.y+o.maxY});var b=new Z.default(h,m),y;let g=_=>{_.translate(b.x,b.y),s.draw(_,{justify:y})},v=(_,k)=>{let S=p(_,k);if(!e.index.bboxCollides(S,e.order))return[{anchor:n,bboxes:[S],draw:g}]};for(let _ of d){let k=this.computeXAxisOffset(h,o,_),S=this.computeYAxisOffset(m,o,_);return y=this.computeJustify(f,_),b=new Z.default(k,S),v(n,b)}}computeXAxisOffset(e,r,i){let n=r.maxX,a=n/2;return[1,5].includes(i)?e-a:[8,7,6].includes(i)?e-n:e}computeYAxisOffset(e,r,i){let n=Math.abs(r.minY),a=r.maxY,s=(r.minY+r.maxY)/2;return[3,7].includes(i)?e-s:[8,2,1].includes(i)?e-a:[6,4,5].includes(i)?e+n:e}computeJustify(e,r){return e||([1,5].includes(r)?2:[2,3,4].includes(r)?1:3)}},le=class{constructor(e){this.symbolizer=new Xt(new He(e),e)}place(e,r,i){return this.symbolizer.place(e,r,i)}},Me;(function(i){i[i.Above=1]="Above",i[i.Center=2]="Center",i[i.Below=3]="Below"})(Me||(Me={}));var ce=class{constructor(e){var r;this.font=new We(e),this.text=new Ze(e),this.fill=new I(e.fill,"black"),this.stroke=new I(e.stroke,"black"),this.width=new B(e.width,0),this.offset=new B(e.offset,0),this.position=(r=e.position)!=null?r:1,this.maxLabelCodeUnits=new B(e.maxLabelChars,40),this.repeatDistance=new B(e.repeatDistance,250)}place(e,r,i){let n=this.text.get(e.zoom,i);if(!n||n.length>this.maxLabelCodeUnits.get(e.zoom,i))return;let a=20,s=i.bbox;if(s.maxY-s.minY4&&(d*=1<({minX:g.x-c/2,minY:g.y-c/2,maxX:g.x+c/2,maxY:g.y+c/2})),y=g=>{g.globalAlpha=1,g.rotate(Math.atan2(m,h)),h<0&&(g.scale(-1,-1),g.translate(-u,0));let v=0;this.position===3?v+=f:this.position===2&&(v+=f/2),g.translate(0,v-this.offset.get(e.zoom,i)),g.font=o;let _=this.width.get(e.zoom,i);_&&(g.lineWidth=_,g.strokeStyle=this.stroke.get(e.zoom,i),g.strokeText(n,0,0)),g.fillStyle=this.fill.get(e.zoom,i),g.fillText(n,0,0)};w.push({anchor:z.start,bboxes:b,draw:y,deduplicationKey:n,deduplicationDistance:d})}return w}},ue=class{constructor(e){this.symbolizer=new He(e)}place(e,r,i){let n=i.bbox;if((n.maxY-n.minY)*(n.maxX-n.minX)<2e4)return;let s=this.symbolizer.place(e,[[new Z.default(0,0)]],i);if(!s||s.length==0)return;let o=s[0],l=o.bboxes[0],u=r[0],f=(0,ii.default)([u.map(w=>[w.x,w.y])]),d=new Z.default(f[0],f[1]),c={minX:d.x-(l.maxX-l.minX)/2,minY:d.y-(l.maxY-l.minY)/2,maxX:d.x+(l.maxX-l.minX)/2,maxY:d.y+(l.maxY-l.minY)/2};return[{anchor:d,bboxes:[c],draw:w=>{w.translate(o.anchor.x-(l.maxX-l.minX)/2,o.anchor.y),o.draw(w)}}]}};var fi=(t,e)=>{let r=Tt(e),i=er({},t);for(let[n,a]of Object.entries(t)){let s=Tt(a);i[n]=Hr(r[0],r[1],s[2],s[3])}return i},Ce=(t,e)=>(e&&(t=fi(t,e)),[{dataLayer:"earth",symbolizer:new A({fill:t.earth})},{dataLayer:"natural",symbolizer:new A({fill:t.glacier}),filter:(r,i)=>i.props.natural=="glacier"},{dataLayer:"landuse",symbolizer:new A({fill:t.residential}),filter:(r,i)=>i.props.landuse=="residential"||i.props.place=="neighbourhood"},{dataLayer:"landuse",symbolizer:new A({fill:t.hospital}),filter:(r,i)=>i.props.amenity=="hospital"},{dataLayer:"landuse",symbolizer:new A({fill:t.cemetery}),filter:(r,i)=>i.props.landuse=="cemetery"},{dataLayer:"landuse",symbolizer:new A({fill:t.school}),filter:(r,i)=>i.props.amenity=="school"||i.props.amenity=="kindergarten"||i.props.amenity=="university"||i.props.amenity=="college"},{dataLayer:"landuse",symbolizer:new A({fill:t.industrial}),filter:(r,i)=>i.props.landuse=="industrial"},{dataLayer:"natural",symbolizer:new A({fill:t.wood}),filter:(r,i)=>i.props.natural=="wood"},{dataLayer:"landuse",symbolizer:new A({fill:t.grass}),filter:(r,i)=>i.props.landuse=="grass"},{dataLayer:"landuse",symbolizer:new A({fill:t.park}),filter:(r,i)=>i.props.leisure=="park"},{dataLayer:"water",symbolizer:new A({fill:t.water})},{dataLayer:"natural",symbolizer:new A({fill:t.sand}),filter:(r,i)=>i.props.natural=="sand"},{dataLayer:"buildings",symbolizer:new A({fill:t.buildings})},{dataLayer:"roads",symbolizer:new C({color:t.highwayCasing,width:j(1.4,[[5,1.5],[11,4],[16,9],[20,40]])}),filter:(r,i)=>i.props["pmap:kind"]=="highway"},{dataLayer:"roads",symbolizer:new C({color:t.majorRoadCasing,width:j(1.4,[[9,3],[12,4],[17,8],[20,22]])}),filter:(r,i)=>i.props["pmap:kind"]=="major_road"},{dataLayer:"roads",symbolizer:new C({color:t.mediumRoadCasing,width:j(1.4,[[13,3],[17,6],[20,18]])}),filter:(r,i)=>i.props["pmap:kind"]=="medium_road"},{dataLayer:"roads",symbolizer:new C({color:t.minorRoadCasing,width:j(1.4,[[14,2],[17,5],[20,15]])}),filter:(r,i)=>i.props["pmap:kind"]=="minor_road"},{dataLayer:"roads",symbolizer:new C({color:t.minorRoad,width:j(1.4,[[14,1],[17,3],[20,13]])}),filter:(r,i)=>i.props["pmap:kind"]=="minor_road"},{dataLayer:"roads",symbolizer:new C({color:t.mediumRoad,width:j(1.4,[[13,2],[17,4],[20,15]])}),filter:(r,i)=>i.props["pmap:kind"]=="medium_road"},{dataLayer:"roads",symbolizer:new C({color:t.majorRoad,width:j(1.4,[[9,2],[12,3],[17,6],[20,20]])}),filter:(r,i)=>i.props["pmap:kind"]=="major_road"},{dataLayer:"roads",symbolizer:new C({color:t.highway,width:j(1.4,[[5,.5],[11,2.5],[16,7],[20,30]])}),filter:(r,i)=>i.props["pmap:kind"]=="highway"},{dataLayer:"boundaries",symbolizer:new C({color:t.boundaries,width:2,opacity:.4})},{dataLayer:"mask",symbolizer:new A({fill:t.mask})}]),Te=(t,e,r,i)=>{e&&(t=fi(t,e));var n=["name"];r&&(n=r);let a=(s,o)=>i?s instanceof le?new $e([s,new le({fill:o,label_props:i})]):new $e([s,new U({fill:o,label_props:i})]):s;return[{dataLayer:"places",symbolizer:a(new U({label_props:n,fill:t.countryLabel,lineHeight:1.5,font:(s,o)=>s<6?"200 14px sans-serif":"200 20px sans-serif",textTransform:"uppercase"}),t.countryLabel),filter:(s,o)=>o.props["pmap:kind"]=="country"},{dataLayer:"places",symbolizer:a(new U({label_props:n,fill:t.stateLabel,font:"300 16px sans-serif"}),t.stateLabel),filter:(s,o)=>o.props["pmap:kind"]=="state"},{id:"cities_high",dataLayer:"places",filter:(s,o)=>o.props["pmap:kind"]=="city",minzoom:7,symbolizer:a(new U({label_props:n,fill:t.cityLabel,font:(s,o)=>(o==null?void 0:o.props["pmap:rank"])===1?s>8?"600 20px sans-serif":"600 12px sans-serif":s>8?"600 16px sans-serif":"600 10px sans-serif"}),t.cityLabel),sort:(s,o)=>s["pmap:rank"]-o["pmap:rank"]},{id:"cities_low",dataLayer:"places",filter:(s,o)=>o.props["pmap:kind"]=="city",maxzoom:6,symbolizer:new ye([new te({radius:2,fill:t.cityLabel}),a(new le({label_props:n,fill:t.cityLabel,offsetX:2,offsetY:2,font:(s,o)=>(o==null?void 0:o.props["pmap:rank"])===1?s>8?"600 20px sans-serif":"600 12px sans-serif":s>8?"600 16px sans-serif":"600 10px sans-serif"}),t.cityLabel)]),sort:(s,o)=>s["pmap:rank"]-o["pmap:rank"]},{id:"neighbourhood",dataLayer:"places",symbolizer:a(new U({label_props:n,fill:t.neighbourhoodLabel,font:"500 10px sans-serif",textTransform:"uppercase"}),t.neighbourhoodLabel),filter:(s,o)=>o.props["pmap:kind"]=="neighbourhood"},{dataLayer:"landuse",symbolizer:a(new ue({label_props:n,fill:t.landuseLabel,font:"300 12px sans-serif"}),t.landuseLabel)},{dataLayer:"water",symbolizer:a(new ue({label_props:n,fill:t.waterLabel,font:"italic 600 12px sans-serif"}),t.waterLabel)},{dataLayer:"natural",symbolizer:a(new ue({label_props:n,fill:t.naturalLabel,font:"italic 300 12px sans-serif"}),t.naturalLabel)},{dataLayer:"roads",symbolizer:a(new ce({label_props:n,fill:t.roadsLabel,font:"500 12px sans-serif"}),t.roadsLabel),minzoom:12},{dataLayer:"roads",symbolizer:new lt({label_props:["ref"],font:"600 9px sans-serif",background:t.highway,padding:2,fill:t.neighbourhoodLabel}),filter:(s,o)=>o.props["pmap:kind"]=="highway"},{dataLayer:"pois",symbolizer:new ye([new te({radius:2,fill:t.poisLabel}),a(new le({label_props:n,fill:t.poisLabel,offsetX:2,offsetY:2,font:"300 10px sans-serif"}),t.poisLabel)])}]};var di=(t,e,r)=>[{dataSource:t,dataLayer:e,symbolizer:new te({opacity:.2,fill:r,radius:4}),filter:(i,n)=>n.geomType==ee.Point},{dataSource:t,dataLayer:e,symbolizer:new C({opacity:.2,color:r,width:2}),filter:(i,n)=>n.geomType==ee.Line},{dataSource:t,dataLayer:e,symbolizer:new A({opacity:.2,fill:r,stroke:r,width:1}),filter:(i,n)=>n.geomType==ee.Polygon}],ut=(t,e)=>{var r=[];for(var[i,n]of t)for(var a of n)for(var s of a.data.keys())i===e.dataSource&&s===e.dataLayer||(r=r.concat(di(i,s,"steelblue")));return r=r.concat(di(e.dataSource||"",e.dataLayer,"red")),r};var Ke=6378137,ci=85.0511287798,H=Ke*Math.PI,mi=t=>{let e=Math.PI/180,r=Math.max(Math.min(ci,t.y),-ci),i=Math.sin(r*e);return new he.default(Ke*t.x*e,Ke*Math.log((1+i)/(1-i))/2)},ra=t=>{var e=180/Math.PI;return{lat:(2*Math.atan(Math.exp(t.y/Ke))-Math.PI/2)*e,lng:t.x*e/Ke}},ia=(t,e)=>r=>{let i=mi(r);return new he.default((i.x+H)/(H*2),1-(i.y+H)/(H*2)).mult((1<r=>{let i=new he.default(r.x,r.y).add(t).div((1<{let r=e*(360/t);return Math.log2(r/256)},pi=class{constructor(e){let r=e.dark?Se:Le;this.paint_rules=e.paint_rules||Ce(r,e.shade),this.label_rules=e.label_rules||Te(r,e.shade,e.language1,e.language2),this.backgroundColor=e.backgroundColor,this.views=Ve(e),this.debug=e.debug||"",this.xray=e.xray}drawContext(e,r,i,n,a){return O(this,null,function*(){let s=mi(n),l=new he.default((s.x+H)/(H*2),1-(s.y+H)/(H*2)).clone().mult(Math.pow(2,a)*256).sub(new he.default(r/2,i/2)),u={minX:l.x,minY:l.y,maxX:l.x+r,maxY:l.y+i},f=[];for(let[p,b]of this.views){let y=b.getBbox(a,u);f.push({key:p,promise:y})}let d=yield Promise.all(f.map(p=>p.promise.then(b=>({status:"fulfilled",value:b,key:p.key}),b=>({status:"rejected",value:[],reason:b,key:p.key})))),c=new Map;for(let p of d)p.status==="fulfilled"&&c.set(p.key,p.value);let x=performance.now(),w=new Ue(a,e,this.label_rules,16,void 0),z=w.add(c);this.backgroundColor&&(e.save(),e.fillStyle=this.backgroundColor,e.fillRect(0,0,r,i),e.restore());let h=this.paint_rules;this.xray&&(h=ut(c,this.xray));let m=Ye(e,a,c,this.xray?null:w.index,h,u,l,!0,this.debug);if(this.debug){e.save(),e.translate(-l.x,-l.y),e.strokeStyle=this.debug,e.fillStyle=this.debug,e.font="12px sans-serif";let p=0;for(let[b,y]of c){for(let g of y){e.strokeRect(g.origin.x,g.origin.y,g.dim,g.dim);let v=g.data_tile;e.fillText(b+(b?" ":"")+v.z+" "+v.x+" "+v.y,g.origin.x+4,g.origin.y+14*(1+p))}p++}e.restore()}return{elapsed:performance.now()-x,project:ia(l,a),unproject:na(l,a)}})}drawCanvas(a,s,o){return O(this,arguments,function*(e,r,i,n={}){let l=window.devicePixelRatio,u=e.clientWidth,f=e.clientHeight;e.width==u*l&&e.height==f*l||(e.width=u*l,e.height=f*l),n.lang&&(e.lang=n.lang);let d=e.getContext("2d");return d.setTransform(l,0,0,l,0,0),this.drawContext(d,u,f,r,i)})}drawContextBounds(e,r,i,n,a){return O(this,null,function*(){let s=i.x-r.x,o=new he.default((r.x+i.x)/2,(r.y+i.y)/2);return this.drawContext(e,n,a,o,Vt(s,n))})}drawCanvasBounds(s,o,l,u){return O(this,arguments,function*(e,r,i,n,a={}){let f=i.x-r.x,d=new he.default((r.x+i.x)/2,(r.y+i.y)/2);return this.drawCanvas(e,d,Vt(f,n),a)})}};var yi=N(re());var aa=t=>new Promise((e,r)=>{setTimeout(()=>{e()},t)}),sa=t=>t.then(e=>({status:"fulfilled",value:e}),e=>({status:"rejected",reason:e})),oa=(t={})=>{class e extends L.GridLayer{constructor(i={}){i.noWrap&&!i.bounds&&(i.bounds=[[-90,-180],[90,180]]),i.attribution==null&&(i.attribution='Protomaps \xA9 OpenStreetMap'),super(i);let n=i.dark?Se:Le;this.paint_rules=i.paint_rules||Ce(n,i.shade),this.label_rules=i.label_rules||Te(n,i.shade,i.language1,i.language2),this.backgroundColor=i.backgroundColor,this.lastRequestedZ=void 0,this.xray=i.xray,this.tasks=i.tasks||[],this.views=Ve(i),this.debug=i.debug;let a=document.createElement("canvas").getContext("2d");this.scratch=a,this.onTilesInvalidated=s=>{s.forEach(o=>{this.rerenderTile(o)})},this.labelers=new je(this.scratch,this.label_rules,16,this.onTilesInvalidated),this.tile_size=256*window.devicePixelRatio,this.tileDelay=i.tileDelay||3,this.lang=i.lang,this.inspector=this.inspect(this)}setDefaultStyle(i,n,a,s){let o=i?Se:Le;this.paint_rules=Ce(o,n),this.label_rules=Te(o,n,a,s)}renderTile(i,n,a,s=()=>{}){return O(this,null,function*(){this.lastRequestedZ=i.z;let o=[];for(let[_,k]of this.views){let S=k.getDisplayTile(i);o.push({key:_,promise:S})}let l=yield Promise.all(o.map(_=>_.promise.then(k=>({status:"fulfilled",value:k,key:_.key}),k=>({status:"rejected",reason:k,key:_.key})))),u=new Map;for(let _ of l)_.status==="fulfilled"?u.set(_.key,[_.value]):_.reason.name==="AbortError"||console.error(_.reason);if(n.key!=a||this.lastRequestedZ!==i.z||(yield Promise.all(this.tasks.map(sa)),n.key!=a)||this.lastRequestedZ!==i.z)return;let f=this.labelers.add(i.z,u);if(n.key!=a||this.lastRequestedZ!==i.z)return;let d=this.labelers.getIndex(i.z);if(!this._map)return;let c=this._map.getCenter().wrap(),x=this._getTiledPixelBounds(c),w=this._pxBoundsToTileRange(x),z=w.getCenter(),h=i.distanceTo(z)*this.tileDelay;if(yield aa(h),n.key!=a||this.lastRequestedZ!==i.z)return;let m=16,p={minX:256*i.x-m,minY:256*i.y-m,maxX:256*(i.x+1)+m,maxY:256*(i.y+1)+m},b=new yi.default(256*i.x,256*i.y);n.width=this.tile_size,n.height=this.tile_size;let y=n.getContext("2d");y.setTransform(this.tile_size/256,0,0,this.tile_size/256,0,0),y.clearRect(0,0,256,256),this.backgroundColor&&(y.save(),y.fillStyle=this.backgroundColor,y.fillRect(0,0,256,256),y.restore());var g=0;let v=this.paint_rules;if(this.xray&&(v=ut(u,this.xray)),g=Ye(y,i.z,u,this.xray?null:d,v,p,b,!1,this.debug),this.debug){y.save(),y.fillStyle=this.debug,y.font="600 12px sans-serif",y.fillText(i.z+" "+i.x+" "+i.y,4,14),y.font="12px sans-serif";let _=28;for(let[k,S]of u){let D=S[0].data_tile;y.fillText(k+(k?" ":"")+D.z+" "+D.x+" "+D.y,4,_),_+=14}y.font="600 10px sans-serif",g>8&&(y.fillText(g.toFixed()+" ms paint",4,_),_+=14),f>8&&y.fillText(f.toFixed()+" ms layout",4,_),y.strokeStyle=this.debug,y.lineWidth=.5,y.beginPath(),y.moveTo(0,0),y.lineTo(0,256),y.stroke(),y.lineWidth=.5,y.beginPath(),y.moveTo(0,0),y.lineTo(256,0),y.stroke(),y.restore()}s()})}rerenderTile(i){for(let n in this._tiles){let a=this._wrapCoords(this._keyToTileCoords(n));i===this._tileCoordsToKey(a)&&this.renderTile(a,this._tiles[n].el,i)}}clearLayout(){this.labelers=new je(this.scratch,this.label_rules,16,this.onTilesInvalidated)}rerenderTiles(){for(let i in this._tiles){let n=this._wrapCoords(this._keyToTileCoords(i)),a=this._tileCoordsToKey(n);this.renderTile(n,this._tiles[i].el,a)}}createTile(i,n){let a=L.DomUtil.create("canvas","leaflet-tile");a.lang=this.lang;let s=this._tileCoordsToKey(i);return a.key=s,this.renderTile(i,a,s,()=>{n(null,a)}),a}_removeTile(i){let n=this._tiles[i];!n||(n.el.removed=!0,n.el.key=void 0,L.DomUtil.removeClass(n.el,"leaflet-tile-loaded"),n.el.width=n.el.height=0,L.DomUtil.remove(n.el),delete this._tiles[i],this.fire("tileunload",{tile:n.el,coords:this._keyToTileCoords(i)}))}queryFeatures(i,n){let a=new Map;for(var[s,o]of this.views)a.set(s,o.queryFeatures(i,n,this._map.getZoom()));return a}inspect(i){return n=>{let a=["\u25CE","\u27CD","\u25FB"],s=i._map.wrapLatLng(n.latlng),o=i.queryFeatures(s.lng,s.lat);var l="";let u=!0;for(var[f,d]of o)for(var c of d)if(!(this.xray&&this.xray!==!0&&!((this.xray.dataSource||"")===f&&this.xray.dataLayer===c.layerName))){l=l+`
${a[c.feature.geomType-1]} ${f} ${f?"/":""} ${c.layerName} ${c.feature.id||""}
`;for(let x in c.feature.props)l=l+`
${x} = ${c.feature.props[x]}
`;u=!1}u&&(l="No features."),L.popup().setLatLng(n.latlng).setContent('
'+l+"
").openOn(i._map)}}addInspector(i){return i.on("click",this.inspector)}removeInspector(i){return i.off("click",this.inspector)}}return new e(t)};function Yt(t){let e=0,r=0;for(let o of t)e+=o.w*o.h,r=Math.max(r,o.w);t.sort((o,l)=>l.h-o.h);let i=Math.max(Math.ceil(Math.sqrt(e/.95)),r),n=[{x:0,y:0,w:i,h:1/0}],a=0,s=0;for(let o of t)for(let l=n.length-1;l>=0;l--){let u=n[l];if(!(o.w>u.w||o.h>u.h)){if(o.x=u.x,o.y=u.y,s=Math.max(s,o.y+o.h),a=Math.max(a,o.x+o.w),o.w===u.w&&o.h===u.h){let f=n.pop();l{let i=new FontFace(t,"url("+e+")",{weight:r});return document.fonts.add(i),i.load()},xi=t=>O(void 0,null,function*(){return new Promise((e,r)=>{let i=new Image;i.onload=()=>e(i),i.onerror=()=>r("Invalid SVG"),i.src=t})}),la=` + + + + + + +`,gi=class{constructor(e){this.src=e,this.canvas=document.createElement("canvas"),this.mapping=new Map,this.missingBox={x:0,y:0,w:0,h:0}}load(){return O(this,null,function*(){let e=this.src,r=window.devicePixelRatio;e.endsWith(".html")&&(e=yield(yield fetch(e)).text());let i=new window.DOMParser().parseFromString(e,"text/html"),n=Array.from(i.body.children),a=yield xi("data:image/svg+xml;base64,"+btoa(la)),s=[{w:a.width*r,h:a.height*r,img:a,id:""}],o=new XMLSerializer;for(let c of n){var l=btoa(o.serializeToString(c)),u="data:image/svg+xml;base64,"+l;let x=yield xi(u);s.push({w:x.width*r,h:x.height*r,img:x,id:c.id})}let f=Yt(s);this.canvas.width=f.w,this.canvas.height=f.h;let d=this.canvas.getContext("2d");if(d)for(let c of s)c.x!==void 0&&c.y!==void 0&&(d.drawImage(c.img,c.x,c.y,c.w,c.h),c.id?this.mapping.set(c.id,{x:c.x,y:c.y,w:c.w,h:c.h}):this.missingBox={x:c.x,y:c.y,w:c.w,h:c.h});return this})}get(e){let r=this.mapping.get(e);return r||(r=this.missingBox),r}};function ht(t,e){return typeof t=="number"?t:e}function Je(t){if(t.includes("$type"))return e=>!0;if(t[0]=="==")return(e,r)=>r.props[t[1]]===t[2];if(t[0]=="!=")return(e,r)=>r.props[t[1]]!==t[2];if(t[0]=="!"){let e=Je(t[1]);return(r,i)=>!e(r,i)}else{if(t[0]==="<")return(e,r)=>ht(r.props[t[1]],1/0)ht(r.props[t[1]],1/0)<=t[2];if(t[0]===">")return(e,r)=>ht(r.props[t[1]],-1/0)>t[2];if(t[0]===">=")return(e,r)=>ht(r.props[t[1]],-1/0)>=t[2];if(t[0]==="in")return(e,r)=>t.slice(2,t.length).includes(r.props[t[1]]);if(t[0]==="!in")return(e,r)=>!t.slice(2,t.length).includes(r.props[t[1]]);if(t[0]==="has")return(e,r)=>r.props.hasOwnProperty(t[1]);if(t[0]==="!has")return(e,r)=>!r.props.hasOwnProperty(t[1]);if(t[0]==="all"){let e=t.slice(1,t.length).map(r=>Je(r));return(r,i)=>e.every(n=>n(r,i))}else if(t[0]==="any"){let e=t.slice(1,t.length).map(r=>Je(r));return(r,i)=>e.some(n=>n(r,i))}else return console.log("Unimplemented filter: ",t[0]),e=>!1}}function ft(t){if(t.base&&t.stops)return r=>j(t.base,t.stops)(r-1);if(t[0]=="interpolate"&&t[1][0]=="exponential"&&t[2]=="zoom"){let r=t.slice(3),i=[];for(var e=0;ej(t[1][1],i)(n-1)}else if(t[0]=="step"&&t[1][0]=="get"){let r=t.slice(2),i=t[1][1];return(n,a)=>{let s=a==null?void 0:a.props[i];if(typeof s=="number"){if(s1}function jt(t,e=0){return t?typeof t=="number"?t:(r,i)=>i?ft(t)(r,i):e:e}function Nt(t,e){let r=jt(t,1),i=jt(e);return(n,a)=>{let s=typeof r=="number"?r:r(n,a);return i?s+(typeof i=="number"?i:i(n,a)):s}}function qt(t,e){let r=[];for(let o of t["text-font"])e.hasOwnProperty(o)&&r.push(e[o]);r.length===0&&r.push({face:"sans-serif"});let i=t["text-size"];var n="";r.length&&r[0].weight&&(n=r[0].weight+" ");var a="";if(r.length&&r[0].style&&(a=r[0].style+" "),typeof i=="number")return o=>`${a}${n}${i}px ${r.map(l=>l.face).join(", ")}`;if(i.stops){var s=1.4;i.base?s=i.base:i.base=s;let o=ft(i);return(l,u)=>`${a}${n}${o(l,u)}px ${r.map(f=>f.face).join(", ")}`}else if(i[0]=="step"){let o=ft(i);return(l,u)=>`${a}${n}${o(l,u)}px ${r.map(f=>f.face).join(", ")}`}else return console.log("Can't parse font: ",t),o=>"12px sans-serif"}function ua(t,e){let r=[],i=[],n=new Map;for(var a of t.layers){if(n.set(a.id,a),a.layout&&a.layout.visibility=="none")continue;if(a.ref){let u=n.get(a.ref);a.type=u.type,a.filter=u.filter,a.source=u.source,a["source-layer"]=u["source-layer"]}let l=a["source-layer"];var s,o=void 0;a.filter&&(o=Je(a.filter)),a.type=="fill"?r.push({dataLayer:a["source-layer"],filter:o,symbolizer:new A({fill:a.paint["fill-color"],opacity:a.paint["fill-opacity"]})}):a.type=="fill-extrusion"?r.push({dataLayer:a["source-layer"],filter:o,symbolizer:new A({fill:a.paint["fill-extrusion-color"],opacity:a.paint["fill-extrusion-opacity"]})}):a.type=="line"?a.paint["line-dasharray"]?r.push({dataLayer:a["source-layer"],filter:o,symbolizer:new C({width:Nt(a.paint["line-width"],a.paint["line-gap-width"]),dash:a.paint["line-dasharray"],dashColor:a.paint["line-color"]})}):r.push({dataLayer:a["source-layer"],filter:o,symbolizer:new C({color:a.paint["line-color"],width:Nt(a.paint["line-width"],a.paint["line-gap-width"])})}):a.type=="symbol"?a.layout["symbol-placement"]=="line"?i.push({dataLayer:a["source-layer"],filter:o,symbolizer:new ce({font:qt(a.layout,e),fill:a.paint["text-color"],width:a.paint["text-halo-width"],stroke:a.paint["text-halo-color"],textTransform:a.layout["text-transform"],label_props:a.layout["text-field"]?[a.layout["text-field"]]:void 0})}):i.push({dataLayer:a["source-layer"],filter:o,symbolizer:new U({font:qt(a.layout,e),fill:a.paint["text-color"],stroke:a.paint["text-halo-color"],width:a.paint["text-halo-width"],textTransform:a.layout["text-transform"],label_props:a.layout["text-field"]?[a.layout["text-field"]]:void 0})}):a.type=="circle"&&r.push({dataLayer:a["source-layer"],filter:o,symbolizer:new te({radius:a.paint["circle-radius"],fill:a.paint["circle-color"],stroke:a.paint["circle-stroke-color"],width:a.paint["circle-stroke-width"]})})}return i.reverse(),{paint_rules:r,label_rules:i,tasks:[]}}var ha=t=>{let e=Ot(4,4,s=>{var o=s.getContext("2d");o&&(o.beginPath(),o.rect(0,0,1,1),o.rect(2,2,1,1),o.fillStyle="black",o.fill())});var r="black";t==="lite"&&(r="#d9d9d9");let i=["name:en","name"],n=[{dataLayer:"earth",symbolizer:new A({fill:"white"})},{dataLayer:"landuse",symbolizer:new A({pattern:e}),filter:(s,o)=>o.props.leisure=="park"},{dataLayer:"water",symbolizer:new A({fill:r})},{dataLayer:"roads",symbolizer:new C({color:"#dddddd"}),filter:(s,o)=>o.props["pmap:kind"]==="minor_road"},{dataLayer:"roads",symbolizer:new C({color:"white",width:de(16,[7,9,17,20])}),filter:(s,o)=>o.props["pmap:kind"]==="medium_road"},{dataLayer:"roads",symbolizer:new C({color:"#cccccc",width:de(10,[.2,.2,.2,.4,.8,1.5,4,7,13,16])}),filter:(s,o)=>o.props["pmap:kind"]==="medium_road"},{dataLayer:"roads",symbolizer:new C({color:"white",width:de(11,[1.25,5,5,5,8,11,18,22,30])}),filter:(s,o)=>o.props["pmap:kind"]==="major_road"},{dataLayer:"roads",symbolizer:new C({color:"black",width:de(9,[.15,.5,.7,1,1.5,1.9,5,7,12,18,26])}),filter:(s,o)=>o.props["pmap:kind"]==="major_road"},{dataLayer:"roads",symbolizer:new C({color:"white",width:de(7,[2.25,3.25,4.25,5,6,7,8,9,11,14,24,42,49])}),filter:(s,o)=>o.props["pmap:kind"]==="highway"},{dataLayer:"roads",symbolizer:new C({color:"black",width:de(6,[.1,1.5,1.5,1.5,2,2.5,3,3,4,6,9,15,28,35])}),filter:(s,o)=>o.props["pmap:kind"]==="highway"},{dataLayer:"transit",symbolizer:new C({color:"#888888",dashColor:"#888888",dash:[1,4],dashWidth:3}),filter:(s,o)=>o.props["pmap:kind"]==="railway",minzoom:14},{dataLayer:"transit",symbolizer:new C({color:"#888888"}),filter:(s,o)=>o.props["pmap:kind"]==="railway",minzoom:14},{dataLayer:"buildings",symbolizer:new C({color:"#888888",width:.5})},{dataLayer:"boundaries",symbolizer:new C({color:"black",width:1}),maxzoom:6},{dataLayer:"boundaries",symbolizer:new C({color:"white",width:2.5,dash:[3,1],dashWidth:.3,dashColor:"black"}),minzoom:7}],a=[{dataLayer:"places",symbolizer:new U({label_props:i,fill:"black",stroke:"white",width:1.5,fontFamily:"Inter",fontWeight:300,fontSize:15,justify:X.Center}),filter:(s,o)=>o.props["pmap:kind"]=="country"},{dataLayer:"places",symbolizer:new U({label_props:i,fill:"black",stroke:"white",width:2,fontFamily:"Inter",fontWeight:300,fontSize:12,justify:X.Center}),filter:(s,o)=>o.props["pmap:kind"]=="state"},{dataLayer:"places",symbolizer:new ye([new te({radius:2,fill:"black",stroke:"white",width:2}),new le({label_props:i,offsetX:3,fill:"black",stroke:"white",width:1.5,fontFamily:"Inter",fontWeight:600,fontSize:(s,o)=>o.props["pmap:rank"]==1?15:13})]),sort:(s,o)=>s["pmap:rank"]-o["pmap:rank"],filter:(s,o)=>o.props["pmap:kind"]=="city",maxzoom:8},{dataLayer:"places",symbolizer:new U({label_props:i,justify:X.Center,fill:"black",stroke:"white",width:2,fontFamily:"Inter",fontWeight:600,fontSize:(s,o)=>o.props["pmap:rank"]==1?15:13}),sort:(s,o)=>s["pmap:rank"]-o["pmap:rank"],filter:(s,o)=>o.props["pmap:kind"]=="city",minzoom:9},{dataLayer:"water",symbolizer:new ue({label_props:i,fill:"white",stroke:"black",width:3,font:"italic 400 12px Inter"})},{dataLayer:"landuse",symbolizer:new ue({fill:"black",stroke:"white",width:2,font:"italic 400 12px Inter"})},{dataLayer:"physical_point",symbolizer:new U({label_props:i,fill:"white",stroke:"black",width:3,font:"italic 600 12px Inter",textTransform:"uppercase",justify:X.Center}),filter:(s,o)=>["ocean","sea"].includes(o.props.place)},{dataLayer:"roads",symbolizer:new ce({fill:"black",stroke:"white",width:2,font:"600 14px Inter",offset:4})}];return{tasks:[Ut("Inter","https://cdn.protomaps.com/fonts/woff2/Inter.var.woff2","100 900")],paint_rules:n,label_rules:a,attribution:'Map tiles by Stamen Design, under CC BY 3.0.'}};return fa;})(); +/*! ieee754. BSD-3-Clause License. Feross Aboukhadijeh */ diff --git a/worldmap/worldmap.js b/worldmap/worldmap.js index 11a6529..a8d789c 100644 --- a/worldmap/worldmap.js +++ b/worldmap/worldmap.js @@ -38,6 +38,7 @@ var sendRoute; var oldBounds = {ne:{lat:0, lng:0}, sw:{lat:0, lng:0}}; var edgeLayer = new L.layerGroup(); var edgeEnabled = true; +var pmtloaded = ""; var iconSz = { "Team/Crew": 24, @@ -93,7 +94,7 @@ var connect = function() { document.getElementById("footer").innerHTML = ""+pagefoot+""; } ws.send(JSON.stringify({action:"connected",parameters:Object.fromEntries((new URL(location)).searchParams),clientTimezone:Intl.DateTimeFormat().resolvedOptions().timeZone || false})); - onoffline(); + setTimeout(function() { onoffline(); }, 500); }; ws.onclose = function() { console.log("DISCONNECTED"); @@ -181,7 +182,8 @@ layers["_countries"] = omnivore.topojson('images/world-50m-flat.json',null,custo overlays["countries"] = layers["_countries"]; var onoffline = function() { if (!navigator.onLine) { - map.addLayer(overlays["countries"]); + if (pmtloaded !== "") { basemaps[pmtloaded].addTo(map); layercontrol._update(); } + else { map.addLayer(overlays["countries"]); } } } document.addEventListener ("keydown", function (ev) { @@ -581,7 +583,7 @@ setInterval( function() { moveTerminator() }, 60000 ); // move the rainfall overlay (if enabled) every 10 minutes function moveRainfall() { - if (navigator.onLine && map.hasLayer(overlays["rainfall"])) { + if (navigator.onLine && overlays.hasOwnProperty("rainfall") && map.hasLayer(overlays["rainfall"])) { overlays["rainfall"]["_url"] = 'https://tilecache.rainviewer.com/v2/radar/' + parseInt(Date.now()/600000)*600 + '/256/{z}/{x}/{y}/2/1_1.png'; overlays["rainfall"].redraw(); } @@ -1081,12 +1083,13 @@ var addBaseMaps = function(maplist,first) { if (first) { if (layerlookup[first]) { baselayername = layerlookup[first]; } - else { basenayername = first; } + else { baselayername = first; } + if (!basemaps[baselayername]) { baselayername = Object.keys(basemaps)[0]; } } else { - basenayername = Object.keys(basemaps)[0]; + baselayername = Object.keys(basemaps)[0]; } - basemaps[baselayername].addTo(map); + if (baselayername) { basemaps[baselayername].addTo(map); } if (showLayerMenu) { map.removeControl(layercontrol); layercontrol = L.control.layers(basemaps, overlays).addTo(map); @@ -2333,9 +2336,38 @@ function setMarker(data) { if (p === true) { marker.openPopup(); } } +var custIco = function() { + var col = cmd.map.iconColor ?? "#910000"; + var myMarker = L.VectorMarkers.icon({ + icon: "circle", + markerColor: col, + prefix: 'fa', + iconColor: 'white' + }); + if (cmd.map.hasOwnProperty("icon")) { + myMarker = L.divIcon({ + className:"faicon", + html: '
', + iconSize: [16, 16], + }); + } + var customLayer = L.geoJson(null, { + pointToLayer: function(geoJsonPoint, latlng) { + //console.log("KML/GPX point",geoJsonPoint) + var d = (geoJsonPoint.properties.description || "").trim(); + var mypop = ''+geoJsonPoint.properties.name + '
'+d+'
lat,lon : ' + geoJsonPoint.geometry.coordinates[1] + ', ' + geoJsonPoint.geometry.coordinates[0]; + if (geoJsonPoint.geometry.coordinates[2]) { + mypop = ''+geoJsonPoint.properties.name + '
'+d+'
lat,lon.alt : ' + geoJsonPoint.geometry.coordinates[1] + ', ' + geoJsonPoint.geometry.coordinates[0] + ', ' + geoJsonPoint.geometry.coordinates[2]; + } + return L.marker(latlng, {icon:myMarker, title:geoJsonPoint.properties.name}).bindPopup(mypop); + } + }); + return customLayer; +} + // handle any incoming COMMANDS to control the map remotely function doCommand(cmd) { - //console.log("COMMAND",cmd); + // console.log("COMMAND",cmd); if (cmd.init && cmd.hasOwnProperty("maplist")) { //basemaps = {}; addBaseMaps(cmd.maplist,cmd.layer); @@ -2535,6 +2567,31 @@ function doCommand(cmd) { basemaps[baselayername].addTo(map); } } + // Add a new PMtiles/PBF feature layer + if (cmd.map && cmd.map.hasOwnProperty("name") && cmd.map.hasOwnProperty("pmtiles") ) { + try { + if (basemaps.hasOwnProperty(cmd.map.name)) { + basemaps[cmd.map.name].removeFrom(map); + existsalready = true; + } + var opt = {}; + if (cmd.map.hasOwnProperty("opt")) { opt = cmd.map.opt; } + opt.url = cmd.map.pmtiles; + opt.attribution = opt.attribution || '© Protomaps'; + opt.maxDataZoom = opt.maxDataZoom || 15; + opt.maxZoom = opt.maxZoom || 20; + console.log("New PMtiles:",cmd.map.name,opt); + basemaps[cmd.map.name] = protomapsL.leafletLayer(opt); + if (!existsalready) { + layercontrol.addBaseLayer(basemaps[cmd.map.name],cmd.map.name); + } + if (Object.keys(basemaps).length === 1) { + baselayername = cmd.map.name; + basemaps[baselayername].addTo(map); + } + if (pmtloaded === "") { pmtloaded = cmd.map.name; } + } catch(e) { console.log(e); } + } // Add or swap new minimap layer if (cmd.map && cmd.map.hasOwnProperty("minimap")) { if (minimap) { map.removeControl(minimap); } @@ -2696,36 +2753,6 @@ function doCommand(cmd) { if (cmd.map.hasOwnProperty("fly") && cmd.map.fly === true) { map.flyToBounds(overlays[cmd.map.overlay].getBounds()); } else if (cmd.map.hasOwnProperty("fit") && cmd.map.fit === true) { map.fitBounds(overlays[cmd.map.overlay].getBounds()); } } - - var custIco = function() { - var col = cmd.map.iconColor ?? "#910000"; - var myMarker = L.VectorMarkers.icon({ - icon: "circle", - markerColor: col, - prefix: 'fa', - iconColor: 'white' - }); - if (cmd.map.hasOwnProperty("icon")) { - myMarker = L.divIcon({ - className:"faicon", - html: '
', - iconSize: [16, 16], - }); - } - var customLayer = L.geoJson(null, { - pointToLayer: function(geoJsonPoint, latlng) { - //console.log("KML/GPX point",geoJsonPoint) - var d = (geoJsonPoint.properties.description || "").trim(); - var mypop = ''+geoJsonPoint.properties.name + '
'+d+'
lat,lon : ' + geoJsonPoint.geometry.coordinates[1] + ', ' + geoJsonPoint.geometry.coordinates[0]; - if (geoJsonPoint.geometry.coordinates[2]) { - mypop = ''+geoJsonPoint.properties.name + '
'+d+'
lat,lon.alt : ' + geoJsonPoint.geometry.coordinates[1] + ', ' + geoJsonPoint.geometry.coordinates[0] + ', ' + geoJsonPoint.geometry.coordinates[2]; - } - return L.marker(latlng, {icon:myMarker, title:geoJsonPoint.properties.name}).bindPopup(mypop); - } - }); - return customLayer; - } - // Add a new KMZ overlay layer (or KML) //if (cmd.map && cmd.map.hasOwnProperty("overlay") && cmd.map.hasOwnProperty("kmz")) { if (cmd.map && cmd.map.hasOwnProperty("overlay") && ( cmd.map.hasOwnProperty("kmz") || cmd.map.hasOwnProperty("kml")) ) { @@ -2813,7 +2840,7 @@ function doCommand(cmd) { // var gp = new DOMParser().parseFromString(cmd.map.gpx, "text/xml"); // var json = window.toGeoJSON.gpx(gp); // console.log("j",json) - // doGeojson(json.features[0].properties.name,json,json.features[0].properties.type) // DCJ name,geojson,layer,options + // doGeojson(json.features[0].properties.name,json,json.features[0].properties.type) // name,geojson,layer,options overlays[cmd.map.overlay] = omnivore.gpx.parse(cmd.map.gpx, null, custIco()); if (!existsalready) { layercontrol.addOverlay(overlays[cmd.map.overlay],cmd.map.overlay); @@ -2939,6 +2966,7 @@ function doCommand(cmd) { else { lockit = false; doLock(false); } document.getElementById("lockit").checked = lockit; } + // if (cmd.hasOwnProperty("panlock") && lockit === true) { doLock(true); } // Move to a new position var clat = map.getCenter().lat; var clon = map.getCenter().lng; @@ -2962,6 +2990,7 @@ function doCommand(cmd) { document.getElementById("setclus").value = cmd.cluster; setCluster(clusterAt); } + // Set max age of markers if (cmd.hasOwnProperty("maxage")) { document.getElementById("maxage").value = cmd.maxage; setMaxAge(); @@ -2974,7 +3003,7 @@ function doCommand(cmd) { // document.getElementById("heatall").checked = !!cmd.heatmap; // heat.redraw(); } - if (cmd.hasOwnProperty("panlock") && lockit === true) { doLock(true); } + // Lock zoom controls if (cmd.hasOwnProperty("zoomlock")) { if (cmd.zoomlock == "true" || cmd.zoomlock == true) { if (map.doubleClickZoom.enabled()) { map.removeControl(map.zoomControl); } @@ -2989,7 +3018,8 @@ function doCommand(cmd) { map.touchZoom.enable(); } } - if (cmd.hasOwnProperty("bounds")) { // Move/Zoom map to new bounds + // Move/Zoom map to new bounds + if (cmd.hasOwnProperty("bounds")) { if (cmd.bounds.length === 2 && cmd.bounds[0].length === 2 && cmd.bounds[1].length === 2) { if (cmd.hasOwnProperty("fly") && cmd.fly === true) { map.flyToBounds(cmd.bounds);