From 06c7a91cdcf116356eb2449bc704b3a4a555f97f Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Sat, 12 Oct 2024 22:15:00 +0200 Subject: [PATCH 01/21] [REF] split web_view_leaflet_map into web_view_leaflet_map and web_leaflet_lib, to be used by other modules, like 'web_widget_map'. (see : https://github.com/OCA/web/pull/2953/) --- web_leaflet_lib/README.rst | 121 ++++ web_leaflet_lib/__init__.py | 2 + web_leaflet_lib/__manifest__.py | 25 + web_leaflet_lib/data/ir_config_parameter.xml | 20 + web_leaflet_lib/demo/ir_config_parameter.xml | 16 + web_leaflet_lib/hooks.py | 14 + web_leaflet_lib/i18n/fr.po | 21 + web_leaflet_lib/models/__init__.py | 1 + web_leaflet_lib/models/ir_http.py | 20 + web_leaflet_lib/readme/CONFIGURE.rst | 5 + web_leaflet_lib/readme/CONTRIBUTORS.rst | 1 + web_leaflet_lib/readme/CREDITS.rst | 1 + web_leaflet_lib/readme/DESCRIPTION.rst | 24 + web_leaflet_lib/static/description/icon.png | Bin 0 -> 39188 bytes web_leaflet_lib/static/description/index.html | 454 ++++++++++++ .../static/lib/leaflet/images/layers-2x.png | Bin 0 -> 1259 bytes .../static/lib/leaflet/images/layers.png | Bin 0 -> 696 bytes .../lib/leaflet/images/marker-icon-2x.png | Bin 0 -> 2464 bytes .../static/lib/leaflet/images/marker-icon.png | Bin 0 -> 1466 bytes .../lib/leaflet/images/marker-shadow.png | Bin 0 -> 618 bytes .../static/lib/leaflet/leaflet.css | 661 ++++++++++++++++++ web_leaflet_lib/static/lib/leaflet/leaflet.js | 6 + .../static/lib/leaflet/leaflet.js.map | 1 + 23 files changed, 1393 insertions(+) create mode 100644 web_leaflet_lib/README.rst create mode 100644 web_leaflet_lib/__init__.py create mode 100644 web_leaflet_lib/__manifest__.py create mode 100644 web_leaflet_lib/data/ir_config_parameter.xml create mode 100644 web_leaflet_lib/demo/ir_config_parameter.xml create mode 100644 web_leaflet_lib/hooks.py create mode 100644 web_leaflet_lib/i18n/fr.po create mode 100644 web_leaflet_lib/models/__init__.py create mode 100644 web_leaflet_lib/models/ir_http.py create mode 100644 web_leaflet_lib/readme/CONFIGURE.rst create mode 100644 web_leaflet_lib/readme/CONTRIBUTORS.rst create mode 100644 web_leaflet_lib/readme/CREDITS.rst create mode 100644 web_leaflet_lib/readme/DESCRIPTION.rst create mode 100644 web_leaflet_lib/static/description/icon.png create mode 100644 web_leaflet_lib/static/description/index.html create mode 100644 web_leaflet_lib/static/lib/leaflet/images/layers-2x.png create mode 100644 web_leaflet_lib/static/lib/leaflet/images/layers.png create mode 100644 web_leaflet_lib/static/lib/leaflet/images/marker-icon-2x.png create mode 100644 web_leaflet_lib/static/lib/leaflet/images/marker-icon.png create mode 100644 web_leaflet_lib/static/lib/leaflet/images/marker-shadow.png create mode 100644 web_leaflet_lib/static/lib/leaflet/leaflet.css create mode 100644 web_leaflet_lib/static/lib/leaflet/leaflet.js create mode 100644 web_leaflet_lib/static/lib/leaflet/leaflet.js.map diff --git a/web_leaflet_lib/README.rst b/web_leaflet_lib/README.rst new file mode 100644 index 000000000..6681def66 --- /dev/null +++ b/web_leaflet_lib/README.rst @@ -0,0 +1,121 @@ +========================== +Leaflet Javascript Library +========================== + +.. + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! This file is generated by oca-gen-addon-readme !! + !! changes will be overwritten. !! + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + !! source digest: sha256:e5af47c08dbb573c870e80a506feaccced35a36e61e63c6d39644fa84a357de1 + !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! + +.. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png + :target: https://odoo-community.org/page/development-status + :alt: Beta +.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png + :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html + :alt: License: AGPL-3 +.. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fgeospatial-lightgray.png?logo=github + :target: https://github.com/OCA/geospatial/tree/16.0/web_leaflet_lib + :alt: OCA/geospatial +.. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png + :target: https://translation.odoo-community.org/projects/geospatial-16-0/geospatial-16-0-web_leaflet_lib + :alt: Translate me on Weblate +.. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png + :target: https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=16.0 + :alt: Try me on Runboat + +|badge1| |badge2| |badge3| |badge4| |badge5| + +This module extends odoo to include Leaflet Javacript library. + +This module is used by ``web_view_leaflet_map``. + +**Important Note** + +The javascript library is opensource and distributed under BSD 2 Licence. +See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE +You can so use it freely. + +However, display maps requires to display layers provided by tiles servers, that +requires ressources. + +**For testing purpose** + +You can use the openStreetMap url ``https://tile.openstreetmap.org/{z}/{x}/{y}.png`` or other, listed in that page : https://wiki.openstreetmap.org/wiki/Tile_servers + +Apart from very limited testing purposes, you should not use the tiles supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run non-profit body and cannot supply tiles for large-scale commercial use. + +**Regular / High Usage** + +- you can contact one of the following companies : https://switch2osm.org/providers/ + +- You can also install yourself your own tiles servers. See documentation : https://switch2osm.org/serving-tiles/ + +**Table of contents** + +.. contents:: + :local: + +Configuration +============= + +* Go to Settings > Technical > Parameters > System Parameters + +* Create or edit the parameter with the key ``leaflet.tile_url`` + +* As a value, set the url of the tiles server you chose. (See description) + +Bug Tracker +=========== + +Bugs are tracked on `GitHub Issues `_. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +`feedback `_. + +Do not contact contributors directly about support or help with technical issues. + +Credits +======= + +Authors +~~~~~~~ + +* GRAP + +Contributors +~~~~~~~~~~~~ + +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) + +Other credits +~~~~~~~~~~~~~ + +The module embed the Leaflet.js library. + +Maintainers +~~~~~~~~~~~ + +This module is maintained by the OCA. + +.. image:: https://odoo-community.org/logo.png + :alt: Odoo Community Association + :target: https://odoo-community.org + +OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use. + +.. |maintainer-legalsylvain| image:: https://github.com/legalsylvain.png?size=40px + :target: https://github.com/legalsylvain + :alt: legalsylvain + +Current `maintainer `__: + +|maintainer-legalsylvain| + +This module is part of the `OCA/geospatial `_ project on GitHub. + +You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_leaflet_lib/__init__.py b/web_leaflet_lib/__init__.py new file mode 100644 index 000000000..6d58305f5 --- /dev/null +++ b/web_leaflet_lib/__init__.py @@ -0,0 +1,2 @@ +from . import models +from .hooks import pre_init_hook diff --git a/web_leaflet_lib/__manifest__.py b/web_leaflet_lib/__manifest__.py new file mode 100644 index 000000000..890852e25 --- /dev/null +++ b/web_leaflet_lib/__manifest__.py @@ -0,0 +1,25 @@ +# Copyright (C) 2024 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +{ + "name": "Leaflet Javascript Library", + "summary": "Bring leaflet.js librairy in odoo.", + "version": "16.0.1.0.0", + "author": "GRAP, Odoo Community Association (OCA)", + "maintainers": ["legalsylvain"], + "website": "https://github.com/OCA/geospatial", + "license": "AGPL-3", + "category": "Extra Tools", + "depends": ["base"], + "data": ["data/ir_config_parameter.xml"], + "demo": ["demo/ir_config_parameter.xml"], + "assets": { + "web.assets_backend": [ + "/web_leaflet_lib/static/lib/leaflet/leaflet.css", + "/web_leaflet_lib/static/lib/leaflet/leaflet.js", + ], + }, + "installable": True, + "pre_init_hook": "pre_init_hook", +} diff --git a/web_leaflet_lib/data/ir_config_parameter.xml b/web_leaflet_lib/data/ir_config_parameter.xml new file mode 100644 index 000000000..91e4ecdb4 --- /dev/null +++ b/web_leaflet_lib/data/ir_config_parameter.xml @@ -0,0 +1,20 @@ + + + + + leaflet.copyright + OpenStreetMap]]> + + + diff --git a/web_leaflet_lib/demo/ir_config_parameter.xml b/web_leaflet_lib/demo/ir_config_parameter.xml new file mode 100644 index 000000000..dcdee6e33 --- /dev/null +++ b/web_leaflet_lib/demo/ir_config_parameter.xml @@ -0,0 +1,16 @@ + + + + + leaflet.tile_url + https://tile.openstreetmap.org/{z}/{x}/{y}.png + + diff --git a/web_leaflet_lib/hooks.py b/web_leaflet_lib/hooks.py new file mode 100644 index 000000000..4cf094ea3 --- /dev/null +++ b/web_leaflet_lib/hooks.py @@ -0,0 +1,14 @@ +def pre_init_hook(cr): + # move configuration from web_view_leaflet_map + # into web_leaflet_lib, if exists. + cr.execute( + """ + UPDATE ir_model_data + SET module='web_leaflet_lib' + WHERE module = 'web_view_leaflet_map' + AND name in ( + 'config_parameter_leaflet_copyright', + 'config_parameter_leaflet_tile_url' + ) + """ + ) diff --git a/web_leaflet_lib/i18n/fr.po b/web_leaflet_lib/i18n/fr.po new file mode 100644 index 000000000..a8b2b7c66 --- /dev/null +++ b/web_leaflet_lib/i18n/fr.po @@ -0,0 +1,21 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_leaflet_lib +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"POT-Creation-Date: 2024-10-12 20:11+0000\n" +"PO-Revision-Date: 2024-10-12 20:11+0000\n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_leaflet_lib +#: model:ir.model,name:web_leaflet_lib.model_ir_http +msgid "HTTP Routing" +msgstr "Routage HTTP" diff --git a/web_leaflet_lib/models/__init__.py b/web_leaflet_lib/models/__init__.py new file mode 100644 index 000000000..9a5eb7187 --- /dev/null +++ b/web_leaflet_lib/models/__init__.py @@ -0,0 +1 @@ +from . import ir_http diff --git a/web_leaflet_lib/models/ir_http.py b/web_leaflet_lib/models/ir_http.py new file mode 100644 index 000000000..976035a2c --- /dev/null +++ b/web_leaflet_lib/models/ir_http.py @@ -0,0 +1,20 @@ +# Copyright (C) 2022 - Today: GRAP (http://www.grap.coop) +# @author: Sylvain LE GAL (https://twitter.com/legalsylvain) +# License AGPL-3.0 or later (http://www.gnu.org/licenses/agpl.html). + +from odoo import models + + +class Http(models.AbstractModel): + _inherit = "ir.http" + + def session_info(self): + result = super(Http, self).session_info() + config = self.env["ir.config_parameter"].sudo() + result.update( + { + "leaflet.tile_url": config.get_param("leaflet.tile_url", default=""), + "leaflet.copyright": config.get_param("leaflet.copyright", default=""), + } + ) + return result diff --git a/web_leaflet_lib/readme/CONFIGURE.rst b/web_leaflet_lib/readme/CONFIGURE.rst new file mode 100644 index 000000000..cf45731ce --- /dev/null +++ b/web_leaflet_lib/readme/CONFIGURE.rst @@ -0,0 +1,5 @@ +* Go to Settings > Technical > Parameters > System Parameters + +* Create or edit the parameter with the key ``leaflet.tile_url`` + +* As a value, set the url of the tiles server you chose. (See description) diff --git a/web_leaflet_lib/readme/CONTRIBUTORS.rst b/web_leaflet_lib/readme/CONTRIBUTORS.rst new file mode 100644 index 000000000..e1525ce04 --- /dev/null +++ b/web_leaflet_lib/readme/CONTRIBUTORS.rst @@ -0,0 +1 @@ +* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/web_leaflet_lib/readme/CREDITS.rst b/web_leaflet_lib/readme/CREDITS.rst new file mode 100644 index 000000000..c70319635 --- /dev/null +++ b/web_leaflet_lib/readme/CREDITS.rst @@ -0,0 +1 @@ +The module embed the Leaflet.js library. diff --git a/web_leaflet_lib/readme/DESCRIPTION.rst b/web_leaflet_lib/readme/DESCRIPTION.rst new file mode 100644 index 000000000..882413671 --- /dev/null +++ b/web_leaflet_lib/readme/DESCRIPTION.rst @@ -0,0 +1,24 @@ +This module extends odoo to include Leaflet Javacript library. + +This module is used by ``web_view_leaflet_map``. + +**Important Note** + +The javascript library is opensource and distributed under BSD 2 Licence. +See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE +You can so use it freely. + +However, display maps requires to display layers provided by tiles servers, that +requires ressources. + +**For testing purpose** + +You can use the openStreetMap url ``https://tile.openstreetmap.org/{z}/{x}/{y}.png`` or other, listed in that page : https://wiki.openstreetmap.org/wiki/Tile_servers + +Apart from very limited testing purposes, you should not use the tiles supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run non-profit body and cannot supply tiles for large-scale commercial use. + +**Regular / High Usage** + +- you can contact one of the following companies : https://switch2osm.org/providers/ + +- You can also install yourself your own tiles servers. See documentation : https://switch2osm.org/serving-tiles/ diff --git a/web_leaflet_lib/static/description/icon.png b/web_leaflet_lib/static/description/icon.png new file mode 100644 index 0000000000000000000000000000000000000000..9a516f2f8a1871318c6531a23430eb43cb4ac1e9 GIT binary patch literal 39188 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 literal 0 HcmV?d00001 diff --git a/web_leaflet_lib/static/description/index.html b/web_leaflet_lib/static/description/index.html new file mode 100644 index 000000000..655af50d8 --- /dev/null +++ b/web_leaflet_lib/static/description/index.html @@ -0,0 +1,454 @@ + + + + + +Leaflet Javascript Library + + + +
+

Leaflet Javascript Library

+ + +

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

+

This module extends odoo to include Leaflet Javacript library.

+

This module is used by web_view_leaflet_map.

+

Important Note

+

The javascript library is opensource and distributed under BSD 2 Licence. +See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE +You can so use it freely.

+

However, display maps requires to display layers provided by tiles servers, that +requires ressources.

+

For testing purpose

+

You can use the openStreetMap url https://tile.openstreetmap.org/{z}/{x}/{y}.png or other, listed in that page : https://wiki.openstreetmap.org/wiki/Tile_servers

+

Apart from very limited testing purposes, you should not use the tiles supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run non-profit body and cannot supply tiles for large-scale commercial use.

+

Regular / High Usage

+ +

Table of contents

+ +
+

Configuration

+
    +
  • Go to Settings > Technical > Parameters > System Parameters
  • +
  • Create or edit the parameter with the key leaflet.tile_url
  • +
  • As a value, set the url of the tiles server you chose. (See description)
  • +
+
+
+

Bug Tracker

+

Bugs are tracked on GitHub Issues. +In case of trouble, please check there if your issue has already been reported. +If you spotted it first, help us to smash it by providing a detailed and welcomed +feedback.

+

Do not contact contributors directly about support or help with technical issues.

+
+
+

Credits

+
+

Authors

+
    +
  • GRAP
  • +
+
+ +
+

Other credits

+

The module embed the Leaflet.js library.

+
+
+

Maintainers

+

This module is maintained by the OCA.

+ +Odoo Community Association + +

OCA, or the Odoo Community Association, is a nonprofit organization whose +mission is to support the collaborative development of Odoo features and +promote its widespread use.

+

Current maintainer:

+

legalsylvain

+

This module is part of the OCA/geospatial project on GitHub.

+

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

+
+
+
+ + diff --git a/web_leaflet_lib/static/lib/leaflet/images/layers-2x.png b/web_leaflet_lib/static/lib/leaflet/images/layers-2x.png new file mode 100644 index 0000000000000000000000000000000000000000..200c333dca9652ac4cba004d609e5af4eee168c1 GIT binary patch literal 1259 zcmVFhCYNy;#0irRPomHqW|G1C*;4?@4#E?jH>?v@U%cy?3dQAc-DchXVErpOh~ z-jbon+tNbnl6hoEb;)TVk+%hTDDi_G%i3*RZ&15!$Fjr^f;Ke&A@|?=`2&+{zr+3a z{D*=t(`AXyS%X7N z%a#RZw6vD^t_rnM`L4E>m=U&R!A-&}nZIi$BOPvkhrCuUe@BN~-lRD)f44;J%TwgE zcze8u!PQ_NR7?o(NylLXVTfDO zxs5=@|GsYEsNo4M#nT%N!UE(?dnS)t2+{ELYAFp*3=iF=|EQnTp`#vlSXuGVraYo? z+RCzXo6h3qA8{KG?S4nE(lM+;Eb4nT3XV;7gcAxUi5m)`k5tv}cPy()8ZR3TLW3I- zAS^}cq-IJvL7a4RgR!yk@~RT%$lA7{L5ES*hyx)M4(yxI$Ub(4f)K|^v1>zvwQY!_ zIrWw8q9GS^!Dp~}+?mbnB6jDF8mVlbQ!jFKDY;w=7;XO{9bq7>LXGK24WA`;rL)_Z z)&j}pbV(;6gY;VMhbxgvn`X;6x}VUEE-7 z%)7j-%t8S=ZL3yc)HbXDAqJZvBTPoiW_A-+a8m3_Z?v{DN7Tnr#O_VUMT0UBt$;p` zDh6JbGHN8JJ*JN%y2%msb97@_S>9!%Egwk;?PEkU9ntz&3uR}%Fj5d$JHQbQb3}a{ zSzFT^#n=VInPpcAS}CNxj?_ zVscANk5Cfz(51EI1pz};AWWb|kgbYNb4wCEGUn3+eMUMV?1-{=I4TlmLJMot@rd07 zZuo2hk1ccu{YmGkcYdWAVdk{Z4Nm?^cTD&}jGm+Q1SYIXMwmG*oO*83&#>l%nbR`G zhh=lZ%xIb7kU3#;TBbfECrnC9P=-XpL|TG2BoZdj61*XiFbW8?1Z_wp%#;>${SUIy V$8qr;L*)Pf002ovPDHLkV1hYLS~36t literal 0 HcmV?d00001 diff --git a/web_leaflet_lib/static/lib/leaflet/images/layers.png b/web_leaflet_lib/static/lib/leaflet/images/layers.png new file mode 100644 index 0000000000000000000000000000000000000000..1a72e5784b2b456eac5d7670738db80697af3377 GIT binary patch literal 696 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 e-I|>x8~*?ZhF3snGbtJX0000cOl4 literal 0 HcmV?d00001 diff --git a/web_leaflet_lib/static/lib/leaflet/images/marker-icon.png b/web_leaflet_lib/static/lib/leaflet/images/marker-icon.png new file mode 100644 index 0000000000000000000000000000000000000000..950edf24677ded147df13b26f91baa2b0fa70513 GIT binary patch literal 1466 zcmV;r1x5OaP)P001cn1^@s6z>|W`000GnNklGNuHDcIX17Zdjl&3`L?0sTjIws<{((Dh&g-s0<@jYQyl?D*X^?%13;ml^gy> ziMrY_^1WI=(g@LMizu=zCoA>C`6|QEq1eV92k*7m>G65*&@&6)aC&e}G zI)pf-Za|N`DT&Cn1J|o`19mumxW~hiKiKyc-P`S@q)rdTo84@QI@;0yXrG%9uhI>A zG5QHb6s4=<6xy{1 z@NMxEkryp{LS44%z$3lP^cX!9+2-;CTt3wM4(k*#C{aiIiLuB>jJj;KPhPzIC00bL zU3a#;aJld94lCW=`4&aAy8M7PY=HQ>O%$YEP4c4UY#CRxfgbE~(|uiI=YS8q;O9y6 zmIkXzR`}p7ti|PrM3a}WMnR=3NVnWdAAR>b9X@)DKL6=YsvmH%?I24wdq?Gh54_;# z$?_LvgjEdspdQlft#4CQ z`2Zyvy?*)N1Ftw|{_hakhG9WjS?Az@I@+IZ8JbWewR!XUK4&6346+d#~gsE0SY(LX8&JfY>Aj)RxGy96nwhs2rv zzW6pTnMpFkDSkT*a*6Dx|u@ds6ISVn0@^RmIsKZ5Y;bazbc;tTSq(kg(=481ODrPyNB6n z-$+U}(w$m6U6H$w17Bw+wDaFIe~GvNMYvnw31MpY0eQKT9l>SU``8k7w4)z!GZKMI z#_cEKq7k~i%nlK@6c-K?+R;B#5$?T#YpKD`t_4bAs^#E+@5QW$@OX3*`;(#{U^d-vY)&xEE>n5lYl&T?Amke9$Lam@{1K@O ze*LXqlKQHiv=gx+V^Cbb2?z@ISBQ*3amF;9UJ3SBg(N|710TLamQmYZ&Qjn2LuO<* zCZlB4n%@pc&7NNnY1}x+NWpHlq`OJEo|`aYN9<`RBUB+79g;>dgb6YlfN#kGL?lO_ z!6~M^7sOnbsUkKk<@Ysie&`G>ruxH&Mgy&8;i=A zB9OO!xR{AyODw>DS-q5YM{0ExFEAzt zm>RdS+ssW(-8|?xr0(?$vBVB*%(xDLtq3Hf0I5yFm<_g=W2`QWAax{1rWVH=I!VrP zs(rTFX@W#t$hXNvbgX`gK&^w_YD;CQ!B@e0QbLIWaKAXQe2-kkloo;{iF#6}z!4=W zi$giRj1{ zt;2w`VSCF#WE&*ev7jpsC=6175@(~nTE2;7M-L((0bH@yG}-TB$R~WXd?tA$s3|%y zA`9$sA(>F%J3ioz<-LJl*^o1|w84l>HBR`>3l9c8$5Xr@xCiIQ7{x$fMCzOk_-M=% z+{a_Q#;42`#KfUte@$NT77uaTz?b-fBe)1s5XE$yA79fm?KqM^VgLXD07*qoM6N<$ Ef<_J(9smFU literal 0 HcmV?d00001 diff --git a/web_leaflet_lib/static/lib/leaflet/leaflet.css b/web_leaflet_lib/static/lib/leaflet/leaflet.css new file mode 100644 index 000000000..de25a71ed --- /dev/null +++ b/web_leaflet_lib/static/lib/leaflet/leaflet.css @@ -0,0 +1,661 @@ +/* required styles */ + +.leaflet-pane, +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-tile-container, +.leaflet-pane > svg, +.leaflet-pane > canvas, +.leaflet-zoom-box, +.leaflet-image-layer, +.leaflet-layer { + position: absolute; + left: 0; + top: 0; + } +.leaflet-container { + overflow: hidden; + } +.leaflet-tile, +.leaflet-marker-icon, +.leaflet-marker-shadow { + -webkit-user-select: none; + -moz-user-select: none; + user-select: none; + -webkit-user-drag: none; + } +/* Prevents IE11 from highlighting tiles in blue */ +.leaflet-tile::selection { + background: transparent; +} +/* Safari renders non-retina tile on retina better with this, but Chrome is worse */ +.leaflet-safari .leaflet-tile { + image-rendering: -webkit-optimize-contrast; + } +/* hack that prevents hw layers "stretching" when loading new tiles */ +.leaflet-safari .leaflet-tile-container { + width: 1600px; + height: 1600px; + -webkit-transform-origin: 0 0; + } +.leaflet-marker-icon, +.leaflet-marker-shadow { + display: block; + } +/* .leaflet-container svg: reset svg max-width decleration shipped in Joomla! (joomla.org) 3.x */ +/* .leaflet-container img: map is broken in FF if you have max-width: 100% on tiles */ +.leaflet-container .leaflet-overlay-pane svg { + max-width: none !important; + max-height: none !important; + } +.leaflet-container .leaflet-marker-pane img, +.leaflet-container .leaflet-shadow-pane img, +.leaflet-container .leaflet-tile-pane img, +.leaflet-container img.leaflet-image-layer, +.leaflet-container .leaflet-tile { + max-width: none !important; + max-height: none !important; + width: auto; + padding: 0; + } + +.leaflet-container img.leaflet-tile { + /* See: https://bugs.chromium.org/p/chromium/issues/detail?id=600120 */ + mix-blend-mode: plus-lighter; +} + +.leaflet-container.leaflet-touch-zoom { + -ms-touch-action: pan-x pan-y; + touch-action: pan-x pan-y; + } +.leaflet-container.leaflet-touch-drag { + -ms-touch-action: pinch-zoom; + /* Fallback for FF which doesn't support pinch-zoom */ + touch-action: none; + touch-action: pinch-zoom; +} +.leaflet-container.leaflet-touch-drag.leaflet-touch-zoom { + -ms-touch-action: none; + touch-action: none; +} +.leaflet-container { + -webkit-tap-highlight-color: transparent; +} +.leaflet-container a { + -webkit-tap-highlight-color: rgba(51, 181, 229, 0.4); +} +.leaflet-tile { + filter: inherit; + visibility: hidden; + } +.leaflet-tile-loaded { + visibility: inherit; + } +.leaflet-zoom-box { + width: 0; + height: 0; + -moz-box-sizing: border-box; + box-sizing: border-box; + z-index: 800; + } +/* workaround for https://bugzilla.mozilla.org/show_bug.cgi?id=888319 */ +.leaflet-overlay-pane svg { + -moz-user-select: none; + } + +.leaflet-pane { z-index: 400; } + +.leaflet-tile-pane { z-index: 200; } +.leaflet-overlay-pane { z-index: 400; } +.leaflet-shadow-pane { z-index: 500; } +.leaflet-marker-pane { z-index: 600; } +.leaflet-tooltip-pane { z-index: 650; } +.leaflet-popup-pane { z-index: 700; } + +.leaflet-map-pane canvas { z-index: 100; } +.leaflet-map-pane svg { z-index: 200; } + +.leaflet-vml-shape { + width: 1px; + height: 1px; + } +.lvml { + behavior: url(#default#VML); + display: inline-block; + position: absolute; + } + + +/* control positioning */ + +.leaflet-control { + position: relative; + z-index: 800; + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } +.leaflet-top, +.leaflet-bottom { + position: absolute; + z-index: 1000; + pointer-events: none; + } +.leaflet-top { + top: 0; + } +.leaflet-right { + right: 0; + } +.leaflet-bottom { + bottom: 0; + } +.leaflet-left { + left: 0; + } +.leaflet-control { + float: left; + clear: both; + } +.leaflet-right .leaflet-control { + float: right; + } +.leaflet-top .leaflet-control { + margin-top: 10px; + } +.leaflet-bottom .leaflet-control { + margin-bottom: 10px; + } +.leaflet-left .leaflet-control { + margin-left: 10px; + } +.leaflet-right .leaflet-control { + margin-right: 10px; + } + + +/* zoom and fade animations */ + +.leaflet-fade-anim .leaflet-popup { + opacity: 0; + -webkit-transition: opacity 0.2s linear; + -moz-transition: opacity 0.2s linear; + transition: opacity 0.2s linear; + } +.leaflet-fade-anim .leaflet-map-pane .leaflet-popup { + opacity: 1; + } +.leaflet-zoom-animated { + -webkit-transform-origin: 0 0; + -ms-transform-origin: 0 0; + transform-origin: 0 0; + } +svg.leaflet-zoom-animated { + will-change: transform; +} + +.leaflet-zoom-anim .leaflet-zoom-animated { + -webkit-transition: -webkit-transform 0.25s cubic-bezier(0,0,0.25,1); + -moz-transition: -moz-transform 0.25s cubic-bezier(0,0,0.25,1); + transition: transform 0.25s cubic-bezier(0,0,0.25,1); + } +.leaflet-zoom-anim .leaflet-tile, +.leaflet-pan-anim .leaflet-tile { + -webkit-transition: none; + -moz-transition: none; + transition: none; + } + +.leaflet-zoom-anim .leaflet-zoom-hide { + visibility: hidden; + } + + +/* cursors */ + +.leaflet-interactive { + cursor: pointer; + } +.leaflet-grab { + cursor: -webkit-grab; + cursor: -moz-grab; + cursor: grab; + } +.leaflet-crosshair, +.leaflet-crosshair .leaflet-interactive { + cursor: crosshair; + } +.leaflet-popup-pane, +.leaflet-control { + cursor: auto; + } +.leaflet-dragging .leaflet-grab, +.leaflet-dragging .leaflet-grab .leaflet-interactive, +.leaflet-dragging .leaflet-marker-draggable { + cursor: move; + cursor: -webkit-grabbing; + cursor: -moz-grabbing; + cursor: grabbing; + } + +/* marker & overlays interactivity */ +.leaflet-marker-icon, +.leaflet-marker-shadow, +.leaflet-image-layer, +.leaflet-pane > svg path, +.leaflet-tile-container { + pointer-events: none; + } + +.leaflet-marker-icon.leaflet-interactive, +.leaflet-image-layer.leaflet-interactive, +.leaflet-pane > svg path.leaflet-interactive, +svg.leaflet-image-layer.leaflet-interactive path { + pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */ + pointer-events: auto; + } + +/* visual tweaks */ + +.leaflet-container { + background: #ddd; + outline-offset: 1px; + } +.leaflet-container a { + color: #0078A8; + } +.leaflet-zoom-box { + border: 2px dotted #38f; + background: rgba(255,255,255,0.5); + } + + +/* general typography */ +.leaflet-container { + font-family: "Helvetica Neue", Arial, Helvetica, sans-serif; + font-size: 12px; + font-size: 0.75rem; + line-height: 1.5; + } + + +/* general toolbar styles */ + +.leaflet-bar { + box-shadow: 0 1px 5px rgba(0,0,0,0.65); + border-radius: 4px; + } +.leaflet-bar a { + background-color: #fff; + border-bottom: 1px solid #ccc; + width: 26px; + height: 26px; + line-height: 26px; + display: block; + text-align: center; + text-decoration: none; + color: black; + } +.leaflet-bar a, +.leaflet-control-layers-toggle { + background-position: 50% 50%; + background-repeat: no-repeat; + display: block; + } +.leaflet-bar a:hover, +.leaflet-bar a:focus { + background-color: #f4f4f4; + } +.leaflet-bar a:first-child { + border-top-left-radius: 4px; + border-top-right-radius: 4px; + } +.leaflet-bar a:last-child { + border-bottom-left-radius: 4px; + border-bottom-right-radius: 4px; + border-bottom: none; + } +.leaflet-bar a.leaflet-disabled { + cursor: default; + background-color: #f4f4f4; + color: #bbb; + } + +.leaflet-touch .leaflet-bar a { + width: 30px; + height: 30px; + line-height: 30px; + } +.leaflet-touch .leaflet-bar a:first-child { + border-top-left-radius: 2px; + border-top-right-radius: 2px; + } +.leaflet-touch .leaflet-bar a:last-child { + border-bottom-left-radius: 2px; + border-bottom-right-radius: 2px; + } + +/* zoom control */ + +.leaflet-control-zoom-in, +.leaflet-control-zoom-out { + font: bold 18px 'Lucida Console', Monaco, monospace; + text-indent: 1px; + } + +.leaflet-touch .leaflet-control-zoom-in, .leaflet-touch .leaflet-control-zoom-out { + font-size: 22px; + } + + +/* layers control */ + +.leaflet-control-layers { + box-shadow: 0 1px 5px rgba(0,0,0,0.4); + background: #fff; + border-radius: 5px; + } +.leaflet-control-layers-toggle { + background-image: url(images/layers.png); + width: 36px; + height: 36px; + } +.leaflet-retina .leaflet-control-layers-toggle { + background-image: url(images/layers-2x.png); + background-size: 26px 26px; + } +.leaflet-touch .leaflet-control-layers-toggle { + width: 44px; + height: 44px; + } +.leaflet-control-layers .leaflet-control-layers-list, +.leaflet-control-layers-expanded .leaflet-control-layers-toggle { + display: none; + } +.leaflet-control-layers-expanded .leaflet-control-layers-list { + display: block; + position: relative; + } +.leaflet-control-layers-expanded { + padding: 6px 10px 6px 6px; + color: #333; + background: #fff; + } +.leaflet-control-layers-scrollbar { + overflow-y: scroll; + overflow-x: hidden; + padding-right: 5px; + } +.leaflet-control-layers-selector { + margin-top: 2px; + position: relative; + top: 1px; + } +.leaflet-control-layers label { + display: block; + font-size: 13px; + font-size: 1.08333em; + } +.leaflet-control-layers-separator { + height: 0; + border-top: 1px solid #ddd; + margin: 5px -10px 5px -6px; + } + +/* Default icon URLs */ +.leaflet-default-icon-path { /* used only in path-guessing heuristic, see L.Icon.Default */ + background-image: url(images/marker-icon.png); + } + + +/* attribution and scale controls */ + +.leaflet-container .leaflet-control-attribution { + background: #fff; + background: rgba(255, 255, 255, 0.8); + margin: 0; + } +.leaflet-control-attribution, +.leaflet-control-scale-line { + padding: 0 5px; + color: #333; + line-height: 1.4; + } +.leaflet-control-attribution a { + text-decoration: none; + } +.leaflet-control-attribution a:hover, +.leaflet-control-attribution a:focus { + text-decoration: underline; + } +.leaflet-attribution-flag { + display: inline !important; + vertical-align: baseline !important; + width: 1em; + height: 0.6669em; + } +.leaflet-left .leaflet-control-scale { + margin-left: 5px; + } +.leaflet-bottom .leaflet-control-scale { + margin-bottom: 5px; + } +.leaflet-control-scale-line { + border: 2px solid #777; + border-top: none; + line-height: 1.1; + padding: 2px 5px 1px; + white-space: nowrap; + -moz-box-sizing: border-box; + box-sizing: border-box; + background: rgba(255, 255, 255, 0.8); + text-shadow: 1px 1px #fff; + } +.leaflet-control-scale-line:not(:first-child) { + border-top: 2px solid #777; + border-bottom: none; + margin-top: -2px; + } +.leaflet-control-scale-line:not(:first-child):not(:last-child) { + border-bottom: 2px solid #777; + } + +.leaflet-touch .leaflet-control-attribution, +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + box-shadow: none; + } +.leaflet-touch .leaflet-control-layers, +.leaflet-touch .leaflet-bar { + border: 2px solid rgba(0,0,0,0.2); + background-clip: padding-box; + } + + +/* popup */ + +.leaflet-popup { + position: absolute; + text-align: center; + margin-bottom: 20px; + } +.leaflet-popup-content-wrapper { + padding: 1px; + text-align: left; + border-radius: 12px; + } +.leaflet-popup-content { + margin: 13px 24px 13px 20px; + line-height: 1.3; + font-size: 13px; + font-size: 1.08333em; + min-height: 1px; + } +.leaflet-popup-content p { + margin: 17px 0; + margin: 1.3em 0; + } +.leaflet-popup-tip-container { + width: 40px; + height: 20px; + position: absolute; + left: 50%; + margin-top: -1px; + margin-left: -20px; + overflow: hidden; + pointer-events: none; + } +.leaflet-popup-tip { + width: 17px; + height: 17px; + padding: 1px; + + margin: -10px auto 0; + pointer-events: auto; + + -webkit-transform: rotate(45deg); + -moz-transform: rotate(45deg); + -ms-transform: rotate(45deg); + transform: rotate(45deg); + } +.leaflet-popup-content-wrapper, +.leaflet-popup-tip { + background: white; + color: #333; + box-shadow: 0 3px 14px rgba(0,0,0,0.4); + } +.leaflet-container a.leaflet-popup-close-button { + position: absolute; + top: 0; + right: 0; + border: none; + text-align: center; + width: 24px; + height: 24px; + font: 16px/24px Tahoma, Verdana, sans-serif; + color: #757575; + text-decoration: none; + background: transparent; + } +.leaflet-container a.leaflet-popup-close-button:hover, +.leaflet-container a.leaflet-popup-close-button:focus { + color: #585858; + } +.leaflet-popup-scrolled { + overflow: auto; + } + +.leaflet-oldie .leaflet-popup-content-wrapper { + -ms-zoom: 1; + } +.leaflet-oldie .leaflet-popup-tip { + width: 24px; + margin: 0 auto; + + -ms-filter: "progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678)"; + filter: progid:DXImageTransform.Microsoft.Matrix(M11=0.70710678, M12=0.70710678, M21=-0.70710678, M22=0.70710678); + } + +.leaflet-oldie .leaflet-control-zoom, +.leaflet-oldie .leaflet-control-layers, +.leaflet-oldie .leaflet-popup-content-wrapper, +.leaflet-oldie .leaflet-popup-tip { + border: 1px solid #999; + } + + +/* div icon */ + +.leaflet-div-icon { + background: #fff; + border: 1px solid #666; + } + + +/* Tooltip */ +/* Base styles for the element that has a tooltip */ +.leaflet-tooltip { + position: absolute; + padding: 6px; + background-color: #fff; + border: 1px solid #fff; + border-radius: 3px; + color: #222; + white-space: nowrap; + -webkit-user-select: none; + -moz-user-select: none; + -ms-user-select: none; + user-select: none; + pointer-events: none; + box-shadow: 0 1px 3px rgba(0,0,0,0.4); + } +.leaflet-tooltip.leaflet-interactive { + cursor: pointer; + pointer-events: auto; + } +.leaflet-tooltip-top:before, +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + position: absolute; + pointer-events: none; + border: 6px solid transparent; + background: transparent; + content: ""; + } + +/* Directions */ + +.leaflet-tooltip-bottom { + margin-top: 6px; +} +.leaflet-tooltip-top { + margin-top: -6px; +} +.leaflet-tooltip-bottom:before, +.leaflet-tooltip-top:before { + left: 50%; + margin-left: -6px; + } +.leaflet-tooltip-top:before { + bottom: 0; + margin-bottom: -12px; + border-top-color: #fff; + } +.leaflet-tooltip-bottom:before { + top: 0; + margin-top: -12px; + margin-left: -6px; + border-bottom-color: #fff; + } +.leaflet-tooltip-left { + margin-left: -6px; +} +.leaflet-tooltip-right { + margin-left: 6px; +} +.leaflet-tooltip-left:before, +.leaflet-tooltip-right:before { + top: 50%; + margin-top: -6px; + } +.leaflet-tooltip-left:before { + right: 0; + margin-right: -12px; + border-left-color: #fff; + } +.leaflet-tooltip-right:before { + left: 0; + margin-left: -12px; + border-right-color: #fff; + } + +/* Printing */ + +@media print { + /* Prevent printers from removing background-images of controls. */ + .leaflet-control { + -webkit-print-color-adjust: exact; + print-color-adjust: exact; + } + } diff --git a/web_leaflet_lib/static/lib/leaflet/leaflet.js b/web_leaflet_lib/static/lib/leaflet/leaflet.js new file mode 100644 index 000000000..a3bf693d0 --- /dev/null +++ b/web_leaflet_lib/static/lib/leaflet/leaflet.js @@ -0,0 +1,6 @@ +/* @preserve + * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com + * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade + */ +!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).leaflet={})}(this,function(t){"use strict";function l(t){for(var e,i,n=1,o=arguments.length;n=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=_(t);var e=this.min,i=this.max,n=t.min,t=t.max,o=t.x>=e.x&&n.x<=i.x,t=t.y>=e.y&&n.y<=i.y;return o&&t},overlaps:function(t){t=_(t);var e=this.min,i=this.max,n=t.min,t=t.max,o=t.x>e.x&&n.xe.y&&n.y=n.lat&&i.lat<=o.lat&&e.lng>=n.lng&&i.lng<=o.lng},intersects:function(t){t=g(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),t=t.getNorthEast(),o=t.lat>=e.lat&&n.lat<=i.lat,t=t.lng>=e.lng&&n.lng<=i.lng;return o&&t},overlaps:function(t){t=g(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),t=t.getNorthEast(),o=t.lat>e.lat&&n.late.lng&&n.lng","http://www.w3.org/2000/svg"===(Wt.firstChild&&Wt.firstChild.namespaceURI));function y(t){return 0<=navigator.userAgent.toLowerCase().indexOf(t)}var b={ie:pt,ielt9:mt,edge:n,webkit:ft,android:gt,android23:vt,androidStock:yt,opera:xt,chrome:wt,gecko:bt,safari:Pt,phantom:Lt,opera12:o,win:Tt,ie3d:Mt,webkit3d:zt,gecko3d:_t,any3d:Ct,mobile:Zt,mobileWebkit:St,mobileWebkit3d:Et,msPointer:kt,pointer:Ot,touch:Bt,touchNative:At,mobileOpera:It,mobileGecko:Rt,retina:Nt,passiveEvents:Dt,canvas:jt,svg:Ht,vml:!Ht&&function(){try{var t=document.createElement("div"),e=(t.innerHTML='',t.firstChild);return e.style.behavior="url(#default#VML)",e&&"object"==typeof e.adj}catch(t){return!1}}(),inlineSvg:Wt,mac:0===navigator.platform.indexOf("Mac"),linux:0===navigator.platform.indexOf("Linux")},Ft=b.msPointer?"MSPointerDown":"pointerdown",Ut=b.msPointer?"MSPointerMove":"pointermove",Vt=b.msPointer?"MSPointerUp":"pointerup",qt=b.msPointer?"MSPointerCancel":"pointercancel",Gt={touchstart:Ft,touchmove:Ut,touchend:Vt,touchcancel:qt},Kt={touchstart:function(t,e){e.MSPOINTER_TYPE_TOUCH&&e.pointerType===e.MSPOINTER_TYPE_TOUCH&&O(e);ee(t,e)},touchmove:ee,touchend:ee,touchcancel:ee},Yt={},Xt=!1;function Jt(t,e,i){return"touchstart"!==e||Xt||(document.addEventListener(Ft,$t,!0),document.addEventListener(Ut,Qt,!0),document.addEventListener(Vt,te,!0),document.addEventListener(qt,te,!0),Xt=!0),Kt[e]?(i=Kt[e].bind(this,i),t.addEventListener(Gt[e],i,!1),i):(console.warn("wrong event specified:",e),u)}function $t(t){Yt[t.pointerId]=t}function Qt(t){Yt[t.pointerId]&&(Yt[t.pointerId]=t)}function te(t){delete Yt[t.pointerId]}function ee(t,e){if(e.pointerType!==(e.MSPOINTER_TYPE_MOUSE||"mouse")){for(var i in e.touches=[],Yt)e.touches.push(Yt[i]);e.changedTouches=[e],t(e)}}var ie=200;function ne(t,i){t.addEventListener("dblclick",i);var n,o=0;function e(t){var e;1!==t.detail?n=t.detail:"mouse"===t.pointerType||t.sourceCapabilities&&!t.sourceCapabilities.firesTouchEvents||((e=Ne(t)).some(function(t){return t instanceof HTMLLabelElement&&t.attributes.for})&&!e.some(function(t){return t instanceof HTMLInputElement||t instanceof HTMLSelectElement})||((e=Date.now())-o<=ie?2===++n&&i(function(t){var e,i,n={};for(i in t)e=t[i],n[i]=e&&e.bind?e.bind(t):e;return(t=n).type="dblclick",n.detail=2,n.isTrusted=!1,n._simulated=!0,n}(t)):n=1,o=e))}return t.addEventListener("click",e),{dblclick:i,simDblclick:e}}var oe,se,re,ae,he,le,ue=we(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),ce=we(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===ce||"OTransition"===ce?ce+"End":"transitionend";function _e(t){return"string"==typeof t?document.getElementById(t):t}function pe(t,e){var i=t.style[e]||t.currentStyle&&t.currentStyle[e];return"auto"===(i=i&&"auto"!==i||!document.defaultView?i:(t=document.defaultView.getComputedStyle(t,null))?t[e]:null)?null:i}function P(t,e,i){t=document.createElement(t);return t.className=e||"",i&&i.appendChild(t),t}function T(t){var e=t.parentNode;e&&e.removeChild(t)}function me(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function fe(t){var e=t.parentNode;e&&e.lastChild!==t&&e.appendChild(t)}function ge(t){var e=t.parentNode;e&&e.firstChild!==t&&e.insertBefore(t,e.firstChild)}function ve(t,e){return void 0!==t.classList?t.classList.contains(e):0<(t=xe(t)).length&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(t)}function M(t,e){var i;if(void 0!==t.classList)for(var n=F(e),o=0,s=n.length;othis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,e){this._enforcingBounds=!0;var i=this.getCenter(),t=this._limitCenter(i,this._zoom,g(t));return i.equals(t)||this.panTo(t,e),this._enforcingBounds=!1,this},panInside:function(t,e){var i=m((e=e||{}).paddingTopLeft||e.padding||[0,0]),n=m(e.paddingBottomRight||e.padding||[0,0]),o=this.project(this.getCenter()),t=this.project(t),s=this.getPixelBounds(),i=_([s.min.add(i),s.max.subtract(n)]),s=i.getSize();return i.contains(t)||(this._enforcingBounds=!0,n=t.subtract(i.getCenter()),i=i.extend(t).getSize().subtract(s),o.x+=n.x<0?-i.x:i.x,o.y+=n.y<0?-i.y:i.y,this.panTo(this.unproject(o),e),this._enforcingBounds=!1),this},invalidateSize:function(t){if(!this._loaded)return this;t=l({animate:!1,pan:!0},!0===t?{animate:!0}:t);var e=this.getSize(),i=(this._sizeChanged=!0,this._lastCenter=null,this.getSize()),n=e.divideBy(2).round(),o=i.divideBy(2).round(),n=n.subtract(o);return n.x||n.y?(t.animate&&t.pan?this.panBy(n):(t.pan&&this._rawPanBy(n),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(a(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){var e,i;return t=this._locateOptions=l({timeout:1e4,watch:!1},t),"geolocation"in navigator?(e=a(this._handleGeolocationResponse,this),i=a(this._handleGeolocationError,this),t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t)):this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e;this._container._leaflet_id&&(e=t.code,t=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout"),this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+t+"."}))},_handleGeolocationResponse:function(t){if(this._container._leaflet_id){var e,i,n=new v(t.coords.latitude,t.coords.longitude),o=n.toBounds(2*t.coords.accuracy),s=this._locateOptions,r=(s.setView&&(e=this.getBoundsZoom(o),this.setView(n,s.maxZoom?Math.min(e,s.maxZoom):e)),{latlng:n,bounds:o,timestamp:t.timestamp});for(i in t.coords)"number"==typeof t.coords[i]&&(r[i]=t.coords[i]);this.fire("locationfound",r)}},addHandler:function(t,e){return e&&(e=this[t]=new e(this),this._handlers.push(e),this.options[t]&&e.enable()),this},remove:function(){if(this._initEvents(!0),this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}for(var t in void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),T(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(r(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload"),this._layers)this._layers[t].remove();for(t in this._panes)T(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,e){e=P("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),e||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter.clone():this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new s(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=g(t),i=m(i||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),t=t.getSouthEast(),i=this.getSize().subtract(i),t=_(this.project(t,n),this.project(r,n)).getSize(),r=b.any3d?this.options.zoomSnap:1,a=i.x/t.x,i=i.y/t.y,t=e?Math.max(a,i):Math.min(a,i),n=this.getScaleZoom(t,n);return r&&(n=Math.round(n/(r/100))*(r/100),n=e?Math.ceil(n/r)*r:Math.floor(n/r)*r),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new p(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,e){t=this._getTopLeftPoint(t,e);return new f(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,e){var i=this.options.crs;return e=void 0===e?this._zoom:e,i.scale(t)/i.scale(e)},getScaleZoom:function(t,e){var i=this.options.crs,t=(e=void 0===e?this._zoom:e,i.zoom(t*i.scale(e)));return isNaN(t)?1/0:t},project:function(t,e){return e=void 0===e?this._zoom:e,this.options.crs.latLngToPoint(w(t),e)},unproject:function(t,e){return e=void 0===e?this._zoom:e,this.options.crs.pointToLatLng(m(t),e)},layerPointToLatLng:function(t){t=m(t).add(this.getPixelOrigin());return this.unproject(t)},latLngToLayerPoint:function(t){return this.project(w(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(w(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(g(t))},distance:function(t,e){return this.options.crs.distance(w(t),w(e))},containerPointToLayerPoint:function(t){return m(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return m(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){t=this.containerPointToLayerPoint(m(t));return this.layerPointToLatLng(t)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(w(t)))},mouseEventToContainerPoint:function(t){return De(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){t=this._container=_e(t);if(!t)throw new Error("Map container not found.");if(t._leaflet_id)throw new Error("Map container is already initialized.");S(t,"scroll",this._onScroll,this),this._containerId=h(t)},_initLayout:function(){var t=this._container,e=(this._fadeAnimated=this.options.fadeAnimation&&b.any3d,M(t,"leaflet-container"+(b.touch?" leaflet-touch":"")+(b.retina?" leaflet-retina":"")+(b.ielt9?" leaflet-oldie":"")+(b.safari?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":"")),pe(t,"position"));"absolute"!==e&&"relative"!==e&&"fixed"!==e&&"sticky"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Z(this._mapPane,new p(0,0)),this.createPane("tilePane"),this.createPane("overlayPane"),this.createPane("shadowPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(M(t.markerPane,"leaflet-zoom-hide"),M(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,e,i){Z(this._mapPane,new p(0,0));var n=!this._loaded,o=(this._loaded=!0,e=this._limitZoom(e),this.fire("viewprereset"),this._zoom!==e);this._moveStart(o,i)._move(t,e)._moveEnd(o),this.fire("viewreset"),n&&this.fire("load")},_moveStart:function(t,e){return t&&this.fire("zoomstart"),e||this.fire("movestart"),this},_move:function(t,e,i,n){void 0===e&&(e=this._zoom);var o=this._zoom!==e;return this._zoom=e,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),n?i&&i.pinch&&this.fire("zoom",i):((o||i&&i.pinch)&&this.fire("zoom",i),this.fire("move",i)),this},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return r(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Z(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={};var e=t?k:S;e((this._targets[h(this._container)]=this)._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress keydown keyup",this._handleDOMEvent,this),this.options.trackResize&&e(window,"resize",this._onResize,this),b.any3d&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){r(this._resizeRequest),this._resizeRequest=x(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i,n=[],o="mouseout"===e||"mouseover"===e,s=t.target||t.srcElement,r=!1;s;){if((i=this._targets[h(s)])&&("click"===e||"preclick"===e)&&this._draggableMoved(i)){r=!0;break}if(i&&i.listens(e,!0)){if(o&&!We(s,t))break;if(n.push(i),o)break}if(s===this._container)break;s=s.parentNode}return n=n.length||r||o||!this.listens(e,!0)?n:[this]},_isClickDisabled:function(t){for(;t&&t!==this._container;){if(t._leaflet_disable_click)return!0;t=t.parentNode}},_handleDOMEvent:function(t){var e,i=t.target||t.srcElement;!this._loaded||i._leaflet_disable_events||"click"===t.type&&this._isClickDisabled(i)||("mousedown"===(e=t.type)&&Me(i),this._fireDOMEvent(t,e))},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,i){"click"===t.type&&((a=l({},t)).type="preclick",this._fireDOMEvent(a,a.type,i));var n=this._findEventTargets(t,e);if(i){for(var o=[],s=0;sthis.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),n=this._getCenterOffset(t)._divideBy(1-1/n);if(!0!==i.animate&&!this.getSize().contains(n))return!1;x(function(){this._moveStart(!0,i.noMoveStart||!1)._animateZoom(t,e,!0)},this)}return!0},_animateZoom:function(t,e,i,n){this._mapPane&&(i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,M(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:n}),this._tempFireZoomEvent||(this._tempFireZoomEvent=this._zoom!==this._animateToZoom),this._move(this._animateToCenter,this._animateToZoom,void 0,!0),setTimeout(a(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&z(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._tempFireZoomEvent&&this.fire("zoom"),delete this._tempFireZoomEvent,this.fire("move"),this._moveEnd(!0))}});function Ue(t){return new B(t)}var B=et.extend({options:{position:"topright"},initialize:function(t){c(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),t=t._controlCorners[i];return M(e,"leaflet-control"),-1!==i.indexOf("bottom")?t.insertBefore(e,t.firstChild):t.appendChild(e),this._map.on("unload",this.remove,this),this},remove:function(){return this._map&&(T(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null),this},_refocusOnMap:function(t){this._map&&t&&0",e=document.createElement("div");return e.innerHTML=t,e.firstChild},_addItem:function(t){var e,i=document.createElement("label"),n=this._map.hasLayer(t.layer),n=(t.overlay?((e=document.createElement("input")).type="checkbox",e.className="leaflet-control-layers-selector",e.defaultChecked=n):e=this._createRadioElement("leaflet-base-layers_"+h(this),n),this._layerControlInputs.push(e),e.layerId=h(t.layer),S(e,"click",this._onInputClick,this),document.createElement("span")),o=(n.innerHTML=" "+t.name,document.createElement("span"));return i.appendChild(o),o.appendChild(e),o.appendChild(n),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(i),this._checkDisabledLayers(),i},_onInputClick:function(){if(!this._preventClick){var t,e,i=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=i.length-1;0<=s;s--)t=i[s],e=this._getLayer(t.layerId).layer,t.checked?n.push(e):t.checked||o.push(e);for(s=0;se.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expandSafely:function(){var t=this._section,e=(this._preventClick=!0,S(t,"click",O),this.expand(),this);setTimeout(function(){k(t,"click",O),e._preventClick=!1})}})),qe=B.extend({options:{position:"topleft",zoomInText:'',zoomInTitle:"Zoom in",zoomOutText:'',zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=P("div",e+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,n,o){i=P("a",i,n);return i.innerHTML=t,i.href="#",i.title=e,i.setAttribute("role","button"),i.setAttribute("aria-label",e),Ie(i),S(i,"click",Re),S(i,"click",o,this),S(i,"click",this._refocusOnMap,this),i},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";z(this._zoomInButton,e),z(this._zoomOutButton,e),this._zoomInButton.setAttribute("aria-disabled","false"),this._zoomOutButton.setAttribute("aria-disabled","false"),!this._disabled&&t._zoom!==t.getMinZoom()||(M(this._zoomOutButton,e),this._zoomOutButton.setAttribute("aria-disabled","true")),!this._disabled&&t._zoom!==t.getMaxZoom()||(M(this._zoomInButton,e),this._zoomInButton.setAttribute("aria-disabled","true"))}}),Ge=(A.mergeOptions({zoomControl:!0}),A.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new qe,this.addControl(this.zoomControl))}),B.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=P("div",e),n=this.options;return this._addScales(n,e+"-line",i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=P("div",e,i)),t.imperial&&(this._iScale=P("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,t=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(t)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t);this._updateScale(this._mScale,e<1e3?e+" m":e/1e3+" km",e/t)},_updateImperial:function(t){var e,i,t=3.2808399*t;5280'+(b.inlineSvg?' ':"")+"Leaflet"},initialize:function(t){c(this,t),this._attributions={}},onAdd:function(t){for(var e in(t.attributionControl=this)._container=P("div","leaflet-control-attribution"),Ie(this._container),t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),t.on("layeradd",this._addAttribution,this),this._container},onRemove:function(t){t.off("layeradd",this._addAttribution,this)},_addAttribution:function(t){t.layer.getAttribution&&(this.addAttribution(t.layer.getAttribution()),t.layer.once("remove",function(){this.removeAttribution(t.layer.getAttribution())},this))},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t&&(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update()),this},removeAttribution:function(t){return t&&this._attributions[t]&&(this._attributions[t]--,this._update()),this},_update:function(){if(this._map){var t,e=[];for(t in this._attributions)this._attributions[t]&&e.push(t);var i=[];this.options.prefix&&i.push(this.options.prefix),e.length&&i.push(e.join(", ")),this._container.innerHTML=i.join(' ')}}}),n=(A.mergeOptions({attributionControl:!0}),A.addInitHook(function(){this.options.attributionControl&&(new Ke).addTo(this)}),B.Layers=Ve,B.Zoom=qe,B.Scale=Ge,B.Attribution=Ke,Ue.layers=function(t,e,i){return new Ve(t,e,i)},Ue.zoom=function(t){return new qe(t)},Ue.scale=function(t){return new Ge(t)},Ue.attribution=function(t){return new Ke(t)},et.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled||(this._enabled=!0,this.addHooks()),this},disable:function(){return this._enabled&&(this._enabled=!1,this.removeHooks()),this},enabled:function(){return!!this._enabled}})),ft=(n.addTo=function(t,e){return t.addHandler(e,this),this},{Events:e}),Ye=b.touch?"touchstart mousedown":"mousedown",Xe=it.extend({options:{clickTolerance:3},initialize:function(t,e,i,n){c(this,n),this._element=t,this._dragStartTarget=e||t,this._preventOutline=i},enable:function(){this._enabled||(S(this._dragStartTarget,Ye,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Xe._dragging===this&&this.finishDrag(!0),k(this._dragStartTarget,Ye,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){var e,i;this._enabled&&(this._moved=!1,ve(this._element,"leaflet-zoom-anim")||(t.touches&&1!==t.touches.length?Xe._dragging===this&&this.finishDrag():Xe._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||((Xe._dragging=this)._preventOutline&&Me(this._element),Le(),re(),this._moving||(this.fire("down"),i=t.touches?t.touches[0]:t,e=Ce(this._element),this._startPoint=new p(i.clientX,i.clientY),this._startPos=Pe(this._element),this._parentScale=Ze(e),i="mousedown"===t.type,S(document,i?"mousemove":"touchmove",this._onMove,this),S(document,i?"mouseup":"touchend touchcancel",this._onUp,this)))))},_onMove:function(t){var e;this._enabled&&(t.touches&&1e&&(i.push(t[n]),o=n);oe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i}function ri(t,e,i,n){var o=e.x,e=e.y,s=i.x-o,r=i.y-e,a=s*s+r*r;return 0this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(l=!l);return l||yi.prototype._containsPoint.call(this,t,!0)}});var wi=ci.extend({initialize:function(t,e){c(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,o=d(t)?t:t.features;if(o){for(e=0,i=o.length;es.x&&(r=i.x+a-s.x+o.x),i.x-r-n.x<(a=0)&&(r=i.x-n.x),i.y+e+o.y>s.y&&(a=i.y+e-s.y+o.y),i.y-a-n.y<0&&(a=i.y-n.y),(r||a)&&(this.options.keepInView&&(this._autopanning=!0),t.fire("autopanstart").panBy([r,a]))))},_getAnchor:function(){return m(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}})),Ii=(A.mergeOptions({closePopupOnClick:!0}),A.include({openPopup:function(t,e,i){return this._initOverlay(Bi,t,e,i).openOn(this),this},closePopup:function(t){return(t=arguments.length?t:this._popup)&&t.close(),this}}),o.include({bindPopup:function(t,e){return this._popup=this._initOverlay(Bi,this._popup,t,e),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t){return this._popup&&(this instanceof ci||(this._popup._source=this),this._popup._prepareOpen(t||this._latlng)&&this._popup.openOn(this._map)),this},closePopup:function(){return this._popup&&this._popup.close(),this},togglePopup:function(){return this._popup&&this._popup.toggle(this),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var e;this._popup&&this._map&&(Re(t),e=t.layer||t.target,this._popup._source!==e||e instanceof fi?(this._popup._source=e,this.openPopup(t.latlng)):this._map.hasLayer(this._popup)?this.closePopup():this.openPopup(t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}}),Ai.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,opacity:.9},onAdd:function(t){Ai.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&(this.addEventParent(this._source),this._source.fire("tooltipopen",{tooltip:this},!0))},onRemove:function(t){Ai.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&(this.removeEventParent(this._source),this._source.fire("tooltipclose",{tooltip:this},!0))},getEvents:function(){var t=Ai.prototype.getEvents.call(this);return this.options.permanent||(t.preclick=this.close),t},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=P("div",t),this._container.setAttribute("role","tooltip"),this._container.setAttribute("id","leaflet-tooltip-"+h(this))},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e,i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),i=i.layerPointToContainerPoint(t),s=this.options.direction,r=n.offsetWidth,a=n.offsetHeight,h=m(this.options.offset),l=this._getAnchor(),i="top"===s?(e=r/2,a):"bottom"===s?(e=r/2,0):(e="center"===s?r/2:"right"===s?0:"left"===s?r:i.xthis.options.maxZoom||nthis.options.maxZoom||void 0!==this.options.minZoom&&oi.max.x)||!e.wrapLat&&(t.yi.max.y))return!1}return!this.options.bounds||(e=this._tileCoordsToBounds(t),g(this.options.bounds).overlaps(e))},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var e=this._map,i=this.getTileSize(),n=t.scaleBy(i),i=n.add(i);return[e.unproject(n,t.z),e.unproject(i,t.z)]},_tileCoordsToBounds:function(t){t=this._tileCoordsToNwSe(t),t=new s(t[0],t[1]);return t=this.options.noWrap?t:this._map.wrapLatLngBounds(t)},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var t=t.split(":"),e=new p(+t[0],+t[1]);return e.z=+t[2],e},_removeTile:function(t){var e=this._tiles[t];e&&(T(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){M(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=u,t.onmousemove=u,b.ielt9&&this.options.opacity<1&&C(t,this.options.opacity)},_addTile:function(t,e){var i=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),a(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&x(a(this._tileReady,this,t,null,o)),Z(o,i),this._tiles[n]={el:o,coords:t,current:!0},e.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,e,i){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var n=this._tileCoordsToKey(t);(i=this._tiles[n])&&(i.loaded=+new Date,this._map._fadeAnimated?(C(i.el,0),r(this._fadeFrame),this._fadeFrame=x(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(M(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),b.ielt9||!this._map._fadeAnimated?x(this._pruneTiles,this):setTimeout(a(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new p(this._wrapX?H(t.x,this._wrapX):t.x,this._wrapY?H(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new f(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});var Di=Ni.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1,referrerPolicy:!1},initialize:function(t,e){this._url=t,(e=c(this,e)).detectRetina&&b.retina&&0')}}catch(t){}return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}(),zt={_initContainer:function(){this._container=P("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(Wi.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=Vi("shape");M(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=Vi("path"),e.appendChild(t._path),this._updateStyle(t),this._layers[h(t)]=t},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;T(e),t.removeInteractiveTarget(e),delete this._layers[h(t)]},_updateStyle:function(t){var e=t._stroke,i=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(e=e||(t._stroke=Vi("stroke")),o.appendChild(e),e.weight=n.weight+"px",e.color=n.color,e.opacity=n.opacity,n.dashArray?e.dashStyle=d(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=n.lineCap.replace("butt","flat"),e.joinstyle=n.lineJoin):e&&(o.removeChild(e),t._stroke=null),n.fill?(i=i||(t._fill=Vi("fill")),o.appendChild(i),i.color=n.fillColor||n.color,i.opacity=n.fillOpacity):i&&(o.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,23592600")},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){fe(t._container)},_bringToBack:function(t){ge(t._container)}},qi=b.vml?Vi:ct,Gi=Wi.extend({_initContainer:function(){this._container=qi("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=qi("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){T(this._container),k(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_update:function(){var t,e,i;this._map._animatingZoom&&this._bounds||(Wi.prototype._update.call(this),e=(t=this._bounds).getSize(),i=this._container,this._svgSize&&this._svgSize.equals(e)||(this._svgSize=e,i.setAttribute("width",e.x),i.setAttribute("height",e.y)),Z(i,t.min),i.setAttribute("viewBox",[t.min.x,t.min.y,e.x,e.y].join(" ")),this.fire("update"))},_initPath:function(t){var e=t._path=qi("path");t.options.className&&M(e,t.options.className),t.options.interactive&&M(e,"leaflet-interactive"),this._updateStyle(t),this._layers[h(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){T(t._path),t.removeInteractiveTarget(t._path),delete this._layers[h(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var e=t._path,t=t.options;e&&(t.stroke?(e.setAttribute("stroke",t.color),e.setAttribute("stroke-opacity",t.opacity),e.setAttribute("stroke-width",t.weight),e.setAttribute("stroke-linecap",t.lineCap),e.setAttribute("stroke-linejoin",t.lineJoin),t.dashArray?e.setAttribute("stroke-dasharray",t.dashArray):e.removeAttribute("stroke-dasharray"),t.dashOffset?e.setAttribute("stroke-dashoffset",t.dashOffset):e.removeAttribute("stroke-dashoffset")):e.setAttribute("stroke","none"),t.fill?(e.setAttribute("fill",t.fillColor||t.color),e.setAttribute("fill-opacity",t.fillOpacity),e.setAttribute("fill-rule",t.fillRule||"evenodd")):e.setAttribute("fill","none"))},_updatePoly:function(t,e){this._setPath(t,dt(t._parts,e))},_updateCircle:function(t){var e=t._point,i=Math.max(Math.round(t._radius),1),n="a"+i+","+(Math.max(Math.round(t._radiusY),1)||i)+" 0 1,0 ",e=t._empty()?"M0 0":"M"+(e.x-i)+","+e.y+n+2*i+",0 "+n+2*-i+",0 ";this._setPath(t,e)},_setPath:function(t,e){t._path.setAttribute("d",e)},_bringToFront:function(t){fe(t._path)},_bringToBack:function(t){ge(t._path)}});function Ki(t){return b.svg||b.vml?new Gi(t):null}b.vml&&Gi.include(zt),A.include({getRenderer:function(t){t=(t=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer)||(this._renderer=this._createRenderer());return this.hasLayer(t)||this.addLayer(t),t},_getPaneRenderer:function(t){var e;return"overlayPane"!==t&&void 0!==t&&(void 0===(e=this._paneRenderers[t])&&(e=this._createRenderer({pane:t}),this._paneRenderers[t]=e),e)},_createRenderer:function(t){return this.options.preferCanvas&&Ui(t)||Ki(t)}});var Yi=xi.extend({initialize:function(t,e){xi.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return[(t=g(t)).getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});Gi.create=qi,Gi.pointsToPath=dt,wi.geometryToLayer=bi,wi.coordsToLatLng=Li,wi.coordsToLatLngs=Ti,wi.latLngToCoords=Mi,wi.latLngsToCoords=zi,wi.getFeature=Ci,wi.asFeature=Zi,A.mergeOptions({boxZoom:!0});var _t=n.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){S(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){k(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){T(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),re(),Le(),this._startPoint=this._map.mouseEventToContainerPoint(t),S(document,{contextmenu:Re,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=P("div","leaflet-zoom-box",this._container),M(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var t=new f(this._point,this._startPoint),e=t.getSize();Z(this._box,t.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(T(this._box),z(this._container,"leaflet-crosshair")),ae(),Te(),k(document,{contextmenu:Re,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){1!==t.which&&1!==t.button||(this._finish(),this._moved&&(this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(a(this._resetState,this),0),t=new s(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point)),this._map.fitBounds(t).fire("boxzoomend",{boxZoomBounds:t})))},_onKeyDown:function(t){27===t.keyCode&&(this._finish(),this._clearDeferredResetState(),this._resetState())}}),Ct=(A.addInitHook("addHandler","boxZoom",_t),A.mergeOptions({doubleClickZoom:!0}),n.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom(),n=e.options.zoomDelta,i=t.originalEvent.shiftKey?i-n:i+n;"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}})),Zt=(A.addInitHook("addHandler","doubleClickZoom",Ct),A.mergeOptions({dragging:!0,inertia:!0,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0}),n.extend({addHooks:function(){var t;this._draggable||(t=this._map,this._draggable=new Xe(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))),M(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){z(this._map._container,"leaflet-grab"),z(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t,e=this._map;e._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity?(t=g(this._map.options.maxBounds),this._offsetLimit=_(this._map.latLngToContainerPoint(t.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(t.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))):this._offsetLimit=null,e.fire("movestart").fire("dragstart"),e.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){var e,i;this._map.options.inertia&&(e=this._lastTime=+new Date,i=this._lastPos=this._draggable._absPos||this._draggable._newPos,this._positions.push(i),this._times.push(e),this._prunePositions(e)),this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;1e.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t))},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,n=(n+e+i)%t-e-i,t=Math.abs(o+i)e.getMaxZoom()&&1 Date: Tue, 29 Oct 2024 10:14:52 +0000 Subject: [PATCH 02/21] [UPD] Update web_leaflet_lib.pot --- web_leaflet_lib/i18n/fr.po | 1 + web_leaflet_lib/i18n/web_leaflet_lib.pot | 19 +++++++++++++++++++ 2 files changed, 20 insertions(+) create mode 100644 web_leaflet_lib/i18n/web_leaflet_lib.pot diff --git a/web_leaflet_lib/i18n/fr.po b/web_leaflet_lib/i18n/fr.po index a8b2b7c66..40589a830 100644 --- a/web_leaflet_lib/i18n/fr.po +++ b/web_leaflet_lib/i18n/fr.po @@ -10,6 +10,7 @@ msgstr "" "PO-Revision-Date: 2024-10-12 20:11+0000\n" "Last-Translator: \n" "Language-Team: \n" +"Language: \n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" diff --git a/web_leaflet_lib/i18n/web_leaflet_lib.pot b/web_leaflet_lib/i18n/web_leaflet_lib.pot new file mode 100644 index 000000000..09c74a5c3 --- /dev/null +++ b/web_leaflet_lib/i18n/web_leaflet_lib.pot @@ -0,0 +1,19 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_leaflet_lib +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 16.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: \n" +"Language-Team: \n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: \n" + +#. module: web_leaflet_lib +#: model:ir.model,name:web_leaflet_lib.model_ir_http +msgid "HTTP Routing" +msgstr "" From 2835715dc2f470d9a7593e9abbdff1c6c8d7d387 Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Tue, 29 Oct 2024 11:25:05 +0100 Subject: [PATCH 03/21] [IMP] web_leaflet_lib: pre-commit stuff --- web_leaflet_lib/README.rst | 54 ++++++++++--------- web_leaflet_lib/pyproject.toml | 3 ++ web_leaflet_lib/readme/CONFIGURE.md | 4 ++ web_leaflet_lib/readme/CONFIGURE.rst | 5 -- web_leaflet_lib/readme/CONTRIBUTORS.md | 1 + web_leaflet_lib/readme/CONTRIBUTORS.rst | 1 - .../readme/{CREDITS.rst => CREDITS.md} | 0 web_leaflet_lib/readme/DESCRIPTION.md | 29 ++++++++++ web_leaflet_lib/readme/DESCRIPTION.rst | 24 --------- web_leaflet_lib/static/description/index.html | 33 +++++++----- 10 files changed, 86 insertions(+), 68 deletions(-) create mode 100644 web_leaflet_lib/pyproject.toml create mode 100644 web_leaflet_lib/readme/CONFIGURE.md delete mode 100644 web_leaflet_lib/readme/CONFIGURE.rst create mode 100644 web_leaflet_lib/readme/CONTRIBUTORS.md delete mode 100644 web_leaflet_lib/readme/CONTRIBUTORS.rst rename web_leaflet_lib/readme/{CREDITS.rst => CREDITS.md} (100%) create mode 100644 web_leaflet_lib/readme/DESCRIPTION.md delete mode 100644 web_leaflet_lib/readme/DESCRIPTION.rst diff --git a/web_leaflet_lib/README.rst b/web_leaflet_lib/README.rst index 6681def66..c52849b0c 100644 --- a/web_leaflet_lib/README.rst +++ b/web_leaflet_lib/README.rst @@ -17,13 +17,13 @@ Leaflet Javascript Library :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fgeospatial-lightgray.png?logo=github - :target: https://github.com/OCA/geospatial/tree/16.0/web_leaflet_lib + :target: https://github.com/OCA/geospatial/tree/17.0/web_leaflet_lib :alt: OCA/geospatial .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/geospatial-16-0/geospatial-16-0-web_leaflet_lib + :target: https://translation.odoo-community.org/projects/geospatial-17-0/geospatial-17-0-web_leaflet_lib :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=16.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=17.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -34,24 +34,29 @@ This module is used by ``web_view_leaflet_map``. **Important Note** -The javascript library is opensource and distributed under BSD 2 Licence. -See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE -You can so use it freely. +The javascript library is opensource and distributed under BSD 2 +Licence. See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE You +can so use it freely. -However, display maps requires to display layers provided by tiles servers, that -requires ressources. +However, display maps requires to display layers provided by tiles +servers, that requires ressources. **For testing purpose** -You can use the openStreetMap url ``https://tile.openstreetmap.org/{z}/{x}/{y}.png`` or other, listed in that page : https://wiki.openstreetmap.org/wiki/Tile_servers +You can use the openStreetMap url +``https://tile.openstreetmap.org/{z}/{x}/{y}.png`` or other, listed in +that page : https://wiki.openstreetmap.org/wiki/Tile_servers -Apart from very limited testing purposes, you should not use the tiles supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run non-profit body and cannot supply tiles for large-scale commercial use. +Apart from very limited testing purposes, you should not use the tiles +supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run +non-profit body and cannot supply tiles for large-scale commercial use. **Regular / High Usage** -- you can contact one of the following companies : https://switch2osm.org/providers/ - -- You can also install yourself your own tiles servers. See documentation : https://switch2osm.org/serving-tiles/ +- you can contact one of the following companies : + https://switch2osm.org/providers/ +- You can also install yourself your own tiles servers. See + documentation : https://switch2osm.org/serving-tiles/ **Table of contents** @@ -61,11 +66,10 @@ Apart from very limited testing purposes, you should not use the tiles supplied Configuration ============= -* Go to Settings > Technical > Parameters > System Parameters - -* Create or edit the parameter with the key ``leaflet.tile_url`` - -* As a value, set the url of the tiles server you chose. (See description) +- Go to Settings > Technical > Parameters > System Parameters +- Create or edit the parameter with the key ``leaflet.tile_url`` +- As a value, set the url of the tiles server you chose. (See + description) Bug Tracker =========== @@ -73,7 +77,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -81,22 +85,22 @@ Credits ======= Authors -~~~~~~~ +------- * GRAP Contributors -~~~~~~~~~~~~ +------------ -* Sylvain LE GAL (https://www.twitter.com/legalsylvain) +- Sylvain LE GAL (https://www.twitter.com/legalsylvain) Other credits -~~~~~~~~~~~~~ +------------- The module embed the Leaflet.js library. Maintainers -~~~~~~~~~~~ +----------- This module is maintained by the OCA. @@ -116,6 +120,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/geospatial `_ project on GitHub. +This module is part of the `OCA/geospatial `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_leaflet_lib/pyproject.toml b/web_leaflet_lib/pyproject.toml new file mode 100644 index 000000000..4231d0ccc --- /dev/null +++ b/web_leaflet_lib/pyproject.toml @@ -0,0 +1,3 @@ +[build-system] +requires = ["whool"] +build-backend = "whool.buildapi" diff --git a/web_leaflet_lib/readme/CONFIGURE.md b/web_leaflet_lib/readme/CONFIGURE.md new file mode 100644 index 000000000..6c07774f0 --- /dev/null +++ b/web_leaflet_lib/readme/CONFIGURE.md @@ -0,0 +1,4 @@ +- Go to Settings \> Technical \> Parameters \> System Parameters +- Create or edit the parameter with the key `leaflet.tile_url` +- As a value, set the url of the tiles server you chose. (See + description) diff --git a/web_leaflet_lib/readme/CONFIGURE.rst b/web_leaflet_lib/readme/CONFIGURE.rst deleted file mode 100644 index cf45731ce..000000000 --- a/web_leaflet_lib/readme/CONFIGURE.rst +++ /dev/null @@ -1,5 +0,0 @@ -* Go to Settings > Technical > Parameters > System Parameters - -* Create or edit the parameter with the key ``leaflet.tile_url`` - -* As a value, set the url of the tiles server you chose. (See description) diff --git a/web_leaflet_lib/readme/CONTRIBUTORS.md b/web_leaflet_lib/readme/CONTRIBUTORS.md new file mode 100644 index 000000000..4a6b63400 --- /dev/null +++ b/web_leaflet_lib/readme/CONTRIBUTORS.md @@ -0,0 +1 @@ +- Sylvain LE GAL () diff --git a/web_leaflet_lib/readme/CONTRIBUTORS.rst b/web_leaflet_lib/readme/CONTRIBUTORS.rst deleted file mode 100644 index e1525ce04..000000000 --- a/web_leaflet_lib/readme/CONTRIBUTORS.rst +++ /dev/null @@ -1 +0,0 @@ -* Sylvain LE GAL (https://www.twitter.com/legalsylvain) diff --git a/web_leaflet_lib/readme/CREDITS.rst b/web_leaflet_lib/readme/CREDITS.md similarity index 100% rename from web_leaflet_lib/readme/CREDITS.rst rename to web_leaflet_lib/readme/CREDITS.md diff --git a/web_leaflet_lib/readme/DESCRIPTION.md b/web_leaflet_lib/readme/DESCRIPTION.md new file mode 100644 index 000000000..dde2a06e9 --- /dev/null +++ b/web_leaflet_lib/readme/DESCRIPTION.md @@ -0,0 +1,29 @@ +This module extends odoo to include Leaflet Javacript library. + +This module is used by `web_view_leaflet_map`. + +**Important Note** + +The javascript library is opensource and distributed under BSD 2 +Licence. See : +You can so use it freely. + +However, display maps requires to display layers provided by tiles +servers, that requires ressources. + +**For testing purpose** + +You can use the openStreetMap url +`https://tile.openstreetmap.org/{z}/{x}/{y}.png` or other, listed in +that page : + +Apart from very limited testing purposes, you should not use the tiles +supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run +non-profit body and cannot supply tiles for large-scale commercial use. + +**Regular / High Usage** + +- you can contact one of the following companies : + +- You can also install yourself your own tiles servers. See + documentation : diff --git a/web_leaflet_lib/readme/DESCRIPTION.rst b/web_leaflet_lib/readme/DESCRIPTION.rst deleted file mode 100644 index 882413671..000000000 --- a/web_leaflet_lib/readme/DESCRIPTION.rst +++ /dev/null @@ -1,24 +0,0 @@ -This module extends odoo to include Leaflet Javacript library. - -This module is used by ``web_view_leaflet_map``. - -**Important Note** - -The javascript library is opensource and distributed under BSD 2 Licence. -See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE -You can so use it freely. - -However, display maps requires to display layers provided by tiles servers, that -requires ressources. - -**For testing purpose** - -You can use the openStreetMap url ``https://tile.openstreetmap.org/{z}/{x}/{y}.png`` or other, listed in that page : https://wiki.openstreetmap.org/wiki/Tile_servers - -Apart from very limited testing purposes, you should not use the tiles supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run non-profit body and cannot supply tiles for large-scale commercial use. - -**Regular / High Usage** - -- you can contact one of the following companies : https://switch2osm.org/providers/ - -- You can also install yourself your own tiles servers. See documentation : https://switch2osm.org/serving-tiles/ diff --git a/web_leaflet_lib/static/description/index.html b/web_leaflet_lib/static/description/index.html index 655af50d8..8dd0e6f20 100644 --- a/web_leaflet_lib/static/description/index.html +++ b/web_leaflet_lib/static/description/index.html @@ -369,22 +369,28 @@

Leaflet Javascript Library

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:e5af47c08dbb573c870e80a506feaccced35a36e61e63c6d39644fa84a357de1 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

This module extends odoo to include Leaflet Javacript library.

This module is used by web_view_leaflet_map.

Important Note

-

The javascript library is opensource and distributed under BSD 2 Licence. -See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE -You can so use it freely.

-

However, display maps requires to display layers provided by tiles servers, that -requires ressources.

+

The javascript library is opensource and distributed under BSD 2 +Licence. See : https://github.com/Leaflet/Leaflet/blob/main/LICENSE You +can so use it freely.

+

However, display maps requires to display layers provided by tiles +servers, that requires ressources.

For testing purpose

-

You can use the openStreetMap url https://tile.openstreetmap.org/{z}/{x}/{y}.png or other, listed in that page : https://wiki.openstreetmap.org/wiki/Tile_servers

-

Apart from very limited testing purposes, you should not use the tiles supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run non-profit body and cannot supply tiles for large-scale commercial use.

+

You can use the openStreetMap url +https://tile.openstreetmap.org/{z}/{x}/{y}.png or other, listed in +that page : https://wiki.openstreetmap.org/wiki/Tile_servers

+

Apart from very limited testing purposes, you should not use the tiles +supplied by OpenStreetMap.org itself. OpenStreetMap is a volunteer-run +non-profit body and cannot supply tiles for large-scale commercial use.

Regular / High Usage

Table of contents

@@ -405,7 +411,8 @@

Configuration

  • Go to Settings > Technical > Parameters > System Parameters
  • Create or edit the parameter with the key leaflet.tile_url
  • -
  • As a value, set the url of the tiles server you chose. (See description)
  • +
  • As a value, set the url of the tiles server you chose. (See +description)
@@ -413,7 +420,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -445,7 +452,7 @@

Maintainers

promote its widespread use.

Current maintainer:

legalsylvain

-

This module is part of the OCA/geospatial project on GitHub.

+

This module is part of the OCA/geospatial project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

From 9abb1a92b9e7cda385cc782b34b64656c1935f0b Mon Sep 17 00:00:00 2001 From: Sylvain LE GAL Date: Tue, 29 Oct 2024 12:28:14 +0100 Subject: [PATCH 04/21] [MIG] web_leaflet_lib. From 16.0 to 17.0 - Bump version. - Remove obsolete hook. (that was usefull during the refactoring done here https://github.com/OCA/geospatial/pull/380) --- web_leaflet_lib/__init__.py | 1 - web_leaflet_lib/__manifest__.py | 3 +-- web_leaflet_lib/hooks.py | 14 -------------- web_leaflet_lib/models/ir_http.py | 2 +- 4 files changed, 2 insertions(+), 18 deletions(-) delete mode 100644 web_leaflet_lib/hooks.py diff --git a/web_leaflet_lib/__init__.py b/web_leaflet_lib/__init__.py index 6d58305f5..0650744f6 100644 --- a/web_leaflet_lib/__init__.py +++ b/web_leaflet_lib/__init__.py @@ -1,2 +1 @@ from . import models -from .hooks import pre_init_hook diff --git a/web_leaflet_lib/__manifest__.py b/web_leaflet_lib/__manifest__.py index 890852e25..73a71dae0 100644 --- a/web_leaflet_lib/__manifest__.py +++ b/web_leaflet_lib/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Leaflet Javascript Library", "summary": "Bring leaflet.js librairy in odoo.", - "version": "16.0.1.0.0", + "version": "17.0.1.0.0", "author": "GRAP, Odoo Community Association (OCA)", "maintainers": ["legalsylvain"], "website": "https://github.com/OCA/geospatial", @@ -21,5 +21,4 @@ ], }, "installable": True, - "pre_init_hook": "pre_init_hook", } diff --git a/web_leaflet_lib/hooks.py b/web_leaflet_lib/hooks.py deleted file mode 100644 index 4cf094ea3..000000000 --- a/web_leaflet_lib/hooks.py +++ /dev/null @@ -1,14 +0,0 @@ -def pre_init_hook(cr): - # move configuration from web_view_leaflet_map - # into web_leaflet_lib, if exists. - cr.execute( - """ - UPDATE ir_model_data - SET module='web_leaflet_lib' - WHERE module = 'web_view_leaflet_map' - AND name in ( - 'config_parameter_leaflet_copyright', - 'config_parameter_leaflet_tile_url' - ) - """ - ) diff --git a/web_leaflet_lib/models/ir_http.py b/web_leaflet_lib/models/ir_http.py index 976035a2c..9fe6aad64 100644 --- a/web_leaflet_lib/models/ir_http.py +++ b/web_leaflet_lib/models/ir_http.py @@ -9,7 +9,7 @@ class Http(models.AbstractModel): _inherit = "ir.http" def session_info(self): - result = super(Http, self).session_info() + result = super().session_info() config = self.env["ir.config_parameter"].sudo() result.update( { From 778a829db2ea55cb7c7681568d02ed8456981168 Mon Sep 17 00:00:00 2001 From: oca-ci Date: Wed, 20 Nov 2024 08:52:39 +0000 Subject: [PATCH 05/21] [UPD] Update web_leaflet_lib.pot --- web_leaflet_lib/i18n/web_leaflet_lib.pot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_leaflet_lib/i18n/web_leaflet_lib.pot b/web_leaflet_lib/i18n/web_leaflet_lib.pot index 09c74a5c3..ecd02b107 100644 --- a/web_leaflet_lib/i18n/web_leaflet_lib.pot +++ b/web_leaflet_lib/i18n/web_leaflet_lib.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 16.0\n" +"Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" From 9aeb44a21242268621af17329191c289711e9af5 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Wed, 20 Nov 2024 08:54:31 +0000 Subject: [PATCH 06/21] [BOT] post-merge updates --- web_leaflet_lib/README.rst | 2 +- web_leaflet_lib/static/description/index.html | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/web_leaflet_lib/README.rst b/web_leaflet_lib/README.rst index c52849b0c..a8ad6d571 100644 --- a/web_leaflet_lib/README.rst +++ b/web_leaflet_lib/README.rst @@ -7,7 +7,7 @@ Leaflet Javascript Library !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:e5af47c08dbb573c870e80a506feaccced35a36e61e63c6d39644fa84a357de1 + !! source digest: sha256:2902df904fa5e24d0d393c8f2096289c8bcb04f7c9f6511c60b394f7f4be3cb8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png diff --git a/web_leaflet_lib/static/description/index.html b/web_leaflet_lib/static/description/index.html index 8dd0e6f20..7d9b93657 100644 --- a/web_leaflet_lib/static/description/index.html +++ b/web_leaflet_lib/static/description/index.html @@ -367,7 +367,7 @@

Leaflet Javascript Library

!! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -!! source digest: sha256:e5af47c08dbb573c870e80a506feaccced35a36e61e63c6d39644fa84a357de1 +!! source digest: sha256:2902df904fa5e24d0d393c8f2096289c8bcb04f7c9f6511c60b394f7f4be3cb8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! -->

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

This module extends odoo to include Leaflet Javacript library.

From 5ccae124b6f9f29feba299d30e7c3d18a6192983 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 21 Nov 2024 08:36:36 +0000 Subject: [PATCH 07/21] Added translation using Weblate (Italian) --- web_leaflet_lib/i18n/it.po | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) create mode 100644 web_leaflet_lib/i18n/it.po diff --git a/web_leaflet_lib/i18n/it.po b/web_leaflet_lib/i18n/it.po new file mode 100644 index 000000000..4a24cc53b --- /dev/null +++ b/web_leaflet_lib/i18n/it.po @@ -0,0 +1,20 @@ +# Translation of Odoo Server. +# This file contains the translation of the following modules: +# * web_leaflet_lib +# +msgid "" +msgstr "" +"Project-Id-Version: Odoo Server 17.0\n" +"Report-Msgid-Bugs-To: \n" +"Last-Translator: Automatically generated\n" +"Language-Team: none\n" +"Language: it\n" +"MIME-Version: 1.0\n" +"Content-Type: text/plain; charset=UTF-8\n" +"Content-Transfer-Encoding: \n" +"Plural-Forms: nplurals=2; plural=n != 1;\n" + +#. module: web_leaflet_lib +#: model:ir.model,name:web_leaflet_lib.model_ir_http +msgid "HTTP Routing" +msgstr "" From 0443e1270feec2f472a0316e3e3ceb1e05675074 Mon Sep 17 00:00:00 2001 From: mymage Date: Thu, 21 Nov 2024 08:36:45 +0000 Subject: [PATCH 08/21] Translated using Weblate (Italian) Currently translated at 100.0% (1 of 1 strings) Translation: geospatial-17.0/geospatial-17.0-web_leaflet_lib Translate-URL: https://translation.odoo-community.org/projects/geospatial-17-0/geospatial-17-0-web_leaflet_lib/it/ --- web_leaflet_lib/i18n/it.po | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/web_leaflet_lib/i18n/it.po b/web_leaflet_lib/i18n/it.po index 4a24cc53b..f4322c522 100644 --- a/web_leaflet_lib/i18n/it.po +++ b/web_leaflet_lib/i18n/it.po @@ -6,15 +6,17 @@ msgid "" msgstr "" "Project-Id-Version: Odoo Server 17.0\n" "Report-Msgid-Bugs-To: \n" -"Last-Translator: Automatically generated\n" +"PO-Revision-Date: 2024-11-21 11:06+0000\n" +"Last-Translator: mymage \n" "Language-Team: none\n" "Language: it\n" "MIME-Version: 1.0\n" "Content-Type: text/plain; charset=UTF-8\n" "Content-Transfer-Encoding: \n" "Plural-Forms: nplurals=2; plural=n != 1;\n" +"X-Generator: Weblate 5.6.2\n" #. module: web_leaflet_lib #: model:ir.model,name:web_leaflet_lib.model_ir_http msgid "HTTP Routing" -msgstr "" +msgstr "Instradamento HTTP" From f3ce3d92c53638a3417dd4612d24b072986f602d Mon Sep 17 00:00:00 2001 From: Mourad Date: Tue, 21 Oct 2025 12:40:44 +0200 Subject: [PATCH 09/21] [MIG] web_leaflet_lib: Migration to 18.0 --- web_leaflet_lib/README.rst | 28 +++++++++---------- web_leaflet_lib/__manifest__.py | 2 +- web_leaflet_lib/static/description/index.html | 6 ++-- 3 files changed, 18 insertions(+), 18 deletions(-) diff --git a/web_leaflet_lib/README.rst b/web_leaflet_lib/README.rst index a8ad6d571..b7352f8a5 100644 --- a/web_leaflet_lib/README.rst +++ b/web_leaflet_lib/README.rst @@ -17,13 +17,13 @@ Leaflet Javascript Library :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fgeospatial-lightgray.png?logo=github - :target: https://github.com/OCA/geospatial/tree/17.0/web_leaflet_lib + :target: https://github.com/OCA/geospatial/tree/18.0/web_leaflet_lib :alt: OCA/geospatial .. |badge4| image:: https://img.shields.io/badge/weblate-Translate%20me-F47D42.png - :target: https://translation.odoo-community.org/projects/geospatial-17-0/geospatial-17-0-web_leaflet_lib + :target: https://translation.odoo-community.org/projects/geospatial-18-0/geospatial-18-0-web_leaflet_lib :alt: Translate me on Weblate .. |badge5| image:: https://img.shields.io/badge/runboat-Try%20me-875A7B.png - :target: https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=17.0 + :target: https://runboat.odoo-community.org/builds?repo=OCA/geospatial&target_branch=18.0 :alt: Try me on Runboat |badge1| |badge2| |badge3| |badge4| |badge5| @@ -53,10 +53,10 @@ non-profit body and cannot supply tiles for large-scale commercial use. **Regular / High Usage** -- you can contact one of the following companies : - https://switch2osm.org/providers/ -- You can also install yourself your own tiles servers. See - documentation : https://switch2osm.org/serving-tiles/ +- you can contact one of the following companies : + https://switch2osm.org/providers/ +- You can also install yourself your own tiles servers. See + documentation : https://switch2osm.org/serving-tiles/ **Table of contents** @@ -66,10 +66,10 @@ non-profit body and cannot supply tiles for large-scale commercial use. Configuration ============= -- Go to Settings > Technical > Parameters > System Parameters -- Create or edit the parameter with the key ``leaflet.tile_url`` -- As a value, set the url of the tiles server you chose. (See - description) +- Go to Settings > Technical > Parameters > System Parameters +- Create or edit the parameter with the key ``leaflet.tile_url`` +- As a value, set the url of the tiles server you chose. (See + description) Bug Tracker =========== @@ -77,7 +77,7 @@ Bug Tracker Bugs are tracked on `GitHub Issues `_. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -`feedback `_. +`feedback `_. Do not contact contributors directly about support or help with technical issues. @@ -92,7 +92,7 @@ Authors Contributors ------------ -- Sylvain LE GAL (https://www.twitter.com/legalsylvain) +- Sylvain LE GAL (https://www.twitter.com/legalsylvain) Other credits ------------- @@ -120,6 +120,6 @@ Current `maintainer `__: |maintainer-legalsylvain| -This module is part of the `OCA/geospatial `_ project on GitHub. +This module is part of the `OCA/geospatial `_ project on GitHub. You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute. diff --git a/web_leaflet_lib/__manifest__.py b/web_leaflet_lib/__manifest__.py index 73a71dae0..022fda4ee 100644 --- a/web_leaflet_lib/__manifest__.py +++ b/web_leaflet_lib/__manifest__.py @@ -5,7 +5,7 @@ { "name": "Leaflet Javascript Library", "summary": "Bring leaflet.js librairy in odoo.", - "version": "17.0.1.0.0", + "version": "18.0.1.0.0", "author": "GRAP, Odoo Community Association (OCA)", "maintainers": ["legalsylvain"], "website": "https://github.com/OCA/geospatial", diff --git a/web_leaflet_lib/static/description/index.html b/web_leaflet_lib/static/description/index.html index 7d9b93657..5b8eeff25 100644 --- a/web_leaflet_lib/static/description/index.html +++ b/web_leaflet_lib/static/description/index.html @@ -369,7 +369,7 @@

Leaflet Javascript Library

!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! !! source digest: sha256:2902df904fa5e24d0d393c8f2096289c8bcb04f7c9f6511c60b394f7f4be3cb8 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! --> -

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

This module extends odoo to include Leaflet Javacript library.

This module is used by web_view_leaflet_map.

Important Note

@@ -420,7 +420,7 @@

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed -feedback.

+feedback.

Do not contact contributors directly about support or help with technical issues.

@@ -452,7 +452,7 @@

Maintainers

promote its widespread use.

Current maintainer:

legalsylvain

-

This module is part of the OCA/geospatial project on GitHub.

+

This module is part of the OCA/geospatial project on GitHub.

You are welcome to contribute. To learn how please visit https://odoo-community.org/page/Contribute.

From c9aea3e4ea5ccd1b74b9ff072db1fa917bb456dc Mon Sep 17 00:00:00 2001 From: oca-ci Date: Fri, 7 Nov 2025 14:28:07 +0000 Subject: [PATCH 10/21] [UPD] Update web_leaflet_lib.pot --- web_leaflet_lib/i18n/web_leaflet_lib.pot | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/web_leaflet_lib/i18n/web_leaflet_lib.pot b/web_leaflet_lib/i18n/web_leaflet_lib.pot index ecd02b107..e721356d0 100644 --- a/web_leaflet_lib/i18n/web_leaflet_lib.pot +++ b/web_leaflet_lib/i18n/web_leaflet_lib.pot @@ -4,7 +4,7 @@ # msgid "" msgstr "" -"Project-Id-Version: Odoo Server 17.0\n" +"Project-Id-Version: Odoo Server 18.0\n" "Report-Msgid-Bugs-To: \n" "Last-Translator: \n" "Language-Team: \n" From 4501d3fca64a7d7f0cc4126c959417dc987bca19 Mon Sep 17 00:00:00 2001 From: OCA-git-bot Date: Fri, 7 Nov 2025 14:29:55 +0000 Subject: [PATCH 11/21] [BOT] post-merge updates --- web_leaflet_lib/README.rst | 8 +++-- web_leaflet_lib/static/description/index.html | 30 +++++++++++-------- 2 files changed, 24 insertions(+), 14 deletions(-) diff --git a/web_leaflet_lib/README.rst b/web_leaflet_lib/README.rst index b7352f8a5..936601cb8 100644 --- a/web_leaflet_lib/README.rst +++ b/web_leaflet_lib/README.rst @@ -1,3 +1,7 @@ +.. image:: https://odoo-community.org/readme-banner-image + :target: https://odoo-community.org/get-involved?utm_source=readme + :alt: Odoo Community Association + ========================== Leaflet Javascript Library ========================== @@ -7,13 +11,13 @@ Leaflet Javascript Library !! This file is generated by oca-gen-addon-readme !! !! changes will be overwritten. !! !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! - !! source digest: sha256:2902df904fa5e24d0d393c8f2096289c8bcb04f7c9f6511c60b394f7f4be3cb8 + !! source digest: sha256:82bf1d439961ac805898f84dd8ac4f30c994edfd067f965182b3aae8cf7a70d3 !!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!!! .. |badge1| image:: https://img.shields.io/badge/maturity-Beta-yellow.png :target: https://odoo-community.org/page/development-status :alt: Beta -.. |badge2| image:: https://img.shields.io/badge/licence-AGPL--3-blue.png +.. |badge2| image:: https://img.shields.io/badge/license-AGPL--3-blue.png :target: http://www.gnu.org/licenses/agpl-3.0-standalone.html :alt: License: AGPL-3 .. |badge3| image:: https://img.shields.io/badge/github-OCA%2Fgeospatial-lightgray.png?logo=github diff --git a/web_leaflet_lib/static/description/index.html b/web_leaflet_lib/static/description/index.html index 5b8eeff25..e88e65da2 100644 --- a/web_leaflet_lib/static/description/index.html +++ b/web_leaflet_lib/static/description/index.html @@ -3,7 +3,7 @@ -Leaflet Javascript Library +README.rst -
-

Leaflet Javascript Library

+
+ + +Odoo Community Association + +
+

Leaflet Javascript Library

-

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

+

Beta License: AGPL-3 OCA/geospatial Translate me on Weblate Try me on Runboat

This module extends odoo to include Leaflet Javacript library.

This module is used by web_view_leaflet_map.

Important Note

@@ -407,7 +412,7 @@

Leaflet Javascript Library

-

Configuration

+

Configuration

  • Go to Settings > Technical > Parameters > System Parameters
  • Create or edit the parameter with the key leaflet.tile_url
  • @@ -416,7 +421,7 @@

    Configuration

-

Bug Tracker

+

Bug Tracker

Bugs are tracked on GitHub Issues. In case of trouble, please check there if your issue has already been reported. If you spotted it first, help us to smash it by providing a detailed and welcomed @@ -424,25 +429,25 @@

Bug Tracker

Do not contact contributors directly about support or help with technical issues.

-

Credits

+

Credits

-

Authors

+

Authors

  • GRAP
-

Other credits

+

Other credits

The module embed the Leaflet.js library.

-

Maintainers

+

Maintainers

This module is maintained by the OCA.

Odoo Community Association @@ -457,5 +462,6 @@

Maintainers

+
From 84da09931a629f1d434381fd5599ecf1a9f0f92d Mon Sep 17 00:00:00 2001 From: Ronald Portier Date: Mon, 10 Nov 2025 17:13:25 +0100 Subject: [PATCH 12/21] [FIX] web_leaflet_lib: use unminified library Odoo minifies javascript sources when adding those to asset bundles. Having the unminified versions available is needed for debugging. The OCA contributor guidelines state: 'Never add minified Javascript libraries'. --- web_leaflet_lib/static/lib/leaflet/leaflet.js | 14510 +++++++++++++++- .../static/lib/leaflet/leaflet.js.map | 1 - 2 files changed, 14508 insertions(+), 3 deletions(-) delete mode 100644 web_leaflet_lib/static/lib/leaflet/leaflet.js.map diff --git a/web_leaflet_lib/static/lib/leaflet/leaflet.js b/web_leaflet_lib/static/lib/leaflet/leaflet.js index a3bf693d0..eeb30dfdd 100644 --- a/web_leaflet_lib/static/lib/leaflet/leaflet.js +++ b/web_leaflet_lib/static/lib/leaflet/leaflet.js @@ -2,5 +2,14511 @@ * Leaflet 1.9.4, a JS library for interactive maps. https://leafletjs.com * (c) 2010-2023 Vladimir Agafonkin, (c) 2010-2011 CloudMade */ -!function(t,e){"object"==typeof exports&&"undefined"!=typeof module?e(exports):"function"==typeof define&&define.amd?define(["exports"],e):e((t="undefined"!=typeof globalThis?globalThis:t||self).leaflet={})}(this,function(t){"use strict";function l(t){for(var e,i,n=1,o=arguments.length;n=this.min.x&&i.x<=this.max.x&&e.y>=this.min.y&&i.y<=this.max.y},intersects:function(t){t=_(t);var e=this.min,i=this.max,n=t.min,t=t.max,o=t.x>=e.x&&n.x<=i.x,t=t.y>=e.y&&n.y<=i.y;return o&&t},overlaps:function(t){t=_(t);var e=this.min,i=this.max,n=t.min,t=t.max,o=t.x>e.x&&n.xe.y&&n.y=n.lat&&i.lat<=o.lat&&e.lng>=n.lng&&i.lng<=o.lng},intersects:function(t){t=g(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),t=t.getNorthEast(),o=t.lat>=e.lat&&n.lat<=i.lat,t=t.lng>=e.lng&&n.lng<=i.lng;return o&&t},overlaps:function(t){t=g(t);var e=this._southWest,i=this._northEast,n=t.getSouthWest(),t=t.getNorthEast(),o=t.lat>e.lat&&n.late.lng&&n.lng","http://www.w3.org/2000/svg"===(Wt.firstChild&&Wt.firstChild.namespaceURI));function y(t){return 0<=navigator.userAgent.toLowerCase().indexOf(t)}var b={ie:pt,ielt9:mt,edge:n,webkit:ft,android:gt,android23:vt,androidStock:yt,opera:xt,chrome:wt,gecko:bt,safari:Pt,phantom:Lt,opera12:o,win:Tt,ie3d:Mt,webkit3d:zt,gecko3d:_t,any3d:Ct,mobile:Zt,mobileWebkit:St,mobileWebkit3d:Et,msPointer:kt,pointer:Ot,touch:Bt,touchNative:At,mobileOpera:It,mobileGecko:Rt,retina:Nt,passiveEvents:Dt,canvas:jt,svg:Ht,vml:!Ht&&function(){try{var t=document.createElement("div"),e=(t.innerHTML='',t.firstChild);return e.style.behavior="url(#default#VML)",e&&"object"==typeof e.adj}catch(t){return!1}}(),inlineSvg:Wt,mac:0===navigator.platform.indexOf("Mac"),linux:0===navigator.platform.indexOf("Linux")},Ft=b.msPointer?"MSPointerDown":"pointerdown",Ut=b.msPointer?"MSPointerMove":"pointermove",Vt=b.msPointer?"MSPointerUp":"pointerup",qt=b.msPointer?"MSPointerCancel":"pointercancel",Gt={touchstart:Ft,touchmove:Ut,touchend:Vt,touchcancel:qt},Kt={touchstart:function(t,e){e.MSPOINTER_TYPE_TOUCH&&e.pointerType===e.MSPOINTER_TYPE_TOUCH&&O(e);ee(t,e)},touchmove:ee,touchend:ee,touchcancel:ee},Yt={},Xt=!1;function Jt(t,e,i){return"touchstart"!==e||Xt||(document.addEventListener(Ft,$t,!0),document.addEventListener(Ut,Qt,!0),document.addEventListener(Vt,te,!0),document.addEventListener(qt,te,!0),Xt=!0),Kt[e]?(i=Kt[e].bind(this,i),t.addEventListener(Gt[e],i,!1),i):(console.warn("wrong event specified:",e),u)}function $t(t){Yt[t.pointerId]=t}function Qt(t){Yt[t.pointerId]&&(Yt[t.pointerId]=t)}function te(t){delete Yt[t.pointerId]}function ee(t,e){if(e.pointerType!==(e.MSPOINTER_TYPE_MOUSE||"mouse")){for(var i in e.touches=[],Yt)e.touches.push(Yt[i]);e.changedTouches=[e],t(e)}}var ie=200;function ne(t,i){t.addEventListener("dblclick",i);var n,o=0;function e(t){var e;1!==t.detail?n=t.detail:"mouse"===t.pointerType||t.sourceCapabilities&&!t.sourceCapabilities.firesTouchEvents||((e=Ne(t)).some(function(t){return t instanceof HTMLLabelElement&&t.attributes.for})&&!e.some(function(t){return t instanceof HTMLInputElement||t instanceof HTMLSelectElement})||((e=Date.now())-o<=ie?2===++n&&i(function(t){var e,i,n={};for(i in t)e=t[i],n[i]=e&&e.bind?e.bind(t):e;return(t=n).type="dblclick",n.detail=2,n.isTrusted=!1,n._simulated=!0,n}(t)):n=1,o=e))}return t.addEventListener("click",e),{dblclick:i,simDblclick:e}}var oe,se,re,ae,he,le,ue=we(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),ce=we(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===ce||"OTransition"===ce?ce+"End":"transitionend";function _e(t){return"string"==typeof t?document.getElementById(t):t}function pe(t,e){var i=t.style[e]||t.currentStyle&&t.currentStyle[e];return"auto"===(i=i&&"auto"!==i||!document.defaultView?i:(t=document.defaultView.getComputedStyle(t,null))?t[e]:null)?null:i}function P(t,e,i){t=document.createElement(t);return t.className=e||"",i&&i.appendChild(t),t}function T(t){var e=t.parentNode;e&&e.removeChild(t)}function me(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function fe(t){var e=t.parentNode;e&&e.lastChild!==t&&e.appendChild(t)}function ge(t){var e=t.parentNode;e&&e.firstChild!==t&&e.insertBefore(t,e.firstChild)}function ve(t,e){return void 0!==t.classList?t.classList.contains(e):0<(t=xe(t)).length&&new RegExp("(^|\\s)"+e+"(\\s|$)").test(t)}function M(t,e){var i;if(void 0!==t.classList)for(var n=F(e),o=0,s=n.length;othis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,e){this._enforcingBounds=!0;var i=this.getCenter(),t=this._limitCenter(i,this._zoom,g(t));return i.equals(t)||this.panTo(t,e),this._enforcingBounds=!1,this},panInside:function(t,e){var i=m((e=e||{}).paddingTopLeft||e.padding||[0,0]),n=m(e.paddingBottomRight||e.padding||[0,0]),o=this.project(this.getCenter()),t=this.project(t),s=this.getPixelBounds(),i=_([s.min.add(i),s.max.subtract(n)]),s=i.getSize();return i.contains(t)||(this._enforcingBounds=!0,n=t.subtract(i.getCenter()),i=i.extend(t).getSize().subtract(s),o.x+=n.x<0?-i.x:i.x,o.y+=n.y<0?-i.y:i.y,this.panTo(this.unproject(o),e),this._enforcingBounds=!1),this},invalidateSize:function(t){if(!this._loaded)return this;t=l({animate:!1,pan:!0},!0===t?{animate:!0}:t);var e=this.getSize(),i=(this._sizeChanged=!0,this._lastCenter=null,this.getSize()),n=e.divideBy(2).round(),o=i.divideBy(2).round(),n=n.subtract(o);return n.x||n.y?(t.animate&&t.pan?this.panBy(n):(t.pan&&this._rawPanBy(n),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(a(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:e,newSize:i})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){var e,i;return t=this._locateOptions=l({timeout:1e4,watch:!1},t),"geolocation"in navigator?(e=a(this._handleGeolocationResponse,this),i=a(this._handleGeolocationError,this),t.watch?this._locationWatchId=navigator.geolocation.watchPosition(e,i,t):navigator.geolocation.getCurrentPosition(e,i,t)):this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this},stopLocate:function(){return navigator.geolocation&&navigator.geolocation.clearWatch&&navigator.geolocation.clearWatch(this._locationWatchId),this._locateOptions&&(this._locateOptions.setView=!1),this},_handleGeolocationError:function(t){var e;this._container._leaflet_id&&(e=t.code,t=t.message||(1===e?"permission denied":2===e?"position unavailable":"timeout"),this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:e,message:"Geolocation error: "+t+"."}))},_handleGeolocationResponse:function(t){if(this._container._leaflet_id){var e,i,n=new v(t.coords.latitude,t.coords.longitude),o=n.toBounds(2*t.coords.accuracy),s=this._locateOptions,r=(s.setView&&(e=this.getBoundsZoom(o),this.setView(n,s.maxZoom?Math.min(e,s.maxZoom):e)),{latlng:n,bounds:o,timestamp:t.timestamp});for(i in t.coords)"number"==typeof t.coords[i]&&(r[i]=t.coords[i]);this.fire("locationfound",r)}},addHandler:function(t,e){return e&&(e=this[t]=new e(this),this._handlers.push(e),this.options[t]&&e.enable()),this},remove:function(){if(this._initEvents(!0),this.options.maxBounds&&this.off("moveend",this._panInsideMaxBounds),this._containerId!==this._container._leaflet_id)throw new Error("Map container is being reused by another instance");try{delete this._container._leaflet_id,delete this._containerId}catch(t){this._container._leaflet_id=void 0,this._containerId=void 0}for(var t in void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),T(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(r(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload"),this._layers)this._layers[t].remove();for(t in this._panes)T(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,e){e=P("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),e||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter.clone():this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new s(this.unproject(t.getBottomLeft()),this.unproject(t.getTopRight()))},getMinZoom:function(){return void 0===this.options.minZoom?this._layersMinZoom||0:this.options.minZoom},getMaxZoom:function(){return void 0===this.options.maxZoom?void 0===this._layersMaxZoom?1/0:this._layersMaxZoom:this.options.maxZoom},getBoundsZoom:function(t,e,i){t=g(t),i=m(i||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),t=t.getSouthEast(),i=this.getSize().subtract(i),t=_(this.project(t,n),this.project(r,n)).getSize(),r=b.any3d?this.options.zoomSnap:1,a=i.x/t.x,i=i.y/t.y,t=e?Math.max(a,i):Math.min(a,i),n=this.getScaleZoom(t,n);return r&&(n=Math.round(n/(r/100))*(r/100),n=e?Math.ceil(n/r)*r:Math.floor(n/r)*r),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new p(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,e){t=this._getTopLeftPoint(t,e);return new f(t,t.add(this.getSize()))},getPixelOrigin:function(){return this._checkIfLoaded(),this._pixelOrigin},getPixelWorldBounds:function(t){return this.options.crs.getProjectedBounds(void 0===t?this.getZoom():t)},getPane:function(t){return"string"==typeof t?this._panes[t]:t},getPanes:function(){return this._panes},getContainer:function(){return this._container},getZoomScale:function(t,e){var i=this.options.crs;return e=void 0===e?this._zoom:e,i.scale(t)/i.scale(e)},getScaleZoom:function(t,e){var i=this.options.crs,t=(e=void 0===e?this._zoom:e,i.zoom(t*i.scale(e)));return isNaN(t)?1/0:t},project:function(t,e){return e=void 0===e?this._zoom:e,this.options.crs.latLngToPoint(w(t),e)},unproject:function(t,e){return e=void 0===e?this._zoom:e,this.options.crs.pointToLatLng(m(t),e)},layerPointToLatLng:function(t){t=m(t).add(this.getPixelOrigin());return this.unproject(t)},latLngToLayerPoint:function(t){return this.project(w(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(w(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(g(t))},distance:function(t,e){return this.options.crs.distance(w(t),w(e))},containerPointToLayerPoint:function(t){return m(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return m(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){t=this.containerPointToLayerPoint(m(t));return this.layerPointToLatLng(t)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(w(t)))},mouseEventToContainerPoint:function(t){return De(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){t=this._container=_e(t);if(!t)throw new Error("Map container not found.");if(t._leaflet_id)throw new Error("Map container is already initialized.");S(t,"scroll",this._onScroll,this),this._containerId=h(t)},_initLayout:function(){var t=this._container,e=(this._fadeAnimated=this.options.fadeAnimation&&b.any3d,M(t,"leaflet-container"+(b.touch?" leaflet-touch":"")+(b.retina?" leaflet-retina":"")+(b.ielt9?" leaflet-oldie":"")+(b.safari?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":"")),pe(t,"position"));"absolute"!==e&&"relative"!==e&&"fixed"!==e&&"sticky"!==e&&(t.style.position="relative"),this._initPanes(),this._initControlPos&&this._initControlPos()},_initPanes:function(){var t=this._panes={};this._paneRenderers={},this._mapPane=this.createPane("mapPane",this._container),Z(this._mapPane,new p(0,0)),this.createPane("tilePane"),this.createPane("overlayPane"),this.createPane("shadowPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(M(t.markerPane,"leaflet-zoom-hide"),M(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,e,i){Z(this._mapPane,new p(0,0));var n=!this._loaded,o=(this._loaded=!0,e=this._limitZoom(e),this.fire("viewprereset"),this._zoom!==e);this._moveStart(o,i)._move(t,e)._moveEnd(o),this.fire("viewreset"),n&&this.fire("load")},_moveStart:function(t,e){return t&&this.fire("zoomstart"),e||this.fire("movestart"),this},_move:function(t,e,i,n){void 0===e&&(e=this._zoom);var o=this._zoom!==e;return this._zoom=e,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),n?i&&i.pinch&&this.fire("zoom",i):((o||i&&i.pinch)&&this.fire("zoom",i),this.fire("move",i)),this},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return r(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){Z(this._mapPane,this._getMapPanePos().subtract(t))},_getZoomSpan:function(){return this.getMaxZoom()-this.getMinZoom()},_panInsideMaxBounds:function(){this._enforcingBounds||this.panInsideBounds(this.options.maxBounds)},_checkIfLoaded:function(){if(!this._loaded)throw new Error("Set map center and zoom first.")},_initEvents:function(t){this._targets={};var e=t?k:S;e((this._targets[h(this._container)]=this)._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress keydown keyup",this._handleDOMEvent,this),this.options.trackResize&&e(window,"resize",this._onResize,this),b.any3d&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){r(this._resizeRequest),this._resizeRequest=x(function(){this.invalidateSize({debounceMoveend:!0})},this)},_onScroll:function(){this._container.scrollTop=0,this._container.scrollLeft=0},_onMoveEnd:function(){var t=this._getMapPanePos();Math.max(Math.abs(t.x),Math.abs(t.y))>=this.options.transform3DLimit&&this._resetView(this.getCenter(),this.getZoom())},_findEventTargets:function(t,e){for(var i,n=[],o="mouseout"===e||"mouseover"===e,s=t.target||t.srcElement,r=!1;s;){if((i=this._targets[h(s)])&&("click"===e||"preclick"===e)&&this._draggableMoved(i)){r=!0;break}if(i&&i.listens(e,!0)){if(o&&!We(s,t))break;if(n.push(i),o)break}if(s===this._container)break;s=s.parentNode}return n=n.length||r||o||!this.listens(e,!0)?n:[this]},_isClickDisabled:function(t){for(;t&&t!==this._container;){if(t._leaflet_disable_click)return!0;t=t.parentNode}},_handleDOMEvent:function(t){var e,i=t.target||t.srcElement;!this._loaded||i._leaflet_disable_events||"click"===t.type&&this._isClickDisabled(i)||("mousedown"===(e=t.type)&&Me(i),this._fireDOMEvent(t,e))},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,i){"click"===t.type&&((a=l({},t)).type="preclick",this._fireDOMEvent(a,a.type,i));var n=this._findEventTargets(t,e);if(i){for(var o=[],s=0;sthis.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(e),n=this._getCenterOffset(t)._divideBy(1-1/n);if(!0!==i.animate&&!this.getSize().contains(n))return!1;x(function(){this._moveStart(!0,i.noMoveStart||!1)._animateZoom(t,e,!0)},this)}return!0},_animateZoom:function(t,e,i,n){this._mapPane&&(i&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=e,M(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:e,noUpdate:n}),this._tempFireZoomEvent||(this._tempFireZoomEvent=this._zoom!==this._animateToZoom),this._move(this._animateToCenter,this._animateToZoom,void 0,!0),setTimeout(a(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&z(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom,void 0,!0),this._tempFireZoomEvent&&this.fire("zoom"),delete this._tempFireZoomEvent,this.fire("move"),this._moveEnd(!0))}});function Ue(t){return new B(t)}var B=et.extend({options:{position:"topright"},initialize:function(t){c(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var e=this._map;return e&&e.removeControl(this),this.options.position=t,e&&e.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var e=this._container=this.onAdd(t),i=this.getPosition(),t=t._controlCorners[i];return M(e,"leaflet-control"),-1!==i.indexOf("bottom")?t.insertBefore(e,t.firstChild):t.appendChild(e),this._map.on("unload",this.remove,this),this},remove:function(){return this._map&&(T(this._container),this.onRemove&&this.onRemove(this._map),this._map.off("unload",this.remove,this),this._map=null),this},_refocusOnMap:function(t){this._map&&t&&0",e=document.createElement("div");return e.innerHTML=t,e.firstChild},_addItem:function(t){var e,i=document.createElement("label"),n=this._map.hasLayer(t.layer),n=(t.overlay?((e=document.createElement("input")).type="checkbox",e.className="leaflet-control-layers-selector",e.defaultChecked=n):e=this._createRadioElement("leaflet-base-layers_"+h(this),n),this._layerControlInputs.push(e),e.layerId=h(t.layer),S(e,"click",this._onInputClick,this),document.createElement("span")),o=(n.innerHTML=" "+t.name,document.createElement("span"));return i.appendChild(o),o.appendChild(e),o.appendChild(n),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(i),this._checkDisabledLayers(),i},_onInputClick:function(){if(!this._preventClick){var t,e,i=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=i.length-1;0<=s;s--)t=i[s],e=this._getLayer(t.layerId).layer,t.checked?n.push(e):t.checked||o.push(e);for(s=0;se.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expandSafely:function(){var t=this._section,e=(this._preventClick=!0,S(t,"click",O),this.expand(),this);setTimeout(function(){k(t,"click",O),e._preventClick=!1})}})),qe=B.extend({options:{position:"topleft",zoomInText:'',zoomInTitle:"Zoom in",zoomOutText:'',zoomOutTitle:"Zoom out"},onAdd:function(t){var e="leaflet-control-zoom",i=P("div",e+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,e+"-in",i,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,e+"-out",i,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),i},onRemove:function(t){t.off("zoomend zoomlevelschange",this._updateDisabled,this)},disable:function(){return this._disabled=!0,this._updateDisabled(),this},enable:function(){return this._disabled=!1,this._updateDisabled(),this},_zoomIn:function(t){!this._disabled&&this._map._zoomthis._map.getMinZoom()&&this._map.zoomOut(this._map.options.zoomDelta*(t.shiftKey?3:1))},_createButton:function(t,e,i,n,o){i=P("a",i,n);return i.innerHTML=t,i.href="#",i.title=e,i.setAttribute("role","button"),i.setAttribute("aria-label",e),Ie(i),S(i,"click",Re),S(i,"click",o,this),S(i,"click",this._refocusOnMap,this),i},_updateDisabled:function(){var t=this._map,e="leaflet-disabled";z(this._zoomInButton,e),z(this._zoomOutButton,e),this._zoomInButton.setAttribute("aria-disabled","false"),this._zoomOutButton.setAttribute("aria-disabled","false"),!this._disabled&&t._zoom!==t.getMinZoom()||(M(this._zoomOutButton,e),this._zoomOutButton.setAttribute("aria-disabled","true")),!this._disabled&&t._zoom!==t.getMaxZoom()||(M(this._zoomInButton,e),this._zoomInButton.setAttribute("aria-disabled","true"))}}),Ge=(A.mergeOptions({zoomControl:!0}),A.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new qe,this.addControl(this.zoomControl))}),B.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var e="leaflet-control-scale",i=P("div",e),n=this.options;return this._addScales(n,e+"-line",i),t.on(n.updateWhenIdle?"moveend":"move",this._update,this),t.whenReady(this._update,this),i},onRemove:function(t){t.off(this.options.updateWhenIdle?"moveend":"move",this._update,this)},_addScales:function(t,e,i){t.metric&&(this._mScale=P("div",e,i)),t.imperial&&(this._iScale=P("div",e,i))},_update:function(){var t=this._map,e=t.getSize().y/2,t=t.distance(t.containerPointToLatLng([0,e]),t.containerPointToLatLng([this.options.maxWidth,e]));this._updateScales(t)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var e=this._getRoundNum(t);this._updateScale(this._mScale,e<1e3?e+" m":e/1e3+" km",e/t)},_updateImperial:function(t){var e,i,t=3.2808399*t;5280'+(b.inlineSvg?' ':"")+"Leaflet"},initialize:function(t){c(this,t),this._attributions={}},onAdd:function(t){for(var e in(t.attributionControl=this)._container=P("div","leaflet-control-attribution"),Ie(this._container),t._layers)t._layers[e].getAttribution&&this.addAttribution(t._layers[e].getAttribution());return this._update(),t.on("layeradd",this._addAttribution,this),this._container},onRemove:function(t){t.off("layeradd",this._addAttribution,this)},_addAttribution:function(t){t.layer.getAttribution&&(this.addAttribution(t.layer.getAttribution()),t.layer.once("remove",function(){this.removeAttribution(t.layer.getAttribution())},this))},setPrefix:function(t){return this.options.prefix=t,this._update(),this},addAttribution:function(t){return t&&(this._attributions[t]||(this._attributions[t]=0),this._attributions[t]++,this._update()),this},removeAttribution:function(t){return t&&this._attributions[t]&&(this._attributions[t]--,this._update()),this},_update:function(){if(this._map){var t,e=[];for(t in this._attributions)this._attributions[t]&&e.push(t);var i=[];this.options.prefix&&i.push(this.options.prefix),e.length&&i.push(e.join(", ")),this._container.innerHTML=i.join(' ')}}}),n=(A.mergeOptions({attributionControl:!0}),A.addInitHook(function(){this.options.attributionControl&&(new Ke).addTo(this)}),B.Layers=Ve,B.Zoom=qe,B.Scale=Ge,B.Attribution=Ke,Ue.layers=function(t,e,i){return new Ve(t,e,i)},Ue.zoom=function(t){return new qe(t)},Ue.scale=function(t){return new Ge(t)},Ue.attribution=function(t){return new Ke(t)},et.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled||(this._enabled=!0,this.addHooks()),this},disable:function(){return this._enabled&&(this._enabled=!1,this.removeHooks()),this},enabled:function(){return!!this._enabled}})),ft=(n.addTo=function(t,e){return t.addHandler(e,this),this},{Events:e}),Ye=b.touch?"touchstart mousedown":"mousedown",Xe=it.extend({options:{clickTolerance:3},initialize:function(t,e,i,n){c(this,n),this._element=t,this._dragStartTarget=e||t,this._preventOutline=i},enable:function(){this._enabled||(S(this._dragStartTarget,Ye,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Xe._dragging===this&&this.finishDrag(!0),k(this._dragStartTarget,Ye,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){var e,i;this._enabled&&(this._moved=!1,ve(this._element,"leaflet-zoom-anim")||(t.touches&&1!==t.touches.length?Xe._dragging===this&&this.finishDrag():Xe._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||((Xe._dragging=this)._preventOutline&&Me(this._element),Le(),re(),this._moving||(this.fire("down"),i=t.touches?t.touches[0]:t,e=Ce(this._element),this._startPoint=new p(i.clientX,i.clientY),this._startPos=Pe(this._element),this._parentScale=Ze(e),i="mousedown"===t.type,S(document,i?"mousemove":"touchmove",this._onMove,this),S(document,i?"mouseup":"touchend touchcancel",this._onUp,this)))))},_onMove:function(t){var e;this._enabled&&(t.touches&&1e&&(i.push(t[n]),o=n);oe.max.x&&(i|=2),t.ye.max.y&&(i|=8),i}function ri(t,e,i,n){var o=e.x,e=e.y,s=i.x-o,r=i.y-e,a=s*s+r*r;return 0this._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()t.y!=n.y>t.y&&t.x<(n.x-i.x)*(t.y-i.y)/(n.y-i.y)+i.x&&(l=!l);return l||yi.prototype._containsPoint.call(this,t,!0)}});var wi=ci.extend({initialize:function(t,e){c(this,e),this._layers={},t&&this.addData(t)},addData:function(t){var e,i,n,o=d(t)?t:t.features;if(o){for(e=0,i=o.length;es.x&&(r=i.x+a-s.x+o.x),i.x-r-n.x<(a=0)&&(r=i.x-n.x),i.y+e+o.y>s.y&&(a=i.y+e-s.y+o.y),i.y-a-n.y<0&&(a=i.y-n.y),(r||a)&&(this.options.keepInView&&(this._autopanning=!0),t.fire("autopanstart").panBy([r,a]))))},_getAnchor:function(){return m(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}})),Ii=(A.mergeOptions({closePopupOnClick:!0}),A.include({openPopup:function(t,e,i){return this._initOverlay(Bi,t,e,i).openOn(this),this},closePopup:function(t){return(t=arguments.length?t:this._popup)&&t.close(),this}}),o.include({bindPopup:function(t,e){return this._popup=this._initOverlay(Bi,this._popup,t,e),this._popupHandlersAdded||(this.on({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!0),this},unbindPopup:function(){return this._popup&&(this.off({click:this._openPopup,keypress:this._onKeyPress,remove:this.closePopup,move:this._movePopup}),this._popupHandlersAdded=!1,this._popup=null),this},openPopup:function(t){return this._popup&&(this instanceof ci||(this._popup._source=this),this._popup._prepareOpen(t||this._latlng)&&this._popup.openOn(this._map)),this},closePopup:function(){return this._popup&&this._popup.close(),this},togglePopup:function(){return this._popup&&this._popup.toggle(this),this},isPopupOpen:function(){return!!this._popup&&this._popup.isOpen()},setPopupContent:function(t){return this._popup&&this._popup.setContent(t),this},getPopup:function(){return this._popup},_openPopup:function(t){var e;this._popup&&this._map&&(Re(t),e=t.layer||t.target,this._popup._source!==e||e instanceof fi?(this._popup._source=e,this.openPopup(t.latlng)):this._map.hasLayer(this._popup)?this.closePopup():this.openPopup(t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}}),Ai.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,opacity:.9},onAdd:function(t){Ai.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&(this.addEventParent(this._source),this._source.fire("tooltipopen",{tooltip:this},!0))},onRemove:function(t){Ai.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&(this.removeEventParent(this._source),this._source.fire("tooltipclose",{tooltip:this},!0))},getEvents:function(){var t=Ai.prototype.getEvents.call(this);return this.options.permanent||(t.preclick=this.close),t},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=P("div",t),this._container.setAttribute("role","tooltip"),this._container.setAttribute("id","leaflet-tooltip-"+h(this))},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var e,i=this._map,n=this._container,o=i.latLngToContainerPoint(i.getCenter()),i=i.layerPointToContainerPoint(t),s=this.options.direction,r=n.offsetWidth,a=n.offsetHeight,h=m(this.options.offset),l=this._getAnchor(),i="top"===s?(e=r/2,a):"bottom"===s?(e=r/2,0):(e="center"===s?r/2:"right"===s?0:"left"===s?r:i.xthis.options.maxZoom||nthis.options.maxZoom||void 0!==this.options.minZoom&&oi.max.x)||!e.wrapLat&&(t.yi.max.y))return!1}return!this.options.bounds||(e=this._tileCoordsToBounds(t),g(this.options.bounds).overlaps(e))},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var e=this._map,i=this.getTileSize(),n=t.scaleBy(i),i=n.add(i);return[e.unproject(n,t.z),e.unproject(i,t.z)]},_tileCoordsToBounds:function(t){t=this._tileCoordsToNwSe(t),t=new s(t[0],t[1]);return t=this.options.noWrap?t:this._map.wrapLatLngBounds(t)},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var t=t.split(":"),e=new p(+t[0],+t[1]);return e.z=+t[2],e},_removeTile:function(t){var e=this._tiles[t];e&&(T(e.el),delete this._tiles[t],this.fire("tileunload",{tile:e.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){M(t,"leaflet-tile");var e=this.getTileSize();t.style.width=e.x+"px",t.style.height=e.y+"px",t.onselectstart=u,t.onmousemove=u,b.ielt9&&this.options.opacity<1&&C(t,this.options.opacity)},_addTile:function(t,e){var i=this._getTilePos(t),n=this._tileCoordsToKey(t),o=this.createTile(this._wrapCoords(t),a(this._tileReady,this,t));this._initTile(o),this.createTile.length<2&&x(a(this._tileReady,this,t,null,o)),Z(o,i),this._tiles[n]={el:o,coords:t,current:!0},e.appendChild(o),this.fire("tileloadstart",{tile:o,coords:t})},_tileReady:function(t,e,i){e&&this.fire("tileerror",{error:e,tile:i,coords:t});var n=this._tileCoordsToKey(t);(i=this._tiles[n])&&(i.loaded=+new Date,this._map._fadeAnimated?(C(i.el,0),r(this._fadeFrame),this._fadeFrame=x(this._updateOpacity,this)):(i.active=!0,this._pruneTiles()),e||(M(i.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:i.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),b.ielt9||!this._map._fadeAnimated?x(this._pruneTiles,this):setTimeout(a(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var e=new p(this._wrapX?H(t.x,this._wrapX):t.x,this._wrapY?H(t.y,this._wrapY):t.y);return e.z=t.z,e},_pxBoundsToTileRange:function(t){var e=this.getTileSize();return new f(t.min.unscaleBy(e).floor(),t.max.unscaleBy(e).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}});var Di=Ni.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1,referrerPolicy:!1},initialize:function(t,e){this._url=t,(e=c(this,e)).detectRetina&&b.retina&&0')}}catch(t){}return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}(),zt={_initContainer:function(){this._container=P("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(Wi.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var e=t._container=Vi("shape");M(e,"leaflet-vml-shape "+(this.options.className||"")),e.coordsize="1 1",t._path=Vi("path"),e.appendChild(t._path),this._updateStyle(t),this._layers[h(t)]=t},_addPath:function(t){var e=t._container;this._container.appendChild(e),t.options.interactive&&t.addInteractiveTarget(e)},_removePath:function(t){var e=t._container;T(e),t.removeInteractiveTarget(e),delete this._layers[h(t)]},_updateStyle:function(t){var e=t._stroke,i=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(e=e||(t._stroke=Vi("stroke")),o.appendChild(e),e.weight=n.weight+"px",e.color=n.color,e.opacity=n.opacity,n.dashArray?e.dashStyle=d(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):e.dashStyle="",e.endcap=n.lineCap.replace("butt","flat"),e.joinstyle=n.lineJoin):e&&(o.removeChild(e),t._stroke=null),n.fill?(i=i||(t._fill=Vi("fill")),o.appendChild(i),i.color=n.fillColor||n.color,i.opacity=n.fillOpacity):i&&(o.removeChild(i),t._fill=null)},_updateCircle:function(t){var e=t._point.round(),i=Math.round(t._radius),n=Math.round(t._radiusY||i);this._setPath(t,t._empty()?"M0 0":"AL "+e.x+","+e.y+" "+i+","+n+" 0,23592600")},_setPath:function(t,e){t._path.v=e},_bringToFront:function(t){fe(t._container)},_bringToBack:function(t){ge(t._container)}},qi=b.vml?Vi:ct,Gi=Wi.extend({_initContainer:function(){this._container=qi("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=qi("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){T(this._container),k(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_update:function(){var t,e,i;this._map._animatingZoom&&this._bounds||(Wi.prototype._update.call(this),e=(t=this._bounds).getSize(),i=this._container,this._svgSize&&this._svgSize.equals(e)||(this._svgSize=e,i.setAttribute("width",e.x),i.setAttribute("height",e.y)),Z(i,t.min),i.setAttribute("viewBox",[t.min.x,t.min.y,e.x,e.y].join(" ")),this.fire("update"))},_initPath:function(t){var e=t._path=qi("path");t.options.className&&M(e,t.options.className),t.options.interactive&&M(e,"leaflet-interactive"),this._updateStyle(t),this._layers[h(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){T(t._path),t.removeInteractiveTarget(t._path),delete this._layers[h(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var e=t._path,t=t.options;e&&(t.stroke?(e.setAttribute("stroke",t.color),e.setAttribute("stroke-opacity",t.opacity),e.setAttribute("stroke-width",t.weight),e.setAttribute("stroke-linecap",t.lineCap),e.setAttribute("stroke-linejoin",t.lineJoin),t.dashArray?e.setAttribute("stroke-dasharray",t.dashArray):e.removeAttribute("stroke-dasharray"),t.dashOffset?e.setAttribute("stroke-dashoffset",t.dashOffset):e.removeAttribute("stroke-dashoffset")):e.setAttribute("stroke","none"),t.fill?(e.setAttribute("fill",t.fillColor||t.color),e.setAttribute("fill-opacity",t.fillOpacity),e.setAttribute("fill-rule",t.fillRule||"evenodd")):e.setAttribute("fill","none"))},_updatePoly:function(t,e){this._setPath(t,dt(t._parts,e))},_updateCircle:function(t){var e=t._point,i=Math.max(Math.round(t._radius),1),n="a"+i+","+(Math.max(Math.round(t._radiusY),1)||i)+" 0 1,0 ",e=t._empty()?"M0 0":"M"+(e.x-i)+","+e.y+n+2*i+",0 "+n+2*-i+",0 ";this._setPath(t,e)},_setPath:function(t,e){t._path.setAttribute("d",e)},_bringToFront:function(t){fe(t._path)},_bringToBack:function(t){ge(t._path)}});function Ki(t){return b.svg||b.vml?new Gi(t):null}b.vml&&Gi.include(zt),A.include({getRenderer:function(t){t=(t=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer)||(this._renderer=this._createRenderer());return this.hasLayer(t)||this.addLayer(t),t},_getPaneRenderer:function(t){var e;return"overlayPane"!==t&&void 0!==t&&(void 0===(e=this._paneRenderers[t])&&(e=this._createRenderer({pane:t}),this._paneRenderers[t]=e),e)},_createRenderer:function(t){return this.options.preferCanvas&&Ui(t)||Ki(t)}});var Yi=xi.extend({initialize:function(t,e){xi.prototype.initialize.call(this,this._boundsToLatLngs(t),e)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return[(t=g(t)).getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});Gi.create=qi,Gi.pointsToPath=dt,wi.geometryToLayer=bi,wi.coordsToLatLng=Li,wi.coordsToLatLngs=Ti,wi.latLngToCoords=Mi,wi.latLngsToCoords=zi,wi.getFeature=Ci,wi.asFeature=Zi,A.mergeOptions({boxZoom:!0});var _t=n.extend({initialize:function(t){this._map=t,this._container=t._container,this._pane=t._panes.overlayPane,this._resetStateTimeout=0,t.on("unload",this._destroy,this)},addHooks:function(){S(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){k(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){T(this._pane),delete this._pane},_resetState:function(){this._resetStateTimeout=0,this._moved=!1},_clearDeferredResetState:function(){0!==this._resetStateTimeout&&(clearTimeout(this._resetStateTimeout),this._resetStateTimeout=0)},_onMouseDown:function(t){if(!t.shiftKey||1!==t.which&&1!==t.button)return!1;this._clearDeferredResetState(),this._resetState(),re(),Le(),this._startPoint=this._map.mouseEventToContainerPoint(t),S(document,{contextmenu:Re,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=P("div","leaflet-zoom-box",this._container),M(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var t=new f(this._point,this._startPoint),e=t.getSize();Z(this._box,t.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(T(this._box),z(this._container,"leaflet-crosshair")),ae(),Te(),k(document,{contextmenu:Re,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){1!==t.which&&1!==t.button||(this._finish(),this._moved&&(this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(a(this._resetState,this),0),t=new s(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point)),this._map.fitBounds(t).fire("boxzoomend",{boxZoomBounds:t})))},_onKeyDown:function(t){27===t.keyCode&&(this._finish(),this._clearDeferredResetState(),this._resetState())}}),Ct=(A.addInitHook("addHandler","boxZoom",_t),A.mergeOptions({doubleClickZoom:!0}),n.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var e=this._map,i=e.getZoom(),n=e.options.zoomDelta,i=t.originalEvent.shiftKey?i-n:i+n;"center"===e.options.doubleClickZoom?e.setZoom(i):e.setZoomAround(t.containerPoint,i)}})),Zt=(A.addInitHook("addHandler","doubleClickZoom",Ct),A.mergeOptions({dragging:!0,inertia:!0,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0}),n.extend({addHooks:function(){var t;this._draggable||(t=this._map,this._draggable=new Xe(t._mapPane,t._container),this._draggable.on({dragstart:this._onDragStart,drag:this._onDrag,dragend:this._onDragEnd},this),this._draggable.on("predrag",this._onPreDragLimit,this),t.options.worldCopyJump&&(this._draggable.on("predrag",this._onPreDragWrap,this),t.on("zoomend",this._onZoomEnd,this),t.whenReady(this._onZoomEnd,this))),M(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){z(this._map._container,"leaflet-grab"),z(this._map._container,"leaflet-touch-drag"),this._draggable.disable()},moved:function(){return this._draggable&&this._draggable._moved},moving:function(){return this._draggable&&this._draggable._moving},_onDragStart:function(){var t,e=this._map;e._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity?(t=g(this._map.options.maxBounds),this._offsetLimit=_(this._map.latLngToContainerPoint(t.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(t.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))):this._offsetLimit=null,e.fire("movestart").fire("dragstart"),e.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){var e,i;this._map.options.inertia&&(e=this._lastTime=+new Date,i=this._lastPos=this._draggable._absPos||this._draggable._newPos,this._positions.push(i),this._times.push(e),this._prunePositions(e)),this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;1e.max.x&&(t.x=this._viscousLimit(t.x,e.max.x)),t.y>e.max.y&&(t.y=this._viscousLimit(t.y,e.max.y)),this._draggable._newPos=this._draggable._startPos.add(t))},_onPreDragWrap:function(){var t=this._worldWidth,e=Math.round(t/2),i=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-e+i)%t+e-i,n=(n+e+i)%t-e-i,t=Math.abs(o+i)e.getMaxZoom()&&1 0 ? Math.floor(v) : Math.ceil(v); + }; + + Point.prototype = { + + // @method clone(): Point + // Returns a copy of the current point. + clone: function () { + return new Point(this.x, this.y); + }, + + // @method add(otherPoint: Point): Point + // Returns the result of addition of the current and the given points. + add: function (point) { + // non-destructive, returns a new point + return this.clone()._add(toPoint(point)); + }, + + _add: function (point) { + // destructive, used directly for performance in situations where it's safe to modify existing point + this.x += point.x; + this.y += point.y; + return this; + }, + + // @method subtract(otherPoint: Point): Point + // Returns the result of subtraction of the given point from the current. + subtract: function (point) { + return this.clone()._subtract(toPoint(point)); + }, + + _subtract: function (point) { + this.x -= point.x; + this.y -= point.y; + return this; + }, + + // @method divideBy(num: Number): Point + // Returns the result of division of the current point by the given number. + divideBy: function (num) { + return this.clone()._divideBy(num); + }, + + _divideBy: function (num) { + this.x /= num; + this.y /= num; + return this; + }, + + // @method multiplyBy(num: Number): Point + // Returns the result of multiplication of the current point by the given number. + multiplyBy: function (num) { + return this.clone()._multiplyBy(num); + }, + + _multiplyBy: function (num) { + this.x *= num; + this.y *= num; + return this; + }, + + // @method scaleBy(scale: Point): Point + // Multiply each coordinate of the current point by each coordinate of + // `scale`. In linear algebra terms, multiply the point by the + // [scaling matrix](https://en.wikipedia.org/wiki/Scaling_%28geometry%29#Matrix_representation) + // defined by `scale`. + scaleBy: function (point) { + return new Point(this.x * point.x, this.y * point.y); + }, + + // @method unscaleBy(scale: Point): Point + // Inverse of `scaleBy`. Divide each coordinate of the current point by + // each coordinate of `scale`. + unscaleBy: function (point) { + return new Point(this.x / point.x, this.y / point.y); + }, + + // @method round(): Point + // Returns a copy of the current point with rounded coordinates. + round: function () { + return this.clone()._round(); + }, + + _round: function () { + this.x = Math.round(this.x); + this.y = Math.round(this.y); + return this; + }, + + // @method floor(): Point + // Returns a copy of the current point with floored coordinates (rounded down). + floor: function () { + return this.clone()._floor(); + }, + + _floor: function () { + this.x = Math.floor(this.x); + this.y = Math.floor(this.y); + return this; + }, + + // @method ceil(): Point + // Returns a copy of the current point with ceiled coordinates (rounded up). + ceil: function () { + return this.clone()._ceil(); + }, + + _ceil: function () { + this.x = Math.ceil(this.x); + this.y = Math.ceil(this.y); + return this; + }, + + // @method trunc(): Point + // Returns a copy of the current point with truncated coordinates (rounded towards zero). + trunc: function () { + return this.clone()._trunc(); + }, + + _trunc: function () { + this.x = trunc(this.x); + this.y = trunc(this.y); + return this; + }, + + // @method distanceTo(otherPoint: Point): Number + // Returns the cartesian distance between the current and the given points. + distanceTo: function (point) { + point = toPoint(point); + + var x = point.x - this.x, + y = point.y - this.y; + + return Math.sqrt(x * x + y * y); + }, + + // @method equals(otherPoint: Point): Boolean + // Returns `true` if the given point has the same coordinates. + equals: function (point) { + point = toPoint(point); + + return point.x === this.x && + point.y === this.y; + }, + + // @method contains(otherPoint: Point): Boolean + // Returns `true` if both coordinates of the given point are less than the corresponding current point coordinates (in absolute values). + contains: function (point) { + point = toPoint(point); + + return Math.abs(point.x) <= Math.abs(this.x) && + Math.abs(point.y) <= Math.abs(this.y); + }, + + // @method toString(): String + // Returns a string representation of the point for debugging purposes. + toString: function () { + return 'Point(' + + formatNum(this.x) + ', ' + + formatNum(this.y) + ')'; + } + }; + + // @factory L.point(x: Number, y: Number, round?: Boolean) + // Creates a Point object with the given `x` and `y` coordinates. If optional `round` is set to true, rounds the `x` and `y` values. + + // @alternative + // @factory L.point(coords: Number[]) + // Expects an array of the form `[x, y]` instead. + + // @alternative + // @factory L.point(coords: Object) + // Expects a plain object of the form `{x: Number, y: Number}` instead. + function toPoint(x, y, round) { + if (x instanceof Point) { + return x; + } + if (isArray(x)) { + return new Point(x[0], x[1]); + } + if (x === undefined || x === null) { + return x; + } + if (typeof x === 'object' && 'x' in x && 'y' in x) { + return new Point(x.x, x.y); + } + return new Point(x, y, round); + } + + /* + * @class Bounds + * @aka L.Bounds + * + * Represents a rectangular area in pixel coordinates. + * + * @example + * + * ```js + * var p1 = L.point(10, 10), + * p2 = L.point(40, 60), + * bounds = L.bounds(p1, p2); + * ``` + * + * All Leaflet methods that accept `Bounds` objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this: + * + * ```js + * otherBounds.intersects([[10, 10], [40, 60]]); + * ``` + * + * Note that `Bounds` does not inherit from Leaflet's `Class` object, + * which means new classes can't inherit from it, and new methods + * can't be added to it with the `include` function. + */ + + function Bounds(a, b) { + if (!a) { return; } + + var points = b ? [a, b] : a; + + for (var i = 0, len = points.length; i < len; i++) { + this.extend(points[i]); + } + } + + Bounds.prototype = { + // @method extend(point: Point): this + // Extends the bounds to contain the given point. + + // @alternative + // @method extend(otherBounds: Bounds): this + // Extend the bounds to contain the given bounds + extend: function (obj) { + var min2, max2; + if (!obj) { return this; } + + if (obj instanceof Point || typeof obj[0] === 'number' || 'x' in obj) { + min2 = max2 = toPoint(obj); + } else { + obj = toBounds(obj); + min2 = obj.min; + max2 = obj.max; + + if (!min2 || !max2) { return this; } + } + + // @property min: Point + // The top left corner of the rectangle. + // @property max: Point + // The bottom right corner of the rectangle. + if (!this.min && !this.max) { + this.min = min2.clone(); + this.max = max2.clone(); + } else { + this.min.x = Math.min(min2.x, this.min.x); + this.max.x = Math.max(max2.x, this.max.x); + this.min.y = Math.min(min2.y, this.min.y); + this.max.y = Math.max(max2.y, this.max.y); + } + return this; + }, + + // @method getCenter(round?: Boolean): Point + // Returns the center point of the bounds. + getCenter: function (round) { + return toPoint( + (this.min.x + this.max.x) / 2, + (this.min.y + this.max.y) / 2, round); + }, + + // @method getBottomLeft(): Point + // Returns the bottom-left point of the bounds. + getBottomLeft: function () { + return toPoint(this.min.x, this.max.y); + }, + + // @method getTopRight(): Point + // Returns the top-right point of the bounds. + getTopRight: function () { // -> Point + return toPoint(this.max.x, this.min.y); + }, + + // @method getTopLeft(): Point + // Returns the top-left point of the bounds (i.e. [`this.min`](#bounds-min)). + getTopLeft: function () { + return this.min; // left, top + }, + + // @method getBottomRight(): Point + // Returns the bottom-right point of the bounds (i.e. [`this.max`](#bounds-max)). + getBottomRight: function () { + return this.max; // right, bottom + }, + + // @method getSize(): Point + // Returns the size of the given bounds + getSize: function () { + return this.max.subtract(this.min); + }, + + // @method contains(otherBounds: Bounds): Boolean + // Returns `true` if the rectangle contains the given one. + // @alternative + // @method contains(point: Point): Boolean + // Returns `true` if the rectangle contains the given point. + contains: function (obj) { + var min, max; + + if (typeof obj[0] === 'number' || obj instanceof Point) { + obj = toPoint(obj); + } else { + obj = toBounds(obj); + } + + if (obj instanceof Bounds) { + min = obj.min; + max = obj.max; + } else { + min = max = obj; + } + + return (min.x >= this.min.x) && + (max.x <= this.max.x) && + (min.y >= this.min.y) && + (max.y <= this.max.y); + }, + + // @method intersects(otherBounds: Bounds): Boolean + // Returns `true` if the rectangle intersects the given bounds. Two bounds + // intersect if they have at least one point in common. + intersects: function (bounds) { // (Bounds) -> Boolean + bounds = toBounds(bounds); + + var min = this.min, + max = this.max, + min2 = bounds.min, + max2 = bounds.max, + xIntersects = (max2.x >= min.x) && (min2.x <= max.x), + yIntersects = (max2.y >= min.y) && (min2.y <= max.y); + + return xIntersects && yIntersects; + }, + + // @method overlaps(otherBounds: Bounds): Boolean + // Returns `true` if the rectangle overlaps the given bounds. Two bounds + // overlap if their intersection is an area. + overlaps: function (bounds) { // (Bounds) -> Boolean + bounds = toBounds(bounds); + + var min = this.min, + max = this.max, + min2 = bounds.min, + max2 = bounds.max, + xOverlaps = (max2.x > min.x) && (min2.x < max.x), + yOverlaps = (max2.y > min.y) && (min2.y < max.y); + + return xOverlaps && yOverlaps; + }, + + // @method isValid(): Boolean + // Returns `true` if the bounds are properly initialized. + isValid: function () { + return !!(this.min && this.max); + }, + + + // @method pad(bufferRatio: Number): Bounds + // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. + // For example, a ratio of 0.5 extends the bounds by 50% in each direction. + // Negative values will retract the bounds. + pad: function (bufferRatio) { + var min = this.min, + max = this.max, + heightBuffer = Math.abs(min.x - max.x) * bufferRatio, + widthBuffer = Math.abs(min.y - max.y) * bufferRatio; + + + return toBounds( + toPoint(min.x - heightBuffer, min.y - widthBuffer), + toPoint(max.x + heightBuffer, max.y + widthBuffer)); + }, + + + // @method equals(otherBounds: Bounds): Boolean + // Returns `true` if the rectangle is equivalent to the given bounds. + equals: function (bounds) { + if (!bounds) { return false; } + + bounds = toBounds(bounds); + + return this.min.equals(bounds.getTopLeft()) && + this.max.equals(bounds.getBottomRight()); + }, + }; + + + // @factory L.bounds(corner1: Point, corner2: Point) + // Creates a Bounds object from two corners coordinate pairs. + // @alternative + // @factory L.bounds(points: Point[]) + // Creates a Bounds object from the given array of points. + function toBounds(a, b) { + if (!a || a instanceof Bounds) { + return a; + } + return new Bounds(a, b); + } + + /* + * @class LatLngBounds + * @aka L.LatLngBounds + * + * Represents a rectangular geographical area on a map. + * + * @example + * + * ```js + * var corner1 = L.latLng(40.712, -74.227), + * corner2 = L.latLng(40.774, -74.125), + * bounds = L.latLngBounds(corner1, corner2); + * ``` + * + * All Leaflet methods that accept LatLngBounds objects also accept them in a simple Array form (unless noted otherwise), so the bounds example above can be passed like this: + * + * ```js + * map.fitBounds([ + * [40.712, -74.227], + * [40.774, -74.125] + * ]); + * ``` + * + * Caution: if the area crosses the antimeridian (often confused with the International Date Line), you must specify corners _outside_ the [-180, 180] degrees longitude range. + * + * Note that `LatLngBounds` does not inherit from Leaflet's `Class` object, + * which means new classes can't inherit from it, and new methods + * can't be added to it with the `include` function. + */ + + function LatLngBounds(corner1, corner2) { // (LatLng, LatLng) or (LatLng[]) + if (!corner1) { return; } + + var latlngs = corner2 ? [corner1, corner2] : corner1; + + for (var i = 0, len = latlngs.length; i < len; i++) { + this.extend(latlngs[i]); + } + } + + LatLngBounds.prototype = { + + // @method extend(latlng: LatLng): this + // Extend the bounds to contain the given point + + // @alternative + // @method extend(otherBounds: LatLngBounds): this + // Extend the bounds to contain the given bounds + extend: function (obj) { + var sw = this._southWest, + ne = this._northEast, + sw2, ne2; + + if (obj instanceof LatLng) { + sw2 = obj; + ne2 = obj; + + } else if (obj instanceof LatLngBounds) { + sw2 = obj._southWest; + ne2 = obj._northEast; + + if (!sw2 || !ne2) { return this; } + + } else { + return obj ? this.extend(toLatLng(obj) || toLatLngBounds(obj)) : this; + } + + if (!sw && !ne) { + this._southWest = new LatLng(sw2.lat, sw2.lng); + this._northEast = new LatLng(ne2.lat, ne2.lng); + } else { + sw.lat = Math.min(sw2.lat, sw.lat); + sw.lng = Math.min(sw2.lng, sw.lng); + ne.lat = Math.max(ne2.lat, ne.lat); + ne.lng = Math.max(ne2.lng, ne.lng); + } + + return this; + }, + + // @method pad(bufferRatio: Number): LatLngBounds + // Returns bounds created by extending or retracting the current bounds by a given ratio in each direction. + // For example, a ratio of 0.5 extends the bounds by 50% in each direction. + // Negative values will retract the bounds. + pad: function (bufferRatio) { + var sw = this._southWest, + ne = this._northEast, + heightBuffer = Math.abs(sw.lat - ne.lat) * bufferRatio, + widthBuffer = Math.abs(sw.lng - ne.lng) * bufferRatio; + + return new LatLngBounds( + new LatLng(sw.lat - heightBuffer, sw.lng - widthBuffer), + new LatLng(ne.lat + heightBuffer, ne.lng + widthBuffer)); + }, + + // @method getCenter(): LatLng + // Returns the center point of the bounds. + getCenter: function () { + return new LatLng( + (this._southWest.lat + this._northEast.lat) / 2, + (this._southWest.lng + this._northEast.lng) / 2); + }, + + // @method getSouthWest(): LatLng + // Returns the south-west point of the bounds. + getSouthWest: function () { + return this._southWest; + }, + + // @method getNorthEast(): LatLng + // Returns the north-east point of the bounds. + getNorthEast: function () { + return this._northEast; + }, + + // @method getNorthWest(): LatLng + // Returns the north-west point of the bounds. + getNorthWest: function () { + return new LatLng(this.getNorth(), this.getWest()); + }, + + // @method getSouthEast(): LatLng + // Returns the south-east point of the bounds. + getSouthEast: function () { + return new LatLng(this.getSouth(), this.getEast()); + }, + + // @method getWest(): Number + // Returns the west longitude of the bounds + getWest: function () { + return this._southWest.lng; + }, + + // @method getSouth(): Number + // Returns the south latitude of the bounds + getSouth: function () { + return this._southWest.lat; + }, + + // @method getEast(): Number + // Returns the east longitude of the bounds + getEast: function () { + return this._northEast.lng; + }, + + // @method getNorth(): Number + // Returns the north latitude of the bounds + getNorth: function () { + return this._northEast.lat; + }, + + // @method contains(otherBounds: LatLngBounds): Boolean + // Returns `true` if the rectangle contains the given one. + + // @alternative + // @method contains (latlng: LatLng): Boolean + // Returns `true` if the rectangle contains the given point. + contains: function (obj) { // (LatLngBounds) or (LatLng) -> Boolean + if (typeof obj[0] === 'number' || obj instanceof LatLng || 'lat' in obj) { + obj = toLatLng(obj); + } else { + obj = toLatLngBounds(obj); + } + + var sw = this._southWest, + ne = this._northEast, + sw2, ne2; + + if (obj instanceof LatLngBounds) { + sw2 = obj.getSouthWest(); + ne2 = obj.getNorthEast(); + } else { + sw2 = ne2 = obj; + } + + return (sw2.lat >= sw.lat) && (ne2.lat <= ne.lat) && + (sw2.lng >= sw.lng) && (ne2.lng <= ne.lng); + }, + + // @method intersects(otherBounds: LatLngBounds): Boolean + // Returns `true` if the rectangle intersects the given bounds. Two bounds intersect if they have at least one point in common. + intersects: function (bounds) { + bounds = toLatLngBounds(bounds); + + var sw = this._southWest, + ne = this._northEast, + sw2 = bounds.getSouthWest(), + ne2 = bounds.getNorthEast(), + + latIntersects = (ne2.lat >= sw.lat) && (sw2.lat <= ne.lat), + lngIntersects = (ne2.lng >= sw.lng) && (sw2.lng <= ne.lng); + + return latIntersects && lngIntersects; + }, + + // @method overlaps(otherBounds: LatLngBounds): Boolean + // Returns `true` if the rectangle overlaps the given bounds. Two bounds overlap if their intersection is an area. + overlaps: function (bounds) { + bounds = toLatLngBounds(bounds); + + var sw = this._southWest, + ne = this._northEast, + sw2 = bounds.getSouthWest(), + ne2 = bounds.getNorthEast(), + + latOverlaps = (ne2.lat > sw.lat) && (sw2.lat < ne.lat), + lngOverlaps = (ne2.lng > sw.lng) && (sw2.lng < ne.lng); + + return latOverlaps && lngOverlaps; + }, + + // @method toBBoxString(): String + // Returns a string with bounding box coordinates in a 'southwest_lng,southwest_lat,northeast_lng,northeast_lat' format. Useful for sending requests to web services that return geo data. + toBBoxString: function () { + return [this.getWest(), this.getSouth(), this.getEast(), this.getNorth()].join(','); + }, + + // @method equals(otherBounds: LatLngBounds, maxMargin?: Number): Boolean + // Returns `true` if the rectangle is equivalent (within a small margin of error) to the given bounds. The margin of error can be overridden by setting `maxMargin` to a small number. + equals: function (bounds, maxMargin) { + if (!bounds) { return false; } + + bounds = toLatLngBounds(bounds); + + return this._southWest.equals(bounds.getSouthWest(), maxMargin) && + this._northEast.equals(bounds.getNorthEast(), maxMargin); + }, + + // @method isValid(): Boolean + // Returns `true` if the bounds are properly initialized. + isValid: function () { + return !!(this._southWest && this._northEast); + } + }; + + // TODO International date line? + + // @factory L.latLngBounds(corner1: LatLng, corner2: LatLng) + // Creates a `LatLngBounds` object by defining two diagonally opposite corners of the rectangle. + + // @alternative + // @factory L.latLngBounds(latlngs: LatLng[]) + // Creates a `LatLngBounds` object defined by the geographical points it contains. Very useful for zooming the map to fit a particular set of locations with [`fitBounds`](#map-fitbounds). + function toLatLngBounds(a, b) { + if (a instanceof LatLngBounds) { + return a; + } + return new LatLngBounds(a, b); + } + + /* @class LatLng + * @aka L.LatLng + * + * Represents a geographical point with a certain latitude and longitude. + * + * @example + * + * ``` + * var latlng = L.latLng(50.5, 30.5); + * ``` + * + * All Leaflet methods that accept LatLng objects also accept them in a simple Array form and simple object form (unless noted otherwise), so these lines are equivalent: + * + * ``` + * map.panTo([50, 30]); + * map.panTo({lon: 30, lat: 50}); + * map.panTo({lat: 50, lng: 30}); + * map.panTo(L.latLng(50, 30)); + * ``` + * + * Note that `LatLng` does not inherit from Leaflet's `Class` object, + * which means new classes can't inherit from it, and new methods + * can't be added to it with the `include` function. + */ + + function LatLng(lat, lng, alt) { + if (isNaN(lat) || isNaN(lng)) { + throw new Error('Invalid LatLng object: (' + lat + ', ' + lng + ')'); + } + + // @property lat: Number + // Latitude in degrees + this.lat = +lat; + + // @property lng: Number + // Longitude in degrees + this.lng = +lng; + + // @property alt: Number + // Altitude in meters (optional) + if (alt !== undefined) { + this.alt = +alt; + } + } + + LatLng.prototype = { + // @method equals(otherLatLng: LatLng, maxMargin?: Number): Boolean + // Returns `true` if the given `LatLng` point is at the same position (within a small margin of error). The margin of error can be overridden by setting `maxMargin` to a small number. + equals: function (obj, maxMargin) { + if (!obj) { return false; } + + obj = toLatLng(obj); + + var margin = Math.max( + Math.abs(this.lat - obj.lat), + Math.abs(this.lng - obj.lng)); + + return margin <= (maxMargin === undefined ? 1.0E-9 : maxMargin); + }, + + // @method toString(): String + // Returns a string representation of the point (for debugging purposes). + toString: function (precision) { + return 'LatLng(' + + formatNum(this.lat, precision) + ', ' + + formatNum(this.lng, precision) + ')'; + }, + + // @method distanceTo(otherLatLng: LatLng): Number + // Returns the distance (in meters) to the given `LatLng` calculated using the [Spherical Law of Cosines](https://en.wikipedia.org/wiki/Spherical_law_of_cosines). + distanceTo: function (other) { + return Earth.distance(this, toLatLng(other)); + }, + + // @method wrap(): LatLng + // Returns a new `LatLng` object with the longitude wrapped so it's always between -180 and +180 degrees. + wrap: function () { + return Earth.wrapLatLng(this); + }, + + // @method toBounds(sizeInMeters: Number): LatLngBounds + // Returns a new `LatLngBounds` object in which each boundary is `sizeInMeters/2` meters apart from the `LatLng`. + toBounds: function (sizeInMeters) { + var latAccuracy = 180 * sizeInMeters / 40075017, + lngAccuracy = latAccuracy / Math.cos((Math.PI / 180) * this.lat); + + return toLatLngBounds( + [this.lat - latAccuracy, this.lng - lngAccuracy], + [this.lat + latAccuracy, this.lng + lngAccuracy]); + }, + + clone: function () { + return new LatLng(this.lat, this.lng, this.alt); + } + }; + + + + // @factory L.latLng(latitude: Number, longitude: Number, altitude?: Number): LatLng + // Creates an object representing a geographical point with the given latitude and longitude (and optionally altitude). + + // @alternative + // @factory L.latLng(coords: Array): LatLng + // Expects an array of the form `[Number, Number]` or `[Number, Number, Number]` instead. + + // @alternative + // @factory L.latLng(coords: Object): LatLng + // Expects an plain object of the form `{lat: Number, lng: Number}` or `{lat: Number, lng: Number, alt: Number}` instead. + + function toLatLng(a, b, c) { + if (a instanceof LatLng) { + return a; + } + if (isArray(a) && typeof a[0] !== 'object') { + if (a.length === 3) { + return new LatLng(a[0], a[1], a[2]); + } + if (a.length === 2) { + return new LatLng(a[0], a[1]); + } + return null; + } + if (a === undefined || a === null) { + return a; + } + if (typeof a === 'object' && 'lat' in a) { + return new LatLng(a.lat, 'lng' in a ? a.lng : a.lon, a.alt); + } + if (b === undefined) { + return null; + } + return new LatLng(a, b, c); + } + + /* + * @namespace CRS + * @crs L.CRS.Base + * Object that defines coordinate reference systems for projecting + * geographical points into pixel (screen) coordinates and back (and to + * coordinates in other units for [WMS](https://en.wikipedia.org/wiki/Web_Map_Service) services). See + * [spatial reference system](https://en.wikipedia.org/wiki/Spatial_reference_system). + * + * Leaflet defines the most usual CRSs by default. If you want to use a + * CRS not defined by default, take a look at the + * [Proj4Leaflet](https://github.com/kartena/Proj4Leaflet) plugin. + * + * Note that the CRS instances do not inherit from Leaflet's `Class` object, + * and can't be instantiated. Also, new classes can't inherit from them, + * and methods can't be added to them with the `include` function. + */ + + var CRS = { + // @method latLngToPoint(latlng: LatLng, zoom: Number): Point + // Projects geographical coordinates into pixel coordinates for a given zoom. + latLngToPoint: function (latlng, zoom) { + var projectedPoint = this.projection.project(latlng), + scale = this.scale(zoom); + + return this.transformation._transform(projectedPoint, scale); + }, + + // @method pointToLatLng(point: Point, zoom: Number): LatLng + // The inverse of `latLngToPoint`. Projects pixel coordinates on a given + // zoom into geographical coordinates. + pointToLatLng: function (point, zoom) { + var scale = this.scale(zoom), + untransformedPoint = this.transformation.untransform(point, scale); + + return this.projection.unproject(untransformedPoint); + }, + + // @method project(latlng: LatLng): Point + // Projects geographical coordinates into coordinates in units accepted for + // this CRS (e.g. meters for EPSG:3857, for passing it to WMS services). + project: function (latlng) { + return this.projection.project(latlng); + }, + + // @method unproject(point: Point): LatLng + // Given a projected coordinate returns the corresponding LatLng. + // The inverse of `project`. + unproject: function (point) { + return this.projection.unproject(point); + }, + + // @method scale(zoom: Number): Number + // Returns the scale used when transforming projected coordinates into + // pixel coordinates for a particular zoom. For example, it returns + // `256 * 2^zoom` for Mercator-based CRS. + scale: function (zoom) { + return 256 * Math.pow(2, zoom); + }, + + // @method zoom(scale: Number): Number + // Inverse of `scale()`, returns the zoom level corresponding to a scale + // factor of `scale`. + zoom: function (scale) { + return Math.log(scale / 256) / Math.LN2; + }, + + // @method getProjectedBounds(zoom: Number): Bounds + // Returns the projection's bounds scaled and transformed for the provided `zoom`. + getProjectedBounds: function (zoom) { + if (this.infinite) { return null; } + + var b = this.projection.bounds, + s = this.scale(zoom), + min = this.transformation.transform(b.min, s), + max = this.transformation.transform(b.max, s); + + return new Bounds(min, max); + }, + + // @method distance(latlng1: LatLng, latlng2: LatLng): Number + // Returns the distance between two geographical coordinates. + + // @property code: String + // Standard code name of the CRS passed into WMS services (e.g. `'EPSG:3857'`) + // + // @property wrapLng: Number[] + // An array of two numbers defining whether the longitude (horizontal) coordinate + // axis wraps around a given range and how. Defaults to `[-180, 180]` in most + // geographical CRSs. If `undefined`, the longitude axis does not wrap around. + // + // @property wrapLat: Number[] + // Like `wrapLng`, but for the latitude (vertical) axis. + + // wrapLng: [min, max], + // wrapLat: [min, max], + + // @property infinite: Boolean + // If true, the coordinate space will be unbounded (infinite in both axes) + infinite: false, + + // @method wrapLatLng(latlng: LatLng): LatLng + // Returns a `LatLng` where lat and lng has been wrapped according to the + // CRS's `wrapLat` and `wrapLng` properties, if they are outside the CRS's bounds. + wrapLatLng: function (latlng) { + var lng = this.wrapLng ? wrapNum(latlng.lng, this.wrapLng, true) : latlng.lng, + lat = this.wrapLat ? wrapNum(latlng.lat, this.wrapLat, true) : latlng.lat, + alt = latlng.alt; + + return new LatLng(lat, lng, alt); + }, + + // @method wrapLatLngBounds(bounds: LatLngBounds): LatLngBounds + // Returns a `LatLngBounds` with the same size as the given one, ensuring + // that its center is within the CRS's bounds. + // Only accepts actual `L.LatLngBounds` instances, not arrays. + wrapLatLngBounds: function (bounds) { + var center = bounds.getCenter(), + newCenter = this.wrapLatLng(center), + latShift = center.lat - newCenter.lat, + lngShift = center.lng - newCenter.lng; + + if (latShift === 0 && lngShift === 0) { + return bounds; + } + + var sw = bounds.getSouthWest(), + ne = bounds.getNorthEast(), + newSw = new LatLng(sw.lat - latShift, sw.lng - lngShift), + newNe = new LatLng(ne.lat - latShift, ne.lng - lngShift); + + return new LatLngBounds(newSw, newNe); + } + }; + + /* + * @namespace CRS + * @crs L.CRS.Earth + * + * Serves as the base for CRS that are global such that they cover the earth. + * Can only be used as the base for other CRS and cannot be used directly, + * since it does not have a `code`, `projection` or `transformation`. `distance()` returns + * meters. + */ + + var Earth = extend({}, CRS, { + wrapLng: [-180, 180], + + // Mean Earth Radius, as recommended for use by + // the International Union of Geodesy and Geophysics, + // see https://rosettacode.org/wiki/Haversine_formula + R: 6371000, + + // distance between two geographical points using spherical law of cosines approximation + distance: function (latlng1, latlng2) { + var rad = Math.PI / 180, + lat1 = latlng1.lat * rad, + lat2 = latlng2.lat * rad, + sinDLat = Math.sin((latlng2.lat - latlng1.lat) * rad / 2), + sinDLon = Math.sin((latlng2.lng - latlng1.lng) * rad / 2), + a = sinDLat * sinDLat + Math.cos(lat1) * Math.cos(lat2) * sinDLon * sinDLon, + c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a)); + return this.R * c; + } + }); + + /* + * @namespace Projection + * @projection L.Projection.SphericalMercator + * + * Spherical Mercator projection — the most common projection for online maps, + * used by almost all free and commercial tile providers. Assumes that Earth is + * a sphere. Used by the `EPSG:3857` CRS. + */ + + var earthRadius = 6378137; + + var SphericalMercator = { + + R: earthRadius, + MAX_LATITUDE: 85.0511287798, + + project: function (latlng) { + var d = Math.PI / 180, + max = this.MAX_LATITUDE, + lat = Math.max(Math.min(max, latlng.lat), -max), + sin = Math.sin(lat * d); + + return new Point( + this.R * latlng.lng * d, + this.R * Math.log((1 + sin) / (1 - sin)) / 2); + }, + + unproject: function (point) { + var d = 180 / Math.PI; + + return new LatLng( + (2 * Math.atan(Math.exp(point.y / this.R)) - (Math.PI / 2)) * d, + point.x * d / this.R); + }, + + bounds: (function () { + var d = earthRadius * Math.PI; + return new Bounds([-d, -d], [d, d]); + })() + }; + + /* + * @class Transformation + * @aka L.Transformation + * + * Represents an affine transformation: a set of coefficients `a`, `b`, `c`, `d` + * for transforming a point of a form `(x, y)` into `(a*x + b, c*y + d)` and doing + * the reverse. Used by Leaflet in its projections code. + * + * @example + * + * ```js + * var transformation = L.transformation(2, 5, -1, 10), + * p = L.point(1, 2), + * p2 = transformation.transform(p), // L.point(7, 8) + * p3 = transformation.untransform(p2); // L.point(1, 2) + * ``` + */ + + + // factory new L.Transformation(a: Number, b: Number, c: Number, d: Number) + // Creates a `Transformation` object with the given coefficients. + function Transformation(a, b, c, d) { + if (isArray(a)) { + // use array properties + this._a = a[0]; + this._b = a[1]; + this._c = a[2]; + this._d = a[3]; + return; + } + this._a = a; + this._b = b; + this._c = c; + this._d = d; + } + + Transformation.prototype = { + // @method transform(point: Point, scale?: Number): Point + // Returns a transformed point, optionally multiplied by the given scale. + // Only accepts actual `L.Point` instances, not arrays. + transform: function (point, scale) { // (Point, Number) -> Point + return this._transform(point.clone(), scale); + }, + + // destructive transform (faster) + _transform: function (point, scale) { + scale = scale || 1; + point.x = scale * (this._a * point.x + this._b); + point.y = scale * (this._c * point.y + this._d); + return point; + }, + + // @method untransform(point: Point, scale?: Number): Point + // Returns the reverse transformation of the given point, optionally divided + // by the given scale. Only accepts actual `L.Point` instances, not arrays. + untransform: function (point, scale) { + scale = scale || 1; + return new Point( + (point.x / scale - this._b) / this._a, + (point.y / scale - this._d) / this._c); + } + }; + + // factory L.transformation(a: Number, b: Number, c: Number, d: Number) + + // @factory L.transformation(a: Number, b: Number, c: Number, d: Number) + // Instantiates a Transformation object with the given coefficients. + + // @alternative + // @factory L.transformation(coefficients: Array): Transformation + // Expects an coefficients array of the form + // `[a: Number, b: Number, c: Number, d: Number]`. + + function toTransformation(a, b, c, d) { + return new Transformation(a, b, c, d); + } + + /* + * @namespace CRS + * @crs L.CRS.EPSG3857 + * + * The most common CRS for online maps, used by almost all free and commercial + * tile providers. Uses Spherical Mercator projection. Set in by default in + * Map's `crs` option. + */ + + var EPSG3857 = extend({}, Earth, { + code: 'EPSG:3857', + projection: SphericalMercator, + + transformation: (function () { + var scale = 0.5 / (Math.PI * SphericalMercator.R); + return toTransformation(scale, 0.5, -scale, 0.5); + }()) + }); + + var EPSG900913 = extend({}, EPSG3857, { + code: 'EPSG:900913' + }); + + // @namespace SVG; @section + // There are several static functions which can be called without instantiating L.SVG: + + // @function create(name: String): SVGElement + // Returns a instance of [SVGElement](https://developer.mozilla.org/docs/Web/API/SVGElement), + // corresponding to the class name passed. For example, using 'line' will return + // an instance of [SVGLineElement](https://developer.mozilla.org/docs/Web/API/SVGLineElement). + function svgCreate(name) { + return document.createElementNS('http://www.w3.org/2000/svg', name); + } + + // @function pointsToPath(rings: Point[], closed: Boolean): String + // Generates a SVG path string for multiple rings, with each ring turning + // into "M..L..L.." instructions + function pointsToPath(rings, closed) { + var str = '', + i, j, len, len2, points, p; + + for (i = 0, len = rings.length; i < len; i++) { + points = rings[i]; + + for (j = 0, len2 = points.length; j < len2; j++) { + p = points[j]; + str += (j ? 'L' : 'M') + p.x + ' ' + p.y; + } + + // closes the ring for polygons; "x" is VML syntax + str += closed ? (Browser.svg ? 'z' : 'x') : ''; + } + + // SVG complains about empty path strings + return str || 'M0 0'; + } + + /* + * @namespace Browser + * @aka L.Browser + * + * A namespace with static properties for browser/feature detection used by Leaflet internally. + * + * @example + * + * ```js + * if (L.Browser.ielt9) { + * alert('Upgrade your browser, dude!'); + * } + * ``` + */ + + var style = document.documentElement.style; + + // @property ie: Boolean; `true` for all Internet Explorer versions (not Edge). + var ie = 'ActiveXObject' in window; + + // @property ielt9: Boolean; `true` for Internet Explorer versions less than 9. + var ielt9 = ie && !document.addEventListener; + + // @property edge: Boolean; `true` for the Edge web browser. + var edge = 'msLaunchUri' in navigator && !('documentMode' in document); + + // @property webkit: Boolean; + // `true` for webkit-based browsers like Chrome and Safari (including mobile versions). + var webkit = userAgentContains('webkit'); + + // @property android: Boolean + // **Deprecated.** `true` for any browser running on an Android platform. + var android = userAgentContains('android'); + + // @property android23: Boolean; **Deprecated.** `true` for browsers running on Android 2 or Android 3. + var android23 = userAgentContains('android 2') || userAgentContains('android 3'); + + /* See https://stackoverflow.com/a/17961266 for details on detecting stock Android */ + var webkitVer = parseInt(/WebKit\/([0-9]+)|$/.exec(navigator.userAgent)[1], 10); // also matches AppleWebKit + // @property androidStock: Boolean; **Deprecated.** `true` for the Android stock browser (i.e. not Chrome) + var androidStock = android && userAgentContains('Google') && webkitVer < 537 && !('AudioNode' in window); + + // @property opera: Boolean; `true` for the Opera browser + var opera = !!window.opera; + + // @property chrome: Boolean; `true` for the Chrome browser. + var chrome = !edge && userAgentContains('chrome'); + + // @property gecko: Boolean; `true` for gecko-based browsers like Firefox. + var gecko = userAgentContains('gecko') && !webkit && !opera && !ie; + + // @property safari: Boolean; `true` for the Safari browser. + var safari = !chrome && userAgentContains('safari'); + + var phantom = userAgentContains('phantom'); + + // @property opera12: Boolean + // `true` for the Opera browser supporting CSS transforms (version 12 or later). + var opera12 = 'OTransition' in style; + + // @property win: Boolean; `true` when the browser is running in a Windows platform + var win = navigator.platform.indexOf('Win') === 0; + + // @property ie3d: Boolean; `true` for all Internet Explorer versions supporting CSS transforms. + var ie3d = ie && ('transition' in style); + + // @property webkit3d: Boolean; `true` for webkit-based browsers supporting CSS transforms. + var webkit3d = ('WebKitCSSMatrix' in window) && ('m11' in new window.WebKitCSSMatrix()) && !android23; + + // @property gecko3d: Boolean; `true` for gecko-based browsers supporting CSS transforms. + var gecko3d = 'MozPerspective' in style; + + // @property any3d: Boolean + // `true` for all browsers supporting CSS transforms. + var any3d = !window.L_DISABLE_3D && (ie3d || webkit3d || gecko3d) && !opera12 && !phantom; + + // @property mobile: Boolean; `true` for all browsers running in a mobile device. + var mobile = typeof orientation !== 'undefined' || userAgentContains('mobile'); + + // @property mobileWebkit: Boolean; `true` for all webkit-based browsers in a mobile device. + var mobileWebkit = mobile && webkit; + + // @property mobileWebkit3d: Boolean + // `true` for all webkit-based browsers in a mobile device supporting CSS transforms. + var mobileWebkit3d = mobile && webkit3d; + + // @property msPointer: Boolean + // `true` for browsers implementing the Microsoft touch events model (notably IE10). + var msPointer = !window.PointerEvent && window.MSPointerEvent; + + // @property pointer: Boolean + // `true` for all browsers supporting [pointer events](https://msdn.microsoft.com/en-us/library/dn433244%28v=vs.85%29.aspx). + var pointer = !!(window.PointerEvent || msPointer); + + // @property touchNative: Boolean + // `true` for all browsers supporting [touch events](https://developer.mozilla.org/docs/Web/API/Touch_events). + // **This does not necessarily mean** that the browser is running in a computer with + // a touchscreen, it only means that the browser is capable of understanding + // touch events. + var touchNative = 'ontouchstart' in window || !!window.TouchEvent; + + // @property touch: Boolean + // `true` for all browsers supporting either [touch](#browser-touch) or [pointer](#browser-pointer) events. + // Note: pointer events will be preferred (if available), and processed for all `touch*` listeners. + var touch = !window.L_NO_TOUCH && (touchNative || pointer); + + // @property mobileOpera: Boolean; `true` for the Opera browser in a mobile device. + var mobileOpera = mobile && opera; + + // @property mobileGecko: Boolean + // `true` for gecko-based browsers running in a mobile device. + var mobileGecko = mobile && gecko; + + // @property retina: Boolean + // `true` for browsers on a high-resolution "retina" screen or on any screen when browser's display zoom is more than 100%. + var retina = (window.devicePixelRatio || (window.screen.deviceXDPI / window.screen.logicalXDPI)) > 1; + + // @property passiveEvents: Boolean + // `true` for browsers that support passive events. + var passiveEvents = (function () { + var supportsPassiveOption = false; + try { + var opts = Object.defineProperty({}, 'passive', { + get: function () { // eslint-disable-line getter-return + supportsPassiveOption = true; + } + }); + window.addEventListener('testPassiveEventSupport', falseFn, opts); + window.removeEventListener('testPassiveEventSupport', falseFn, opts); + } catch (e) { + // Errors can safely be ignored since this is only a browser support test. + } + return supportsPassiveOption; + }()); + + // @property canvas: Boolean + // `true` when the browser supports [``](https://developer.mozilla.org/docs/Web/API/Canvas_API). + var canvas$1 = (function () { + return !!document.createElement('canvas').getContext; + }()); + + // @property svg: Boolean + // `true` when the browser supports [SVG](https://developer.mozilla.org/docs/Web/SVG). + var svg$1 = !!(document.createElementNS && svgCreate('svg').createSVGRect); + + var inlineSvg = !!svg$1 && (function () { + var div = document.createElement('div'); + div.innerHTML = ''; + return (div.firstChild && div.firstChild.namespaceURI) === 'http://www.w3.org/2000/svg'; + })(); + + // @property vml: Boolean + // `true` if the browser supports [VML](https://en.wikipedia.org/wiki/Vector_Markup_Language). + var vml = !svg$1 && (function () { + try { + var div = document.createElement('div'); + div.innerHTML = ''; + + var shape = div.firstChild; + shape.style.behavior = 'url(#default#VML)'; + + return shape && (typeof shape.adj === 'object'); + + } catch (e) { + return false; + } + }()); + + + // @property mac: Boolean; `true` when the browser is running in a Mac platform + var mac = navigator.platform.indexOf('Mac') === 0; + + // @property mac: Boolean; `true` when the browser is running in a Linux platform + var linux = navigator.platform.indexOf('Linux') === 0; + + function userAgentContains(str) { + return navigator.userAgent.toLowerCase().indexOf(str) >= 0; + } + + + var Browser = { + ie: ie, + ielt9: ielt9, + edge: edge, + webkit: webkit, + android: android, + android23: android23, + androidStock: androidStock, + opera: opera, + chrome: chrome, + gecko: gecko, + safari: safari, + phantom: phantom, + opera12: opera12, + win: win, + ie3d: ie3d, + webkit3d: webkit3d, + gecko3d: gecko3d, + any3d: any3d, + mobile: mobile, + mobileWebkit: mobileWebkit, + mobileWebkit3d: mobileWebkit3d, + msPointer: msPointer, + pointer: pointer, + touch: touch, + touchNative: touchNative, + mobileOpera: mobileOpera, + mobileGecko: mobileGecko, + retina: retina, + passiveEvents: passiveEvents, + canvas: canvas$1, + svg: svg$1, + vml: vml, + inlineSvg: inlineSvg, + mac: mac, + linux: linux + }; + + /* + * Extends L.DomEvent to provide touch support for Internet Explorer and Windows-based devices. + */ + + var POINTER_DOWN = Browser.msPointer ? 'MSPointerDown' : 'pointerdown'; + var POINTER_MOVE = Browser.msPointer ? 'MSPointerMove' : 'pointermove'; + var POINTER_UP = Browser.msPointer ? 'MSPointerUp' : 'pointerup'; + var POINTER_CANCEL = Browser.msPointer ? 'MSPointerCancel' : 'pointercancel'; + var pEvent = { + touchstart : POINTER_DOWN, + touchmove : POINTER_MOVE, + touchend : POINTER_UP, + touchcancel : POINTER_CANCEL + }; + var handle = { + touchstart : _onPointerStart, + touchmove : _handlePointer, + touchend : _handlePointer, + touchcancel : _handlePointer + }; + var _pointers = {}; + var _pointerDocListener = false; + + // Provides a touch events wrapper for (ms)pointer events. + // ref https://www.w3.org/TR/pointerevents/ https://www.w3.org/Bugs/Public/show_bug.cgi?id=22890 + + function addPointerListener(obj, type, handler) { + if (type === 'touchstart') { + _addPointerDocListener(); + } + if (!handle[type]) { + console.warn('wrong event specified:', type); + return falseFn; + } + handler = handle[type].bind(this, handler); + obj.addEventListener(pEvent[type], handler, false); + return handler; + } + + function removePointerListener(obj, type, handler) { + if (!pEvent[type]) { + console.warn('wrong event specified:', type); + return; + } + obj.removeEventListener(pEvent[type], handler, false); + } + + function _globalPointerDown(e) { + _pointers[e.pointerId] = e; + } + + function _globalPointerMove(e) { + if (_pointers[e.pointerId]) { + _pointers[e.pointerId] = e; + } + } + + function _globalPointerUp(e) { + delete _pointers[e.pointerId]; + } + + function _addPointerDocListener() { + // need to keep track of what pointers and how many are active to provide e.touches emulation + if (!_pointerDocListener) { + // we listen document as any drags that end by moving the touch off the screen get fired there + document.addEventListener(POINTER_DOWN, _globalPointerDown, true); + document.addEventListener(POINTER_MOVE, _globalPointerMove, true); + document.addEventListener(POINTER_UP, _globalPointerUp, true); + document.addEventListener(POINTER_CANCEL, _globalPointerUp, true); + + _pointerDocListener = true; + } + } + + function _handlePointer(handler, e) { + if (e.pointerType === (e.MSPOINTER_TYPE_MOUSE || 'mouse')) { return; } + + e.touches = []; + for (var i in _pointers) { + e.touches.push(_pointers[i]); + } + e.changedTouches = [e]; + + handler(e); + } + + function _onPointerStart(handler, e) { + // IE10 specific: MsTouch needs preventDefault. See #2000 + if (e.MSPOINTER_TYPE_TOUCH && e.pointerType === e.MSPOINTER_TYPE_TOUCH) { + preventDefault(e); + } + _handlePointer(handler, e); + } + + /* + * Extends the event handling code with double tap support for mobile browsers. + * + * Note: currently most browsers fire native dblclick, with only a few exceptions + * (see https://github.com/Leaflet/Leaflet/issues/7012#issuecomment-595087386) + */ + + function makeDblclick(event) { + // in modern browsers `type` cannot be just overridden: + // https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Errors/Getter_only + var newEvent = {}, + prop, i; + for (i in event) { + prop = event[i]; + newEvent[i] = prop && prop.bind ? prop.bind(event) : prop; + } + event = newEvent; + newEvent.type = 'dblclick'; + newEvent.detail = 2; + newEvent.isTrusted = false; + newEvent._simulated = true; // for debug purposes + return newEvent; + } + + var delay = 200; + function addDoubleTapListener(obj, handler) { + // Most browsers handle double tap natively + obj.addEventListener('dblclick', handler); + + // On some platforms the browser doesn't fire native dblclicks for touch events. + // It seems that in all such cases `detail` property of `click` event is always `1`. + // So here we rely on that fact to avoid excessive 'dblclick' simulation when not needed. + var last = 0, + detail; + function simDblclick(e) { + if (e.detail !== 1) { + detail = e.detail; // keep in sync to avoid false dblclick in some cases + return; + } + + if (e.pointerType === 'mouse' || + (e.sourceCapabilities && !e.sourceCapabilities.firesTouchEvents)) { + + return; + } + + // When clicking on an , the browser generates a click on its + //