diff --git a/assets/css/Control.Geocoder.css b/assets/css/Control.Geocoder.css
new file mode 100644
index 00000000..00c32255
--- /dev/null
+++ b/assets/css/Control.Geocoder.css
@@ -0,0 +1,126 @@
+.leaflet-control-geocoder {
+ border-radius: 4px;
+ background: white;
+ min-width: 26px;
+ min-height: 26px;
+}
+
+.leaflet-touch .leaflet-control-geocoder {
+ min-width: 30px;
+ min-height: 30px;
+}
+
+.leaflet-control-geocoder a,
+.leaflet-control-geocoder .leaflet-control-geocoder-icon {
+ border-bottom: none;
+ display: inline-block;
+}
+
+.leaflet-control-geocoder .leaflet-control-geocoder-alternatives a {
+ width: inherit;
+ height: inherit;
+ line-height: inherit;
+}
+
+.leaflet-control-geocoder a:hover,
+.leaflet-control-geocoder .leaflet-control-geocoder-icon:hover {
+ border-bottom: none;
+ display: inline-block;
+}
+
+.leaflet-control-geocoder-form {
+ display: none;
+ vertical-align: middle;
+}
+.leaflet-control-geocoder-expanded .leaflet-control-geocoder-form {
+ display: inline-block;
+}
+.leaflet-control-geocoder-form input {
+ font-size: 120%;
+ border: 0;
+ background-color: transparent;
+ width: 246px;
+}
+
+.leaflet-control-geocoder-icon {
+ border-radius: 4px;
+ width: 26px;
+ height: 26px;
+ border: none;
+ background-color: white;
+ background-image: url(images/geocoder.png);
+ background-repeat: no-repeat;
+ background-position: center;
+ cursor: pointer;
+}
+
+.leaflet-touch .leaflet-control-geocoder-icon {
+ width: 30px;
+ height: 30px;
+}
+
+.leaflet-control-geocoder-throbber .leaflet-control-geocoder-icon {
+ background-image: url(images/throbber.gif);
+}
+
+.leaflet-control-geocoder-form-no-error {
+ display: none;
+}
+
+.leaflet-control-geocoder-form input:focus {
+ outline: none;
+}
+
+.leaflet-control-geocoder-form button {
+ display: none;
+}
+.leaflet-control-geocoder-error {
+ margin-top: 8px;
+ margin-left: 8px;
+ display: block;
+ color: #444;
+}
+.leaflet-control-geocoder-alternatives {
+ display: block;
+ width: 272px;
+ list-style: none;
+ padding: 0;
+ margin: 0;
+}
+
+.leaflet-control-geocoder-alternatives-minimized {
+ display: none;
+ height: 0;
+}
+.leaflet-control-geocoder-alternatives li {
+ white-space: nowrap;
+ display: block;
+ overflow: hidden;
+ padding: 5px 8px;
+ text-overflow: ellipsis;
+ border-bottom: 1px solid #ccc;
+ cursor: pointer;
+}
+
+.leaflet-control-geocoder-alternatives li a,
+.leaflet-control-geocoder-alternatives li a:hover {
+ width: inherit;
+ height: inherit;
+ line-height: inherit;
+ background: inherit;
+ border-radius: inherit;
+ text-align: left;
+}
+
+.leaflet-control-geocoder-alternatives li:last-child {
+ border-bottom: none;
+}
+.leaflet-control-geocoder-alternatives li:hover,
+.leaflet-control-geocoder-selected {
+ background-color: #f5f5f5;
+}
+.leaflet-control-geocoder-address-detail {
+}
+.leaflet-control-geocoder-address-context {
+ color: #666;
+}
diff --git a/assets/css/images/geocoder.png b/assets/css/images/geocoder.png
new file mode 100644
index 00000000..d82a0170
Binary files /dev/null and b/assets/css/images/geocoder.png differ
diff --git a/assets/css/images/layers-2x.png b/assets/css/images/layers-2x.png
new file mode 100644
index 00000000..200c333d
Binary files /dev/null and b/assets/css/images/layers-2x.png differ
diff --git a/assets/css/images/layers.png b/assets/css/images/layers.png
new file mode 100644
index 00000000..1a72e578
Binary files /dev/null and b/assets/css/images/layers.png differ
diff --git a/assets/css/images/marker-icon-2x.png b/assets/css/images/marker-icon-2x.png
new file mode 100644
index 00000000..88f9e501
Binary files /dev/null and b/assets/css/images/marker-icon-2x.png differ
diff --git a/assets/css/images/marker-icon.png b/assets/css/images/marker-icon.png
new file mode 100644
index 00000000..950edf24
Binary files /dev/null and b/assets/css/images/marker-icon.png differ
diff --git a/assets/css/images/marker-shadow.png b/assets/css/images/marker-shadow.png
new file mode 100644
index 00000000..9fd29795
Binary files /dev/null and b/assets/css/images/marker-shadow.png differ
diff --git a/assets/css/images/throbber.gif b/assets/css/images/throbber.gif
new file mode 100644
index 00000000..c0c52a06
Binary files /dev/null and b/assets/css/images/throbber.gif differ
diff --git a/assets/css/leaflet.css b/assets/css/leaflet.css
new file mode 100644
index 00000000..70802f36
--- /dev/null
+++ b/assets/css/leaflet.css
@@ -0,0 +1,635 @@
+/* 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;
+ }
+/* 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,
+.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;
+ }
+
+.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-tile {
+ will-change: opacity;
+ }
+.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;
+ }
+.leaflet-zoom-anim .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 {
+ pointer-events: visiblePainted; /* IE 9-10 doesn't have auto */
+ pointer-events: auto;
+ }
+
+/* visual tweaks */
+
+.leaflet-container {
+ background: #ddd;
+ outline: 0;
+ }
+.leaflet-container a {
+ color: #0078A8;
+ }
+.leaflet-container a.leaflet-active {
+ outline: 2px solid orange;
+ }
+.leaflet-zoom-box {
+ border: 2px dotted #38f;
+ background: rgba(255,255,255,0.5);
+ }
+
+
+/* general typography */
+.leaflet-container {
+ font: 12px/1.5 "Helvetica Neue", Arial, Helvetica, sans-serif;
+ }
+
+
+/* general toolbar styles */
+
+.leaflet-bar {
+ box-shadow: 0 1px 5px rgba(0,0,0,0.65);
+ border-radius: 4px;
+ }
+.leaflet-bar a,
+.leaflet-bar a:hover {
+ 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 {
+ 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;
+ }
+.leaflet-control-layers-separator {
+ height: 0;
+ border-top: 1px solid #ddd;
+ margin: 5px -10px 5px -6px;
+ }
+
+/* Default icon URLs */
+.leaflet-default-icon-path {
+ background-image: url(images/marker-icon.png);
+ }
+
+
+/* attribution and scale controls */
+
+.leaflet-container .leaflet-control-attribution {
+ background: #fff;
+ background: rgba(255, 255, 255, 0.7);
+ margin: 0;
+ }
+.leaflet-control-attribution,
+.leaflet-control-scale-line {
+ padding: 0 5px;
+ color: #333;
+ }
+.leaflet-control-attribution a {
+ text-decoration: none;
+ }
+.leaflet-control-attribution a:hover {
+ text-decoration: underline;
+ }
+.leaflet-container .leaflet-control-attribution,
+.leaflet-container .leaflet-control-scale {
+ font-size: 11px;
+ }
+.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;
+ font-size: 11px;
+ white-space: nowrap;
+ overflow: hidden;
+ -moz-box-sizing: border-box;
+ box-sizing: border-box;
+
+ background: #fff;
+ background: rgba(255, 255, 255, 0.5);
+ }
+.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 19px;
+ line-height: 1.4;
+ }
+.leaflet-popup-content p {
+ margin: 18px 0;
+ }
+.leaflet-popup-tip-container {
+ width: 40px;
+ height: 20px;
+ position: absolute;
+ left: 50%;
+ margin-left: -20px;
+ overflow: hidden;
+ pointer-events: none;
+ }
+.leaflet-popup-tip {
+ width: 17px;
+ height: 17px;
+ padding: 1px;
+
+ margin: -10px auto 0;
+
+ -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;
+ padding: 4px 4px 0 0;
+ border: none;
+ text-align: center;
+ width: 18px;
+ height: 14px;
+ font: 16px/14px Tahoma, Verdana, sans-serif;
+ color: #c3c3c3;
+ text-decoration: none;
+ font-weight: bold;
+ background: transparent;
+ }
+.leaflet-container a.leaflet-popup-close-button:hover {
+ color: #999;
+ }
+.leaflet-popup-scrolled {
+ overflow: auto;
+ border-bottom: 1px solid #ddd;
+ border-top: 1px solid #ddd;
+ }
+
+.leaflet-oldie .leaflet-popup-content-wrapper {
+ 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-popup-tip-container {
+ margin-top: -1px;
+ }
+
+.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-clickable {
+ 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;
+ }
diff --git a/assets/js/Control.Geocoder.js b/assets/js/Control.Geocoder.js
new file mode 100644
index 00000000..78408d40
--- /dev/null
+++ b/assets/js/Control.Geocoder.js
@@ -0,0 +1,1348 @@
+this.L = this.L || {};
+this.L.Control = this.L.Control || {};
+this.L.Control.Geocoder = (function (L) {
+'use strict';
+
+L = L && L.hasOwnProperty('default') ? L['default'] : L;
+
+var lastCallbackId = 0;
+
+// Adapted from handlebars.js
+// https://github.com/wycats/handlebars.js/
+var badChars = /[&<>"'`]/g;
+var possible = /[&<>"'`]/;
+var escape = {
+ '&': '&',
+ '<': '<',
+ '>': '>',
+ '"': '"',
+ "'": ''',
+ '`': '`'
+};
+
+function escapeChar(chr) {
+ return escape[chr];
+}
+
+function htmlEscape(string) {
+ if (string == null) {
+ return '';
+ } else if (!string) {
+ return string + '';
+ }
+
+ // Force a string conversion as this will be done by the append regardless and
+ // the regex test will do this transparently behind the scenes, causing issues if
+ // an object's to string has escaped characters in it.
+ string = '' + string;
+
+ if (!possible.test(string)) {
+ return string;
+ }
+ return string.replace(badChars, escapeChar);
+}
+
+function jsonp(url, params, callback, context, jsonpParam) {
+ var callbackId = '_l_geocoder_' + lastCallbackId++;
+ params[jsonpParam || 'callback'] = callbackId;
+ window[callbackId] = L.Util.bind(callback, context);
+ var script = document.createElement('script');
+ script.type = 'text/javascript';
+ script.src = url + L.Util.getParamString(params);
+ script.id = callbackId;
+ document.getElementsByTagName('head')[0].appendChild(script);
+}
+
+function getJSON(url, params, callback) {
+ var xmlHttp = new XMLHttpRequest();
+ xmlHttp.onreadystatechange = function() {
+ if (xmlHttp.readyState !== 4) {
+ return;
+ }
+ if (xmlHttp.status !== 200 && xmlHttp.status !== 304) {
+ callback('');
+ return;
+ }
+ callback(JSON.parse(xmlHttp.response));
+ };
+ xmlHttp.open('GET', url + L.Util.getParamString(params), true);
+ xmlHttp.setRequestHeader('Accept', 'application/json');
+ xmlHttp.send(null);
+}
+
+function template(str, data) {
+ return str.replace(/\{ *([\w_]+) *\}/g, function(str, key) {
+ var value = data[key];
+ if (value === undefined) {
+ value = '';
+ } else if (typeof value === 'function') {
+ value = value(data);
+ }
+ return htmlEscape(value);
+ });
+}
+
+var Nominatim = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://nominatim.openstreetmap.org/',
+ geocodingQueryParams: {},
+ reverseQueryParams: {},
+ htmlTemplate: function(r) {
+ var a = r.address,
+ parts = [];
+ if (a.road || a.building) {
+ parts.push('{building} {road} {house_number}');
+ }
+
+ if (a.city || a.town || a.village || a.hamlet) {
+ parts.push(
+ '{postcode} {city} {town} {village} {hamlet}'
+ );
+ }
+
+ if (a.state || a.country) {
+ parts.push(
+ '{state} {country}'
+ );
+ }
+
+ return template(parts.join('
'), a, true);
+ }
+ },
+
+ initialize: function(options) {
+ L.Util.setOptions(this, options);
+ },
+
+ geocode: function(query, cb, context) {
+ getJSON(
+ this.options.serviceUrl + 'search',
+ L.extend(
+ {
+ q: query,
+ limit: 5,
+ format: 'json',
+ addressdetails: 1
+ },
+ this.options.geocodingQueryParams
+ ),
+ L.bind(function(data) {
+ var results = [];
+ for (var i = data.length - 1; i >= 0; i--) {
+ var bbox = data[i].boundingbox;
+ for (var j = 0; j < 4; j++) bbox[j] = parseFloat(bbox[j]);
+ results[i] = {
+ icon: data[i].icon,
+ name: data[i].display_name,
+ html: this.options.htmlTemplate ? this.options.htmlTemplate(data[i]) : undefined,
+ bbox: L.latLngBounds([bbox[0], bbox[2]], [bbox[1], bbox[3]]),
+ center: L.latLng(data[i].lat, data[i].lon),
+ properties: data[i]
+ };
+ }
+ cb.call(context, results);
+ }, this)
+ );
+ },
+
+ reverse: function(location, scale, cb, context) {
+ getJSON(
+ this.options.serviceUrl + 'reverse',
+ L.extend(
+ {
+ lat: location.lat,
+ lon: location.lng,
+ zoom: Math.round(Math.log(scale / 256) / Math.log(2)),
+ addressdetails: 1,
+ format: 'json'
+ },
+ this.options.reverseQueryParams
+ ),
+ L.bind(function(data) {
+ var result = [],
+ loc;
+
+ if (data && data.lat && data.lon) {
+ loc = L.latLng(data.lat, data.lon);
+ result.push({
+ name: data.display_name,
+ html: this.options.htmlTemplate ? this.options.htmlTemplate(data) : undefined,
+ center: loc,
+ bounds: L.latLngBounds(loc, loc),
+ properties: data
+ });
+ }
+
+ cb.call(context, result);
+ }, this)
+ );
+ }
+ }),
+
+ factory: function(options) {
+ return new L.Control.Geocoder.Nominatim(options);
+ }
+};
+
+var Control = {
+ class: L.Control.extend({
+ options: {
+ showResultIcons: false,
+ collapsed: true,
+ expand: 'touch', // options: touch, click, anythingelse
+ position: 'topright',
+ placeholder: 'Search...',
+ errorMessage: 'Nothing found.',
+ suggestMinLength: 3,
+ suggestTimeout: 250,
+ defaultMarkGeocode: true
+ },
+
+ includes: L.Evented.prototype || L.Mixin.Events,
+
+ initialize: function(options) {
+ L.Util.setOptions(this, options);
+ if (!this.options.geocoder) {
+ this.options.geocoder = new Nominatim.class();
+ }
+
+ this._requestCount = 0;
+ },
+
+ onAdd: function(map) {
+ var className = 'leaflet-control-geocoder',
+ container = L.DomUtil.create('div', className + ' leaflet-bar'),
+ icon = L.DomUtil.create('button', className + '-icon', container),
+ form = (this._form = L.DomUtil.create('div', className + '-form', container)),
+ input;
+
+ this._map = map;
+ this._container = container;
+
+ icon.innerHTML = ' ';
+ icon.type = 'button';
+
+ input = this._input = L.DomUtil.create('input', '', form);
+ input.type = 'text';
+ input.placeholder = this.options.placeholder;
+
+ this._errorElement = L.DomUtil.create('div', className + '-form-no-error', container);
+ this._errorElement.innerHTML = this.options.errorMessage;
+
+ this._alts = L.DomUtil.create(
+ 'ul',
+ className + '-alternatives leaflet-control-geocoder-alternatives-minimized',
+ container
+ );
+ L.DomEvent.disableClickPropagation(this._alts);
+
+ L.DomEvent.addListener(input, 'keydown', this._keydown, this);
+ if (this.options.geocoder.suggest) {
+ L.DomEvent.addListener(input, 'input', this._change, this);
+ }
+ L.DomEvent.addListener(
+ input,
+ 'blur',
+ function() {
+ if (this.options.collapsed && !this._preventBlurCollapse) {
+ this._collapse();
+ }
+ this._preventBlurCollapse = false;
+ },
+ this
+ );
+
+ if (this.options.collapsed) {
+ if (this.options.expand === 'click') {
+ L.DomEvent.addListener(
+ container,
+ 'click',
+ function(e) {
+ if (e.button === 0 && e.detail !== 2) {
+ this._toggle();
+ }
+ },
+ this
+ );
+ } else if (L.Browser.touch && this.options.expand === 'touch') {
+ L.DomEvent.addListener(
+ container,
+ 'touchstart mousedown',
+ function(e) {
+ this._toggle();
+ e.preventDefault(); // mobile: clicking focuses the icon, so UI expands and immediately collapses
+ e.stopPropagation();
+ },
+ this
+ );
+ } else {
+ L.DomEvent.addListener(container, 'mouseover', this._expand, this);
+ L.DomEvent.addListener(container, 'mouseout', this._collapse, this);
+ this._map.on('movestart', this._collapse, this);
+ }
+ } else {
+ this._expand();
+ if (L.Browser.touch) {
+ L.DomEvent.addListener(
+ container,
+ 'touchstart',
+ function() {
+ this._geocode();
+ },
+ this
+ );
+ } else {
+ L.DomEvent.addListener(
+ container,
+ 'click',
+ function() {
+ this._geocode();
+ },
+ this
+ );
+ }
+ }
+
+ if (this.options.defaultMarkGeocode) {
+ this.on('markgeocode', this.markGeocode, this);
+ }
+
+ this.on(
+ 'startgeocode',
+ function() {
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-throbber');
+ },
+ this
+ );
+ this.on(
+ 'finishgeocode',
+ function() {
+ L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-throbber');
+ },
+ this
+ );
+
+ L.DomEvent.disableClickPropagation(container);
+
+ return container;
+ },
+
+ _geocodeResult: function(results, suggest) {
+ if (!suggest && results.length === 1) {
+ this._geocodeResultSelected(results[0]);
+ } else if (results.length > 0) {
+ this._alts.innerHTML = '';
+ this._results = results;
+ L.DomUtil.removeClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
+ for (var i = 0; i < results.length; i++) {
+ this._alts.appendChild(this._createAlt(results[i], i));
+ }
+ } else {
+ L.DomUtil.addClass(this._errorElement, 'leaflet-control-geocoder-error');
+ }
+ },
+
+ markGeocode: function(result) {
+ result = result.geocode || result;
+
+ this._map.fitBounds(result.bbox);
+
+ if (this._geocodeMarker) {
+ this._map.removeLayer(this._geocodeMarker);
+ }
+
+ this._geocodeMarker = new L.Marker(result.center)
+ .bindPopup(result.html || result.name)
+ .addTo(this._map)
+ .openPopup();
+
+ return this;
+ },
+
+ _geocode: function(suggest) {
+ var requestCount = ++this._requestCount,
+ mode = suggest ? 'suggest' : 'geocode',
+ eventData = { input: this._input.value };
+
+ this._lastGeocode = this._input.value;
+ if (!suggest) {
+ this._clearResults();
+ }
+
+ this.fire('start' + mode, eventData);
+ this.options.geocoder[mode](
+ this._input.value,
+ function(results) {
+ if (requestCount === this._requestCount) {
+ eventData.results = results;
+ this.fire('finish' + mode, eventData);
+ this._geocodeResult(results, suggest);
+ }
+ },
+ this
+ );
+ },
+
+ _geocodeResultSelected: function(result) {
+ this.fire('markgeocode', { geocode: result });
+ },
+
+ _toggle: function() {
+ if (L.DomUtil.hasClass(this._container, 'leaflet-control-geocoder-expanded')) {
+ this._collapse();
+ } else {
+ this._expand();
+ }
+ },
+
+ _expand: function() {
+ L.DomUtil.addClass(this._container, 'leaflet-control-geocoder-expanded');
+ this._input.select();
+ this.fire('expand');
+ },
+
+ _collapse: function() {
+ L.DomUtil.removeClass(this._container, 'leaflet-control-geocoder-expanded');
+ L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
+ L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
+ this._input.blur(); // mobile: keyboard shouldn't stay expanded
+ this.fire('collapse');
+ },
+
+ _clearResults: function() {
+ L.DomUtil.addClass(this._alts, 'leaflet-control-geocoder-alternatives-minimized');
+ this._selection = null;
+ L.DomUtil.removeClass(this._errorElement, 'leaflet-control-geocoder-error');
+ },
+
+ _createAlt: function(result, index) {
+ var li = L.DomUtil.create('li', ''),
+ a = L.DomUtil.create('a', '', li),
+ icon = this.options.showResultIcons && result.icon ? L.DomUtil.create('img', '', a) : null,
+ text = result.html ? undefined : document.createTextNode(result.name),
+ mouseDownHandler = function mouseDownHandler(e) {
+ // In some browsers, a click will fire on the map if the control is
+ // collapsed directly after mousedown. To work around this, we
+ // wait until the click is completed, and _then_ collapse the
+ // control. Messy, but this is the workaround I could come up with
+ // for #142.
+ this._preventBlurCollapse = true;
+ L.DomEvent.stop(e);
+ this._geocodeResultSelected(result);
+ L.DomEvent.on(
+ li,
+ 'click',
+ function() {
+ if (this.options.collapsed) {
+ this._collapse();
+ } else {
+ this._clearResults();
+ }
+ },
+ this
+ );
+ };
+
+ if (icon) {
+ icon.src = result.icon;
+ }
+
+ li.setAttribute('data-result-index', index);
+
+ if (result.html) {
+ a.innerHTML = a.innerHTML + result.html;
+ } else {
+ a.appendChild(text);
+ }
+
+ // Use mousedown and not click, since click will fire _after_ blur,
+ // causing the control to have collapsed and removed the items
+ // before the click can fire.
+ L.DomEvent.addListener(li, 'mousedown touchstart', mouseDownHandler, this);
+
+ return li;
+ },
+
+ _keydown: function(e) {
+ var _this = this,
+ select = function select(dir) {
+ if (_this._selection) {
+ L.DomUtil.removeClass(_this._selection, 'leaflet-control-geocoder-selected');
+ _this._selection = _this._selection[dir > 0 ? 'nextSibling' : 'previousSibling'];
+ }
+ if (!_this._selection) {
+ _this._selection = _this._alts[dir > 0 ? 'firstChild' : 'lastChild'];
+ }
+
+ if (_this._selection) {
+ L.DomUtil.addClass(_this._selection, 'leaflet-control-geocoder-selected');
+ }
+ };
+
+ switch (e.keyCode) {
+ // Escape
+ case 27:
+ if (this.options.collapsed) {
+ this._collapse();
+ }
+ break;
+ // Up
+ case 38:
+ select(-1);
+ break;
+ // Up
+ case 40:
+ select(1);
+ break;
+ // Enter
+ case 13:
+ if (this._selection) {
+ var index = parseInt(this._selection.getAttribute('data-result-index'), 10);
+ this._geocodeResultSelected(this._results[index]);
+ this._clearResults();
+ } else {
+ this._geocode();
+ }
+ break;
+ }
+ },
+ _change: function() {
+ var v = this._input.value;
+ if (v !== this._lastGeocode) {
+ clearTimeout(this._suggestTimeout);
+ if (v.length >= this.options.suggestMinLength) {
+ this._suggestTimeout = setTimeout(
+ L.bind(function() {
+ this._geocode(true);
+ }, this),
+ this.options.suggestTimeout
+ );
+ } else {
+ this._clearResults();
+ }
+ }
+ }
+ }),
+ factory: function(options) {
+ return new L.Control.Geocoder(options);
+ }
+};
+
+var Bing = {
+ class: L.Class.extend({
+ initialize: function(key) {
+ this.key = key;
+ },
+
+ geocode: function(query, cb, context) {
+ jsonp(
+ 'https://dev.virtualearth.net/REST/v1/Locations',
+ {
+ query: query,
+ key: this.key
+ },
+ function(data) {
+ var results = [];
+ if (data.resourceSets.length > 0) {
+ for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
+ var resource = data.resourceSets[0].resources[i],
+ bbox = resource.bbox;
+ results[i] = {
+ name: resource.name,
+ bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
+ center: L.latLng(resource.point.coordinates)
+ };
+ }
+ }
+ cb.call(context, results);
+ },
+ this,
+ 'jsonp'
+ );
+ },
+
+ reverse: function(location, scale, cb, context) {
+ jsonp(
+ '//dev.virtualearth.net/REST/v1/Locations/' + location.lat + ',' + location.lng,
+ {
+ key: this.key
+ },
+ function(data) {
+ var results = [];
+ for (var i = data.resourceSets[0].resources.length - 1; i >= 0; i--) {
+ var resource = data.resourceSets[0].resources[i],
+ bbox = resource.bbox;
+ results[i] = {
+ name: resource.name,
+ bbox: L.latLngBounds([bbox[0], bbox[1]], [bbox[2], bbox[3]]),
+ center: L.latLng(resource.point.coordinates)
+ };
+ }
+ cb.call(context, results);
+ },
+ this,
+ 'jsonp'
+ );
+ }
+ }),
+
+ factory: function(key) {
+ return new L.Control.Geocoder.Bing(key);
+ }
+};
+
+var MapQuest = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://www.mapquestapi.com/geocoding/v1'
+ },
+
+ initialize: function(key, options) {
+ // MapQuest seems to provide URI encoded API keys,
+ // so to avoid encoding them twice, we decode them here
+ this._key = decodeURIComponent(key);
+
+ L.Util.setOptions(this, options);
+ },
+
+ _formatName: function() {
+ var r = [],
+ i;
+ for (i = 0; i < arguments.length; i++) {
+ if (arguments[i]) {
+ r.push(arguments[i]);
+ }
+ }
+
+ return r.join(', ');
+ },
+
+ geocode: function(query, cb, context) {
+ getJSON(
+ this.options.serviceUrl + '/address',
+ {
+ key: this._key,
+ location: query,
+ limit: 5,
+ outFormat: 'json'
+ },
+ L.bind(function(data) {
+ var results = [],
+ loc,
+ latLng;
+ if (data.results && data.results[0].locations) {
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
+ loc = data.results[0].locations[i];
+ latLng = L.latLng(loc.latLng);
+ results[i] = {
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
+ bbox: L.latLngBounds(latLng, latLng),
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ }, this)
+ );
+ },
+
+ reverse: function(location, scale, cb, context) {
+ getJSON(
+ this.options.serviceUrl + '/reverse',
+ {
+ key: this._key,
+ location: location.lat + ',' + location.lng,
+ outputFormat: 'json'
+ },
+ L.bind(function(data) {
+ var results = [],
+ loc,
+ latLng;
+ if (data.results && data.results[0].locations) {
+ for (var i = data.results[0].locations.length - 1; i >= 0; i--) {
+ loc = data.results[0].locations[i];
+ latLng = L.latLng(loc.latLng);
+ results[i] = {
+ name: this._formatName(loc.street, loc.adminArea4, loc.adminArea3, loc.adminArea1),
+ bbox: L.latLngBounds(latLng, latLng),
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ }, this)
+ );
+ }
+ }),
+
+ factory: function(key, options) {
+ return new L.Control.Geocoder.MapQuest(key, options);
+ }
+};
+
+var Mapbox = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://api.tiles.mapbox.com/v4/geocode/mapbox.places-v1/',
+ geocodingQueryParams: {},
+ reverseQueryParams: {}
+ },
+
+ initialize: function(accessToken, options) {
+ L.setOptions(this, options);
+ this.options.geocodingQueryParams.access_token = accessToken;
+ this.options.reverseQueryParams.access_token = accessToken;
+ },
+
+ geocode: function(query, cb, context) {
+ var params = this.options.geocodingQueryParams;
+ if (
+ typeof params.proximity !== 'undefined' &&
+ params.proximity.hasOwnProperty('lat') &&
+ params.proximity.hasOwnProperty('lng')
+ ) {
+ params.proximity = params.proximity.lng + ',' + params.proximity.lat;
+ }
+ getJSON(this.options.serviceUrl + encodeURIComponent(query) + '.json', params, function(
+ data
+ ) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.features && data.features.length) {
+ for (var i = 0; i <= data.features.length - 1; i++) {
+ loc = data.features[i];
+ latLng = L.latLng(loc.center.reverse());
+ if (loc.hasOwnProperty('bbox')) {
+ latLngBounds = L.latLngBounds(
+ L.latLng(loc.bbox.slice(0, 2).reverse()),
+ L.latLng(loc.bbox.slice(2, 4).reverse())
+ );
+ } else {
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ }
+ results[i] = {
+ name: loc.place_name,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
+ },
+
+ reverse: function(location, scale, cb, context) {
+ getJSON(
+ this.options.serviceUrl +
+ encodeURIComponent(location.lng) +
+ ',' +
+ encodeURIComponent(location.lat) +
+ '.json',
+ this.options.reverseQueryParams,
+ function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.features && data.features.length) {
+ for (var i = 0; i <= data.features.length - 1; i++) {
+ loc = data.features[i];
+ latLng = L.latLng(loc.center.reverse());
+ if (loc.hasOwnProperty('bbox')) {
+ latLngBounds = L.latLngBounds(
+ L.latLng(loc.bbox.slice(0, 2).reverse()),
+ L.latLng(loc.bbox.slice(2, 4).reverse())
+ );
+ } else {
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ }
+ results[i] = {
+ name: loc.place_name,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ }
+ );
+ }
+ }),
+
+ factory: function(accessToken, options) {
+ return new L.Control.Geocoder.Mapbox(accessToken, options);
+ }
+};
+
+var What3Words = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://api.what3words.com/v2/'
+ },
+
+ initialize: function(accessToken) {
+ this._accessToken = accessToken;
+ },
+
+ geocode: function(query, cb, context) {
+ //get three words and make a dot based string
+ getJSON(
+ this.options.serviceUrl + 'forward',
+ {
+ key: this._accessToken,
+ addr: query.split(/\s+/).join('.')
+ },
+ function(data) {
+ var results = [],
+ latLng,
+ latLngBounds;
+ if (data.hasOwnProperty('geometry')) {
+ latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ results[0] = {
+ name: data.words,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+
+ cb.call(context, results);
+ }
+ );
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
+ },
+
+ reverse: function(location, scale, cb, context) {
+ getJSON(
+ this.options.serviceUrl + 'reverse',
+ {
+ key: this._accessToken,
+ coords: [location.lat, location.lng].join(',')
+ },
+ function(data) {
+ var results = [],
+ latLng,
+ latLngBounds;
+ if (data.status.status == 200) {
+ latLng = L.latLng(data.geometry['lat'], data.geometry['lng']);
+ latLngBounds = L.latLngBounds(latLng, latLng);
+ results[0] = {
+ name: data.words,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ cb.call(context, results);
+ }
+ );
+ }
+ }),
+
+ factory: function(accessToken) {
+ return new L.Control.Geocoder.What3Words(accessToken);
+ }
+};
+
+var Google = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://maps.googleapis.com/maps/api/geocode/json',
+ geocodingQueryParams: {},
+ reverseQueryParams: {}
+ },
+
+ initialize: function(key, options) {
+ this._key = key;
+ L.setOptions(this, options);
+ // Backwards compatibility
+ this.options.serviceUrl = this.options.service_url || this.options.serviceUrl;
+ },
+
+ geocode: function(query, cb, context) {
+ var params = {
+ address: query
+ };
+
+ if (this._key && this._key.length) {
+ params.key = this._key;
+ }
+
+ params = L.Util.extend(params, this.options.geocodingQueryParams);
+
+ getJSON(this.options.serviceUrl, params, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.results && data.results.length) {
+ for (var i = 0; i <= data.results.length - 1; i++) {
+ loc = data.results[i];
+ latLng = L.latLng(loc.geometry.location);
+ latLngBounds = L.latLngBounds(
+ L.latLng(loc.geometry.viewport.northeast),
+ L.latLng(loc.geometry.viewport.southwest)
+ );
+ results[i] = {
+ name: loc.formatted_address,
+ bbox: latLngBounds,
+ center: latLng,
+ properties: loc.address_components
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ },
+
+ reverse: function(location, scale, cb, context) {
+ var params = {
+ latlng: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng)
+ };
+ params = L.Util.extend(params, this.options.reverseQueryParams);
+ if (this._key && this._key.length) {
+ params.key = this._key;
+ }
+
+ getJSON(this.options.serviceUrl, params, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.results && data.results.length) {
+ for (var i = 0; i <= data.results.length - 1; i++) {
+ loc = data.results[i];
+ latLng = L.latLng(loc.geometry.location);
+ latLngBounds = L.latLngBounds(
+ L.latLng(loc.geometry.viewport.northeast),
+ L.latLng(loc.geometry.viewport.southwest)
+ );
+ results[i] = {
+ name: loc.formatted_address,
+ bbox: latLngBounds,
+ center: latLng,
+ properties: loc.address_components
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ }
+ }),
+
+ factory: function(key, options) {
+ return new L.Control.Geocoder.Google(key, options);
+ }
+};
+
+var Photon = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://photon.komoot.de/api/',
+ reverseUrl: 'https://photon.komoot.de/reverse/',
+ nameProperties: ['name', 'street', 'suburb', 'hamlet', 'town', 'city', 'state', 'country']
+ },
+
+ initialize: function(options) {
+ L.setOptions(this, options);
+ },
+
+ geocode: function(query, cb, context) {
+ var params = L.extend(
+ {
+ q: query
+ },
+ this.options.geocodingQueryParams
+ );
+
+ getJSON(
+ this.options.serviceUrl,
+ params,
+ L.bind(function(data) {
+ cb.call(context, this._decodeFeatures(data));
+ }, this)
+ );
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
+ },
+
+ reverse: function(latLng, scale, cb, context) {
+ var params = L.extend(
+ {
+ lat: latLng.lat,
+ lon: latLng.lng
+ },
+ this.options.reverseQueryParams
+ );
+
+ getJSON(
+ this.options.reverseUrl,
+ params,
+ L.bind(function(data) {
+ cb.call(context, this._decodeFeatures(data));
+ }, this)
+ );
+ },
+
+ _decodeFeatures: function(data) {
+ var results = [],
+ i,
+ f,
+ c,
+ latLng,
+ extent,
+ bbox;
+
+ if (data && data.features) {
+ for (i = 0; i < data.features.length; i++) {
+ f = data.features[i];
+ c = f.geometry.coordinates;
+ latLng = L.latLng(c[1], c[0]);
+ extent = f.properties.extent;
+
+ if (extent) {
+ bbox = L.latLngBounds([extent[1], extent[0]], [extent[3], extent[2]]);
+ } else {
+ bbox = L.latLngBounds(latLng, latLng);
+ }
+
+ results.push({
+ name: this._deocodeFeatureName(f),
+ html: this.options.htmlTemplate ? this.options.htmlTemplate(f) : undefined,
+ center: latLng,
+ bbox: bbox,
+ properties: f.properties
+ });
+ }
+ }
+
+ return results;
+ },
+
+ _deocodeFeatureName: function(f) {
+ var j, name;
+ for (j = 0; !name && j < this.options.nameProperties.length; j++) {
+ name = f.properties[this.options.nameProperties[j]];
+ }
+
+ return name;
+ }
+ }),
+
+ factory: function(options) {
+ return new L.Control.Geocoder.Photon(options);
+ }
+};
+
+var Mapzen = {
+ class: L.Class.extend({
+ options: {
+ serviceUrl: 'https://search.mapzen.com/v1',
+ geocodingQueryParams: {},
+ reverseQueryParams: {}
+ },
+
+ initialize: function(apiKey, options) {
+ L.Util.setOptions(this, options);
+ this._apiKey = apiKey;
+ this._lastSuggest = 0;
+ },
+
+ geocode: function(query, cb, context) {
+ var _this = this;
+ getJSON(
+ this.options.serviceUrl + '/search',
+ L.extend(
+ {
+ api_key: this._apiKey,
+ text: query
+ },
+ this.options.geocodingQueryParams
+ ),
+ function(data) {
+ cb.call(context, _this._parseResults(data, 'bbox'));
+ }
+ );
+ },
+
+ suggest: function(query, cb, context) {
+ var _this = this;
+ getJSON(
+ this.options.serviceUrl + '/autocomplete',
+ L.extend(
+ {
+ api_key: this._apiKey,
+ text: query
+ },
+ this.options.geocodingQueryParams
+ ),
+ L.bind(function(data) {
+ if (data.geocoding.timestamp > this._lastSuggest) {
+ this._lastSuggest = data.geocoding.timestamp;
+ cb.call(context, _this._parseResults(data, 'bbox'));
+ }
+ }, this)
+ );
+ },
+
+ reverse: function(location, scale, cb, context) {
+ var _this = this;
+ getJSON(
+ this.options.serviceUrl + '/reverse',
+ L.extend(
+ {
+ api_key: this._apiKey,
+ 'point.lat': location.lat,
+ 'point.lon': location.lng
+ },
+ this.options.reverseQueryParams
+ ),
+ function(data) {
+ cb.call(context, _this._parseResults(data, 'bounds'));
+ }
+ );
+ },
+
+ _parseResults: function(data, bboxname) {
+ var results = [];
+ L.geoJson(data, {
+ pointToLayer: function(feature, latlng) {
+ return L.circleMarker(latlng);
+ },
+ onEachFeature: function(feature, layer) {
+ var result = {},
+ bbox,
+ center;
+
+ if (layer.getBounds) {
+ bbox = layer.getBounds();
+ center = bbox.getCenter();
+ } else {
+ center = layer.getLatLng();
+ bbox = L.latLngBounds(center, center);
+ }
+
+ result.name = layer.feature.properties.label;
+ result.center = center;
+ result[bboxname] = bbox;
+ result.properties = layer.feature.properties;
+ results.push(result);
+ }
+ });
+ return results;
+ }
+ }),
+
+ factory: function(apiKey, options) {
+ return new L.Control.Geocoder.Mapzen(apiKey, options);
+ }
+};
+
+var ArcGis = {
+ class: L.Class.extend({
+ options: {
+ service_url: 'http://geocode.arcgis.com/arcgis/rest/services/World/GeocodeServer'
+ },
+
+ initialize: function(accessToken, options) {
+ L.setOptions(this, options);
+ this._accessToken = accessToken;
+ },
+
+ geocode: function(query, cb, context) {
+ var params = {
+ SingleLine: query,
+ outFields: 'Addr_Type',
+ forStorage: false,
+ maxLocations: 10,
+ f: 'json'
+ };
+
+ if (this._key && this._key.length) {
+ params.token = this._key;
+ }
+
+ getJSON(this.options.service_url + '/findAddressCandidates', params, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+
+ if (data.candidates && data.candidates.length) {
+ for (var i = 0; i <= data.candidates.length - 1; i++) {
+ loc = data.candidates[i];
+ latLng = L.latLng(loc.location.y, loc.location.x);
+ latLngBounds = L.latLngBounds(
+ L.latLng(loc.extent.ymax, loc.extent.xmax),
+ L.latLng(loc.extent.ymin, loc.extent.xmin)
+ );
+ results[i] = {
+ name: loc.address,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ }
+
+ cb.call(context, results);
+ });
+ },
+
+ suggest: function(query, cb, context) {
+ return this.geocode(query, cb, context);
+ },
+
+ reverse: function(location, scale, cb, context) {
+ var params = {
+ location: encodeURIComponent(location.lng) + ',' + encodeURIComponent(location.lat),
+ distance: 100,
+ f: 'json'
+ };
+
+ getJSON(this.options.service_url + '/reverseGeocode', params, function(data) {
+ var result = [],
+ loc;
+
+ if (data && !data.error) {
+ loc = L.latLng(data.location.y, data.location.x);
+ result.push({
+ name: data.address.Match_addr,
+ center: loc,
+ bounds: L.latLngBounds(loc, loc)
+ });
+ }
+
+ cb.call(context, result);
+ });
+ }
+ }),
+
+ factory: function(accessToken, options) {
+ return new L.Control.Geocoder.ArcGis(accessToken, options);
+ }
+};
+
+var HERE = {
+ class: L.Class.extend({
+ options: {
+ geocodeUrl: 'http://geocoder.api.here.com/6.2/geocode.json',
+ reverseGeocodeUrl: 'http://reverse.geocoder.api.here.com/6.2/reversegeocode.json',
+ app_id: '',
+ app_code: '',
+ geocodingQueryParams: {},
+ reverseQueryParams: {}
+ },
+
+ initialize: function(options) {
+ L.setOptions(this, options);
+ },
+
+ geocode: function(query, cb, context) {
+ var params = {
+ searchtext: query,
+ gen: 9,
+ app_id: this.options.app_id,
+ app_code: this.options.app_code,
+ jsonattributes: 1
+ };
+ params = L.Util.extend(params, this.options.geocodingQueryParams);
+ this.getJSON(this.options.geocodeUrl, params, cb, context);
+ },
+
+ reverse: function(location, scale, cb, context) {
+ var params = {
+ prox: encodeURIComponent(location.lat) + ',' + encodeURIComponent(location.lng),
+ mode: 'retrieveAddresses',
+ app_id: this.options.app_id,
+ app_code: this.options.app_code,
+ gen: 9,
+ jsonattributes: 1
+ };
+ params = L.Util.extend(params, this.options.reverseQueryParams);
+ this.getJSON(this.options.reverseGeocodeUrl, params, cb, context);
+ },
+
+ getJSON: function(url, params, cb, context) {
+ getJSON(url, params, function(data) {
+ var results = [],
+ loc,
+ latLng,
+ latLngBounds;
+ if (data.response.view && data.response.view.length) {
+ for (var i = 0; i <= data.response.view[0].result.length - 1; i++) {
+ loc = data.response.view[0].result[i].location;
+ latLng = L.latLng(loc.displayPosition.latitude, loc.displayPosition.longitude);
+ latLngBounds = L.latLngBounds(
+ L.latLng(loc.mapView.topLeft.latitude, loc.mapView.topLeft.longitude),
+ L.latLng(loc.mapView.bottomRight.latitude, loc.mapView.bottomRight.longitude)
+ );
+ results[i] = {
+ name: loc.address.label,
+ bbox: latLngBounds,
+ center: latLng
+ };
+ }
+ }
+ cb.call(context, results);
+ });
+ }
+ }),
+
+ factory: function(options) {
+ return new L.Control.Geocoder.HERE(options);
+ }
+};
+
+var Geocoder = L.Util.extend(Control.class, {
+ Nominatim: Nominatim.class,
+ nominatim: Nominatim.factory,
+ Bing: Bing.class,
+ bing: Bing.factory,
+ MapQuest: MapQuest.class,
+ mapQuest: MapQuest.factory,
+ Mapbox: Mapbox.class,
+ mapbox: Mapbox.factory,
+ What3Words: What3Words.class,
+ what3words: What3Words.factory,
+ Google: Google.class,
+ google: Google.factory,
+ Photon: Photon.class,
+ photon: Photon.factory,
+ Mapzen: Mapzen.class,
+ mapzen: Mapzen.factory,
+ ArcGis: ArcGis.class,
+ arcgis: ArcGis.factory,
+ HERE: HERE.class,
+ here: HERE.factory
+});
+
+L.Util.extend(L.Control, {
+ Geocoder: Geocoder,
+ geocoder: Control.factory
+});
+
+return Geocoder;
+
+}(L));
+//# sourceMappingURL=Control.Geocoder.js.map
diff --git a/assets/js/admin/locationpicker.js b/assets/js/admin/locationpicker.js
deleted file mode 100644
index ffd472cc..00000000
--- a/assets/js/admin/locationpicker.js
+++ /dev/null
@@ -1,16 +0,0 @@
-jQuery(document).ready(function($){
- $(".sp-location-picker").locationpicker({
- location: {
- latitude: Number($(".sp-latitude").val()),
- longitude: Number($(".sp-longitude").val())
- },
- radius: 0,
- inputBinding: {
- latitudeInput: $(".sp-latitude"),
- longitudeInput: $(".sp-longitude"),
- locationNameInput: $(".sp-address")
- },
- addressFormat: null,
- enableAutocomplete: true
- });
-});
\ No newline at end of file
diff --git a/assets/js/admin/sp-geocoder.js b/assets/js/admin/sp-geocoder.js
new file mode 100644
index 00000000..00ce4039
--- /dev/null
+++ b/assets/js/admin/sp-geocoder.js
@@ -0,0 +1,54 @@
+//Get variables form input values
+latitude = document.getElementById('term_meta[sp_latitude]').value;
+longitude = document.getElementById('term_meta[sp_longitude]').value;
+
+//Initialize the map and add the Search control box
+var map = L.map('sp-location-picker').setView([latitude, longitude], 15),
+ geocoder = L.Control.Geocoder.nominatim(),
+ control = L.Control.geocoder({
+ geocoder: geocoder,
+ collapsed: false,
+ defaultMarkGeocode: false
+ }).addTo(map),
+ //Add a marker to use from the begining
+ marker = L.marker([latitude, longitude],{draggable: true, autoPan: true}).addTo(map);
+
+L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
+ attribution: '© OpenStreetMap contributors'
+}).addTo(map);
+
+//Pass the values to the fields after dragging
+marker.on('dragend', function (e) {
+ document.getElementById('term_meta[sp_latitude]').value = marker.getLatLng().lat;
+ document.getElementById('term_meta[sp_longitude]').value = marker.getLatLng().lng;
+ geocoder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
+ var r = results[0];
+ if (r) {
+ document.getElementById('term_meta[sp_address]').value = r.name;
+ }
+ })
+});
+
+//After searching
+control.on('markgeocode', function(e) {
+ var center = e.geocode.center;
+ var address = e.geocode.name;
+ map.setView([center.lat, center.lng], 15); //Center map to the new place
+ map.removeLayer(marker); //Remove previous marker
+ marker = L.marker([center.lat, center.lng],{draggable: true, autoPan: true}).addTo(map); //Add new marker to use
+ //Pass the values to the fields after searching
+ document.getElementById('term_meta[sp_latitude]').value = center.lat;
+ document.getElementById('term_meta[sp_longitude]').value = center.lng;
+ document.getElementById('term_meta[sp_address]').value = address;
+ //Pass the values to the fields after dragging
+ marker.on('dragend', function (e) {
+ document.getElementById('term_meta[sp_latitude]').value = marker.getLatLng().lat;
+ document.getElementById('term_meta[sp_longitude]').value = marker.getLatLng().lng;
+ geocoder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
+ var r = results[0];
+ if (r) {
+ document.getElementById('term_meta[sp_address]').value = r.name;
+ }
+ })
+ });
+}).addTo(map);
\ No newline at end of file
diff --git a/assets/js/admin/sp-setup-geocoder.js b/assets/js/admin/sp-setup-geocoder.js
new file mode 100644
index 00000000..504b6329
--- /dev/null
+++ b/assets/js/admin/sp-setup-geocoder.js
@@ -0,0 +1,54 @@
+//Get variables form input values
+latitude = document.getElementById('sp_latitude').value;
+longitude = document.getElementById('sp_longitude').value;
+
+//Initialize the map and add the Search control box
+var map = L.map('sp-location-picker').setView([latitude, longitude], 15),
+ geocoder = L.Control.Geocoder.nominatim(),
+ control = L.Control.geocoder({
+ geocoder: geocoder,
+ collapsed: false,
+ defaultMarkGeocode: false
+ }).addTo(map),
+ //Add a marker to use from the begining
+ marker = L.marker([latitude, longitude],{draggable: true, autoPan: true}).addTo(map);
+
+L.tileLayer('http://{s}.tile.osm.org/{z}/{x}/{y}.png', {
+ attribution: '© OpenStreetMap contributors'
+}).addTo(map);
+
+//Pass the values to the fields after dragging
+marker.on('dragend', function (e) {
+ document.getElementById('sp_latitude').value = marker.getLatLng().lat;
+ document.getElementById('sp_longitude').value = marker.getLatLng().lng;
+ geocoder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
+ var r = results[0];
+ if (r) {
+ document.getElementById('sp_address').value = r.name;
+ }
+ })
+});
+
+//After searching
+control.on('markgeocode', function(e) {
+ var center = e.geocode.center;
+ var address = e.geocode.name;
+ map.setView([center.lat, center.lng], 15); //Center map to the new place
+ map.removeLayer(marker); //Remove previous marker
+ marker = L.marker([center.lat, center.lng],{draggable: true, autoPan: true}).addTo(map); //Add new marker to use
+ //Pass the values to the fields after searching
+ document.getElementById('sp_latitude').value = center.lat;
+ document.getElementById('sp_longitude').value = center.lng;
+ document.getElementById('sp_address').value = address;
+ //Pass the values to the fields after dragging
+ marker.on('dragend', function (e) {
+ document.getElementById('sp_latitude').value = marker.getLatLng().lat;
+ document.getElementById('sp_longitude').value = marker.getLatLng().lng;
+ geocoder.reverse(marker.getLatLng(), map.options.crs.scale(map.getZoom()), function(results) {
+ var r = results[0];
+ if (r) {
+ document.getElementById('sp_address').value = r.name;
+ }
+ })
+ });
+}).addTo(map);
\ No newline at end of file
diff --git a/assets/js/leaflet.js b/assets/js/leaflet.js
new file mode 100644
index 00000000..576a90ee
--- /dev/null
+++ b/assets/js/leaflet.js
@@ -0,0 +1,5 @@
+/* @preserve
+ * Leaflet 1.4.0+Detached: 3337f36d2a2d2b33946779057619b31f674ff5dc.3337f36, a JS library for interactive maps. http://leafletjs.com
+ * (c) 2010-2018 Vladimir Agafonkin, (c) 2010-2011 CloudMade
+ */
+!function(t,i){"object"==typeof exports&&"undefined"!=typeof module?i(exports):"function"==typeof define&&define.amd?define(["exports"],i):i(t.L={})}(this,function(t){"use strict";function i(t){var i,e,n,o;for(e=1,n=arguments.length;e=0}function A(t,i,e,n){return"touchstart"===i?O(t,e,n):"touchmove"===i?W(t,e,n):"touchend"===i&&H(t,e,n),this}function I(t,i,e){var n=t["_leaflet_"+i+e];return"touchstart"===i?t.removeEventListener(te,n,!1):"touchmove"===i?t.removeEventListener(ie,n,!1):"touchend"===i&&(t.removeEventListener(ee,n,!1),t.removeEventListener(ne,n,!1)),this}function O(t,i,n){var o=e(function(t){if("mouse"!==t.pointerType&&t.MSPOINTER_TYPE_MOUSE&&t.pointerType!==t.MSPOINTER_TYPE_MOUSE){if(!(oe.indexOf(t.target.tagName)<0))return;Pt(t)}j(t,i)});t["_leaflet_touchstart"+n]=o,t.addEventListener(te,o,!1),re||(document.documentElement.addEventListener(te,R,!0),document.documentElement.addEventListener(ie,N,!0),document.documentElement.addEventListener(ee,D,!0),document.documentElement.addEventListener(ne,D,!0),re=!0)}function R(t){se[t.pointerId]=t,ae++}function N(t){se[t.pointerId]&&(se[t.pointerId]=t)}function D(t){delete se[t.pointerId],ae--}function j(t,i){t.touches=[];for(var e in se)t.touches.push(se[e]);t.changedTouches=[t],i(t)}function W(t,i,e){var n=function(t){(t.pointerType!==t.MSPOINTER_TYPE_MOUSE&&"mouse"!==t.pointerType||0!==t.buttons)&&j(t,i)};t["_leaflet_touchmove"+e]=n,t.addEventListener(ie,n,!1)}function H(t,i,e){var n=function(t){j(t,i)};t["_leaflet_touchend"+e]=n,t.addEventListener(ee,n,!1),t.addEventListener(ne,n,!1)}function F(t,i,e){function n(t){var i;if(Vi){if(!bi||"mouse"===t.pointerType)return;i=ae}else i=t.touches.length;if(!(i>1)){var e=Date.now(),n=e-(s||e);r=t.touches?t.touches[0]:t,a=n>0&&n<=h,s=e}}function o(t){if(a&&!r.cancelBubble){if(Vi){if(!bi||"mouse"===t.pointerType)return;var e,n,o={};for(n in r)e=r[n],o[n]=e&&e.bind?e.bind(r):e;r=o}r.type="dblclick",i(r),s=null}}var s,r,a=!1,h=250;return t[le+he+e]=n,t[le+ue+e]=o,t[le+"dblclick"+e]=i,t.addEventListener(he,n,!1),t.addEventListener(ue,o,!1),t.addEventListener("dblclick",i,!1),this}function U(t,i){var e=t[le+he+i],n=t[le+ue+i],o=t[le+"dblclick"+i];return t.removeEventListener(he,e,!1),t.removeEventListener(ue,n,!1),bi||t.removeEventListener("dblclick",o,!1),this}function V(t){return"string"==typeof t?document.getElementById(t):t}function q(t,i){var e=t.style[i]||t.currentStyle&&t.currentStyle[i];if((!e||"auto"===e)&&document.defaultView){var n=document.defaultView.getComputedStyle(t,null);e=n?n[i]:null}return"auto"===e?null:e}function G(t,i,e){var n=document.createElement(t);return n.className=i||"",e&&e.appendChild(n),n}function K(t){var i=t.parentNode;i&&i.removeChild(t)}function Y(t){for(;t.firstChild;)t.removeChild(t.firstChild)}function X(t){var i=t.parentNode;i&&i.lastChild!==t&&i.appendChild(t)}function J(t){var i=t.parentNode;i&&i.firstChild!==t&&i.insertBefore(t,i.firstChild)}function $(t,i){if(void 0!==t.classList)return t.classList.contains(i);var e=et(t);return e.length>0&&new RegExp("(^|\\s)"+i+"(\\s|$)").test(e)}function Q(t,i){if(void 0!==t.classList)for(var e=u(i),n=0,o=e.length;n100&&n<500||t.target._simulatedClick&&!t._simulated?Lt(t):(ge=e,i(t))}function Zt(t,i){if(!i||!t.length)return t.slice();var e=i*i;return t=At(t,e),t=kt(t,e)}function Et(t,i,e){return Math.sqrt(Dt(t,i,e,!0))}function kt(t,i){var e=t.length,n=new(typeof Uint8Array!=void 0+""?Uint8Array:Array)(e);n[0]=n[e-1]=1,Bt(t,n,i,0,e-1);var o,s=[];for(o=0;oh&&(s=r,h=a);h>e&&(i[s]=1,Bt(t,i,e,n,s),Bt(t,i,e,s,o))}function At(t,i){for(var e=[t[0]],n=1,o=0,s=t.length;ni&&(e.push(t[n]),o=n);return oi.max.x&&(e|=2),t.yi.max.y&&(e|=8),e}function Nt(t,i){var e=i.x-t.x,n=i.y-t.y;return e*e+n*n}function Dt(t,i,e,n){var o,s=i.x,r=i.y,a=e.x-s,h=e.y-r,u=a*a+h*h;return u>0&&((o=((t.x-s)*a+(t.y-r)*h)/u)>1?(s=e.x,r=e.y):o>0&&(s+=a*o,r+=h*o)),a=t.x-s,h=t.y-r,n?a*a+h*h:new x(s,r)}function jt(t){return!oi(t[0])||"object"!=typeof t[0][0]&&void 0!==t[0][0]}function Wt(t){return console.warn("Deprecated use of _flat, please use L.LineUtil.isFlat instead."),jt(t)}function Ht(t,i,e){var n,o,s,r,a,h,u,l,c,_=[1,4,2,8];for(o=0,u=t.length;o0?Math.floor(t):Math.ceil(t)};x.prototype={clone:function(){return new x(this.x,this.y)},add:function(t){return this.clone()._add(w(t))},_add:function(t){return this.x+=t.x,this.y+=t.y,this},subtract:function(t){return this.clone()._subtract(w(t))},_subtract:function(t){return this.x-=t.x,this.y-=t.y,this},divideBy:function(t){return this.clone()._divideBy(t)},_divideBy:function(t){return this.x/=t,this.y/=t,this},multiplyBy:function(t){return this.clone()._multiplyBy(t)},_multiplyBy:function(t){return this.x*=t,this.y*=t,this},scaleBy:function(t){return new x(this.x*t.x,this.y*t.y)},unscaleBy:function(t){return new x(this.x/t.x,this.y/t.y)},round:function(){return this.clone()._round()},_round:function(){return this.x=Math.round(this.x),this.y=Math.round(this.y),this},floor:function(){return this.clone()._floor()},_floor:function(){return this.x=Math.floor(this.x),this.y=Math.floor(this.y),this},ceil:function(){return this.clone()._ceil()},_ceil:function(){return this.x=Math.ceil(this.x),this.y=Math.ceil(this.y),this},trunc:function(){return this.clone()._trunc()},_trunc:function(){return this.x=_i(this.x),this.y=_i(this.y),this},distanceTo:function(t){var i=(t=w(t)).x-this.x,e=t.y-this.y;return Math.sqrt(i*i+e*e)},equals:function(t){return(t=w(t)).x===this.x&&t.y===this.y},contains:function(t){return t=w(t),Math.abs(t.x)<=Math.abs(this.x)&&Math.abs(t.y)<=Math.abs(this.y)},toString:function(){return"Point("+a(this.x)+", "+a(this.y)+")"}},P.prototype={extend:function(t){return t=w(t),this.min||this.max?(this.min.x=Math.min(t.x,this.min.x),this.max.x=Math.max(t.x,this.max.x),this.min.y=Math.min(t.y,this.min.y),this.max.y=Math.max(t.y,this.max.y)):(this.min=t.clone(),this.max=t.clone()),this},getCenter:function(t){return new x((this.min.x+this.max.x)/2,(this.min.y+this.max.y)/2,t)},getBottomLeft:function(){return new x(this.min.x,this.max.y)},getTopRight:function(){return new x(this.max.x,this.min.y)},getTopLeft:function(){return this.min},getBottomRight:function(){return this.max},getSize:function(){return this.max.subtract(this.min)},contains:function(t){var i,e;return(t="number"==typeof t[0]||t instanceof x?w(t):b(t))instanceof P?(i=t.min,e=t.max):i=e=t,i.x>=this.min.x&&e.x<=this.max.x&&i.y>=this.min.y&&e.y<=this.max.y},intersects:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>=i.x&&n.x<=e.x,r=o.y>=i.y&&n.y<=e.y;return s&&r},overlaps:function(t){t=b(t);var i=this.min,e=this.max,n=t.min,o=t.max,s=o.x>i.x&&n.xi.y&&n.y=n.lat&&e.lat<=o.lat&&i.lng>=n.lng&&e.lng<=o.lng},intersects:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>=i.lat&&n.lat<=e.lat,r=o.lng>=i.lng&&n.lng<=e.lng;return s&&r},overlaps:function(t){t=z(t);var i=this._southWest,e=this._northEast,n=t.getSouthWest(),o=t.getNorthEast(),s=o.lat>i.lat&&n.lati.lng&&n.lng1,Xi=!!document.createElement("canvas").getContext,Ji=!(!document.createElementNS||!E("svg").createSVGRect),$i=!Ji&&function(){try{var t=document.createElement("div");t.innerHTML='';var i=t.firstChild;return i.style.behavior="url(#default#VML)",i&&"object"==typeof i.adj}catch(t){return!1}}(),Qi=(Object.freeze||Object)({ie:Pi,ielt9:Li,edge:bi,webkit:Ti,android:zi,android23:Mi,androidStock:Si,opera:Zi,chrome:Ei,gecko:ki,safari:Bi,phantom:Ai,opera12:Ii,win:Oi,ie3d:Ri,webkit3d:Ni,gecko3d:Di,any3d:ji,mobile:Wi,mobileWebkit:Hi,mobileWebkit3d:Fi,msPointer:Ui,pointer:Vi,touch:qi,mobileOpera:Gi,mobileGecko:Ki,retina:Yi,canvas:Xi,svg:Ji,vml:$i}),te=Ui?"MSPointerDown":"pointerdown",ie=Ui?"MSPointerMove":"pointermove",ee=Ui?"MSPointerUp":"pointerup",ne=Ui?"MSPointerCancel":"pointercancel",oe=["INPUT","SELECT","OPTION"],se={},re=!1,ae=0,he=Ui?"MSPointerDown":Vi?"pointerdown":"touchstart",ue=Ui?"MSPointerUp":Vi?"pointerup":"touchend",le="_leaflet_",ce=st(["transform","webkitTransform","OTransform","MozTransform","msTransform"]),_e=st(["webkitTransition","transition","OTransition","MozTransition","msTransition"]),de="webkitTransition"===_e||"OTransition"===_e?_e+"End":"transitionend";if("onselectstart"in document)fi=function(){mt(window,"selectstart",Pt)},gi=function(){ft(window,"selectstart",Pt)};else{var pe=st(["userSelect","WebkitUserSelect","OUserSelect","MozUserSelect","msUserSelect"]);fi=function(){if(pe){var t=document.documentElement.style;vi=t[pe],t[pe]="none"}},gi=function(){pe&&(document.documentElement.style[pe]=vi,vi=void 0)}}var me,fe,ge,ve=(Object.freeze||Object)({TRANSFORM:ce,TRANSITION:_e,TRANSITION_END:de,get:V,getStyle:q,create:G,remove:K,empty:Y,toFront:X,toBack:J,hasClass:$,addClass:Q,removeClass:tt,setClass:it,getClass:et,setOpacity:nt,testProp:st,setTransform:rt,setPosition:at,getPosition:ht,disableTextSelection:fi,enableTextSelection:gi,disableImageDrag:ut,enableImageDrag:lt,preventOutline:ct,restoreOutline:_t,getSizedParentNode:dt,getScale:pt}),ye="_leaflet_events",xe=Oi&&Ei?2*window.devicePixelRatio:ki?window.devicePixelRatio:1,we={},Pe=(Object.freeze||Object)({on:mt,off:ft,stopPropagation:yt,disableScrollPropagation:xt,disableClickPropagation:wt,preventDefault:Pt,stop:Lt,getMousePosition:bt,getWheelDelta:Tt,fakeStop:zt,skipped:Mt,isExternalTarget:Ct,addListener:mt,removeListener:ft}),Le=ci.extend({run:function(t,i,e,n){this.stop(),this._el=t,this._inProgress=!0,this._duration=e||.25,this._easeOutPower=1/Math.max(n||.5,.2),this._startPos=ht(t),this._offset=i.subtract(this._startPos),this._startTime=+new Date,this.fire("start"),this._animate()},stop:function(){this._inProgress&&(this._step(!0),this._complete())},_animate:function(){this._animId=f(this._animate,this),this._step()},_step:function(t){var i=+new Date-this._startTime,e=1e3*this._duration;ithis.options.maxZoom)?this.setZoom(t):this},panInsideBounds:function(t,i){this._enforcingBounds=!0;var e=this.getCenter(),n=this._limitCenter(e,this._zoom,z(t));return e.equals(n)||this.panTo(n,i),this._enforcingBounds=!1,this},panInside:function(t,i){var e=w((i=i||{}).paddingTopLeft||i.padding||[0,0]),n=w(i.paddingBottomRight||i.padding||[0,0]),o=this.getCenter(),s=this.project(o),r=this.project(t),a=this.getPixelBounds(),h=a.getSize().divideBy(2),u=b([a.min.add(e),a.max.subtract(n)]);if(!u.contains(r)){this._enforcingBounds=!0;var l=s.subtract(r),c=w(r.x+l.x,r.y+l.y);(r.xu.max.x)&&(c.x=s.x-l.x,l.x>0?c.x+=h.x-e.x:c.x-=h.x-n.x),(r.yu.max.y)&&(c.y=s.y-l.y,l.y>0?c.y+=h.y-e.y:c.y-=h.y-n.y),this.panTo(this.unproject(c),i),this._enforcingBounds=!1}return this},invalidateSize:function(t){if(!this._loaded)return this;t=i({animate:!1,pan:!0},!0===t?{animate:!0}:t);var n=this.getSize();this._sizeChanged=!0,this._lastCenter=null;var o=this.getSize(),s=n.divideBy(2).round(),r=o.divideBy(2).round(),a=s.subtract(r);return a.x||a.y?(t.animate&&t.pan?this.panBy(a):(t.pan&&this._rawPanBy(a),this.fire("move"),t.debounceMoveend?(clearTimeout(this._sizeTimer),this._sizeTimer=setTimeout(e(this.fire,this,"moveend"),200)):this.fire("moveend")),this.fire("resize",{oldSize:n,newSize:o})):this},stop:function(){return this.setZoom(this._limitZoom(this._zoom)),this.options.zoomSnap||this.fire("viewreset"),this._stop()},locate:function(t){if(t=this._locateOptions=i({timeout:1e4,watch:!1},t),!("geolocation"in navigator))return this._handleGeolocationError({code:0,message:"Geolocation not supported."}),this;var n=e(this._handleGeolocationResponse,this),o=e(this._handleGeolocationError,this);return t.watch?this._locationWatchId=navigator.geolocation.watchPosition(n,o,t):navigator.geolocation.getCurrentPosition(n,o,t),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 i=t.code,e=t.message||(1===i?"permission denied":2===i?"position unavailable":"timeout");this._locateOptions.setView&&!this._loaded&&this.fitWorld(),this.fire("locationerror",{code:i,message:"Geolocation error: "+e+"."})},_handleGeolocationResponse:function(t){var i=new M(t.coords.latitude,t.coords.longitude),e=i.toBounds(2*t.coords.accuracy),n=this._locateOptions;if(n.setView){var o=this.getBoundsZoom(e);this.setView(i,n.maxZoom?Math.min(o,n.maxZoom):o)}var s={latlng:i,bounds:e,timestamp:t.timestamp};for(var r in t.coords)"number"==typeof t.coords[r]&&(s[r]=t.coords[r]);this.fire("locationfound",s)},addHandler:function(t,i){if(!i)return this;var e=this[t]=new i(this);return this._handlers.push(e),this.options[t]&&e.enable(),this},remove:function(){if(this._initEvents(!0),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}void 0!==this._locationWatchId&&this.stopLocate(),this._stop(),K(this._mapPane),this._clearControlPos&&this._clearControlPos(),this._resizeRequest&&(g(this._resizeRequest),this._resizeRequest=null),this._clearHandlers(),this._loaded&&this.fire("unload");var t;for(t in this._layers)this._layers[t].remove();for(t in this._panes)K(this._panes[t]);return this._layers=[],this._panes=[],delete this._mapPane,delete this._renderer,this},createPane:function(t,i){var e=G("div","leaflet-pane"+(t?" leaflet-"+t.replace("Pane","")+"-pane":""),i||this._mapPane);return t&&(this._panes[t]=e),e},getCenter:function(){return this._checkIfLoaded(),this._lastCenter&&!this._moved()?this._lastCenter:this.layerPointToLatLng(this._getCenterLayerPoint())},getZoom:function(){return this._zoom},getBounds:function(){var t=this.getPixelBounds();return new T(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,i,e){t=z(t),e=w(e||[0,0]);var n=this.getZoom()||0,o=this.getMinZoom(),s=this.getMaxZoom(),r=t.getNorthWest(),a=t.getSouthEast(),h=this.getSize().subtract(e),u=b(this.project(a,n),this.project(r,n)).getSize(),l=ji?this.options.zoomSnap:1,c=h.x/u.x,_=h.y/u.y,d=i?Math.max(c,_):Math.min(c,_);return n=this.getScaleZoom(d,n),l&&(n=Math.round(n/(l/100))*(l/100),n=i?Math.ceil(n/l)*l:Math.floor(n/l)*l),Math.max(o,Math.min(s,n))},getSize:function(){return this._size&&!this._sizeChanged||(this._size=new x(this._container.clientWidth||0,this._container.clientHeight||0),this._sizeChanged=!1),this._size.clone()},getPixelBounds:function(t,i){var e=this._getTopLeftPoint(t,i);return new P(e,e.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,i){var e=this.options.crs;return i=void 0===i?this._zoom:i,e.scale(t)/e.scale(i)},getScaleZoom:function(t,i){var e=this.options.crs;i=void 0===i?this._zoom:i;var n=e.zoom(t*e.scale(i));return isNaN(n)?1/0:n},project:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.latLngToPoint(C(t),i)},unproject:function(t,i){return i=void 0===i?this._zoom:i,this.options.crs.pointToLatLng(w(t),i)},layerPointToLatLng:function(t){var i=w(t).add(this.getPixelOrigin());return this.unproject(i)},latLngToLayerPoint:function(t){return this.project(C(t))._round()._subtract(this.getPixelOrigin())},wrapLatLng:function(t){return this.options.crs.wrapLatLng(C(t))},wrapLatLngBounds:function(t){return this.options.crs.wrapLatLngBounds(z(t))},distance:function(t,i){return this.options.crs.distance(C(t),C(i))},containerPointToLayerPoint:function(t){return w(t).subtract(this._getMapPanePos())},layerPointToContainerPoint:function(t){return w(t).add(this._getMapPanePos())},containerPointToLatLng:function(t){var i=this.containerPointToLayerPoint(w(t));return this.layerPointToLatLng(i)},latLngToContainerPoint:function(t){return this.layerPointToContainerPoint(this.latLngToLayerPoint(C(t)))},mouseEventToContainerPoint:function(t){return bt(t,this._container)},mouseEventToLayerPoint:function(t){return this.containerPointToLayerPoint(this.mouseEventToContainerPoint(t))},mouseEventToLatLng:function(t){return this.layerPointToLatLng(this.mouseEventToLayerPoint(t))},_initContainer:function(t){var i=this._container=V(t);if(!i)throw new Error("Map container not found.");if(i._leaflet_id)throw new Error("Map container is already initialized.");mt(i,"scroll",this._onScroll,this),this._containerId=n(i)},_initLayout:function(){var t=this._container;this._fadeAnimated=this.options.fadeAnimation&&ji,Q(t,"leaflet-container"+(qi?" leaflet-touch":"")+(Yi?" leaflet-retina":"")+(Li?" leaflet-oldie":"")+(Bi?" leaflet-safari":"")+(this._fadeAnimated?" leaflet-fade-anim":""));var i=q(t,"position");"absolute"!==i&&"relative"!==i&&"fixed"!==i&&(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),at(this._mapPane,new x(0,0)),this.createPane("tilePane"),this.createPane("shadowPane"),this.createPane("overlayPane"),this.createPane("markerPane"),this.createPane("tooltipPane"),this.createPane("popupPane"),this.options.markerZoomAnimation||(Q(t.markerPane,"leaflet-zoom-hide"),Q(t.shadowPane,"leaflet-zoom-hide"))},_resetView:function(t,i){at(this._mapPane,new x(0,0));var e=!this._loaded;this._loaded=!0,i=this._limitZoom(i),this.fire("viewprereset");var n=this._zoom!==i;this._moveStart(n,!1)._move(t,i)._moveEnd(n),this.fire("viewreset"),e&&this.fire("load")},_moveStart:function(t,i){return t&&this.fire("zoomstart"),i||this.fire("movestart"),this},_move:function(t,i,e){void 0===i&&(i=this._zoom);var n=this._zoom!==i;return this._zoom=i,this._lastCenter=t,this._pixelOrigin=this._getNewPixelOrigin(t),(n||e&&e.pinch)&&this.fire("zoom",e),this.fire("move",e)},_moveEnd:function(t){return t&&this.fire("zoomend"),this.fire("moveend")},_stop:function(){return g(this._flyToFrame),this._panAnim&&this._panAnim.stop(),this},_rawPanBy:function(t){at(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={},this._targets[n(this._container)]=this;var i=t?ft:mt;i(this._container,"click dblclick mousedown mouseup mouseover mouseout mousemove contextmenu keypress",this._handleDOMEvent,this),this.options.trackResize&&i(window,"resize",this._onResize,this),ji&&this.options.transform3DLimit&&(t?this.off:this.on).call(this,"moveend",this._onMoveEnd)},_onResize:function(){g(this._resizeRequest),this._resizeRequest=f(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,i){for(var e,o=[],s="mouseout"===i||"mouseover"===i,r=t.target||t.srcElement,a=!1;r;){if((e=this._targets[n(r)])&&("click"===i||"preclick"===i)&&!t._simulated&&this._draggableMoved(e)){a=!0;break}if(e&&e.listens(i,!0)){if(s&&!Ct(r,t))break;if(o.push(e),s)break}if(r===this._container)break;r=r.parentNode}return o.length||a||s||!Ct(r,t)||(o=[this]),o},_handleDOMEvent:function(t){if(this._loaded&&!Mt(t)){var i=t.type;"mousedown"!==i&&"keypress"!==i||ct(t.target||t.srcElement),this._fireDOMEvent(t,i)}},_mouseEvents:["click","dblclick","mouseover","mouseout","contextmenu"],_fireDOMEvent:function(t,e,n){if("click"===t.type){var o=i({},t);o.type="preclick",this._fireDOMEvent(o,o.type,n)}if(!t._stopped&&(n=(n||[]).concat(this._findEventTargets(t,e))).length){var s=n[0];"contextmenu"===e&&s.listens(e,!0)&&Pt(t);var r={originalEvent:t};if("keypress"!==t.type){var a=s.getLatLng&&(!s._radius||s._radius<=10);r.containerPoint=a?this.latLngToContainerPoint(s.getLatLng()):this.mouseEventToContainerPoint(t),r.layerPoint=this.containerPointToLayerPoint(r.containerPoint),r.latlng=a?s.getLatLng():this.layerPointToLatLng(r.layerPoint)}for(var h=0;h0?Math.round(t-i)/2:Math.max(0,Math.ceil(t))-Math.max(0,Math.floor(i))},_limitZoom:function(t){var i=this.getMinZoom(),e=this.getMaxZoom(),n=ji?this.options.zoomSnap:1;return n&&(t=Math.round(t/n)*n),Math.max(i,Math.min(e,t))},_onPanTransitionStep:function(){this.fire("move")},_onPanTransitionEnd:function(){tt(this._mapPane,"leaflet-pan-anim"),this.fire("moveend")},_tryAnimatedPan:function(t,i){var e=this._getCenterOffset(t)._trunc();return!(!0!==(i&&i.animate)&&!this.getSize().contains(e))&&(this.panBy(e,i),!0)},_createAnimProxy:function(){var t=this._proxy=G("div","leaflet-proxy leaflet-zoom-animated");this._panes.mapPane.appendChild(t),this.on("zoomanim",function(t){var i=ce,e=this._proxy.style[i];rt(this._proxy,this.project(t.center,t.zoom),this.getZoomScale(t.zoom,1)),e===this._proxy.style[i]&&this._animatingZoom&&this._onZoomTransitionEnd()},this),this.on("load moveend",function(){var t=this.getCenter(),i=this.getZoom();rt(this._proxy,this.project(t,i),this.getZoomScale(i,1))},this),this._on("unload",this._destroyAnimProxy,this)},_destroyAnimProxy:function(){K(this._proxy),delete this._proxy},_catchTransitionEnd:function(t){this._animatingZoom&&t.propertyName.indexOf("transform")>=0&&this._onZoomTransitionEnd()},_nothingToAnimate:function(){return!this._container.getElementsByClassName("leaflet-zoom-animated").length},_tryAnimatedZoom:function(t,i,e){if(this._animatingZoom)return!0;if(e=e||{},!this._zoomAnimated||!1===e.animate||this._nothingToAnimate()||Math.abs(i-this._zoom)>this.options.zoomAnimationThreshold)return!1;var n=this.getZoomScale(i),o=this._getCenterOffset(t)._divideBy(1-1/n);return!(!0!==e.animate&&!this.getSize().contains(o))&&(f(function(){this._moveStart(!0,!1)._animateZoom(t,i,!0)},this),!0)},_animateZoom:function(t,i,n,o){this._mapPane&&(n&&(this._animatingZoom=!0,this._animateToCenter=t,this._animateToZoom=i,Q(this._mapPane,"leaflet-zoom-anim")),this.fire("zoomanim",{center:t,zoom:i,noUpdate:o}),setTimeout(e(this._onZoomTransitionEnd,this),250))},_onZoomTransitionEnd:function(){this._animatingZoom&&(this._mapPane&&tt(this._mapPane,"leaflet-zoom-anim"),this._animatingZoom=!1,this._move(this._animateToCenter,this._animateToZoom),f(function(){this._moveEnd(!0)},this))}}),Te=v.extend({options:{position:"topright"},initialize:function(t){l(this,t)},getPosition:function(){return this.options.position},setPosition:function(t){var i=this._map;return i&&i.removeControl(this),this.options.position=t,i&&i.addControl(this),this},getContainer:function(){return this._container},addTo:function(t){this.remove(),this._map=t;var i=this._container=this.onAdd(t),e=this.getPosition(),n=t._controlCorners[e];return Q(i,"leaflet-control"),-1!==e.indexOf("bottom")?n.insertBefore(i,n.firstChild):n.appendChild(i),this},remove:function(){return this._map?(K(this._container),this.onRemove&&this.onRemove(this._map),this._map=null,this):this},_refocusOnMap:function(t){this._map&&t&&t.screenX>0&&t.screenY>0&&this._map.getContainer().focus()}}),ze=function(t){return new Te(t)};be.include({addControl:function(t){return t.addTo(this),this},removeControl:function(t){return t.remove(),this},_initControlPos:function(){function t(t,o){var s=e+t+" "+e+o;i[t+o]=G("div",s,n)}var i=this._controlCorners={},e="leaflet-",n=this._controlContainer=G("div",e+"control-container",this._container);t("top","left"),t("top","right"),t("bottom","left"),t("bottom","right")},_clearControlPos:function(){for(var t in this._controlCorners)K(this._controlCorners[t]);K(this._controlContainer),delete this._controlCorners,delete this._controlContainer}});var Me=Te.extend({options:{collapsed:!0,position:"topright",autoZIndex:!0,hideSingleBase:!1,sortLayers:!1,sortFunction:function(t,i,e,n){return e1,this._baseLayersList.style.display=t?"":"none"),this._separator.style.display=i&&t?"":"none",this},_onLayerChange:function(t){this._handlingClick||this._update();var i=this._getLayer(n(t.target)),e=i.overlay?"add"===t.type?"overlayadd":"overlayremove":"add"===t.type?"baselayerchange":null;e&&this._map.fire(e,i)},_createRadioElement:function(t,i){var e='",n=document.createElement("div");return n.innerHTML=e,n.firstChild},_addItem:function(t){var i,e=document.createElement("label"),o=this._map.hasLayer(t.layer);t.overlay?((i=document.createElement("input")).type="checkbox",i.className="leaflet-control-layers-selector",i.defaultChecked=o):i=this._createRadioElement("leaflet-base-layers",o),this._layerControlInputs.push(i),i.layerId=n(t.layer),mt(i,"click",this._onInputClick,this);var s=document.createElement("span");s.innerHTML=" "+t.name;var r=document.createElement("div");return e.appendChild(r),r.appendChild(i),r.appendChild(s),(t.overlay?this._overlaysList:this._baseLayersList).appendChild(e),this._checkDisabledLayers(),e},_onInputClick:function(){var t,i,e=this._layerControlInputs,n=[],o=[];this._handlingClick=!0;for(var s=e.length-1;s>=0;s--)t=e[s],i=this._getLayer(t.layerId).layer,t.checked?n.push(i):t.checked||o.push(i);for(s=0;s=0;o--)t=e[o],i=this._getLayer(t.layerId).layer,t.disabled=void 0!==i.options.minZoom&&ni.options.maxZoom},_expandIfNotCollapsed:function(){return this._map&&!this.options.collapsed&&this.expand(),this},_expand:function(){return this.expand()},_collapse:function(){return this.collapse()}}),Ce=Te.extend({options:{position:"topleft",zoomInText:"+",zoomInTitle:"Zoom in",zoomOutText:"−",zoomOutTitle:"Zoom out"},onAdd:function(t){var i="leaflet-control-zoom",e=G("div",i+" leaflet-bar"),n=this.options;return this._zoomInButton=this._createButton(n.zoomInText,n.zoomInTitle,i+"-in",e,this._zoomIn),this._zoomOutButton=this._createButton(n.zoomOutText,n.zoomOutTitle,i+"-out",e,this._zoomOut),this._updateDisabled(),t.on("zoomend zoomlevelschange",this._updateDisabled,this),e},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,i,e,n,o){var s=G("a",e,n);return s.innerHTML=t,s.href="#",s.title=i,s.setAttribute("role","button"),s.setAttribute("aria-label",i),wt(s),mt(s,"click",Lt),mt(s,"click",o,this),mt(s,"click",this._refocusOnMap,this),s},_updateDisabled:function(){var t=this._map,i="leaflet-disabled";tt(this._zoomInButton,i),tt(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMinZoom())&&Q(this._zoomOutButton,i),(this._disabled||t._zoom===t.getMaxZoom())&&Q(this._zoomInButton,i)}});be.mergeOptions({zoomControl:!0}),be.addInitHook(function(){this.options.zoomControl&&(this.zoomControl=new Ce,this.addControl(this.zoomControl))});var Se=Te.extend({options:{position:"bottomleft",maxWidth:100,metric:!0,imperial:!0},onAdd:function(t){var i=G("div","leaflet-control-scale"),e=this.options;return this._addScales(e,"leaflet-control-scale-line",i),t.on(e.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,i,e){t.metric&&(this._mScale=G("div",i,e)),t.imperial&&(this._iScale=G("div",i,e))},_update:function(){var t=this._map,i=t.getSize().y/2,e=t.distance(t.containerPointToLatLng([0,i]),t.containerPointToLatLng([this.options.maxWidth,i]));this._updateScales(e)},_updateScales:function(t){this.options.metric&&t&&this._updateMetric(t),this.options.imperial&&t&&this._updateImperial(t)},_updateMetric:function(t){var i=this._getRoundNum(t),e=i<1e3?i+" m":i/1e3+" km";this._updateScale(this._mScale,e,i/t)},_updateImperial:function(t){var i,e,n,o=3.2808399*t;o>5280?(i=o/5280,e=this._getRoundNum(i),this._updateScale(this._iScale,e+" mi",e/i)):(n=this._getRoundNum(o),this._updateScale(this._iScale,n+" ft",n/o))},_updateScale:function(t,i,e){t.style.width=Math.round(this.options.maxWidth*e)+"px",t.innerHTML=i},_getRoundNum:function(t){var i=Math.pow(10,(Math.floor(t)+"").length-1),e=t/i;return e=e>=10?10:e>=5?5:e>=3?3:e>=2?2:1,i*e}}),Ze=Te.extend({options:{position:"bottomright",prefix:'Leaflet'},initialize:function(t){l(this,t),this._attributions={}},onAdd:function(t){t.attributionControl=this,this._container=G("div","leaflet-control-attribution"),wt(this._container);for(var i in t._layers)t._layers[i].getAttribution&&this.addAttribution(t._layers[i].getAttribution());return this._update(),this._container},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):this},removeAttribution:function(t){return t?(this._attributions[t]&&(this._attributions[t]--,this._update()),this):this},_update:function(){if(this._map){var t=[];for(var i in this._attributions)this._attributions[i]&&t.push(i);var e=[];this.options.prefix&&e.push(this.options.prefix),t.length&&e.push(t.join(", ")),this._container.innerHTML=e.join(" | ")}}});be.mergeOptions({attributionControl:!0}),be.addInitHook(function(){this.options.attributionControl&&(new Ze).addTo(this)});Te.Layers=Me,Te.Zoom=Ce,Te.Scale=Se,Te.Attribution=Ze,ze.layers=function(t,i,e){return new Me(t,i,e)},ze.zoom=function(t){return new Ce(t)},ze.scale=function(t){return new Se(t)},ze.attribution=function(t){return new Ze(t)};var Ee=v.extend({initialize:function(t){this._map=t},enable:function(){return this._enabled?this:(this._enabled=!0,this.addHooks(),this)},disable:function(){return this._enabled?(this._enabled=!1,this.removeHooks(),this):this},enabled:function(){return!!this._enabled}});Ee.addTo=function(t,i){return t.addHandler(i,this),this};var ke,Be={Events:li},Ae=qi?"touchstart mousedown":"mousedown",Ie={mousedown:"mouseup",touchstart:"touchend",pointerdown:"touchend",MSPointerDown:"touchend"},Oe={mousedown:"mousemove",touchstart:"touchmove",pointerdown:"touchmove",MSPointerDown:"touchmove"},Re=ci.extend({options:{clickTolerance:3},initialize:function(t,i,e,n){l(this,n),this._element=t,this._dragStartTarget=i||t,this._preventOutline=e},enable:function(){this._enabled||(mt(this._dragStartTarget,Ae,this._onDown,this),this._enabled=!0)},disable:function(){this._enabled&&(Re._dragging===this&&this.finishDrag(),ft(this._dragStartTarget,Ae,this._onDown,this),this._enabled=!1,this._moved=!1)},_onDown:function(t){if(!t._simulated&&this._enabled&&(this._moved=!1,!$(this._element,"leaflet-zoom-anim")&&!(Re._dragging||t.shiftKey||1!==t.which&&1!==t.button&&!t.touches||(Re._dragging=this,this._preventOutline&&ct(this._element),ut(),fi(),this._moving)))){this.fire("down");var i=t.touches?t.touches[0]:t,e=dt(this._element);this._startPoint=new x(i.clientX,i.clientY),this._parentScale=pt(e),mt(document,Oe[t.type],this._onMove,this),mt(document,Ie[t.type],this._onUp,this)}},_onMove:function(t){if(!t._simulated&&this._enabled)if(t.touches&&t.touches.length>1)this._moved=!0;else{var i=t.touches&&1===t.touches.length?t.touches[0]:t,e=new x(i.clientX,i.clientY)._subtract(this._startPoint);(e.x||e.y)&&(Math.abs(e.x)+Math.abs(e.y)1e-7;h++)i=s*Math.sin(a),i=Math.pow((1-i)/(1+i),s/2),a+=u=Math.PI/2-2*Math.atan(r*i)-a;return new M(a*e,t.x*e/n)}},He=(Object.freeze||Object)({LonLat:je,Mercator:We,SphericalMercator:mi}),Fe=i({},pi,{code:"EPSG:3395",projection:We,transformation:function(){var t=.5/(Math.PI*We.R);return Z(t,.5,-t,.5)}()}),Ue=i({},pi,{code:"EPSG:4326",projection:je,transformation:Z(1/180,1,-1/180,.5)}),Ve=i({},di,{projection:je,transformation:Z(1,0,-1,0),scale:function(t){return Math.pow(2,t)},zoom:function(t){return Math.log(t)/Math.LN2},distance:function(t,i){var e=i.lng-t.lng,n=i.lat-t.lat;return Math.sqrt(e*e+n*n)},infinite:!0});di.Earth=pi,di.EPSG3395=Fe,di.EPSG3857=yi,di.EPSG900913=xi,di.EPSG4326=Ue,di.Simple=Ve;var qe=ci.extend({options:{pane:"overlayPane",attribution:null,bubblingMouseEvents:!0},addTo:function(t){return t.addLayer(this),this},remove:function(){return this.removeFrom(this._map||this._mapToAdd)},removeFrom:function(t){return t&&t.removeLayer(this),this},getPane:function(t){return this._map.getPane(t?this.options[t]||t:this.options.pane)},addInteractiveTarget:function(t){return this._map._targets[n(t)]=this,this},removeInteractiveTarget:function(t){return delete this._map._targets[n(t)],this},getAttribution:function(){return this.options.attribution},_layerAdd:function(t){var i=t.target;if(i.hasLayer(this)){if(this._map=i,this._zoomAnimated=i._zoomAnimated,this.getEvents){var e=this.getEvents();i.on(e,this),this.once("remove",function(){i.off(e,this)},this)}this.onAdd(i),this.getAttribution&&i.attributionControl&&i.attributionControl.addAttribution(this.getAttribution()),this.fire("add"),i.fire("layeradd",{layer:this})}}});be.include({addLayer:function(t){if(!t._layerAdd)throw new Error("The provided object is not a Layer.");var i=n(t);return this._layers[i]?this:(this._layers[i]=t,t._mapToAdd=this,t.beforeAdd&&t.beforeAdd(this),this.whenReady(t._layerAdd,t),this)},removeLayer:function(t){var i=n(t);return this._layers[i]?(this._loaded&&t.onRemove(this),t.getAttribution&&this.attributionControl&&this.attributionControl.removeAttribution(t.getAttribution()),delete this._layers[i],this._loaded&&(this.fire("layerremove",{layer:t}),t.fire("remove")),t._map=t._mapToAdd=null,this):this},hasLayer:function(t){return!!t&&n(t)in this._layers},eachLayer:function(t,i){for(var e in this._layers)t.call(i,this._layers[e]);return this},_addLayers:function(t){for(var i=0,e=(t=t?oi(t)?t:[t]:[]).length;ithis._layersMaxZoom&&this.setZoom(this._layersMaxZoom),void 0===this.options.minZoom&&this._layersMinZoom&&this.getZoom()i)return r=(n-i)/e,this._map.layerPointToLatLng([s.x-r*(s.x-o.x),s.y-r*(s.y-o.y)])},getBounds:function(){return this._bounds},addLatLng:function(t,i){return i=i||this._defaultShape(),t=C(t),i.push(t),this._bounds.extend(t),this.redraw()},_setLatLngs:function(t){this._bounds=new T,this._latlngs=this._convertLatLngs(t)},_defaultShape:function(){return jt(this._latlngs)?this._latlngs:this._latlngs[0]},_convertLatLngs:function(t){for(var i=[],e=jt(t),n=0,o=t.length;n=2&&i[0]instanceof M&&i[0].equals(i[e-1])&&i.pop(),i},_setLatLngs:function(t){nn.prototype._setLatLngs.call(this,t),jt(this._latlngs)&&(this._latlngs=[this._latlngs])},_defaultShape:function(){return jt(this._latlngs[0])?this._latlngs[0]:this._latlngs[0][0]},_clipPoints:function(){var t=this._renderer._bounds,i=this.options.weight,e=new x(i,i);if(t=new P(t.min.subtract(e),t.max.add(e)),this._parts=[],this._pxBounds&&this._pxBounds.intersects(t))if(this.options.noClip)this._parts=this._rings;else for(var n,o=0,s=this._rings.length;ot.y!=n.y>t.y&&t.x<(n.x-e.x)*(t.y-e.y)/(n.y-e.y)+e.x&&(u=!u);return u||nn.prototype._containsPoint.call(this,t,!0)}}),sn=Ke.extend({initialize:function(t,i){l(this,i),this._layers={},t&&this.addData(t)},addData:function(t){var i,e,n,o=oi(t)?t:t.features;if(o){for(i=0,e=o.length;i0?o:[i.src]}else{oi(this._url)||(this._url=[this._url]),i.autoplay=!!this.options.autoplay,i.loop=!!this.options.loop;for(var a=0;ao?(i.height=o+"px",Q(t,"leaflet-popup-scrolled")):tt(t,"leaflet-popup-scrolled"),this._containerWidth=this._container.offsetWidth},_animateZoom:function(t){var i=this._map._latLngToNewLayerPoint(this._latlng,t.zoom,t.center),e=this._getAnchor();at(this._container,i.add(e))},_adjustPan:function(){if(this.options.autoPan){this._map._panAnim&&this._map._panAnim.stop();var t=this._map,i=parseInt(q(this._container,"marginBottom"),10)||0,e=this._container.offsetHeight+i,n=this._containerWidth,o=new x(this._containerLeft,-e-this._containerBottom);o._add(ht(this._container));var s=t.layerPointToContainerPoint(o),r=w(this.options.autoPanPadding),a=w(this.options.autoPanPaddingTopLeft||r),h=w(this.options.autoPanPaddingBottomRight||r),u=t.getSize(),l=0,c=0;s.x+n+h.x>u.x&&(l=s.x+n-u.x+h.x),s.x-l-a.x<0&&(l=s.x-a.x),s.y+e+h.y>u.y&&(c=s.y+e-u.y+h.y),s.y-c-a.y<0&&(c=s.y-a.y),(l||c)&&t.fire("autopanstart").panBy([l,c])}},_onCloseButtonClick:function(t){this._close(),Lt(t)},_getAnchor:function(){return w(this._source&&this._source._getPopupAnchor?this._source._getPopupAnchor():[0,0])}});be.mergeOptions({closePopupOnClick:!0}),be.include({openPopup:function(t,i,e){return t instanceof cn||(t=new cn(e).setContent(t)),i&&t.setLatLng(i),this.hasLayer(t)?this:(this._popup&&this._popup.options.autoClose&&this.closePopup(),this._popup=t,this.addLayer(t))},closePopup:function(t){return t&&t!==this._popup||(t=this._popup,this._popup=null),t&&this.removeLayer(t),this}}),qe.include({bindPopup:function(t,i){return t instanceof cn?(l(t,i),this._popup=t,t._source=this):(this._popup&&!i||(this._popup=new cn(i,this)),this._popup.setContent(t)),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,i){if(t instanceof qe||(i=t,t=this),t instanceof Ke)for(var e in this._layers){t=this._layers[e];break}return i||(i=t.getCenter?t.getCenter():t.getLatLng()),this._popup&&this._map&&(this._popup._source=t,this._popup.update(),this._map.openPopup(this._popup,i)),this},closePopup:function(){return this._popup&&this._popup._close(),this},togglePopup:function(t){return this._popup&&(this._popup._map?this.closePopup():this.openPopup(t)),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 i=t.layer||t.target;this._popup&&this._map&&(Lt(t),i instanceof Qe?this.openPopup(t.layer||t.target,t.latlng):this._map.hasLayer(this._popup)&&this._popup._source===i?this.closePopup():this.openPopup(i,t.latlng))},_movePopup:function(t){this._popup.setLatLng(t.latlng)},_onKeyPress:function(t){13===t.originalEvent.keyCode&&this._openPopup(t)}});var _n=ln.extend({options:{pane:"tooltipPane",offset:[0,0],direction:"auto",permanent:!1,sticky:!1,interactive:!1,opacity:.9},onAdd:function(t){ln.prototype.onAdd.call(this,t),this.setOpacity(this.options.opacity),t.fire("tooltipopen",{tooltip:this}),this._source&&this._source.fire("tooltipopen",{tooltip:this},!0)},onRemove:function(t){ln.prototype.onRemove.call(this,t),t.fire("tooltipclose",{tooltip:this}),this._source&&this._source.fire("tooltipclose",{tooltip:this},!0)},getEvents:function(){var t=ln.prototype.getEvents.call(this);return qi&&!this.options.permanent&&(t.preclick=this._close),t},_close:function(){this._map&&this._map.closeTooltip(this)},_initLayout:function(){var t="leaflet-tooltip "+(this.options.className||"")+" leaflet-zoom-"+(this._zoomAnimated?"animated":"hide");this._contentNode=this._container=G("div",t)},_updateLayout:function(){},_adjustPan:function(){},_setPosition:function(t){var i=this._map,e=this._container,n=i.latLngToContainerPoint(i.getCenter()),o=i.layerPointToContainerPoint(t),s=this.options.direction,r=e.offsetWidth,a=e.offsetHeight,h=w(this.options.offset),u=this._getAnchor();"top"===s?t=t.add(w(-r/2+h.x,-a+h.y+u.y,!0)):"bottom"===s?t=t.subtract(w(r/2-h.x,-h.y,!0)):"center"===s?t=t.subtract(w(r/2+h.x,a/2-u.y+h.y,!0)):"right"===s||"auto"===s&&o.xthis.options.maxZoom||en&&this._retainParent(o,s,r,n))},_retainChildren:function(t,i,e,n){for(var o=2*t;o<2*t+2;o++)for(var s=2*i;s<2*i+2;s++){var r=new x(o,s);r.z=e+1;var a=this._tileCoordsToKey(r),h=this._tiles[a];h&&h.active?h.retain=!0:(h&&h.loaded&&(h.retain=!0),e+1this.options.maxZoom||void 0!==this.options.minZoom&&o1)this._setView(t,e);else{for(var c=o.min.y;c<=o.max.y;c++)for(var _=o.min.x;_<=o.max.x;_++){var d=new x(_,c);if(d.z=this._tileZoom,this._isValidTile(d)){var p=this._tiles[this._tileCoordsToKey(d)];p?p.current=!0:r.push(d)}}if(r.sort(function(t,i){return t.distanceTo(s)-i.distanceTo(s)}),0!==r.length){this._loading||(this._loading=!0,this.fire("loading"));var m=document.createDocumentFragment();for(_=0;_e.max.x)||!i.wrapLat&&(t.ye.max.y))return!1}if(!this.options.bounds)return!0;var n=this._tileCoordsToBounds(t);return z(this.options.bounds).overlaps(n)},_keyToBounds:function(t){return this._tileCoordsToBounds(this._keyToTileCoords(t))},_tileCoordsToNwSe:function(t){var i=this._map,e=this.getTileSize(),n=t.scaleBy(e),o=n.add(e);return[i.unproject(n,t.z),i.unproject(o,t.z)]},_tileCoordsToBounds:function(t){var i=this._tileCoordsToNwSe(t),e=new T(i[0],i[1]);return this.options.noWrap||(e=this._map.wrapLatLngBounds(e)),e},_tileCoordsToKey:function(t){return t.x+":"+t.y+":"+t.z},_keyToTileCoords:function(t){var i=t.split(":"),e=new x(+i[0],+i[1]);return e.z=+i[2],e},_removeTile:function(t){var i=this._tiles[t];i&&(K(i.el),delete this._tiles[t],this.fire("tileunload",{tile:i.el,coords:this._keyToTileCoords(t)}))},_initTile:function(t){Q(t,"leaflet-tile");var i=this.getTileSize();t.style.width=i.x+"px",t.style.height=i.y+"px",t.onselectstart=r,t.onmousemove=r,Li&&this.options.opacity<1&&nt(t,this.options.opacity),zi&&!Mi&&(t.style.WebkitBackfaceVisibility="hidden")},_addTile:function(t,i){var n=this._getTilePos(t),o=this._tileCoordsToKey(t),s=this.createTile(this._wrapCoords(t),e(this._tileReady,this,t));this._initTile(s),this.createTile.length<2&&f(e(this._tileReady,this,t,null,s)),at(s,n),this._tiles[o]={el:s,coords:t,current:!0},i.appendChild(s),this.fire("tileloadstart",{tile:s,coords:t})},_tileReady:function(t,i,n){i&&this.fire("tileerror",{error:i,tile:n,coords:t});var o=this._tileCoordsToKey(t);(n=this._tiles[o])&&(n.loaded=+new Date,this._map._fadeAnimated?(nt(n.el,0),g(this._fadeFrame),this._fadeFrame=f(this._updateOpacity,this)):(n.active=!0,this._pruneTiles()),i||(Q(n.el,"leaflet-tile-loaded"),this.fire("tileload",{tile:n.el,coords:t})),this._noTilesToLoad()&&(this._loading=!1,this.fire("load"),Li||!this._map._fadeAnimated?f(this._pruneTiles,this):setTimeout(e(this._pruneTiles,this),250)))},_getTilePos:function(t){return t.scaleBy(this.getTileSize()).subtract(this._level.origin)},_wrapCoords:function(t){var i=new x(this._wrapX?s(t.x,this._wrapX):t.x,this._wrapY?s(t.y,this._wrapY):t.y);return i.z=t.z,i},_pxBoundsToTileRange:function(t){var i=this.getTileSize();return new P(t.min.unscaleBy(i).floor(),t.max.unscaleBy(i).ceil().subtract([1,1]))},_noTilesToLoad:function(){for(var t in this._tiles)if(!this._tiles[t].loaded)return!1;return!0}}),mn=pn.extend({options:{minZoom:0,maxZoom:18,subdomains:"abc",errorTileUrl:"",zoomOffset:0,tms:!1,zoomReverse:!1,detectRetina:!1,crossOrigin:!1},initialize:function(t,i){this._url=t,(i=l(this,i)).detectRetina&&Yi&&i.maxZoom>0&&(i.tileSize=Math.floor(i.tileSize/2),i.zoomReverse?(i.zoomOffset--,i.minZoom++):(i.zoomOffset++,i.maxZoom--),i.minZoom=Math.max(0,i.minZoom)),"string"==typeof i.subdomains&&(i.subdomains=i.subdomains.split("")),zi||this.on("tileunload",this._onTileRemove)},setUrl:function(t,i){return this._url===t&&void 0===i&&(i=!0),this._url=t,i||this.redraw(),this},createTile:function(t,i){var n=document.createElement("img");return mt(n,"load",e(this._tileOnLoad,this,i,n)),mt(n,"error",e(this._tileOnError,this,i,n)),(this.options.crossOrigin||""===this.options.crossOrigin)&&(n.crossOrigin=!0===this.options.crossOrigin?"":this.options.crossOrigin),n.alt="",n.setAttribute("role","presentation"),n.src=this.getTileUrl(t),n},getTileUrl:function(t){var e={r:Yi?"@2x":"",s:this._getSubdomain(t),x:t.x,y:t.y,z:this._getZoomForUrl()};if(this._map&&!this._map.options.crs.infinite){var n=this._globalTileRange.max.y-t.y;this.options.tms&&(e.y=n),e["-y"]=n}return _(this._url,i(e,this.options))},_tileOnLoad:function(t,i){Li?setTimeout(e(t,this,null,i),0):t(null,i)},_tileOnError:function(t,i,e){var n=this.options.errorTileUrl;n&&i.getAttribute("src")!==n&&(i.src=n),t(e,i)},_onTileRemove:function(t){t.tile.onload=null},_getZoomForUrl:function(){var t=this._tileZoom,i=this.options.maxZoom,e=this.options.zoomReverse,n=this.options.zoomOffset;return e&&(t=i-t),t+n},_getSubdomain:function(t){var i=Math.abs(t.x+t.y)%this.options.subdomains.length;return this.options.subdomains[i]},_abortLoading:function(){var t,i;for(t in this._tiles)this._tiles[t].coords.z!==this._tileZoom&&((i=this._tiles[t].el).onload=r,i.onerror=r,i.complete||(i.src=si,K(i),delete this._tiles[t]))},_removeTile:function(t){var i=this._tiles[t];if(i)return Si||i.el.setAttribute("src",si),pn.prototype._removeTile.call(this,t)},_tileReady:function(t,i,e){if(this._map&&(!e||e.getAttribute("src")!==si))return pn.prototype._tileReady.call(this,t,i,e)}}),fn=mn.extend({defaultWmsParams:{service:"WMS",request:"GetMap",layers:"",styles:"",format:"image/jpeg",transparent:!1,version:"1.1.1"},options:{crs:null,uppercase:!1},initialize:function(t,e){this._url=t;var n=i({},this.defaultWmsParams);for(var o in e)o in this.options||(n[o]=e[o]);var s=(e=l(this,e)).detectRetina&&Yi?2:1,r=this.getTileSize();n.width=r.x*s,n.height=r.y*s,this.wmsParams=n},onAdd:function(t){this._crs=this.options.crs||t.options.crs,this._wmsVersion=parseFloat(this.wmsParams.version);var i=this._wmsVersion>=1.3?"crs":"srs";this.wmsParams[i]=this._crs.code,mn.prototype.onAdd.call(this,t)},getTileUrl:function(t){var i=this._tileCoordsToNwSe(t),e=this._crs,n=b(e.project(i[0]),e.project(i[1])),o=n.min,s=n.max,r=(this._wmsVersion>=1.3&&this._crs===Ue?[o.y,o.x,s.y,s.x]:[o.x,o.y,s.x,s.y]).join(","),a=mn.prototype.getTileUrl.call(this,t);return a+c(this.wmsParams,a,this.options.uppercase)+(this.options.uppercase?"&BBOX=":"&bbox=")+r},setParams:function(t,e){return i(this.wmsParams,t),e||this.redraw(),this}});mn.WMS=fn,Jt.wms=function(t,i){return new fn(t,i)};var gn=qe.extend({options:{padding:.1,tolerance:0},initialize:function(t){l(this,t),n(this),this._layers=this._layers||{}},onAdd:function(){this._container||(this._initContainer(),this._zoomAnimated&&Q(this._container,"leaflet-zoom-animated")),this.getPane().appendChild(this._container),this._update(),this.on("update",this._updatePaths,this)},onRemove:function(){this.off("update",this._updatePaths,this),this._destroyContainer()},getEvents:function(){var t={viewreset:this._reset,zoom:this._onZoom,moveend:this._update,zoomend:this._onZoomEnd};return this._zoomAnimated&&(t.zoomanim=this._onAnimZoom),t},_onAnimZoom:function(t){this._updateTransform(t.center,t.zoom)},_onZoom:function(){this._updateTransform(this._map.getCenter(),this._map.getZoom())},_updateTransform:function(t,i){var e=this._map.getZoomScale(i,this._zoom),n=ht(this._container),o=this._map.getSize().multiplyBy(.5+this.options.padding),s=this._map.project(this._center,i),r=this._map.project(t,i).subtract(s),a=o.multiplyBy(-e).add(n).add(o).subtract(r);ji?rt(this._container,a,e):at(this._container,a)},_reset:function(){this._update(),this._updateTransform(this._center,this._zoom);for(var t in this._layers)this._layers[t]._reset()},_onZoomEnd:function(){for(var t in this._layers)this._layers[t]._project()},_updatePaths:function(){for(var t in this._layers)this._layers[t]._update()},_update:function(){var t=this.options.padding,i=this._map.getSize(),e=this._map.containerPointToLayerPoint(i.multiplyBy(-t)).round();this._bounds=new P(e,e.add(i.multiplyBy(1+2*t)).round()),this._center=this._map.getCenter(),this._zoom=this._map.getZoom()}}),vn=gn.extend({getEvents:function(){var t=gn.prototype.getEvents.call(this);return t.viewprereset=this._onViewPreReset,t},_onViewPreReset:function(){this._postponeUpdatePaths=!0},onAdd:function(){gn.prototype.onAdd.call(this),this._draw()},_initContainer:function(){var t=this._container=document.createElement("canvas");mt(t,"mousemove",o(this._onMouseMove,32,this),this),mt(t,"click dblclick mousedown mouseup contextmenu",this._onClick,this),mt(t,"mouseout",this._handleMouseOut,this),this._ctx=t.getContext("2d")},_destroyContainer:function(){g(this._redrawRequest),delete this._ctx,K(this._container),ft(this._container),delete this._container},_updatePaths:function(){if(!this._postponeUpdatePaths){this._redrawBounds=null;for(var t in this._layers)this._layers[t]._update();this._redraw()}},_update:function(){if(!this._map._animatingZoom||!this._bounds){gn.prototype._update.call(this);var t=this._bounds,i=this._container,e=t.getSize(),n=Yi?2:1;at(i,t.min),i.width=n*e.x,i.height=n*e.y,i.style.width=e.x+"px",i.style.height=e.y+"px",Yi&&this._ctx.scale(2,2),this._ctx.translate(-t.min.x,-t.min.y),this.fire("update")}},_reset:function(){gn.prototype._reset.call(this),this._postponeUpdatePaths&&(this._postponeUpdatePaths=!1,this._updatePaths())},_initPath:function(t){this._updateDashArray(t),this._layers[n(t)]=t;var i=t._order={layer:t,prev:this._drawLast,next:null};this._drawLast&&(this._drawLast.next=i),this._drawLast=i,this._drawFirst=this._drawFirst||this._drawLast},_addPath:function(t){this._requestRedraw(t)},_removePath:function(t){var i=t._order,e=i.next,o=i.prev;e?e.prev=o:this._drawLast=o,o?o.next=e:this._drawFirst=e,delete t._order,delete this._layers[n(t)],this._requestRedraw(t)},_updatePath:function(t){this._extendRedrawBounds(t),t._project(),t._update(),this._requestRedraw(t)},_updateStyle:function(t){this._updateDashArray(t),this._requestRedraw(t)},_updateDashArray:function(t){if("string"==typeof t.options.dashArray){var i,e,n=t.options.dashArray.split(/[, ]+/),o=[];for(e=0;e')}}catch(t){return function(t){return document.createElement("<"+t+' xmlns="urn:schemas-microsoft.com:vml" class="lvml">')}}}(),xn={_initContainer:function(){this._container=G("div","leaflet-vml-container")},_update:function(){this._map._animatingZoom||(gn.prototype._update.call(this),this.fire("update"))},_initPath:function(t){var i=t._container=yn("shape");Q(i,"leaflet-vml-shape "+(this.options.className||"")),i.coordsize="1 1",t._path=yn("path"),i.appendChild(t._path),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){var i=t._container;this._container.appendChild(i),t.options.interactive&&t.addInteractiveTarget(i)},_removePath:function(t){var i=t._container;K(i),t.removeInteractiveTarget(i),delete this._layers[n(t)]},_updateStyle:function(t){var i=t._stroke,e=t._fill,n=t.options,o=t._container;o.stroked=!!n.stroke,o.filled=!!n.fill,n.stroke?(i||(i=t._stroke=yn("stroke")),o.appendChild(i),i.weight=n.weight+"px",i.color=n.color,i.opacity=n.opacity,n.dashArray?i.dashStyle=oi(n.dashArray)?n.dashArray.join(" "):n.dashArray.replace(/( *, *)/g," "):i.dashStyle="",i.endcap=n.lineCap.replace("butt","flat"),i.joinstyle=n.lineJoin):i&&(o.removeChild(i),t._stroke=null),n.fill?(e||(e=t._fill=yn("fill")),o.appendChild(e),e.color=n.fillColor||n.color,e.opacity=n.fillOpacity):e&&(o.removeChild(e),t._fill=null)},_updateCircle:function(t){var i=t._point.round(),e=Math.round(t._radius),n=Math.round(t._radiusY||e);this._setPath(t,t._empty()?"M0 0":"AL "+i.x+","+i.y+" "+e+","+n+" 0,23592600")},_setPath:function(t,i){t._path.v=i},_bringToFront:function(t){X(t._container)},_bringToBack:function(t){J(t._container)}},wn=$i?yn:E,Pn=gn.extend({getEvents:function(){var t=gn.prototype.getEvents.call(this);return t.zoomstart=this._onZoomStart,t},_initContainer:function(){this._container=wn("svg"),this._container.setAttribute("pointer-events","none"),this._rootGroup=wn("g"),this._container.appendChild(this._rootGroup)},_destroyContainer:function(){K(this._container),ft(this._container),delete this._container,delete this._rootGroup,delete this._svgSize},_onZoomStart:function(){this._update()},_update:function(){if(!this._map._animatingZoom||!this._bounds){gn.prototype._update.call(this);var t=this._bounds,i=t.getSize(),e=this._container;this._svgSize&&this._svgSize.equals(i)||(this._svgSize=i,e.setAttribute("width",i.x),e.setAttribute("height",i.y)),at(e,t.min),e.setAttribute("viewBox",[t.min.x,t.min.y,i.x,i.y].join(" ")),this.fire("update")}},_initPath:function(t){var i=t._path=wn("path");t.options.className&&Q(i,t.options.className),t.options.interactive&&Q(i,"leaflet-interactive"),this._updateStyle(t),this._layers[n(t)]=t},_addPath:function(t){this._rootGroup||this._initContainer(),this._rootGroup.appendChild(t._path),t.addInteractiveTarget(t._path)},_removePath:function(t){K(t._path),t.removeInteractiveTarget(t._path),delete this._layers[n(t)]},_updatePath:function(t){t._project(),t._update()},_updateStyle:function(t){var i=t._path,e=t.options;i&&(e.stroke?(i.setAttribute("stroke",e.color),i.setAttribute("stroke-opacity",e.opacity),i.setAttribute("stroke-width",e.weight),i.setAttribute("stroke-linecap",e.lineCap),i.setAttribute("stroke-linejoin",e.lineJoin),e.dashArray?i.setAttribute("stroke-dasharray",e.dashArray):i.removeAttribute("stroke-dasharray"),e.dashOffset?i.setAttribute("stroke-dashoffset",e.dashOffset):i.removeAttribute("stroke-dashoffset")):i.setAttribute("stroke","none"),e.fill?(i.setAttribute("fill",e.fillColor||e.color),i.setAttribute("fill-opacity",e.fillOpacity),i.setAttribute("fill-rule",e.fillRule||"evenodd")):i.setAttribute("fill","none"))},_updatePoly:function(t,i){this._setPath(t,k(t._parts,i))},_updateCircle:function(t){var i=t._point,e=Math.max(Math.round(t._radius),1),n="a"+e+","+(Math.max(Math.round(t._radiusY),1)||e)+" 0 1,0 ",o=t._empty()?"M0 0":"M"+(i.x-e)+","+i.y+n+2*e+",0 "+n+2*-e+",0 ";this._setPath(t,o)},_setPath:function(t,i){t._path.setAttribute("d",i)},_bringToFront:function(t){X(t._path)},_bringToBack:function(t){J(t._path)}});$i&&Pn.include(xn),be.include({getRenderer:function(t){var i=t.options.renderer||this._getPaneRenderer(t.options.pane)||this.options.renderer||this._renderer;return i||(i=this._renderer=this._createRenderer()),this.hasLayer(i)||this.addLayer(i),i},_getPaneRenderer:function(t){if("overlayPane"===t||void 0===t)return!1;var i=this._paneRenderers[t];return void 0===i&&(i=this._createRenderer({pane:t}),this._paneRenderers[t]=i),i},_createRenderer:function(t){return this.options.preferCanvas&&$t(t)||Qt(t)}});var Ln=on.extend({initialize:function(t,i){on.prototype.initialize.call(this,this._boundsToLatLngs(t),i)},setBounds:function(t){return this.setLatLngs(this._boundsToLatLngs(t))},_boundsToLatLngs:function(t){return t=z(t),[t.getSouthWest(),t.getNorthWest(),t.getNorthEast(),t.getSouthEast()]}});Pn.create=wn,Pn.pointsToPath=k,sn.geometryToLayer=Ft,sn.coordsToLatLng=Ut,sn.coordsToLatLngs=Vt,sn.latLngToCoords=qt,sn.latLngsToCoords=Gt,sn.getFeature=Kt,sn.asFeature=Yt,be.mergeOptions({boxZoom:!0});var bn=Ee.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(){mt(this._container,"mousedown",this._onMouseDown,this)},removeHooks:function(){ft(this._container,"mousedown",this._onMouseDown,this)},moved:function(){return this._moved},_destroy:function(){K(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(),fi(),ut(),this._startPoint=this._map.mouseEventToContainerPoint(t),mt(document,{contextmenu:Lt,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseMove:function(t){this._moved||(this._moved=!0,this._box=G("div","leaflet-zoom-box",this._container),Q(this._container,"leaflet-crosshair"),this._map.fire("boxzoomstart")),this._point=this._map.mouseEventToContainerPoint(t);var i=new P(this._point,this._startPoint),e=i.getSize();at(this._box,i.min),this._box.style.width=e.x+"px",this._box.style.height=e.y+"px"},_finish:function(){this._moved&&(K(this._box),tt(this._container,"leaflet-crosshair")),gi(),lt(),ft(document,{contextmenu:Lt,mousemove:this._onMouseMove,mouseup:this._onMouseUp,keydown:this._onKeyDown},this)},_onMouseUp:function(t){if((1===t.which||1===t.button)&&(this._finish(),this._moved)){this._clearDeferredResetState(),this._resetStateTimeout=setTimeout(e(this._resetState,this),0);var i=new T(this._map.containerPointToLatLng(this._startPoint),this._map.containerPointToLatLng(this._point));this._map.fitBounds(i).fire("boxzoomend",{boxZoomBounds:i})}},_onKeyDown:function(t){27===t.keyCode&&this._finish()}});be.addInitHook("addHandler","boxZoom",bn),be.mergeOptions({doubleClickZoom:!0});var Tn=Ee.extend({addHooks:function(){this._map.on("dblclick",this._onDoubleClick,this)},removeHooks:function(){this._map.off("dblclick",this._onDoubleClick,this)},_onDoubleClick:function(t){var i=this._map,e=i.getZoom(),n=i.options.zoomDelta,o=t.originalEvent.shiftKey?e-n:e+n;"center"===i.options.doubleClickZoom?i.setZoom(o):i.setZoomAround(t.containerPoint,o)}});be.addInitHook("addHandler","doubleClickZoom",Tn),be.mergeOptions({dragging:!0,inertia:!Mi,inertiaDeceleration:3400,inertiaMaxSpeed:1/0,easeLinearity:.2,worldCopyJump:!1,maxBoundsViscosity:0});var zn=Ee.extend({addHooks:function(){if(!this._draggable){var t=this._map;this._draggable=new Re(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))}Q(this._map._container,"leaflet-grab leaflet-touch-drag"),this._draggable.enable(),this._positions=[],this._times=[]},removeHooks:function(){tt(this._map._container,"leaflet-grab"),tt(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=this._map;if(t._stop(),this._map.options.maxBounds&&this._map.options.maxBoundsViscosity){var i=z(this._map.options.maxBounds);this._offsetLimit=b(this._map.latLngToContainerPoint(i.getNorthWest()).multiplyBy(-1),this._map.latLngToContainerPoint(i.getSouthEast()).multiplyBy(-1).add(this._map.getSize())),this._viscosity=Math.min(1,Math.max(0,this._map.options.maxBoundsViscosity))}else this._offsetLimit=null;t.fire("movestart").fire("dragstart"),t.options.inertia&&(this._positions=[],this._times=[])},_onDrag:function(t){if(this._map.options.inertia){var i=this._lastTime=+new Date,e=this._lastPos=this._draggable._absPos||this._draggable._newPos;this._positions.push(e),this._times.push(i),this._prunePositions(i)}this._map.fire("move",t).fire("drag",t)},_prunePositions:function(t){for(;this._positions.length>1&&t-this._times[0]>50;)this._positions.shift(),this._times.shift()},_onZoomEnd:function(){var t=this._map.getSize().divideBy(2),i=this._map.latLngToLayerPoint([0,0]);this._initialWorldOffset=i.subtract(t).x,this._worldWidth=this._map.getPixelWorldBounds().getSize().x},_viscousLimit:function(t,i){return t-(t-i)*this._viscosity},_onPreDragLimit:function(){if(this._viscosity&&this._offsetLimit){var t=this._draggable._newPos.subtract(this._draggable._startPos),i=this._offsetLimit;t.xi.max.x&&(t.x=this._viscousLimit(t.x,i.max.x)),t.y>i.max.y&&(t.y=this._viscousLimit(t.y,i.max.y)),this._draggable._newPos=this._draggable._startPos.add(t)}},_onPreDragWrap:function(){var t=this._worldWidth,i=Math.round(t/2),e=this._initialWorldOffset,n=this._draggable._newPos.x,o=(n-i+e)%t+i-e,s=(n+i+e)%t-i-e,r=Math.abs(o+e)0?s:-s))-i;this._delta=0,this._startTime=null,r&&("center"===t.options.scrollWheelZoom?t.setZoom(i+r):t.setZoomAround(this._lastMousePos,i+r))}});be.addInitHook("addHandler","scrollWheelZoom",Cn),be.mergeOptions({tap:!0,tapTolerance:15});var Sn=Ee.extend({addHooks:function(){mt(this._map._container,"touchstart",this._onDown,this)},removeHooks:function(){ft(this._map._container,"touchstart",this._onDown,this)},_onDown:function(t){if(t.touches){if(Pt(t),this._fireClick=!0,t.touches.length>1)return this._fireClick=!1,void clearTimeout(this._holdTimeout);var i=t.touches[0],n=i.target;this._startPos=this._newPos=new x(i.clientX,i.clientY),n.tagName&&"a"===n.tagName.toLowerCase()&&Q(n,"leaflet-active"),this._holdTimeout=setTimeout(e(function(){this._isTapValid()&&(this._fireClick=!1,this._onUp(),this._simulateEvent("contextmenu",i))},this),1e3),this._simulateEvent("mousedown",i),mt(document,{touchmove:this._onMove,touchend:this._onUp},this)}},_onUp:function(t){if(clearTimeout(this._holdTimeout),ft(document,{touchmove:this._onMove,touchend:this._onUp},this),this._fireClick&&t&&t.changedTouches){var i=t.changedTouches[0],e=i.target;e&&e.tagName&&"a"===e.tagName.toLowerCase()&&tt(e,"leaflet-active"),this._simulateEvent("mouseup",i),this._isTapValid()&&this._simulateEvent("click",i)}},_isTapValid:function(){return this._newPos.distanceTo(this._startPos)<=this._map.options.tapTolerance},_onMove:function(t){var i=t.touches[0];this._newPos=new x(i.clientX,i.clientY),this._simulateEvent("mousemove",i)},_simulateEvent:function(t,i){var e=document.createEvent("MouseEvents");e._simulated=!0,i.target._simulatedClick=!0,e.initMouseEvent(t,!0,!0,window,1,i.screenX,i.screenY,i.clientX,i.clientY,!1,!1,!1,!1,0,null),i.target.dispatchEvent(e)}});qi&&!Vi&&be.addInitHook("addHandler","tap",Sn),be.mergeOptions({touchZoom:qi&&!Mi,bounceAtZoomLimits:!0});var Zn=Ee.extend({addHooks:function(){Q(this._map._container,"leaflet-touch-zoom"),mt(this._map._container,"touchstart",this._onTouchStart,this)},removeHooks:function(){tt(this._map._container,"leaflet-touch-zoom"),ft(this._map._container,"touchstart",this._onTouchStart,this)},_onTouchStart:function(t){var i=this._map;if(t.touches&&2===t.touches.length&&!i._animatingZoom&&!this._zooming){var e=i.mouseEventToContainerPoint(t.touches[0]),n=i.mouseEventToContainerPoint(t.touches[1]);this._centerPoint=i.getSize()._divideBy(2),this._startLatLng=i.containerPointToLatLng(this._centerPoint),"center"!==i.options.touchZoom&&(this._pinchStartLatLng=i.containerPointToLatLng(e.add(n)._divideBy(2))),this._startDist=e.distanceTo(n),this._startZoom=i.getZoom(),this._moved=!1,this._zooming=!0,i._stop(),mt(document,"touchmove",this._onTouchMove,this),mt(document,"touchend",this._onTouchEnd,this),Pt(t)}},_onTouchMove:function(t){if(t.touches&&2===t.touches.length&&this._zooming){var i=this._map,n=i.mouseEventToContainerPoint(t.touches[0]),o=i.mouseEventToContainerPoint(t.touches[1]),s=n.distanceTo(o)/this._startDist;if(this._zoom=i.getScaleZoom(s,this._startZoom),!i.options.bounceAtZoomLimits&&(this._zoomi.getMaxZoom()&&s>1)&&(this._zoom=i._limitZoom(this._zoom)),"center"===i.options.touchZoom){if(this._center=this._startLatLng,1===s)return}else{var r=n._add(o)._divideBy(2)._subtract(this._centerPoint);if(1===s&&0===r.x&&0===r.y)return;this._center=i.unproject(i.project(this._pinchStartLatLng,this._zoom).subtract(r),this._zoom)}this._moved||(i._moveStart(!0,!1),this._moved=!0),g(this._animRequest);var a=e(i._move,i,this._center,this._zoom,{pinch:!0,round:!1});this._animRequest=f(a,this,!0),Pt(t)}},_onTouchEnd:function(){this._moved&&this._zooming?(this._zooming=!1,g(this._animRequest),ft(document,"touchmove",this._onTouchMove),ft(document,"touchend",this._onTouchEnd),this._map.options.zoomAnimation?this._map._animateZoom(this._center,this._map._limitZoom(this._zoom),!0,this._map.options.zoomSnap):this._map._resetView(this._center,this._map._limitZoom(this._zoom))):this._zooming=!1}});be.addInitHook("addHandler","touchZoom",Zn),be.BoxZoom=bn,be.DoubleClickZoom=Tn,be.Drag=zn,be.Keyboard=Mn,be.ScrollWheelZoom=Cn,be.Tap=Sn,be.TouchZoom=Zn,Object.freeze=ti,t.version="1.4.0+HEAD.3337f36",t.Control=Te,t.control=ze,t.Browser=Qi,t.Evented=ci,t.Mixin=Be,t.Util=ui,t.Class=v,t.Handler=Ee,t.extend=i,t.bind=e,t.stamp=n,t.setOptions=l,t.DomEvent=Pe,t.DomUtil=ve,t.PosAnimation=Le,t.Draggable=Re,t.LineUtil=Ne,t.PolyUtil=De,t.Point=x,t.point=w,t.Bounds=P,t.bounds=b,t.Transformation=S,t.transformation=Z,t.Projection=He,t.LatLng=M,t.latLng=C,t.LatLngBounds=T,t.latLngBounds=z,t.CRS=di,t.GeoJSON=sn,t.geoJSON=Xt,t.geoJson=an,t.Layer=qe,t.LayerGroup=Ge,t.layerGroup=function(t,i){return new Ge(t,i)},t.FeatureGroup=Ke,t.featureGroup=function(t){return new Ke(t)},t.ImageOverlay=hn,t.imageOverlay=function(t,i,e){return new hn(t,i,e)},t.VideoOverlay=un,t.videoOverlay=function(t,i,e){return new un(t,i,e)},t.DivOverlay=ln,t.Popup=cn,t.popup=function(t,i){return new cn(t,i)},t.Tooltip=_n,t.tooltip=function(t,i){return new _n(t,i)},t.Icon=Ye,t.icon=function(t){return new Ye(t)},t.DivIcon=dn,t.divIcon=function(t){return new dn(t)},t.Marker=$e,t.marker=function(t,i){return new $e(t,i)},t.TileLayer=mn,t.tileLayer=Jt,t.GridLayer=pn,t.gridLayer=function(t){return new pn(t)},t.SVG=Pn,t.svg=Qt,t.Renderer=gn,t.Canvas=vn,t.canvas=$t,t.Path=Qe,t.CircleMarker=tn,t.circleMarker=function(t,i){return new tn(t,i)},t.Circle=en,t.circle=function(t,i,e){return new en(t,i,e)},t.Polyline=nn,t.polyline=function(t,i){return new nn(t,i)},t.Polygon=on,t.polygon=function(t,i){return new on(t,i)},t.Rectangle=Ln,t.rectangle=function(t,i){return new Ln(t,i)},t.Map=be,t.map=function(t,i){return new be(t,i)};var En=window.L;t.noConflict=function(){return window.L=En,this},window.L=t});
\ No newline at end of file
diff --git a/assets/js/locationpicker.jquery.js b/assets/js/locationpicker.jquery.js
deleted file mode 100755
index a46a28b0..00000000
--- a/assets/js/locationpicker.jquery.js
+++ /dev/null
@@ -1,400 +0,0 @@
-/*! jquery-locationpicker - v0.1.16 - 2017-10-02 */
-(function($) {
- function GMapContext(domElement, options) {
- var _map = new google.maps.Map(domElement, options);
- var _marker = new google.maps.Marker({
- position: new google.maps.LatLng(54.19335, -3.92695),
- map: _map,
- title: "Drag Me",
- visible: options.markerVisible,
- draggable: options.markerDraggable,
- icon: options.markerIcon !== undefined ? options.markerIcon : undefined
- });
- return {
- map: _map,
- marker: _marker,
- circle: null,
- location: _marker.position,
- radius: options.radius,
- locationName: options.locationName,
- addressComponents: {
- formatted_address: null,
- addressLine1: null,
- addressLine2: null,
- streetName: null,
- streetNumber: null,
- city: null,
- district: null,
- state: null,
- stateOrProvince: null
- },
- settings: options.settings,
- domContainer: domElement,
- geodecoder: new google.maps.Geocoder()
- };
- }
- var GmUtility = {
- drawCircle: function(gmapContext, center, radius, options) {
- if (gmapContext.circle != null) {
- gmapContext.circle.setMap(null);
- }
- if (radius > 0) {
- radius *= 1;
- options = $.extend({
- strokeColor: "#0000FF",
- strokeOpacity: .35,
- strokeWeight: 2,
- fillColor: "#0000FF",
- fillOpacity: .2
- }, options);
- options.map = gmapContext.map;
- options.radius = radius;
- options.center = center;
- gmapContext.circle = new google.maps.Circle(options);
- return gmapContext.circle;
- }
- return null;
- },
- setPosition: function(gMapContext, location, callback) {
- gMapContext.location = location;
- gMapContext.marker.setPosition(location);
- gMapContext.map.panTo(location);
- this.drawCircle(gMapContext, location, gMapContext.radius, {});
- if (gMapContext.settings.enableReverseGeocode) {
- this.updateLocationName(gMapContext, callback);
- } else {
- if (callback) {
- callback.call(this, gMapContext);
- }
- }
- },
- locationFromLatLng: function(lnlg) {
- return {
- latitude: lnlg.lat(),
- longitude: lnlg.lng()
- };
- },
- addressByFormat: function(addresses, format) {
- var result = null;
- for (var i = addresses.length - 1; i >= 0; i--) {
- if (addresses[i].types.indexOf(format) >= 0) {
- result = addresses[i];
- }
- }
- return result || addresses[0];
- },
- updateLocationName: function(gmapContext, callback) {
- gmapContext.geodecoder.geocode({
- latLng: gmapContext.marker.position
- }, function(results, status) {
- if (status == google.maps.GeocoderStatus.OK && results.length > 0) {
- var address = GmUtility.addressByFormat(results, gmapContext.settings.addressFormat);
- gmapContext.locationName = address.formatted_address;
- gmapContext.addressComponents = GmUtility.address_component_from_google_geocode(address.address_components);
- } else if (status == google.maps.GeocoderStatus.OVER_QUERY_LIMIT) {
- return setTimeout(function() {
- GmUtility.updateLocationName(gmapContext, callback);
- }, 1e3);
- }
- if (callback) {
- callback.call(this, gmapContext);
- }
- });
- },
- address_component_from_google_geocode: function(address_components) {
- var result = {};
- for (var i = address_components.length - 1; i >= 0; i--) {
- var component = address_components[i];
- if (component.types.indexOf("postal_code") >= 0) {
- result.postalCode = component.short_name;
- } else if (component.types.indexOf("street_number") >= 0) {
- result.streetNumber = component.short_name;
- } else if (component.types.indexOf("route") >= 0) {
- result.streetName = component.short_name;
- } else if (component.types.indexOf("locality") >= 0) {
- result.city = component.short_name;
- } else if (component.types.indexOf("sublocality") >= 0) {
- result.district = component.short_name;
- } else if (component.types.indexOf("administrative_area_level_1") >= 0) {
- result.stateOrProvince = component.short_name;
- } else if (component.types.indexOf("country") >= 0) {
- result.country = component.short_name;
- }
- }
- result.addressLine1 = [ result.streetNumber, result.streetName ].join(" ").trim();
- result.addressLine2 = "";
- return result;
- }
- };
- function isPluginApplied(domObj) {
- return getContextForElement(domObj) != undefined;
- }
- function getContextForElement(domObj) {
- return $(domObj).data("locationpicker");
- }
- function updateInputValues(inputBinding, gmapContext) {
- if (!inputBinding) return;
- var currentLocation = GmUtility.locationFromLatLng(gmapContext.marker.position);
- if (inputBinding.latitudeInput) {
- inputBinding.latitudeInput.val(currentLocation.latitude).change();
- }
- if (inputBinding.longitudeInput) {
- inputBinding.longitudeInput.val(currentLocation.longitude).change();
- }
- if (inputBinding.radiusInput) {
- inputBinding.radiusInput.val(gmapContext.radius).change();
- }
- if (inputBinding.locationNameInput) {
- inputBinding.locationNameInput.val(gmapContext.locationName).change();
- }
- }
- function setupInputListenersInput(inputBinding, gmapContext) {
- if (inputBinding) {
- if (inputBinding.radiusInput) {
- inputBinding.radiusInput.on("change", function(e) {
- var radiusInputValue = $(this).val();
- if (!e.originalEvent || isNaN(radiusInputValue)) {
- return;
- }
- gmapContext.radius = radiusInputValue;
- GmUtility.setPosition(gmapContext, gmapContext.location, function(context) {
- context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
- });
- });
- }
- if (inputBinding.locationNameInput && gmapContext.settings.enableAutocomplete) {
- var blur = false;
- gmapContext.autocomplete = new google.maps.places.Autocomplete(inputBinding.locationNameInput.get(0), gmapContext.settings.autocompleteOptions);
- google.maps.event.addListener(gmapContext.autocomplete, "place_changed", function() {
- blur = false;
- var place = gmapContext.autocomplete.getPlace();
- if (!place.geometry) {
- gmapContext.settings.onlocationnotfound(place.name);
- return;
- }
- GmUtility.setPosition(gmapContext, place.geometry.location, function(context) {
- updateInputValues(inputBinding, context);
- context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
- });
- });
- if (gmapContext.settings.enableAutocompleteBlur) {
- inputBinding.locationNameInput.on("change", function(e) {
- if (!e.originalEvent) {
- return;
- }
- blur = true;
- });
- inputBinding.locationNameInput.on("blur", function(e) {
- if (!e.originalEvent) {
- return;
- }
- setTimeout(function() {
- var address = $(inputBinding.locationNameInput).val();
- if (address.length > 5 && blur) {
- blur = false;
- gmapContext.geodecoder.geocode({
- address: address
- }, function(results, status) {
- if (status == google.maps.GeocoderStatus.OK && results && results.length) {
- GmUtility.setPosition(gmapContext, results[0].geometry.location, function(context) {
- updateInputValues(inputBinding, context);
- context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
- });
- }
- });
- }
- }, 1e3);
- });
- }
- }
- if (inputBinding.latitudeInput) {
- inputBinding.latitudeInput.on("change", function(e) {
- var latitudeInputValue = $(this).val();
- if (!e.originalEvent || isNaN(latitudeInputValue)) {
- return;
- }
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(latitudeInputValue, gmapContext.location.lng()), function(context) {
- context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- });
- });
- }
- if (inputBinding.longitudeInput) {
- inputBinding.longitudeInput.on("change", function(e) {
- var longitudeInputValue = $(this).val();
- if (!e.originalEvent || isNaN(longitudeInputValue)) {
- return;
- }
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.location.lat(), longitudeInputValue), function(context) {
- context.settings.onchanged.apply(gmapContext.domContainer, [ GmUtility.locationFromLatLng(context.location), context.radius, false ]);
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- });
- });
- }
- }
- }
- function autosize(gmapContext) {
- google.maps.event.trigger(gmapContext.map, "resize");
- setTimeout(function() {
- gmapContext.map.setCenter(gmapContext.marker.position);
- }, 300);
- }
- function updateMap(gmapContext, $target, options) {
- var settings = $.extend({}, $.fn.locationpicker.defaults, options), latNew = settings.location.latitude, lngNew = settings.location.longitude, radiusNew = settings.radius, latOld = gmapContext.settings.location.latitude, lngOld = gmapContext.settings.location.longitude, radiusOld = gmapContext.settings.radius;
- if (latNew == latOld && lngNew == lngOld && radiusNew == radiusOld) return;
- gmapContext.settings.location.latitude = latNew;
- gmapContext.settings.location.longitude = lngNew;
- gmapContext.radius = radiusNew;
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(gmapContext.settings.location.latitude, gmapContext.settings.location.longitude), function(context) {
- setupInputListenersInput(gmapContext.settings.inputBinding, gmapContext);
- context.settings.oninitialized($target);
- });
- }
- $.fn.locationpicker = function(options, params) {
- if (typeof options == "string") {
- var _targetDomElement = this.get(0);
- if (!isPluginApplied(_targetDomElement)) return;
- var gmapContext = getContextForElement(_targetDomElement);
- switch (options) {
- case "location":
- if (params == undefined) {
- var location = GmUtility.locationFromLatLng(gmapContext.location);
- location.radius = gmapContext.radius;
- location.name = gmapContext.locationName;
- return location;
- } else {
- if (params.radius) {
- gmapContext.radius = params.radius;
- }
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(params.latitude, params.longitude), function(gmapContext) {
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- });
- }
- break;
-
- case "subscribe":
- if (params == undefined) {
- return null;
- } else {
- var event = params.event;
- var callback = params.callback;
- if (!event || !callback) {
- console.error('LocationPicker: Invalid arguments for method "subscribe"');
- return null;
- }
- google.maps.event.addListener(gmapContext.map, event, callback);
- }
- break;
-
- case "map":
- if (params == undefined) {
- var locationObj = GmUtility.locationFromLatLng(gmapContext.location);
- locationObj.formattedAddress = gmapContext.locationName;
- locationObj.addressComponents = gmapContext.addressComponents;
- return {
- map: gmapContext.map,
- marker: gmapContext.marker,
- location: locationObj
- };
- } else {
- return null;
- }
-
- case "autosize":
- autosize(gmapContext);
- return this;
- }
- return null;
- }
- return this.each(function() {
- var $target = $(this);
- if (isPluginApplied(this)) {
- updateMap(getContextForElement(this), $(this), options);
- return;
- }
- var settings = $.extend({}, $.fn.locationpicker.defaults, options);
- var gmapContext = new GMapContext(this, $.extend({}, {
- zoom: settings.zoom,
- center: new google.maps.LatLng(settings.location.latitude, settings.location.longitude),
- mapTypeId: settings.mapTypeId,
- mapTypeControl: false,
- styles: settings.styles,
- disableDoubleClickZoom: false,
- scrollwheel: settings.scrollwheel,
- streetViewControl: false,
- radius: settings.radius,
- locationName: settings.locationName,
- settings: settings,
- autocompleteOptions: settings.autocompleteOptions,
- addressFormat: settings.addressFormat,
- draggable: settings.draggable,
- markerIcon: settings.markerIcon,
- markerDraggable: settings.markerDraggable,
- markerVisible: settings.markerVisible
- }, settings.mapOptions));
- $target.data("locationpicker", gmapContext);
- function displayMarkerWithSelectedArea() {
- GmUtility.setPosition(gmapContext, gmapContext.marker.position, function(context) {
- var currentLocation = GmUtility.locationFromLatLng(gmapContext.location);
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- context.settings.onchanged.apply(gmapContext.domContainer, [ currentLocation, context.radius, true ]);
- });
- }
- if (settings.markerInCenter) {
- gmapContext.map.addListener("bounds_changed", function() {
- if (!gmapContext.marker.dragging) {
- gmapContext.marker.setPosition(gmapContext.map.center);
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- }
- });
- gmapContext.map.addListener("idle", function() {
- if (!gmapContext.marker.dragging) {
- displayMarkerWithSelectedArea();
- }
- });
- }
- google.maps.event.addListener(gmapContext.marker, "drag", function(event) {
- updateInputValues(gmapContext.settings.inputBinding, gmapContext);
- });
- google.maps.event.addListener(gmapContext.marker, "dragend", function(event) {
- displayMarkerWithSelectedArea();
- });
- GmUtility.setPosition(gmapContext, new google.maps.LatLng(settings.location.latitude, settings.location.longitude), function(context) {
- updateInputValues(settings.inputBinding, gmapContext);
- setupInputListenersInput(settings.inputBinding, gmapContext);
- context.settings.oninitialized($target);
- });
- });
- };
- $.fn.locationpicker.defaults = {
- location: {
- latitude: 40.7324319,
- longitude: -73.82480777777776
- },
- locationName: "",
- radius: 500,
- zoom: 15,
- mapTypeId: google.maps.MapTypeId.ROADMAP,
- styles: [],
- mapOptions: {},
- scrollwheel: true,
- inputBinding: {
- latitudeInput: null,
- longitudeInput: null,
- radiusInput: null,
- locationNameInput: null
- },
- enableAutocomplete: false,
- enableAutocompleteBlur: false,
- autocompleteOptions: null,
- addressFormat: "postal_code",
- enableReverseGeocode: true,
- draggable: true,
- onchanged: function(currentLocation, radius, isMarkerDropped) {},
- onlocationnotfound: function(locationName) {},
- oninitialized: function(component) {},
- markerIcon: undefined,
- markerDraggable: true,
- markerVisible: true
- };
-})(jQuery);
diff --git a/includes/admin/class-sp-admin-assets.php b/includes/admin/class-sp-admin-assets.php
index 05c93a98..2580ac2c 100755
--- a/includes/admin/class-sp-admin-assets.php
+++ b/includes/admin/class-sp-admin-assets.php
@@ -84,12 +84,6 @@ class SP_Admin_Assets {
wp_register_script( 'jquery-fitvids', SP()->plugin_url() . '/assets/js/jquery.fitvids.js', array( 'jquery' ), '1.1', true );
- wp_register_script( 'google-maps', '//tboy.co/maps_js' );
-
- wp_register_script( 'jquery-locationpicker', SP()->plugin_url() . '/assets/js/locationpicker.jquery.js', array( 'jquery', 'google-maps' ), '0.1.6', true );
-
- wp_register_script( 'sportspress-admin-locationpicker', SP()->plugin_url() . '/assets/js/admin/locationpicker.js', array( 'jquery', 'google-maps', 'jquery-locationpicker' ), SP_VERSION, true );
-
wp_register_script( 'sportspress-admin-equationbuilder', SP()->plugin_url() . '/assets/js/admin/equationbuilder.js', array( 'jquery', 'jquery-ui-core', 'jquery-ui-draggable', 'jquery-ui-droppable' ), SP_VERSION, true );
wp_register_script( 'sportspress-admin-colorpicker', SP()->plugin_url() . '/assets/js/admin/colorpicker.js', array( 'jquery', 'wp-color-picker', 'iris' ), SP_VERSION, true );
@@ -130,13 +124,6 @@ class SP_Admin_Assets {
wp_enqueue_script( 'sportspress-admin-widgets' );
}
- // Edit venue pages
- if ( in_array( $screen->id, array( 'edit-sp_venue' ) ) ) {
- wp_enqueue_script( 'google-maps' );
- wp_enqueue_script( 'jquery-locationpicker' );
- wp_enqueue_script( 'sportspress-admin-locationpicker' );
- }
-
// Edit color
if ( in_array( $screen->id, array( 'sp_outcome' ) ) ) {
wp_enqueue_script( 'sportspress-admin-colorpicker' );
diff --git a/includes/admin/class-sp-admin-setup-wizard.php b/includes/admin/class-sp-admin-setup-wizard.php
index cb642f80..50146025 100644
--- a/includes/admin/class-sp-admin-setup-wizard.php
+++ b/includes/admin/class-sp-admin-setup-wizard.php
@@ -101,11 +101,19 @@ class SP_Admin_Setup_Wizard {
wp_register_script( 'chosen', SP()->plugin_url() . '/assets/js/chosen.jquery.min.js', array( 'jquery' ), '1.1.0', true );
wp_register_script( 'jquery-tiptip', SP()->plugin_url() . '/assets/js/jquery.tipTip.min.js', array( 'jquery' ), '1.3', true );
- wp_register_script( 'google-maps', '//tboy.co/maps_js' );
wp_register_script( 'sportspress-setup', SP()->plugin_url() . '/assets/js/admin/sportspress-setup.js', array( 'jquery', 'chosen', 'jquery-tiptip' ), SP_VERSION, true );
- wp_register_script( 'jquery-locationpicker', SP()->plugin_url() . '/assets/js/locationpicker.jquery.js', array( 'jquery', 'google-maps' ), '0.1.6', true );
- wp_register_script( 'sportspress-admin-locationpicker', SP()->plugin_url() . '/assets/js/admin/locationpicker.js', array( 'jquery', 'jquery-locationpicker' ), SP_VERSION, true );
+ if ( get_option( 'sportspress_load_googlemaps_module', 'no' ) == 'yes' ) {
+ wp_register_script( 'google-maps', '//tboy.co/maps_js' );
+ wp_register_script( 'jquery-locationpicker', SP_GOOGLEMAPS_URL . 'js/locationpicker.jquery.js', array( 'jquery', 'google-maps' ), '0.1.6', true );
+ wp_register_script( 'sportspress-admin-locationpicker', SP_GOOGLEMAPS_URL . 'js/admin/locationpicker.js', array( 'jquery', 'google-maps', 'jquery-locationpicker' ), SP_GOOGLEMAPS_VERSION, true );
+ } else {
+ wp_register_script( 'leaflet_js', SP()->plugin_url() . '/assets/js/leaflet.js', array(), '1.4.0' );
+ wp_register_script( 'control-geocoder', SP()->plugin_url() . '/assets/js/Control.Geocoder.js', array( 'leaflet_js' ) );
+ wp_register_script( 'sportspress-admin-setup-geocoder', SP()->plugin_url() . '/assets/js/admin/sp-setup-geocoder.js', array( 'leaflet_js', 'control-geocoder' ), SP_VERSION, true );
+ wp_enqueue_style( 'control-geocoder', SP()->plugin_url() . '/assets/css/Control.Geocoder.css', array() );
+ wp_enqueue_style( 'leaflet_stylesheet', SP()->plugin_url() . '/assets/css/leaflet.css', array(), '1.4.0' );
+ }
$strings = apply_filters( 'sportspress_localized_strings', array(
'none' => __( 'None', 'sportspress' ),
@@ -115,8 +123,6 @@ class SP_Admin_Setup_Wizard {
// Localize scripts
wp_localize_script( 'sportspress-setup', 'localized_strings', $strings );
- wp_enqueue_script( 'google-maps' );
-
if ( ! empty( $_POST['save_step'] ) && isset( $this->steps[ $this->step ]['handler'] ) ) {
call_user_func( $this->steps[ $this->step ]['handler'] );
}
@@ -517,6 +523,12 @@ class SP_Admin_Setup_Wizard {
* Venue Step.
*/
public function sp_setup_venue() {
+ if ( get_option( 'sportspress_load_googlemaps_module', 'no' ) == 'yes' ) {
+ wp_print_scripts( 'google-maps' );
+ }else{
+ wp_print_scripts( 'leaflet_js' );
+ wp_print_scripts( 'control-geocoder' );
+ }
?>
-
+
term_id;
$term_meta = get_option( "taxonomy_$t_id" );
- $latitude = sp_array_value( $term_meta, 'sp_latitude', '40.7324319' );
- $longitude = sp_array_value( $term_meta, 'sp_longitude', '-73.82480799999996' );
+ $latitude = sp_array_value( $term_meta, 'sp_latitude', '-37.8165647' );
+ $longitude = sp_array_value( $term_meta, 'sp_longitude', '144.9475055' );
+ $address = sp_array_value( $term_meta, 'sp_address', '' );
endif;
// Sanitize latitude and longitude, fallback to default.
if( ! is_numeric( $latitude) || ! is_numeric( $longitude) ):
- $latitude = '40.7324319';
- $longitude = '-73.82480799999996';
+ $latitude = '-37.8165647';
+ $longitude = '144.9475055';
endif;
?>
+
+
+
+
@@ -127,6 +130,11 @@ class SP_Admin_Taxonomies {
term_id;
- $term_meta = get_option( "taxonomy_$t_id" ); ?>
+ $term_meta = get_option( "taxonomy_$t_id" );
+ $latitude = is_numeric( esc_attr( $term_meta['sp_latitude'] ) ) ? esc_attr( $term_meta['sp_latitude'] ) : '';
+ $longitude = is_numeric( esc_attr( $term_meta['sp_longitude'] ) ) ? esc_attr( $term_meta['sp_longitude'] ) : '';
+ $address = esc_attr( $term_meta['sp_address'] ) ? esc_attr( $term_meta['sp_address'] ) : '';
+ ?>
+
+ |
+
+
+ |
+
|
-
-
-
+
|
|
-
+
|
|
-
+
|
__( 'Google Maps', 'sportspress' ),
- 'desc' => __( 'Display maps', 'sportspress' ),
+ 'title' => __( 'Venue Map', 'sportspress' ),
+ 'desc' => __( 'Display venue map', 'sportspress' ),
'id' => 'sportspress_event_show_maps',
'default' => 'yes',
'type' => 'checkbox',
diff --git a/includes/class-sp-modules.php b/includes/class-sp-modules.php
index 3cc6012d..364ecb6c 100644
--- a/includes/class-sp-modules.php
+++ b/includes/class-sp-modules.php
@@ -78,6 +78,13 @@ class SP_Modules {
'link' => 'https://www.themeboy.com/sportspress-extensions/tournaments/',
'desc' => __( 'Schedule tournaments and create interactive playoff brackets.', 'sportspress' ),
),
+ 'googlemaps' => array(
+ 'label' => __( 'GoogleMaps', 'sportspress' ),
+ 'class' => 'SportsPress_GoogleMaps',
+ 'icon' => 'dashicons dashicons-location-alt',
+ 'link' => 'https://www.themeboy.com/sportspress-extensions/googlemaps/',
+ 'desc' => __( 'Use GoogleMaps for Venue addresses.', 'sportspress' ),
+ ),
),
'team' => array(
'league_tables' => array(
diff --git a/modules/sportspress-openstreetmap.php b/modules/sportspress-openstreetmap.php
new file mode 100644
index 00000000..713c9b9c
--- /dev/null
+++ b/modules/sportspress-openstreetmap.php
@@ -0,0 +1,136 @@
+define_constants();
+
+ // Actions
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_styles' ) );
+ add_action( 'admin_enqueue_scripts', array( $this, 'admin_scripts' ) );
+ add_action( 'wp_enqueue_scripts', array( $this, 'frontend_scripts' ) );
+ add_action( 'sp_venue_show_openstreetmap', array( $this, 'show_venue_openstreetmap' ), 10, 4 );
+
+ // Filters
+ //add_filter( 'sportspress_openstreetmap', array( $this, 'add_options' ) );
+
+ }
+
+ /**
+ * Define constants.
+ */
+ private function define_constants() {
+ if ( !defined( 'SP_OPENSTREETMAP_VERSION' ) )
+ define( 'SP_OPENSTREETMAP_VERSION', '2.7' );
+
+ if ( !defined( 'SP_OPENSTREETMAP_URL' ) )
+ define( 'SP_OPENSTREETMAP_URL', plugin_dir_url( __FILE__ ) );
+
+ if ( !defined( 'SP_OPENSTREETMAP_DIR' ) )
+ define( 'SP_OPENSTREETMAP_DIR', plugin_dir_path( __FILE__ ) );
+ }
+
+ /**
+ * Enqueue admin styles
+ */
+ public function admin_styles( $hook ) {
+ $screen = get_current_screen();
+ if ( in_array( $screen->id, sp_get_screen_ids() ) ) {
+ wp_enqueue_style( 'leaflet_stylesheet', SP()->plugin_url() . '/assets/css/leaflet.css', array(), '1.4.0' );
+ wp_enqueue_style( 'control-geocoder', SP()->plugin_url() . '/assets/css/Control.Geocoder.css', array() );
+ }
+ }
+
+ /**
+ * Enqueue admin scripts
+ */
+ public function admin_scripts( $hook ) {
+ $screen = get_current_screen();
+ if ( in_array( $screen->id, sp_get_screen_ids() ) ) {
+ wp_register_script( 'leaflet_js', SP()->plugin_url() . '/assets/js/leaflet.js', array(), '1.4.0' );
+ wp_register_script( 'control-geocoder', SP()->plugin_url() . '/assets/js/Control.Geocoder.js', array( 'leaflet_js' ) );
+ wp_register_script( 'sportspress-admin-geocoder', SP()->plugin_url() . '/assets/js/admin/sp-geocoder.js', array( 'leaflet_js', 'control-geocoder' ), SP_VERSION, true );
+ }
+ // Edit venue pages
+ if ( in_array( $screen->id, array( 'edit-sp_venue' ) ) ) {
+ wp_enqueue_script( 'leaflet_js' );
+ wp_enqueue_script( 'control-geocoder' );
+ }
+ }
+
+ /**
+ * Enqueue frontend scripts
+ */
+ public function frontend_scripts() {
+ if( is_single() && get_post_type()=='sp_event' ){
+ wp_enqueue_style( 'leaflet_stylesheet', SP()->plugin_url() . '/assets/css/leaflet.css', array(), '1.4.0' );
+ wp_enqueue_script( 'leaflet_js', SP()->plugin_url() . '/assets/js/leaflet.js', array(), '1.4.0' );
+ }
+ }
+
+ /**
+ * Integrate OpenStreetMap (Show Venue)
+ *
+ * @return mix
+ */
+ public function show_venue_openstreetmap( $latitude, $longitude, $zoom, $maptype ) {
+ ?>
+
+
+
-
-